diff --git a/.gitignore b/.gitignore index 71e257752..b72055ed9 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,5 @@ Frameworks Build Demos -Aristo +./Aristo WebSite diff --git a/AppKit/CPAlert.j b/AppKit/CPAlert.j index f25d78b32..6e41f149b 100644 --- a/AppKit/CPAlert.j +++ b/AppKit/CPAlert.j @@ -62,12 +62,12 @@ var CPAlertWarningImage, CPAlert is an alert panel that can be displayed modally to present the user with a message and one or more options. - It can be used to display an information message (
CPInformationalAlertStyle
), - a warning message (
CPWarningAlertStyle
- which is the default), or a critical - alert (
CPCriticalAlertStyle
). In each case the user can be presented with one - or more options by adding buttons using the
addButtonWithTitle:
method. + It can be used to display an information message \c CPInformationalAlertStyle, + a warning message \c CPWarningAlertStyle (the default), or a critical + alert \c CPCriticalAlertStyle. In each case the user can be presented with one + or more options by adding buttons using the \c -addButtonWithTitle: method. - The panel is displayed modally by calling
runModal
and once the user has + The panel is displayed modally by calling \c -runModal and once the user has dismissed the panel, a message will be sent to the panel's delegate (if set), informing it which button was clicked (see delegate methods). @@ -112,7 +112,7 @@ var CPAlertWarningImage, } /*! - Initializes a
CPAlert
panel with the default alert style (
CPWarningAlertStyle
). + Initializes a \c CPAlert panel with the default alert style \c CPWarningAlertStyle. */ - (id)init { @@ -244,7 +244,7 @@ var CPAlertWarningImage, /*! Adds a button with a given title to the receiver. - Buttons will be added starting from the right hand side of the
CPAlert
panel. + Buttons will be added starting from the right hand side of the \c CPAlert panel. The first button will have the index 0, the second button 1 and so on. You really shouldn't need more than 3 buttons. @@ -269,7 +269,7 @@ var CPAlertWarningImage, } /*! - Displays the
CPAlert
panel as a modal dialog. The user will not be + Displays the \c CPAlert panel as a modal dialog. The user will not be able to interact with any other controls until s/he has dismissed the alert by clicking on one of the buttons. */ diff --git a/AppKit/CPAnimation.j b/AppKit/CPAnimation.j index 77fdaab91..df880842c 100644 --- a/AppKit/CPAnimation.j +++ b/AppKit/CPAnimation.j @@ -57,10 +57,10 @@ ACTUAL_FRAME_RATE = 0; @par Delegate Methods @delegate -(BOOL)animationShouldStart:(CPAnimation)animation; - Called at the beginning of startAnimation. + Called at the beginning of \c -startAnimation. @param animation the animation that will start - @return YES allows the animation to start. - NO stops the animation. + @return \c YES allows the animation to start. + \c NO stops the animation. @delegate -(void)animationDidEnd:(CPAnimation)animation; Called when an animation has completed. @@ -72,7 +72,7 @@ ACTUAL_FRAME_RATE = 0; @delegate - (float)animation:(CPAnimation)animation valueForProgress:(float)progress; The value from this method will be returned when CPAnimation's - currentValue method is called. + \c currentValue method is called. @param animation the animation to obtain the curve value for @param progress the current animation progress @return the curve value @@ -154,7 +154,7 @@ ACTUAL_FRAME_RATE = 0; /*! Sets the animation's length. @param aDuration the new animation length - @throws CPInvalidArgumentException if aDuration is negative + @throws CPInvalidArgumentException if \c aDuration is negative */ - (void)setDuration:(CPTimeInterval)aDuration { @@ -175,7 +175,7 @@ ACTUAL_FRAME_RATE = 0; /*! Sets the animation frame rate. This is not a guaranteed frame rate. 0 means to go as fast as possible. @param frameRate the new desired frame rate - @throws CPInvalidArgumentException if frameRate is negative + @throws CPInvalidArgumentException if \c frameRate is negative */ - (void)setFrameRate:(float)frameRate { @@ -211,7 +211,7 @@ ACTUAL_FRAME_RATE = 0; } /*! - Starts the animation. The method calls animationShouldStart: + Starts the animation. The method calls \c -animationShouldStart: on the delegate (if it implements it) to see if the animation should begin. */ @@ -270,7 +270,7 @@ ACTUAL_FRAME_RATE = 0; } /*! - Returns YES if the animation + Returns \c YES if the animation is running. */ - (BOOL)isAnimating diff --git a/AppKit/CPApplication.j b/AppKit/CPApplication.j index f150bb026..54b424754 100644 --- a/AppKit/CPApplication.j +++ b/AppKit/CPApplication.j @@ -29,6 +29,8 @@ @import "CPDocumentController.j" @import "CPThemeBlend.j" @import "CPCibLoading.j" +@import "CPPlatform.j" + var CPMainCibFile = @"CPMainCibFile", CPMainCibFileHumanFriendly = @"Main cib file base name"; @@ -49,7 +51,7 @@ CPRunContinuesResponse = -1002; CPApplication is THE way to start up the Cappucino framework for your application to use. Every GUI application has exactly one instance of CPApplication (or of a custom subclass of CPApplication). Your program's main() function can create that instance by calling the - CPApplicationMain function. A simple example looks like this: + \c CPApplicationMain function. A simple example looks like this:
     function main(args, namedArgs)
@@ -105,7 +107,7 @@ CPRunContinuesResponse  = -1002;
 
 /*!
     Initializes the Document based application with basic menu functions.
-    Functions are New, Open, Undo, Redo, Save, Cut, Copy, Paste.
+    Functions are \c New, \c Open, \c Undo, \c Redo, \c Save, \c Cut, \c Copy, \c Paste.
     @return the initialized application
 */
 - (id)init
@@ -235,10 +237,10 @@ CPRunContinuesResponse  = -1002;
 }
 
 /*!
-    This method is called by run before the event loop begins.
+    This method is called by \c -run before the event loop begins.
     When it successfully completes, it posts the notification
     CPApplicationDidFinishLaunchingNotification. If you override
-    finishLaunching, the subclass method should invoke the superclass method.
+    \c -finishLaunching, the subclass method should invoke the superclass method.
 */
 - (void)finishLaunching
 {
@@ -278,7 +280,7 @@ CPRunContinuesResponse  = -1002;
 }
 
 /*!
-    Calls finishLaunching method which results in starting
+    Calls \c -finishLaunching method which results in starting
     the main event loop.
 */
 - (void)run
@@ -288,7 +290,7 @@ CPRunContinuesResponse  = -1002;
 
 // Managing the Event Loop
 /*!
-    Starts a modal event loop for aWindow
+    Starts a modal event loop for \c aWindow
     @param aWindow the window to start the event loop for
 */
 - (void)runModalForWindow:(CPWindow)aWindow
@@ -297,8 +299,8 @@ CPRunContinuesResponse  = -1002;
 }
 
 /*!
-    Stops the event loop started by runModalForWindow: and
-    sets the code that runModalForWindow: will return.
+    Stops the event loop started by \c -runModalForWindow: and
+    sets the code that \c -runModalForWindow: will return.
     @param aCode the return code for the modal event
 */
 - (void)stopModalWithCode:(int)aCode
@@ -339,7 +341,7 @@ CPRunContinuesResponse  = -1002;
 }
 
 /*!
-    Aborts the event loop started by runModalForWindow:
+    Aborts the event loop started by \c -runModalForWindow:
 */
 - (void)abortModal
 {
@@ -347,7 +349,7 @@ CPRunContinuesResponse  = -1002;
 }
 
 /*!
-    Sets up a modal session with theWindow.
+    Sets up a modal session with \c theWindow.
     @param aWindow the window to set up the modal session for
 */
 - (CPModalSession)beginModalSessionForWindow:(CPWindow)aWindow
@@ -376,7 +378,7 @@ CPRunContinuesResponse  = -1002;
 
 /*!
     Returns the window for the current modal session. If there is no
-    modal session, it returns nil.
+    modal session, it returns \c nil.
 */
 - (CPWindow)modalWindow
 {
@@ -444,7 +446,7 @@ CPRunContinuesResponse  = -1002;
 }
 
 /*!
-    Returns the CPWindow object corresponding to aWindowNumber.
+    Returns the CPWindow object corresponding to \c aWindowNumber.
 */
 - (CPWindow)windowWithWindowNumber:(int)aWindowNumber
 {
@@ -500,7 +502,7 @@ CPRunContinuesResponse  = -1002;
     @param anAction the action to perform.
     @param anObject the argument for the action
     method
-    @return YES if the action was performed
+    @return \c YES if the action was performed
 */
 - (BOOL)tryToPerform:(SEL)anAction with:(id)anObject
 {
@@ -525,7 +527,7 @@ CPRunContinuesResponse  = -1002;
     @param anAction the action to send
     @param aTarget the target for the action
     @param aSender the action sender
-    @return YES
+    @return \c YES
 */
 - (BOOL)sendAction:(SEL)anAction to:(id)aTarget from:(id)aSender
 {
@@ -541,12 +543,12 @@ CPRunContinuesResponse  = -1002;
 
 /*!
     Finds a target for the specified action. If the
-    action is nil, returns nil.
-    If the target is not nil, aTarget is
-    returned. Otherwise, it calls targetForAction:
+    action is \c nil, returns \c nil.
+    If the target is not \c nil, \c aTarget is
+    returned. Otherwise, it calls \c -targetForAction:
     to search for a target.
     @param anAction the action to find a target for
-    @param aTarget if not nil, this will be returned
+    @param aTarget if not \c nil, this will be returned
     @aSender not used
     @return a target for the action
 */
@@ -574,7 +576,7 @@ CPRunContinuesResponse  = -1002;
     
     @param aWindow the window to search for a target
     @param anAction the action to find a responder to
-    @return the object that responds to the action, or nil
+    @return the object that responds to the action, or \c nil
     if no matching target was found
     @ignore
 */
@@ -626,7 +628,7 @@ CPRunContinuesResponse  = -1002;
         
  • the document controller
  • @param anAction the action to handle - @return a target that can respond, or nil + @return a target that can respond, or \c nil if no match could be found */ - (id)targetForAction:(SEL)anAction @@ -756,7 +758,7 @@ var _CPRunModalLoop = function(anEvent) /*! Starts the GUI and Cappuccino frameworks. This function should be - called from the main() function of your program. + called from the \c main() function of your program. @class CPApplication @return void */ @@ -772,14 +774,18 @@ function CPApplicationMain(args, namedArgs) [principalClass sharedApplication]; //FIXME? - if (!args && !namedArgs) + if (!args) { - var args = [CPApp arguments], - searchParams = window.location.search.substring(1).split("&"); - namedArgs = [CPDictionary dictionary]; + var args = [CPApp arguments]; if([args containsObject:"debug"]) CPLogRegister(CPLogPopup); + } + + if (!namedArgs) + { + var searchParams = window.location.search.substring(1).split("&"); + namedArgs = [CPDictionary dictionary]; for(var i=0; iYES if the button has a 'mixed' state in addition to on and off. + Returns \c YES if the button has a 'mixed' state in addition to on and off. */ - (BOOL)allowsMixedState { @@ -248,9 +248,9 @@ CPButtonStateMixed = CPThemeState("mixed"); } /*! - Sets the button's state to aState. + Sets the button's state to \c aState. @param aState Possible states are any of the CPButton globals: - CPOffState, CPOnState, CPMixedState + \c CPOffState, \c CPOnState, \c CPMixedState */ - (void)setState:(CPInteger)aState { @@ -602,7 +602,7 @@ var CPButtonImageKey = @"CPButtonImageKey", @implementation CPButton (CPCoding) /*! - Initializes the button by unarchiving data from aCoder. + Initializes the button by unarchiving data from \c aCoder. @param aCoder the coder containing the archived CPButton. */ - (id)initWithCoder:(CPCoder)aCoder diff --git a/AppKit/CPClipView.j b/AppKit/CPClipView.j index 6349ed58e..cae93bd44 100644 --- a/AppKit/CPClipView.j +++ b/AppKit/CPClipView.j @@ -38,8 +38,8 @@ } /*! - Sets the document view to be aView. - @param aView the new document view. It's frame origin will be changed to (0,0) after calling this method. + Sets the document view to be \c aView. + @param aView the new document view. It's frame origin will be changed to \c (0,0) after calling this method. */ - (void)setDocumentView:(CPView)aView { @@ -95,7 +95,7 @@ } /*! - Returns a new point that may be adjusted from aPoint + Returns a new point that may be adjusted from \c aPoint to make sure it lies within the document view. @param aPoint @return the adjusted point @@ -128,7 +128,7 @@ /*! Scrolls the clip view to the specified point. The method - sets its bounds origin to aPoint. + sets its bounds origin to \c aPoint. */ - (void)scrollToPoint:(CGPoint)aPoint { diff --git a/AppKit/CPCollectionView.j b/AppKit/CPCollectionView.j index f8fe4f07f..b1f3952b8 100644 --- a/AppKit/CPCollectionView.j +++ b/AppKit/CPCollectionView.j @@ -122,7 +122,7 @@ } /*! - Sets the item prototype to anItem + Sets the item prototype to \c anItem @param anItem the new item prototype */ - (void)setItemPrototype:(CPCollectionViewItem)anItem @@ -143,7 +143,7 @@ } /*! - Returns a collection view item for anObject. + Returns a collection view item for \c anObject. @param anObject the object to be represented. */ - (CPCollectionViewItem)newItemForRepresentedObject:(id)anObject @@ -163,7 +163,7 @@ // Working with the Responder Chain /*! - Returns YES by default. + Returns \c YES by default. */ - (BOOL)acceptsFirstResponder { @@ -180,8 +180,8 @@ // Setting the Content /*! - Sets the content of the collection view to the content in anArray. - This array can be of any type, and each element will be passed to the setRepresentedObject: method. + Sets the content of the collection view to the content in \c anArray. + This array can be of any type, and each element will be passed to the \c -setRepresentedObject: method. It's the responsibility of your custom collection view item to interpret the object. @param anArray the content array */ @@ -214,7 +214,7 @@ // Setting the Selection Mode /*! Sets whether the user is allowed to select items - @param isSelectable YES allows the user to select items. + @param isSelectable \c YES allows the user to select items. */ - (void)setSelectable:(BOOL)isSelectable { @@ -233,8 +233,8 @@ } /*! - Returns YES if the collection view is - selected, and NO otherwise. + Returns \c YES if the collection view is + selected, and \c NO otherwise. */ - (BOOL)isSelected { @@ -243,7 +243,7 @@ /*! Sets whether the user may have no items selected. If YES, mouse clicks not on any item will empty the current selection. The first item will also start off as selected. - @param shouldAllowMultipleSelection YES allows the user to select multiple items + @param shouldAllowMultipleSelection \c YES allows the user to select multiple items */ - (void)setAllowsEmptySelection:(BOOL)shouldAllowEmptySelection { @@ -251,7 +251,7 @@ } /*! - Returns YES if the user can select no items, NO otherwise. + Returns \c YES if the user can select no items, \c NO otherwise. */ - (BOOL)allowsEmptySelection { @@ -260,7 +260,7 @@ /*! Sets whether the user can select multiple items. - @param shouldAllowMultipleSelection YES allows the user to select multiple items + @param shouldAllowMultipleSelection \c YES allows the user to select multiple items */ - (void)setAllowsMultipleSelection:(BOOL)shouldAllowMultipleSelection { @@ -268,7 +268,7 @@ } /*! - Returns YES if the user can select multiple items, NO otherwise. + Returns \c YES if the user can select multiple items, \c NO otherwise. */ - (BOOL)allowsMultipleSelection { @@ -684,7 +684,7 @@ // Modifying the Selection /*! Sets whether this view item should be selected. - @param shouldBeSelected YES makes the item selected. NO deselects it. + @param shouldBeSelected \c YES makes the item selected. \c NO deselects it. */ - (void)setSelected:(BOOL)shouldBeSelected { @@ -698,7 +698,7 @@ } /*! - Returns YES if the item is currently selected. NO if the item is not selected. + Returns \c YES if the item is currently selected. \c NO if the item is not selected. */ - (BOOL)isSelected { diff --git a/AppKit/CPColor.j b/AppKit/CPColor.j index 53342b37a..636f96a3f 100644 --- a/AppKit/CPColor.j +++ b/AppKit/CPColor.j @@ -58,13 +58,13 @@ var cachedBlackColor, @ingroup appkit @code CPColor - CPColor can be used to represent color + \c CPColor can be used to represent color in an RGB or HSB model with an optional transparency value.

    It also provides some class helper methods that returns instances of commonly used colors.

    -

    The class does not have a set: method +

    The class does not have a \c -set: method like NextStep based frameworks to change the color of the current context. To change the color of the current context, use CGContextSetFillColor(). @@ -117,7 +117,7 @@ var cachedBlackColor, /*! - Creates a new color object with white for the RGB components. + Creates a new color object with \c white for the RGB components. For the alpha component, a value of 1.0 is opaque, and 0.0 means completely transparent. @param white a float between 0.0 and 1.0 @@ -133,7 +133,7 @@ var cachedBlackColor, /*! @deprecated in favor of colorWithWhite:apha: - Creates a new color object with white for the RGB components. + Creates a new color object with \c white for the RGB components. For the alpha component, a value of 1.0 is opaque, and 0.0 means completely transparent. @param white a float between 0.0 and 1.0 @@ -386,7 +386,7 @@ var cachedBlackColor, } /*! - Creates a color using a tile pattern with anImage + Creates a color using a tile pattern with \c anImage @param the image to tile @return a tiled image color object */ @@ -736,7 +736,7 @@ var CPColorComponentsKey = @"CPColorComponentsKey", var hexCharacters = "0123456789ABCDEF"; /*! - Used for the CPColor colorWithHexString: implementation + Used for the CPColor \c +colorWithHexString: implementation @ignore @class CPColor @return an array of rgb components diff --git a/AppKit/CPColorPanel.j b/AppKit/CPColorPanel.j index b12829400..4c57cf99a 100644 --- a/AppKit/CPColorPanel.j +++ b/AppKit/CPColorPanel.j @@ -58,7 +58,7 @@ CPColorPickerViewHeight = 370; CPColorPanel provides a reusable panel that can be used displayed on screen to prompt the user for a color selection. To - obtain the panel, call the sharedColorPanel method. + obtain the panel, call the \c +sharedColorPanel method. */ @implementation CPColorPanel : CPPanel { @@ -111,7 +111,7 @@ CPColorPickerViewHeight = 370; } /* - To obtain the color panel, use sharedColorPanel. + To obtain the color panel, use \c +sharedColorPanel. @ignore */ - (id)init @@ -137,7 +137,7 @@ CPColorPickerViewHeight = 370; } /*! - Sets the color of the panel, and updates the picker. Also posts a CPColorPanelDidChangeNotification. + Sets the color of the panel, and updates the picker. Also posts a \c CPColorPanelDidChangeNotification. */ - (void)setColor:(CPColor)aColor { diff --git a/AppKit/CPColorPicker.j b/AppKit/CPColorPicker.j index eeb0e8c60..f8e89f334 100644 --- a/AppKit/CPColorPicker.j +++ b/AppKit/CPColorPicker.j @@ -27,7 +27,7 @@ @ingroup appkit @class CPColorPicker - CPColorPicker is an abstract superclass for all color picker subclasses. If you want a particular color picker, use CPColorPanel's setPickerMode: method. The simplest way to implement your own color picker is to create a subclass of CPColorPicker. + CPColorPicker is an abstract superclass for all color picker subclasses. If you want a particular color picker, use CPColorPanel's \c +setPickerMode: method. The simplest way to implement your own color picker is to create a subclass of CPColorPicker. */ @implementation CPColorPicker : CPObject { @@ -60,7 +60,7 @@ /* FIXME Not implemented. - @return nil + @return \c nil @ignore */ - (CPImage)provideNewButtonImage diff --git a/AppKit/CPColorWell.j b/AppKit/CPColorWell.j index 355f7c739..2c2586821 100644 --- a/AppKit/CPColorWell.j +++ b/AppKit/CPColorWell.j @@ -35,7 +35,7 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv CPColorWell is a CPControl for selecting and displaying a single color value. An example of a CPColorWell object (or simply color well) is found in CPColorPanel, which uses a color well to display the current color selection.

    -

    An application can have one or more active CPColorWells. You can activate multiple CPColorWells by invoking the activate: method with NO as its argument. When a mouse-down event occurs on an CPColorWell's border, it becomes the only active color well. When a color well becomes active, it brings up the color panel also. +

    An application can have one or more active CPColorWells. You can activate multiple CPColorWells by invoking the \c -activate: method with \c NO as its argument. When a mouse-down event occurs on an CPColorWell's border, it becomes the only active color well. When a color well becomes active, it brings up the color panel also. */ @implementation CPColorWell : CPControl { @@ -127,7 +127,7 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv } /*! - Changes the color of the well to that of aSender. + Changes the color of the well to that of \c aSender. @param aSender the object from which to retrieve the color */ - (void)takeColorFrom:(id)aSender @@ -138,7 +138,7 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv // Activating and Deactivating Color Wells /*! Activates the color well, displays the color panel, and makes the panel's current color the same as its own. - If exclusive is YES, deactivates any other CPColorWells. NO, keeps them active. + If exclusive is \c YES, deactivates any other CPColorWells. \c NO, keeps them active. @param shouldBeExclusive whether other color wells should be deactivated. */ - (void)activate:(BOOL)shouldBeExclusive @@ -179,7 +179,7 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv } /*! - Returns YES if the color well is active. + Returns \c YES if the color well is active. */ - (BOOL)isActive { @@ -262,7 +262,7 @@ var CPColorWellColorKey = "CPColorWellColorKey", @implementation CPColorWell (CPCoding) /*! - Initializes the color well by unarchiving data from aCoder. + Initializes the color well by unarchiving data from \c aCoder. @param aCoder the coder containing the archived CPColorWell. */ - (id)initWithCoder:(CPCoder)aCoder diff --git a/AppKit/CPControl.j b/AppKit/CPControl.j index 4151688f4..27882991a 100644 --- a/AppKit/CPControl.j +++ b/AppKit/CPControl.j @@ -178,7 +178,7 @@ var CPControlBlackColor = [CPColor blackColor]; } /*! - Causes anAction to be sent to anObject. + Causes \c anAction to be sent to \c anObject. @param anAction the action to send @param anObject the object to which the action will be sent */ diff --git a/AppKit/CPCookie.j b/AppKit/CPCookie.j index 2be313551..5a5694a94 100644 --- a/AppKit/CPCookie.j +++ b/AppKit/CPCookie.j @@ -38,7 +38,7 @@ } /*! - Initializes a cookie with a given name aName. + Initializes a cookie with a given name \c aName. @param the name for the cookie */ - (id)initWithName:(CPString)aName diff --git a/AppKit/CPDocument.j b/AppKit/CPDocument.j index b39506c37..32e0bd185 100644 --- a/AppKit/CPDocument.j +++ b/AppKit/CPDocument.j @@ -90,7 +90,9 @@ var CPDocumentUntitledCount = 0; CPDocuments should be used to represent this. */ @implementation CPDocument : CPResponder -{ +{ + CPWindow _window; // For outlet purposes. + CPURL _fileURL; CPString _fileType; CPArray _windowControllers; @@ -174,8 +176,8 @@ var CPDocumentUntitledCount = 0; @param absoluteContentsURL the location of the document's contents @param aType the type of the contents @param aDelegate this object will receive a callback after the document's contents are loaded - @param aDidReadSelector the message selector that will be sent to aDelegate - @param aContextInfo passed as the argument to the message sent to the aDelegate + @param aDidReadSelector the message selector that will be sent to \c aDelegate + @param aContextInfo passed as the argument to the message sent to the \c aDelegate @return the initialized document */ - (id)initForURL:(CPURL)anAbsoluteURL withContentsOfURL:(CPURL)absoluteContentsURL ofType:(CPString)aType delegate:(id)aDelegate didReadSelector:(SEL)aDidReadSelector contextInfo:(id)aContextInfo @@ -228,9 +230,10 @@ var CPDocumentUntitledCount = 0; */ - (void)makeWindowControllers { - var controller = [[CPWindowController alloc] initWithWindowCibName:nil]; - - [self addWindowController:controller]; + var windowCibName = [self windowCibName]; + + if (windowCibName) + [self addWindowController:[[CPWindowController alloc] initWithWindowCibName:windowCibName owner:self]]; } /*! @@ -250,7 +253,7 @@ var CPDocumentUntitledCount = 0; { [_windowControllers addObject:aWindowController]; - if ([aWindowController document] != self) + if ([aWindowController document] !== self) { [aWindowController setNextResponder:self]; [aWindowController setDocument:self]; @@ -292,18 +295,18 @@ var CPDocumentUntitledCount = 0; } /*! - Called after aWindowController loads the document's Nib file. + Called after \c aWindowController loads the document's Nib file. @param aWindowController the controller that loaded the Nib file */ -- (void)windowControllerDidLoadNib:(CPWindowController)aWindowController +- (void)windowControllerDidLoadCib:(CPWindowController)aWindowController { } /*! - Called before aWindowController will load the document's Nib file. + Called before \c aWindowController will load the document's Nib file. @param aWindowController the controller that will load the Nib file */ -- (void)windowControllerWillLoadNib:(CPWindowController)aWindowController +- (void)windowControllerWillLoadCib:(CPWindowController)aWindowController { } @@ -502,7 +505,7 @@ var CPDocumentUntitledCount = 0; // Managing Document Status /*! - Returns YES if there are any unsaved changes. + Returns \c YES if there are any unsaved changes. */ - (BOOL)isDocumentEdited { @@ -548,7 +551,7 @@ var CPDocumentUntitledCount = 0; // Working with Undo Manager /*! - Returns YES if the document has a + Returns \c YES if the document has a CPUndoManager. */ - (BOOL)hasUndoManager @@ -558,7 +561,7 @@ var CPDocumentUntitledCount = 0; /*! Sets whether the document should have a CPUndoManager. - @param aFlag YES makes the document have an undo manager + @param aFlag \c YES makes the document have an undo manager */ - (void)setHasUndoManager:(BOOL)aFlag { @@ -642,7 +645,7 @@ var CPDocumentUntitledCount = 0; /*! Returns the document's undo manager. If the document - should have one, but the manager is nil, it + should have one, but the manager is \c nil, it will be created and then returned. @return the document's undo manager */ @@ -666,8 +669,8 @@ var CPDocumentUntitledCount = 0; // Handling User Actions /*! Saves the document. If the document does not - have a file path to save to (fileURL) - then saveDocumentAs: will be called. + have a file path to save to (\c fileURL) + then \c -saveDocumentAs: will be called. @param aSender the object requesting the save */ - (void)saveDocument:(id)aSender diff --git a/AppKit/CPDocumentController.j b/AppKit/CPDocumentController.j index 0dff57fad..4a8f83724 100644 --- a/AppKit/CPDocumentController.j +++ b/AppKit/CPDocumentController.j @@ -78,7 +78,7 @@ var CPSharedDocumentController = nil; method searches documents already open. It does not open the document at the URL if it is not already open. @param aURL the url of the document - @return the document, or nil if such a document is not open + @return the document, or \c nil if such a document is not open */ - (CPDocument)documentForURL:(CPURL)aURL { @@ -157,7 +157,7 @@ var CPSharedDocumentController = nil; @param anAbsoluteURL the document URL @param absoluteContentsURL the location of the document's contents @param anError not used - @return the loaded document or nil if there was an error + @return the loaded document or \c nil if there was an error */ - (CPDocument)reopenDocumentForURL:(CPURL)anAbsoluteURL withContentsOfURL:(CPURL)absoluteContentsURL error:(CPError)anError { @@ -187,7 +187,7 @@ var CPSharedDocumentController = nil; @param aDelegate receives a callback after the load has completed @param aSelector the selector to invoke for the callback @param aContextInfo an object passed as an argument for the callback - @return a new document or nil if there was an error + @return a new document or \c nil if there was an error */ - (CPDocument)makeDocumentForURL:(CPURL)anAbsoluteURL withContentsOfURL:(CPURL)absoluteContentsURL ofType:(CPString)aType delegate:(id)aDelegate didReadSelector:(SEL)aSelector contextInfo:(id)aContextInfo { @@ -231,7 +231,7 @@ var CPSharedDocumentController = nil; } /*! - Adds aDocument under the control of the receiver. + Adds \c aDocument under the control of the receiver. @param aDocument the document to add */ - (void)addDocument:(CPDocument)aDocument @@ -240,7 +240,7 @@ var CPSharedDocumentController = nil; } /*! - Removes aDocument from the control of the receiver. + Removes \c aDocument from the control of the receiver. @param aDocument the document to remove */ - (void)removeDocument:(CPDocument)aDocument @@ -296,9 +296,9 @@ var CPSharedDocumentController = nil; } /*! - Returns the CPDocument subclass associated with aType. + Returns the CPDocument subclass associated with \c aType. @param aType the type of document - @return a Cappuccino Class object, or nil if no match was found + @return a Cappuccino Class object, or \c nil if no match was found */ - (Class)documentClassForType:(CPString)aType { diff --git a/AppKit/CPDragServer.j b/AppKit/CPDragServer.j index f39524a61..a341ddc90 100644 --- a/AppKit/CPDragServer.j +++ b/AppKit/CPDragServer.j @@ -26,6 +26,7 @@ @import #import "CoreGraphics/CGGeometry.h" +#import "Platform/Platform.h" #define DRAGGING_WINDOW(anObject) ([anObject isKindOfClass:[CPWindow class]] ? anObject : [anObject window]) @@ -111,7 +112,7 @@ var CPDragServerUpdateDragging = function(anEvent) bridgeLocation = [[anEvent window] convertBaseToBridge:location]; // We have to convert base to bridge since the drag event comes from the source window, not the drag window. - var draggingDestination = [[CPDOMWindowBridge sharedDOMWindowBridge] _dragHitTest:bridgeLocation pasteboard:CPDragServerPasteboard]; + var draggingDestination = [[CPPlatformWindow primaryPlatformWindow] _dragHitTest:bridgeLocation pasteboard:CPDragServerPasteboard]; CPDragServerLocation = [DRAGGING_WINDOW(draggingDestination) convertBridgeToBase:bridgeLocation]; @@ -235,20 +236,27 @@ var CPDragServerUpdateDragging = function(anEvent) @param anEvent @param aPasteboard the pasteboard that contains the drag data @param aSourceObject the object where the drag started - @param slideBack if YES, aView slides back to + @param slideBack if \c YES, \c aView slides back to its origin on a failed drop */ - (void)dragView:(CPView)aView fromWindow:(CPWindow)aWindow at:(CGPoint)viewLocation offset:(CGSize)mouseOffset event:(CPEvent)anEvent pasteboard:(CPPasteboard)aPasteboard source:(id)aSourceObject slideBack:(BOOL)slideBack { var eventLocation = [anEvent locationInWindow]; - + CPDragServerView = aView; CPDragServerSource = aSourceObject; CPDragServerWindow = aWindow; CPDragServerOffset = CPPointMake(eventLocation.x - viewLocation.x, eventLocation.y - viewLocation.y); CPDragServerPasteboard = [CPPasteboard pasteboardWithName:CPDragPboard];//aPasteboard; - [_dragWindow setFrameSize:CGSizeMakeCopy([[CPDOMWindowBridge sharedDOMWindowBridge] frame].size)]; +#if PLATFORM(BROWSER) + var platformWindow = [aWindow platformWindow]; + + // FIXME: We should just have the window be the size of the view and move the window around. + [_dragWindow setPlatformWindow:platformWindow]; + [_dragWindow setFrameSize:[platformWindow contentBounds].size]; +#endif + [_dragWindow orderFront:self]; [aView setFrameOrigin:viewLocation]; @@ -290,7 +298,7 @@ var CPDragServerUpdateDragging = function(anEvent) @param anEvent @param aPasteboard the pasteboard where the drag data is located @param aSourceObject the object where the drag started - @param slideBack if YES, aView slides back to + @param slideBack if \c YES, \c aView slides back to its origin on a failed drop */ - (void)dragImage:(CPImage)anImage fromWindow:(CPWindow)aWindow at:(CGPoint)imageLocation offset:(CGSize)mouseOffset event:(CPEvent)anEvent pasteboard:(CPPasteboard)aPasteboard source:(id)aSourceObject slideBack:(BOOL)slideBack @@ -318,7 +326,7 @@ var CPDragServerUpdateDragging = function(anEvent) return nil; // We don't need to do this because the only place this gets called -// -_dragHitTest: in CPDOMWindowBridge does this already. Perhaps to +// -_dragHitTest: in CPPlatformWindow does this already. Perhaps to // be safe? // if (![self containsPoint:aPoint]) // return nil; diff --git a/AppKit/CPEvent.j b/AppKit/CPEvent.j index 5a5cf2a75..37ba58358 100644 --- a/AppKit/CPEvent.j +++ b/AppKit/CPEvent.j @@ -221,16 +221,16 @@ var _CPEventPeriodicEventPeriod = 0, /*! Creates a new keyboard event. @param anEventType the event type. Must be one of CPKeyDown, CPKeyUp or CPFlagsChanged - @param aPoint the location of the cursor in the window specified by aWindowNumber + @param aPoint the location of the cursor in the window specified by \c aWindowNumber @param modifierFlags a bitwise combination of the modifiers specified in the CPEvent globals @param aTimestamp the time the event occurred @param aWindowNumber the number of the CPWindow where the event occurred @param aGraphicsContext the graphics context where the event occurred @param characters the characters associated with the event @param unmodCharacters the string of keys pressed without the presence of any modifiers other than Shift - @param repeatKey YES if this is caused by the system repeat as opposed to the user pressing the key again + @param repeatKey \c YES if this is caused by the system repeat as opposed to the user pressing the key again @param code a number associated with the keyboard key of this event - @throws CPInternalInconsistencyException if anEventType is not a CPKeyDown, + @throws CPInternalInconsistencyException if \c anEventType is not a CPKeyDown, CPKeyUp or CPFlagsChanged @return the keyboard event */ @@ -246,7 +246,7 @@ var _CPEventPeriodicEventPeriod = 0, /*! Creates a new mouse event @param anEventType the event type - @param aPoint the location of the cursor in the window specified by aWindowNumber + @param aPoint the location of the cursor in the window specified by \c aWindowNumber @param modifierFlags a bitwise combination of the modifiers specified in the CPEvent globals @param aTimestamp the time the event occurred @param aWindowNumber the number of the CPWindow where the event occurred @@ -268,7 +268,7 @@ var _CPEventPeriodicEventPeriod = 0, /*! Creates a new custom event @param anEventType the event type. Must be one of CPAppKitDefined, CPSystemDefined, CPApplicationDefined or CPPeriodic - @param aLocation the location of the cursor in the window specified by aWindowNumber + @param aLocation the location of the cursor in the window specified by \c aWindowNumber @param modifierFlags a bitwise combination of the modifiers specified in the CPEvent globals @param aTimestamp the time the event occurred @param aWindowNumber the number of the CPWindow where the event occurred @@ -358,15 +358,15 @@ var _CPEventPeriodicEventPeriod = 0, /*! Returns the location of the mouse (for mouse events). - If this is not a mouse event, it returns nil. - If window returns nil, then + If this is not a mouse event, it returns \c nil. + If \c window returns \c nil, then the mouse coordinates will be based on the screen coordinates. Otherwise, the coordinates are relative to the window's coordinates. - @return the location of the mouse, or nil for non-mouse events. + @return the location of the mouse, or \c nil for non-mouse events. */ - (CGPoint)locationInWindow { - return _location; + return _CGPointMakeCopy(_location); } /*! @@ -448,7 +448,7 @@ var _CPEventPeriodicEventPeriod = 0, } /*! - Returns YES if the keyboard event was caused by the key being held down. + Returns \c YES if the keyboard event was caused by the key being held down. @throws CPInternalInconsistencyException if this method is called on a non-key event */ - (BOOL)isARepeat @@ -504,7 +504,7 @@ var _CPEventPeriodicEventPeriod = 0, } /*! - Generates periodic events every aPeriod seconds. + Generates periodic events every \c aPeriod seconds. @param aDelay the number of seconds before the first event @param aPeriod the length of time in seconds between successive events */ diff --git a/AppKit/CPFlashMovie.j b/AppKit/CPFlashMovie.j index ef6298fc6..b666c2391 100644 --- a/AppKit/CPFlashMovie.j +++ b/AppKit/CPFlashMovie.j @@ -34,7 +34,7 @@ } /*! - Creates a new Flash movie with the swf at aFileName. + Creates a new Flash movie with the swf at \c aFileName. @param aFilename the swf to load @return the initialized CPFlashMovie */ diff --git a/AppKit/CPFlashView.j b/AppKit/CPFlashView.j index 874614b7a..5d3f983a4 100644 --- a/AppKit/CPFlashView.j +++ b/AppKit/CPFlashView.j @@ -20,10 +20,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -@import "CPDOMWindowBridge.j" @import "CPFlashMovie.j" @import "CPView.j" + /*! @ingroup appkit */ @@ -96,17 +96,17 @@ - (void)mouseDragged:(CPEvent)anEvent { - [[CPDOMWindowBridge sharedDOMWindowBridge] _propagateCurrentDOMEvent:YES]; + [[[self window] platformWindow] _propagateCurrentDOMEvent:YES]; } - (void)mouseDown:(CPEvent)anEvent { - [[CPDOMWindowBridge sharedDOMWindowBridge] _propagateCurrentDOMEvent:YES]; + [[[self window] platformWindow] _propagateCurrentDOMEvent:YES]; } - (void)mouseUp:(CPEvent)anEvent { - [[CPDOMWindowBridge sharedDOMWindowBridge] _propagateCurrentDOMEvent:YES]; + [[[self window] platformWindow] _propagateCurrentDOMEvent:YES]; } @end diff --git a/AppKit/CPGeometry.j b/AppKit/CPGeometry.j index c49ec1e4d..c7d190afb 100644 --- a/AppKit/CPGeometry.j +++ b/AppKit/CPGeometry.j @@ -62,11 +62,11 @@ function CPPointMake(x, y) } /*! - Makes a CGRect with an origin and size equal to aRect less the dX/dY insets specified. + Makes a CGRect with an origin and size equal to \c aRect less the \c dX/dY insets specified. @param dX the size of the inset in the x-axis @param dY the size of the inset in the y-axis @group CGRect - @return CGRect a rectangle like aRect with an inset + @return CGRect a rectangle like \c aRect with an inset */ function CPRectInset(aRect, dX, dY) { @@ -132,7 +132,7 @@ function CPRectMake(x, y, width, height) } /*! - Creates a new rectangle with its origin offset by dX and dY. + Creates a new rectangle with its origin offset by \c dX and \c dY. @group CGRect @param aRect the rectangle to copy the origin and size from @param dX the amount added to the x-size of the new rectangle @@ -171,7 +171,7 @@ function CPRectStandardize(aRect) } /*! - Returns the smallest rectangle that can contain the two argument CGRects. + Returns the smallest rectangle that can contain the two argument \c CGRects. @group CGRect @param lhsRect the first CGRect to use for the union calculation @param rhsRect the second CGRect to use for the union calculation @@ -211,12 +211,12 @@ function CPSizeMake(width, height) } /*! - Returns YES if the CGRect, aRect, contains - the CGPoint, aPoint. + Returns \c YES if the CGRect, \c aRect, contains + the CGPoint, \c aPoint. @param aRect the rectangle to test with @param aPoint the point to test with @group CGRect - @return BOOL YES if the rectangle contains the point, NO otherwise. + @return BOOL \c YES if the rectangle contains the point, \c NO otherwise. */ function CPRectContainsPoint(aRect, aPoint) { @@ -227,12 +227,12 @@ function CPRectContainsPoint(aRect, aPoint) } /*! - Returns a BOOL indicating whether CGRect possibleOuter - contains CGRect possibleInner. + Returns a \c BOOL indicating whether CGRect \c possibleOuter + contains CGRect \c possibleInner. @group CGRect - @param possibleOuter the CGRect to test if possibleInner is inside of - @param possibleInner the CGRect to test if it fits inside possibleOuter. - @return BOOL YES if possibleInner fits inside possibleOuter. + @param possibleOuter the CGRect to test if \c possibleInner is inside of + @param possibleInner the CGRect to test if it fits inside \c possibleOuter. + @return BOOL \c YES if \c possibleInner fits inside \c possibleOuter. */ function CPRectContainsRect(lhsRect, rhsRect) { @@ -241,11 +241,11 @@ function CPRectContainsRect(lhsRect, rhsRect) /*! Tests whether the two CGPoints are equal to each other by comparing their - x and y members. + \c x and \c y members. @group @CGPoint @param lhsPoint the first CGPoint to check @param rhsPoint the second CGPoint to check - @return BOOL YES if the two points have the same x's, and the same y's. + @return BOOL \c YES if the two points have the same x's, and the same y's. */ function CPPointEqualToPoint(lhsPoint, rhsPoint) { @@ -257,7 +257,7 @@ function CPPointEqualToPoint(lhsPoint, rhsPoint) @group CGRect @param lhsRect the first CGRect to compare @param rhsRect the second CGRect to compare - @return BOOL YES if the two rectangles have the same origin and size. NO, otherwise. + @return BOOL \c YES if the two rectangles have the same origin and size. \c NO, otherwise. */ function CPRectEqualToRect(lhsRect, rhsRect) { @@ -346,11 +346,11 @@ function CPRectGetWidth(aRect) } /*! - Returns YES if the two rectangles intersect + Returns \c YES if the two rectangles intersect @group CGRect @param lhsRect the first CGRect @param rhsRect the second CGRect - @return BOOL YES if the two rectangles have any common spaces, and NO, otherwise. + @return BOOL \c YES if the two rectangles have any common spaces, and \c NO, otherwise. */ function CPRectIntersectsRect(lhsRect, rhsRect) { @@ -358,11 +358,11 @@ function CPRectIntersectsRect(lhsRect, rhsRect) } /*! - Returns YES if the CGRect has no area. + Returns \c YES if the CGRect has no area. The test is performed by checking if the width and height are both zero. @group CGRect @param aRect the CGRect to test - @return BOOL YES if the CGRect has no area, and NO, otherwise. + @return BOOL \c YES if the CGRect has no area, and \c NO, otherwise. */ function CPRectIsEmpty(aRect) { @@ -370,10 +370,10 @@ function CPRectIsEmpty(aRect) } /*! - Returns YES if the CGRect has no area. + Returns \c YES if the CGRect has no area. The test is performed by checking if the width and height are both zero. @group CGRect - @return BOOL YES if the CGRect has no area, and NO, otherwise. + @return BOOL \c YES if the CGRect has no area, and \c NO, otherwise. */ function CPRectIsNull(aRect) { @@ -381,11 +381,11 @@ function CPRectIsNull(aRect) } /*! - Returns YES if the two CGSizes are identical. + Returns \c YES if the two CGSizes are identical. @group CGSize @param lhsSize the first CGSize to compare @param rhsSize the second CGSize to compare - @return BOOL YES if the two sizes are identical. NO, otherwise. + @return BOOL \c YES if the two sizes are identical. \c NO, otherwise. */ function CPSizeEqualToSize(lhsSize, rhsSize) { @@ -454,7 +454,7 @@ function CPSizeFromString(aString) /*! Returns a CGRect created from a string. @group CGRect - @param aString a string in the form generated by CPStringFromRect + @param aString a string in the form generated by \c CPStringFromRect @return CGRect the rectangle created from the string */ function CPRectFromString(aString) @@ -477,7 +477,7 @@ function CPPointFromEvent(anEvent) /*! Returns a zero sized CGSize. @group CGSize - @return CGSize a size object with zeros for width and height + @return CGSize a size object with zeros for \c width and \c height */ function CPSizeMakeZero() { @@ -485,7 +485,7 @@ function CPSizeMakeZero() } /*! - Returns a rectangle at origin (0,0) and size of (0,0). + Returns a rectangle at origin \c (0,0) and size of \c (0,0). @group CGRect @return CGRect a zeroed out CGRect */ @@ -495,9 +495,9 @@ function CPRectMakeZero() } /*! - Returns a point located at (0, 0). + Returns a point located at \c (0, 0). @group CGPoint - @return CGPoint a point located at (0, 0) + @return CGPoint a point located at \c (0, 0) */ function CPPointMakeZero() { diff --git a/AppKit/CPImage.j b/AppKit/CPImage.j index 4962912bf..e42bf35b1 100644 --- a/AppKit/CPImage.j +++ b/AppKit/CPImage.j @@ -92,7 +92,7 @@ function CPImageInBundle(aFilename, aSize, aBundle) /*! Initializes the image, by associating it with a filename. The image - denoted in aFilename is not actually loaded. It will + denoted in \c aFilename is not actually loaded. It will be loaded once needed. @param aFilename the file containing the image @param aSize the image's size @@ -187,9 +187,9 @@ function CPImageInBundle(aFilename, aSize, aBundle) } /*! - Returns YES if the image data has already been loaded. + Returns the load status, which will be CPImageLoadStatusCompleted if the image data has already been loaded. */ -- (BOOL)loadStatus +- (unsigned)loadStatus { return _loadStatus; } diff --git a/AppKit/CPImageView.j b/AppKit/CPImageView.j index c8657562f..c75187073 100644 --- a/AppKit/CPImageView.j +++ b/AppKit/CPImageView.j @@ -161,8 +161,8 @@ var LEFT_SHADOW_INSET = 3.0, } /*! - Returns YES if the image view draws with - a drop shadow. The default is NO. + Returns \c YES if the image view draws with + a drop shadow. The default is \c NO. */ - (BOOL)hasShadow { diff --git a/AppKit/CPMenu.j b/AppKit/CPMenu.j index 79ca0e9d2..35c39fa1b 100644 --- a/AppKit/CPMenu.j +++ b/AppKit/CPMenu.j @@ -119,7 +119,7 @@ var _CPMenuBarVisible = NO, // FIXME: There must be a better way to do this. #if PLATFORM(DOM) - [[CPDOMWindowBridge sharedDOMWindowBridge] _bridgeResizeEvent:nil]; + [[CPPlatformWindow primaryPlatformWindow] resizeEvent:nil]; #endif } @@ -369,7 +369,7 @@ var _CPMenuBarVisible = NO, /*! Returns the menu item with the specified tag @param the tag of the desired menu item - @return the menu item or nil if a match was not found + @return the menu item or \c nil if a match was not found */ - (CPMenuItem)menuWithTag:(int)aTag { @@ -384,7 +384,7 @@ var _CPMenuBarVisible = NO, /*! Returns the menu item with the specified title. @param aTitle the title of the menu item - @return the menu item or nil if a match was not found + @return the menu item or \c nil if a match was not found */ - (CPMenuItem)menuWithTitle:(CPString)aTitle { @@ -551,7 +551,7 @@ var _CPMenuBarVisible = NO, } /*! - Returns the attaced menu, or nil if there isn't one. + Returns the attaced menu, or \c nil if there isn't one. */ - (CPMenu)attachedMenu { @@ -559,7 +559,7 @@ var _CPMenuBarVisible = NO, } /*! - Returns YES if the menu is attached to another menu. + Returns \c YES if the menu is attached to another menu. */ - (BOOL)isAttached { @@ -575,7 +575,7 @@ var _CPMenuBarVisible = NO, } /*! - Returns the super menu or nil if there is none. + Returns the super menu or \c nil if there is none. */ - (CPMenu)supermenu { @@ -592,8 +592,8 @@ var _CPMenuBarVisible = NO, } /*! - If there are two instances of this menu visible, return NO. - Otherwise, return YES if we are a detached menu and visible. + If there are two instances of this menu visible, return \c NO. + Otherwise, return \c YES if we are a detached menu and visible. */ - (BOOL)isTornOff { @@ -603,7 +603,7 @@ var _CPMenuBarVisible = NO, // Enabling and Disabling Menu Items /*! Sets whether the menu automatically enables menu items. - @param aFlag YES sets the menu to automatically enable items. + @param aFlag \c YES sets the menu to automatically enable items. */ - (void)setAutoenablesItems:(BOOL)aFlag { @@ -611,7 +611,7 @@ var _CPMenuBarVisible = NO, } /*! - Returns YES if the menu auto enables items. + Returns \c YES if the menu auto enables items. */ - (BOOL)autoenablesItems { @@ -691,7 +691,7 @@ var _CPMenuBarVisible = NO, // Managing Display of State Column /*! Sets whether to show the state column - @param shouldShowStateColumn YES shows the state column + @param shouldShowStateColumn \c YES shows the state column */ - (void)setShowsStateColumn:(BOOL)shouldShowStateColumn { @@ -699,7 +699,7 @@ var _CPMenuBarVisible = NO, } /*! - Returns YES if the menu shows the state column + Returns \c YES if the menu shows the state column */ - (BOOL)showsStateColumn { @@ -709,7 +709,7 @@ var _CPMenuBarVisible = NO, // Handling Highlighting /*! Returns the currently highlighted menu item. - @return the highlighted menu item or nil if no item is currently highlighted + @return the highlighted menu item or \c nil if no item is currently highlighted */ - (CPMenuItem)highlightedItem { @@ -745,9 +745,9 @@ var _CPMenuBarVisible = NO, /*! Initiates the action of the menu item that - has a keyboard shortcut equivalent to anEvent + has a keyboard shortcut equivalent to \c anEvent @param anEvent the keyboard event - @return YES if it was handled. + @return \c YES if it was handled. */ - (BOOL)performKeyEquivalent:(CPEvent)anEvent { @@ -1078,7 +1078,7 @@ var STICKY_TIME_INTERVAL = 500, { _unconstrainedFrame = CGRectMakeCopy([self frame]); - var screenBounds = CGRectInset([[CPDOMWindowBridge sharedDOMWindowBridge] contentBounds], 5.0, 5.0), + var screenBounds = CGRectInset([[self platformWindow] contentBounds], 5.0, 5.0), constrainedFrame = CGRectIntersection(_unconstrainedFrame, screenBounds), menuViewOrigin = [self convertBaseToBridge:CGPointMake(LEFT_MARGIN, TOP_MARGIN)]; @@ -1158,7 +1158,7 @@ var STICKY_TIME_INTERVAL = 500, if (type == CPPeriodic) { - var constrainedBounds = CGRectInset([[CPDOMWindowBridge sharedDOMWindowBridge] contentBounds], 5.0, 5.0); + var constrainedBounds = CGRectInset([[self platformWindow] contentBounds], 5.0, 5.0); if (_scrollingState == _CPMenuWindowScrollingStateUp) { @@ -1447,9 +1447,9 @@ var _CPMenuBarWindowBackgroundColor = nil, - (id)init { - var bridgeWidth = CGRectGetWidth([[CPDOMWindowBridge sharedDOMWindowBridge] contentBounds]); + var platformWindowWidth = CGRectGetWidth([[CPPlatformWindow primaryPlatformWindow] contentBounds]); - self = [super initWithContentRect:CGRectMake(0.0, 0.0, bridgeWidth, MENUBAR_HEIGHT) styleMask:CPBorderlessWindowMask]; + self = [super initWithContentRect:CGRectMake(0.0, 0.0, platformWindowWidth, MENUBAR_HEIGHT) styleMask:CPBorderlessWindowMask]; if (self) { diff --git a/AppKit/CPMenuItem.j b/AppKit/CPMenuItem.j index 401000872..b738729ed 100644 --- a/AppKit/CPMenuItem.j +++ b/AppKit/CPMenuItem.j @@ -113,7 +113,7 @@ // Enabling a Menu Item /*! Sets whether the menu item is enabled or not - @param isEnabled YES enables the item. NO disables it. + @param isEnabled \c YES enables the item. \c NO disables it. */ - (void)setEnabled:(BOOL)isEnabled { @@ -128,7 +128,7 @@ } /*! - Returns YES if the item is enabled. + Returns \c YES if the item is enabled. */ - (BOOL)isEnabled { @@ -138,7 +138,7 @@ // Managing Hidden Status /*! Sets whether the item should be hidden. A hidden item can not be triggered by keyboard shortcuts. - @param isHidden YES hides the item. NO reveals it. + @param isHidden \c YES hides the item. \c NO reveals it. */ - (void)setHidden:(BOOL)isHidden { @@ -151,7 +151,7 @@ } /*! - Returns YES if the item is hidden. + Returns \c YES if the item is hidden. */ - (BOOL)isHidden { @@ -159,7 +159,7 @@ } /*! - Returns YES if the item is hidden or if one of it's supermenus is hidden. + Returns \c YES if the item is hidden or if one of it's supermenus is hidden. */ - (BOOL)isHiddenOrHasHiddenAncestor { @@ -461,7 +461,7 @@ CPOffState } /*! - Returns the submenu of the item. nil if there is no submenu. + Returns the submenu of the item. \c nil if there is no submenu. */ - (CPMenu)submenu { @@ -469,7 +469,7 @@ CPOffState } /*! - Returns YES if the menu item has a submenu. + Returns \c YES if the menu item has a submenu. */ - (BOOL)hasSubmenu { @@ -491,7 +491,7 @@ CPOffState } /*! - Returns YES if the menu item is a separator. + Returns \c YES if the menu item is a separator. */ - (BOOL)isSeparatorItem { @@ -613,7 +613,7 @@ CPControlKeyMask /*! Sets whether this item is an alternate for the previous menu item. - @param isAlternate YES denotes that this menu item is an alternate + @param isAlternate \c YES denotes that this menu item is an alternate */ - (void)setAlternate:(BOOL)isAlternate { @@ -621,7 +621,7 @@ CPControlKeyMask } /*! - Returns YES if the menu item is an alternate for the previous item. + Returns \c YES if the menu item is an alternate for the previous item. */ - (BOOL)isAlternate { @@ -717,7 +717,7 @@ CPControlKeyMask // Getting Highlighted Status /*! - Returns YES if the menu item is highlighted. + Returns \c YES if the menu item is highlighted. */ - (BOOL)isHighlighted { diff --git a/AppKit/CPPanel.j b/AppKit/CPPanel.j index bcff72814..65dc9b177 100644 --- a/AppKit/CPPanel.j +++ b/AppKit/CPPanel.j @@ -53,7 +53,7 @@ CPCancelButton = 0; } /*! - Returns YES if the receiver is a floating panel (like a palette). + Returns \c YES if the receiver is a floating panel (like a palette). */ - (BOOL)isFloatingPanel { @@ -61,8 +61,8 @@ CPCancelButton = 0; } /*! - Sets the receiver to be a floating panel. YES - makes the window a floating panel. NO makes it a normal window. + Sets the receiver to be a floating panel. \c YES + makes the window a floating panel. \c NO makes it a normal window. @param isFloatingPanel specifies whether to make it floating */ - (void)setFloatingPanel:(BOOL)isFloatingPanel @@ -71,8 +71,8 @@ CPCancelButton = 0; } /*! - Returns YES if the window only becomes key - if needed. NO means it behaves just like other windows. + Returns \c YES if the window only becomes key + if needed. \c NO means it behaves just like other windows. */ - (BOOL)becomesKeyOnlyIfNeeded { @@ -81,7 +81,7 @@ CPCancelButton = 0; /*! Sets whether the the window becomes key only if needed. - @param shouldBecomeKeyOnlyIfNeeded YES makes the window become key only if needed + @param shouldBecomeKeyOnlyIfNeeded \c YES makes the window become key only if needed */ - (void)setBecomesKeyOnlyIfNeeded:(BOOL)shouldBecomeKeyOnlyIfNeeded { diff --git a/AppKit/CPPasteboard.j b/AppKit/CPPasteboard.j index 31ba69299..f74711361 100644 --- a/AppKit/CPPasteboard.j +++ b/AppKit/CPPasteboard.j @@ -173,7 +173,7 @@ var CPPasteboards = nil; Sets the pasteboard data for the specified type @param aData the data @param aType the data type being set - @return YES if the data was successfully written to the pasteboard + @return \c YES if the data was successfully written to the pasteboard */ - (BOOL)setData:(CPData)aData forType:(CPString)aType { @@ -186,7 +186,7 @@ var CPPasteboards = nil; Writes the specified property list as data for the specified type @param aPropertyList the property list to write @param aType the data type - @return YES if the property list was successfully written to the pasteboard + @return \c YES if the property list was successfully written to the pasteboard */ - (BOOL)setPropertyList:(id)aPropertyList forType:(CPString)aType { @@ -197,7 +197,7 @@ var CPPasteboards = nil; Sets the specified string as data for the specified type @param aString the string to write @param aType the data type - @return YES if the string was successfully written to the pasteboard + @return \c YES if the string was successfully written to the pasteboard */ - (void)setString:(CPString)aString forType:(CPString)aType { @@ -209,7 +209,7 @@ var CPPasteboards = nil; Checks the pasteboard's types for a match with the types listen in the specified array. The array should be ordered by the requestor's most preferred data type first. @param anArray an array of requested types ordered by preference - @return the highest match with the pasteboard's supported types or nil if no match was found + @return the highest match with the pasteboard's supported types or \c nil if no match was found */ - (CPString)availableTypeFromArray:(CPArray)anArray { @@ -236,7 +236,7 @@ var CPPasteboards = nil; /*! Returns the pasteboard data for the specified data type @param aType the requested data type - @return the requested data or nil if the data doesn't exist + @return the requested data or \c nil if the data doesn't exist */ - (CPData)dataForType:(CPString)aType { @@ -262,7 +262,7 @@ var CPPasteboards = nil; /*! Returns the property list for the specified data type @param aType the requested data type - @return the property list or nil if the list was not found + @return the property list or \c nil if the list was not found */ - (id)propertyListForType:(CPString)aType { @@ -277,7 +277,7 @@ var CPPasteboards = nil; /*! Returns the string for the specified data type @param aType the requested data type - @return the string or nil if the string was not found + @return the string or \c nil if the string was not found */ - (CPString)stringForType:(CPString)aType { diff --git a/AppKit/CPPopUpButton.j b/AppKit/CPPopUpButton.j index acaecb870..b3776fd77 100644 --- a/AppKit/CPPopUpButton.j +++ b/AppKit/CPPopUpButton.j @@ -54,7 +54,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down"); /*! Initializes the pop-up button to the specified size. @param aFrame the size for the button - @param shouldPullDown YES makes this a pull-down menu, NO makes it a pop-up menu. + @param shouldPullDown \c YES makes this a pull-down menu, \c NO makes it a pop-up menu. @return the initialized pop-up button */ - (id)initWithFrame:(CGRect)aFrame pullsDown:(BOOL)shouldPullDown @@ -87,8 +87,8 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down"); /*! Specifies whether the object is a pull-down or a pop-up menu. - @param shouldPullDown YES makes the pop-up button - a pull-down menu. NO makes it a pop-up menu. + @param shouldPullDown \c YES makes the pop-up button + a pull-down menu. \c NO makes it a pop-up menu. */ - (void)setPullsDown:(BOOL)shouldPullDown { @@ -111,7 +111,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down"); } /*! - Returns YES if the button is a pull-down menu. NO if the button is a pop-up menu. + Returns \c YES if the button is a pull-down menu. \c NO if the button is a pop-up menu. */ - (BOOL)pullsDown { @@ -200,18 +200,18 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down"); // Getting the User's Selection /*! - Returns the selected item or nil if no item is selected. + Returns the selected item or \c nil if no item is selected. */ - (CPMenuItem)selectedItem { - if (_selectedIndex < 0) + if (_selectedIndex < 0 || _selectedIndex > [self numberOfItems] - 1) return nil; return [_menu itemAtIndex:_selectedIndex]; } /*! - Returns the title of the selected item or nil if no item is selected. + Returns the title of the selected item or \c nil if no item is selected. */ - (CPString)titleOfSelectedItem { @@ -372,7 +372,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down"); } /*! - Returns the item at the specified index or nil if the item does not exist. + Returns the item at the specified index or \c nil if the item does not exist. @param anIndex the index of the item to obtain */ - (CPMenuItem)itemAtIndex:(unsigned)anIndex @@ -381,7 +381,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down"); } /*! - Returns the title of the item at the specified index or nil if no item exists. + Returns the title of the item at the specified index or \c nil if no item exists. @param anIndex the index of the item */ - (CPString)itemTitleAtIndex:(unsigned)anIndex @@ -628,13 +628,15 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down"); { var numberOfItems = [self numberOfItems]; - if (numberOfItems <= _selectedIndex) + if (numberOfItems <= _selectedIndex && numberOfItems > 0) [self selectItemAtIndex:numberOfItems - 1]; + else + [self synchronizeTitleAndSelectedItem]; } - (void)mouseDown:(CPEvent)anEvent { - if (![self isEnabled]) + if (![self isEnabled] || ![self numberOfItems]) return; [self highlight:YES]; diff --git a/AppKit/CPProgressIndicator.j b/AppKit/CPProgressIndicator.j index a5e1756ee..663da8450 100644 --- a/AppKit/CPProgressIndicator.j +++ b/AppKit/CPProgressIndicator.j @@ -205,7 +205,7 @@ var CPProgressIndicatorSpinningStyleColors = nil, } /*! - Always returns NO. Cappuccino does not have multiple threads. + Always returns \c NO. Cappuccino does not have multiple threads. */ - (BOOL)usesThreadedAnimation { @@ -329,7 +329,7 @@ var CPProgressIndicatorSpinningStyleColors = nil, /*! Specifies whether this progress indicator should be indeterminate or display progress based on it's max and min. - @param isDeterminate YES makes the indicator indeterminate + @param isDeterminate \c YES makes the indicator indeterminate */ - (void)setIndeterminate:(BOOL)isIndeterminate { @@ -342,7 +342,7 @@ var CPProgressIndicatorSpinningStyleColors = nil, } /*! - Returns YES if the progress bar is indeterminate. + Returns \c YES if the progress bar is indeterminate. */ - (BOOL)isIndeterminate { @@ -377,9 +377,9 @@ var CPProgressIndicatorSpinningStyleColors = nil, } /*! - Sets whether the indicator should be displayed when it isn't animating. By default this is YES if the style - is CPProgressIndicatorBarStyle, and NO if it's CPProgressIndicatorSpinningStyle. - @param isDisplayedWhenStopped YES means the indicator will be displayed when it's not animating. + Sets whether the indicator should be displayed when it isn't animating. By default this is \c YES if the style + is CPProgressIndicatorBarStyle, and \c NO if it's CPProgressIndicatorSpinningStyle. + @param isDisplayedWhenStopped \c YES means the indicator will be displayed when it's not animating. */ - (void)setDisplayedWhenStopped:(BOOL)isDisplayedWhenStopped { @@ -394,7 +394,7 @@ var CPProgressIndicatorSpinningStyleColors = nil, } /*! - Returns YES if the progress bar is displayed when not animating. + Returns \c YES if the progress bar is displayed when not animating. */ - (BOOL)isDisplayedWhenStopped { diff --git a/AppKit/CPResponder.j b/AppKit/CPResponder.j index c55a2731c..cdb541abd 100644 --- a/AppKit/CPResponder.j +++ b/AppKit/CPResponder.j @@ -46,7 +46,7 @@ CPDownArrowKeyCode = 40; // Changing the first responder /*! - Returns YES if the receiver is able to become the first responder. NO otherwise. + Returns \c YES if the receiver is able to become the first responder. \c NO otherwise. */ - (BOOL)acceptsFirstResponder { @@ -55,8 +55,8 @@ CPDownArrowKeyCode = 40; /*! Notifies the receiver that it will become the first responder. The receiver can reject first - responder if it returns NO. The default implementation always returns YES. - @return YES if the receiver accepts first responder status. + responder if it returns \c NO. The default implementation always returns \c YES. + @return \c YES if the receiver accepts first responder status. */ - (BOOL)becomeFirstResponder { @@ -65,7 +65,7 @@ CPDownArrowKeyCode = 40; /*! Notifies the receiver that it has been asked to give up first responder status. - @return YES if the receiver is willing to give up first responder status. + @return \c YES if the receiver is willing to give up first responder status. */ - (BOOL)resignFirstResponder { @@ -216,9 +216,9 @@ CPDownArrowKeyCode = 40; /* FIXME This description is bad. - Based on anEvent, the receiver should simulate the event. + Based on \c anEvent, the receiver should simulate the event. @param anEvent the event to simulate - @return YES if the event receiver simulated the event + @return \c YES if the event receiver simulated the event */ - (BOOL)performKeyEquivalent:(CPEvent)anEvent { @@ -267,7 +267,7 @@ CPDownArrowKeyCode = 40; // Dispatch methods /*! The receiver will attempt to perform the command, - if it responds to it. If not, the nextResponder will be called to do it. + if it responds to it. If not, the \c -nextResponder will be called to do it. @param aSelector the command to attempt */ - (void)doCommandBySelector:(SEL)aSelector @@ -282,7 +282,7 @@ CPDownArrowKeyCode = 40; The receiver will attempt to perform the command, or pass it on to the next responder if it doesn't respond to it. @param aSelector the command to perform @param anObject the argument to the method - @return YES if the receiver was able to perform the command, or a responder down the chain was + @return \c YES if the receiver was able to perform the command, or a responder down the chain was able to perform the command. */ - (BOOL)tryToPerform:(SEL)aSelector with:(id)anObject diff --git a/AppKit/CPScrollView.j b/AppKit/CPScrollView.j index ec93beb28..b1f68e9a6 100644 --- a/AppKit/CPScrollView.j +++ b/AppKit/CPScrollView.j @@ -306,7 +306,7 @@ /*! Specifies whether the scroll view can have a horizontal scroller. - @param hasHorizontalScroller YES lets the scroll view + @param hasHorizontalScroller \c YES lets the scroll view allocate a horizontal scroller if necessary. */ - (void)setHasHorizontalScroller:(BOOL)shouldHaveHorizontalScroller @@ -328,7 +328,7 @@ } /*! - Returns YES if the scroll view can have a horizontal scroller. + Returns \c YES if the scroll view can have a horizontal scroller. */ - (BOOL)hasHorizontalScroller { @@ -369,7 +369,7 @@ /*! Specifies whether the scroll view has can have a vertical scroller. It allocates it if necessary. - @param hasVerticalScroller YES allows + @param hasVerticalScroller \c YES allows the scroll view to display a vertical scroller */ - (void)setHasVerticalScroller:(BOOL)shouldHaveVerticalScroller @@ -391,7 +391,7 @@ } /*! - Returns YES if the scroll view can have a vertical scroller. + Returns \c YES if the scroll view can have a vertical scroller. */ - (BOOL)hasVerticalScroller { @@ -400,7 +400,7 @@ /*! Sets whether the scroll view hides its scoll bars when not needed. - @param autohidesScrollers YES causes the scroll bars + @param autohidesScrollers \c YES causes the scroll bars to be hidden when not needed. */ - (void)setAutohidesScrollers:(BOOL)autohidesScrollers @@ -414,7 +414,7 @@ } /*! - Returns YES if the scroll view hides its scroll + Returns \c YES if the scroll view hides its scroll bars when not necessary. */ - (BOOL)autohidesScrollers diff --git a/AppKit/CPScroller.j b/AppKit/CPScroller.j index af566614e..b6664f474 100644 --- a/AppKit/CPScroller.j +++ b/AppKit/CPScroller.j @@ -198,7 +198,7 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob"; } /*! - Returns the part of the scroller that would be hit by aPoint. + Returns the part of the scroller that would be hit by \c aPoint. @param aPoint the simulated point hit @return the part of the scroller that intersects the point */ diff --git a/AppKit/CPSearchField.j b/AppKit/CPSearchField.j index 8adc431aa..63f61b6ce 100644 --- a/AppKit/CPSearchField.j +++ b/AppKit/CPSearchField.j @@ -143,8 +143,7 @@ var CPSearchFieldSearchImage = nil, // Managing Buttons /*! Sets the button used to display the search-button image - @param button - @param The search button. + @param button The search button. */ - (void)setSearchButton:(CPButton)button { @@ -295,7 +294,7 @@ var CPSearchFieldSearchImage = nil, // Managing Search Modes /*! Returns a Boolean value indicating whether the receiver sends the search action message when the user clicks the search button (or presses return) or after each keystroke. - @return YES if the action message is sent all at once when the user clicks the search button or presses return; otherwise, NO if the search string is sent after each keystroke. The default value is NO. + @return \c YES if the action message is sent all at once when the user clicks the search button or presses return; otherwise, NO if the search string is sent after each keystroke. The default value is NO. */ - (BOOL)sendsWholeSearchString { @@ -304,7 +303,7 @@ var CPSearchFieldSearchImage = nil, /*! Sets whether the receiver sends the search action message when the user clicks the search button (or presses return) or after each keystroke. - @param flag YES to send the action message all at once when the user clicks the search button or presses return; otherwise, NO to send the search string after each keystroke. + @param flag \c YES to send the action message all at once when the user clicks the search button or presses return; otherwise, NO to send the search string after each keystroke. */ - (void)setSendsWholeSearchString:(BOOL)flag { @@ -313,7 +312,7 @@ var CPSearchFieldSearchImage = nil, /*! Returns a Boolean value indicating whether the receiver sends its action immediately upon being notified of changes to the search field text or after a brief pause. - @return YES if the text field sends its action immediately upon notification of any changes to the search field; otherwise, NO. + @return \c YES if the text field sends its action immediately upon notification of any changes to the search field; otherwise, NO. */ - (BOOL)sendsSearchStringImmediately { @@ -322,7 +321,7 @@ var CPSearchFieldSearchImage = nil, /*! Sets whether the text field sends its action message to the target immediately upon notification of any changes to the search field text or after a brief pause. - @param flag YES to send the text field's action immediately upon notification of any changes to the search field; otherwise, NO if you want the text field to pause briefly before sending its action message. Pausing gives the user the opportunity to type more text into the search field before initiating the search. + @param flag \c YES to send the text field's action immediately upon notification of any changes to the search field; otherwise, NO if you want the text field to pause briefly before sending its action message. Pausing gives the user the opportunity to type more text into the search field before initiating the search. */ - (void)setSendsSearchStringImmediately:(BOOL)flag { @@ -355,7 +354,7 @@ var CPSearchFieldSearchImage = nil, /*! Returns the list of recent search strings for the control. - @return An array of objects, each of which contains a search string either displayed in the search menu or from a recent autosave archive. If there have been no recent searches and no prior searches saved under an autosave name, this array may be empty. + @return An array of \c CPString objects, each of which contains a search string either displayed in the search menu or from a recent autosave archive. If there have been no recent searches and no prior searches saved under an autosave name, this array may be empty. */ - (CPArray)recentSearches { @@ -567,7 +566,7 @@ var CPSearchFieldSearchImage = nil, - (void)_showMenu:(id)sender { - if(_searchMenu == nil) + if(_searchMenu == nil || ![self isEnabled]) return; [super selectText:nil]; @@ -690,13 +689,15 @@ var CPSearchButtonKey = @"CPSearchButtonKey", self = [super initWithCoder:coder]; _searchButton = [coder decodeObjectForKey:CPSearchButtonKey]; - _searchButton = [coder decodeObjectForKey:CPCancelButtonKey]; + _cancelButton = [coder decodeObjectForKey:CPCancelButtonKey]; _recentsAutosaveName = [coder decodeObjectForKey:CPRecentsAutosaveNameKey]; _sendsWholeSearchString = [coder decodeBoolForKey:CPSendsWholeSearchStringKey]; _sendsSearchStringImmediately = [coder decodeBoolForKey:CPSendsSearchStringImmediatelyKey]; _maximumRecents = [coder decodeIntForKey:CPMaximumRecentsKey]; [self setSearchMenuTemplate:[coder decodeObjectForKey:CPSearchMenuTemplateKey]]; - + [self resetCancelButton]; + [self setDelegate:self]; + return self; } diff --git a/AppKit/CPSegmentedControl.j b/AppKit/CPSegmentedControl.j index 90bf96be0..fe17d85cf 100644 --- a/AppKit/CPSegmentedControl.j +++ b/AppKit/CPSegmentedControl.j @@ -141,7 +141,7 @@ CPSegmentSwitchTrackingMomentary = 2; /*! Selects a segment. @param aSegment the segment to select - @throws CPRangeException if aSegment is out of bounds + @throws CPRangeException if \c aSegment is out of bounds */ - (void)setSelectedSegment:(unsigned)aSegment { @@ -225,7 +225,7 @@ CPSegmentSwitchTrackingMomentary = 2; Sets the width of the specified segment. @param aWidth the new width for the segment @param aSegment the segment to set the width for - @throws CPRangeException if aSegment is out of bounds + @throws CPRangeException if \c aSegment is out of bounds */ - (void)setWidth:(float)aWidth forSegment:(unsigned)aSegment { @@ -237,7 +237,7 @@ CPSegmentSwitchTrackingMomentary = 2; /*! Returns the width for the specified segment. @param aSegment the segment to get the width for - @throws CPRangeException if aSegment is out of bounds + @throws CPRangeException if \c aSegment is out of bounds */ - (float)widthForSegment:(unsigned)aSegment { @@ -248,7 +248,7 @@ CPSegmentSwitchTrackingMomentary = 2; Sets the image for the specified segment. @param anImage the image for the segment @param aSegment the segment to set the image on - @throws CPRangeException if aSegment is out of bounds + @throws CPRangeException if \c aSegment is out of bounds */ - (void)setImage:(CPImage)anImage forSegment:(unsigned)aSegment { @@ -262,7 +262,7 @@ CPSegmentSwitchTrackingMomentary = 2; /*! Returns the image for the specified segment @param aSegment the segment to obtain the image for - @throws CPRangeException if aSegment is out of bounds + @throws CPRangeException if \c aSegment is out of bounds */ - (CPImage)imageForSegment:(unsigned)aSegment { @@ -273,7 +273,7 @@ CPSegmentSwitchTrackingMomentary = 2; Sets the label for the specified segment @param aLabel the label for the segment @param aSegment the segment to label - @throws CPRangeException if aSegment is out of bounds + @throws CPRangeException if \c aSegment is out of bounds */ - (void)setLabel:(CPString)aLabel forSegment:(unsigned)aSegment { @@ -287,7 +287,7 @@ CPSegmentSwitchTrackingMomentary = 2; /*! Returns the label for the specified segment @param the segment to obtain the label for - @throws CPRangeException if aSegment is out of bounds + @throws CPRangeException if \c aSegment is out of bounds */ - (CPString)labelForSegment:(unsigned)aSegment { @@ -298,7 +298,7 @@ CPSegmentSwitchTrackingMomentary = 2; Sets the menu for the specified segment @param aMenu the menu to set @param aSegment the segment to set the menu on - @throws CPRangeException if aSegment is out of bounds + @throws CPRangeException if \c aSegment is out of bounds */ - (void)setMenu:(CPMenu)aMenu forSegment:(unsigned)aSegment { @@ -308,7 +308,7 @@ CPSegmentSwitchTrackingMomentary = 2; /*! Returns the menu for the specified segment. @param aSegment the segment to obtain the menu for - @throws CPRangeException if aSegment is out of bounds + @throws CPRangeException if \c aSegment is out of bounds */ - (CPMenu)menuForSegment:(unsigned)aSegment { @@ -318,9 +318,9 @@ CPSegmentSwitchTrackingMomentary = 2; /*! Sets the selection for the specified segment. If only one segment can be selected at a time, any other segment will be deselected. - @param isSelected YES selects the segment. NO deselects it. + @param isSelected \c YES selects the segment. \c NO deselects it. @param aSegment the segment to set the selection for - @throws CPRangeException if aSegment is out of bounds + @throws CPRangeException if \c aSegment is out of bounds */ - (void)setSelected:(BOOL)isSelected forSegment:(unsigned)aSegment { @@ -358,9 +358,9 @@ CPSegmentSwitchTrackingMomentary = 2; } /*! - Returns YES if the specified segment is selected. + Returns \c YES if the specified segment is selected. @param aSegment the segment to check for selection - @throws CPRangeException if aSegment is out of bounds + @throws CPRangeException if \c aSegment is out of bounds */ - (BOOL)isSelectedForSegment:(unsigned)aSegment { @@ -369,9 +369,9 @@ CPSegmentSwitchTrackingMomentary = 2; /*! Enables/diables the specified segment. - @param isEnabled YES enables the segment + @param isEnabled \c YES enables the segment @param aSegment the segment to enable/disble - @throws CPRangeException if aSegment is out of bounds + @throws CPRangeException if \c aSegment is out of bounds */ - (void)setEnabled:(BOOL)isEnabled forSegment:(unsigned)aSegment { @@ -382,9 +382,9 @@ CPSegmentSwitchTrackingMomentary = 2; } /*! - Returns YES if the specified segment is enabled. + Returns \c YES if the specified segment is enabled. @param aSegment the segment to check - @throws CPRangeException if aSegment is out of bounds + @throws CPRangeException if \c aSegment is out of bounds */ - (BOOL)isEnabledForSegment:(unsigned)aSegment { @@ -414,7 +414,7 @@ CPSegmentSwitchTrackingMomentary = 2; /*! Draws the specified segment bezel @param aSegment the segment to draw the bezel for - @param shouldHighlight YES highlights the bezel + @param shouldHighlight \c YES highlights the bezel */ - (void)drawSegmentBezel:(int)aSegment highlight:(BOOL)shouldHighlight { @@ -582,7 +582,7 @@ CPSegmentSwitchTrackingMomentary = 2; /*! Draws the specified segment @param aSegment the segment to draw - @param shouldHighlight YES highlights the bezel + @param shouldHighlight \c YES highlights the bezel */ - (void)drawSegment:(int)aSegment highlight:(BOOL)shouldHighlight { diff --git a/AppKit/CPSplitView.j b/AppKit/CPSplitView.j index 533e74198..97622b881 100644 --- a/AppKit/CPSplitView.j +++ b/AppKit/CPSplitView.j @@ -559,7 +559,7 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey", @implementation CPSplitView (CPCoding) /* - Initializes the split view by unarchiving data from aCoder. + Initializes the split view by unarchiving data from \c aCoder. @param aCoder the coder containing the archived CPSplitView. */ - (id)initWithCoder:(CPCoder)aCoder diff --git a/AppKit/CPStringDrawing.j b/AppKit/CPStringDrawing.j index 61b4fda70..dec7bde1c 100644 --- a/AppKit/CPStringDrawing.j +++ b/AppKit/CPStringDrawing.j @@ -22,13 +22,9 @@ @import -#include "CoreGraphics/CGGeometry.h" -#include "Platform/Platform.h" +@import "CPPlatformString.j" -var CPStringReferenceElement = nil, - CPStringDefaultFont = nil; - @implementation CPString (CPStringDrawing) /*! @@ -46,75 +42,7 @@ var CPStringReferenceElement = nil, - (CGSize)sizeWithFont:(CPFont)aFont inWidth:(float)aWidth { -#if PLATFORM(DOM) - if (!CPStringReferenceElement) - { - CPStringReferenceElement = document.createElement("span"); - - var style = CPStringReferenceElement.style; - - style.position = "absolute"; - style.whiteSpace = "pre"; - style.visibility = "visible"; - style.padding = "0px"; - style.margin = "0px"; - - style.left = "-100000px"; - style.top = "-100000px"; - style.zIndex = "10000"; - style.background = "red"; - - document.getElementsByTagName("body")[0].appendChild(CPStringReferenceElement); - } - - if (!aFont) - { - if (!CPStringDefaultFont) - CPStringDefaultFont = [CPFont systemFontOfSize:12.0]; - - aFont = CPStringDefaultFont; - } - - var style = CPStringReferenceElement.style; - - if (aWidth === NULL) - { - style.width = ""; - style.whiteSpace = "pre"; - } - - else - { - style.width = ROUND(aWidth) + "px"; - - if (document.attachEvent) - style.wordWrap = "break-word"; - - else - { - style.whiteSpace = "-o-pre-wrap"; - style.whiteSpace = "-pre-wrap"; - style.whiteSpace = "-moz-pre-wrap"; - style.whiteSpace = "pre-wrap"; - } - } - - style.font = [aFont cssString]; - - if (CPFeatureIsCompatible(CPJavascriptInnerTextFeature)) - CPStringReferenceElement.innerText = self; - - else if (CPFeatureIsCompatible(CPJavascriptTextContentFeature)) - CPStringReferenceElement.textContent = self; - - return _CGSizeMake(CPStringReferenceElement.clientWidth, CPStringReferenceElement.clientHeight); -#endif - return _CGSizeMakeZero(); -} - -+ (void)_resetSize -{ - CPStringReferenceElement = nil; + return [CPPlatformString sizeOfString:self withFont:aFont forWidth:aWidth]; } @end diff --git a/AppKit/CPTableColumn.j b/AppKit/CPTableColumn.j index e8edcff9c..d1f2e7b0e 100644 --- a/AppKit/CPTableColumn.j +++ b/AppKit/CPTableColumn.j @@ -391,4 +391,4 @@ var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey", reason:@"dataCellForRow: is not supported. Use -dataViewForRow:row instead."]; } -@end +@end \ No newline at end of file diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index eff694654..42a3bc9e6 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -770,7 +770,12 @@ CPTableViewSelectionHighlightStyleSourceList = 1; { } - return FLOOR(y / (_rowHeight + _intercellSpacing.height)); + var row = FLOOR(y / (_rowHeight + _intercellSpacing.height)); + + if (row >= _numberOfRows) + return -1; + + return row; } - (CGRect)frameOfDataViewAtColumn:(CPInteger)aColumnIndex row:(CPInteger)aRowIndex @@ -1468,4 +1473,4 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey", [aCoder encodeObject:_tableColumns forKey:CPTableViewTableColumnsKey]; } -@end +@end \ No newline at end of file diff --git a/AppKit/CPTextField.j b/AppKit/CPTextField.j index de0731812..6672a4596 100644 --- a/AppKit/CPTextField.j +++ b/AppKit/CPTextField.j @@ -100,7 +100,7 @@ var CPSecureTextFieldCharacter = "\u2022"; @implementation CPString (CPTextFieldAdditions) /*! - Returns the string (self). + Returns the string (\c self). */ - (CPString)string { @@ -389,7 +389,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); } /*! - Returns YES if the textfield is currently editable by the user. + Returns \c YES if the textfield is currently editable by the user. */ - (BOOL)isEditable { @@ -398,7 +398,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); /*! Sets whether the field's text is selectable by the user. - @param aFlag YES makes the text selectable + @param aFlag \c YES makes the text selectable */ - (void)setSelectable:(BOOL)aFlag { @@ -406,7 +406,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); } /*! - Returns YES if the field's text is selectable by the user. + Returns \c YES if the field's text is selectable by the user. */ - (BOOL)isSelectable { @@ -415,7 +415,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); /*! Sets whether the field's text is secure. - @param aFlag YES makes the text secure + @param aFlag \c YES makes the text secure */ - (void)setSecure:(BOOL)aFlag { @@ -423,7 +423,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); } /*! - Returns YES if the field's text is secure (password entry). + Returns \c YES if the field's text is secure (password entry). */ - (BOOL)isSecure { @@ -433,7 +433,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); // Setting the Bezel Style /*! Sets whether the textfield will have a bezeled border. - @param shouldBeBezeled YES means the textfield will draw a bezeled border + @param shouldBeBezeled \c YES means the textfield will draw a bezeled border */ - (void)setBezeled:(BOOL)shouldBeBezeled { @@ -444,7 +444,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); } /*! - Returns YES if the textfield draws a bezeled border. + Returns \c YES if the textfield draws a bezeled border. */ - (BOOL)isBezeled { @@ -478,7 +478,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); /*! Sets whether the textfield will have a border drawn. - @param shouldBeBordered YES makes the textfield draw a border + @param shouldBeBordered \c YES makes the textfield draw a border */ - (void)setBordered:(BOOL)shouldBeBordered { @@ -489,7 +489,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); } /*! - Returns YES if the textfield has a border. + Returns \c YES if the textfield has a border. */ - (BOOL)isBordered { @@ -498,7 +498,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); /*! Sets whether the textfield will have a background drawn. - @param shouldDrawBackground YES makes the textfield draw a background + @param shouldDrawBackground \c YES makes the textfield draw a background */ - (void)setDrawsBackground:(BOOL)shouldDrawBackground { @@ -512,7 +512,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); } /*! - Returns YES if the textfield draws a background. + Returns \c YES if the textfield draws a background. */ - (BOOL)drawsBackground { @@ -597,7 +597,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); //post CPControlTextDidBeginEditingNotification [self textDidBeginEditing:[CPNotification notificationWithName:CPControlTextDidBeginEditingNotification object:self userInfo:nil]]; - [[CPDOMWindowBridge sharedDOMWindowBridge] _propagateCurrentDOMEvent:YES]; + [[[self window] platformWindow] _propagateCurrentDOMEvent:YES]; CPTextFieldInputIsActive = YES; diff --git a/AppKit/CPToolbar.j b/AppKit/CPToolbar.j index f292d7631..6bcff4a60 100644 --- a/AppKit/CPToolbar.j +++ b/AppKit/CPToolbar.j @@ -76,9 +76,9 @@ var CPToolbarConfigurationsByIdentifier = nil; Called to obtain a toolbar item. Required. @param toolbar the toolbar the item belongs to @param itemIdentifier the identifier of the toolbar item - @param flag YES means the item will be placed in the toolbar. NO means the item will be displayed for + @param flag \c YES means the item will be placed in the toolbar. \c NO means the item will be displayed for some other purpose (non-functional) - @return the toolbar item or nil if no such item belongs in the toolbar + @return the toolbar item or \c nil if no such item belongs in the toolbar */ @implementation CPToolbar : CPObject { @@ -176,7 +176,7 @@ var CPToolbarConfigurationsByIdentifier = nil; } /*! - Returns YES if the toolbar is currently visible + Returns \c YES if the toolbar is currently visible */ - (BOOL)isVisible { @@ -185,7 +185,7 @@ var CPToolbarConfigurationsByIdentifier = nil; /*! Sets whether the toolbar should be visible. - @param aFlag YES makes the toolbar visible + @param aFlag \c YES makes the toolbar visible */ - (void)setVisible:(BOOL)aFlag { @@ -304,7 +304,7 @@ var CPToolbarConfigurationsByIdentifier = nil; } /*! - Returns the toolbar items sorted by their visibilityPriority(ies). + Returns the toolbar items sorted by their \c visibilityPriority(ies). */ - (CPArray)itemsSortedByVisibilityPriority { @@ -369,7 +369,7 @@ var CPToolbarIdentifierKey = "CPToolbarIdentifierKey", @implementation CPToolbar (CPCoding) /* - Initializes the toolbar by unarchiving data from aCoder. + Initializes the toolbar by unarchiving data from \c aCoder. @param aCoder the coder containing the archived CPToolbar. */ - (id)initWithCoder:(CPCoder)aCoder diff --git a/AppKit/CPToolbarItem.j b/AppKit/CPToolbarItem.j index c235463a9..64c4aea7c 100644 --- a/AppKit/CPToolbarItem.j +++ b/AppKit/CPToolbarItem.j @@ -223,7 +223,7 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItemIdentifier"; } /*! - Sets the target of the action that is triggered when the user clicks this item. nil will cause + Sets the target of the action that is triggered when the user clicks this item. \c nil will cause the action to be passed on to the first responder. @param aTarget the new target */ @@ -261,7 +261,7 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItemIdentifier"; } /*! - Returns YES if the item is enabled. + Returns \c YES if the item is enabled. */ - (BOOL)isEnabled { @@ -273,7 +273,7 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItemIdentifier"; /*! Sets whether the item is enabled. - @param aFlag YES enables the item + @param aFlag \c YES enables the item */ - (void)setEnabled:(BOOL)shouldBeEnabled { diff --git a/AppKit/CPView.j b/AppKit/CPView.j index a98759de3..9d0d78bc9 100644 --- a/AppKit/CPView.j +++ b/AppKit/CPView.j @@ -114,7 +114,7 @@ var CPViewFlags = { }, headed by the window's content view. Every other view in a window is a descendant of this view.

    -

    Subclasses can override -drawRect: in order to implement their +

    Subclasses can override \c -drawRect: in order to implement their appearance. Other methods of CPView and CPResponder can also be overridden to handle user generated events. */ @@ -329,10 +329,10 @@ var CPViewFlags = { }, } /*! - Makes aSubview a subview of the receiver. It is positioned relative to anotherView + Makes \c aSubview a subview of the receiver. It is positioned relative to \c anotherView @param aSubview the view to add as a subview - @param anOrderingMode specifies aSubview's ordering relative to anotherView - @param anotherView aSubview will be positioned relative to this argument + @param anOrderingMode specifies \c aSubview's ordering relative to \c anotherView + @param anotherView \c aSubview will be positioned relative to this argument */ - (void)addSubview:(CPView)aSubview positioned:(CPWindowOrderingMode)anOrderingMode relativeTo:(CPView)anotherView { @@ -420,7 +420,7 @@ var CPViewFlags = { }, } /*! - Called when the receiver has added aSubview to it's child views. + Called when the receiver has added \c aSubview to it's child views. @param aSubview the view that was added */ - (void)didAddSubview:(CPView)aSubview @@ -504,7 +504,7 @@ var CPViewFlags = { }, } /*! - Returns YES if the receiver is, or is a descendant of, aView. + Returns \c YES if the receiver is, or is a descendant of, \c aView. @param aView the view to test for ancestry */ - (BOOL)isDescendantOf:(CPView)aView @@ -562,7 +562,7 @@ var CPViewFlags = { }, /*! Returns the menu item containing the receiver or one of its ancestor views. - @return a menu item, or nil if the view or one of its ancestors wasn't found + @return a menu item, or \c nil if the view or one of its ancestors wasn't found */ - (CPMenuItem)enclosingMenuItem { @@ -615,7 +615,7 @@ var CPViewFlags = { }, /*! Returns whether the view is flipped. - @return YES if the view is flipped. NO, otherwise. + @return \c YES if the view is flipped. \c NO, otherwise. */ - (BOOL)isFlipped { @@ -711,7 +711,7 @@ var CPViewFlags = { }, } /*! - Sets the receiver's frame size. If aSize is the same as the frame's current dimensions, this + Sets the receiver's frame size. If \c aSize is the same as the frame's current dimensions, this method simply returns. The method posts a CPViewFrameDidChangeNotification to the default notification center if the receiver is configured to do so. @param aSize the new size for the frame @@ -928,7 +928,7 @@ var CPViewFlags = { }, } /*! - Initiates superviewSizeChanged: messages to subviews. + Initiates \c -superviewSizeChanged: messages to subviews. @param aSize the size for the subviews */ - (void)resizeSubviewsWithOldSize:(CGSize)aSize @@ -941,9 +941,9 @@ var CPViewFlags = { }, /*! Specifies whether the receiver view should automatically resize its - subviews when its setFrameSize: method receives a change. - @param aFlag If YES, then subviews will automatically be resized - when this view is resized. NO means the views will not + subviews when its \c -setFrameSize: method receives a change. + @param aFlag If \c YES, then subviews will automatically be resized + when this view is resized. \c NO means the views will not be resized automatically. */ - (void)setAutoresizesSubviews:(BOOL)aFlag @@ -953,7 +953,7 @@ var CPViewFlags = { }, /*! Reports whether the receiver automatically resizes its subviews when its frame size changes. - @return YES means it resizes its subviews on a frame size change. + @return \c YES means it resizes its subviews on a frame size change. */ - (BOOL)autoresizesSubviews { @@ -996,7 +996,7 @@ var CPViewFlags = { }, { _fullScreenModeState = _CPViewFullScreenModeStateMake(self); - var fullScreenWindow = [[CPWindow alloc] initWithContentRect:[[CPDOMWindowBridge sharedDOMWindowBridge] contentBounds] styleMask:CPBorderlessWindowMask]; + var fullScreenWindow = [[CPWindow alloc] initWithContentRect:[[CPPlatformWindow primaryPlatformWindow] contentBounds] styleMask:CPBorderlessWindowMask]; [fullScreenWindow setLevel:CPScreenSaverWindowLevel]; [fullScreenWindow setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable]; @@ -1045,7 +1045,7 @@ var CPViewFlags = { }, } /*! - Returns YES if the receiver is currently in full screen mode. + Returns \c YES if the receiver is currently in full screen mode. */ - (BOOL)isInFullScreenMode { @@ -1054,7 +1054,7 @@ var CPViewFlags = { }, /*! Sets whether the receiver should be hidden. - @param aFlag YES makes the receiver hidden. + @param aFlag \c YES makes the receiver hidden. */ - (void)setHidden:(BOOL)aFlag { @@ -1090,7 +1090,7 @@ var CPViewFlags = { }, } /*! - Returns YES if the receiver is hidden. + Returns \c YES if the receiver is hidden. */ - (BOOL)isHidden { @@ -1134,8 +1134,8 @@ var CPViewFlags = { }, } /*! - Returns YES if the receiver is hidden, or one - of it's ancestor views is hidden. NO, otherwise. + Returns \c YES if the receiver is hidden, or one + of it's ancestor views is hidden. \c NO, otherwise. */ - (BOOL)isHiddenOrHasHiddenAncestor { @@ -1148,9 +1148,9 @@ var CPViewFlags = { }, } /*! - Returns whether the receiver should be sent a mouseDown: message for anEvent.
    - Returns YES by default. - @return YES, if the view object accepts first mouse-down event. NO, otherwise. + Returns whether the receiver should be sent a \c -mouseDown: message for \c anEvent.
    + Returns \c YES by default. + @return \c YES, if the view object accepts first mouse-down event. \c NO, otherwise. */ //FIXME: should be NO by default? - (BOOL)acceptsFirstMouse:(CPEvent)anEvent @@ -1160,7 +1160,7 @@ var CPViewFlags = { }, /*! Returns whether or not the view responds to hit tests. - @return YES if this view listens to hitTest messages, NO otherwise. + @return \c YES if this view listens to \c -hitTest messages, \c NO otherwise. */ - (BOOL)hitTests { @@ -1169,7 +1169,7 @@ var CPViewFlags = { }, /*! Set whether or not the view should respond to hit tests. - @param shouldHitTest should be YES if this view should respond to hit tests, NO otherwise. + @param shouldHitTest should be \c YES if this view should respond to hit tests, \c NO otherwise. */ - (void)setHitTests:(BOOL)shouldHitTest { @@ -1201,8 +1201,8 @@ var CPViewFlags = { }, } /*! - Returns YES if mouse events aren't needed by the receiver and can be sent to the superview. The - default implementation returns NO if the view is opaque. + Returns \c YES if mouse events aren't needed by the receiver and can be sent to the superview. The + default implementation returns \c NO if the view is opaque. */ - (BOOL)mouseDownCanMoveWindow { @@ -1340,7 +1340,7 @@ var CPViewFlags = { }, // Converting Coordinates /*! - Converts aPoint from the coordinate space of aView to the coordinate space of the receiver. + Converts \c aPoint from the coordinate space of \c aView to the coordinate space of the receiver. @param aPoint the point to convert @param aView the view space to convert from @return the converted point @@ -1351,7 +1351,7 @@ var CPViewFlags = { }, } /*! - Converts aPoint from the receiver's coordinate space to the coordinate space of aView. + Converts \c aPoint from the receiver's coordinate space to the coordinate space of \c aView. @param aPoint the point to convert @param aView the coordinate space to which the point will be converted @return the converted point @@ -1362,7 +1362,7 @@ var CPViewFlags = { }, } /*! - Convert's aSize from aView's coordinate space to the receiver's coordinate space. + Convert's \c aSize from \c aView's coordinate space to the receiver's coordinate space. @param aSize the size to convert @param aView the coordinate space to convert from @return the converted size @@ -1373,7 +1373,7 @@ var CPViewFlags = { }, } /*! - Convert's aSize from the receiver's coordinate space to aView's coordinate space. + Convert's \c aSize from the receiver's coordinate space to \c aView's coordinate space. @param aSize the size to convert @param the coordinate space to which the size will be converted @return the converted size @@ -1384,7 +1384,7 @@ var CPViewFlags = { }, } /*! - Converts aRect from aView's coordinate space to the receiver's space. + Converts \c aRect from \c aView's coordinate space to the receiver's space. @param aRect the rectangle to convert @param aView the coordinate space from which to convert @return the converted rectangle @@ -1395,7 +1395,7 @@ var CPViewFlags = { }, } /*! - Converts aRect from the receiver's coordinate space to aView's coordinate space. + Converts \c aRect from the receiver's coordinate space to \c aView's coordinate space. @param aRect the rectangle to convert @param aView the coordinate space to which the rectangle will be converted @return the converted rectangle @@ -1407,14 +1407,14 @@ var CPViewFlags = { }, /*! Sets whether the receiver posts a CPViewFrameDidChangeNotification notification - to the default notification center when its frame is changed. The default is NO. + to the default notification center when its frame is changed. The default is \c NO. Methods that could cause a frame change notification are:

     setFrame:
     setFrameSize:
     setFrameOrigin:
     
    - @param shouldPostFrameChangedNotifications YES makes the receiver post + @param shouldPostFrameChangedNotifications \c YES makes the receiver post notifications on frame changes (size or origin) */ - (void)setPostsFrameChangedNotifications:(BOOL)shouldPostFrameChangedNotifications @@ -1431,7 +1431,7 @@ setFrameOrigin: } /*! - Returns YES if the receiver posts a CPViewFrameDidChangeNotification if its frame is changed. + Returns \c YES if the receiver posts a CPViewFrameDidChangeNotification if its frame is changed. */ - (BOOL)postsFrameChangedNotifications { @@ -1440,14 +1440,14 @@ setFrameOrigin: /*! Sets whether the receiver posts a CPViewBoundsDidChangeNotification notification - to the default notification center when its bounds is changed. The default is NO. + to the default notification center when its bounds is changed. The default is \c NO. Methods that could cause a bounds change notification are:
     setBounds:
     setBoundsSize:
     setBoundsOrigin:
     
    - @param shouldPostBoundsChangedNotifications YES makes the receiver post + @param shouldPostBoundsChangedNotifications \c YES makes the receiver post notifications on bounds changes */ - (void)setPostsBoundsChangedNotifications:(BOOL)shouldPostBoundsChangedNotifications @@ -1464,7 +1464,7 @@ setBoundsOrigin: } /*! - Returns YES if the receiver posts a + Returns \c YES if the receiver posts a CPViewBoundsDidChangeNotification when its bounds is changed. */ @@ -1476,9 +1476,9 @@ setBoundsOrigin: /*! Initiates a drag operation from the receiver to another view that accepts dragged data. @param anImage the image to be dragged - @param aLocation the lower-left corner coordinate of anImage - @param mouseOffset the distance from the mouseDown: location and the current location - @param anEvent the mouseDown: that triggered the drag + @param aLocation the lower-left corner coordinate of \c anImage + @param mouseOffset the distance from the \c -mouseDown: location and the current location + @param anEvent the \c -mouseDown: that triggered the drag @param aPastebaord the pasteboard that holds the drag data @param aSourceObject the drag operation controller @param slideBack Whether the image should 'slide back' if the drag is rejected @@ -1491,9 +1491,9 @@ setBoundsOrigin: /*! Initiates a drag operation from the receiver to another view that accepts dragged data. @param aView the view to be dragged - @param aLocation the top-left corner coordinate of aView - @param mouseOffset the distance from the mouseDown: location and the current location - @param anEvent the mouseDown: that triggered the drag + @param aLocation the top-left corner coordinate of \c aView + @param mouseOffset the distance from the \c -mouseDown: location and the current location + @param anEvent the \c -mouseDown: that triggered the drag @param aPastebaord the pasteboard that holds the drag data @param aSourceObject the drag operation controller @param slideBack Whether the view should 'slide back' if the drag is rejected @@ -1545,7 +1545,7 @@ setBoundsOrigin: } /*! - Draws the receiver into aRect. This method should be overridden by subclasses. + Draws the receiver into \c aRect. This method should be overridden by subclasses. @param aRect the area that should be drawn into */ - (void)drawRect:(CPRect)aRect @@ -1569,7 +1569,7 @@ setBoundsOrigin: } /*! - Marks the area denoted by aRect as dirty, and initiates a redraw on it. + Marks the area denoted by \c aRect as dirty, and initiates a redraw on it. @param aRect the area that needs to be redrawn */ - (void)setNeedsDisplayInRect:(CPRect)aRect @@ -1607,7 +1607,7 @@ setBoundsOrigin: } /*! - Draws the entire area of the receiver as defined by its bounds. + Draws the entire area of the receiver as defined by its \c -bounds. */ - (void)display { @@ -1621,7 +1621,7 @@ setBoundsOrigin: } /*! - Draws the receiver into the area defined by aRect. + Draws the receiver into the area defined by \c aRect. @param aRect the area to be drawn */ - (void)displayRect:(CPRect)aRect @@ -1719,7 +1719,7 @@ setBoundsOrigin: } /*! - Returns whether the receiver is completely opaque. By default, returns NO. + Returns whether the receiver is completely opaque. By default, returns \c NO. */ - (BOOL)isOpaque { @@ -1751,7 +1751,7 @@ setBoundsOrigin: } /*! - Changes the receiver's frame origin to a 'constrained' aPoint. + Changes the receiver's frame origin to a 'constrained' \c aPoint. @param aPoint the proposed frame origin */ - (void)scrollPoint:(CGPoint)aPoint @@ -1765,9 +1765,9 @@ setBoundsOrigin: } /*! - Scrolls the nearest ancestor CPClipView a minimum amount so aRect can become visible. + Scrolls the nearest ancestor CPClipView a minimum amount so \c aRect can become visible. @param aRect the area to become visible - @return if any scrolling occurred, NO otherwise. + @return YES
    means the receiver wants a layer. + @param \c YES means the receiver wants a layer. */ - (void)setWantsLayer:(BOOL)aFlag { @@ -1969,8 +1969,8 @@ setBoundsOrigin: } /*! - Returns YES if the receiver uses a CALayer - @returns YES if the receiver uses a CALayer + Returns \c YES if the receiver uses a CALayer + @returns \c YES if the receiver uses a CALayer */ - (BOOL)wantsLayer { diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index 48a9968c6..c8b7612f2 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -27,6 +27,7 @@ @import "CGGeometry.j" @import "CPAnimation.j" @import "CPResponder.j" +@import "CPPlatformWindow.j" #include "../Platform/Platform.h" #include "../Platform/DOM/CPDOMDisplayServer.h" @@ -230,72 +231,74 @@ var CPWindowSaveImage = nil, @delegate -(BOOL)windowShouldClose:(id)window; Called when the user tries to close the window. @param window the window to close - @return YES allows the window to close. NO + @return \c YES allows the window to close. \c NO vetoes the close operation and leaves the window open. */ @implementation CPWindow : CPResponder { - int _windowNumber; - unsigned _styleMask; - CGRect _frame; - int _level; - BOOL _isVisible; - BOOL _isAnimating; - BOOL _hasShadow; - BOOL _isMovableByWindowBackground; + CPPlatformWindow _platformWindow; - BOOL _isDocumentEdited; - BOOL _isDocumentSaving; + int _windowNumber; + unsigned _styleMask; + CGRect _frame; + int _level; + BOOL _isVisible; + BOOL _isAnimating; + BOOL _hasShadow; + BOOL _isMovableByWindowBackground; - CPImageView _shadowView; + BOOL _isDocumentEdited; + BOOL _isDocumentSaving; - CPView _windowView; - CPView _contentView; - CPView _toolbarView; + CPImageView _shadowView; - CPArray _mouseEnteredStack; - CPView _leftMouseDownView; - CPView _rightMouseDownView; + CPView _windowView; + CPView _contentView; + CPView _toolbarView; - CPToolbar _toolbar; - CPResponder _firstResponder; - CPResponder _initialFirstResponder; - id _delegate; + CPArray _mouseEnteredStack; + CPView _leftMouseDownView; + CPView _rightMouseDownView; - CPString _title; + CPToolbar _toolbar; + CPResponder _firstResponder; + CPResponder _initialFirstResponder; + id _delegate; - BOOL _acceptsMouseMovedEvents; - BOOL _ignoresMouseEvents; + CPString _title; - CPWindowController _windowController; + BOOL _acceptsMouseMovedEvents; + BOOL _ignoresMouseEvents; - CGSize _minSize; - CGSize _maxSize; + CPWindowController _windowController; - CPUndoManager _undoManager; - CPURL _representedURL; + CGSize _minSize; + CGSize _maxSize; - CPSet _registeredDraggedTypes; - CPArray _registeredDraggedTypesArray; - CPCountedSet _inclusiveRegisteredDraggedTypes; + CPUndoManager _undoManager; + CPURL _representedURL; - CPButton _defaultButton; - BOOL _defaultButtonEnabled; + CPSet _registeredDraggedTypes; + CPArray _registeredDraggedTypesArray; + CPCountedSet _inclusiveRegisteredDraggedTypes; - BOOL _autorecalculatesKeyViewLoop; - BOOL _keyViewLoopIsDirty; + CPButton _defaultButton; + BOOL _defaultButtonEnabled; + + BOOL _autorecalculatesKeyViewLoop; + BOOL _keyViewLoopIsDirty; // Bridge Support #if PLATFORM(DOM) - DOMElement _DOMElement; + DOMElement _DOMElement; #endif - CPDOMWindowBridge _bridge; - unsigned _autoresizingMask; - - BOOL _delegateRespondsToWindowWillReturnUndoManagerSelector; - BOOL _isFullBridge; - _CPWindowFullBridgeSession _fullBridgeSession; + unsigned _autoresizingMask; + + BOOL _delegateRespondsToWindowWillReturnUndoManagerSelector; + + BOOL _isFullPlatformWindow; + _CPWindowFullPlatformWindowSession _fullPlatformWindowSession; } /* @@ -328,38 +331,14 @@ CPTexturedBackgroundWindowMask @return the initialized window */ - (id)initWithContentRect:(CGRect)aContentRect styleMask:(unsigned int)aStyleMask -{ -#if PLATFORM(DOM) - return [self initWithContentRect:aContentRect styleMask:aStyleMask bridge:[CPDOMWindowBridge sharedDOMWindowBridge]]; -#else - return [self initWithContentRect:aContentRect styleMask:aStyleMask bridge:nil]; -#endif -} - -/*! - Initializes the window. The method also takes a style bit mask made up - of any of the following values: -
    -CPBorderlessWindowMask
    -CPTitledWindowMask
    -CPClosableWindowMask
    -CPMiniaturizableWindowMask
    -CPResizableWindowMask
    -CPTexturedBackgroundWindowMask
    -
    - @param aContentRect the size and location of the window in screen space - @param aStyleMask a style mask - @param aBridge a DOM-Window bridge object - @return the initialized window - @ignore -*/ -- (id)initWithContentRect:(CGRect)aContentRect styleMask:(unsigned int)aStyleMask bridge:(CPDOMWindowBridge)aBridge { self = [super init]; if (self) { - _isFullBridge = NO; + [self setPlatformWindow:[CPPlatformWindow primaryPlatformWindow]]; + + _isFullPlatformWindow = NO; _registeredDraggedTypes = [CPSet set]; _registeredDraggedTypesArray = []; @@ -395,21 +374,19 @@ CPTexturedBackgroundWindowMask _DOMElement.style.position = "absolute"; _DOMElement.style.visibility = "visible"; _DOMElement.style.zIndex = 0; - + CPDOMDisplayServerSetStyleLeftTop(_DOMElement, NULL, _CGRectGetMinX(_frame), _CGRectGetMinY(_frame)); CPDOMDisplayServerSetStyleSize(_DOMElement, 1, 1); CPDOMDisplayServerAppendChild(_DOMElement, _windowView._DOMElement); #endif - [self setBridge:aBridge]; - [self setNextResponder:CPApp]; [self setHasShadow:aStyleMask !== CPBorderlessWindowMask]; if (aStyleMask & CPBorderlessBridgeWindowMask) - [self setFullBridge:YES]; + [self setFullPlatformWindow:YES]; _defaultButtonEnabled = YES; _keyViewLoopIsDirty = YES; @@ -418,6 +395,17 @@ CPTexturedBackgroundWindowMask return self; } +- (CPPlatformWindow)platformWindow +{ + return _platformWindow; +} + +- (void)setPlatformWindow:(CPPlatformWindow)aPlatformWindow +{ + // FIXME: already visible. + _platformWindow = aPlatformWindow; +} + /*! @ignore */ @@ -432,7 +420,7 @@ CPTexturedBackgroundWindowMask return _CPStandardWindowView; } -+ (Class)_windowViewClassForFullBridgeStyleMask:(unsigned)aStyleMask ++ (Class)_windowViewClassForFullPlatformWindowStyleMask:(unsigned)aStyleMask { return _CPBorderlessBridgeWindowView; } @@ -482,46 +470,49 @@ CPTexturedBackgroundWindowMask #endif } -- (void)setFullBridge:(BOOL)shouldBeFullBridge +- (void)setFullPlatformWindow:(BOOL)shouldBeFullPlatformWindow { - shouldBeFullBridge = !!shouldBeFullBridge; - - if (_isFullBridge === shouldBeFullBridge) + if (![_platformWindow supportsFullPlatformWindows]) return; - _isFullBridge = shouldBeFullBridge; + shouldBeFullPlatformWindow = !!shouldBeFullPlatformWindow; - if (_isFullBridge) + if (_isFullPlatformWindow === shouldBeFullPlatformWindow) + return; + + _isFullPlatformWindow = shouldBeFullPlatformWindow; + + if (_isFullPlatformWindow) { - _fullBridgeSession = _CPWindowFullBridgeSessionMake(_windowView, [self contentRectForFrameRect:[self frame]], [self hasShadow], [self level]); + _fullPlatformWindowSession = _CPWindowFullPlatformWindowSessionMake(_windowView, [self contentRectForFrameRect:[self frame]], [self hasShadow], [self level]); - var fullBridgeWindowViewClass = [[self class] _windowViewClassForFullBridgeStyleMask:_styleMask], - windowView = [[fullBridgeWindowViewClass alloc] initWithFrame:CGRectMakeZero() styleMask:_styleMask]; + var fullPlatformWindowViewClass = [[self class] _windowViewClassForFullPlatformWindowStyleMask:_styleMask], + windowView = [[fullPlatformWindowViewClass alloc] initWithFrame:CGRectMakeZero() styleMask:_styleMask]; [self _setWindowView:windowView]; [self setLevel:CPBackgroundWindowLevel]; [self setHasShadow:NO]; [self setAutoresizingMask:CPWindowWidthSizable | CPWindowHeightSizable]; - [self setFrame:[_bridge visibleFrame]]; + [self setFrame:[_platformWindow usableContentFrame]]; } else { - var windowView = _fullBridgeSession.windowView; + var windowView = _fullPlatformWindowSession.windowView; [self _setWindowView:windowView]; - [self setLevel:_fullBridgeSession.level]; - [self setHasShadow:_fullBridgeSession.hasShadow]; + [self setLevel:_fullPlatformWindowSession.level]; + [self setHasShadow:_fullPlatformWindowSession.hasShadow]; [self setAutoresizingMask:CPWindowNotSizable]; - [self setFrame:[windowView frameRectForContentRect:_fullBridgeSession.contentRect]]; + [self setFrame:[windowView frameRectForContentRect:_fullPlatformWindowSession.contentRect]]; } } -- (BOOL)isFullBridge +- (BOOL)isFullPlatformWindow { - return _isFullBridge; + return _isFullPlatformWindow; } /*! @@ -613,7 +604,7 @@ CPTexturedBackgroundWindowMask origin.x = anOrigin.x; origin.y = anOrigin.y; - + #if PLATFORM(DOM) CPDOMDisplayServerSetStyleLeftTop(_DOMElement, NULL, origin.x, origin.y); #endif @@ -633,9 +624,9 @@ CPTexturedBackgroundWindowMask return; _frame.size = aSize; - + [_windowView setFrameSize:aSize]; - + if (_hasShadow) [_shadowView setFrameSize:_CGSizeMake(SHADOW_MARGIN_LEFT + aSize.width + SHADOW_MARGIN_RIGHT, SHADOW_MARGIN_BOTTOM + aSize.height + SHADOW_MARGIN_TOP + SHADOW_DISTANCE)]; @@ -649,7 +640,8 @@ CPTexturedBackgroundWindowMask */ - (void)orderFront:(id)aSender { - [_bridge order:CPWindowAbove window:self relativeTo:nil]; + [_platformWindow orderFront:self]; + [_platformWindow order:CPWindowAbove window:self relativeTo:nil]; } /* @@ -659,7 +651,7 @@ CPTexturedBackgroundWindowMask */ - (void)orderBack:(id)aSender { - //[_bridge order:CPWindowBelow + //[_platformWindow order:CPWindowBelow } /*! @@ -671,7 +663,7 @@ CPTexturedBackgroundWindowMask if ([_delegate respondsToSelector:@selector(windowWillClose:)]) [_delegate windowWillClose:self]; - [_bridge order:CPWindowOut window:self relativeTo:nil]; + [_platformWindow order:CPWindowOut window:self relativeTo:nil]; if ([CPApp keyWindow] == self) { @@ -683,12 +675,12 @@ CPTexturedBackgroundWindowMask /*! Relocates the window in the screen list. - @param aPlace the positioning relative to otherWindowNumber + @param aPlace the positioning relative to \c otherWindowNumber @param otherWindowNumber the window relative to which the receiver should be placed */ - (void)orderWindow:(CPWindowOrderingMode)aPlace relativeTo:(int)otherWindowNumber { - [_bridge order:aPlace window:self relativeTo:CPApp._windows[otherWindowNumber]]; + [_platformWindow order:aPlace window:self relativeTo:CPApp._windows[otherWindowNumber]]; } /*! @@ -709,7 +701,7 @@ CPTexturedBackgroundWindowMask } /*! - Returns YES if the window is visible. It does not mean that the window is not obscured by other windows. + Returns \c YES if the window is visible. It does not mean that the window is not obscured by other windows. */ - (BOOL)isVisible { @@ -717,7 +709,7 @@ CPTexturedBackgroundWindowMask } /*! - Returns YES if the window's resize indicator is showing. NO otherwise. + Returns \c YES if the window's resize indicator is showing. \c NO otherwise. */ - (BOOL)showsResizeIndicator { @@ -726,7 +718,7 @@ CPTexturedBackgroundWindowMask /*! Sets the window's resize indicator. - @param shouldShowResizeIndicator YES sets the window to show its resize indicator. + @param shouldShowResizeIndicator \c YES sets the window to show its resize indicator. */ - (void)setShowsResizeIndicator:(BOOL)shouldShowResizeIndicator { @@ -874,7 +866,7 @@ CPTexturedBackgroundWindowMask } /*! - Returns YES if the window has a drop shadow. NO otherwise. + Returns \c YES if the window has a drop shadow. \c NO otherwise. */ - (BOOL)hasShadow { @@ -883,7 +875,7 @@ CPTexturedBackgroundWindowMask /*! Sets whether the window should have a drop shadow. - @param shouldHaveShadow YES to have a drop shadow. + @param shouldHaveShadow \c YES to have a drop shadow. */ - (void)setHasShadow:(BOOL)shouldHaveShadow { @@ -936,7 +928,7 @@ CPTexturedBackgroundWindowMask } /*! - Sets the delegate for the window. Passing nil will just remove the window's current delegate. + Sets the delegate for the window. Passing \c nil will just remove the window's current delegate. @param aDelegate an object to respond to the various delegate methods of CPWindow */ - (void)setDelegate:(id)aDelegate @@ -1010,11 +1002,11 @@ CPTexturedBackgroundWindowMask } /*! - Attempts to make the aResponder the first responder. Before trying + Attempts to make the \c aResponder the first responder. Before trying to make it the first responder, the receiver will ask the current first responder to resign its first responder status. If it resigns, it will ask - aResponder accept first responder, then finally tell it to become first responder. - @return YES if the attempt was successful. NO otherwise. + \c aResponder accept first responder, then finally tell it to become first responder. + @return \c YES if the attempt was successful. \c NO otherwise. */ - (void)makeFirstResponder:(CPResponder)aResponder { @@ -1132,7 +1124,7 @@ CPTexturedBackgroundWindowMask /*! Sets whether the window can be moved by dragging its background. The default is based on the window style. - @param shouldBeMovableByWindowBackground YES makes the window move from a background drag. + @param shouldBeMovableByWindowBackground \c YES makes the window move from a background drag. */ - (void)setMovableByWindowBackground:(BOOL)shouldBeMovableByWindowBackground { @@ -1140,7 +1132,7 @@ CPTexturedBackgroundWindowMask } /*! - Returns YES if the window can be moved by dragging its background. + Returns \c YES if the window can be moved by dragging its background. */ - (BOOL)isMovableByWindowBackground { @@ -1153,9 +1145,9 @@ CPTexturedBackgroundWindowMask - (void)center { var size = [self frame].size, - bridgeSize = [_bridge contentBounds].size; + containerSize = [_platformWindow contentBounds].size; - [self setFrameOrigin:CGPointMake((bridgeSize.width - size.width) / 2.0, (bridgeSize.height - size.height) / 2.0)]; + [self setFrameOrigin:CGPointMake((containerSize.width - size.width) / 2.0, (containerSize.height - size.height) / 2.0)]; } /*! @@ -1275,7 +1267,7 @@ CPTexturedBackgroundWindowMask /*! Called when the receiver should become the key window. It also sends - the becomeKeyWindow message to the first responder. + the \c -becomeKeyWindow message to the first responder. */ - (void)becomeKeyWindow { @@ -1285,7 +1277,7 @@ CPTexturedBackgroundWindowMask /*! Determines if the window can become the key window. - @return YES means the window can become the key window. + @return \c YES means the window can become the key window. */ - (BOOL)canBecomeKeyWindow { @@ -1293,7 +1285,7 @@ CPTexturedBackgroundWindowMask } /*! - Returns YES if the window is the key window. + Returns \c YES if the window is the key window. */ - (BOOL)isKeyWindow { @@ -1342,9 +1334,9 @@ CPTexturedBackgroundWindowMask /*! Initiates a drag operation from the receiver to another view that accepts dragged data. @param anImage the image to be dragged - @param aLocation the lower-left corner coordinate of anImage - @param mouseOffset the distance from the mouseDown: location and the current location - @param anEvent the mouseDown: that triggered the drag + @param aLocation the lower-left corner coordinate of \c anImage + @param mouseOffset the distance from the \c -mouseDown: location and the current location + @param anEvent the \c -mouseDown: that triggered the drag @param aPastebaord the pasteboard that holds the drag data @param aSourceObject the drag operation controller @param slideBack Whether the image should 'slide back' if the drag is rejected @@ -1379,9 +1371,9 @@ CPTexturedBackgroundWindowMask /*! Initiates a drag operation from the receiver to another view that accepts dragged data. @param aView the view to be dragged - @param aLocation the lower-left corner coordinate of aView - @param mouseOffset the distance from the mouseDown: location and the current location - @param anEvent the mouseDown: that triggered the drag + @param aLocation the lower-left corner coordinate of \c aView + @param mouseOffset the distance from the \c -mouseDown: location and the current location + @param anEvent the \c -mouseDown: that triggered the drag @param aPastebaord the pasteboard that holds the drag data @param aSourceObject the drag operation controller @param slideBack Whether the view should 'slide back' if the drag is rejected @@ -1434,7 +1426,7 @@ CPTexturedBackgroundWindowMask /*! Sets whether the document has been edited. - @param isDocumentEdited YES if the document has been edited. + @param isDocumentEdited \c YES if the document has been edited. */ - (void)setDocumentEdited:(BOOL)isDocumentEdited { @@ -1447,7 +1439,7 @@ CPTexturedBackgroundWindowMask } /*! - Returns YES if the document has been edited. + Returns \c YES if the document has been edited. */ - (BOOL)isDocumentEdited { @@ -1524,7 +1516,7 @@ CPTexturedBackgroundWindowMask } /*! - Closes the window. Posts a CPWindowWillCloseNotification to the + Closes the window. Posts a \c CPWindowWillCloseNotification to the notification center before closing the window. */ - (void)close @@ -1536,7 +1528,7 @@ CPTexturedBackgroundWindowMask // Managing Main Status /*! - Returns YES if this the main window. + Returns \c YES if this the main window. */ - (BOOL)isMainWindow { @@ -1544,7 +1536,7 @@ CPTexturedBackgroundWindowMask } /*! - Returns YES if the window can become the main window. + Returns \c YES if the window can become the main window. */ - (BOOL)canBecomeMainWindow { @@ -1639,8 +1631,8 @@ CPTexturedBackgroundWindowMask [_windowView noteToolbarChanged]; - if (_isFullBridge) - newFrame = [_bridge visibleFrame]; + if (_isFullPlatformWindow) + newFrame = [_platformWindow usableContentFrame]; else { newFrame = CGRectMakeCopy([self frame]); @@ -1707,7 +1699,7 @@ CPTexturedBackgroundWindowMask [self _setAttachedSheetFrameOrigin]; // Place this window above ourselves. - [_bridge order:CPWindowAbove window:aSheet relativeTo:self]; + [_platformWindow order:CPWindowAbove window:aSheet relativeTo:self]; } /*! @@ -1719,7 +1711,7 @@ CPTexturedBackgroundWindowMask } /*! - Returns YES if the window has ever run as a sheet. + Returns \c YES if the window has ever run as a sheet. */ - (BOOL)isSheet { @@ -1737,7 +1729,7 @@ CPTexturedBackgroundWindowMask } /*! - Returns YES if the receiver is able to receive input events + Returns \c YES if the receiver is able to receive input events even when a modal session is active. */ - (BOOL)worksWhenModal @@ -1929,38 +1921,17 @@ var keyViewComparator = function(a, b, context) @implementation CPWindow (BridgeSupport) /* - Sets the DOM-Window bridge for this window. @ignore */ -- (void)setBridge:(CPDOMWindowBridge)aBridge +- (void)resizeWithOldPlatformWindowSize:(CGSize)aSize { - if (_bridge == aBridge) - return; - - if (_bridge) - { - [self orderOut:self]; - // FIXME: If the bridge changes, then we have to recreate all of our subviews' DOM Elements. - } - - _bridge = aBridge; - - if ([self isFullBridge]) - [self setFrame:[aBridge contentBounds]]; -} - -/* - @ignore -*/ -- (void)resizeWithOldBridgeSize:(CGSize)aSize -{ - if ([self isFullBridge]) - return [self setFrame:[_bridge visibleFrame]]; + if ([self isFullPlatformWindow]) + return [self setFrame:[_platformWindow usableContentFrame]]; if (_autoresizingMask == CPWindowNotSizable) return; - var frame = [_bridge contentBounds], + var frame = [_platformWindow contentBounds], newFrame = CGRectMakeCopy(_frame), dX = (CGRectGetWidth(frame) - aSize.width) / (((_autoresizingMask & CPWindowMinXMargin) ? 1 : 0) + (_autoresizingMask & CPWindowWidthSizable ? 1 : 0) + (_autoresizingMask & CPWindowMaxXMargin ? 1 : 0)), @@ -2032,7 +2003,7 @@ var keyViewComparator = function(a, b, context) } /*! - Sends the undo manager an undo message. + Sends the undo manager an \c -undo: message. @param aSender the object requesting this */ - (void)undo:(id)aSender @@ -2041,7 +2012,7 @@ var keyViewComparator = function(a, b, context) } /*! - Sends the undo manager a redo: message. + Sends the undo manager a \c -redo: message. @param aSender the object requesting this */ - (void)redo:(id)aSender @@ -2056,6 +2027,20 @@ var keyViewComparator = function(a, b, context) @end +@implementation CPWindow (Deprecated) + +- (void)setFullBridge:(BOOL)shouldBeFullBridge +{ + [self setFullPlatformWindow:shouldBeFullBridge]; +} + +- (BOOL)isFullBridge +{ + return [self isFullPlatformWindow]; +} + +@end + var interpolate = function(fromValue, toValue, progress) { return fromValue + (toValue - fromValue) * progress; @@ -2107,7 +2092,7 @@ var interpolate = function(fromValue, toValue, progress) @end -function _CPWindowFullBridgeSessionMake(aWindowView, aContentRect, hasShadow, aLevel) +function _CPWindowFullPlatformWindowSessionMake(aWindowView, aContentRect, hasShadow, aLevel) { return { windowView:aWindowView, contentRect:aContentRect, hasShadow:hasShadow, level:aLevel }; } @@ -2118,5 +2103,4 @@ function _CPWindowFullBridgeSessionMake(aWindowView, aContentRect, hasShadow, aL @import "_CPBorderlessWindowView.j" @import "_CPBorderlessBridgeWindowView.j" @import "CPDragServer.j" -@import "CPDOMWindowBridge.j" @import "CPView.j" diff --git a/AppKit/CPWindow/_CPWindowView.j b/AppKit/CPWindow/_CPWindowView.j index 7bbfaf22b..fe2d1ca4d 100644 --- a/AppKit/CPWindow/_CPWindowView.j +++ b/AppKit/CPWindow/_CPWindowView.j @@ -145,7 +145,7 @@ var _CPWindowViewResizeIndicatorImage = nil; var visibleFrame = _cachedScreenFrame; if (!visibleFrame) - visibleFrame = [[CPDOMWindowBridge sharedDOMWindowBridge] visibleFrame]; + visibleFrame = [[CPPlatformWindow primaryPlatformWindow] usableContentFrame]; var restrictedPoint = CGPointMake(0, 0); @@ -167,7 +167,7 @@ var _CPWindowViewResizeIndicatorImage = nil; else if (type === CPLeftMouseDown) { _mouseDraggedPoint = [[self window] convertBaseToBridge:[anEvent locationInWindow]]; - _cachedScreenFrame = [[CPDOMWindowBridge sharedDOMWindowBridge] visibleFrame]; + _cachedScreenFrame = [[CPPlatformWindow primaryPlatformWindow] usableContentFrame]; } else if (type === CPLeftMouseDragged) { diff --git a/AppKit/CPWindowController.j b/AppKit/CPWindowController.j index 35bc94c90..0562465a3 100644 --- a/AppKit/CPWindowController.j +++ b/AppKit/CPWindowController.j @@ -41,10 +41,22 @@ */ @implementation CPWindowController : CPResponder { - id _owner; CPWindow _window; + CPDocument _document; + BOOL _shouldCloseDocument; + + id _cibOwner; CPString _windowCibName; + CPString _windowCibPath; + + BOOL _isWindowLoading; + BOOL _shouldDisplayWindowWhenLoaded; +} + +- (id)init +{ + return [self initWithWindow:nil]; } /*! @@ -55,14 +67,18 @@ - (id)initWithWindow:(CPWindow)aWindow { self = [super init]; - + if (self) { [self setWindow:aWindow]; - + [self setShouldCloseDocument:NO]; + [self setNextResponder:CPApp]; + + if (aWindow) + [self windowDidLoad]; } - + return self; } @@ -84,37 +100,78 @@ */ - (id)initWithWindowCibName:(CPString)aWindowCibName owner:(id)anOwner { - self = [super init]; - + self = [self initWithWindow:nil]; + if (self) { - _owner = anOwner; + _cibOwner = anOwner; _windowCibName = aWindowCibName; - - [self setNextResponder:CPApp]; } - + + return self; +} + +- (id)initWithWindowCibPath:(CPString)aWindowCibPath owner:(id)anOwner +{ + self = [self initWithWindow:nil]; + + if (self) + { + _cibOwner = anOwner; + _windowCibPath = aWindowCibPath; + } + return self; } /*! Loads the window */ -- (void)loadWindow +- (BOOL)loadWindow { - [self windowWillLoad]; - //FIXME: ACTUALLY LOAD WINDOW!!! - [self setWindow:CPApp._keyWindow = [[CPWindow alloc] initWithContentRect:CPRectMakeZero() styleMask:CPBorderlessBridgeWindowMask|CPTitledWindowMask|CPClosableWindowMask|CPResizableWindowMask]]; - + if ([self isWindowLoaded]) + return YES; + + if (![self isWindowLoading]) + { + _isWindowLoading = YES; + + [self windowWillLoad]; + + [CPBundle loadCibFile:[self windowCibPath] + externalNameTable:[CPDictionary dictionaryWithObject:_cibOwner forKey:CPCibOwner] + loadDelegate:self]; + } + + return NO; +} + +- (void)cibDidFinishLoading:(CPCib)aCib +{ + if (_window === nil && _document !== nil && _cibOwner === _document) + [self setWindow:[_document valueForKey:@"window"]]; + + [self synchronizeWindowTitleWithDocumentName]; + [self windowDidLoad]; + + if (_shouldDisplayWindowWhenLoaded) + [self showWindow:self]; } /*! Shows the window. @param aSender the object requesting the show */ -- (CFAction)showWindow:(id)aSender +- (@action)showWindow:(id)aSender { + if (![self loadWindow]) + { + _shouldDisplayWindowWhenLoaded = YES; + + return; + } + var theWindow = [self window]; if ([theWindow respondsToSelector:@selector(becomesKeyOnlyIfNeeded)] && [theWindow becomesKeyOnlyIfNeeded]) @@ -124,12 +181,17 @@ } /*! - Returns YES if the window has been loaded. Specifically, + Returns \c YES if the window has been loaded. Specifically, if loadWindow has been called. */ - (BOOL)isWindowLoaded { - return _window; + return _window !== nil; +} + +- (BOOL)isWindowLoading +{ + return _isWindowLoading; } /*! @@ -149,8 +211,10 @@ */ - (void)setWindow:(CPWindow)aWindow { + [_window setWindowController:nil]; + _window = aWindow; - + [_window setWindowController:self]; [_window setNextResponder:self]; } @@ -160,8 +224,8 @@ */ - (void)windowDidLoad { - [_document windowControllerDidLoadNib:self]; - + [_document windowControllerDidLoadCib:self]; + [self synchronizeWindowTitleWithDocumentName]; } @@ -170,7 +234,7 @@ */ - (void)windowWillLoad { - [_document windowControllerWillLoadNib:self]; + [_document windowControllerWillLoadCib:self]; } /*! @@ -179,17 +243,17 @@ */ - (void)setDocument:(CPDocument)aDocument { - if (_document == aDocument) + if (_document === aDocument) return; - + var defaultCenter = [CPNotificationCenter defaultCenter]; - + if (_document) { [defaultCenter removeObserver:self name:CPDocumentWillSaveNotification object:_document]; - + [defaultCenter removeObserver:self name:CPDocumentDidSaveNotification object:_document]; @@ -198,16 +262,16 @@ name:CPDocumentDidFailToSaveNotification object:_document]; } - + _document = aDocument; - + if (_document) { [defaultCenter addObserver:self selector:@selector(_documentWillSave:) name:CPDocumentWillSaveNotification object:_document]; - + [defaultCenter addObserver:self selector:@selector(_documentDidSave:) name:CPDocumentDidSaveNotification @@ -217,10 +281,10 @@ selector:@selector(_documentDidFailToSave:) name:CPDocumentDidFailToSaveNotification object:_document]; - + [self setDocumentEdited:[_document isDocumentEdited]]; - } - + } + [self synchronizeWindowTitleWithDocumentName]; } @@ -252,13 +316,49 @@ /*! Sets whether the document has unsaved changes. The window can use this as a hint to - @param isEdited YES means the document has unsaved changes. + @param isEdited \c YES means the document has unsaved changes. */ - (void)setDocumentEdited:(BOOL)isEdited { [[self window] setDocumentEdited:isEdited]; } +- (void)close +{ + [[self window] close]; +} + +- (void)setShouldCloseDocument:(BOOL)shouldCloseDocument +{ + _shouldCloseDocument = shouldCloseDocument; +} + +- (BOOL)shouldCloseDocument +{ + return _shouldCloseDocument; +} + +- (id)owner +{ + return _cibOwner; +} + +- (CPString)windowCibName +{ + if (_windowCibName) + return _windowCibName; + + return [[_windowCibPath lastPathComponent] stringByDeletingPathExtension]; +} + +- (CPString)windowCibPath +{ + if (_windowCibPath) + return _windowCibPath; + + return [[CPBundle bundleForClass:[_cibOwner class]] pathForResource:_windowCibName + @".cib"]; +} + // Setting and Getting Window Attributes /*! @@ -268,7 +368,7 @@ { if (!_document || !_window) return; - + // [_window setRepresentedFilename:]; [_window setTitle:[self windowTitleForDocumentDisplayName:[_document displayName]]]; } diff --git a/AppKit/CoreAnimation/CAAnimation.j b/AppKit/CoreAnimation/CAAnimation.j index bc7e51672..06876996e 100644 --- a/AppKit/CoreAnimation/CAAnimation.j +++ b/AppKit/CoreAnimation/CAAnimation.j @@ -54,8 +54,8 @@ } /*! - Returns YES - @return YES + Returns \c YES + @return \c YES */ - (void)shouldArchiveValueForKey:(CPString)aKey { @@ -63,8 +63,8 @@ } /*! - Returns nil - @return nil + Returns \c nil + @return \c nil */ + (id)defaultValueForKey:(CPString)aKey { @@ -73,7 +73,7 @@ /*! Specifies whether this animation should be removed after it has completed. - @param YES means the animation should be removed + @param \c YES means the animation should be removed */ - (void)setRemovedOnCompletion:(BOOL)isRemovedOnCompletion { @@ -81,7 +81,7 @@ } /*! - Returns YES if the animation is removed after completion + Returns \c YES if the animation is removed after completion */ - (BOOL)removedOnCompletion { @@ -89,7 +89,7 @@ } /*! - Returns YES if the animation is removed after completion + Returns \c YES if the animation is removed after completion */ - (BOOL)isRemovedOnCompletion { @@ -97,7 +97,7 @@ } /*! - Returns the animation's timing function. If nil, then it has a linear pacing. + Returns the animation's timing function. If \c nil, then it has a linear pacing. */ - (CAMediaTimingFunction)timingFunction { diff --git a/AppKit/CoreAnimation/CALayer.j b/AppKit/CoreAnimation/CALayer.j index 85e415787..4df328715 100644 --- a/AppKit/CoreAnimation/CALayer.j +++ b/AppKit/CoreAnimation/CALayer.j @@ -56,12 +56,12 @@ var CALayerRegisteredRunLoopUpdates = nil; @delegate -(void)drawLayer:(CALayer)layer inContext:(CGContextRef)ctx; If the delegate implements this method, the CALayer will - call this in place of its drawInContext:. + call this in place of its \c -drawInContext:. @param layer the layer to draw for @param ctx the context to draw on @delegate -(void)displayLayer:(CALayer)layer; - The delegate can override the layer's display method + The delegate can override the layer's \c -display method by implementing this method. */ @implementation CALayer : CPObject @@ -419,7 +419,7 @@ var CALayerRegisteredRunLoopUpdates = nil; // Providing Layer Content /*! Returns the CGImage contents of this layer. - The default contents are nil. + The default contents are \c nil. */ - (CGImage)contents { @@ -547,7 +547,7 @@ var CALayerRegisteredRunLoopUpdates = nil; // Style Attributes /*! Returns the opacity of the layer. The value is between - 0.0 (transparent) and 1.0 (opaque). + \c 0.0 (transparent) and \c 1.0 (opaque). */ - (float)opacity { @@ -556,7 +556,7 @@ var CALayerRegisteredRunLoopUpdates = nil; /*! Sets the opacity for the layer. - @param anOpacity the new opacity (between 0.0 (transparent) and 1.0 (opaque)). + @param anOpacity the new opacity (between \c 0.0 (transparent) and \c 1.0 (opaque)). */ - (void)setOpacity:(float)anOpacity { @@ -571,7 +571,7 @@ var CALayerRegisteredRunLoopUpdates = nil; /*! Sets whether the layer is hidden. - @param isHidden YES means the layer will be hidden. NO means the layer will be visible. + @param isHidden \c YES means the layer will be hidden. \c NO means the layer will be visible. */ - (void)setHidden:(BOOL)isHidden { @@ -580,7 +580,7 @@ var CALayerRegisteredRunLoopUpdates = nil; } /*! - Returns YES if the layer is hidden. + Returns \c YES if the layer is hidden. */ - (BOOL)hidden { @@ -588,7 +588,7 @@ var CALayerRegisteredRunLoopUpdates = nil; } /*! - Returns YES if the layer is hidden. + Returns \c YES if the layer is hidden. */ - (BOOL)isHidden { @@ -597,7 +597,7 @@ var CALayerRegisteredRunLoopUpdates = nil; /*! Sets whether content that goes lies outside the bounds is hidden or visible. - @param masksToBounds YES hides the excess content. NO makes it visible. + @param masksToBounds \c YES hides the excess content. \c NO makes it visible. */ - (void)setMasksToBounds:(BOOL)masksToBounds { @@ -724,7 +724,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex) Inserts a layer below another layer. @param aLayer the layer to insert @param aSublayer the layer to insert below - @throws CALayerNotFoundException if aSublayer is not in the array of sublayers + @throws CALayerNotFoundException if \c aSublayer is not in the array of sublayers */ - (void)insertSublayer:(CALayer)aLayer below:(CALayer)aSublayer { @@ -737,7 +737,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex) Inserts a layer above another layer. @param aLayer the layer to insert @param aSublayer the layer to insert above - @throws CALayerNotFoundException if aSublayer is not in the array of sublayers + @throws CALayerNotFoundException if \c aSublayer is not in the array of sublayers */ - (void)insertSublayer:(CALayer)aLayer above:(CALayer)aSublayer { @@ -834,7 +834,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex) /*! Sets whether the layer needs to be redrawn when its bounds are changed. - @param needsDisplayOnBoundsChange YES means the display is redraw on a bounds change. + @param needsDisplayOnBoundsChange \c YES means the display is redraw on a bounds change. */ - (void)setNeedsDisplayOnBoundsChange:(BOOL)needsDisplayOnBoundsChange { @@ -842,7 +842,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex) } /*! - Returns YES if the display should be redrawn on a bounds change. + Returns \c YES if the display should be redrawn on a bounds change. */ - (BOOL)needsDisplayOnBoundsChange { @@ -906,7 +906,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex) // Hit Testing /*! - Returns YES if the layer contains the point. + Returns \c YES if the layer contains the point. @param aPoint the point to test */ - (BOOL)containsPoint:(CGPoint)aPoint @@ -917,7 +917,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex) /*! Returns the farthest descendant of this layer that contains the specified point. @param aPoint the point to test - @return the containing layer or nil if there was no hit. + @return the containing layer or \c nil if there was no hit. */ - (CALayer)hitTest:(CGPoint)aPoint { diff --git a/AppKit/CoreGraphics/CGColor.j b/AppKit/CoreGraphics/CGColor.j index 6c9381041..96d7fa643 100644 --- a/AppKit/CoreGraphics/CGColor.j +++ b/AppKit/CoreGraphics/CGColor.j @@ -101,8 +101,8 @@ function CGColorCreateCopy(aColor) /*! Creates a gray color object. - @param gray the value to use for the color intensities (0.0-1.0) - @param alpha the gray's alpha value (0.0-1.0) + @param gray the value to use for the color intensities (\c 0.\c 0-\c 1.\c 0). + @param alpha the gray's alpha value (\c 0.\c 0-\c 1.\c 0). @return CGColor the new gray color object @group CGColor */ @@ -113,10 +113,10 @@ function CGColorCreateGenericGray(gray, alpha) /*! Creates an RGB color. - @param red the red component (0.0-1.0) - @param green the green component (0.0-1.0) - @param blue the blue component (0.0-1.0) - @param alpha the alpha component (0.0-1.0) + @param red the red component (\c 0.\c 0-\c 1.\c 0).. + @param green the green component (\c 0.\c 0-\c 1.\c 0). + @param blue the blue component (\c 0.\c 0-\c 1.\c 0). + @param alpha the alpha component (\c 0.\c 0-\c 1.\c 0). @return CGColor the RGB based color @group CGColor */ @@ -127,11 +127,11 @@ function CGColorCreateGenericRGB(red, green, blue, alpha) /*! Creates a CMYK color. - @param cyan the cyan component (0.0-1.0) - @param magenta the magenta component (0.0-1.0) - @param yellow the yellow component (0.0-1.0) - @param black the black component (0.0-1.0) - @param alpha the alpha component (0.0-1.0) + @param cyan the cyan component (\c 0.\c 0-\c 1.\c 0). + @param magenta the magenta component (\c 0.\c 0-\c 1.\c 0). + @param yellow the yellow component (\c 0.\c 0-\c 1.\c 0). + @param black the black component (\c 0.\c 0-\c 1.\c 0). + @param alpha the alpha component (\c 0.\c 0-\c 1.\c 0). @return CGColor the CMYK based color @group CGColor */ @@ -143,7 +143,7 @@ function CGColorCreateGenericCMYK(cyan, magenta, yellow, black, alpha) /*! Creates a copy of the color with a specified alpha. @param aColor the color object to copy - @param anAlpha the new alpha component for the copy (0.0-1.0) + @param anAlpha the new alpha component for the copy (\c 0.\c 0-\c 1.\c 0). @return CGColor the new copy @group CGColor */ @@ -184,8 +184,8 @@ function CGColorCreateWithPattern(aColorSpace, aPattern, components) Determines if two colors are the same. @param lhs the first CGColor @param rhs the second CGColor - @return YES if the two colors are equal. - NO otherwise. + @return \c YES if the two colors are equal. + \c NO otherwise. */ function CGColorEqualToColor(lhs, rhs) { @@ -218,7 +218,7 @@ function CGColorEqualToColor(lhs, rhs) /*! Returns the color's alpha component. @param aColor the color - @return float the alpha component (0.0-1.0) + @return float the alpha component (\c 0.\c 0-\c 1.\c 0). @group CGColor */ function CGColorGetAlpha(aColor) diff --git a/AppKit/CoreGraphics/CGContext.j b/AppKit/CoreGraphics/CGContext.j index a56d20e4d..fd28689d1 100644 --- a/AppKit/CoreGraphics/CGContext.j +++ b/AppKit/CoreGraphics/CGContext.j @@ -652,10 +652,10 @@ function CGContextSetStrokeColor(aContext, aColor) @param aContext the CGContext to draw into @param aRect the base rectangle @param aRadius the distance from the rectange corner to the rounded corner - @param ne set it to YES for a rounded northeast corner - @param se set it to YES for a rounded southeast corner - @param sw set it to YES for a rounded southwest corner - @param nw set it to YES for a rounded northwest corner + @param ne set it to \c YES for a rounded northeast corner + @param se set it to \c YES for a rounded southeast corner + @param sw set it to \c YES for a rounded southwest corner + @param nw set it to \c YES for a rounded northwest corner @return void */ function CGContextFillRoundedRectangleInRect(aContext, aRect, aRadius, ne, se, sw, nw) @@ -671,10 +671,10 @@ function CGContextFillRoundedRectangleInRect(aContext, aRect, aRadius, ne, se, s @param aContext the CGContext to draw into @param aRect the base rectangle @param aRadius the distance from the rectange corner to the rounded corner - @param ne set it to YES for a rounded northeast corner - @param se set it to YES for a rounded southeast corner - @param sw set it to YES for a rounded southwest corner - @param nw set it to YES for a rounded northwest corner + @param ne set it to \c YES for a rounded northeast corner + @param se set it to \c YES for a rounded southeast corner + @param sw set it to \c YES for a rounded southwest corner + @param nw set it to \c YES for a rounded northwest corner @return void */ function CGContextStrokeRoundedRectangleInRect(aContext, aRect, aRadius, ne, se, sw, nw) diff --git a/AppKit/CoreGraphics/CGGeometry.j b/AppKit/CoreGraphics/CGGeometry.j index 78eedcf91..d4737cd5d 100644 --- a/AppKit/CoreGraphics/CGGeometry.j +++ b/AppKit/CoreGraphics/CGGeometry.j @@ -76,12 +76,12 @@ _function(CGInsetIsEmpty(anInset)) */ /*! - Returns a BOOL indicating whether CGRect lhsRect - contains CGRect rhsRect. + Returns a \c BOOL indicating whether CGRect \c lhsRect + contains CGRect \c rhsRect. @group CGRect - @param lhsRect the CGRect to test if rhsRect is inside of - @param rhsRect the CGRect to test if it fits inside lhsRect. - @return BOOL YES if rhsRect fits inside lhsRect. + @param lhsRect the CGRect to test if \c rhsRect is inside of + @param rhsRect the CGRect to test if it fits inside \c lhsRect. + @return BOOL \c YES if \c rhsRect fits inside \c lhsRect. */ function CGRectContainsRect(lhsRect, rhsRect) { @@ -91,11 +91,11 @@ function CGRectContainsRect(lhsRect, rhsRect) } /*! - Returns YES if the two rectangles intersect + Returns \c YES if the two rectangles intersect @group CGRect @param lhsRect the first CGRect @param rhsRect the second CGRect - @return BOOL YES if the two rectangles have any common spaces, and NO, otherwise. + @return BOOL \c YES if the two rectangles have any common spaces, and \c NO, otherwise. */ function CGRectIntersectsRect(lhsRect, rhsRect) { diff --git a/AppKit/Platform/CPPlatform.j b/AppKit/Platform/CPPlatform.j new file mode 100644 index 000000000..8a75b53ab --- /dev/null +++ b/AppKit/Platform/CPPlatform.j @@ -0,0 +1,27 @@ + +@import + +#include "Platform.h" + + +@implementation CPPlatform : CPObject +{ +} + ++ (void)bootstrap +{ +#if PLATFORM(DOM) + var body = document.getElementsByTagName("body")[0]; + + body.innerHTML = ""; // Get rid of anything that might be lingering in the body element. + body.style.overflow = "hidden"; + + if (document.documentElement) + document.documentElement.style.overflow = "hidden"; +#endif + + [CPPlatformString bootstrap]; + [CPPlatformWindow setPrimaryPlatformWindow:[[CPPlatformWindow alloc] _init]]; +} + +@end diff --git a/AppKit/Platform/CPPlatformString.j b/AppKit/Platform/CPPlatformString.j new file mode 100644 index 000000000..24e91d152 --- /dev/null +++ b/AppKit/Platform/CPPlatformString.j @@ -0,0 +1,104 @@ + + +@import + +#include "../CoreGraphics/CGGeometry.h" +#include "Platform.h" + + +#if PLATFORM(DOM) +var DOMIFrameElement = nil, + DOMSpanElement = nil, + DefaultFont = nil; +#endif + +@implementation CPPlatformString : CPObject +{ +} + ++ (void)bootstrap +{ +#if PLATFORM(DOM) + DOMIFrameElement = document.createElement("iframe"); + + DOMIFrameElement.name = name = "iframe_" + FLOOR(RAND() * 10000); + DOMIFrameElement.style.position = "absolute"; + DOMIFrameElement.style.left = "-100px"; + DOMIFrameElement.style.top = "-100px"; + DOMIFrameElement.style.width = "1px"; + DOMIFrameElement.style.height = "1px"; + DOMIFrameElement.style.borderWidth = "0px"; + DOMIFrameElement.style.background = "blue"; + DOMIFrameElement.style.overflow = "hidden"; + DOMIFrameElement.style.zIndex = 100000000000; + + document.getElementsByTagName("body")[0].appendChild(DOMIFrameElement); + + var DOMIFrameDocument = (DOMIFrameElement.contentDocument || DOMIFrameElement.contentWindow.document); + + DOMIFrameDocument.write(""); + DOMIFrameDocument.close(); + + DOMSpanElement = DOMIFrameDocument.createElement("span"); + + DOMSpanElement.style.position = "absolute"; + DOMSpanElement.style.whiteSpace = "pre"; + DOMSpanElement.style.visibility = "visible"; + DOMSpanElement.style.padding = "0px"; + DOMSpanElement.style.margin = "0px"; + DOMSpanElement.style.background = "red"; + + DOMIFrameDocument.getElementsByTagName("body")[0].appendChild(DOMSpanElement); +#endif +} + ++ (CGSize)sizeOfString:(CPString)aString withFont:(CPFont)aFont forWidth:(float)aWidth +{ +#if PLATFORM(DOM) + if (!aFont) + { + if (!DefaultFont) + DefaultFont = [CPFont systemFontOfSize:12.0]; + + aFont = DefaultFont; + } + + var style = DOMSpanElement.style; + + if (aWidth === NULL) + { + style.width = ""; + style.whiteSpace = "pre"; + } + + else + { + style.width = ROUND(aWidth) + "px"; + + if (document.attachEvent) + style.wordWrap = "break-word"; + + else + { + style.whiteSpace = "-o-pre-wrap"; + style.whiteSpace = "-pre-wrap"; + style.whiteSpace = "-moz-pre-wrap"; + style.whiteSpace = "pre-wrap"; + } + } + + style.font = [aFont cssString]; + + if (CPFeatureIsCompatible(CPJavascriptInnerTextFeature)) + DOMSpanElement.innerText = aString; + + else if (CPFeatureIsCompatible(CPJavascriptTextContentFeature)) + DOMSpanElement.textContent = aString; + + return _CGSizeMake(DOMSpanElement.clientWidth, DOMSpanElement.clientHeight); +#else + return _CGSizeMakeZero(); +#endif +} + +@end diff --git a/AppKit/Platform/CPPlatformWindow.j b/AppKit/Platform/CPPlatformWindow.j new file mode 100644 index 000000000..8a6bd2ea5 --- /dev/null +++ b/AppKit/Platform/CPPlatformWindow.j @@ -0,0 +1,177 @@ + +@import + +#import "Platform.h" +#import "../CoreGraphics/CGGeometry.h" + + +var PrimaryPlatformWindow = NULL; + +@implementation CPPlatformWindow : CPObject +{ + CGRect _contentRect; + +#if PLATFORM(DOM) + DOMWindow _DOMWindow; + + DOMElement _DOMBodyElement; + DOMElement _DOMFocusElement; + + CPArray _windowLevels; + CPDictionary _windowLayers; + + BOOL _mouseIsDown; + CPWindow _mouseDownWindow; + CPTimeInterval _lastMouseUp; + CPTimeInterval _lastMouseDown; + + Object _charCodes; + unsigned _keyCode; + + BOOL _DOMEventMode; + + // Native Pasteboard Support + DOMElement _DOMPasteboardElement; + CPEvent _pasteboardKeyDownEvent; + + CPString _overriddenEventType; +#endif +} + ++ (CPPlatformWindow)primaryPlatformWindow +{ + return PrimaryPlatformWindow; +} + ++ (void)setPrimaryPlatformWindow:(CPPlatformWindow)aPlatformWindow +{ + PrimaryPlatformWindow = aPlatformWindow; +} + +- (id)initWithContentRect:(CGRect)aRect +{ + self = [super init]; + + if (self) + { + _contentRect = _CGRectMakeCopy(aRect); + +#if PLATFORM(DOM) + _windowLevels = []; + _windowLayers = [CPDictionary dictionary]; + + _charCodes = {}; +#endif + } + + return self; +} + +- (id)init +{ + return [self initWithContentRect:_CGRectMake(0.0, 0.0, 400.0, 500.0)]; +} + +- (CGRect)contentRect +{ + return _CGRectMakeCopy(_contentRect); +} + +- (CGRect)contentBounds +{ + var contentBounds = [self contentRect]; + + contentBounds.origin = _CGPointMakeZero(); + + return contentBounds; +} + +- (void)usableContentFrame +{ + var frame = [self contentBounds]; + + frame.origin = CGPointMakeZero(); + + if ([CPMenu menuBarVisible]) + { + var menuBarHeight = [[CPApp mainMenu] menuBarHeight]; + + frame.origin.y += menuBarHeight; + frame.size.height -= menuBarHeight; + } + + return frame; +} + +- (void)setContentRect:(CGRect)aRect +{ + if (!aRect || _CGRectEqualToRect(_contentRect, aRect)) + return; + + [self setContentOrigin:aRect.origin]; + [self setContentSize:aRect.size]; +} + +- (void)setContentOrigin:(CGPoint)aPoint +{ + var origin = _contentRect.origin; + + if (!aPoint || _CGPointEqualToPoint(origin, aPoint)) + return; + + origin.x = aPoint.x; + origin.y = aPoint.y; + + [self updateNativeContentOrigin]; +} + +- (void)setContentSize:(CGSize)aSize +{ + var size = _contentRect.size; + + if (!aSize || _CGSizeEqualToSize(size, aSize)) + return; + + var delta = _CGSizeMake(aSize.width - size.width, aSize.height - size.height); + + size.width = aSize.width; + size.height = aSize.height; + + [self updateNativeContentSize]; +} + +- (void)updateFromNativeContentRect +{ + [self setContentRect:[self nativeContentRect]]; +} +/* +- (BOOL)isVisible +{ + return NO; +} + +/* ++ (BOOL)supportsMultipleWindows +{ +#if PLATFORM(BROWSER) + return YES; +#else + return NO; +#endif +} +*/ + +- (BOOL)supportsFullPlatformWindows +{ +#if PLATFORM(BROWSER) + return YES; +#else + return NO; +#endif +} + +@end + +#if PLATFORM(BROWSER) +@import "CPPlatformWindow+DOM.j" +#endif diff --git a/AppKit/Platform/DOM/CPDOMWindowBridge.j b/AppKit/Platform/DOM/CPDOMWindowBridge.j deleted file mode 100644 index 6b6c57d29..000000000 --- a/AppKit/Platform/DOM/CPDOMWindowBridge.j +++ /dev/null @@ -1,1060 +0,0 @@ -/* - * CPDOMWindowBridge.j - * AppKit - * - * Created by Francisco Tolmasky. - * Copyright 2008, 280 North, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -@import -@import - -@import "CPEvent.j" -@import "CPCompatibility.j" - -@import "CPDOMWindowLayer.j" - -#import "../../CoreGraphics/CGGeometry.h" - - -CPSharedDOMWindowBridge = nil; - -var ExcludedDOMElements = []; - -// Define up here so compressor knows about em. -var CPDOMWindowGetFrame, - CPDOMEventGetClickCount, - CPDOMEventStop; - -@implementation CPDOMWindowBridge : CPObject -{ - CPArray _orderedWindows; - CPWindow _mouseDownWindow; - - DOMWindow _DOMWindow; - DOMElement _DOMBodyElement; - DOMElement _DOMFocusElement; - - CPArray _windowLevels; - CPDictionary _windowLayers; - - CPRect _frame; - CPRect _contentBounds; - - BOOL _mouseIsDown; - CPTimeInterval _lastMouseUp; - CPTimeInterval _lastMouseDown; - - JSObject _charCodes; - unsigned _keyCode; - - BOOL _DOMEventMode; - - // Native Pasteboard Support - DOMElement _DOMPasteboardElement; - CPEvent _pasteboardKeyDownEvent; - - CPString _overriddenEventType; -} - -/*! - Returns the shared DOMWindowBridge. -*/ -+ (id)sharedDOMWindowBridge -{ - if (!CPSharedDOMWindowBridge) - CPSharedDOMWindowBridge = [[CPDOMWindowBridge alloc] _initWithDOMWindow:window]; - - return CPSharedDOMWindowBridge; -} - -- (id)initWithFrame:(CPRect)aFrame -{ - alert("unimplemented"); -} - -/* @ignore */ -- (id)_initWithDOMWindow:(DOMWindow)aDOMWindow -{ - self = [super init]; - - if (self) - { - _DOMWindow = aDOMWindow; - - _windowLevels = []; - _windowLayers = [CPDictionary dictionary]; - - // Do this before getting the frame of the window, because if not it will be wrong in IE. - _DOMBodyElement = document.getElementsByTagName("body")[0]; - _DOMBodyElement.innerHTML = ""; // Get rid of anything that might be lingering in the body element. - _DOMBodyElement.style.overflow = "hidden"; - _DOMBodyElement.style.webkitTouchCallout = "none"; - - [CPString _resetSize]; - - if (document.documentElement) - document.documentElement.style.overflow = "hidden"; - - _frame = CPDOMWindowGetFrame(_DOMWindow); - _contentBounds = CGRectMake(0.0, 0.0, CPRectGetWidth(_frame), CPRectGetHeight(_frame)); - - _DOMFocusElement = document.createElement("input"); - _DOMFocusElement.style.position = "absolute"; - _DOMFocusElement.style.zIndex = "-1000"; - _DOMFocusElement.style.opacity = "0"; - _DOMFocusElement.style.filter = "alpha(opacity=0)"; - _DOMBodyElement.appendChild(_DOMFocusElement); - - // Create Native Pasteboard handler. - _DOMPasteboardElement = document.createElement("input"); - _DOMPasteboardElement.style.position = "absolute"; - _DOMPasteboardElement.style.top = "-10000px"; - _DOMPasteboardElement.style.zIndex = "99"; - - _DOMBodyElement.appendChild(_DOMPasteboardElement); - - // Make sure the pastboard element is blurred. - _DOMPasteboardElement.blur(); - - _charCodes = {}; - - // - var theClass = [self class], - - keyEventSelector = @selector(_bridgeKeyEvent:), - keyEventImplementation = class_getMethodImplementation(theClass, keyEventSelector), - keyEventCallback = function (anEvent) { keyEventImplementation(self, nil, anEvent); }, - - mouseEventSelector = @selector(_bridgeMouseEvent:), - mouseEventImplementation = class_getMethodImplementation(theClass, mouseEventSelector), - mouseEventCallback = function (anEvent) { mouseEventImplementation(self, nil, anEvent); }, - - scrollEventSelector = @selector(_bridgeScrollEvent:), - scrollEventImplementation = class_getMethodImplementation(theClass, scrollEventSelector), - scrollEventCallback = function (anEvent) { scrollEventImplementation(self, nil, anEvent); }, - - resizeEventSelector = @selector(_bridgeResizeEvent:), - resizeEventImplementation = class_getMethodImplementation(theClass, resizeEventSelector), - resizeEventCallback = function (anEvent) { resizeEventImplementation(self, nil, anEvent); }, - - touchEventSelector = @selector(_bridgeTouchEvent:), - touchEventImplementation = class_getMethodImplementation(theClass, touchEventSelector), - touchEventCallback = function (anEvent) { touchEventImplementation(self, nil, anEvent); }, - - theDocument = _DOMWindow.document; - - if (document.addEventListener) - { - _DOMWindow.addEventListener("resize", resizeEventCallback, NO); - - theDocument.addEventListener(CPDOMEventMouseUp, mouseEventCallback, NO); - theDocument.addEventListener(CPDOMEventMouseDown, mouseEventCallback, NO); - theDocument.addEventListener(CPDOMEventMouseMoved, mouseEventCallback, NO); - - theDocument.addEventListener(CPDOMEventKeyUp, keyEventCallback, NO); - theDocument.addEventListener(CPDOMEventKeyDown, keyEventCallback, NO); - theDocument.addEventListener(CPDOMEventKeyPress, keyEventCallback, NO); - - - theDocument.addEventListener(CPDOMEventTouchStart, touchEventCallback, NO); - theDocument.addEventListener(CPDOMEventTouchEnd, touchEventCallback, NO); - theDocument.addEventListener(CPDOMEventTouchMove, touchEventCallback, NO); - theDocument.addEventListener(CPDOMEventTouchCancel, touchEventCallback, NO); - - //FIXME: does firefox really need a different value? - _DOMWindow.addEventListener("DOMMouseScroll", scrollEventCallback, NO); - _DOMWindow.addEventListener(CPDOMEventScrollWheel, scrollEventCallback, NO); - } - else if(document.attachEvent) - { - _DOMWindow.attachEvent("onresize", resizeEventCallback); - - theDocument.attachEvent("on" + CPDOMEventMouseUp, mouseEventCallback); - theDocument.attachEvent("on" + CPDOMEventMouseDown, mouseEventCallback); - theDocument.attachEvent("on" + CPDOMEventMouseMoved, mouseEventCallback); - theDocument.attachEvent("on" + CPDOMEventDoubleClick, mouseEventCallback); - - theDocument.attachEvent("on" + CPDOMEventKeyUp, keyEventCallback); - theDocument.attachEvent("on" + CPDOMEventKeyDown, keyEventCallback); - theDocument.attachEvent("on" + CPDOMEventKeyPress, keyEventCallback); - - _DOMWindow.onmousewheel = scrollEventCallback; - theDocument.onmousewheel = scrollEventCallback; - - theDocument.body.ondrag = function () { return NO; }; - theDocument.body.onselectstart = function () { return window.event.srcElement == _DOMPasteboardElement; }; - } - - ExcludedDOMElements["INPUT"] = YES; - ExcludedDOMElements["SELECT"] = YES; - ExcludedDOMElements["TEXTAREA"] = YES; - ExcludedDOMElements["OPTION"] = YES; - } - - return self; -} - -- (CPRect)frame -{ - return CGRectMakeCopy(_frame); -} - -- (CGRect)visibleFrame -{ - var frame = [self frame]; - - frame.origin = CGPointMakeZero(); - - if ([CPMenu menuBarVisible]) - { - var menuBarHeight = [[CPApp mainMenu] menuBarHeight]; - - frame.origin.y += menuBarHeight; - frame.size.height -= menuBarHeight; - } - - return frame; -} - -- (CPRect)contentBounds -{ - return CPRectCreateCopy(_contentBounds); -} - -- (CPArray)orderedWindowsAtLevel:(int)aLevel -{ - var layer = [self layerAtLevel:aLevel create:NO]; - - if (!layer) - return []; - - return [layer orderedWindows]; -} - -- (CPDOMWindowLayer)layerAtLevel:(int)aLevel create:(BOOL)aFlag -{ - var layer = [_windowLayers objectForKey:aLevel]; - - // If the layer doesn't currently exist, and the create flag is true, - // create the layer. - if (!layer && aFlag) - { - layer = [[CPDOMWindowLayer alloc] initWithLevel:aLevel]; - - [_windowLayers setObject:layer forKey:aLevel]; - - // Find the nearest layer. This is similar to a binary search, - // only we know we won't find the value. - var low = 0, - high = _windowLevels.length - 1, - middle; - - while (low <= high) - { - middle = FLOOR((low + high) / 2); - - if (_windowLevels[middle] > aLevel) - high = middle - 1; - else - low = middle + 1; - } - - [_windowLevels insertObject:aLevel atIndex:_windowLevels[middle] > aLevel ? middle : middle + 1]; - layer._DOMElement.style.zIndex = aLevel; - _DOMBodyElement.appendChild(layer._DOMElement); - } - - return layer; -} - -- (void)order:(CPWindowOrderingMode)aPlace window:(CPWindow)aWindow relativeTo:(CPWindow)otherWindow -{ - // Grab the appropriate level for the layer, and create it if - // necessary (if we are not simply removing the window). - var layer = [self layerAtLevel:[aWindow level] create:aPlace != CPWindowOut]; - - // Ignore otherWindow, simply remove this window from it's level. - // If layer is nil, this will be a no-op. - if (aPlace == CPWindowOut) - return [layer removeWindow:aWindow]; - - // Place the window at the appropriate index. - [layer insertWindow:aWindow atIndex:(otherWindow ? (aPlace == CPWindowAbove ? otherWindow._index + 1 : otherWindow._index) : CPNotFound)]; -} - -/* @ignore */ -- (id)_dragHitTest:(CPPoint)aPoint pasteboard:(CPPasteboard)aPasteboard -{ - var levels = _windowLevels, - layers = _windowLayers, - levelCount = levels.length; - - while (levelCount--) - { - // Skip any windows above or at the dragging level. - if (levels[levelCount] >= CPDraggingWindowLevel) - continue; - - var windows = [layers objectForKey:levels[levelCount]]._windows, - windowCount = windows.length; - - while (windowCount--) - { - var theWindow = windows[windowCount]; - - if ([theWindow containsPoint:aPoint]) - return [theWindow _dragHitTest:aPoint pasteboard:aPasteboard]; - } - } - - return nil; -} - -/* @ignore */ -- (void)_propagateCurrentDOMEvent:(BOOL)aFlag -{ - StopDOMEventPropagation = !aFlag; -} - -- (CPWindow)hitTest:(CPPoint)location -{ - var levels = _windowLevels, - layers = _windowLayers, - levelCount = levels.length, - theWindow = nil; - - while (levelCount-- && !theWindow) - { - var windows = [layers objectForKey:levels[levelCount]]._windows, - windowCount = windows.length; - - while (windowCount-- && !theWindow) - { - var candidateWindow = windows[windowCount]; - - if (!candidateWindow._ignoresMouseEvents && [candidateWindow containsPoint:location]) - theWindow = candidateWindow; - } - } - - return theWindow; -} - -@end - -var CPDOMWindowGetFrame = function(_DOMWindow) -{ - var frame = nil;//CGRectMakeZero(); - - // We will rarely be able to get all this information, but we do the best we can: - if (_DOMWindow.outerWidth) - frame = CGRectMake(0, 0, _DOMWindow.outerWidth, _DOMWindow.outerHeight); - - else /*if(self.outerWidth)*/ - frame = CGRectMake(0, 0, -1, -1); - - if (window.screenTop) - frame.origin = CGPointMake(_DOMWindow.screenLeft, _DOMWindow.screenTop, 0); - - else if (window.screenX) - frame.origin = CGPointMake(_DOMWindow.screenX, _DOMWindow.screenY, 0); - - // Safari, Mozilla, Firefox, and Opera - if (_DOMWindow.innerWidth) - frame.size = CGSizeMake(_DOMWindow.innerWidth, _DOMWindow.innerHeight); - - // Internet Explorer 6 in Strict Mode - else if (document.documentElement && document.documentElement.clientWidth) - frame.size = CGSizeMake(_DOMWindow.document.documentElement.clientWidth, _DOMWindow.document.documentElement.clientHeight); - - // Internet Explorer X - else - frame.size = CGSizeMake(_DOMWindow.document.body.clientWidth, _DOMWindow.document.body.clientHeight); - - return frame; -} - -//right now we hard code q, w, r and t as keys to propogate -//these aren't normal keycodes, they are with modifier key codes -//might be mac only, we should investigate futher later. -var KeyCodesToPrevent = {}, - CharacterKeysToPrevent = {}, - KeyCodesWithoutKeyPressEvents = { '8':1, '9':1, '16':1, '37':1, '38':1, '39':1, '40':1, '46':1, '33':1, '34':1 }; - -var CTRL_KEY_CODE = 17; - -@implementation CPDOMWindowBridge (Events) - -/*! - When using command (mac) or control (windows), keys are propagated to the browser by default. - To prevent a character key from propagating (to prevent its default action, and instead use it - in your own application), use these methods. These methods are additive -- the list builds until you clear it. - - @param characters a list of characters to stop propagating keypresses to the browser. -*/ -- (void)preventCharacterKeysFromPropagating:(CPArray)characters -{ - for(var i=characters.length; i>0; i--) - CharacterKeysToPrevent[""+characters[i-1].toLowerCase()] = YES; -} - -/*! - @param character a character to stop propagating keypresses to the browser. -*/ -- (void)preventCharacterKeyFromPropagating:(CPString)character -{ - CharacterKeysToPrevent[character.toLowerCase()] = YES; -} - -/*! - Clear the list of characters for which we are not sending keypresses to the browser. -*/ -- (void)clearCharacterKeysToPreventFromPropagating -{ - CharacterKeysToPrevent = {}; -} - -/*! - Prevent these keyCodes from sending their keypresses to the browser. - @param keyCodes an array of keycodes to prevent propagation. -*/ -- (void)preventKeyCodesFromPropagating:(CPArray)keyCodes -{ - for(var i=keyCodes.length; i>0; i--) - KeyCodesToPrevent[keyCodes[i-1]] = YES; -} - -/*! - Prevent this keyCode from sending its key events to the browser. - @param keyCode a keycode to prevent propagation. -*/ -- (void)preventKeyCodeFromPropagating:(CPString)keyCode -{ - KeyCodesToPrevent[keyCode] = YES; -} - -/*! - Clear the list of keyCodes for which we are not sending keypresses to the browser. -*/ -- (void)clearKeyCodesToPreventFromPropagating -{ - KeyCodesToPrevent = {}; -} - -/* @ignore */ -- (void)_bridgeMouseEvent:(DOMEvent)aDOMEvent -{ - var theType = _overriddenEventType || aDOMEvent.type; - - // IE's event order is down, up, up, dblclick, so we have create these events artificially. - if (theType === CPDOMEventDoubleClick) - { - _overriddenEventType = CPDOMEventMouseDown; - [self _bridgeMouseEvent:aDOMEvent]; - - _overriddenEventType = CPDOMEventMouseUp; - [self _bridgeMouseEvent:aDOMEvent]; - - _overriddenEventType = nil; - - return; - } - -#ifndef DEBUG - try - { -#endif - var event, - location = _CGPointMake(aDOMEvent.clientX, aDOMEvent.clientY), - timestamp = aDOMEvent.timeStamp ? aDOMEvent.timeStamp : new Date(), - sourceElement = (aDOMEvent.target || aDOMEvent.srcElement), - windowNumber = 0, - modifierFlags = (aDOMEvent.shiftKey ? CPShiftKeyMask : 0) | - (aDOMEvent.ctrlKey ? CPControlKeyMask : 0) | - (aDOMEvent.altKey ? CPAlternateKeyMask : 0) | - (aDOMEvent.metaKey ? CPCommandKeyMask : 0); - - StopDOMEventPropagation = YES; - - if (_mouseDownWindow) - windowNumber = [_mouseDownWindow windowNumber]; - else - { - var theWindow = [self hitTest:location]; - - if ((aDOMEvent.type === CPDOMEventMouseDown) && theWindow) - _mouseDownWindow = theWindow; - - windowNumber = [theWindow windowNumber]; - } - - if (windowNumber) - { - var windowFrame = CPApp._windows[windowNumber]._frame; - - location.x -= _CGRectGetMinX(windowFrame); - location.y -= _CGRectGetMinY(windowFrame); - } - - switch (theType) - { - case CPDOMEventMouseUp: if(_mouseIsDown) - { - event = _CPEventFromNativeMouseEvent(aDOMEvent, CPLeftMouseUp, location, modifierFlags, timestamp, windowNumber, nil, -1, CPDOMEventGetClickCount(_lastMouseUp, timestamp, location), 0); - - _mouseIsDown = NO; - _lastMouseUp = event; - _mouseDownWindow = nil; - } - - if(_DOMEventMode) - { - _DOMEventMode = NO; - return; - } - - break; - - case CPDOMEventMouseDown: if (ExcludedDOMElements[sourceElement.tagName] && sourceElement != _DOMFocusElement) - { - _DOMEventMode = YES; - _mouseIsDown = YES; - - //fake a down and up event so that event tracking mode will work correctly - [CPApp sendEvent:[CPEvent mouseEventWithType:CPLeftMouseDown location:location modifierFlags:modifierFlags - timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:-1 - clickCount:CPDOMEventGetClickCount(_lastMouseDown, timestamp, location) pressure:0]]; - - [CPApp sendEvent:[CPEvent mouseEventWithType:CPLeftMouseUp location:location modifierFlags:modifierFlags - timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:-1 - clickCount:CPDOMEventGetClickCount(_lastMouseDown, timestamp, location) pressure:0]]; - - return; - } - - event = _CPEventFromNativeMouseEvent(aDOMEvent, CPLeftMouseDown, location, modifierFlags, timestamp, windowNumber, nil, -1, CPDOMEventGetClickCount(_lastMouseDown, timestamp, location), 0); - - _mouseIsDown = YES; - _lastMouseDown = event; - - break; - - case CPDOMEventMouseMoved: if (_DOMEventMode) - return; - - event = _CPEventFromNativeMouseEvent(aDOMEvent, _mouseIsDown ? CPLeftMouseDragged : CPMouseMoved, location, modifierFlags, timestamp, windowNumber, nil, -1, 1, 0); - - break; - } - - if (event) - { - event._DOMEvent = aDOMEvent; - - [CPApp sendEvent:event]; - } - - if (StopDOMEventPropagation) - CPDOMEventStop(aDOMEvent); - - [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; -#ifndef DEBUG - } - catch (anException) - { - objj_exception_report(anException, {path:@"CPDOMWindowBridge.j"}); - } -#endif -} - -/* @ignore */ -- (void)_bridgeKeyEvent:(DOMEvent)aDOMEvent -{ -#ifndef DEBUG - try - { -#endif - var event, - timestamp = aDOMEvent.timeStamp ? aDOMEvent.timeStamp : new Date(), - sourceElement = (aDOMEvent.target || aDOMEvent.srcElement), - windowNumber = [[CPApp keyWindow] windowNumber], - modifierFlags = (aDOMEvent.shiftKey ? CPShiftKeyMask : 0) | - (aDOMEvent.ctrlKey ? CPControlKeyMask : 0) | - (aDOMEvent.altKey ? CPAlternateKeyMask : 0) | - (aDOMEvent.metaKey ? CPCommandKeyMask : 0); - - if (ExcludedDOMElements[sourceElement.tagName] && sourceElement != _DOMFocusElement && sourceElement != _DOMPasteboardElement) - return; - - //We want to stop propagation if this is a command key AND this character or keycode has been added to our blacklist - StopDOMEventPropagation = !(modifierFlags & (CPControlKeyMask | CPCommandKeyMask)) || - CharacterKeysToPrevent[String.fromCharCode(aDOMEvent.keyCode || aDOMEvent.charCode).toLowerCase()] || - KeyCodesToPrevent[aDOMEvent.keyCode]; - - var isNativePasteEvent = NO, - isNativeCopyOrCutEvent = NO; - - switch (aDOMEvent.type) - { - case CPDOMEventKeyDown: // Grab and store the keycode now since it is correct and consistent at this point. - _keyCode = aDOMEvent.keyCode; - - var characters = String.fromCharCode(_keyCode).toLowerCase(); - - // If this could be a native PASTE event, then we need to further examine it before - // sending a CPEvent. Select our element to see if anything gets pasted in it. - if (characters == "v" && (modifierFlags & CPPlatformActionKeyMask)) - { - _DOMPasteboardElement.select(); - _DOMPasteboardElement.value = ""; - - isNativePasteEvent = YES; - } - - // Normally we return now because we let keypress send the actual CPEvent keyDown event, since we don't have - // a complete set of information yet. - - // However, of this could be a native COPY event, we need to let the normal event-process take place so it - // can capture our internal Cappuccino pasteboard. - else if ((characters == "c" || characters == "x") && (modifierFlags & CPPlatformActionKeyMask)) - isNativeCopyOrCutEvent = YES; - - // Also, certain browsers (IE and Safari), have broken keyboard supportwhere they don't send keypresses for certain events. - // So, allow the keypress event to handle the event if we are not a browser with broken (remedial) key support... - else if (!CPFeatureIsCompatible(CPJavascriptRemedialKeySupport)) - return; - - // Or, if this is not one of those special keycodes, and also not a ctrl+event - else if (!KeyCodesWithoutKeyPressEvents[_keyCode] && (_keyCode == CTRL_KEY_CODE || !(modifierFlags & CPControlKeyMask))) - return; - - // If this is in fact our broke state, continue to keypress and send the keydown. - case CPDOMEventKeyPress: - // If the source of this event is our pasteboard element, then simply let it continue - // as normal, so that the paste event can successfully complete. - if ((aDOMEvent.target || aDOMEvent.srcElement) == _DOMPasteboardElement) - return; - - var keyCode = _keyCode, - charCode = aDOMEvent.keyCode || aDOMEvent.charCode, - isARepeat = (_charCodes[keyCode] != nil); - - _charCodes[keyCode] = charCode; - - var characters = String.fromCharCode(charCode), - charactersIgnoringModifiers = characters.toLowerCase(); - - event = [CPEvent keyEventWithType:CPKeyDown location:location modifierFlags:modifierFlags - timestamp:timestamp windowNumber:windowNumber context:nil - characters:characters charactersIgnoringModifiers:charactersIgnoringModifiers isARepeat:isARepeat keyCode:keyCode]; - - if (isNativePasteEvent) - { - _pasteboardKeyDownEvent = event; - - window.setNativeTimeout(function () { [self _checkPasteboardElement] }, 0); - - return; - } - - break; - - case CPDOMEventKeyUp: var keyCode = aDOMEvent.keyCode, - charCode = _charCodes[keyCode]; - - _charCodes[keyCode] = nil; - - var characters = String.fromCharCode(charCode), - charactersIgnoringModifiers = characters.toLowerCase(); - - if (!(modifierFlags & CPShiftKeyMask)) - characters = charactersIgnoringModifiers; - - event = [CPEvent keyEventWithType:CPKeyUp location:location modifierFlags:modifierFlags - timestamp: timestamp windowNumber:windowNumber context:nil - characters:characters charactersIgnoringModifiers:charactersIgnoringModifiers isARepeat:NO keyCode:keyCode]; - break; - } - - if (event) - { - event._DOMEvent = aDOMEvent; - - [CPApp sendEvent:event]; - - if (isNativeCopyOrCutEvent) - { - var pasteboard = [CPPasteboard generalPasteboard], - types = [pasteboard types]; - - // If this is a native copy event, then check if the pasteboard has anything in it. - if (types.length) - { - if ([types indexOfObjectIdenticalTo:CPStringPboardType] != CPNotFound) - _DOMPasteboardElement.value = [pasteboard stringForType:CPStringPboardType]; - else - _DOMPasteboardElement.value = [pasteboard _generateStateUID]; - - _DOMPasteboardElement.select(); - - window.setNativeTimeout(function() { [self _clearPasteboardElement]; }, 0); - } - - return; - } - } - - if (StopDOMEventPropagation) - CPDOMEventStop(aDOMEvent); - - [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; -#ifndef DEBUG - } - catch (anException) - { - objj_exception_report(anException, {path:@"CPDOMWindowBridge.j"}); - } -#endif -} - -/* @ignore */ -- (void)_bridgeScrollEvent:(DOMEvent)aDOMEvent -{ - if(!aDOMEvent) - aDOMEvent = window.event; - -#ifndef DEBUG - try - { -#endif - if (CPFeatureIsCompatible(CPJavaScriptMouseWheelValues_8_15)) - { - var x = 0.0, - y = 0.0, - element = aDOMEvent.target; - - while (element.nodeType !== 1) - element = element.parentNode; - - if (element.offsetParent) - { - do - { - x += element.offsetLeft; - y += element.offsetTop; - - } while (element = element.offsetParent); - } - - var location = _CGPointMake((x + ((aDOMEvent.clientX - 8) / 15)), (y + ((aDOMEvent.clientY - 8) / 15)));} - else - var location = _CGPointMake(aDOMEvent.clientX, aDOMEvent.clientY); - - var deltaX = 0.0, - deltaY = 0.0, - windowNumber = 0, - timestamp = aDOMEvent.timeStamp ? aDOMEvent.timeStamp : new Date(), - modifierFlags = (aDOMEvent.shiftKey ? CPShiftKeyMask : 0) | - (aDOMEvent.ctrlKey ? CPControlKeyMask : 0) | - (aDOMEvent.altKey ? CPAlternateKeyMask : 0) | - (aDOMEvent.metaKey ? CPCommandKeyMask : 0); - - StopDOMEventPropagation = YES; - - windowNumber = [[self hitTest:location] windowNumber]; - - if (!windowNumber) - return; - - var windowFrame = CPApp._windows[windowNumber]._frame; - - location.x -= CGRectGetMinX(windowFrame); - location.y -= CGRectGetMinY(windowFrame); - - if(typeof aDOMEvent.wheelDeltaX != "undefined") - { - deltaX = aDOMEvent.wheelDeltaX / 120.0; - deltaY = aDOMEvent.wheelDeltaY / 120.0; - } - - else if (aDOMEvent.wheelDelta) - deltaY = aDOMEvent.wheelDelta / 120.0; - - else if (aDOMEvent.detail) - deltaY = -aDOMEvent.detail / 3.0; - - else - return; - - if(!CPFeatureIsCompatible(CPJavaScriptNegativeMouseWheelValues)) - { - deltaX = -deltaX; - deltaY = -deltaY; - } - - var event = [CPEvent mouseEventWithType:CPScrollWheel location:location modifierFlags:modifierFlags - timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:-1 clickCount:1 pressure:0 ]; - - event._DOMEvent = aDOMEvent; - event._deltaX = deltaX; - event._deltaY = deltaY; - - [CPApp sendEvent:event]; - - if (StopDOMEventPropagation) - CPDOMEventStop(aDOMEvent); - - [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; -#ifndef DEBUG - } - catch (anException) - { - objj_exception_report(anException, {path:@"CPDOMWindowBridge.j"}); - } -#endif -} - -/* @ignore */ -- (void)_bridgeResizeEvent:(DOMEvent)aDOMEvent -{ -#ifndef DEBUG - try - { -#endif - // FIXME: This is not the right way to do this. - // We should pay attention to mouse down and mouse up in conjunction with this. - //window.liveResize = YES; - - var oldSize = _frame.size; - - // window.liveResize = YES? - _frame = CPDOMWindowGetFrame(_DOMWindow); - _contentBounds.size = CGSizeCreateCopy(_frame.size); - - var levels = _windowLevels, - layers = _windowLayers, - levelCount = levels.length; - - while (levelCount--) - { - var windows = [layers objectForKey:levels[levelCount]]._windows, - windowCount = windows.length; - - while (windowCount--) - [windows[windowCount] resizeWithOldBridgeSize:oldSize]; - } - - //window.liveResize = NO; - - [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; -#ifndef DEBUG - } - catch (anException) - { - objj_exception_report(anException, {path:@"CPDOMWindowBridge.j"}); - } -#endif -} - -// DOM event properties used in mouse bridge code - -// type -// clientX -// clientY -// timestamp -// target/srcElement -// shiftKey,ctrlKey,altKey,metaKey - -/* @ignore */ -- (void)_bridgeTouchEvent:(DOMEvent)aDOMEvent -{ -#ifndef DEBUG - try - { -#endif - if (aDOMEvent.touches && (aDOMEvent.touches.length == 1 || (aDOMEvent.touches.length == 0 && aDOMEvent.changedTouches.length == 1))) - { - var newEvent = {}; - - switch(aDOMEvent.type) - { - case CPDOMEventTouchStart: newEvent.type = CPDOMEventMouseDown; - break; - case CPDOMEventTouchEnd: newEvent.type = CPDOMEventMouseUp; - break; - case CPDOMEventTouchMove: newEvent.type = CPDOMEventMouseMoved; - break; - case CPDOMEventTouchCancel: newEvent.type = CPDOMEventMouseUp; - break; - } - - var touch = aDOMEvent.touches.length ? aDOMEvent.touches[0] : aDOMEvent.changedTouches[0]; - - newEvent.clientX = touch.clientX; - newEvent.clientY = touch.clientY; - - newEvent.timestamp = aDOMEvent.timestamp; - newEvent.target = aDOMEvent.target; - - newEvent.shiftKey = newEvent.ctrlKey = newEvent.altKey = newEvent.metaKey = false; - - newEvent.preventDefault = function(){if(aDOMEvent.preventDefault) aDOMEvent.preventDefault()}; - newEvent.stopPropagation = function(){if(aDOMEvent.stopPropagation) aDOMEvent.stopPropagation()}; - - [self _bridgeMouseEvent:newEvent]; - - return; - } - else - { - if (aDOMEvent.preventDefault) - aDOMEvent.preventDefault(); - - if (aDOMEvent.stopPropagation) - aDOMEvent.stopPropagation(); - } -#ifndef DEBUG - } - catch (anException) - { - objj_exception_report(anException, {path:@"CPDOMWindowBridge.j"}); - } -#endif - // handle touch cases specifically -} - -/* @ignore */ -- (void)_checkPasteboardElement -{ -#ifndef DEBUG - try - { -#endif - var value = _DOMPasteboardElement.value; - - if ([value length]) - { - var pasteboard = [CPPasteboard generalPasteboard]; - - if ([pasteboard _stateUID] != value) - { - [pasteboard declareTypes:[CPStringPboardType] owner:self]; - - [pasteboard setString:value forType:CPStringPboardType]; - } - } - - [self _clearPasteboardElement]; - - [CPApp sendEvent:_pasteboardKeyDownEvent]; - - _pasteboardKeyDownEvent = nil; - - [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; -#ifndef DEBUG - } - catch (anException) - { - objj_exception_report(anException, {path:@"CPDOMWindowBridge.j"}); - } -#endif -} - -/* @ignore */ -- (void)_clearPasteboardElement -{ - _DOMPasteboardElement.value = ""; - _DOMPasteboardElement.blur(); -} - -@end - -var CLICK_SPACE_DELTA = 5.0, - CLICK_TIME_DELTA = (typeof document != "undefined" && document.addEventListener) ? 350.0 : 1000.0; - -var CPDOMEventGetClickCount = function(aComparisonEvent, aTimestamp, aLocation) -{ - if (!aComparisonEvent) - return 1; - - var comparisonLocation = [aComparisonEvent locationInWindow]; - - return (aTimestamp - [aComparisonEvent timestamp] < CLICK_TIME_DELTA && - ABS(comparisonLocation.x - aLocation.x) < CLICK_SPACE_DELTA && - ABS(comparisonLocation.y - aLocation.y) < CLICK_SPACE_DELTA) ? [aComparisonEvent clickCount] + 1 : 1; -} - -var CPDOMEventStop = function(aDOMEvent) -{ - // IE Model - aDOMEvent.cancelBubble = true; - aDOMEvent.returnValue = false; - - // W3C Model - if (aDOMEvent.preventDefault) - aDOMEvent.preventDefault(); - - if (aDOMEvent.stopPropagation) - aDOMEvent.stopPropagation(); - - if (aDOMEvent.type === CPDOMEventMouseDown) - { - CPSharedDOMWindowBridge._DOMFocusElement.focus(); - CPSharedDOMWindowBridge._DOMFocusElement.blur(); - } -} - -function CPWindowObjectList() -{ - var bridge = [CPDOMWindowBridge sharedDOMWindowBridge], - levels = bridge._windowLevels, - layers = bridge._windowLayers, - levelCount = levels.length, - windowObjects = []; - - while (levelCount--) - { - var windows = [layers objectForKey:levels[levelCount]]._windows, - windowCount = windows.length; - - while (windowCount--) - windowObjects.push(windows[windowCount]); - } - - return windowObjects; -} - -function CPWindowList() -{ - var bridge = [CPDOMWindowBridge sharedDOMWindowBridge], - levels = bridge._windowLevels, - layers = bridge._windowLayers, - levelCount = levels.length, - windowNumbers = []; - - while (levelCount--) - { - var windows = [layers objectForKey:levels[levelCount]]._windows, - windowCount = windows.length; - - while (windowCount--) - windowNumbers.push([windows[windowCount] windowNumber]); - } - - return windowNumbers; -} diff --git a/AppKit/Platform/DOM/CPDOMWindowLayer.j b/AppKit/Platform/DOM/CPDOMWindowLayer.j index bb5c5c882..3d6f3dede 100644 --- a/AppKit/Platform/DOM/CPDOMWindowLayer.j +++ b/AppKit/Platform/DOM/CPDOMWindowLayer.j @@ -115,7 +115,7 @@ aWindow._isVisible = YES; if ([aWindow isFullBridge]) - [aWindow setFrame:[aWindow._bridge visibleFrame]]; + [aWindow setFrame:[aWindow._platformWindow usableContentFrame]]; } } diff --git a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j new file mode 100644 index 000000000..c491a9a2a --- /dev/null +++ b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j @@ -0,0 +1,1025 @@ +/* + * _CPDOMWindow.j + * AppKit + * + * Created by Francisco Tolmasky. + * Copyright 2008, 280 North, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +@import +@import + +@import "CPEvent.j" +@import "CPCompatibility.j" + +@import "CPDOMWindowLayer.j" + +@import "CPPlatformWindow.j" + +#import "../../CoreGraphics/CGGeometry.h" + + +var DoubleClick = "dblclick", + MouseDown = "mousedown", + MouseUp = "mouseup", + MouseMove = "mousemove", + MouseDrag = "mousedrag", + KeyUp = "keyup", + KeyDown = "keydown", + KeyPress = "keypress", + Copy = "copy", + Paste = "paste", + Resize = "resize", + ScrollWheel = "mousewheel", + TouchStart = "touchstart", + TouchMove = "touchmove", + TouchEnd = "touchend", + TouchCancel = "touchcancel"; + +var ExcludedDOMElements = []; + +ExcludedDOMElements["INPUT"] = YES; +ExcludedDOMElements["SELECT"] = YES; +ExcludedDOMElements["TEXTAREA"] = YES; +ExcludedDOMElements["OPTION"] = YES; + +// Define up here so compressor knows about em. +var CPDOMEventGetClickCount, + CPDOMEventStop; + +//right now we hard code q, w, r and t as keys to propogate +//these aren't normal keycodes, they are with modifier key codes +//might be mac only, we should investigate futher later. +var KeyCodesToPrevent = {}, + CharacterKeysToPrevent = {}, + KeyCodesWithoutKeyPressEvents = { '8':1, '9':1, '16':1, '37':1, '38':1, '39':1, '40':1, '46':1, '33':1, '34':1 }; + +var CTRL_KEY_CODE = 17; + +@implementation CPPlatformWindow (DOM) + +- (id)_init +{ + self = [super init]; + + if (self) + { + _DOMWindow = window; + _contentRect = _CGRectMakeZero(); + + [self registerDOMWindow]; + [self updateFromNativeContentRect]; + + _charCodes = {}; + + _windowLevels = []; + _windowLayers = [CPDictionary dictionary]; + } + + return self; +} + +- (CGRect)nativeContentRect +{ + if (!_DOMWindow) + return [self contentRect]; + + var contentRect = _CGRectMakeZero(); + + if (window.screenTop) + contentRect.origin = _CGPointMake(_DOMWindow.screenLeft, _DOMWindow.screenTop); + + else if (window.screenX) + contentRect.origin = _CGPointMake(_DOMWindow.screenX, _DOMWindow.screenY); + + // Safari, Mozilla, Firefox, and Opera + if (_DOMWindow.innerWidth) + contentRect.size = _CGSizeMake(_DOMWindow.innerWidth, _DOMWindow.innerHeight); + + // Internet Explorer 6 in Strict Mode + else if (document.documentElement && document.documentElement.clientWidth) + contentRect.size = _CGSizeMake(_DOMWindow.document.documentElement.clientWidth, _DOMWindow.document.documentElement.clientHeight); + + // Internet Explorer X + else + contentRect.size = _CGSizeMake(_DOMWindow.document.body.clientWidth, _DOMWindow.document.body.clientHeight); + + return contentRect; +} + +- (void)updateNativeContentOrigin +{ + if (!_DOMWindow) + return; + + var origin = [self contentRect].origin, + nativeOrigin = [self nativeContentRect].origin; + + _DOMWindow.moveBy(origin.x - nativeOrigin.x, origin.y - nativeOrigin.y); +} + +- (void)updateNativeContentSize +{ + if (!_DOMWindow) + return; + + var size = [self contentRect].size, + nativeSize = [self nativeContentRect].size; + + _DOMWindow.resizeBy(size.width - nativeSize.width, size.height - nativeSize.height); +} + +- (void)orderBack:(id)aSender +{ + if (_DOMWindow) + _DOMWindow.blur(); +} + +- (void)registerDOMWindow +{ + var theDocument = _DOMWindow.document; + + _DOMBodyElement = theDocument.getElementsByTagName("body")[0]; + + _DOMBodyElement.webkitTouchCallout = "none"; + + _DOMFocusElement = theDocument.createElement("input"); + + _DOMFocusElement.style.position = "absolute"; + _DOMFocusElement.style.zIndex = "-1000"; + _DOMFocusElement.style.opacity = "0"; + _DOMFocusElement.style.filter = "alpha(opacity=0)"; + + _DOMBodyElement.appendChild(_DOMFocusElement); + + // Create Native Pasteboard handler. + _DOMPasteboardElement = theDocument.createElement("input"); + + _DOMPasteboardElement.style.position = "absolute"; + _DOMPasteboardElement.style.top = "-10000px"; + _DOMPasteboardElement.style.zIndex = "99"; + + _DOMBodyElement.appendChild(_DOMPasteboardElement); + + // Make sure the pastboard element is blurred. + _DOMPasteboardElement.blur(); + + var theClass = [self class], + + resizeEventSelector = @selector(resizeEvent:), + resizeEventImplementation = class_getMethodImplementation(theClass, resizeEventSelector), + resizeEventCallback = function (anEvent) { resizeEventImplementation(self, nil, anEvent); }, + + keyEventSelector = @selector(keyEvent:), + keyEventImplementation = class_getMethodImplementation(theClass, keyEventSelector), + keyEventCallback = function (anEvent) { keyEventImplementation(self, nil, anEvent); }, + + mouseEventSelector = @selector(mouseEvent:), + mouseEventImplementation = class_getMethodImplementation(theClass, mouseEventSelector), + mouseEventCallback = function (anEvent) { mouseEventImplementation(self, nil, anEvent); }, + + scrollEventSelector = @selector(scrollEvent:), + scrollEventImplementation = class_getMethodImplementation(theClass, scrollEventSelector), + scrollEventCallback = function (anEvent) { scrollEventImplementation(self, nil, anEvent); }, + + touchEventSelector = @selector(touchEvent:), + touchEventImplementation = class_getMethodImplementation(theClass, touchEventSelector), + touchEventCallback = function (anEvent) { touchEventImplementation(self, nil, anEvent); }; + + if (theDocument.addEventListener) + { + theDocument.addEventListener("mouseup", mouseEventCallback, NO); + theDocument.addEventListener("mousedown", mouseEventCallback, NO); + theDocument.addEventListener("mousemove", mouseEventCallback, NO); + + theDocument.addEventListener("keyup", keyEventCallback, NO); + theDocument.addEventListener("keydown", keyEventCallback, NO); + theDocument.addEventListener("keypress", keyEventCallback, NO); + + theDocument.addEventListener("touchstart", touchEventCallback, NO); + theDocument.addEventListener("touchend", touchEventCallback, NO); + theDocument.addEventListener("touchmove", touchEventCallback, NO); + theDocument.addEventListener("touchcancel", touchEventCallback, NO); + + _DOMWindow.addEventListener("DOMMouseScroll", scrollEventCallback, NO); + _DOMWindow.addEventListener("mousewheel", scrollEventCallback, NO); + + _DOMWindow.addEventListener("resize", resizeEventCallback, NO); + + _DOMWindow.addEventListener("beforeunload", function() + { + [self updateFromNativeContentRect]; + + theDocument.removeEventListener("mouseup", mouseEventCallback, NO); + theDocument.removeEventListener("mousedown", mouseEventCallback, NO); + theDocument.removeEventListener("mousemove", mouseEventCallback, NO); + + theDocument.removeEventListener("keyup", keyEventCallback, NO); + theDocument.removeEventListener("keydown", keyEventCallback, NO); + theDocument.removeEventListener("keypress", keyEventCallback, NO); + + theDocument.removeEventListener("touchstart", touchEventCallback, NO); + theDocument.removeEventListener("touchend", touchEventCallback, NO); + theDocument.removeEventListener("touchmove", touchEventCallback, NO); + + _DOMWindow.removeEventListener("resize", resizeEventCallback, NO); + + //FIXME: does firefox really need a different value? + _DOMWindow.removeEventListener("DOMMouseScroll", scrollEventCallback, NO); + _DOMWindow.removeEventListener("mousewheel", scrollEventCallback, NO); + + //_DOMWindow.removeEventListener("beforeunload", this, NO); + + self._DOMWindow = nil; + }, NO); + } + else + { + theDocument.attachEvent("onmouseup", mouseEventCallback); + theDocument.attachEvent("onmousedown", mouseEventCallback); + theDocument.attachEvent("onmousemove", mouseEventCallback); + theDocument.attachEvent("ondblclick", mouseEventCallback); + + theDocument.attachEvent("onkeyup", keyEventCallback); + theDocument.attachEvent("onkeydown", keyEventCallback); + theDocument.attachEvent("onkeypress", keyEventCallback); + + _DOMWindow.attachEvent("onresize", resizeEventCallback); + + _DOMWindow.onmousewheel = scrollEventCallback; + theDocument.onmousewheel = scrollEventCallback; + + theDocument.body.ondrag = function () { return NO; }; + theDocument.body.onselectstart = function () { return _DOMWindow.event.srcElement === _DOMPasteboardElement; }; + + _DOMWindow.attachEvent("onbeforeunload", function() + { + [self updateFromNativeContentRect]; + + theDocument.removeEvent("onmouseup", mouseEventCallback); + theDocument.removeEvent("onmousedown", mouseEventCallback); + theDocument.removeEvent("onmousemove", mouseEventCallback); + theDocument.removeEvent("ondblclick", mouseEventCallback); + + theDocument.removeEvent("onkeyup", keyEventCallback); + theDocument.removeEvent("onkeydown", keyEventCallback); + theDocument.removeEvent("onkeypress", keyEventCallback); + + _DOMWindow.removeEvent("onresize", resizeEventCallback); + + _DOMWindow.onmousewheel = NULL; + theDocument.onmousewheel = NULL; + + theDocument.body.ondrag = NULL; + theDocument.body.onselectstart = NULL; + + //_DOMWindow.removeEvent("beforeunload", this); + + self._DOMWindow = nil; + }, NO); + } +} + +- (BOOL)isVisible +{ + return _DOMWindow !== NULL; +} + +- (void)orderFront:(id)aSender +{ + if (_DOMWindow) + return _DOMWindow.focus(); + + _DOMWindow = window.open("", "", "menubar=no,location=no,resizable=yes,scrollbars=no,status=no,left=" + _CGRectGetMinX(_contentRect) + ",top=" + _CGRectGetMinY(_contentRect) + ",width=" + _CGRectGetWidth(_contentRect) + ",height=" + _CGRectGetHeight(_contentRect)); + + [self registerDOMWindow]; +} + +- (void)orderOut:(id)aSender +{ + _DOMWindow.close(); +} + +- (void)keyEvent:(DOMEvent)aDOMEvent +{ + var event, + timestamp = aDOMEvent.timeStamp ? aDOMEvent.timeStamp : new Date(), + sourceElement = (aDOMEvent.target || aDOMEvent.srcElement), + windowNumber = [[CPApp keyWindow] windowNumber], + modifierFlags = (aDOMEvent.shiftKey ? CPShiftKeyMask : 0) | + (aDOMEvent.ctrlKey ? CPControlKeyMask : 0) | + (aDOMEvent.altKey ? CPAlternateKeyMask : 0) | + (aDOMEvent.metaKey ? CPCommandKeyMask : 0); + + if (ExcludedDOMElements[sourceElement.tagName] && sourceElement != _DOMFocusElement && sourceElement != _DOMPasteboardElement) + return; + + //We want to stop propagation if this is a command key AND this character or keycode has been added to our blacklist + StopDOMEventPropagation = !(modifierFlags & (CPControlKeyMask | CPCommandKeyMask)) || + CharacterKeysToPrevent[String.fromCharCode(aDOMEvent.keyCode || aDOMEvent.charCode).toLowerCase()] || + KeyCodesToPrevent[aDOMEvent.keyCode]; + + var isNativePasteEvent = NO, + isNativeCopyOrCutEvent = NO; + + switch (aDOMEvent.type) + { + case "keydown": // Grab and store the keycode now since it is correct and consistent at this point. + _keyCode = aDOMEvent.keyCode; + + var characters = String.fromCharCode(_keyCode).toLowerCase(); + + // If this could be a native PASTE event, then we need to further examine it before + // sending a CPEvent. Select our element to see if anything gets pasted in it. + if (characters == "v" && (modifierFlags & CPPlatformActionKeyMask)) + { + _DOMPasteboardElement.select(); + _DOMPasteboardElement.value = ""; + + isNativePasteEvent = YES; + } + + // Normally we return now because we let keypress send the actual CPEvent keyDown event, since we don't have + // a complete set of information yet. + + // However, of this could be a native COPY event, we need to let the normal event-process take place so it + // can capture our internal Cappuccino pasteboard. + else if ((characters == "c" || characters == "x") && (modifierFlags & CPPlatformActionKeyMask)) + isNativeCopyOrCutEvent = YES; + + // Also, certain browsers (IE and Safari), have broken keyboard supportwhere they don't send keypresses for certain events. + // So, allow the keypress event to handle the event if we are not a browser with broken (remedial) key support... + else if (!CPFeatureIsCompatible(CPJavascriptRemedialKeySupport)) + return; + + // Or, if this is not one of those special keycodes, and also not a ctrl+event + else if (!KeyCodesWithoutKeyPressEvents[_keyCode] && (_keyCode == CTRL_KEY_CODE || !(modifierFlags & CPControlKeyMask))) + return; + + // If this is in fact our broke state, continue to keypress and send the keydown. + case "keypress": // If the source of this event is our pasteboard element, then simply let it continue + // as normal, so that the paste event can successfully complete. + if ((aDOMEvent.target || aDOMEvent.srcElement) == _DOMPasteboardElement) + return; + + var keyCode = _keyCode, + charCode = aDOMEvent.keyCode || aDOMEvent.charCode, + isARepeat = (_charCodes[keyCode] != nil); + + _charCodes[keyCode] = charCode; + + var characters = String.fromCharCode(charCode), + charactersIgnoringModifiers = characters.toLowerCase(); + + event = [CPEvent keyEventWithType:CPKeyDown location:location modifierFlags:modifierFlags + timestamp:timestamp windowNumber:windowNumber context:nil + characters:characters charactersIgnoringModifiers:charactersIgnoringModifiers isARepeat:isARepeat keyCode:keyCode]; + + if (isNativePasteEvent) + { + _pasteboardKeyDownEvent = event; + + window.setNativeTimeout(function () { [self _checkPasteboardElement] }, 0); + + return; + } + + break; + + case "keyup": var keyCode = aDOMEvent.keyCode, + charCode = _charCodes[keyCode]; + + _charCodes[keyCode] = nil; + + var characters = String.fromCharCode(charCode), + charactersIgnoringModifiers = characters.toLowerCase(); + + if (!(modifierFlags & CPShiftKeyMask)) + characters = charactersIgnoringModifiers; + + event = [CPEvent keyEventWithType:CPKeyUp location:location modifierFlags:modifierFlags + timestamp: timestamp windowNumber:windowNumber context:nil + characters:characters charactersIgnoringModifiers:charactersIgnoringModifiers isARepeat:NO keyCode:keyCode]; + break; + } + + if (event) + { + event._DOMEvent = aDOMEvent; + + [CPApp sendEvent:event]; + + if (isNativeCopyOrCutEvent) + { + var pasteboard = [CPPasteboard generalPasteboard], + types = [pasteboard types]; + + // If this is a native copy event, then check if the pasteboard has anything in it. + if (types.length) + { + if ([types indexOfObjectIdenticalTo:CPStringPboardType] != CPNotFound) + _DOMPasteboardElement.value = [pasteboard stringForType:CPStringPboardType]; + else + _DOMPasteboardElement.value = [pasteboard _generateStateUID]; + + _DOMPasteboardElement.select(); + + window.setNativeTimeout(function() { [self _clearPasteboardElement]; }, 0); + } + + return; + } + } + + if (StopDOMEventPropagation) + CPDOMEventStop(aDOMEvent, self); + + [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; + +} + +- (void)scrollEvent:(DOMEvent)aDOMEvent +{ + if(!aDOMEvent) + aDOMEvent = window.event; + + if (CPFeatureIsCompatible(CPJavaScriptMouseWheelValues_8_15)) + { + var x = 0.0, + y = 0.0, + element = aDOMEvent.target; + + while (element.nodeType !== 1) + element = element.parentNode; + + if (element.offsetParent) + { + do + { + x += element.offsetLeft; + y += element.offsetTop; + + } while (element = element.offsetParent); + } + + var location = _CGPointMake((x + ((aDOMEvent.clientX - 8) / 15)), (y + ((aDOMEvent.clientY - 8) / 15))); + } + else + var location = _CGPointMake(aDOMEvent.clientX, aDOMEvent.clientY); + + var deltaX = 0.0, + deltaY = 0.0, + windowNumber = 0, + timestamp = aDOMEvent.timeStamp ? aDOMEvent.timeStamp : new Date(), + modifierFlags = (aDOMEvent.shiftKey ? CPShiftKeyMask : 0) | + (aDOMEvent.ctrlKey ? CPControlKeyMask : 0) | + (aDOMEvent.altKey ? CPAlternateKeyMask : 0) | + (aDOMEvent.metaKey ? CPCommandKeyMask : 0); + + StopDOMEventPropagation = YES; + + var theWindow = [self hitTest:location]; + + if (!theWindow) + return; + + var windowNumber = [theWindow windowNumber]; + + location = [theWindow convertBridgeToBase:location]; + + if(typeof aDOMEvent.wheelDeltaX != "undefined") + { + deltaX = aDOMEvent.wheelDeltaX / 120.0; + deltaY = aDOMEvent.wheelDeltaY / 120.0; + } + + else if (aDOMEvent.wheelDelta) + deltaY = aDOMEvent.wheelDelta / 120.0; + + else if (aDOMEvent.detail) + deltaY = -aDOMEvent.detail / 3.0; + + else + return; + + if(!CPFeatureIsCompatible(CPJavaScriptNegativeMouseWheelValues)) + { + deltaX = -deltaX; + deltaY = -deltaY; + } + + var event = [CPEvent mouseEventWithType:CPScrollWheel location:location modifierFlags:modifierFlags + timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:-1 clickCount:1 pressure:0 ]; + + event._DOMEvent = aDOMEvent; + event._deltaX = deltaX; + event._deltaY = deltaY; + + [CPApp sendEvent:event]; + + if (StopDOMEventPropagation) + CPDOMEventStop(aDOMEvent, self); + + [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; +} + +- (void)resizeEvent:(DOMEvent)aDOMEvent +{ + // FIXME: This is not the right way to do this. + // We should pay attention to mouse down and mouse up in conjunction with this. + //window.liveResize = YES; + + var oldSize = [self contentRect].size; + + [self updateFromNativeContentRect]; + + var levels = _windowLevels, + layers = _windowLayers, + levelCount = levels.length; + + while (levelCount--) + { + var windows = [layers objectForKey:levels[levelCount]]._windows, + windowCount = windows.length; + + while (windowCount--) + [windows[windowCount] resizeWithOldPlatformWindowSize:oldSize]; + } + + //window.liveResize = NO; + + [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; +} + +- (void)touchEvent:(DOMEvent)aDOMEvent +{ + if (aDOMEvent.touches && (aDOMEvent.touches.length == 1 || (aDOMEvent.touches.length == 0 && aDOMEvent.changedTouches.length == 1))) + { + var newEvent = {}; + + switch(aDOMEvent.type) + { + case CPDOMEventTouchStart: newEvent.type = CPDOMEventMouseDown; + break; + case CPDOMEventTouchEnd: newEvent.type = CPDOMEventMouseUp; + break; + case CPDOMEventTouchMove: newEvent.type = CPDOMEventMouseMoved; + break; + case CPDOMEventTouchCancel: newEvent.type = CPDOMEventMouseUp; + break; + } + + var touch = aDOMEvent.touches.length ? aDOMEvent.touches[0] : aDOMEvent.changedTouches[0]; + + newEvent.clientX = touch.clientX; + newEvent.clientY = touch.clientY; + + newEvent.timestamp = aDOMEvent.timestamp; + newEvent.target = aDOMEvent.target; + + newEvent.shiftKey = newEvent.ctrlKey = newEvent.altKey = newEvent.metaKey = false; + + newEvent.preventDefault = function(){if(aDOMEvent.preventDefault) aDOMEvent.preventDefault()}; + newEvent.stopPropagation = function(){if(aDOMEvent.stopPropagation) aDOMEvent.stopPropagation()}; + + [self _bridgeMouseEvent:newEvent]; + + return; + } + else + { + if (aDOMEvent.preventDefault) + aDOMEvent.preventDefault(); + + if (aDOMEvent.stopPropagation) + aDOMEvent.stopPropagation(); + } + // handle touch cases specifically +} + +- (void)mouseEvent:(DOMEvent)aDOMEvent +{ + var type = _overriddenEventType || aDOMEvent.type; + + // IE's event order is down, up, up, dblclick, so we have create these events artificially. + if (type === CPDOMEventDoubleClick) + { + _overriddenEventType = CPDOMEventMouseDown; + [self _bridgeMouseEvent:aDOMEvent]; + + _overriddenEventType = CPDOMEventMouseUp; + [self _bridgeMouseEvent:aDOMEvent]; + + _overriddenEventType = nil; + + return; + } + + var event, + location = _CGPointMake(aDOMEvent.clientX, aDOMEvent.clientY), + timestamp = aDOMEvent.timeStamp ? aDOMEvent.timeStamp : new Date(), + sourceElement = (aDOMEvent.target || aDOMEvent.srcElement), + windowNumber = 0, + modifierFlags = (aDOMEvent.shiftKey ? CPShiftKeyMask : 0) | + (aDOMEvent.ctrlKey ? CPControlKeyMask : 0) | + (aDOMEvent.altKey ? CPAlternateKeyMask : 0) | + (aDOMEvent.metaKey ? CPCommandKeyMask : 0); + + StopDOMEventPropagation = YES; + + if (_mouseDownWindow) + windowNumber = [_mouseDownWindow windowNumber]; + + else + { + var theWindow = [self hitTest:location]; + + if ((aDOMEvent.type === CPDOMEventMouseDown) && theWindow) + _mouseDownWindow = theWindow; + + windowNumber = [theWindow windowNumber]; + } + + if (windowNumber) + location = [CPApp._windows[windowNumber] convertBridgeToBase:location]; + + if (type === "mouseup") + { + if(_mouseIsDown) + { + event = _CPEventFromNativeMouseEvent(aDOMEvent, CPLeftMouseUp, location, modifierFlags, timestamp, windowNumber, nil, -1, CPDOMEventGetClickCount(_lastMouseUp, timestamp, location), 0); + + _mouseIsDown = NO; + _lastMouseUp = event; + _mouseDownWindow = nil; + } + + if(_DOMEventMode) + { + _DOMEventMode = NO; + return; + } + } + + else if (type === "mousedown") + { + if (ExcludedDOMElements[sourceElement.tagName] && sourceElement != _DOMFocusElement) + { + _DOMEventMode = YES; + _mouseIsDown = YES; + + //fake a down and up event so that event tracking mode will work correctly + [CPApp sendEvent:[CPEvent mouseEventWithType:CPLeftMouseDown location:location modifierFlags:modifierFlags + timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:-1 + clickCount:CPDOMEventGetClickCount(_lastMouseDown, timestamp, location) pressure:0]]; + + [CPApp sendEvent:[CPEvent mouseEventWithType:CPLeftMouseUp location:location modifierFlags:modifierFlags + timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:-1 + clickCount:CPDOMEventGetClickCount(_lastMouseDown, timestamp, location) pressure:0]]; + + return; + } + + event = _CPEventFromNativeMouseEvent(aDOMEvent, CPLeftMouseDown, location, modifierFlags, timestamp, windowNumber, nil, -1, CPDOMEventGetClickCount(_lastMouseDown, timestamp, location), 0); + + _mouseIsDown = YES; + _lastMouseDown = event; + } + + else // if (type === "mousemove") + { + if (_DOMEventMode) + return; + + event = _CPEventFromNativeMouseEvent(aDOMEvent, _mouseIsDown ? CPLeftMouseDragged : CPMouseMoved, location, modifierFlags, timestamp, windowNumber, nil, -1, 1, 0); + } + + if (event) + { + event._DOMEvent = aDOMEvent; + + [CPApp sendEvent:event]; + } + + if (StopDOMEventPropagation) + CPDOMEventStop(aDOMEvent, self); + + [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; +} + + (CPArray)orderedWindowsAtLevel:(int)aLevel +{ + var layer = [self layerAtLevel:aLevel create:NO]; + + if (!layer) + return []; + + return [layer orderedWindows]; +} + +- (CPDOMWindowLayer)layerAtLevel:(int)aLevel create:(BOOL)aFlag +{ + var layer = [_windowLayers objectForKey:aLevel]; + + // If the layer doesn't currently exist, and the create flag is true, + // create the layer. + if (!layer && aFlag) + { + layer = [[CPDOMWindowLayer alloc] initWithLevel:aLevel]; + + [_windowLayers setObject:layer forKey:aLevel]; + + // Find the nearest layer. This is similar to a binary search, + // only we know we won't find the value. + var low = 0, + high = _windowLevels.length - 1, + middle; + + while (low <= high) + { + middle = FLOOR((low + high) / 2); + + if (_windowLevels[middle] > aLevel) + high = middle - 1; + else + low = middle + 1; + } + + [_windowLevels insertObject:aLevel atIndex:_windowLevels[middle] > aLevel ? middle : middle + 1]; + layer._DOMElement.style.zIndex = aLevel; + _DOMBodyElement.appendChild(layer._DOMElement); + } + + return layer; +} + +- (void)order:(CPWindowOrderingMode)aPlace window:(CPWindow)aWindow relativeTo:(CPWindow)otherWindow +{ + // Grab the appropriate level for the layer, and create it if + // necessary (if we are not simply removing the window). + var layer = [self layerAtLevel:[aWindow level] create:aPlace != CPWindowOut]; + + // Ignore otherWindow, simply remove this window from it's level. + // If layer is nil, this will be a no-op. + if (aPlace == CPWindowOut) + return [layer removeWindow:aWindow]; + + // Place the window at the appropriate index. + [layer insertWindow:aWindow atIndex:(otherWindow ? (aPlace == CPWindowAbove ? otherWindow._index + 1 : otherWindow._index) : CPNotFound)]; +} + +/* @ignore */ +- (id)_dragHitTest:(CPPoint)aPoint pasteboard:(CPPasteboard)aPasteboard +{ + var levels = _windowLevels, + layers = _windowLayers, + levelCount = levels.length; + + while (levelCount--) + { + // Skip any windows above or at the dragging level. + if (levels[levelCount] >= CPDraggingWindowLevel) + continue; + + var windows = [layers objectForKey:levels[levelCount]]._windows, + windowCount = windows.length; + + while (windowCount--) + { + var theWindow = windows[windowCount]; + + if ([theWindow containsPoint:aPoint]) + return [theWindow _dragHitTest:aPoint pasteboard:aPasteboard]; + } + } + + return nil; +} + +/* @ignore */ +- (void)_propagateCurrentDOMEvent:(BOOL)aFlag +{ + StopDOMEventPropagation = !aFlag; +} + +- (CPWindow)hitTest:(CPPoint)location +{ + var levels = _windowLevels, + layers = _windowLayers, + levelCount = levels.length, + theWindow = nil; + + while (levelCount-- && !theWindow) + { + var windows = [layers objectForKey:levels[levelCount]]._windows, + windowCount = windows.length; + + while (windowCount-- && !theWindow) + { + var candidateWindow = windows[windowCount]; + + if (!candidateWindow._ignoresMouseEvents && [candidateWindow containsPoint:location]) + theWindow = candidateWindow; + } + } + + return theWindow; +} + +- (void)_checkPasteboardElement +{ + var value = _DOMPasteboardElement.value; + + if ([value length]) + { + var pasteboard = [CPPasteboard generalPasteboard]; + + if ([pasteboard _stateUID] != value) + { + [pasteboard declareTypes:[CPStringPboardType] owner:self]; + + [pasteboard setString:value forType:CPStringPboardType]; + } + } + + [self _clearPasteboardElement]; + + [CPApp sendEvent:_pasteboardKeyDownEvent]; + + _pasteboardKeyDownEvent = nil; + + [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; +} + +- (void)_clearPasteboardElement +{ + _DOMPasteboardElement.value = ""; + _DOMPasteboardElement.blur(); +} + +/*! + When using command (mac) or control (windows), keys are propagated to the browser by default. + To prevent a character key from propagating (to prevent its default action, and instead use it + in your own application), use these methods. These methods are additive -- the list builds until you clear it. + + @param characters a list of characters to stop propagating keypresses to the browser. +*/ ++ (void)preventCharacterKeysFromPropagating:(CPArray)characters +{ + for(var i=characters.length; i>0; i--) + CharacterKeysToPrevent[""+characters[i-1].toLowerCase()] = YES; +} + +/*! + @param character a character to stop propagating keypresses to the browser. +*/ ++ (void)preventCharacterKeyFromPropagating:(CPString)character +{ + CharacterKeysToPrevent[character.toLowerCase()] = YES; +} + +/*! + Clear the list of characters for which we are not sending keypresses to the browser. +*/ ++ (void)clearCharacterKeysToPreventFromPropagating +{ + CharacterKeysToPrevent = {}; +} + +/*! + Prevent these keyCodes from sending their keypresses to the browser. + @param keyCodes an array of keycodes to prevent propagation. +*/ ++ (void)preventKeyCodesFromPropagating:(CPArray)keyCodes +{ + for(var i=keyCodes.length; i>0; i--) + KeyCodesToPrevent[keyCodes[i-1]] = YES; +} + +/*! + Prevent this keyCode from sending its key events to the browser. + @param keyCode a keycode to prevent propagation. +*/ ++ (void)preventKeyCodeFromPropagating:(CPString)keyCode +{ + KeyCodesToPrevent[keyCode] = YES; +} + +/*! + Clear the list of keyCodes for which we are not sending keypresses to the browser. +*/ ++ (void)clearKeyCodesToPreventFromPropagating +{ + KeyCodesToPrevent = {}; +} + +@end + +var CPEventClass = [CPEvent class]; + +var _CPEventFromNativeMouseEvent = function(aNativeEvent, anEventType, aPoint, modifierFlags, aTimestamp, aWindowNumber, aGraphicsContext, anEventNumber, aClickCount, aPressure) +{ + aNativeEvent.isa = CPEventClass; + + aNativeEvent._type = anEventType; + aNativeEvent._location = aPoint; + aNativeEvent._modifierFlags = modifierFlags; + aNativeEvent._timestamp = aTimestamp; + aNativeEvent._windowNumber = aWindowNumber; + aNativeEvent._window = nil; + aNativeEvent._context = aGraphicsContext; + aNativeEvent._eventNumber = anEventNumber; + aNativeEvent._clickCount = aClickCount; + aNativeEvent._pressure = aPressure; + + return aNativeEvent; +} + +var CLICK_SPACE_DELTA = 5.0, + CLICK_TIME_DELTA = (typeof document != "undefined" && document.addEventListener) ? 350.0 : 1000.0; + +var CPDOMEventGetClickCount = function(aComparisonEvent, aTimestamp, aLocation) +{ + if (!aComparisonEvent) + return 1; + + var comparisonLocation = [aComparisonEvent locationInWindow]; + + return (aTimestamp - [aComparisonEvent timestamp] < CLICK_TIME_DELTA && + ABS(comparisonLocation.x - aLocation.x) < CLICK_SPACE_DELTA && + ABS(comparisonLocation.y - aLocation.y) < CLICK_SPACE_DELTA) ? [aComparisonEvent clickCount] + 1 : 1; +} + +var CPDOMEventStop = function(aDOMEvent, aPlatformWindow) +{ + // IE Model + aDOMEvent.cancelBubble = true; + aDOMEvent.returnValue = false; + + // W3C Model + if (aDOMEvent.preventDefault) + aDOMEvent.preventDefault(); + + if (aDOMEvent.stopPropagation) + aDOMEvent.stopPropagation(); + + if (aDOMEvent.type === CPDOMEventMouseDown) + { + aPlatformWindow._DOMFocusElement.focus(); + aPlatformWindow._DOMFocusElement.blur(); + } +} + +function CPWindowObjectList() +{ + var platformWindow = [CPPlatformWindow primaryPlatformWindow], + levels = platformWindow._windowLevels, + layers = platformWindow._windowLayers, + levelCount = levels.length, + windowObjects = []; + + while (levelCount--) + { + var windows = [layers objectForKey:levels[levelCount]]._windows, + windowCount = windows.length; + + while (windowCount--) + windowObjects.push(windows[windowCount]); + } + + return windowObjects; +} + +function CPWindowList() +{ + var platformWindow = [CPPlatformWindow primaryPlatformWindow], + levels = platformWindow._windowLevels, + layers = platformWindow._windowLayers, + levelCount = levels.length, + windowNumbers = []; + + while (levelCount--) + { + var windows = [layers objectForKey:levels[levelCount]]._windows, + windowCount = windows.length; + + while (windowCount--) + windowNumbers.push([windows[windowCount] windowNumber]); + } + + return windowNumbers; +} diff --git a/AppKit/Rakefile b/AppKit/Rakefile index f4f3d30cc..a93beb55c 100644 --- a/AppKit/Rakefile +++ b/AppKit/Rakefile @@ -53,6 +53,7 @@ file_d $THEME_PRODUCT => ThemeFiles << $ENVIRONMENT_PRODUCT do puts str end end + rake abort if ($? != 0) end task :build => [:build_subprojects, :AppKit, $ENVIRONMENT_PRODUCT, $THEME_PRODUCT, $ENVIRONMENT_THEME_PRODUCT] diff --git a/AppKit/Resources/CPSearchField/CPSearchFieldCancel.png b/AppKit/Resources/CPSearchField/CPSearchFieldCancel.png new file mode 100644 index 000000000..fc32eabb3 Binary files /dev/null and b/AppKit/Resources/CPSearchField/CPSearchFieldCancel.png differ diff --git a/AppKit/Resources/CPSearchField/CPSearchFieldCancelPressed.png b/AppKit/Resources/CPSearchField/CPSearchFieldCancelPressed.png new file mode 100644 index 000000000..e4fc62e23 Binary files /dev/null and b/AppKit/Resources/CPSearchField/CPSearchFieldCancelPressed.png differ diff --git a/AppKit/Resources/CPSearchField/CPSearchFieldFind.png b/AppKit/Resources/CPSearchField/CPSearchFieldFind.png new file mode 100644 index 000000000..0dcd0cd53 Binary files /dev/null and b/AppKit/Resources/CPSearchField/CPSearchFieldFind.png differ diff --git a/AppKit/Resources/CPSearchField/CPSearchFieldSearch.png b/AppKit/Resources/CPSearchField/CPSearchFieldSearch.png new file mode 100644 index 000000000..77434b8a2 Binary files /dev/null and b/AppKit/Resources/CPSearchField/CPSearchFieldSearch.png differ diff --git a/AppKit/Themes/Aristo/Resources/button-bezel-disabled-center.png b/AppKit/Themes/Aristo/Resources/button-bezel-disabled-center.png new file mode 100644 index 000000000..2f25f5252 Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/button-bezel-disabled-center.png differ diff --git a/AppKit/Themes/Aristo/Resources/button-bezel-disabled-left.png b/AppKit/Themes/Aristo/Resources/button-bezel-disabled-left.png new file mode 100644 index 000000000..8ae5e8eb3 Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/button-bezel-disabled-left.png differ diff --git a/AppKit/Themes/Aristo/Resources/button-bezel-disabled-right.png b/AppKit/Themes/Aristo/Resources/button-bezel-disabled-right.png new file mode 100644 index 000000000..92127238a Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/button-bezel-disabled-right.png differ diff --git a/AppKit/Themes/Aristo/Resources/check-box-bezel-disabled.png b/AppKit/Themes/Aristo/Resources/check-box-bezel-disabled.png new file mode 100644 index 000000000..c1246094f Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/check-box-bezel-disabled.png differ diff --git a/AppKit/Themes/Aristo/Resources/check-box-bezel-highlighted.png b/AppKit/Themes/Aristo/Resources/check-box-bezel-highlighted.png new file mode 100644 index 000000000..51e26047e Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/check-box-bezel-highlighted.png differ diff --git a/AppKit/Themes/Aristo/Resources/check-box-bezel-selected-disabled.png b/AppKit/Themes/Aristo/Resources/check-box-bezel-selected-disabled.png new file mode 100644 index 000000000..fea5c786c Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/check-box-bezel-selected-disabled.png differ diff --git a/AppKit/Themes/Aristo/Resources/check-box-bezel-selected-highlighted.png b/AppKit/Themes/Aristo/Resources/check-box-bezel-selected-highlighted.png new file mode 100644 index 000000000..dc2a5f089 Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/check-box-bezel-selected-highlighted.png differ diff --git a/AppKit/Themes/Aristo/Resources/radio-bezel-disabled.png b/AppKit/Themes/Aristo/Resources/radio-bezel-disabled.png new file mode 100644 index 000000000..76d3c79d7 Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/radio-bezel-disabled.png differ diff --git a/AppKit/Themes/Aristo/Resources/radio-bezel-highlighted.png b/AppKit/Themes/Aristo/Resources/radio-bezel-highlighted.png new file mode 100644 index 000000000..6f16d4803 Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/radio-bezel-highlighted.png differ diff --git a/AppKit/Themes/Aristo/Resources/radio-bezel-selected-disabled.png b/AppKit/Themes/Aristo/Resources/radio-bezel-selected-disabled.png new file mode 100644 index 000000000..7d5d963df Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/radio-bezel-selected-disabled.png differ diff --git a/AppKit/Themes/Aristo/Resources/radio-bezel-selected-highlighted.png b/AppKit/Themes/Aristo/Resources/radio-bezel-selected-highlighted.png new file mode 100644 index 000000000..aa4fbc1d6 Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/radio-bezel-selected-highlighted.png differ diff --git a/AppKit/Themes/Aristo/ThemeDescriptors.j b/AppKit/Themes/Aristo/ThemeDescriptors.j index 57e7033a9..7f747a324 100644 --- a/AppKit/Themes/Aristo/ThemeDescriptors.j +++ b/AppKit/Themes/Aristo/ThemeDescriptors.j @@ -53,6 +53,14 @@ [_CPCibCustomResource imageResourceWithName:"default-button-bezel-highlighted-center.png" size:CGSizeMake(1.0, 24.0)], [_CPCibCustomResource imageResourceWithName:"default-button-bezel-highlighted-right.png" size:CGSizeMake(4.0, 24.0)] ] + isVertical:NO]], + + disabledBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: + [ + [_CPCibCustomResource imageResourceWithName:"button-bezel-disabled-left.png" size:CGSizeMake(4.0, 24.0)], + [_CPCibCustomResource imageResourceWithName:"button-bezel-disabled-center.png" size:CGSizeMake(1.0, 24.0)], + [_CPCibCustomResource imageResourceWithName:"button-bezel-disabled-right.png" size:CGSizeMake(4.0, 24.0)] + ] isVertical:NO]]; [button setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@"font" inState:CPThemeStateBordered]; @@ -65,6 +73,10 @@ [button setValue:highlightedBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateHighlighted]; [button setValue:CGInsetMake(0.0, 5.0, 0.0, 5.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered]; + [button setValue:[CPColor colorWithCalibratedWhite:0.6 alpha:1.0] forThemeAttribute:@"text-color" inState:CPThemeStateDisabled]; + [button setValue:disabledBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateDisabled]; + [button setValue:disabledBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateDefault|CPThemeStateDisabled]; + [button setValue:defaultBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateDefault]; [button setValue:defaultHighlightedBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateHighlighted|CPThemeStateDefault]; [button setValue:[CPColor colorWithCalibratedRed:13.0/255.0 green:51.0/255.0 blue:70.0/255.0 alpha:1.0] forThemeAttribute:@"text-color" inState:CPThemeStateDefault]; @@ -348,6 +360,26 @@ [ [_CPCibCustomResource imageResourceWithName:"radio-bezel-selected.png" size:CGSizeMake(17.0, 17.0)], nil, nil ] + isVertical:NO]), + bezelColorSelectedHighlighted = PatternColor([[CPThreePartImage alloc] initWithImageSlices: + [ + [_CPCibCustomResource imageResourceWithName:"radio-bezel-selected-highlighted.png" size:CGSizeMake(17.0, 17.0)], nil, nil + ] + isVertical:NO]), + bezelColorSelectedDisabled = PatternColor([[CPThreePartImage alloc] initWithImageSlices: + [ + [_CPCibCustomResource imageResourceWithName:"radio-bezel-selected-disabled.png" size:CGSizeMake(17.0, 17.0)], nil, nil + ] + isVertical:NO]), + bezelColorDisabled = PatternColor([[CPThreePartImage alloc] initWithImageSlices: + [ + [_CPCibCustomResource imageResourceWithName:"radio-bezel-disabled.png" size:CGSizeMake(17.0, 17.0)], nil, nil + ] + isVertical:NO]), + bezelColorHighlighted = PatternColor([[CPThreePartImage alloc] initWithImageSlices: + [ + [_CPCibCustomResource imageResourceWithName:"radio-bezel-highlighted.png" size:CGSizeMake(17.0, 17.0)], nil, nil + ] isVertical:NO]); [button setValue:CPLeftTextAlignment forThemeAttribute:@"alignment" inState:CPThemeStateBordered]; @@ -355,6 +387,10 @@ [button setValue:CGInsetMake(0.0, 0.0, 0.0, 20.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered]; [button setValue:bezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered]; [button setValue:bezelColorSelected forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateSelected]; + [button setValue:bezelColorSelectedHighlighted forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateSelected | CPThemeStateHighlighted]; + [button setValue:bezelColorHighlighted forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateHighlighted]; + [button setValue:bezelColorDisabled forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateDisabled]; + [button setValue:bezelColorSelectedDisabled forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateDisabled | CPThemeStateSelected]; [button setValue:CGSizeMake(0.0, 17.0) forThemeAttribute:@"min-size"]; @@ -376,6 +412,26 @@ [ [_CPCibCustomResource imageResourceWithName:"check-box-bezel-selected.png" size:CGSizeMake(15.0, 16.0)], nil, nil ] + isVertical:NO]), + bezelColorSelectedHighlighted = PatternColor([[CPThreePartImage alloc] initWithImageSlices: + [ + [_CPCibCustomResource imageResourceWithName:"check-box-bezel-selected-highlighted.png" size:CGSizeMake(15.0, 16.0)], nil, nil + ] + isVertical:NO]), + bezelColorSelectedDisabled = PatternColor([[CPThreePartImage alloc] initWithImageSlices: + [ + [_CPCibCustomResource imageResourceWithName:"check-box-bezel-selected-disabled.png" size:CGSizeMake(15.0, 16.0)], nil, nil + ] + isVertical:NO]), + bezelColorDisabled = PatternColor([[CPThreePartImage alloc] initWithImageSlices: + [ + [_CPCibCustomResource imageResourceWithName:"check-box-bezel-disabled.png" size:CGSizeMake(15.0, 16.0)], nil, nil + ] + isVertical:NO]), + bezelColorHighlighted = PatternColor([[CPThreePartImage alloc] initWithImageSlices: + [ + [_CPCibCustomResource imageResourceWithName:"check-box-bezel-highlighted.png" size:CGSizeMake(15.0, 16.0)], nil, nil + ] isVertical:NO]); [button setValue:CPLeftTextAlignment forThemeAttribute:@"alignment" inState:CPThemeStateBordered]; @@ -383,6 +439,10 @@ [button setValue:CGInsetMake(0.0, 0.0, 0.0, 20.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered]; [button setValue:bezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered]; [button setValue:bezelColorSelected forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateSelected]; + [button setValue:bezelColorSelectedHighlighted forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateSelected | CPThemeStateHighlighted]; + [button setValue:bezelColorHighlighted forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateHighlighted]; + [button setValue:bezelColorDisabled forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateDisabled]; + [button setValue:bezelColorSelectedDisabled forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateDisabled | CPThemeStateSelected]; [button setValue:CGSizeMake(0.0, 17.0) forThemeAttribute:@"min-size"]; diff --git a/External/Rakefile b/External/Rakefile index 0272cabf9..b51625b9f 100644 --- a/External/Rakefile +++ b/External/Rakefile @@ -7,20 +7,14 @@ require 'rake/clean' require 'fileutils' -$ENVIRONMENT_NARWHAL_PRODUCT = File.join($ENVIRONMENT_DIR, 'narwhal') +$ENVIRONMENT_NARWHAL_PRODUCT = $ENVIRONMENT_DIR $ENVIRONMENT_BROWSERJS_PRODUCT = File.join($ENVIRONMENT_NARWHAL_PRODUCT, 'packages', 'browserjs') $ENVIRONMENT_JACK_PRODUCT = File.join($ENVIRONMENT_NARWHAL_PRODUCT, 'packages', 'jack') -$ENVIRONMENT_NARWHAL_EXECUTABLE = File.join($ENVIRONMENT_BIN_DIR, 'narwhal') - file_d $ENVIRONMENT_DIR do mkdir_p $ENVIRONMENT_DIR end -file_d $ENVIRONMENT_NARWHAL_EXECUTABLE do - FileUtils.ln_sf('../narwhal/bin/narwhal', $ENVIRONMENT_NARWHAL_EXECUTABLE) -end - task :update_submodules do if executable_exists? "git" system %{cd .. && git submodule init && git submodule update} @@ -30,11 +24,12 @@ task :update_submodules do end end -task :build => [:update_submodules, $ENVIRONMENT_DIR, $ENVIRONMENT_NARWHAL_EXECUTABLE] do +task :build => [:update_submodules, $ENVIRONMENT_DIR] do rm_rf($ENVIRONMENT_NARWHAL_PRODUCT) cp_r('narwhal', $ENVIRONMENT_NARWHAL_PRODUCT) cp_r('browserjs', $ENVIRONMENT_BROWSERJS_PRODUCT) cp_r('jack', $ENVIRONMENT_JACK_PRODUCT) + symlink_executable(File.join($ENVIRONMENT_JACK_PRODUCT, "bin", "jackup")) end -CLOBBER.include($ENVIRONMENT_NARWHAL_PRODUCT, $ENVIRONMENT_NARWHAL_EXECUTABLE) +CLOBBER.include($ENVIRONMENT_NARWHAL_PRODUCT) diff --git a/External/jack b/External/jack index 7b410a132..a93518cd1 160000 --- a/External/jack +++ b/External/jack @@ -1 +1 @@ -Subproject commit 7b410a1323367d309b9cf77bf332f1496b086b84 +Subproject commit a93518cd13bd0a92286b25cdb38806f7bbc883c7 diff --git a/External/narwhal b/External/narwhal index e0bb2640c..6ce4d9288 160000 --- a/External/narwhal +++ b/External/narwhal @@ -1 +1 @@ -Subproject commit e0bb2640c541ecff490e2e3d8f7c57301e4209f6 +Subproject commit 6ce4d928875cc4252885fec6725524bfa9855b19 diff --git a/Foundation/CPArray.j b/Foundation/CPArray.j index efe2e8196..566eb57bb 100755 --- a/Foundation/CPArray.j +++ b/Foundation/CPArray.j @@ -117,7 +117,7 @@ } /*! - Creates a new array containing the objects in anArray. + Creates a new array containing the objects in \c anArray. @param anArray Objects in this array will be added to the new array @return a new CPArray of the provided objects */ @@ -127,7 +127,7 @@ } /*! - Creates a new array with anObject in it. + Creates a new array with \c anObject in it. @param anObject the object to be added to the array @return a new CPArray containing a single object */ @@ -175,9 +175,9 @@ // Creating an Array /*! - Creates a new CPArray from anArray. + Creates a new CPArray from \c anArray. @param anArray objects in this array will be added to the new array - @return a new CPArray containing the objects of anArray + @return a new CPArray containing the objects of \c anArray */ - (id)initWithArray:(CPArray)anArray { @@ -190,10 +190,10 @@ } /*! - Initializes a the array with the contents of anArray - and optionally performs a deep copy of the objects based on copyItems. + Initializes a the array with the contents of \c anArray + and optionally performs a deep copy of the objects based on \c copyItems. @param anArray the array to copy the data from - @param copyItems if YES, each object will be copied by having a copy message sent to it, and the + @param copyItems if \c YES, each object will be copied by having a \c -copy message sent to it, and the returned object will be added to the receiver. Otherwise, no copying will be performed. @return the initialized array of objects */ @@ -240,7 +240,7 @@ /*! Initializes the array with a JavaScript array of objects. @param objects the array of objects to add to the receiver - @param aCount the number of objects in objects + @param aCount the number of objects in \c objects @return the initialized CPArray */ - (id)initWithObjects:(id)objects count:(unsigned)aCount @@ -260,7 +260,7 @@ // Querying an array /*! - Returns YES if the array contains anObject. Otherwise, it returns NO. + Returns \c YES if the array contains \c anObject. Otherwise, it returns \c NO. @param anObject the method checks if this object is already in the array */ - (BOOL)containsObject:(id)anObject @@ -277,10 +277,10 @@ } /*! - Returns the index of anObject in this array. - If the object is nil or not in the array, - returns CPNotFound. It first attempts to find - a match using isEqual:, then ==. + Returns the index of \c anObject in this array. + If the object is \c nil or not in the array, + returns \c CPNotFound. It first attempts to find + a match using \c -isEqual:, then \c ==. @param anObject the object to search for */ - (int)indexOfObject:(id)anObject @@ -291,7 +291,7 @@ var i = 0, count = length; - // Only use isEqual: if our object is a CPObject. + // Only use -isEqual: if our object is a CPObject. if (anObject.isa) { for(; i < count; ++i) @@ -312,12 +312,12 @@ } /*! - Returns the index of anObject in the array - within aRange. It first attempts to find - a match using isEqual:, then ==. + Returns the index of \c anObject in the array + within \c aRange. It first attempts to find + a match using \c -isEqual:, then \c ==. @param anObject the object to search for @param aRange the range to search within - @return the index of the object, or CPNotFound if it was not found. + @return the index of the object, or \c CPNotFound if it was not found. */ - (int)indexOfObject:(id)anObject inRange:(CPRange)aRange { @@ -344,9 +344,9 @@ } /*! - Returns the index of anObject in the array. The test for equality is done using only ==. + Returns the index of \c anObject in the array. The test for equality is done using only \c ==. @param anObject the object to search for - @return the index of the object in the array. CPNotFound if the object is not in the array. + @return the index of the object in the array. \c CPNotFound if the object is not in the array. */ - (int)indexOfObjectIdenticalTo:(id)anObject { @@ -373,12 +373,12 @@ } /*! - Returns the index of anObject in the array - within aRange. The test for equality is - done using only ==. + Returns the index of \c anObject in the array + within \c aRange. The test for equality is + done using only \c ==. @param anObject the object to search for @param aRange the range to search within - @return the index of the object, or CPNotFound if it was not found. + @return the index of the object, or \c CPNotFound if it was not found. */ - (int)indexOfObjectIdenticalTo:(id)anObject inRange:(CPRange)aRange { @@ -410,12 +410,12 @@ } /*! - Returns the index of anObject in the array, which must be sorted in the same order as + Returns the index of \c anObject in the array, which must be sorted in the same order as calling sortUsingSelector: with the selector passed to this method would result in. @param anObject the object to search for @param aSelector the comparison selector to call on each item in the list, the same selector should have been used to sort the array (or to maintain its sorted order). - @return the index of the object, or CPNotFound if it was not found. + @return the index of the object, or \c CPNotFound if it was not found. */ - (unsigned)indexOfObject:(id)anObject sortedBySelector:(SEL)aSelector { @@ -423,7 +423,7 @@ } /*! - Returns the index of anObject in the array, which must be sorted in the same order as + Returns the index of \c anObject in the array, which must be sorted in the same order as calling sortUsingFunction: with the selector passed to this method would result in. The function will be called like so:
    @@ -432,7 +432,7 @@
         @param anObject the object to search for
         @param aFunction the comparison function to call on each item in the array that we search. the same
         selector should have been used to sort the array (or to maintain its sorted order).
    -    @return the index of the object, or CPNotFound if it was not found.
    +    @return the index of the object, or \c CPNotFound if it was not found.
     */
     - (unsigned)indexOfObject:(id)anObject sortedByFunction:(Function)aFunction
     {
    @@ -440,7 +440,7 @@
     }
     
     /*!
    -    Returns the index of anObject in the array, which must be sorted in the same order as
    +    Returns the index of \c anObject in the array, which must be sorted in the same order as
         calling sortUsingFunction: with the selector passed to this method would result in. 
         The function will be called like so:
         
    @@ -450,7 +450,7 @@
         @param aFunction the comparison function to call on each item in the array that we search. the same
         function should have been used to sort the array (or to maintain its sorted order).
         @param aContext a context object that will be passed to the sort function
    -    @return the index of the object, or CPNotFound if it was not found.
    +    @return the index of the object, or \c CPNotFound if it was not found.
     */
     - (unsigned)indexOfObject:(id)anObject sortedByFunction:(Function)aFunction context:(id)aContext
     {
    @@ -480,12 +480,12 @@
     }
     
     /*!
    -    Returns the index of anObject in the array, which must be sorted in the same order as
    +    Returns the index of \c anObject in the array, which must be sorted in the same order as
         calling sortUsingDescriptors: with the descriptors passed to this method would result in. 
         @param anObject the object to search for
         @param descriptors the array of descriptors to use to compare each item in the array that we search. the same
         descriptors should have been used to sort the array (or to maintain its sorted order).
    -    @return the index of the object, or CPNotFound if it was not found.
    +    @return the index of the object, or \c CPNotFound if it was not found.
     */
     - (unsigned)indexOfObject:(id)anObject sortedByDescriptors:(CPArray)descriptors
     {
    @@ -504,7 +504,7 @@
     }
     
     /*!
    -    Returns the last object in the array. If the array is empty, returns nil/
    +    Returns the last object in the array. If the array is empty, returns \c nil/
     */
     - (id)lastObject
     {
    @@ -516,8 +516,8 @@
     }
     
     /*!
    -    Returns the object at index anIndex.
    -    @throws CPRangeException if anIndex is out of bounds
    +    Returns the object at index \c anIndex.
    +    @throws CPRangeException if \c anIndex is out of bounds
     */
     - (id)objectAtIndex:(int)anIndex
     {
    @@ -528,7 +528,7 @@
     }
     
     /*!
    -    Returns the objects at indexes in a new CPArray.
    +    Returns the objects at \c indexes in a new CPArray.
         @param indexes the set of indices
         @throws CPRangeException if any of the indices is greater than or equal to the length of the array
     */
    @@ -570,7 +570,7 @@
     /*!
         Sends each element in the array a message.
         @param aSelector the selector of the message to send
    -    @throws CPInvalidArgumentException if aSelector is nil
    +    @throws CPInvalidArgumentException if \c aSelector is \c nil
     */
     - (void)makeObjectsPerformSelector:(SEL)aSelector
     {
    @@ -588,7 +588,7 @@
         Sends each element in the array a message with an argument.
         @param aSelector the selector of the message to send
         @param anObject the first argument of the message
    -    @throws CPInvalidArgumentException if aSelector is nil
    +    @throws CPInvalidArgumentException if \c aSelector is \c nil
     */
     - (void)makeObjectsPerformSelector:(SEL)aSelector withObject:(id)anObject
     {
    @@ -605,8 +605,8 @@
     // Comparing arrays
     /*!
         Returns the first object found in the receiver (starting at index 0) which is present in the
    -    otherArray as determined by using the -containsObject: method.
    -    @return the first object found, or nil if no common object was found.
    +    \c otherArray as determined by using the \c -containsObject: method.
    +    @return the first object found, or \c nil if no common object was found.
     */
     - (id)firstObjectCommonWithArray:(CPArray)anArray
     {
    @@ -663,9 +663,9 @@
     
     // Deriving new arrays
     /*!
    -    Returns a copy of this array plus anObject inside the copy.
    +    Returns a copy of this array plus \c anObject inside the copy.
         @param anObject the object to be added to the array copy
    -    @throws CPInvalidArgumentException if anObject is nil
    +    @throws CPInvalidArgumentException if \c anObject is \c nil
         @return a new array that should be n+1 in size compared to the receiver.
     */
     - (CPArray)arrayByAddingObject:(id)anObject
    @@ -682,7 +682,7 @@
     }
     
     /*!
    -    Returns a new array which is the concatenation of self and otherArray (in this precise order).
    +    Returns a new array which is the concatenation of \c self and otherArray (in this precise order).
         @param anArray the array that will be concatenated to the receiver's copy
     */
     - (CPArray)arrayByAddingObjectsFromArray:(CPArray)anArray
    @@ -706,7 +706,7 @@
     */
     
     /*!
    -    Returns a subarray of the receiver containing the objects found in the specified range aRange.
    +    Returns a subarray of the receiver containing the objects found in the specified range \c aRange.
         @param aRange the range of objects to be copied into the subarray
         @throws CPRangeException if the specified range exceeds the bounds of the array
     */
    @@ -741,8 +741,8 @@
     
     /*!
         Returns an array in which the objects are ordered according
    -    to a sort with aFunction. This invokes
    -    -sortUsingFunction:context.
    +    to a sort with \c aFunction. This invokes
    +    \c -sortUsingFunction:context.
         @param aFunction a JavaScript 'Function' type that compares objects
         @param aContext context information
         @return a new sorted array
    @@ -757,7 +757,7 @@
     }
     
     /*!
    -    Returns a new array in which the objects are ordered according to a sort with aSelector.
    +    Returns a new array in which the objects are ordered according to a sort with \c aSelector.
         @param aSelector the selector that will perform object comparisons
     */
     - (CPArray)sortedArrayUsingSelector:(SEL)aSelector
    @@ -774,7 +774,7 @@
     /*!
         Returns a string formed by concatenating the objects in the
         receiver, with the specified separator string inserted between each part.
    -    If the element is a Objective-J object, then the description
    +    If the element is a Objective-J object, then the \c -description
         of that object will be used, otherwise the default JavaScript representation will be used.
         @param aString the separator that will separate each object string
         @return the string representation of the array
    @@ -816,7 +816,7 @@
     // Collecting paths
     /*!
         Returns a new array subset formed by selecting the elements that have
    -    filename extensions from filterTypes. Only elements
    +    filename extensions from \c filterTypes. Only elements
         that are of type CPString are candidates for inclusion in the returned array.
         @param filterTypes an array of CPString objects that contain file extensions (without the '.')
         @return a new array with matching paths
    @@ -850,7 +850,7 @@
     }
     
     /*!
    -    Returns the value for aKey from each element in the array.
    +    Returns the value for \c aKey from each element in the array.
         @param aKey the key to return the value for
         @return an array of containing a value for each element in the array
     */
    @@ -883,7 +883,7 @@
     
     // Creating arrays
     /*!
    -    Creates an array able to store at least  aCapacity
    +    Creates an array able to store at least  \c aCapacity
         items. Because CPArray is backed by JavaScript arrays,
         this method ends up simply returning a regular array.
     */
    @@ -893,7 +893,7 @@
     }
     
     /*!
    -    Initializes an array able to store at least aCapacity items. Because CPArray
    +    Initializes an array able to store at least \c aCapacity items. Because CPArray
         is backed by JavaScript arrays, this method ends up simply returning a regular array.
     */
     - (id)initWithCapacity:(unsigned)aCapacity
    @@ -903,7 +903,7 @@
     
     // Adding and replacing objects
     /*!
    -    Adds anObject to the end of the array.
    +    Adds \c anObject to the end of the array.
         @param anObject the object to add to the array
     */
     - (void)addObject:(id)anObject
    @@ -912,7 +912,7 @@
     }
     
     /*!
    -    Adds the objects in anArray to the receiver array.
    +    Adds the objects in \c anArray to the receiver array.
         @param anArray the array of objects to add to the end of the receiver
     */
     - (void)addObjectsFromArray:(CPArray)anArray
    @@ -923,7 +923,7 @@
     /*!
         Inserts an object into the receiver at the specified location.
         @param anObject the object to insert into the array
    -    @param anIndex the location to insert anObject at
    +    @param anIndex the location to insert \c anObject at
     */
     - (void)insertObject:(id)anObject atIndex:(int)anIndex
     {
    @@ -956,9 +956,9 @@
     }
     
     /*!
    -    Replaces the element at anIndex with anObject.
    -    The current element at position anIndex will be removed from the array.
    -    @param anIndex the position in the array to place anObject
    +    Replaces the element at \c anIndex with \c anObject.
    +    The current element at position \c anIndex will be removed from the array.
    +    @param anIndex the position in the array to place \c anObject
     */
     - (void)replaceObjectAtIndex:(int)anIndex withObject:(id)anObject
     {
    @@ -966,8 +966,8 @@
     }
     
     /*!
    -    Replace the elements at the indices specified by anIndexSet with
    -    the objects in objects.
    +    Replace the elements at the indices specified by \c anIndexSet with
    +    the objects in \c objects.
         @param anIndexSet the set of indices to array positions that will be replaced
         @param objects the array of objects to place in the specified indices
     */
    @@ -984,12 +984,12 @@
     }
     
     /*!
    -    Replaces some of the receiver's objects with objects from anArray. Specifically, the elements of the
    -    receiver in the range specified by aRange,
    -    with the elements of anArray in the range specified by otherRange.
    +    Replaces some of the receiver's objects with objects from \c anArray. Specifically, the elements of the
    +    receiver in the range specified by \c aRange,
    +    with the elements of \c anArray in the range specified by \c otherRange.
         @param aRange the range of elements to be replaced in the receiver
         @param anArray the array to retrieve objects for placement into the receiver
    -    @param otherRange the range of objects in anArray to pull from for placement into the receiver
    +    @param otherRange the range of objects in \c anArray to pull from for placement into the receiver
     */
     - (void)replaceObjectsInRange:(CPRange)aRange withObjectsFromArray:(CPArray)anArray range:(CPRange)otherRange
     {
    @@ -1001,8 +1001,8 @@
     
     /*!
         Replaces some of the receiver's objects with the objects from
    -    anArray. Specifically, the elements of the
    -    receiver in the range specified by aRange.
    +    \c anArray. Specifically, the elements of the
    +    receiver in the range specified by \c aRange.
         @param aRange the range of elements to be replaced in the receiver
         @param anArray the array to retrieve objects for placement into the receiver
     */
    @@ -1012,7 +1012,7 @@
     }
     
     /*!
    -    Sets the contents of the receiver to be identical to the contents of anArray.
    +    Sets the contents of the receiver to be identical to the contents of \c anArray.
         @param anArray the array of objects used to replace the receiver's objects
     */
     - (void)setArray:(CPArray)anArray
    @@ -1040,7 +1040,7 @@
     }
     
     /*!
    -    Removes all entries of anObject from the array.
    +    Removes all entries of \c anObject from the array.
         @param anObject the object whose entries are to be removed
     */
     - (void)removeObject:(id)anObject
    @@ -1049,7 +1049,7 @@
     }
     
     /*!
    -    Removes all entries of anObject from the array, in the range specified by aRange.
    +    Removes all entries of \c anObject from the array, in the range specified by \c aRange.
         @param anObject the object to remove
         @param aRange the range to search in the receiver for the object
     */
    @@ -1065,7 +1065,7 @@
     }
     
     /*!
    -    Removes the object at anIndex.
    +    Removes the object at \c anIndex.
         @param anIndex the location of the element to be removed
     */
     - (void)removeObjectAtIndex:(int)anIndex
    @@ -1074,7 +1074,7 @@
     }
     
     /*!
    -    Removes the objects at the indices specified by CPIndexSet.
    +    Removes the objects at the indices specified by \c CPIndexSet.
         @param anIndexSet the indices of the elements to be removed from the array
     */
     - (void)removeObjectsAtIndexes:(CPIndexSet)anIndexSet
    @@ -1089,8 +1089,8 @@
     }
     
     /*!
    -    Remove the first instance of anObject from the array.
    -    The search for the object is done using ==.
    +    Remove the first instance of \c anObject from the array.
    +    The search for the object is done using \c ==.
         @param anObject the object to remove
     */
     - (void)removeObjectIdenticalTo:(id)anObject
    @@ -1099,9 +1099,9 @@
     }
     
     /*!
    -    Remove the first instance of anObject from the array,
    -    within the range specified by aRange.
    -    The search for the object is done using ==.
    +    Remove the first instance of \c anObject from the array,
    +    within the range specified by \c aRange.
    +    The search for the object is done using \c ==.
         @param anObject the object to remove
         @param aRange the range in the array to search for the object
     */
    @@ -1117,7 +1117,7 @@
     }
     
     /*!
    -    Remove the objects in anArray from the receiver array.
    +    Remove the objects in \c anArray from the receiver array.
         @param anArray the array of objects to remove from the receiver
     */
     - (void)removeObjectsInArray:(CPArray)anArray
    @@ -1170,7 +1170,7 @@
     /*!
         Sorts the receiver array using a JavaScript function as a comparator, and a specified context.
         @param aFunction a JavaScript function that will be called to compare objects
    -    @param aContext an object that will be passed to aFunction with comparison
    +    @param aContext an object that will be passed to \c aFunction with comparison
     */
     - (void)sortUsingFunction:(Function)aFunction context:(id)aContext
     {
    diff --git a/Foundation/CPAttributedString.j b/Foundation/CPAttributedString.j
    index 580ffde7d..b6bcb23cb 100644
    --- a/Foundation/CPAttributedString.j
    +++ b/Foundation/CPAttributedString.j
    @@ -51,7 +51,7 @@
     /*!
         Creates a new attributed string from a character string.
         @param aString is the string to initialise from.
    -    @return a new CPAttributedString containing the string aString.
    +    @return a new CPAttributedString containing the string \c aString.
     */
     - (id)initWithString:(CPString)aString
     {
    @@ -61,7 +61,7 @@
     /*!
         Creates a new attributed string from an existing attributed string.
         @param aString is the attributed string to initialise from.
    -    @return a new CPAttributedString containing the string aString.
    +    @return a new CPAttributedString containing the string \c aString.
     */ 
     - (id)initWithAttributedString:(CPAttributedString)aString
     {
    @@ -77,8 +77,8 @@
         dictionary of attributes.
         @param aString is the attributed string to initialise from.
         @param attributes is a dictionary of string attributes.
    -    @return a new CPAttributedString containing the string aString
    -    with associated attributes, attributes.
    +    @return a new CPAttributedString containing the string \c aString
    +    with associated attributes, \c attributes.
     */ 
     - (id)initWithString:(CPString)aString attributes:(CPDictionary)attributes
     {
    @@ -152,16 +152,16 @@
         same, can be returned if desired. 
         @note there is no guarantee that the range returned is in fact the complete
         range of the particular attributes. To ensure this use
    -    attributesAtIndex:longestEffectiveRange:inRange: instead. Note
    +    \c attributesAtIndex:longestEffectiveRange:inRange: instead. Note
         however that it may take significantly longer to execute.
         @param anIndex is an unsigned integer index. It must lie within the bounds
         of the string.
         @param aRange is a reference to a CPRange object
         that is set (upon return) to the range over which the attributes are the
    -    same as those at index, anIndex. If not required pass
    -    nil.
    +    same as those at index, \c anIndex. If not required pass
    +    \c nil.
         @return a CPDictionary containing the attributes associated with the 
    -    character at index anIndex. Returns nil if index
    +    character at index \c anIndex. Returns \c nil if index
         is out of bounds.
     */ 
     - (CPDictionary)attributesAtIndex:(unsigned)anIndex effectiveRange:(CPRangePointer)aRange
    @@ -187,10 +187,10 @@
         and, by reference, the range over which the attributes apply. This is the
         maximum range both forwards and backwards in the string over which the
         attributes apply, bounded in both directions by the range limit parameter,
    -    rangeLimit.
    +    \c rangeLimit.
         @note this method performs a search to find this range which may be
    -    computationally intensive. Use the rangeLimit to limit the
    -    search space or use attributesAtIndex:effectiveRange: but
    +    computationally intensive. Use the \c rangeLimit to limit the
    +    search space or use \c -attributesAtIndex:effectiveRange: but
         note that it is not guaranteed to return the full range of the current
         character's attributes.
         @param anIndex is the unsigned integer index. It must lie within the bounds
    @@ -200,7 +200,7 @@
         @param rangeLimit a range limiting the search for the attributes' applicable
         range.
         @return a CPDictionary containing the attributes associated with the 
    -    character at index anIndex. Returns nil if index
    +    character at index \c anIndex. Returns \c nil if index
         is out of bounds.
     */ 
     - (CPDictionary)attributesAtIndex:(unsigned)anIndex longestEffectiveRange:(CPRangePointer)aRange inRange:(CPRange)rangeLimit
    @@ -268,15 +268,15 @@
         required, the range over which the attribute applies. 
         @note there is no guarantee that the range returned is in fact the complete
         range of a particular attribute. To ensure this use
    -    attribute:atIndex:longestEffectiveRange:inRange: instead but
    +    \c -attribute:atIndex:longestEffectiveRange:inRange: instead but
         note that it may take significantly longer to execute.
         @param attribute the name of the desired attribute.
         @param anIndex is an unsigned integer character index from which to retrieve
         the attribute. It must lie within the bounds of the string.
         @param aRange is a reference to a CPRange object, that is set upon return
         to the range over which the named attribute applies.  If not required pass
    -    nil.
    -    @return the named attribute or nil is the attribute does not
    +    \c nil.
    +    @return the named attribute or \c nil is the attribute does not
         exist.
     */ 
     - (id)attribute:(CPString)attribute atIndex:(unsigned)index effectiveRange:(CPRangePointer)aRange
    @@ -300,10 +300,10 @@
         range over which the attribute applies. This is the maximum range both
         forwards and backwards in the string over which the attribute applies,
         bounded in both directions by the range limit parameter,
    -    rangeLimit.
    +    \c rangeLimit.
         @note this method performs a search to find this range which may be
    -    computationally intensive. Use the rangeLimit to limit the
    -    search space or use attribute:atIndex:effectiveRange: but
    +    computationally intensive. Use the \c rangeLimit to limit the
    +    search space or use \c -attribute:atIndex:effectiveRange: but
         note that it is not guaranteed to return the full range of the current
         character's named attribute.
         @param attribute the name of the desired attribute.
    @@ -313,7 +313,7 @@
         to the range over which the named attribute applies.
         @param rangeLimit a range limiting the search for the attribute's applicable
         range.
    -    @return the named attribute or nil is the attribute does not
    +    @return the named attribute or \c nil is the attribute does not
         exist.
     */
     - (id)attribute:(CPString)attribute atIndex:(unsigned)anIndex longestEffectiveRange:(CPRangePointer)aRange inRange:(CPRange)rangeLimit
    @@ -380,7 +380,7 @@
     //Comparing Attributed Strings
     /*!
         Compares the receiver's characters and attributes to the specified
    -    attributed string, aString, and tests for equality.
    +    attributed string, \c aString, and tests for equality.
         @param aString the CPAttributedString to compare.
         @return a boolean indicating equality.
     */
    @@ -432,7 +432,7 @@
     //Extracting a Substring
     /*!
         Extracts a substring from the receiver, both characters and attributes,
    -    within the range given by aRange.
    +    within the range given by \c aRange.
         @param aRange the range of the substring to extract.
         @return a CPAttributedString containing the desired substring.
         @exception CPRangeException if the range lies outside the receiver's bounds.
    @@ -487,13 +487,13 @@
     //Changing Characters
     /*! 
         Replaces the characters in the receiver with those of the specified string
    -    over the range, aRange. If the range has a length of 0 then
    +    over the range, \c aRange. If the range has a length of 0 then
         the specified string is inserted at the range location. The new characters
         inherit the attributes of the first character in the range that they
         replace or in the case if a 0 range length, the first character before of
         after the insert (after if the insert is at location 0).
         @note the replacement string need not be the same length as the range
    -    being replaced. The full aString is inserted and thus the
    +    being replaced. The full \c aString is inserted and thus the
         receiver's length changes to match this
         @param aRange the range of characters to replace.
         @param aString the string to replace the specified characters in the
    @@ -549,11 +549,11 @@
     
         @note This process removes the attributes already associated with the 
         character range. If you wish to retain the current attributes use
    -    addAttributes:range:.
    +    \c -addAttributes:range:.
         @param aDictionary a CPDictionary of attributes (names and values) to set
         to.
         @param aRange a CPRange indicating the range of characters to set their
    -    associated attributes to aDictionary.
    +    associated attributes to \c aDictionary.
     */
     - (void)setAttributes:(CPDictionary)aDictionary range:(CPRange)aRange
     {
    @@ -580,7 +580,7 @@
     
         @note Attributes currently associated with the characters in the range are
         untouched. To remove all previous attributes when adding use
    -    setAttributes:range:.  
    +    \c -setAttributes:range:.  
         @param aDictionary a CPDictionary of attributes (names and values) to add.
         @param aRange a CPRange indicating the range of characters to add the
         attributes to.
    @@ -619,7 +619,7 @@
     
         @note Attributes currently associated with the characters in the range are
         untouched. To remove all previous attributes when adding use
    -    setAttributes:range:.
    +    \c -setAttributes:range:.
         @param anAttribute a CPString of the attribute name.
         @param aValue a value to assign to the attribute. Can be of any type.
         @param aRange a CPRange indicating the range of characters to add the
    @@ -654,7 +654,7 @@
     
     /*!
         Inserts an attributed string (characters and attributes) at index,
    -    anIndex, into the receiver. The portion of the
    +    \c anIndex, into the receiver. The portion of the
         receiver's attributed string from the specified index to the end is shifted
         until after the inserted string.
         @param aString a CPAttributedString to insert.
    @@ -699,8 +699,8 @@
     }
     
     /*!
    -    Replaces characters and attributes in the range aRange with
    -    those of the given attributed string, aString.
    +    Replaces characters and attributes in the range \c aRange with
    +    those of the given attributed string, \c aString.
         @param aRange a CPRange object specifying the range of characters and
         attributes in the object to replace.
         @param aString a CPAttributedString containing the data to be used for
    @@ -717,7 +717,7 @@
     }
     
     /*!
    -    Sets the objects characters and attributes to those of aString.
    +    Sets the objects characters and attributes to those of \c aString.
         @param aString is a CPAttributedString from which the contents will be
         copied.
     */
    diff --git a/Foundation/CPCoder.j b/Foundation/CPCoder.j
    index e9a376fa0..a9cd1bf97 100644
    --- a/Foundation/CPCoder.j
    +++ b/Foundation/CPCoder.j
    @@ -39,7 +39,7 @@
     
     /*!
         Returns a flag indicating whether the receiver supports keyed coding. The default implementation returns
    -    NO. Subclasses supporting keyed coding must override this to return YES.
    +    \c NO. Subclasses supporting keyed coding must override this to return \c YES.
     */
     -(BOOL)allowsKeyedCoding
     {
    @@ -148,7 +148,7 @@
     
     /*!
         Called after an object is unarchived in case a different object should be used in place of it.
    -    The defaut method returns self. Interested subclasses should override this.
    +    The defaut method returns \c self. Interested subclasses should override this.
         @param aDecoder
         @return the original object or it's substitute.
     */
    diff --git a/Foundation/CPDictionary.j b/Foundation/CPDictionary.j
    index 0233f439a..50243f1df 100755
    --- a/Foundation/CPDictionary.j
    +++ b/Foundation/CPDictionary.j
    @@ -70,7 +70,7 @@
     
         If you are familiar with dictionaries in Cocoa, you'll notice that
         there is no CPMutableDictionary class. The regular CPDictionary
    -    has setObject: and removeObjectForKey: methods.
    +    has \c -setObject:forKey: and \c -removeObjectForKey: methods.
         In Cappuccino there is no distinction between immutable and mutable classes.
         They are all mutable.
     */
    @@ -95,7 +95,7 @@
     }
     
     /*!
    -    Returns a new dictionary, initialized with the contents of aDictionary.
    +    Returns a new dictionary, initialized with the contents of \c aDictionary.
         @param aDictionary the dictionary to copy key-value pairs from
         @return the new CPDictionary
     */
    @@ -402,7 +402,7 @@
         }
     */
     /*!
    -    Returns the object for the entry with key aKey.
    +    Returns the object for the entry with key \c aKey.
         @param aKey the key for the object's entry
         @return the object for the entry
     */
    diff --git a/Foundation/CPIndexSet.j b/Foundation/CPIndexSet.j
    index 519ab04ed..ead56ea10 100644
    --- a/Foundation/CPIndexSet.j
    +++ b/Foundation/CPIndexSet.j
    @@ -133,7 +133,7 @@
     /*!
         Compares the receiver with the provided index set.
         @param anIndexSet the index set to compare to
    -    @return YES if the receiver and the index set are functionally equivalent
    +    @return \c YES if the receiver and the index set are functionally equivalent
     */
     - (BOOL)isEqualToIndexSet:(CPIndexSet)anIndexSet
     {
    @@ -160,9 +160,9 @@
     }
     
     /*!
    -    Returns YES if the index set contains the specified index.
    +    Returns \c YES if the index set contains the specified index.
         @param anIndex the index to check for in the set
    -    @return YES if anIndex is in the receiver index set
    +    @return \c YES if \c anIndex is in the receiver index set
     */
     - (BOOL)containsIndex:(CPInteger)anIndex
     {
    @@ -170,7 +170,7 @@
     }
     
     /*!
    -    Returns YES if the index set contains all the numbers in the specified range.
    +    Returns \c YES if the index set contains all the numbers in the specified range.
         @param aRange the range of numbers to check for in the index set
     */
     - (BOOL)containsIndexesInRange:(CPRange)aRange
    @@ -196,7 +196,7 @@
     }
     
     /*!
    -    Returns YES if the receving index set contains all the indices in the argument.
    +    Returns \c YES if the receving index set contains all the indices in the argument.
         @param anIndexSet the set of indices to check for in the receiving index set
     */
     - (BOOL)containsIndexes:(CPIndexSet)anIndexSet
    @@ -221,9 +221,9 @@
     }
     
     /*!
    -    Checks if the receiver contains at least one number in aRange.
    +    Checks if the receiver contains at least one number in \c aRange.
         @param aRange the range of numbers to check.
    -    @return YES if the receiving index set contains at least one number in the provided range
    +    @return \c YES if the receiving index set contains at least one number in the provided range
     */
     - (BOOL)intersectsIndexesInRange:(CPRange)aRange
     {
    @@ -275,7 +275,7 @@
     }
     
     /*!
    -    Returns the first index value in the receiver which is greater than anIndex.
    +    Returns the first index value in the receiver which is greater than \c anIndex.
         @return the closest index or CPNotFound if no match was found
     */
     - (CPInteger)indexGreaterThanIndex:(CPInteger)anIndex
    @@ -306,7 +306,7 @@
     }
     
     /*!
    -    Returns the first index value in the receiver which is less than anIndex.
    +    Returns the first index value in the receiver which is less than \c anIndex.
         @return the closest index or CPNotFound if no match was found
     */
     - (CPInteger)indexLessThanIndex:(CPInteger)anIndex
    @@ -337,7 +337,7 @@
     }
     
     /*!
    -    Returns the first index value in the receiver which is greater than or equal to anIndex.
    +    Returns the first index value in the receiver which is greater than or equal to \c anIndex.
         @return the matching index or CPNotFound if no match was found
     */
     - (CPInteger)indexGreaterThanOrEqualToIndex:(CPInteger)anIndex
    @@ -346,7 +346,7 @@
     }
     
     /*!
    -    Returns the first index value in the receiver which is less than or equal to anIndex.
    +    Returns the first index value in the receiver which is less than or equal to \c anIndex.
         @return the matching index or CPNotFound if no match was found
     */
     - (CPInteger)indexLessThanOrEqualToIndex:(CPInteger)anIndex
    @@ -357,7 +357,7 @@
     /*!
         Fills up the specified array with numbers from the index set within
         the specified range. The method stops filling up the array until the
    -    aMaxCount number have been added or the range maximum is reached.
    +    \c aMaxCount number have been added or the range maximum is reached.
         @param anArray the array to fill up
         @param aMaxCount the maximum number of numbers to adds
         @param aRangePointer the range of indices to add
    diff --git a/Foundation/CPInvocation.j b/Foundation/CPInvocation.j
    index 9aca90a23..19e8c2cb1 100644
    --- a/Foundation/CPInvocation.j
    +++ b/Foundation/CPInvocation.j
    @@ -103,7 +103,7 @@
     }
     
     /*!
    -    Sets a method argument for the invocation. Arguments 0 and 1 are self and _cmd.
    +    Sets a method argument for the invocation. Arguments 0 and 1 are \c self and \c _cmd.
         @param anArgument the argument to add
         @param anIndex the index of the argument in the method
     */
    @@ -114,7 +114,7 @@
     
     /*!
         Returns the argument at the specified index. Arguments 0 and 1 are
    -    self and _cmd respectively. Thus, method arguments start at 2.
    +    \c self and \c _cmd respectively. Thus, method arguments start at 2.
         @param anIndex the index of the argument to return
         @throws CPInvalidArgumentException if anIndex is greater than or equal to the invocation's number of arguments.
     */
    diff --git a/Foundation/CPKeyValueObserving.j b/Foundation/CPKeyValueObserving.j
    index 7a1d575ae..a2c3fc2d5 100644
    --- a/Foundation/CPKeyValueObserving.j
    +++ b/Foundation/CPKeyValueObserving.j
    @@ -58,7 +58,7 @@
         if (!anObserver || !aPath)
             return;
     
    -    [[KVOProxyMap objectForKey:[self UID]] _removeObserver:anObserver forKeyPath:aPath];
    +    [self[KVOProxyKey] _removeObserver:anObserver forKeyPath:aPath];
     }
     
     + (BOOL)automaticallyNotifiesObserversForKey:(CPString)aKey
    @@ -98,12 +98,9 @@ CPKeyValueChangeInsertion   = 2;
     CPKeyValueChangeRemoval     = 3;
     CPKeyValueChangeReplacement = 4;
     
    -//convenience
    -var kvoNewAndOld = CPKeyValueObservingOptionNew|CPKeyValueObservingOptionOld;
    -
    -// Map of real objects to their KVO proxy
    -var KVOProxyMap = [CPDictionary dictionary],
    -    DependentKeysMap = [CPDictionary dictionary];
    +var kvoNewAndOld = CPKeyValueObservingOptionNew|CPKeyValueObservingOptionOld,
    +    DependentKeysKey = "$KVODEPENDENT",
    +    KVOProxyKey = "$KVOPROXY";
     
     //rule of thumb: _ methods are called on the real proxy object, others are called on the "fake" proxy object (aka the real object)
     
    @@ -113,13 +110,14 @@ var KVOProxyMap = [CPDictionary dictionary],
         id              _targetObject;
         Class           _nativeClass;
         CPDictionary    _changesForKey;
    -    CPDictionary    _observersForKey;
    +    Object          _observersForKey;
    +    int             _observersForKeyLength;
         CPSet           _replacedKeys;
     }
     
     + (id)proxyForObject:(CPObject)anObject
     {
    -    var proxy = [KVOProxyMap objectForKey:[anObject UID]];
    +    var proxy = anObject[KVOProxyKey];
     
         if (proxy)
             return proxy;
    @@ -128,7 +126,7 @@ var KVOProxyMap = [CPDictionary dictionary],
     
         [proxy _replaceClass];
     
    -    [KVOProxyMap setObject:proxy forKey:[anObject UID]];
    +    anObject[KVOProxyKey] = proxy;
     
         return proxy;
     }
    @@ -139,9 +137,10 @@ var KVOProxyMap = [CPDictionary dictionary],
     
         _targetObject       = aTarget;
         _nativeClass        = [aTarget class];
    -    _observersForKey    = [CPDictionary dictionary];
    -    _changesForKey      = [CPDictionary dictionary];
         _replacedKeys       = [CPSet set];
    +    _observersForKey    = {};
    +    _changesForKey      = {};
    +    _observersForKeyLength = 0;
     
         return self;
     }
    @@ -205,30 +204,29 @@ var KVOProxyMap = [CPDictionary dictionary],
             }
         }
     
    -    var affectingKeys = [[_nativeClass keyPathsForValuesAffectingValueForKey:aKey] allObjects];
    +    var affectingKeys = [[_nativeClass keyPathsForValuesAffectingValueForKey:aKey] allObjects],
    +        affectingKeysCount = affectingKeys ? affectingKeys.length : 0;
     
    -    if (![affectingKeys count])
    +    if (!affectingKeysCount)
             return;
     
    -    var dependentKeysForClass = [DependentKeysMap objectForKey:[_nativeClass UID]];
    +    var dependentKeysForClass = _nativeClass[DependentKeysKey];
     
         if (!dependentKeysForClass)
         {
    -        dependentKeysForClass = [CPDictionary new];
    -        [DependentKeysMap setObject:dependentKeysForClass forKey:[_nativeClass UID]];
    +        dependentKeysForClass = {};
    +        _nativeClass[DependentKeysKey] = dependentKeysForClass;
         }
     
    -    var count = [affectingKeys count];
    -
    -    while (count--)
    +    while (affectingKeysCount--)
         {
    -        var affectingKey = affectingKeys[count],
    -            affectedKeys = [dependentKeysForClass objectForKey:affectingKey];
    +        var affectingKey = affectingKeys[affectingKeysCount],
    +            affectedKeys = dependentKeysForClass[affectingKey];
     
             if (!affectedKeys)
             {
                 affectedKeys = [CPSet new];
    -            [dependentKeysForClass setObject:affectedKeys forKey:affectingKey];
    +            dependentKeysForClass[affectingKey] = affectedKeys;
             }
     
             [affectedKeys addObject:aKey];
    @@ -248,12 +246,13 @@ var KVOProxyMap = [CPDictionary dictionary],
         else
             [self _replaceSetterForKey:aPath];
     
    -    var observers = [_observersForKey objectForKey:aPath];
    +    var observers = _observersForKey[aPath];
     
         if (!observers)
         {
             observers = [CPDictionary dictionary];
    -        [_observersForKey setObject:observers forKey:aPath];
    +        _observersForKey[aPath] = observers;
    +        _observersForKeyLength++;
         }
     
         [observers setObject:_CPKVOInfoMake(anObserver, options, aContext, forwarder) forKey:[anObserver UID]];
    @@ -272,7 +271,7 @@ var KVOProxyMap = [CPDictionary dictionary],
     
     - (void)_removeObserver:(id)anObserver forKeyPath:(CPString)aPath
     {
    -    var observers = [_observersForKey objectForKey:aPath];
    +    var observers = _observersForKey[aPath];
     
         if (aPath.indexOf('.') != CPNotFound)
         {
    @@ -283,12 +282,15 @@ var KVOProxyMap = [CPDictionary dictionary],
         [observers removeObjectForKey:[anObserver UID]];
     
         if (![observers count])
    -        [_observersForKey removeObjectForKey:aPath];
    +    {
    +        _observersForKeyLength--;
    +        delete _observersForKey[aPath];
    +    }
     
    -    if (![_observersForKey count])
    +    if (!_observersForKeyLength)
         {
             _targetObject.isa = _nativeClass; //restore the original class
    -        [KVOProxyMap removeObjectForKey:[_targetObject UID]];
    +        delete _targetObject[KVOProxyKey];
         }
     }
     
    @@ -296,7 +298,7 @@ var KVOProxyMap = [CPDictionary dictionary],
     
     - (void)_sendNotificationsForKey:(CPString)aKey changeOptions:(CPDictionary)changeOptions isBefore:(BOOL)isBefore
     {
    -    var changes = [_changesForKey objectForKey:aKey];
    +    var changes = _changesForKey[aKey];
     
         if (isBefore)
         {
    @@ -328,7 +330,7 @@ var KVOProxyMap = [CPDictionary dictionary],
             
             [changes setObject:1 forKey:CPKeyValueChangeNotificationIsPriorKey];
     
    -        [_changesForKey setObject:changes forKey:aKey];
    +        _changesForKey[aKey] = changes;
         }
         else
         {
    @@ -359,8 +361,8 @@ var KVOProxyMap = [CPDictionary dictionary],
             }
         }
         
    -    var observers = [[_observersForKey objectForKey:aKey] allValues],
    -        count = [observers count];
    +    var observers = [_observersForKey[aKey] allValues],
    +        count = observers ? observers.length : 0;
     
         while (count--)
         {
    @@ -372,7 +374,12 @@ var KVOProxyMap = [CPDictionary dictionary],
                 [observerInfo.observer observeValueForKeyPath:aKey ofObject:_targetObject change:changes context:observerInfo.context];
         }
         
    -    var keysComposedOfKey = [[[DependentKeysMap objectForKey:[_nativeClass UID]] objectForKey:aKey] allObjects];
    +    var dependentKeysMap = _nativeClass[DependentKeysKey];
    +
    +    if (!dependentKeysMap)
    +        return;
    +
    +    var keysComposedOfKey = [dependentKeysMap[aKey] allObjects];
         
         if (!keysComposedOfKey)
             return;
    @@ -425,7 +432,7 @@ var KVOProxyMap = [CPDictionary dictionary],
     
     - (Class)class
     {
    -    return [KVOProxyMap objectForKey:[self UID]]._nativeClass;
    +    return self[KVOProxyKey]._nativeClass;
     }
     
     - (Class)superclass
    diff --git a/Foundation/CPKeyedArchiver.j b/Foundation/CPKeyedArchiver.j
    index 05f9f601b..328617824 100644
    --- a/Foundation/CPKeyedArchiver.j
    +++ b/Foundation/CPKeyedArchiver.j
    @@ -68,7 +68,7 @@ var _CPKeyedArchiverStringClass                         = Nil,
         Implements keyed archiving of object graphs. Archiving means to
         write data out in a format that be read in again later, or possibly
         stored in a file. To read the data back in, use a
    -    CPKeyedUnarchiver.
    +    \c CPKeyedUnarchiver.
     
         @par Delegate Methods
         
    @@ -87,7 +87,7 @@ var _CPKeyedArchiverStringClass                         = Nil,
     
         @delegate -(id)archiver:(CPKeyedArchiver)archiver willEncodeObject:(id)object;
         Called when an object is about to be encoded. Allows the delegate to replace
    -    the object that gets encoded with a substitute or nil.
    +    the object that gets encoded with a substitute or \c nil.
         @param archiver the archiver encoding the object
         @param object the candidate object for encoding
         @return the object to encode
    @@ -158,7 +158,7 @@ var _CPKeyedArchiverStringClass                         = Nil,
     
     // Initializing an NSKeyedArchiver object
     /*!
    -    Initializes the keyed archiver with the specified CPMutableData for writing.
    +    Initializes the keyed archiver with the specified \c CPMutableData for writing.
         @param data the object to archive to
         @return the initialized keyed archiver
     */
    @@ -246,9 +246,9 @@ var _CPKeyedArchiverStringClass                         = Nil,
     }
     
     /*!
    -    Encodes a BOOL value
    -    @param aBool the BOOL value
    -    @param aKey the key to associate with the BOOL
    +    Encodes a \c BOOL value
    +    @param aBool the \c BOOL value
    +    @param aKey the key to associate with the \c BOOL
     */
     - (void)encodeBool:(BOOL)aBOOL forKey:(CPString)aKey
     {
    @@ -256,9 +256,9 @@ var _CPKeyedArchiverStringClass                         = Nil,
     }
     
     /*!
    -    Encodes a double value
    -    @param aDouble the double value
    -    @param aKey the key to associate with the double
    +    Encodes a \c double value
    +    @param aDouble the \c double value
    +    @param aKey the key to associate with the \c double
     */
     - (void)encodeDouble:(double)aDouble forKey:(CPString)aKey
     {
    @@ -266,9 +266,9 @@ var _CPKeyedArchiverStringClass                         = Nil,
     }
     
     /*!
    -    Encodes a float value
    -    @param aFloat the float value
    -    @param aKey the key to associate with the float
    +    Encodes a \c float value
    +    @param aFloat the \c float value
    +    @param aKey the key to associate with the \c float
     */
     - (void)encodeFloat:(float)aFloat forKey:(CPString)aKey
     {
    @@ -276,9 +276,9 @@ var _CPKeyedArchiverStringClass                         = Nil,
     }
     
     /*!
    -    Encodes a int value
    -    @param anInt the int value
    -    @param aKey the key to associate with the int
    +    Encodes a \c int value
    +    @param anInt the \c int value
    +    @param aKey the key to associate with the \c int
     */
     - (void)encodeInt:(float)anInt forKey:(CPString)aKey
     {
    @@ -409,8 +409,8 @@ var _CPKeyedArchiverStringClass                         = Nil,
     // Managing classes and class names
     /*!
         Allows substitution of class types for encoding. Specifically classes
    -    of type aClass encountered by all keyed archivers will
    -    instead be archived as a class of type aClassName.
    +    of type \c aClass encountered by all keyed archivers will
    +    instead be archived as a class of type \c aClassName.
         @param aClassName the substitute class name
         @param aClass the class to substitute
     */
    @@ -424,9 +424,9 @@ var _CPKeyedArchiverStringClass                         = Nil,
     
     /*!
         Returns the name of the substitute class used for encoding
    -    aClass by all keyed archivers.
    +    \c aClass by all keyed archivers.
         @param aClass the class to substitute
    -    @return the name of the substitute class, or nil if there
    +    @return the name of the substitute class, or \c nil if there
         is no substitute class
     */
     + (CPString)classNameForClass:(Class)aClass
    @@ -441,8 +441,8 @@ var _CPKeyedArchiverStringClass                         = Nil,
     
     /*!
         Allows substitution of class types for encoding. Specifically classes
    -    of type aClass encountered by this keyed archiver will
    -    instead be archived as a class of type aClassName.
    +    of type \c aClass encountered by this keyed archiver will
    +    instead be archived as a class of type \c aClassName.
         @param aClassName the substitute class name
         @param aClass the class to substitute
     */
    @@ -455,9 +455,9 @@ var _CPKeyedArchiverStringClass                         = Nil,
     }
     
     /*!
    -    Returns the name of the substitute class used for encoding aClass by this keyed archiver.
    +    Returns the name of the substitute class used for encoding \c aClass by this keyed archiver.
         @param aClass the class to substitute
    -    @return the name of the substitute class, or nil if there is no substitute class
    +    @return the name of the substitute class, or \c nil if there is no substitute class
     */
     - (CPString)classNameForClass:(Class)aClass
     {
    diff --git a/Foundation/CPKeyedUnarchiver.j b/Foundation/CPKeyedUnarchiver.j
    index 37b5c20e9..f9be40a40 100644
    --- a/Foundation/CPKeyedUnarchiver.j
    +++ b/Foundation/CPKeyedUnarchiver.j
    @@ -75,7 +75,7 @@ var _CPKeyedUnarchiverArrayClass                                            = Ni
         @param an array of class names describing the encoded object's
         class hierarchy. The first index is the encoded class name, and
         each superclass is after that.
    -    @return the Class to use instead or nil
    +    @return the Class to use instead or \c nil
         to abort the unarchiving operation
     
         @delegate -(id)unarchiver:(CPKeyedUnarchiver)unarchiver didDecodeObject:(id)object;
    @@ -83,10 +83,10 @@ var _CPKeyedUnarchiverArrayClass                                            = Ni
         @param unarchiver the unarchiver doing the decoding
         @param object the decoded objec
         @return a substitute to use for the decoded object. This can be the same object argument provide,
    -    another object or nil.
    +    another object or \c nil.
     
         @delegate -(void)unarchiver:(CPKeyedUnarchiver)unarchiver willReplaceObject:(id)object withObject:(id)newObject;
    -    Called when a decoded object has been substituted with another. (for example, from unarchiver:didDecodeObject:.
    +    Called when a decoded object has been substituted with another. (for example, from \c -unarchiver:didDecodeObject:.
         @param unarchiver the unarchiver that decoded the object
         @param object the original decoded object
         @param newObject the replacement object
    @@ -184,7 +184,7 @@ var _CPKeyedUnarchiverArrayClass                                            = Ni
     }
     
     /*
    -    Returns YES if an object exists for aKey.
    +    Returns \c YES if an object exists for \c aKey.
         @param aKey the object's associated key
     */
     - (BOOL)containsValueForKey:(CPString)aKey
    @@ -213,9 +213,9 @@ var _CPKeyedUnarchiverArrayClass                                            = Ni
     }
     
     /*
    -    Decodes a BOOL from the archive
    -    @param aKey the BOOL's associated key
    -    @return the decoded BOOL
    +    Decodes a \c BOOL from the archive
    +    @param aKey the \c BOOL's associated key
    +    @return the decoded \c BOOL
     */
     - (BOOL)decodeBoolForKey:(CPString)aKey
     {
    @@ -223,9 +223,9 @@ var _CPKeyedUnarchiverArrayClass                                            = Ni
     }
     
     /*
    -    Decodes a float from the archive
    -    @param aKey the float's associated key
    -    @return the decoded float
    +    Decodes a \c float from the archive
    +    @param aKey the \c float's associated key
    +    @return the decoded \c float
     */
     - (float)decodeFloatForKey:(CPString)aKey
     {
    @@ -233,9 +233,9 @@ var _CPKeyedUnarchiverArrayClass                                            = Ni
     }
     
     /*
    -    Decodes a double from the archive.
    -    @param aKey the double's associated key
    -    @return the decoded double
    +    Decodes a \c double from the archive.
    +    @param aKey the \c double's associated key
    +    @return the decoded \c double
     */
     - (double)decodeDoubleForKey:(CPString)aKey
     {
    @@ -243,9 +243,9 @@ var _CPKeyedUnarchiverArrayClass                                            = Ni
     }
     
     /*
    -    Decodes an int from the archive.
    -    @param aKey the int's associated key
    -    @return the decoded int
    +    Decodes an \c int from the archive.
    +    @param aKey the \c int's associated key
    +    @return the decoded \c int
     */
     - (int)decodeIntForKey:(CPString)aKey
     {
    diff --git a/Foundation/CPNotificationCenter.j b/Foundation/CPNotificationCenter.j
    index 564c6ea66..527161557 100644
    --- a/Foundation/CPNotificationCenter.j
    +++ b/Foundation/CPNotificationCenter.j
    @@ -72,7 +72,7 @@ var CPNotificationDefaultCenter = nil;
     
     /*!
         Adds an object as an observer. The observer will receive notifications with the specified name
    -    and/or containing the specified object (depending on if they are nil.
    +    and/or containing the specified object (depending on if they are \c nil.
         @param anObserver the observing object
         @param aSelector the message sent to the observer when a notification occurrs
         @param aNotificationName the name of the notification the observer wants to watch
    diff --git a/Foundation/CPNull.j b/Foundation/CPNull.j
    index a0aca8598..43ba1cbc9 100644
    --- a/Foundation/CPNull.j
    +++ b/Foundation/CPNull.j
    @@ -28,10 +28,10 @@ var CPNullSharedNull = nil;
     /*! 
         @class CPNull
         @ingroup foundation
    -    @brief An object representation of nil.
    +    @brief An object representation of \c nil.
     
    -    This class is used as an object representation of nil. This is handy when a collection
    -    only accepts objects as values, but you would like a nil representation in there.
    +    This class is used as an object representation of \c nil. This is handy when a collection
    +    only accepts objects as values, but you would like a \c nil representation in there.
     */
     @implementation CPNull : CPObject
     {
    @@ -46,7 +46,7 @@ var CPNullSharedNull = nil;
     }*/
     /*!
         Returns the singleton instance of the CPNull
    -    object. While CPNull and nil should
    +    object. While CPNull and \c nil should
         be interpreted as the same, they are not equal ('==').
     */
     + (CPNull)null
    diff --git a/Foundation/CPNumber.j b/Foundation/CPNumber.j
    index e1dccbeff..ffb89c537 100644
    --- a/Foundation/CPNumber.j
    +++ b/Foundation/CPNumber.j
    @@ -33,7 +33,7 @@ var __placeholder = new Number(),
         @brief A bridged object to native Javascript numbers.
     
         This class primarily exists for source compatability. The JavaScript
    -    Number type can be changed on the fly based on context,
    +    \c Number type can be changed on the fly based on context,
         so there is no need to call any of these methods. 
         
         In other words, native JavaScript numbers are bridged to CPNumber,
    diff --git a/Foundation/CPObject.j b/Foundation/CPObject.j
    index 95337ba3d..e9173f372 100644
    --- a/Foundation/CPObject.j
    +++ b/Foundation/CPObject.j
    @@ -55,9 +55,9 @@
         To get description value you can use %@ specifier everywhere where format
         specifiers are allowed:
         
    var inst = [[SomeClass alloc] initWithSomeValue:10];
    -CPLog(@"Got some class: %@", inst);
    +CPLog(@"Got some class: %@", inst); would output: -
    Got some class: 
    + \c Got \c some \c class: \c @todo document KVC usage. */ @@ -76,7 +76,7 @@ CPLog(@"Got some class: %@", inst);
    } /*! - Allocates a new instance of the receiver, and sends it an init + Allocates a new instance of the receiver, and sends it an \c -init @return the new object */ + (id)new @@ -158,7 +158,7 @@ CPLog(@"Got some class: %@", inst);
    } /*! - Returns YES if the receiving class is a subclass of aClass. + Returns \c YES if the receiving class is a subclass of \c aClass. @param aClass the class to test inheritance from */ + (BOOL)isSubclassOfClass:(Class)aClass @@ -173,7 +173,7 @@ CPLog(@"Got some class: %@", inst);
    } /*! - Returns YES if the receiver is a aClass type, or a subtype of it. + Returns \c YES if the receiver is a \c aClass type, or a subtype of it. @param aClass the class to test as the receiver's class or super class. */ - (BOOL)isKindOfClass:(Class)aClass @@ -187,7 +187,7 @@ CPLog(@"Got some class: %@", inst); } /*! - Returns YES if the receiver is of the aClass class type. + Returns \c YES if the receiver is of the \c aClass class type. @param aClass the class to test the receiper */ - (BOOL)isMemberOfClass:(Class)aClass @@ -202,7 +202,7 @@ CPLog(@"Got some class: %@", inst); /*! Determines whether the receiver's root object is a proxy. - @return YES if the root object is a proxy + @return \c YES if the root object is a proxy */ - (BOOL)isProxy { @@ -213,7 +213,7 @@ CPLog(@"Got some class: %@", inst); /*! Test whether instances of this class respond to the provided selector. @param aSelector the selector for which to test the class - @return YES if instances of the class respond to the selector + @return \c YES if instances of the class respond to the selector */ + (BOOL)instancesRespondToSelector:(SEL)aSelector { @@ -223,7 +223,7 @@ CPLog(@"Got some class: %@", inst); /*! Tests whether the receiver responds to the provided selector. @param aSelector the selector for which to test the receiver - @return YES if the receiver responds to the selector + @return \c YES if the receiver responds to the selector */ - (BOOL)respondsToSelector:(SEL)aSelector { @@ -310,7 +310,7 @@ CPLog(@"Got some class: %@", inst); /*! Subclasses can override this method to forward message to other objects. Overwriting this method in conjunction with - methodSignatureForSelector: allows the receiver to + \c -methodSignatureForSelector: allows the receiver to forward messages for which it does not respond, to another object that does. */ - (void)forwardInvocation:(CPInvocation)anInvocation @@ -376,7 +376,7 @@ CPLog(@"Got some class: %@", inst); /*! Can be overridden by subclasses to substitute a different class to represent the receiver for keyed archiving. - @return the class to use. A nil means to ignore the method result. + @return the class to use. A \c nil means to ignore the method result. */ - (Class)classForKeyedArchiver { @@ -477,8 +477,8 @@ CPLog(@"Got some class: %@", inst); } /*! - Determines if anObject is functionally equivalent to the receiver. - @return YES if anObject is functionally equivalent to the receiver. + Determines if \c anObject is functionally equivalent to the receiver. + @return \c YES if \c anObject is functionally equivalent to the receiver. */ - (BOOL)isEqual:(id)anObject { diff --git a/Foundation/CPRange.j b/Foundation/CPRange.j index aa446f77f..3e0bafa7b 100755 --- a/Foundation/CPRange.j +++ b/Foundation/CPRange.j @@ -60,7 +60,7 @@ function CPMakeRangeCopy(aRange) } /*! - Sets a range's length to 0. + Sets a range's \c length to 0. @param aRange the range to empty @group CPRange @return CPRange the empty range (same as the argument) @@ -71,7 +71,7 @@ function CPEmptyRange(aRange) } /*! - Finds the range maximum. (location + length) + Finds the range maximum. (\c location + length) @param aRange the range to calculate a maximum from @group CPRange @return int the range maximum @@ -85,7 +85,7 @@ function CPMaxRange(aRange) Determines if two CPRanges are equal. @param lhsRange the first CPRange @param rhsRange the second CPRange - @return BOOL YES if the two CPRanges are equal. + @return BOOL \c YES if the two CPRanges are equal. */ function CPEqualRanges(lhsRange, rhsRange) { @@ -97,7 +97,7 @@ function CPEqualRanges(lhsRange, rhsRange) @param aLocation the number to check @param aRange the CPRange to check within @group CPRange - @return BOOL YES if aLocation/code> is within the range + @return BOOL \c YES if \c aLocation is within the range */ function CPLocationInRange(aLocation, aRange) { @@ -105,8 +105,8 @@ function CPLocationInRange(aLocation, aRange) } /*! - Creates a new range with the minimum location and a length - that extends to the maximum length. + Creates a new range with the minimum \c location and a \c length + that extends to the maximum \c length. @param lhsRange the first CPRange @param rhsRange the second CPRange @group CPRange diff --git a/Foundation/CPSortDescriptor.j b/Foundation/CPSortDescriptor.j index 27dca8d9c..27088c359 100755 --- a/Foundation/CPSortDescriptor.j +++ b/Foundation/CPSortDescriptor.j @@ -94,7 +94,7 @@ CPOrderedDescending = 1; // Getting information about a sort descriptor /*! - Returns YES if the sort descriptor's order is ascending. + Returns \c YES if the sort descriptor's order is ascending. */ - (BOOL)ascending { diff --git a/Foundation/CPString.j b/Foundation/CPString.j index 9f3cb1930..0639bb8b1 100644 --- a/Foundation/CPString.j +++ b/Foundation/CPString.j @@ -62,7 +62,8 @@ var CPStringRegexSpecialCharacters = [ '/', '.', '*', '+', '?', '|', '$', '^', '(', ')', '[', ']', '{', '}', '\\' ], - CPStringRegexEscapeExpression = new RegExp("(\\" + CPStringRegexSpecialCharacters.join("|\\") + ")", 'g'); + CPStringRegexEscapeExpression = new RegExp("(\\" + CPStringRegexSpecialCharacters.join("|\\") + ")", 'g'), + CPStringRegexTrimWhitespace = new RegExp("(^\\s+|\\s+$)", 'g'); /*! @class CPString @@ -70,7 +71,7 @@ var CPStringRegexSpecialCharacters = [ @brief An immutable string (collection of characters). CPString is an object that allows management of strings. Because CPString is - based on the JavaScript String object, CPStrings are immutable, although the + based on the JavaScript \c String object, CPStrings are immutable, although the class does have methods that create new CPStrings generated from modifications to the receiving instance. @@ -107,8 +108,8 @@ var CPStringRegexSpecialCharacters = [ /*! Returns a copy of the specified string. - @param aString a non-nil string to copy - @throws CPInvalidArgumentException if aString is nil + @param aString a non-\c nil string to copy + @throws CPInvalidArgumentException if \c aString is \c nil @return the new CPString */ + (id)stringWithString:(CPString)aString @@ -248,11 +249,11 @@ var CPStringRegexSpecialCharacters = [ /*! Tokenizes the receiver string using the specified delimiter. For example, if the receiver is: -
    "arash.francisco.ross.tom"
    + \c "arash.francisco.ross.tom" and the delimiter is: -
    "."
    + \c "." the returned array would contain: -
    ["arash", "francisco", "ross", "tom"]
    +
     ["arash", "francisco", "ross", "tom"] 
    @param the delimiter @return the array of tokens */ @@ -272,7 +273,7 @@ var CPStringRegexSpecialCharacters = [ } /*! - Returns a substring starting from the specified range location to the range length. + Returns a substring starting from the specified range \c location to the range \c length. @param the range of the substring @return the substring */ @@ -295,7 +296,7 @@ var CPStringRegexSpecialCharacters = [ /*! 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. + does not exist in the receiver, the range \c length will be 0. @param aString the string to search for in the receiver @return the range of charactrs in the receiver */ @@ -319,7 +320,7 @@ var CPStringRegexSpecialCharacters = [ @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, - the length of the range will be 0. + the \c length of the range will be 0. */ - (CPRange)rangeOfString:(CPString)aString options:(int)aMask { @@ -342,7 +343,7 @@ var CPStringRegexSpecialCharacters = [ @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. + the \c length of the range will be 0. */ - (CPRange)rangeOfString:(CPString)aString options:(int)aMask range:(CPrange)aRange { @@ -376,7 +377,7 @@ var CPStringRegexSpecialCharacters = [ 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
    +    @param replacement the string with which to replace the \c target
     */
     
     - (CPString)stringByReplacingOccurrencesOfString:(CPString)target withString:(CPString)replacement
    @@ -388,9 +389,9 @@ var CPStringRegexSpecialCharacters = [
         Returns a new string in which all occurrences of a target string in a specified range of the receiver
         are replaced by another given string.
         @param target The string to replace
    -    @param replacement the string with which to replace the 
    target
    -    @param options A mask of options to use when comparing 
    target
     with the receiver. Pass 0 to specify no options
    -    @param searchRange The range in the receiver in which to search for 
    target
    .
    +    @param replacement the string with which to replace the \c target.
    +    @param options A mask of options to use when comparing \c target with the receiver. Pass 0 to specify no options
    +    @param searchRange The range in the receiver in which to search for \c target.
     */
     
     - (CPString)stringByReplacingOccurrencesOfString:(CPString)target withString:(CPString)replacement options:(int)options range:(CPRange)searchRange
    @@ -413,7 +414,7 @@ var CPStringRegexSpecialCharacters = [
        Returns a new string in which the characters in a specified range of the receiver 
        are replaced by a given string.
        @param range A range of characters in the receiver.
    -   @param replacement The string with which to replace the characters in 
    range
    . + @param replacement The string with which to replace the characters in \c range. */ - (CPString)stringByReplacingCharactersInRange:(CPRange)range withString:(CPString)replacement @@ -421,6 +422,13 @@ var CPStringRegexSpecialCharacters = [ return '' + substring(0, range.location) + replacement + substring(range.location + range.length, self.length); } +/*! + Returns a new string with leading and trailing whitespace trimmed +*/ +- (CPString)stringByTrimmingWhitespace +{ + return self.replace(CPStringRegexTrimWhitespace, ""); +} // Identifying and comparing strings @@ -486,9 +494,9 @@ var CPStringRegexSpecialCharacters = [ } /*! - Returns YES if the receiver starts - with the specified string. If aString - is empty, the method will return NO. + Returns \c YES if the receiver starts + with the specified string. If \c aString + is empty, the method will return \c NO. */ - (BOOL)hasPrefix:(CPString)aString { @@ -496,9 +504,9 @@ var CPStringRegexSpecialCharacters = [ } /*! - Returns NO if the receiver ends - with the specified string. If aString - is empty, the method will return NO. + Returns \c NO if the receiver ends + with the specified string. If \c aString + is empty, the method will return \c NO. */ - (BOOL)hasSuffix:(CPString)aString { @@ -506,7 +514,7 @@ var CPStringRegexSpecialCharacters = [ } /*! - Returns YES if the specified string contains the same characters as the receiver. + Returns \c YES if the specified string contains the same characters as the receiver. */ - (BOOL)isEqualToString:(CPString)aString { @@ -569,8 +577,8 @@ var CPStringRegexSpecialCharacters = [ 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 + Returns \c YES on encountering one of "Y", "y", "T", "t", or + a digit 1-9. Returns \c NO otherwise. This method skips the initial whitespace characters, +,- followed by Zeroes. */ diff --git a/Foundation/CPTimer.j b/Foundation/CPTimer.j index 62d1dad7e..e1ec83ce5 100644 --- a/Foundation/CPTimer.j +++ b/Foundation/CPTimer.j @@ -87,7 +87,7 @@ */ + (CPTimer)timerWithTimeInterval:(CPTimeInterval)seconds invocation:(CPInvocation)anInvocation repeats:(BOOL)shouldRepeat { - return [[self alloc] initWithFireDate:nil interval:seconds invocation:anInvocation repeats:shouldRepeat]; + return [[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds invocation:anInvocation repeats:shouldRepeat]; } /*! @@ -95,7 +95,7 @@ */ + (CPTimer)timerWithTimeInterval:(CPTimeInterval)seconds target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)shouldRepeat { - return [[self alloc] initWithFireDate:nil interval:seconds target:aTarget selector:aSelector userInfo:userInfo repeats:shouldRepeat]; + return [[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds target:aTarget selector:aSelector userInfo:userInfo repeats:shouldRepeat]; } /*! @@ -103,7 +103,7 @@ */ + (CPTimer)timerWithTimeInterval:(CPTimeInterval)seconds callback:(Function)aFunction repeats:(BOOL)shouldRepeat { - return [[self alloc] initWithFireDate:nil interval:seconds callback:aFunction repeats:shouldRepeat]; + return [[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds callback:aFunction repeats:shouldRepeat]; } /*! diff --git a/Foundation/CPURLConnection.j b/Foundation/CPURLConnection.j index 675a57cd5..d1475f18b 100644 --- a/Foundation/CPURLConnection.j +++ b/Foundation/CPURLConnection.j @@ -98,7 +98,7 @@ var CPURLConnectionDelegate = nil; @param aRequest contains the URL to request the data from @param aURLResponse not used @param anError not used - @return the data at the URL or nil if there was an error + @return the data at the URL or \c nil if there was an error */ + (CPData)sendSynchronousRequest:(CPURLRequest)aRequest returningResponse:({CPURLResponse})aURLResponse error:({CPError})anError { @@ -130,7 +130,7 @@ var CPURLConnectionDelegate = nil; Creates a url connection with a delegate to monitor the request progress. @param aRequest contains the URL to obtain data from @param aDelegate will be sent messages related to the request progress - @return a connection that can be started to initiate the request + @return a connection that can be \c started to initiate the request */ + (CPURLConnection)connectionWithRequest:(CPURLRequest)aRequest delegate:(id)aDelegate { @@ -141,7 +141,7 @@ var CPURLConnectionDelegate = nil; Default class initializer. Use one of the class methods instead. @param aRequest contains the URL to contact @param aDelegate will receive progress messages - @param shouldStartImmediately whether the start method should be called from here + @param shouldStartImmediately whether the \c -start method should be called from here @return the initialized url connection */ - (id)initWithRequest:(CPURLRequest)aRequest delegate:(id)aDelegate startImmediately:(BOOL)shouldStartImmediately diff --git a/Foundation/CPUndoManager.j b/Foundation/CPUndoManager.j index 0bab9cfc7..1223b1e29 100644 --- a/Foundation/CPUndoManager.j +++ b/Foundation/CPUndoManager.j @@ -163,8 +163,8 @@ var _CPUndoGroupingParentKey = @"_CPUndoGroupingParentKey", execution of undo or redo actions, and tuning behavior parameters such as the size of the undo stack. Each application entity with its own editing history (e.g., a document) should have its own undo manager instance. - Obtain an instance through a simple [[CPUndoManager alloc] init] - message. + Obtain an instance through a simple \c [[CPUndoManager \c alloc] \c init] + message. */ @implementation CPUndoManager : CPObject { @@ -208,7 +208,7 @@ var _CPUndoGroupingParentKey = @"_CPUndoGroupingParentKey", // Registering Undo Operations /*! - Registers an undo operation. You invoke this method with the target of the undo action providing the selector which can perform the undo with the provided object. The object is often a dictionary of the identifying the attribute and their values before the change. The invocation will be added to the current grouping. If the registrations have been disabled through -disableUndoRegistration, this method does nothing. + Registers an undo operation. You invoke this method with the target of the undo action providing the selector which can perform the undo with the provided object. The object is often a dictionary of the identifying the attribute and their values before the change. The invocation will be added to the current grouping. If the registrations have been disabled through \c -disableUndoRegistration, this method does nothing. @param aTarget the target for the undo invocation @param aSelector the selector for the action message @param anObject the argument for the action message @@ -287,7 +287,7 @@ var _CPUndoGroupingParentKey = @"_CPUndoGroupingParentKey", // Checking Undo Ability /*! - Returns YES if the user can perform a redo operation. + Returns \c YES if the user can perform a redo operation. */ - (BOOL)canRedo { @@ -295,7 +295,7 @@ var _CPUndoGroupingParentKey = @"_CPUndoGroupingParentKey", } /*! - Returns YES if the user can perform an undo operation. + Returns \c YES if the user can perform an undo operation. */ - (BOOL)canUndo { @@ -447,7 +447,7 @@ var _CPUndoGroupingParentKey = @"_CPUndoGroupingParentKey", } /*! - Returns YES if the manager groups undo operations at every iteration of the run loop. + Returns \c YES if the manager groups undo operations at every iteration of the run loop. */ - (BOOL)groupsByEvent { @@ -456,7 +456,7 @@ var _CPUndoGroupingParentKey = @"_CPUndoGroupingParentKey", /*! Sets whether the manager should group undo operations at every iteration of the run loop. - @param aFlag YES groups undo operations + @param aFlag \c YES groups undo operations */ - (void)setGroupsByEvent:(BOOL)aFlag { @@ -502,7 +502,7 @@ var _CPUndoGroupingParentKey = @"_CPUndoGroupingParentKey", } /*! - Returns YES if undo registration is enabled. + Returns \c YES if undo registration is enabled. */ - (BOOL)isUndoRegistrationEnabled { @@ -511,7 +511,7 @@ var _CPUndoGroupingParentKey = @"_CPUndoGroupingParentKey", // Checking Whether Undo or Redo Is Being Performed /*! - Returns YES if the manager is currently performing an undo. + Returns \c YES if the manager is currently performing an undo. */ - (BOOL)isUndoing { @@ -519,7 +519,7 @@ var _CPUndoGroupingParentKey = @"_CPUndoGroupingParentKey", } /*! - Returns YES if the manager is currently performing a redo. + Returns \c YES if the manager is currently performing a redo. */ - (BOOL)isRedoing { @@ -584,8 +584,8 @@ var _CPUndoGroupingParentKey = @"_CPUndoGroupingParentKey", /*! If the receiver can perform a redo, this method returns the action name previously associated with the top grouping with - -setActionName:. This name should identify the action to be redone. - @return the redo action's name, or nil if no there's no redo on the stack. + \c -setActionName:. This name should identify the action to be redone. + @return the redo action's name, or \c nil if no there's no redo on the stack. */ - (CPString)redoActionName { @@ -595,8 +595,8 @@ var _CPUndoGroupingParentKey = @"_CPUndoGroupingParentKey", /*! If the receiver can perform an undo, this method returns the action name previously associated with the top grouping with - -setActionName:. This name should identify the action to be undone. - @return the undo action name or nil if no if there's no undo on the stack. + \c -setActionName:. This name should identify the action to be undone. + @return the undo action name or \c nil if no if there's no undo on the stack. */ - (CPString)undoActionName { @@ -606,7 +606,7 @@ var _CPUndoGroupingParentKey = @"_CPUndoGroupingParentKey", // Working With Run Loops /*! Returns the CPRunLoopModes in which the receiver registers - the -endUndoGrouping processing when it -groupsByEvent. + the \c -endUndoGrouping processing when it \c -groupsByEvent. */ - (CPArray)runLoopModes { @@ -615,8 +615,8 @@ var _CPUndoGroupingParentKey = @"_CPUndoGroupingParentKey", /*! Sets the modes in which the receiver registers the calls - with the current run loop to invoke -endUndoGrouping - when it -groupsByEvent. This method first + with the current run loop to invoke \c -endUndoGrouping + when it \c -groupsByEvent. This method first cancels any pending registrations in the old modes and registers the invocation in the new modes. @param modes the modes in which calls are registered diff --git a/Objective-J/Rakefile b/Objective-J/Rakefile index f0f1782ac..f9e600684 100644 --- a/Objective-J/Rakefile +++ b/Objective-J/Rakefile @@ -17,18 +17,11 @@ $RHINO_FILE = File.join($PRODUCT, 'rhino.platform', 'Objective-J.js' task :Products => [$BROWSER_FILE, $RHINO_FILE, $LICENSE_PRODUCT] -Files = [ 'constants.js', - 'utilities.js', - 'json2.js', - 'runtime.js', - 'dictionary.js', - 'plist.js', - 'file.js', - 'exception.js', - 'preprocess.js', - 'evaluate.js', - 'debug.js', - 'bootstrap.js']; +Files = FileList['constants.js', 'utilities.js', 'json2.js', 'runtime.js', 'dictionary.js', 'plist.js', 'file.js', 'exception.js', 'preprocess.js', 'evaluate.js', 'bootstrap.js'] + +if $CONFIGURATION == 'Debug' + Files.add('debug.js') +end file_d $BROWSER_FILE => Files do |t| build_product(t.name, platform_flags(ObjectiveJ::Platform::Browser, ObjectiveJ::Platform::ObjJ)) @@ -43,7 +36,8 @@ end #Framework in environment directory file_d $ENVIRONMENT_PRODUCT => [:Products] do - cp_r(File.join($PRODUCT, '.'), $ENVIRONMENT_PRODUCT) + rm_rf $ENVIRONMENT_PRODUCT + cp_r($PRODUCT, $ENVIRONMENT_PRODUCT) end file_d $LICENSE_PRODUCT => [$LICENSE_FILE] do @@ -55,9 +49,7 @@ def platform_flags(*platforms) end def build_product(path, flags) - IO.popen("gcc #{flags} -E -x c -P -", "w+") do |preprocessor| - Files.select { |name| name.match(/\.js$/) }.each do |fileName| preprocessor.puts IO.read(fileName) end @@ -67,11 +59,11 @@ def build_product(path, flags) File.open(path, "w") do |file| file.write(IO.read("header.txt") + preprocessor.read) end - end + rake abort if ($? != 0) end -task :build => [:Products, $ENVIRONMENT_PRODUCT, :build_subprojects] +task :build => [:Products, :build_subprojects, $ENVIRONMENT_PRODUCT] task :clean => :clean_suprojects diff --git a/Objective-J/Tools/Rakefile b/Objective-J/Tools/Rakefile index d46729d01..99271dfc4 100644 --- a/Objective-J/Tools/Rakefile +++ b/Objective-J/Tools/Rakefile @@ -5,35 +5,18 @@ require 'objective-j' require 'rake' require 'rake/clean' -$ENVIRONMENT_NARWHAL_PRODUCT = File.join($ENVIRONMENT_DIR, 'narwhal') +$ENVIRONMENT_NARWHAL_PRODUCT = $ENVIRONMENT_DIR $ENVIRONMENT_OBJJ_PRODUCT = File.join($ENVIRONMENT_NARWHAL_PRODUCT, 'packages', 'objj') -$OBJJC_JS_COMPILER = File.join($ENVIRONMENT_LIB_DIR, 'shrinksafe.jar') -$OBJJC_JS_COMPILER_RHINO = File.join($ENVIRONMENT_LIB_DIR, 'js.jar') - $EXECUTABLES = ['objj', 'objjc', 'cplutil'] -$EXECUTABLES_PRODUCTS = $EXECUTABLES.map {|e| File.join($ENVIRONMENT_BIN_DIR, e) } -$EXECUTABLES.each do |executable| - source = File.join('objj', 'bin', executable) - dest = File.join($ENVIRONMENT_BIN_DIR, executable) - file_d dest => source do - #cp(source, dest) - FileUtils.ln_sf("../narwhal/packages/objj/bin/#{executable}", dest) +task :build do + rm_rf($ENVIRONMENT_OBJJ_PRODUCT) + cp_r('objj', $ENVIRONMENT_OBJJ_PRODUCT) + + $EXECUTABLES.each do |executable| + symlink_executable File.join($ENVIRONMENT_BIN_DIR, executable) end end -file_d $OBJJC_JS_COMPILER => 'shrinksafe.jar' do - cp('shrinksafe.jar', $OBJJC_JS_COMPILER) -end - -file_d $OBJJC_JS_COMPILER_RHINO => 'js.jar' do - cp('js.jar', $OBJJC_JS_COMPILER_RHINO) -end - -task :build => [$OBJJC_JS_COMPILER, $OBJJC_JS_COMPILER_RHINO].concat($EXECUTABLES_PRODUCTS) do - rm_rf($ENVIRONMENT_OBJJ_PRODUCT) - cp_r('objj', $ENVIRONMENT_OBJJ_PRODUCT) -end - -CLOBBER.include($ENVIRONMENT_OBJJ_PRODUCT, $EXECUTABLES_PRODUCTS, $OBJJC_JS_COMPILER, $OBJJC_JS_COMPILER_RHINO) +CLOBBER.include($ENVIRONMENT_OBJJ_PRODUCT) diff --git a/Objective-J/Tools/objj/bin/objj b/Objective-J/Tools/objj/bin/objj index 208bcce8b..3c52d2a54 100755 --- a/Objective-J/Tools/objj/bin/objj +++ b/Objective-J/Tools/objj/bin/objj @@ -1,3 +1,3 @@ #!/usr/bin/env narwhal -require("objj/objj"); +require("objj/objj").run(system.args); diff --git a/Objective-J/Tools/objj/bin/objjc b/Objective-J/Tools/objj/bin/objjc index 042076c57..d72c12ac6 100755 --- a/Objective-J/Tools/objj/bin/objjc +++ b/Objective-J/Tools/objj/bin/objjc @@ -1,15 +1,19 @@ #!/usr/bin/env narwhal -var objjc = require("objj/objjc"), +var objj = require("objj/objj"), File = require("file"); -with (objjc) +require("objj/regexp-rhino-patch"); + +with (objj) { importPackage(java.lang); importClass(java.io.BufferedReader); +var SHRINKSAFE_PATH = File.join(OBJJ_HOME, "shrinksafe", "shrinksafe.jar"), + RHINO_PATH = File.join(OBJJ_HOME, "shrinksafe", "js.jar") OBJJ_PREPROCESSOR_PREPROCESS = 1 << 10; OBJJ_PREPROCESSOR_COMPRESS = 1 << 11; @@ -53,7 +57,7 @@ function compress(/*String*/ aCode, /*Object*/ flags, /*File*/ tmpFile) { File.write(tmpFile, aCode, { charset:"UTF-8" }); - return exec(["java", "-Dfile.encoding=UTF-8", "-classpath", OBJJ_HOME + "/lib/js.jar" + ":" + OBJJ_HOME + "/lib/shrinksafe.jar", "org.dojotoolkit.shrinksafe.Main", tmpFile.getCanonicalPath()]); + return exec(["java", "-Dfile.encoding=UTF-8", "-classpath", [RHINO_PATH, SHRINKSAFE_PATH].join(":"), "org.dojotoolkit.shrinksafe.Main", tmpFile.getCanonicalPath()]); } //#define SET_CONTEXT(aFragment, aContext) aFragment.context = aContext diff --git a/Objective-J/Tools/objj/lib-js/objj/loader.js b/Objective-J/Tools/objj/lib-js/objj/loader.js new file mode 100644 index 000000000..2077a23fb --- /dev/null +++ b/Objective-J/Tools/objj/lib-js/objj/loader.js @@ -0,0 +1,23 @@ +var objj = null; + +function ObjectiveJLoader() { + var loader = {}; + var factories = {}; + + loader.reload = function(topId, path) { + if (!objj) objj = require("objj/objj"); + + //print("loading objective-j: " + topId + " (" + path + ")"); + factories[topId] = objj.make_narwhal_factory(system.fs.read(path)/*, topId, path*/); + } + + loader.load = function(topId, path) { + if (!factories.hasOwnProperty(topId)) + loader.reload(topId, path); + return factories[topId]; + } + + return loader; +}; + +require.loader.loaders.unshift([".j", ObjectiveJLoader()]); diff --git a/Objective-J/Tools/objj/lib-js/objj/objj.js b/Objective-J/Tools/objj/lib-js/objj/objj.js new file mode 100644 index 000000000..3d17a562a --- /dev/null +++ b/Objective-J/Tools/objj/lib-js/objj/objj.js @@ -0,0 +1,143 @@ +var File = require("file"); +var window = require("browser/window"); + +// variables to be exported from the module, for use in objjc, etc +var exported = [ + "objj_preprocess", + "FRAGMENT_FILE", "FRAGMENT_LOCAL", + "MARKER_CODE", "MARKER_IMPORT_STD", "MARKER_IMPORT_LOCAL", + "OBJJ_PREPROCESSOR_DEBUG_SYMBOLS" +]; + +// setup OBJJ_HOME, OBJJ_INCLUDE_PATHS, etc +var OBJJ_HOME = exports.OBJJ_HOME = File.resolve(module.path, "..", ".."), + frameworksPath = File.resolve(OBJJ_HOME, "lib/", "Frameworks/"), + objectivejPath = File.resolve(frameworksPath, "Objective-J/", "rhino.platform/", "Objective-J.js"); + +window.OBJJ_INCLUDE_PATHS = [frameworksPath]; +if (system.env["OBJJ_INCLUDE_PATHS"]) + window.OBJJ_INCLUDE_PATHS = system.env["OBJJ_INCLUDE_PATHS"].split(":").concat(window.OBJJ_INCLUDE_PATHS); + +// bring the "window" object into scope. +// TODO: somehow make window object the top scope? +with (window) +{ + // read and eval Objective-J.js with the module's scope + eval(File.read(objectivejPath, { charset:"UTF-8" })); + + // export desired variables. must eval variable name to obtain a reference + for (var i = 0; i < exported.length; i++) + exports[exported[i]] = eval(exported[i]); + +/* + objj_set_evaluator(function(code) { + return function(OBJJ_CURRENT_BUNDLE) { + with (window) { + return eval("function(OBJJ_CURRENT_BUNDLE){"+code+"}"); + } + } + }); +*/ + +// runs the objj repl or file provided in args +exports.run = function(args) +{ + args = args || []; + window.args = args; + + // FIXME: ARGS + args.shift(); + + if (args.length > 0) + { + while (args.length && args[0].indexOf('-I') === 0) + OBJJ_INCLUDE_PATHS = args.shift().substr(2).split(':').concat(OBJJ_INCLUDE_PATHS); + + var mainFilePath = File.canonical(args.shift()); + + objj_import(mainFilePath, YES, function() { + if (typeof main === "function") + main.apply(main, args); + }); + } + else + { + while (true) + { + try { + system.stdout.write("objj> ").flush(); + + var input = system.stdin.readLine(), + result = objj_eval(input); + + if (result !== undefined) + print(result); + + } catch (e) { + print(e); + } + + require("browser/timeout").serviceTimeouts(); + } + } + + require("browser/timeout").serviceTimeouts(); +} + +// synchronously evals Objective-J code +var objj_eval = exports.objj_eval = function(code) +{ + var result = eval(objj_preprocess_sync(code)); + + //require("browser/timeout").serviceTimeouts(); + + return result; +} + +// prepocesses Objective-J code into JavaScript, which will perform imports synchronously when eval'd +var objj_preprocess_sync = function(code) +{ + var fragments = objj_preprocess(code, new objj_bundle(), new objj_file(), OBJJ_PREPROCESSOR_DEBUG_SYMBOLS) + + var preprocessed = []; + + fragments.forEach(function(fragment) { + if (fragment.type & FRAGMENT_CODE) + preprocessed.push(fragment.info); + else if (fragment.type & FRAGMENT_LOCAL) + preprocessed.push("objj_import_sync('"+fragment.info+"',YES);"); + else + preprocessed.push("objj_import_sync('"+fragment.info+"',NO);"); + }); + + return preprocessed.join("\n"); +} + +// synchronously perform an import +var objj_import_sync = function(pathOrPaths, isLocal) +{ + var context = new objj_context(); + context.pushFragment(fragment_create_file(pathOrPaths, new objj_bundle(), isLocal, NULL)); + context.evaluate(); + + // HACK: need a real synchronous require + // FIXME: this is bad. not really synchronous. shouldn't have to call serviceTimeouts. + require("browser/timeout").serviceTimeouts(); +} + +// creates a narwhal factory function in the objj module scope +exports.make_narwhal_factory = function(code) { + // TODO: integrate better with objj load system so relative paths work + var OBJJ_CURRENT_BUNDLE = new objj_bundle(); + + return eval( + "(function(require,exports,module,system,print){" + + objj_preprocess_sync(code) + + "/**/\n})" + ); +} + +} // end "with" + +if (require.main == module.id) + exports.run(system.args); diff --git a/Objective-J/Tools/objj/lib/objj/regexp-rhino-patch.js b/Objective-J/Tools/objj/lib-js/objj/regexp-rhino-patch.js similarity index 100% rename from Objective-J/Tools/objj/lib/objj/regexp-rhino-patch.js rename to Objective-J/Tools/objj/lib-js/objj/regexp-rhino-patch.js diff --git a/Objective-J/Tools/objj/lib/objj/objj.js b/Objective-J/Tools/objj/lib/objj/objj.js deleted file mode 100644 index e17a54d9f..000000000 --- a/Objective-J/Tools/objj/lib/objj/objj.js +++ /dev/null @@ -1,78 +0,0 @@ -var File = require("file"); -var window = require("browser/window"); - -var OBJJ_HOME = system.prefix + "/.."; - -window.OBJJ_INCLUDE_PATHS = [OBJJ_HOME+"/lib/Frameworks/"]; -if (system.env["OBJJ_INCLUDE_PATHS"]) - window.OBJJ_INCLUDE_PATHS = system.env["OBJJ_INCLUDE_PATHS"].split(":").concat(window.OBJJ_INCLUDE_PATHS); - -//if (system.args.length > 0) -// window.OBJJ_MAIN_FILE = String((new Packages.java.io.File(args.shift())).getAbsolutePath()); - -window.args = system.args; - -// FIXME: ARGS -system.args.shift(); - -with (window) -{ - eval(File.read(OBJJ_HOME + "/lib/Frameworks/Objective-J/rhino.platform/Objective-J.js", { charset:"UTF-8" })); - - if (system.args.length > 0) - { - while (system.args.length && system.args[0].indexOf('-I') === 0) - OBJJ_INCLUDE_PATHS = system.args.shift().substr(2).split(':').concat(OBJJ_INCLUDE_PATHS); - - var mainFilePath = String((new Packages.java.io.File(args.shift())).getAbsolutePath()); - - objj_import(mainFilePath, YES, function() { - if (typeof main === "function") - main.apply(main, args); - }); - } - else - { - var br = new Packages.java.io.BufferedReader(new Packages.java.io.InputStreamReader(Packages.java.lang.System["in"], "UTF-8")); - - while (true) - { - try { - Packages.java.lang.System.out.print("objj> "); - - var input = String(br.readLine()), - fragments = objj_preprocess(input, new objj_bundle(), new objj_file(), OBJJ_PREPROCESSOR_DEBUG_SYMBOLS), - count = fragments.length, - ctx = (new objj_context); - - if (count == 1 && (fragments[0].type & FRAGMENT_CODE)) - { - var fragment = fragments[0]; - var result = eval(fragment.info); - if (result != undefined) - print(result); - } - else if (count > 0) - { - while (count--) - { - var fragment = fragments[count]; - - if (fragment.type & FRAGMENT_FILE) - objj_request_file(fragment.info, (fragment.type & FRAGMENT_LOCAL), NULL); - - ctx.pushFragment(fragment); - } - - ctx.schedule(); - } - - require("browser/timeout").serviceTimeouts(); - } catch (e) { - print(e); - } - } - } - - require("browser/timeout").serviceTimeouts(); -} diff --git a/Objective-J/Tools/objj/lib/objj/objjc.js b/Objective-J/Tools/objj/lib/objj/objjc.js deleted file mode 100644 index 9d9357f1c..000000000 --- a/Objective-J/Tools/objj/lib/objj/objjc.js +++ /dev/null @@ -1,19 +0,0 @@ -var File = require("file"); -var window = require("browser/window"); - -require("./regexp-rhino-patch"); - -var exported = ["OBJJ_HOME", "objj_preprocess", - "FRAGMENT_FILE", "FRAGMENT_LOCAL", - "MARKER_CODE", "MARKER_IMPORT_STD", "MARKER_IMPORT_LOCAL", - "OBJJ_PREPROCESSOR_DEBUG_SYMBOLS"]; - -var OBJJ_HOME = system.prefix + "/.."; - -with (window) -{ - eval(File.read(OBJJ_HOME + "/lib/Frameworks/Objective-J/rhino.platform/Objective-J.js", { charset:"UTF-8" }).toString()); - - for (var i = 0; i < exported.length; i++) - exports[exported[i]] = eval(exported[i]); -} diff --git a/Objective-J/Tools/objj/package.json b/Objective-J/Tools/objj/package.json index c4a5826f5..18e5956c7 100644 --- a/Objective-J/Tools/objj/package.json +++ b/Objective-J/Tools/objj/package.json @@ -1,6 +1,7 @@ { "author": "Tom Robinson", "dependencies": [], - "js": "lib", - "jars": "jars/" + "lib": "lib-js", + "jars": "jars/", + "plugins": ["objj/loader"] } diff --git a/Objective-J/Tools/objj/shrinksafe/js.jar b/Objective-J/Tools/objj/shrinksafe/js.jar new file mode 100644 index 000000000..c081d16b8 Binary files /dev/null and b/Objective-J/Tools/objj/shrinksafe/js.jar differ diff --git a/Objective-J/Tools/objj/shrinksafe/shrinksafe.jar b/Objective-J/Tools/objj/shrinksafe/shrinksafe.jar new file mode 100644 index 000000000..516fc7f5f Binary files /dev/null and b/Objective-J/Tools/objj/shrinksafe/shrinksafe.jar differ diff --git a/Objective-J/debug.js b/Objective-J/debug.js index cbc5fd447..2c7624464 100644 --- a/Objective-J/debug.js +++ b/Objective-J/debug.js @@ -1,173 +1,184 @@ -function objj_backtrace_format(aReceiver, aSelector) +// formatting helpers + +function objj_debug_object_format(aReceiver) { - return "[<" + GETMETA(aReceiver).name + " " + (typeof sprintf == "function" ? sprintf("%#08x", aReceiver.__address) : aReceiver.__address.toString(16)) + "> " + aSelector + "]"; + return (aReceiver && aReceiver.isa) ? sprintf("<%s %#08x>", GETMETA(aReceiver).name, aReceiver.__address) : String(aReceiver); } -function objj_msgSend_Backtrace(/*id*/ aReceiver, /*SEL*/ aSelector) +function objj_debug_message_format(aReceiver, aSelector) { - if (aReceiver == nil) - return nil; - - objj_debug_backtrace.push(objj_backtrace_format(aReceiver, aSelector)); - - try - { - var result = class_getMethodImplementation(aReceiver.isa, aSelector).apply(aReceiver, arguments); - } - catch (anException) - { - CPLog.error("Exception " + anException + " in " + objj_backtrace_format(aReceiver, aSelector)); - objj_debug_print_backtrace(); - } - - objj_debug_backtrace.pop(); - - return result; + return sprintf("[%s %s]", objj_debug_object_format(aReceiver), aSelector); } -function objj_msgSendSuper_Backtrace(/*id*/ aSuper, /*SEL*/ aSelector) + +// save the original msgSend implementations so we can restore them later +var objj_msgSend_original = objj_msgSend, + objj_msgSendSuper_original = objj_msgSendSuper; + + +// decorator management functions + +// reset to default objj_msgSend* implementations +function objj_msgSend_reset() { - objj_debug_backtrace.push(objj_backtrace_format(aSuper.receiver, aSelector)); - var super_class = aSuper.super_class; - - arguments[0] = aSuper.receiver; - - try - { - var result = class_getMethodImplementation(super_class, aSelector).apply(aSuper.receiver, arguments); - } - catch (anException) - { - CPLog.error("Exception " + anException + " in " + objj_backtrace_format(aSuper.receiver, aSelector)); - objj_debug_print_backtrace(); - } - - objj_debug_backtrace.pop(); - - return result; + objj_msgSend = objj_msgSend_original; + objj_msgSendSuper = objj_msgSendSuper_original; } -function objj_msgSend_Profile(/*id*/ aReceiver, /*SEL*/ aSelector) +// decorate both objj_msgSend and objj_msgSendSuper +function objj_msgSend_decorate() { - if (aReceiver == nil) - return nil; - - // profiling book keeping - var profileRecord = { - parent : objj_debug_profile, - receiver : GETMETA(aReceiver).name, - selector : aSelector, - calls : [] - } - objj_debug_profile.calls.push(profileRecord); - objj_debug_profile = profileRecord; - profileRecord.start = new Date(); - - var result = class_getMethodImplementation(aReceiver.isa, aSelector).apply(aReceiver, arguments); - - profileRecord.end = new Date(); - objj_debug_profile = profileRecord.parent; - - return result; -} - -function objj_msgSendSuper_Profile(/*id*/ aSuper, /*SEL*/ aSelector) -{ - // profiling book keeping - var profileRecord = { - parent : objj_debug_profile, - receiver : GETMETA(aReceiver).name, - selector : aSelector, - calls : [] - } - objj_debug_profile.calls.push(profileRecord); - objj_debug_profile = profileRecord; - profileRecord.start = new Date(); - - var super_class = aSuper.super_class; - - arguments[0] = aSuper.receiver; - - var result = class_getMethodImplementation(super_class, aSelector).apply(aSuper.receiver, arguments); - - profileRecord.end = new Date(); - objj_debug_profile = profileRecord.parent; - - return result; -} - -var objj_msgSend_Standard = objj_msgSend, - objj_msgSendSuper_Standard = objj_msgSendSuper; - -// FIXME: This could be much better. -var objj_debug_backtrace; - -function objj_backtrace_set_enabled(enabled) -{ - if (enabled) + for (var i = 0; i < arguments.length; i++) { - objj_debug_backtrace = []; - objj_msgSend = objj_msgSend_Backtrace; - objj_msgSendSuper = objj_msgSendSuper_Backtrace; + objj_msgSend = arguments[i](objj_msgSend); + objj_msgSendSuper = arguments[i](objj_msgSendSuper); + } +} + +// reset then decorate both objj_msgSend and objj_msgSendSuper +function objj_msgSend_set_decorators() +{ + objj_msgSend_reset(); + objj_msgSend_decorate.apply(null, arguments); +} + + +// backtrace decorator + +var objj_backtrace = []; + +function objj_backtrace_print(stream) { + for (var i = 0; i < objj_backtrace.length; i++) + objj_fprintf(stream, objj_debug_message_format(objj_backtrace[i].receiver, objj_backtrace[i].selector)); +} + +function objj_backtrace_decorator(msgSend) +{ + return function(aReceiverOrSuper, aSelector) + { + var aReceiver = aReceiverOrSuper && (aReceiverOrSuper.receiver || aReceiverOrSuper); + + // push the receiver and selector onto the backtrace stack + objj_backtrace.push({ receiver: aReceiver, selector : aSelector }); + try + { + return msgSend.apply(null, arguments); + } + catch (anException) + { + // print the exception and backtrace + objj_fprintf(warning_stream, "Exception " + anException + " in " + objj_debug_message_format(aReceiver, aSelector)); + objj_backtrace_print(warning_stream); + } + finally + { + // make sure to always pop + objj_backtrace.pop(); + } + } +} + +// type checking decorator + +var objj_typechecks_reported = {}, + objj_typecheck_prints_backtrace = false; + +function objj_typecheck_decorator(msgSend) +{ + return function(aReceiverOrSuper, aSelector) + { + var aReceiver = aReceiverOrSuper && (aReceiverOrSuper.receiver || aReceiverOrSuper); + + if (!aReceiver) + return msgSend.apply(null, arguments); + + var types = aReceiver.isa.method_dtable[aSelector].types; + for (var i = 2; i < arguments.length; i++) + { + try + { + objj_debug_typecheck(types[i-1], arguments[i]); + } + catch (e) + { + var key = [GETMETA(aReceiver).name, aSelector, i, e].join(";"); + if (!objj_typechecks_reported[key]) { + objj_typechecks_reported[key] = true; + objj_fprintf(warning_stream, "Type check failed on argument " + (i-2) + " of " + objj_debug_message_format(aReceiver, aSelector) + ": " + e); + if (objj_typecheck_prints_backtrace) + objj_backtrace_print(warning_stream); + } + } + } + + var result = msgSend.apply(null, arguments); + + try + { + objj_debug_typecheck(types[0], result); + } + catch (e) + { + var key = [GETMETA(aReceiver).name, aSelector, "ret", e].join(";"); + if (!objj_typechecks_reported[key]) { + objj_typechecks_reported[key] = true; + objj_fprintf(warning_stream, "Type check failed on return val of " + objj_debug_message_format(aReceiver, aSelector) + ": " + e); + if (objj_typecheck_prints_backtrace) + objj_backtrace_print(warning_stream); + } + } + + return result; + } +} + +// type checking logic: +function objj_debug_typecheck(expectedType, object) +{ + var objjClass; + + if (!expectedType) + { + return; + } + else if (expectedType === "id") + { + if (object !== undefined) + return; + } + else if (expectedType === "void") + { + if (object === undefined) + return; + } + else if (objjClass = objj_getClass(expectedType)) + { + if (object === nil) + { + return; + } + else if (object && object.isa) + { + var theClass = object.isa; + for (; theClass; theClass = theClass.super_class) + if (theClass === objjClass) + return; + } } else { - objj_msgSend = objj_msgSend_Standard; - objj_msgSendSuper = objj_msgSendSuper_Standard; - } -} - -function objj_debug_print_backtrace() -{ - alert(objj_debug_backtrace_string()); -} - -function objj_debug_backtrace_string() -{ - return objj_debug_backtrace ? objj_debug_backtrace.join("\n") : ""; -} - -var objj_debug_profile = null, - objj_currently_profiling = false, - objj_profile_cleanup; - -function objj_profile(title) -{ - if (objj_currently_profiling) return; - - var objj_msgSend_profile_saved = objj_msgSend, - objj_msgSendSuper_profile_saved = objj_msgSendSuper; - - objj_msgSend = objj_msgSend_Profile; - objj_msgSendSuper = objj_msgSendSuper_Profile; - - var root = { calls: [] }; - objj_debug_profile = root; - - var context = { - start : new Date(), - title : title, - profile : root - }; - - objj_profile_cleanup = function() { - objj_msgSend = objj_msgSend_profile_saved; - objj_msgSendSuper = objj_msgSendSuper_profile_saved; - context.end = new Date(); - return context; } - objj_currently_profiling = true; -} - -function objj_profileEnd() -{ - if (!objj_currently_profiling) - return; - - objj_debug_profile = null; - objj_currently_profiling = false; - - return objj_profile_cleanup(); + var actualType; + if (object === null) + actualType = "null"; + else if (object === undefined) + actualType = "void"; + else if (object.isa) + actualType = GETMETA(object).name; + else + actualType = typeof object; + + throw ("expected=" + expectedType + ", actual=" + actualType); } diff --git a/Objective-J/preprocess.js b/Objective-J/preprocess.js index 0032ed203..ad96215f9 100644 --- a/Objective-J/preprocess.js +++ b/Objective-J/preprocess.js @@ -20,7 +20,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -var OBJJ_PREPROCESSOR_DEBUG_SYMBOLS = 1 << 0; +var OBJJ_PREPROCESSOR_DEBUG_SYMBOLS = 1 << 0, + OBJJ_PREPROCESSOR_TYPE_SIGNATURES = 1 << 1; function objj_preprocess(/*String*/ aString, /*objj_bundle*/ aBundle, /*objj_file*/ aSourceFile, /*unsigned*/ flags) { @@ -170,6 +171,7 @@ var objj_preprocessor = function(aString, aSourceFile, aBundle, flags) { this._currentClass = ""; this._currentSuperClass = ""; + this._currentSuperMetaClass = ""; this._file = aSourceFile; this._fragments = []; @@ -177,6 +179,7 @@ var objj_preprocessor = function(aString, aSourceFile, aBundle, flags) this._tokens = new objj_lexer(aString); this._flags = flags; this._bundle = aBundle; + this._classMethod = false; this.preprocess(this._tokens, this._preprocessed); //alert(this._preprocessed + ""); @@ -262,8 +265,7 @@ objj_preprocessor.prototype.brackets = function(/*objj_lexer*/ tokens, /*objj_st if (tuples[0][0].atoms[0] == TOKEN_SUPER) { CONCAT(aStringBuffer, "objj_msgSendSuper("); - CONCAT(aStringBuffer, "{ receiver:self, super_class:" + this._currentSuperClass + " }"); - + CONCAT(aStringBuffer, "{ receiver:self, super_class:" + (this._classMethod ? this._currentSuperMetaClass : this._currentSuperClass ) + " }"); } else { @@ -350,7 +352,7 @@ objj_preprocessor.prototype.implementation = function(tokens, /*objj_stringBuffe category = NO, class_name = tokens.skip_whitespace(), superclass_name = "Nil", - + instance_methods = new objj_stringBuffer(), class_methods = new objj_stringBuffer(); @@ -358,6 +360,7 @@ objj_preprocessor.prototype.implementation = function(tokens, /*objj_stringBuffe objj_exception_throw(new objj_exception(OBJJParseException, "*** Expected class name, found \"" + class_name + "\".")); this._currentSuperClass = NULL; + this._currentSuperMetaClass = NULL; this._currentClass = class_name; // If we reach an open parenthesis, we are declaring a category. @@ -376,12 +379,18 @@ objj_preprocessor.prototype.implementation = function(tokens, /*objj_stringBuffe CONCAT(buffer, "var meta_class = the_class.isa;"); var superclass_name = dictionary_getValue(SUPER_CLASSES, class_name); - + // FIXME: We should have a better solution for this case, although it's actually not much slower than the real case. if (!superclass_name) + { this._currentSuperClass = "objj_getClass(\"" + class_name + "\").super_class"; + this._currentSuperMetaClass = "objj_getMetaClass(\"" + class_name + "\").super_class"; + } else + { this._currentSuperClass = "objj_getClass(\"" + superclass_name + "\")"; + this._currentSuperMetaClass = "objj_getMeraClass(\"" + superclass_name + "\")"; + } } else { @@ -394,7 +403,9 @@ objj_preprocessor.prototype.implementation = function(tokens, /*objj_stringBuffe objj_exception_throw(new objj_exception(OBJJParseException, "*** Expected class name, found \"" + token + "\".")); superclass_name = token; + this._currentSuperClass = "objj_getClass(\"" + superclass_name + "\")"; + this._currentSuperMetaClass = "objj_getMetaClass(\"" + superclass_name + "\")"; dictionary_setValue(SUPER_CLASSES, class_name, superclass_name); @@ -503,6 +514,8 @@ objj_preprocessor.prototype.implementation = function(tokens, /*objj_stringBuffe { if (token == TOKEN_PLUS) { + this._classMethod = true; + if (IS_NOT_EMPTY(class_methods)) CONCAT(class_methods, ", "); @@ -511,6 +524,8 @@ objj_preprocessor.prototype.implementation = function(tokens, /*objj_stringBuffe else if (token == TOKEN_MINUS) { + this._classMethod = false; + if (IS_NOT_EMPTY(instance_methods)) CONCAT(instance_methods, ", "); @@ -578,12 +593,15 @@ objj_preprocessor.prototype.method = function(tokens) var buffer = new objj_stringBuffer(), token, selector = "", - parameters = []; + parameters = [], + types = [null]; while((token = tokens.skip_whitespace()) && token != TOKEN_OPEN_BRACE) { if (token == TOKEN_COLON) { + var type = ""; + // Colons are part of the selector name selector += token; @@ -592,18 +610,30 @@ objj_preprocessor.prototype.method = function(tokens) if (token == TOKEN_OPEN_PARENTHESIS) { // Swallow parameter/return type. Perhaps later we can use this for debugging? - while((token = tokens.skip_whitespace()) && token != TOKEN_CLOSE_PARENTHESIS) ; + while((token = tokens.skip_whitespace()) && token != TOKEN_CLOSE_PARENTHESIS) + type += token; token = tokens.skip_whitespace(); } + // Add the type. If it's empty, add null instead. + types[parameters.length+1] = type || null; + // Since this follows a colon, this must be the parameter name. parameters[parameters.length] = token; } else if (token == TOKEN_OPEN_PARENTHESIS) + { + var type = ""; + // Since :( is handled above, this must be the return type, just swallow it. - while((token = tokens.skip_whitespace()) && token != TOKEN_CLOSE_PARENTHESIS) ; + while((token = tokens.skip_whitespace()) && token != TOKEN_CLOSE_PARENTHESIS) + type += token; + + // types[0] is the return argument + types[0] = type || null; + } // Argument list ", ..." else if (token == TOKEN_COMMA) @@ -640,7 +670,11 @@ objj_preprocessor.prototype.method = function(tokens) CONCAT(buffer, ")\n{ with(self)\n{"); CONCAT(buffer, this.preprocess(tokens, NULL, TOKEN_CLOSE_BRACE, TOKEN_OPEN_BRACE)); - CONCAT(buffer, "}\n})"); + CONCAT(buffer, "}\n}"); + // TODO: actually use OBJJ_PREPROCESSOR_TYPE_SIGNATURES flag instead of tying to OBJJ_PREPROCESSOR_DEBUG_SYMBOLS + if (this._flags & OBJJ_PREPROCESSOR_DEBUG_SYMBOLS) //OBJJ_PREPROCESSOR_TYPE_SIGNATURES) + CONCAT(buffer, ","+JSON.stringify(types)); + CONCAT(buffer, ")"); return buffer; } diff --git a/Rakefile b/Rakefile index 4f0a3da62..427f7c560 100644 --- a/Rakefile +++ b/Rakefile @@ -37,8 +37,8 @@ task :downloads => [:starter_download, :tools_download] file_d $TOOLS_DOWNLOAD_ENV => [:debug, :release] do rm_rf($TOOLS_DOWNLOAD_ENV) - cp_r(File.join($RELEASE_ENV, '.'), $TOOLS_DOWNLOAD_ENV) - cp_r(File.join($DEBUG_ENV, 'lib', 'Frameworks', '.'), File.join($TOOLS_DOWNLOAD_ENV, 'lib', 'Frameworks', 'Debug')) + cp_r(File.join($RELEASE_ENV), $TOOLS_DOWNLOAD_ENV) + cp_r(File.join($DEBUG_ENV, 'packages', 'objj', 'lib', 'Frameworks'), File.join($TOOLS_DOWNLOAD_ENV, 'packages', 'objj', 'lib', 'Frameworks', 'Debug')) end file_d $TOOLS_DOWNLOAD_EDITORS => [$TOOLS_EDITORS] do @@ -86,7 +86,9 @@ file_d $STARTER_DOWNLOAD_APPLICATION => [$TOOLS_DOWNLOAD_ENV] do rm_rf($STARTER_DOWNLOAD_APPLICATION) mkdir_p($STARTER_DOWNLOAD) + system %{capp gen #{$STARTER_DOWNLOAD_APPLICATION} -t Application --noconfig } + rake abort if ($? != 0) # No tools means no objective-j gem rm(File.join($STARTER_DOWNLOAD_APPLICATION, 'Rakefile')) @@ -103,7 +105,9 @@ task :install => [:tools_download] do else prefix = '' end + system %{cd #{$TOOLS_DOWNLOAD} && sudo sh ./install-tools #{prefix} } + rake abort if ($? != 0) end task :test => [:build] do @@ -122,6 +126,8 @@ end task :docs do if executable_exists? "doxygen" system %{doxygen #{$DOXYGEN_CONFIG} } + rake abort if ($? != 0) + rm_rf $DOCUMENTATION_BUILD mv "debug.txt", "Documentation" mv "Documentation", $DOCUMENTATION_BUILD @@ -133,6 +139,7 @@ end task :submodules do if executable_exists? "git" system %{git submodule init && git submodule update} + rake abort if ($? != 0) else puts "Git not installed" rake abort diff --git a/Tests/AppKit/CPSegmentedControlTest.j b/Tests/AppKit/CPSegmentedControlTest.j new file mode 100644 index 000000000..ffd794113 --- /dev/null +++ b/Tests/AppKit/CPSegmentedControlTest.j @@ -0,0 +1,33 @@ +@import + +// TODO: Maybe create one test file for each tracking mode so they can be tested separately without confusion. +@implementation CPSegmentedControlTest : OJTestCase +{ + CPSegmentedControlTest _segmentedControl; +} + +- (void)setUp +{ + _segmentedControl = [[CPSegmentedControl alloc] initWithFrame:CGRectMakeZero()]; + [_segmentedControl setSegmentCount:3]; +} + +- (void)testMakeCPSegmentedControlInstance +{ + [self assertNotNull:_segmentedControl]; +} + +- (void)testDefaultsToSelectOneTrackingMode +{ + [self assert:[_segmentedControl trackingMode] equals:CPSegmentSwitchTrackingSelectOne]; +} + +- (void)testSelectsOneSegmentStartingAtBlankState +{ + [self assert:[_segmentedControl selectedSegment] equals:-1]; + [_segmentedControl setSelectedSegment:1]; + [self assert:[_segmentedControl selectedSegment] equals:1]; +} + +@end + diff --git a/Tools/Install/install-tools b/Tools/Install/install-tools index 72834f843..d4f8f0cd9 100755 --- a/Tools/Install/install-tools +++ b/Tools/Install/install-tools @@ -23,18 +23,19 @@ while [ $# -ge 1 ]; do done mkdir -p $INSTALL_DIR/bin -mkdir -p $INSTALL_DIR/share/objj +mkdir -p $INSTALL_DIR/share -cp -fR objj/* $INSTALL_DIR/share/objj/. +rm -rf $INSTALL_DIR/share/narwhal +cp -fR objj $INSTALL_DIR/share/narwhal BINS=`ls objj/bin` for BIN in $BINS do - ln -sf $INSTALL_DIR/share/objj/bin/$BIN $INSTALL_DIR/bin/$BIN + ln -sf $INSTALL_DIR/share/narwhal/bin/$BIN $INSTALL_DIR/bin/$BIN chmod +x $INSTALL_DIR/bin/$BIN done -chmod +x $INSTALL_DIR/share/objj/bin/* +chmod +x $INSTALL_DIR/share/narwhal/bin/* gem install *.gem gem cleanup objective-j diff --git a/Tools/Rake/lib/objective-j/bundletask.rb b/Tools/Rake/lib/objective-j/bundletask.rb index eeee33003..95b77e138 100644 --- a/Tools/Rake/lib/objective-j/bundletask.rb +++ b/Tools/Rake/lib/objective-j/bundletask.rb @@ -390,6 +390,7 @@ module ObjectiveJ puts str end end + #rake abort if ($? != 0) end { 'copy' => include_nibs, 'copied_resources' => [copied_resource] } @@ -424,6 +425,7 @@ module ObjectiveJ puts str end end + rake abort if ($? != 0) end enhance([frameworks_path]) @@ -510,6 +512,7 @@ module ObjectiveJ puts str end end + rake abort if ($? != 0) end BundleTask.compact(build_path) if needs_compact diff --git a/Tools/Rake/lib/objj-executable b/Tools/Rake/lib/objj-executable index ed565c985..d2b89f60f 100755 --- a/Tools/Rake/lib/objj-executable +++ b/Tools/Rake/lib/objj-executable @@ -1,12 +1,14 @@ #!/bin/bash -# get path of the executable +# get the absolute path of the executable SELF_PATH=$(cd -P -- "$(dirname -- "$0")" && pwd -P) && SELF_PATH=$SELF_PATH/$(basename -- "$0") # resolve symlinks -if [ -h $SELF_PATH ]; then - SELF_PATH=`readlink $SELF_PATH` -fi +while [ -h "$SELF_PATH" ]; do + DIR=$(dirname -- "$SELF_PATH") + SYM=$(readlink -- "$SELF_PATH") + SELF_PATH=$(cd -- "$DIR" && cd -- $(dirname -- "$SYM") && pwd)/$(basename -- "$SYM") +done SELF_DIR=`dirname $SELF_PATH` SELF_HOME=`dirname $SELF_DIR` diff --git a/Tools/capp/Templates/Application/index-debug.html b/Tools/capp/Templates/Application/index-debug.html index 5ebc00c9a..54b8f7fbe 100644 --- a/Tools/capp/Templates/Application/index-debug.html +++ b/Tools/capp/Templates/Application/index-debug.html @@ -21,7 +21,22 @@ - + + +