00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 @import <Foundation/CPObject.j>
00111 @import <Foundation/CPRunLoop.j>
00112
00113 @import "CPEvent.j"
00114 @import "CPCompatibility.j"
00115
00116 @import "CPDOMWindowLayer.j"
00117
00118 @import "CPPlatform.j"
00119 @import "CPPlatformWindow.j"
00120 @import "CPPlatformWindow+DOMKeys.j"
00121
00122 #import "../../CoreGraphics/CGGeometry.h"
00123
00124
00125 var PlatformWindows = [CPSet set];
00126
00127
00128 var CPDOMEventGetClickCount,
00129 CPDOMEventStop,
00130 StopDOMEventPropagation;
00131
00132
00133
00134
00135 var KeyCodesToPrevent = {},
00136 CharacterKeysToPrevent = {},
00137 MozKeyCodeToKeyCodeMap = {
00138 61: 187,
00139 59: 186
00140 };
00141
00142 KeyCodesToPrevent[CPKeyCodes.A] = YES;
00143
00144 var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
00145
00146 @implementation CPPlatformWindow (DOM)
00147
00148 - (id)_init
00149 {
00150 self = [super init];
00151
00152 if (self)
00153 {
00154 _DOMWindow = window;
00155 _contentRect = _CGRectMakeZero();
00156
00157 _windowLevels = [];
00158 _windowLayers = [CPDictionary dictionary];
00159
00160 [self registerDOMWindow];
00161 [self updateFromNativeContentRect];
00162
00163 _charCodes = {};
00164 }
00165
00166 return self;
00167 }
00168
00169 - (CGRect)nativeContentRect
00170 {
00171 if (!_DOMWindow)
00172 return [self contentRect];
00173
00174 if (_DOMWindow.cpFrame)
00175 return _DOMWindow.cpFrame();
00176
00177 var contentRect = _CGRectMakeZero();
00178
00179 if (window.screenTop)
00180 contentRect.origin = _CGPointMake(_DOMWindow.screenLeft, _DOMWindow.screenTop);
00181
00182 else if (window.screenX)
00183 contentRect.origin = _CGPointMake(_DOMWindow.screenX, _DOMWindow.screenY);
00184
00185
00186 if (_DOMWindow.innerWidth)
00187 contentRect.size = _CGSizeMake(_DOMWindow.innerWidth, _DOMWindow.innerHeight);
00188
00189
00190 else if (document.documentElement && document.documentElement.clientWidth)
00191 contentRect.size = _CGSizeMake(_DOMWindow.document.documentElement.clientWidth, _DOMWindow.document.documentElement.clientHeight);
00192
00193
00194 else
00195 contentRect.size = _CGSizeMake(_DOMWindow.document.body.clientWidth, _DOMWindow.document.body.clientHeight);
00196
00197 return contentRect;
00198 }
00199
00200 - (void)updateNativeContentRect
00201 {
00202 if (!_DOMWindow)
00203 return;
00204
00205 if (typeof _DOMWindow["cpSetFrame"] === "function")
00206 return _DOMWindow.cpSetFrame([self contentRect]);
00207
00208 var origin = [self contentRect].origin,
00209 nativeOrigin = [self nativeContentRect].origin;
00210
00211 if (origin.x !== nativeOrigin.x || origin.y !== nativeOrigin.y)
00212 {
00213 _DOMWindow.moveBy(origin.x - nativeOrigin.x, origin.y - nativeOrigin.y);
00214 }
00215
00216 var size = [self contentRect].size,
00217 nativeSize = [self nativeContentRect].size;
00218
00219 if (size.width !== nativeSize.width || size.height !== nativeSize.height)
00220 {
00221 _DOMWindow.resizeBy(size.width - nativeSize.width, size.height - nativeSize.height);
00222 }
00223 }
00224
00225 - (void)orderBack:(id)aSender
00226 {
00227 if (_DOMWindow)
00228 _DOMWindow.blur();
00229 }
00230
00231 - (void)createDOMElements
00232 {
00233 var theDocument = _DOMWindow.document;
00234
00235
00236 _DOMFocusElement = theDocument.createElement("input");
00237
00238 _DOMFocusElement.style.position = "absolute";
00239 _DOMFocusElement.style.zIndex = "-1000";
00240 _DOMFocusElement.style.opacity = "0";
00241 _DOMFocusElement.style.filter = "alpha(opacity=0)";
00242 _DOMFocusElement.className = "cpdontremove";
00243
00244 _DOMBodyElement.appendChild(_DOMFocusElement);
00245
00246
00247 _DOMPasteboardElement = theDocument.createElement("textarea");
00248
00249 _DOMPasteboardElement.style.position = "absolute";
00250 _DOMPasteboardElement.style.top = "-10000px";
00251 _DOMPasteboardElement.style.zIndex = "999";
00252 _DOMPasteboardElement.className = "cpdontremove";
00253
00254 _DOMBodyElement.appendChild(_DOMPasteboardElement);
00255
00256
00257 _DOMPasteboardElement.blur();
00258 }
00259
00260 - (void)registerDOMWindow
00261 {
00262 var theDocument = _DOMWindow.document;
00263
00264 _DOMBodyElement = theDocument.getElementById("cappuccino-body") || theDocument.body;
00265
00266
00267 if ([CPPlatform supportsDragAndDrop])
00268 _DOMBodyElement.style["-khtml-user-select"] = "none";
00269
00270 _DOMBodyElement.webkitTouchCallout = "none";
00271
00272 [self createDOMElements];
00273 [self _addLayers];
00274
00275 var theClass = [self class],
00276
00277 dragEventImplementation = class_getMethodImplementation(theClass, @selector(dragEvent:)),
00278 dragEventCallback = function (anEvent) { dragEventImplementation(self, nil, anEvent); },
00279
00280 resizeEventSelector = @selector(resizeEvent:),
00281 resizeEventImplementation = class_getMethodImplementation(theClass, resizeEventSelector),
00282 resizeEventCallback = function (anEvent) { resizeEventImplementation(self, nil, anEvent); },
00283
00284 copyEventSelector = @selector(copyEvent:),
00285 copyEventImplementation = class_getMethodImplementation(theClass, copyEventSelector),
00286 copyEventCallback = function (anEvent) {copyEventImplementation(self, nil, anEvent); },
00287
00288 pasteEventSelector = @selector(pasteEvent:),
00289 pasteEventImplementation = class_getMethodImplementation(theClass, pasteEventSelector),
00290 pasteEventCallback = function (anEvent) {pasteEventImplementation(self, nil, anEvent); },
00291
00292 keyEventSelector = @selector(keyEvent:),
00293 keyEventImplementation = class_getMethodImplementation(theClass, keyEventSelector),
00294 keyEventCallback = function (anEvent) { keyEventImplementation(self, nil, anEvent); },
00295
00296 mouseEventSelector = @selector(mouseEvent:),
00297 mouseEventImplementation = class_getMethodImplementation(theClass, mouseEventSelector),
00298 mouseEventCallback = function (anEvent) { mouseEventImplementation(self, nil, anEvent); },
00299
00300 scrollEventSelector = @selector(scrollEvent:),
00301 scrollEventImplementation = class_getMethodImplementation(theClass, scrollEventSelector),
00302 scrollEventCallback = function (anEvent) { scrollEventImplementation(self, nil, anEvent); },
00303
00304 touchEventSelector = @selector(touchEvent:),
00305 touchEventImplementation = class_getMethodImplementation(theClass, touchEventSelector),
00306 touchEventCallback = function (anEvent) { touchEventImplementation(self, nil, anEvent); };
00307
00308 if (theDocument.addEventListener)
00309 {
00310 if ([CPPlatform supportsDragAndDrop])
00311 {
00312 theDocument.addEventListener("dragstart", dragEventCallback, NO);
00313 theDocument.addEventListener("drag", dragEventCallback, NO);
00314 theDocument.addEventListener("dragend", dragEventCallback, NO);
00315 theDocument.addEventListener("dragover", dragEventCallback, NO);
00316 theDocument.addEventListener("dragleave", dragEventCallback, NO);
00317 theDocument.addEventListener("drop", dragEventCallback, NO);
00318 }
00319
00320 theDocument.addEventListener("mouseup", mouseEventCallback, NO);
00321 theDocument.addEventListener("mousedown", mouseEventCallback, NO);
00322 theDocument.addEventListener("mousemove", mouseEventCallback, NO);
00323
00324 theDocument.addEventListener("beforecopy", copyEventCallback, NO);
00325 theDocument.addEventListener("beforecut", copyEventCallback, NO);
00326 theDocument.addEventListener("beforepaste", pasteEventCallback, NO);
00327
00328 theDocument.addEventListener("keyup", keyEventCallback, NO);
00329 theDocument.addEventListener("keydown", keyEventCallback, NO);
00330 theDocument.addEventListener("keypress", keyEventCallback, NO);
00331
00332 theDocument.addEventListener("touchstart", touchEventCallback, NO);
00333 theDocument.addEventListener("touchend", touchEventCallback, NO);
00334 theDocument.addEventListener("touchmove", touchEventCallback, NO);
00335 theDocument.addEventListener("touchcancel", touchEventCallback, NO);
00336
00337 _DOMWindow.addEventListener("DOMMouseScroll", scrollEventCallback, NO);
00338 _DOMWindow.addEventListener("mousewheel", scrollEventCallback, NO);
00339
00340 _DOMWindow.addEventListener("resize", resizeEventCallback, NO);
00341
00342 _DOMWindow.addEventListener("unload", function()
00343 {
00344 [self updateFromNativeContentRect];
00345 [self _removeLayers];
00346
00347 theDocument.removeEventListener("mouseup", mouseEventCallback, NO);
00348 theDocument.removeEventListener("mousedown", mouseEventCallback, NO);
00349 theDocument.removeEventListener("mousemove", mouseEventCallback, NO);
00350
00351 theDocument.removeEventListener("keyup", keyEventCallback, NO);
00352 theDocument.removeEventListener("keydown", keyEventCallback, NO);
00353 theDocument.removeEventListener("keypress", keyEventCallback, NO);
00354
00355 theDocument.removeEventListener("beforecopy", copyEventCallback, NO);
00356 theDocument.removeEventListener("beforecut", copyEventCallback, NO);
00357 theDocument.removeEventListener("beforepaste", pasteEventCallback, NO);
00358
00359 theDocument.removeEventListener("touchstart", touchEventCallback, NO);
00360 theDocument.removeEventListener("touchend", touchEventCallback, NO);
00361 theDocument.removeEventListener("touchmove", touchEventCallback, NO);
00362
00363 _DOMWindow.removeEventListener("resize", resizeEventCallback, NO);
00364
00365
00366 _DOMWindow.removeEventListener("DOMMouseScroll", scrollEventCallback, NO);
00367 _DOMWindow.removeEventListener("mousewheel", scrollEventCallback, NO);
00368
00369
00370
00371 [PlatformWindows removeObject:self];
00372
00373 self._DOMWindow = nil;
00374 }, NO);
00375 }
00376 else
00377 {
00378 theDocument.attachEvent("onmouseup", mouseEventCallback);
00379 theDocument.attachEvent("onmousedown", mouseEventCallback);
00380 theDocument.attachEvent("onmousemove", mouseEventCallback);
00381 theDocument.attachEvent("ondblclick", mouseEventCallback);
00382
00383 theDocument.attachEvent("onkeyup", keyEventCallback);
00384 theDocument.attachEvent("onkeydown", keyEventCallback);
00385 theDocument.attachEvent("onkeypress", keyEventCallback);
00386
00387 _DOMWindow.attachEvent("onresize", resizeEventCallback);
00388
00389 _DOMWindow.onmousewheel = scrollEventCallback;
00390 theDocument.onmousewheel = scrollEventCallback;
00391
00392 _DOMBodyElement.ondrag = function () { return NO; };
00393 _DOMBodyElement.onselectstart = function () { return _DOMWindow.event.srcElement === _DOMPasteboardElement; };
00394
00395 _DOMWindow.attachEvent("onbeforeunload", function()
00396 {
00397 [self updateFromNativeContentRect];
00398 [self _removeLayers];
00399
00400 theDocument.detachEvent("onmouseup", mouseEventCallback);
00401 theDocument.detachEvent("onmousedown", mouseEventCallback);
00402 theDocument.detachEvent("onmousemove", mouseEventCallback);
00403 theDocument.detachEvent("ondblclick", mouseEventCallback);
00404
00405 theDocument.detachEvent("onkeyup", keyEventCallback);
00406 theDocument.detachEvent("onkeydown", keyEventCallback);
00407 theDocument.detachEvent("onkeypress", keyEventCallback);
00408
00409 _DOMWindow.detachEvent("onresize", resizeEventCallback);
00410
00411 _DOMWindow.onmousewheel = NULL;
00412 theDocument.onmousewheel = NULL;
00413
00414 _DOMBodyElement.ondrag = NULL;
00415 _DOMBodyElement.onselectstart = NULL;
00416
00417
00418
00419 [PlatformWindows removeObject:self];
00420
00421 self._DOMWindow = nil;
00422 }, NO);
00423 }
00424 }
00425
00426 + (CPSet)visiblePlatformWindows
00427 {
00428 if ([[CPPlatformWindow primaryPlatformWindow] isVisible])
00429 {
00430 var set = [CPSet setWithSet:PlatformWindows];
00431 [set addObject:[CPPlatformWindow primaryPlatformWindow]];
00432 return set;
00433 }
00434 else
00435 return PlatformWindows;
00436 }
00437
00438 - (void)orderFront:(id)aSender
00439 {
00440 if (_DOMWindow)
00441 return _DOMWindow.focus();
00442
00443 _DOMWindow = window.open("", "_blank", "menubar=no,location=no,resizable=yes,scrollbars=no,status=no,left=" + _CGRectGetMinX(_contentRect) + ",top=" + _CGRectGetMinY(_contentRect) + ",width=" + _CGRectGetWidth(_contentRect) + ",height=" + _CGRectGetHeight(_contentRect));
00444
00445 [PlatformWindows addObject:self];
00446
00447
00448 _DOMWindow.document.write("<html><head></head><body style = 'background-color:transparent;'></body></html>");
00449 _DOMWindow.document.close();
00450
00451 if (![CPPlatform isBrowser])
00452 {
00453 _DOMWindow.cpWindowNumber = [self._only windowNumber];
00454 _DOMWindow.cpSetFrame(_contentRect);
00455 _DOMWindow.cpSetLevel(_level);
00456 _DOMWindow.cpSetHasShadow(_hasShadow);
00457 _DOMWindow.cpSetShadowStyle(_shadowStyle);
00458 }
00459
00460 [self registerDOMWindow];
00461
00462 _DOMBodyElement.style.cursor = [[CPCursor currentCursor] _cssString];
00463 }
00464
00465 - (void)orderOut:(id)aSender
00466 {
00467 if (!_DOMWindow)
00468 return;
00469
00470 _DOMWindow.close();
00471 }
00472
00473 - (void)dragEvent:(DOMEvent)aDOMEvent
00474 {
00475 var type = aDOMEvent.type,
00476 dragServer = [CPDragServer sharedDragServer],
00477 location = _CGPointMake(aDOMEvent.clientX, aDOMEvent.clientY),
00478 pasteboard = [_CPDOMDataTransferPasteboard DOMDataTransferPasteboard];
00479
00480 [pasteboard _setDataTransfer:aDOMEvent.dataTransfer];
00481
00482 if (aDOMEvent.type === "dragstart")
00483 {
00484 [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
00485
00486 [pasteboard _setPasteboard:[dragServer draggingPasteboard]];
00487
00488 var draggedWindow = [dragServer draggedWindow],
00489 draggedWindowFrame = [draggedWindow frame],
00490 DOMDragElement = draggedWindow._DOMElement;
00491
00492 DOMDragElement.style.left = -_CGRectGetWidth(draggedWindowFrame) + "px";
00493 DOMDragElement.style.top = -_CGRectGetHeight(draggedWindowFrame) + "px";
00494
00495 _DOMBodyElement.appendChild(DOMDragElement);
00496
00497 var draggingOffset = [dragServer draggingOffset];
00498
00499 aDOMEvent.dataTransfer.setDragImage(DOMDragElement, draggingOffset.width, draggingOffset.height);
00500 aDOMEvent.dataTransfer.effectAllowed = "all";
00501
00502 [dragServer draggingStartedInPlatformWindow:self globalLocation:[CPPlatform isBrowser] ? location : _CGPointMake(aDOMEvent.screenX, aDOMEvent.screenY)];
00503 }
00504
00505 else if (type === "drag")
00506 {
00507 var y = aDOMEvent.screenY;
00508
00509 if (CPFeatureIsCompatible(CPHTML5DragAndDropSourceYOffBy1))
00510 y -= 1;
00511
00512 [dragServer draggingSourceUpdatedWithGlobalLocation:[CPPlatform isBrowser] ? location : _CGPointMake(aDOMEvent.screenX, y)];
00513 }
00514
00515 else if (type === "dragover" || type === "dragleave")
00516 {
00517 if (aDOMEvent.preventDefault)
00518 aDOMEvent.preventDefault();
00519
00520 var dropEffect = "none",
00521 dragOperation = [dragServer draggingUpdatedInPlatformWindow:self location:location];
00522
00523 if (dragOperation === CPDragOperationMove || dragOperation === CPDragOperationGeneric || dragOperation === CPDragOperationPrivate)
00524 dropEffect = "move";
00525
00526 else if (dragOperation === CPDragOperationCopy)
00527 dropEffect = "copy";
00528
00529 else if (dragOperation === CPDragOperationLink)
00530 dropEffect = "link";
00531
00532 aDOMEvent.dataTransfer.dropEffect = dropEffect;
00533 }
00534
00535 else if (type === "dragend")
00536 {
00537 var dropEffect = aDOMEvent.dataTransfer.dropEffect;
00538
00539 if (dropEffect === "move")
00540 dragOperation = CPDragOperationMove;
00541 else if (dropEffect === "copy")
00542 dragOperation = CPDragOperationCopy;
00543 else if (dropEffect === "link")
00544 dragOperation = CPDragOperationLink;
00545 else
00546 dragOperation = CPDragOperationNone;
00547
00548 [dragServer draggingEndedInPlatformWindow:self globalLocation:[CPPlatform isBrowser] ? location : _CGPointMake(aDOMEvent.screenX, aDOMEvent.screenY) operation:dragOperation];
00549 }
00550
00551 else
00552 {
00553 [dragServer performDragOperationInPlatformWindow:self];
00554
00555
00556 if (aDOMEvent.preventDefault)
00557 aDOMEvent.preventDefault();
00558
00559 if (aDOMEvent.stopPropagation)
00560 aDOMEvent.stopPropagation();
00561 }
00562
00563 [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
00564 }
00565
00566 - (void)keyEvent:(DOMEvent)aDOMEvent
00567 {
00568 var event,
00569 timestamp = aDOMEvent.timeStamp ? aDOMEvent.timeStamp : new Date(),
00570 sourceElement = (aDOMEvent.target || aDOMEvent.srcElement),
00571 windowNumber = [[CPApp keyWindow] windowNumber],
00572 modifierFlags = (aDOMEvent.shiftKey ? CPShiftKeyMask : 0) |
00573 (aDOMEvent.ctrlKey ? CPControlKeyMask : 0) |
00574 (aDOMEvent.altKey ? CPAlternateKeyMask : 0) |
00575 (aDOMEvent.metaKey ? CPCommandKeyMask : 0);
00576
00577
00578 StopDOMEventPropagation = !!(!(modifierFlags & (CPControlKeyMask | CPCommandKeyMask)) ||
00579 CharacterKeysToPrevent[String.fromCharCode(aDOMEvent.keyCode || aDOMEvent.charCode).toLowerCase()] ||
00580 KeyCodesToPrevent[aDOMEvent.keyCode]);
00581
00582 var isNativePasteEvent = NO,
00583 isNativeCopyOrCutEvent = NO,
00584 overrideCharacters = nil;
00585
00586 switch (aDOMEvent.type)
00587 {
00588 case "keydown":
00589 if (aDOMEvent.keyCode.keyCode in MozKeyCodeToKeyCodeMap)
00590 _keyCode = MozKeyCodeToKeyCodeMap[aDOMEvent.keyCode];
00591 else
00592 _keyCode = aDOMEvent.keyCode;
00593
00594 var characters = String.fromCharCode(_keyCode).toLowerCase();
00595 overrideCharacters = (modifierFlags & CPShiftKeyMask || _capsLockActive) ? characters.toUpperCase() : characters;
00596
00597
00598 if (_keyCode === CPKeyCodes.CAPS_LOCK)
00599 _capsLockActive = YES;
00600
00601 if (modifierFlags & (CPControlKeyMask | CPCommandKeyMask))
00602 {
00603
00604
00605
00606
00607 var eligibleForCopyPaste = [self _validateCopyCutOrPasteEvent:aDOMEvent flags:modifierFlags];
00608
00609
00610
00611 if (characters === "v" && eligibleForCopyPaste)
00612 {
00613 if (!_ignoreNativePastePreparation)
00614 {
00615 _DOMPasteboardElement.select();
00616 _DOMPasteboardElement.value = "";
00617 }
00618
00619 isNativePasteEvent = YES;
00620 }
00621
00622
00623
00624 else if ((characters == "c" || characters == "x") && eligibleForCopyPaste)
00625 {
00626 isNativeCopyOrCutEvent = YES;
00627
00628 if (_ignoreNativeCopyOrCutEvent)
00629 break;
00630 }
00631 }
00632 else if (CPKeyCodes.firesKeyPressEvent(_keyCode, _lastKey, aDOMEvent.shiftKey, aDOMEvent.ctrlKey, aDOMEvent.altKey))
00633 {
00634
00635
00636 StopDOMEventPropagation = NO;
00637 break;
00638 }
00639 else
00640 {
00641
00642
00643 }
00644
00645 case "keypress":
00646
00647
00648 if (aDOMEvent.type === "keypress" && (modifierFlags & (CPControlKeyMask | CPCommandKeyMask)))
00649 break;
00650
00651 var keyCode = _keyCode,
00652 charCode = aDOMEvent.keyCode || aDOMEvent.charCode,
00653 isARepeat = (_charCodes[keyCode] != nil);
00654
00655 _lastKey = keyCode;
00656 _charCodes[keyCode] = charCode;
00657
00658 var characters = overrideCharacters || String.fromCharCode(charCode),
00659 charactersIgnoringModifiers = characters.toLowerCase();
00660
00661
00662 if (!overrideCharacters && (modifierFlags & CPCommandKeyMask) && ((modifierFlags & CPShiftKeyMask) || _capsLockActive))
00663 characters = characters.toUpperCase();
00664
00665 event = [CPEvent keyEventWithType:CPKeyDown location:location modifierFlags:modifierFlags
00666 timestamp:timestamp windowNumber:windowNumber context:nil
00667 characters:characters charactersIgnoringModifiers:charactersIgnoringModifiers isARepeat:isARepeat keyCode:keyCode];
00668
00669 if (isNativePasteEvent)
00670 {
00671 _pasteboardKeyDownEvent = event;
00672 window.setNativeTimeout(function () { [self _checkPasteboardElement] }, 0);
00673 }
00674
00675 break;
00676
00677 case "keyup": var keyCode = aDOMEvent.keyCode,
00678 charCode = _charCodes[keyCode];
00679
00680 _keyCode = -1;
00681 _lastKey = -1;
00682 _charCodes[keyCode] = nil;
00683 _ignoreNativeCopyOrCutEvent = NO;
00684 _ignoreNativePastePreparation = NO;
00685
00686
00687 if (keyCode === CPKeyCodes.CAPS_LOCK)
00688 _capsLockActive = NO;
00689
00690 var characters = String.fromCharCode(charCode),
00691 charactersIgnoringModifiers = characters.toLowerCase();
00692
00693 if (!(modifierFlags & CPShiftKeyMask) && (modifierFlags & CPCommandKeyMask) && !_capsLockActive)
00694 characters = charactersIgnoringModifiers;
00695
00696 event = [CPEvent keyEventWithType:CPKeyUp location:location modifierFlags:modifierFlags
00697 timestamp: timestamp windowNumber:windowNumber context:nil
00698 characters:characters charactersIgnoringModifiers:charactersIgnoringModifiers isARepeat:NO keyCode:keyCode];
00699 break;
00700 }
00701
00702 if (event && !isNativePasteEvent)
00703 {
00704 event._DOMEvent = aDOMEvent;
00705
00706 [CPApp sendEvent:event];
00707
00708 if (isNativeCopyOrCutEvent)
00709 {
00710
00711 [self _primePasteboardElement];
00712 }
00713 }
00714
00715 if (StopDOMEventPropagation)
00716 CPDOMEventStop(aDOMEvent, self);
00717
00718 [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
00719 }
00720
00721 - (void)copyEvent:(DOMEvent)aDOMEvent
00722 {
00723 if ([self _validateCopyCutOrPasteEvent:aDOMEvent flags:CPPlatformActionKeyMask] && !_ignoreNativeCopyOrCutEvent)
00724 {
00725
00726 var cut = aDOMEvent.type === "beforecut",
00727 keyCode = cut ? CPKeyCodes.X : CPKeyCodes.C,
00728 characters = cut ? "x" : "c",
00729 timestamp = aDOMEvent.timeStamp ? aDOMEvent.timeStamp : new Date(),
00730 windowNumber = [[CPApp keyWindow] windowNumber],
00731 modifierFlags = CPPlatformActionKeyMask;
00732
00733 event = [CPEvent keyEventWithType:CPKeyDown location:location modifierFlags:modifierFlags
00734 timestamp:timestamp windowNumber:windowNumber context:nil
00735 characters:characters charactersIgnoringModifiers:characters isARepeat:NO keyCode:keyCode];
00736
00737 event._DOMEvent = aDOMEvent;
00738 [CPApp sendEvent:event];
00739
00740 [self _primePasteboardElement];
00741
00742
00743
00744 _ignoreNativeCopyOrCutEvent = YES;
00745 }
00746
00747 [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
00748 }
00749
00750 - (void)pasteEvent:(DOMEvent)aDOMEvent
00751 {
00752 if ([self _validateCopyCutOrPasteEvent:aDOMEvent flags:CPPlatformActionKeyMask])
00753 {
00754 _DOMPasteboardElement.focus();
00755 _DOMPasteboardElement.select();
00756 _DOMPasteboardElement.value = "";
00757 _ignoreNativePastePreparation = YES;
00758 }
00759
00760 [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
00761 }
00762
00763 - (void)_validateCopyCutOrPasteEvent:(DOMEvent)aDOMEvent flags:(unsigned)modifierFlags
00764 {
00765 return (
00766 ((aDOMEvent.target || aDOMEvent.srcElement).nodeName.toUpperCase() !== "INPUT" &&
00767 (aDOMEvent.target || aDOMEvent.srcElement).nodeName.toUpperCase() !== "TEXTAREA"
00768 ) || aDOMEvent.target === _DOMPasteboardElement
00769 ) &&
00770 (modifierFlags & CPPlatformActionKeyMask);
00771 }
00772
00773 - (void)_primePasteboardElement
00774 {
00775 var pasteboard = [CPPasteboard generalPasteboard],
00776 types = [pasteboard types];
00777
00778 if (types.length)
00779 {
00780 if ([types indexOfObjectIdenticalTo:CPStringPboardType] != CPNotFound)
00781 _DOMPasteboardElement.value = [pasteboard stringForType:CPStringPboardType];
00782 else
00783 _DOMPasteboardElement.value = [pasteboard _generateStateUID];
00784
00785 _DOMPasteboardElement.focus();
00786 _DOMPasteboardElement.select();
00787
00788 window.setNativeTimeout(function() { [self _clearPasteboardElement]; }, 0);
00789 }
00790 }
00791
00792 - (void)_checkPasteboardElement
00793 {
00794 var value = _DOMPasteboardElement.value;
00795
00796 if ([value length])
00797 {
00798 var pasteboard = [CPPasteboard generalPasteboard];
00799
00800 if ([pasteboard _stateUID] != value)
00801 {
00802 [pasteboard declareTypes:[CPStringPboardType] owner:self];
00803 [pasteboard setString:value forType:CPStringPboardType];
00804 }
00805 }
00806
00807 [self _clearPasteboardElement];
00808
00809 [CPApp sendEvent:_pasteboardKeyDownEvent];
00810
00811 _pasteboardKeyDownEvent = nil;
00812
00813 [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
00814 }
00815
00816 - (void)_clearPasteboardElement
00817 {
00818 _DOMPasteboardElement.value = "";
00819 _DOMPasteboardElement.blur();
00820 }
00821
00822 - (void)scrollEvent:(DOMEvent)aDOMEvent
00823 {
00824 if(!aDOMEvent)
00825 aDOMEvent = window.event;
00826
00827 if (CPFeatureIsCompatible(CPJavaScriptMouseWheelValues_8_15))
00828 {
00829 var x = 0.0,
00830 y = 0.0,
00831 element = aDOMEvent.target;
00832
00833 while (element.nodeType !== 1)
00834 element = element.parentNode;
00835
00836 if (element.offsetParent)
00837 {
00838 do
00839 {
00840 x += element.offsetLeft;
00841 y += element.offsetTop;
00842
00843 } while (element = element.offsetParent);
00844 }
00845
00846 var location = _CGPointMake((x + ((aDOMEvent.clientX - 8) / 15)), (y + ((aDOMEvent.clientY - 8) / 15)));
00847 }
00848 else
00849 var location = _CGPointMake(aDOMEvent.clientX, aDOMEvent.clientY);
00850
00851 var deltaX = 0.0,
00852 deltaY = 0.0,
00853 windowNumber = 0,
00854 timestamp = aDOMEvent.timeStamp ? aDOMEvent.timeStamp : new Date(),
00855 modifierFlags = (aDOMEvent.shiftKey ? CPShiftKeyMask : 0) |
00856 (aDOMEvent.ctrlKey ? CPControlKeyMask : 0) |
00857 (aDOMEvent.altKey ? CPAlternateKeyMask : 0) |
00858 (aDOMEvent.metaKey ? CPCommandKeyMask : 0);
00859
00860 StopDOMEventPropagation = YES;
00861
00862 var theWindow = [self hitTest:location];
00863
00864 if (!theWindow)
00865 return;
00866
00867 var windowNumber = [theWindow windowNumber];
00868
00869 location = [theWindow convertBridgeToBase:location];
00870
00871 if(typeof aDOMEvent.wheelDeltaX != "undefined")
00872 {
00873 deltaX = aDOMEvent.wheelDeltaX / 120.0;
00874 deltaY = aDOMEvent.wheelDeltaY / 120.0;
00875 }
00876
00877 else if (aDOMEvent.wheelDelta)
00878 deltaY = aDOMEvent.wheelDelta / 120.0;
00879
00880 else if (aDOMEvent.detail)
00881 deltaY = -aDOMEvent.detail / 3.0;
00882
00883 else
00884 return;
00885
00886 if(!CPFeatureIsCompatible(CPJavaScriptNegativeMouseWheelValues))
00887 {
00888 deltaX = -deltaX;
00889 deltaY = -deltaY;
00890 }
00891
00892 var event = [CPEvent mouseEventWithType:CPScrollWheel location:location modifierFlags:modifierFlags
00893 timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:-1 clickCount:1 pressure:0 ];
00894
00895 event._DOMEvent = aDOMEvent;
00896 event._deltaX = deltaX;
00897 event._deltaY = deltaY;
00898
00899 [CPApp sendEvent:event];
00900
00901 if (StopDOMEventPropagation)
00902 CPDOMEventStop(aDOMEvent, self);
00903
00904 [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
00905 }
00906
00907 - (void)resizeEvent:(DOMEvent)aDOMEvent
00908 {
00909
00910
00911
00912
00913 if ([CPPlatform isBrowser])
00914 [CPApp._activeMenu cancelTracking];
00915
00916 var oldSize = [self contentRect].size;
00917
00918 [self updateFromNativeContentRect];
00919
00920 var levels = _windowLevels,
00921 layers = _windowLayers,
00922 levelCount = levels.length;
00923
00924 while (levelCount--)
00925 {
00926 var windows = [layers objectForKey:levels[levelCount]]._windows,
00927 windowCount = windows.length;
00928
00929 while (windowCount--)
00930 [windows[windowCount] resizeWithOldPlatformWindowSize:oldSize];
00931 }
00932
00933
00934
00935 [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
00936 }
00937
00938 - (void)touchEvent:(DOMEvent)aDOMEvent
00939 {
00940 if (aDOMEvent.touches && (aDOMEvent.touches.length == 1 || (aDOMEvent.touches.length == 0 && aDOMEvent.changedTouches.length == 1)))
00941 {
00942 var newEvent = {};
00943
00944 switch(aDOMEvent.type)
00945 {
00946 case CPDOMEventTouchStart: newEvent.type = CPDOMEventMouseDown;
00947 break;
00948 case CPDOMEventTouchEnd: newEvent.type = CPDOMEventMouseUp;
00949 break;
00950 case CPDOMEventTouchMove: newEvent.type = CPDOMEventMouseMoved;
00951 break;
00952 case CPDOMEventTouchCancel: newEvent.type = CPDOMEventMouseUp;
00953 break;
00954 }
00955
00956 var touch = aDOMEvent.touches.length ? aDOMEvent.touches[0] : aDOMEvent.changedTouches[0];
00957
00958 newEvent.clientX = touch.clientX;
00959 newEvent.clientY = touch.clientY;
00960
00961 newEvent.timestamp = aDOMEvent.timestamp;
00962 newEvent.target = aDOMEvent.target;
00963
00964 newEvent.shiftKey = newEvent.ctrlKey = newEvent.altKey = newEvent.metaKey = false;
00965
00966 newEvent.preventDefault = function(){if(aDOMEvent.preventDefault) aDOMEvent.preventDefault()};
00967 newEvent.stopPropagation = function(){if(aDOMEvent.stopPropagation) aDOMEvent.stopPropagation()};
00968
00969 [self mouseEvent:newEvent];
00970
00971 return;
00972 }
00973 else
00974 {
00975 if (aDOMEvent.preventDefault)
00976 aDOMEvent.preventDefault();
00977
00978 if (aDOMEvent.stopPropagation)
00979 aDOMEvent.stopPropagation();
00980 }
00981
00982 }
00983
00984 - (void)mouseEvent:(DOMEvent)aDOMEvent
00985 {
00986 var type = _overriddenEventType || aDOMEvent.type;
00987
00988
00989 if (type === @"dblclick")
00990 {
00991 _overriddenEventType = CPDOMEventMouseDown;
00992 [self mouseEvent:aDOMEvent];
00993
00994 _overriddenEventType = CPDOMEventMouseUp;
00995 [self mouseEvent:aDOMEvent];
00996
00997 _overriddenEventType = nil;
00998
00999 return;
01000 }
01001
01002 var event,
01003 location = _CGPointMake(aDOMEvent.clientX, aDOMEvent.clientY),
01004 timestamp = aDOMEvent.timeStamp ? aDOMEvent.timeStamp : new Date(),
01005 sourceElement = (aDOMEvent.target || aDOMEvent.srcElement),
01006 windowNumber = 0,
01007 modifierFlags = (aDOMEvent.shiftKey ? CPShiftKeyMask : 0) |
01008 (aDOMEvent.ctrlKey ? CPControlKeyMask : 0) |
01009 (aDOMEvent.altKey ? CPAlternateKeyMask : 0) |
01010 (aDOMEvent.metaKey ? CPCommandKeyMask : 0);
01011
01012 StopDOMEventPropagation = YES;
01013
01014 if (_mouseDownWindow)
01015 windowNumber = [_mouseDownWindow windowNumber];
01016
01017 else
01018 {
01019 var theWindow = [self hitTest:location];
01020
01021 if ((aDOMEvent.type === CPDOMEventMouseDown) && theWindow)
01022 _mouseDownWindow = theWindow;
01023
01024 windowNumber = [theWindow windowNumber];
01025 }
01026
01027 if (windowNumber)
01028 location = [CPApp._windows[windowNumber] convertPlatformWindowToBase:location];
01029
01030 if (type === "mouseup")
01031 {
01032 if(_mouseIsDown)
01033 {
01034 event = _CPEventFromNativeMouseEvent(aDOMEvent, CPLeftMouseUp, location, modifierFlags, timestamp, windowNumber, nil, -1, CPDOMEventGetClickCount(_lastMouseUp, timestamp, location), 0);
01035
01036 _mouseIsDown = NO;
01037 _lastMouseUp = event;
01038 _mouseDownWindow = nil;
01039 }
01040
01041 if(_DOMEventMode)
01042 {
01043 _DOMEventMode = NO;
01044 return;
01045 }
01046 }
01047
01048 else if (type === "mousedown")
01049 {
01050 if (sourceElement.tagName === "INPUT" && sourceElement != _DOMFocusElement)
01051 {
01052 if ([CPPlatform supportsDragAndDrop])
01053 {
01054 _DOMBodyElement.setAttribute("draggable", "false");
01055 _DOMBodyElement.style["-khtml-user-drag"] = "none";
01056 }
01057
01058 _DOMEventMode = YES;
01059 _mouseIsDown = YES;
01060
01061
01062 [CPApp sendEvent:[CPEvent mouseEventWithType:CPLeftMouseDown location:location modifierFlags:modifierFlags
01063 timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:-1
01064 clickCount:CPDOMEventGetClickCount(_lastMouseDown, timestamp, location) pressure:0]];
01065
01066 [CPApp sendEvent:[CPEvent mouseEventWithType:CPLeftMouseUp location:location modifierFlags:modifierFlags
01067 timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:-1
01068 clickCount:CPDOMEventGetClickCount(_lastMouseDown, timestamp, location) pressure:0]];
01069
01070 return;
01071 }
01072 else if ([CPPlatform supportsDragAndDrop])
01073 {
01074 _DOMBodyElement.setAttribute("draggable", "true");
01075 _DOMBodyElement.style["-khtml-user-drag"] = "element";
01076 }
01077
01078 event = _CPEventFromNativeMouseEvent(aDOMEvent, CPLeftMouseDown, location, modifierFlags, timestamp, windowNumber, nil, -1, CPDOMEventGetClickCount(_lastMouseDown, timestamp, location), 0);
01079
01080 _mouseIsDown = YES;
01081 _lastMouseDown = event;
01082 }
01083
01084 else
01085 {
01086 if (_DOMEventMode)
01087 return;
01088
01089 event = _CPEventFromNativeMouseEvent(aDOMEvent, _mouseIsDown ? CPLeftMouseDragged : CPMouseMoved, location, modifierFlags, timestamp, windowNumber, nil, -1, 1, 0);
01090 }
01091
01092 var isDragging = [[CPDragServer sharedDragServer] isDragging];
01093
01094 if (event && (!isDragging || !supportsNativeDragAndDrop))
01095 {
01096 event._DOMEvent = aDOMEvent;
01097
01098 [CPApp sendEvent:event];
01099 }
01100
01101 if (StopDOMEventPropagation && (!supportsNativeDragAndDrop || type !== "mousedown" && !isDragging))
01102 CPDOMEventStop(aDOMEvent, self);
01103
01104 [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
01105 }
01106
01107 - (CPArray)orderedWindowsAtLevel:(int)aLevel
01108 {
01109 var layer = [self layerAtLevel:aLevel create:NO];
01110
01111 if (!layer)
01112 return [];
01113
01114 return [layer orderedWindows];
01115 }
01116
01117 - (CPDOMWindowLayer)layerAtLevel:(int)aLevel create:(BOOL)aFlag
01118 {
01119 var layer = [_windowLayers objectForKey:aLevel];
01120
01121
01122
01123 if (!layer && aFlag)
01124 {
01125 layer = [[CPDOMWindowLayer alloc] initWithLevel:aLevel];
01126
01127 [_windowLayers setObject:layer forKey:aLevel];
01128
01129
01130
01131 var low = 0,
01132 high = _windowLevels.length - 1,
01133 middle;
01134
01135 while (low <= high)
01136 {
01137 middle = FLOOR((low + high) / 2);
01138
01139 if (_windowLevels[middle] > aLevel)
01140 high = middle - 1;
01141 else
01142 low = middle + 1;
01143 }
01144
01145 var insertionIndex = 0;
01146 if (middle !== undefined)
01147 insertionIndex = _windowLevels[middle] > aLevel ? middle : middle + 1
01148
01149 [_windowLevels insertObject:aLevel atIndex:insertionIndex];
01150 layer._DOMElement.style.zIndex = aLevel;
01151 _DOMBodyElement.appendChild(layer._DOMElement);
01152 }
01153
01154 return layer;
01155 }
01156
01157 - (void)order:(CPWindowOrderingMode)aPlace window:(CPWindow)aWindow relativeTo:(CPWindow)otherWindow
01158 {
01159 [CPPlatform initializeScreenIfNecessary];
01160
01161
01162
01163 var layer = [self layerAtLevel:[aWindow level] create:aPlace !== CPWindowOut];
01164
01165
01166
01167 if (aPlace === CPWindowOut)
01168 return [layer removeWindow:aWindow];
01169
01170 var insertionIndex = CPNotFound;
01171 if (otherWindow)
01172 insertionIndex = aPlace === CPWindowAbove ? otherWindow._index + 1 : otherWindow._index;
01173
01174
01175 [layer insertWindow:aWindow atIndex:insertionIndex];
01176 }
01177
01178 - (void)_removeLayers
01179 {
01180 var levels = _windowLevels,
01181 layers = _windowLayers,
01182 levelCount = levels.length;
01183
01184 while (levelCount--)
01185 {
01186 var layer = [layers objectForKey:levels[levelCount]];
01187
01188 _DOMBodyElement.removeChild(layer._DOMElement);
01189 }
01190 }
01191
01192 - (void)_addLayers
01193 {
01194 var levels = _windowLevels,
01195 layers = _windowLayers,
01196 levelCount = levels.length;
01197
01198 while (levelCount--)
01199 {
01200 var layer = [layers objectForKey:levels[levelCount]];
01201
01202 _DOMBodyElement.appendChild(layer._DOMElement);
01203 }
01204 }
01205
01206
01207 - (id)_dragHitTest:(CPPoint)aPoint pasteboard:(CPPasteboard)aPasteboard
01208 {
01209 var levels = _windowLevels,
01210 layers = _windowLayers,
01211 levelCount = levels.length;
01212
01213 while (levelCount--)
01214 {
01215
01216 if (levels[levelCount] >= CPDraggingWindowLevel)
01217 continue;
01218
01219 var windows = [layers objectForKey:levels[levelCount]]._windows,
01220 windowCount = windows.length;
01221
01222 while (windowCount--)
01223 {
01224 var theWindow = windows[windowCount];
01225
01226 if ([theWindow _sharesChromeWithPlatformWindow])
01227 return [theWindow _dragHitTest:aPoint pasteboard:aPasteboard];
01228
01229 if ([theWindow containsPoint:aPoint])
01230 return [theWindow _dragHitTest:aPoint pasteboard:aPasteboard];
01231 }
01232 }
01233
01234 return nil;
01235 }
01236
01237
01238 - (void)_propagateCurrentDOMEvent:(BOOL)aFlag
01239 {
01240 StopDOMEventPropagation = !aFlag;
01241 }
01242
01243 - (BOOL)_willPropagateCurrentDOMEvent
01244 {
01245 return !StopDOMEventPropagation;
01246 }
01247
01248 - (CPWindow)hitTest:(CPPoint)location
01249 {
01250 if (self._only)
01251 return self._only;
01252
01253 var levels = _windowLevels,
01254 layers = _windowLayers,
01255 levelCount = levels.length,
01256 theWindow = nil;
01257
01258 while (levelCount-- && !theWindow)
01259 {
01260 var windows = [layers objectForKey:levels[levelCount]]._windows,
01261 windowCount = windows.length;
01262
01263 while (windowCount-- && !theWindow)
01264 {
01265 var candidateWindow = windows[windowCount];
01266
01267 if (!candidateWindow._ignoresMouseEvents && [candidateWindow containsPoint:location])
01268 theWindow = candidateWindow;
01269 }
01270 }
01271
01272 return theWindow;
01273 }
01274
01282 + (void)preventCharacterKeysFromPropagating:(CPArray)characters
01283 {
01284 for(var i=characters.length; i>0; i--)
01285 CharacterKeysToPrevent[""+characters[i-1].toLowerCase()] = YES;
01286 }
01287
01291 + (void)preventCharacterKeyFromPropagating:(CPString)character
01292 {
01293 CharacterKeysToPrevent[character.toLowerCase()] = YES;
01294 }
01295
01299 + (void)clearCharacterKeysToPreventFromPropagating
01300 {
01301 CharacterKeysToPrevent = {};
01302 }
01303
01308 + (void)preventKeyCodesFromPropagating:(CPArray)keyCodes
01309 {
01310 for(var i=keyCodes.length; i>0; i--)
01311 KeyCodesToPrevent[keyCodes[i-1]] = YES;
01312 }
01313
01318 + (void)preventKeyCodeFromPropagating:(CPString)keyCode
01319 {
01320 KeyCodesToPrevent[keyCode] = YES;
01321 }
01322
01326 + (void)clearKeyCodesToPreventFromPropagating
01327 {
01328 KeyCodesToPrevent = {};
01329 }
01330
01331 @end
01332
01333 var CPEventClass = [CPEvent class];
01334
01335 var _CPEventFromNativeMouseEvent = function(aNativeEvent, anEventType, aPoint, modifierFlags, aTimestamp, aWindowNumber, aGraphicsContext, anEventNumber, aClickCount, aPressure)
01336 {
01337 aNativeEvent.isa = CPEventClass;
01338
01339 aNativeEvent._type = anEventType;
01340 aNativeEvent._location = aPoint;
01341 aNativeEvent._modifierFlags = modifierFlags;
01342 aNativeEvent._timestamp = aTimestamp;
01343 aNativeEvent._windowNumber = aWindowNumber;
01344 aNativeEvent._window = nil;
01345 aNativeEvent._context = aGraphicsContext;
01346 aNativeEvent._eventNumber = anEventNumber;
01347 aNativeEvent._clickCount = aClickCount;
01348 aNativeEvent._pressure = aPressure;
01349
01350 return aNativeEvent;
01351 }
01352
01353 var CLICK_SPACE_DELTA = 5.0,
01354 CLICK_TIME_DELTA = (typeof document != "undefined" && document.addEventListener) ? 350.0 : 1000.0;
01355
01356 var CPDOMEventGetClickCount = function(aComparisonEvent, aTimestamp, aLocation)
01357 {
01358 if (!aComparisonEvent)
01359 return 1;
01360
01361 var comparisonLocation = [aComparisonEvent locationInWindow];
01362
01363 return (aTimestamp - [aComparisonEvent timestamp] < CLICK_TIME_DELTA &&
01364 ABS(comparisonLocation.x - aLocation.x) < CLICK_SPACE_DELTA &&
01365 ABS(comparisonLocation.y - aLocation.y) < CLICK_SPACE_DELTA) ? [aComparisonEvent clickCount] + 1 : 1;
01366 }
01367
01368 var CPDOMEventStop = function(aDOMEvent, aPlatformWindow)
01369 {
01370
01371 aDOMEvent.cancelBubble = true;
01372 aDOMEvent.returnValue = false;
01373
01374
01375 if (aDOMEvent.preventDefault)
01376 aDOMEvent.preventDefault();
01377
01378 if (aDOMEvent.stopPropagation)
01379 aDOMEvent.stopPropagation();
01380
01381 if (aDOMEvent.type === CPDOMEventMouseDown)
01382 {
01383 aPlatformWindow._DOMFocusElement.focus();
01384 aPlatformWindow._DOMFocusElement.blur();
01385 }
01386 }
01387
01388 function CPWindowObjectList()
01389 {
01390 var platformWindows = [CPPlatformWindow visiblePlatformWindows],
01391 platformWindowEnumerator = [platformWindows objectEnumerator],
01392 platformWindow = nil,
01393 windowObjects = [];
01394
01395 while (platformWindow = [platformWindowEnumerator nextObject])
01396 {
01397 var levels = platformWindow._windowLevels,
01398 layers = platformWindow._windowLayers,
01399 levelCount = levels.length;
01400
01401 while (levelCount--)
01402 {
01403 var windows = [layers objectForKey:levels[levelCount]]._windows,
01404 windowCount = windows.length;
01405
01406 while (windowCount--)
01407 windowObjects.push(windows[windowCount]);
01408 }
01409 }
01410
01411 return windowObjects;
01412 }
01413
01414 function CPWindowList()
01415 {
01416 var windowObjectList = CPWindowObjectList(),
01417 windowList = [];
01418
01419 for (var i = 0, count = [windowObjectList count]; i < count; i++)
01420 windowList.push([windowObjectList[i] windowNumber]);
01421
01422 return windowList;
01423 }