diff --git a/AppKit/CPApplication.j b/AppKit/CPApplication.j index 9bad05ec9..0af618766 100644 --- a/AppKit/CPApplication.j +++ b/AppKit/CPApplication.j @@ -319,7 +319,7 @@ CPRunContinuesResponse = -1002; } else { - [[[CPApp mainWindow] platformWindow] _propagateCurrentDOMEvent:YES]; + [[[self keyWindow] platformWindow] _propagateCurrentDOMEvent:YES]; } } @@ -548,13 +548,28 @@ CPRunContinuesResponse = -1002; { _currentEvent = anEvent; + var willPropagate = [[[anEvent window] platformWindow] _willPropagateCurrentDOMEvent]; + + // temporarily pretend we won't propagate the event. we'll restore the saved value later + // we do this outside the if so that changes user code might make in _handleKeyEquiv. are preserved + [[[anEvent window] platformWindow] _propagateCurrentDOMEvent:NO]; + // Check if this is a candidate for key equivalent... if ([anEvent _couldBeKeyEquivalent] && [self _handleKeyEquivalent:anEvent]) { - [[[anEvent window] platformWindow] _propagateCurrentDOMEvent:NO]; + var characters = [anEvent characters], + modifierFlags = [anEvent modifierFlags]; + + // Unconditionally propagate on these keys to solve browser copy paste bugs + if ((characters == "c" || characters == "x" || characters == "v") && (modifierFlags & CPPlatformActionKeyMask)) + [[[anEvent window] platformWindow] _propagateCurrentDOMEvent:YES]; + return; } + // if we make it this far, then restore the original willPropagate value + [[[anEvent window] platformWindow] _propagateCurrentDOMEvent:willPropagate]; + if (_eventListeners.length) { if (_eventListeners[_eventListeners.length - 1]._mask & (1 << [anEvent type])) diff --git a/AppKit/CPCompatibility.j b/AppKit/CPCompatibility.j index 38a0b1d19..b8457e38c 100644 --- a/AppKit/CPCompatibility.j +++ b/AppKit/CPCompatibility.j @@ -31,6 +31,11 @@ CPKHTMLBrowserEngine = 3; CPOperaBrowserEngine = 4; CPWebKitBrowserEngine = 5; +// Operating Systems +CPMacOperatingSystem = 0; +CPWindowsOperatingSystem = 1; +CPOtherOperatingSystem = 2; + // Features CPCSSRGBAFeature = 1 << 5; @@ -183,11 +188,20 @@ function CPFeatureIsCompatible(aFeature) function CPBrowserIsEngine(anEngine) { - return PLATFORM_ENGINE == anEngine; + return PLATFORM_ENGINE === anEngine; } -if (USER_AGENT.indexOf("Mac") != -1) +function CPBrowserIsOperatingSystem(anOperatingSystem) { + return OPERATING_SYSTEM === anOperatingSystem; +} + +OPERATING_SYSTEM = CPOtherOperatingSystem; + +if (USER_AGENT.indexOf("Mac") !== -1) +{ + OPERATING_SYSTEM = CPMacOperatingSystem; + CPPlatformActionKeyMask = CPCommandKeyMask; CPUndoKeyEquivalent = @"Z"; @@ -198,6 +212,9 @@ if (USER_AGENT.indexOf("Mac") != -1) } else { + if (USER_AGENT.indexOf("Windows") !== -1) + OPERATING_SYSTEM = CPWindowsOperatingSystem; + CPPlatformActionKeyMask = CPControlKeyMask; CPUndoKeyEquivalent = @"Z"; diff --git a/AppKit/CPTextField.j b/AppKit/CPTextField.j index 9be50e5ff..a14b065e1 100644 --- a/AppKit/CPTextField.j +++ b/AppKit/CPTextField.j @@ -639,6 +639,9 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); else [[self window] selectNextKeyView:self]; + if ([[[self window] firstResponder] respondsToSelector:@selector(selectText:)]) + [[[self window] firstResponder] selectText:self]; + [[[self window] platformWindow] _propagateCurrentDOMEvent:NO]; } else @@ -781,11 +784,24 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); #if PLATFORM(DOM) var element = [self _inputElement]; - if (element.parentNode === _DOMElement && ([self isEditable] || [self isSelectable])) - window.setTimeout(function() { element.select(); }, 0); + if (([self isEditable] || [self isSelectable])) + { + if ([[self window] firstResponder] === self) + window.setTimeout(function() { element.select(); }, 0); + else + { + [[self window] makeFirstResponder:self]; + window.setTimeout(function() {[self selectText:sender];}, 0); + } + } #endif } +- (void)selectAll:(id)sender +{ + [self selectText:sender]; +} + #pragma mark Setting the Delegate - (void)setDelegate:(id)aDelegate diff --git a/AppKit/CPViewController.j b/AppKit/CPViewController.j index 7aa31ec85..c66f021f8 100644 --- a/AppKit/CPViewController.j +++ b/AppKit/CPViewController.j @@ -22,6 +22,7 @@ @import +var CPViewControllerCachedCibs; /*! @class CPViewController The CPViewController class provides the fundamental view-management controller for Cappuccino applications. @@ -56,6 +57,12 @@ CPDictionary _cibExternalNameTable @accessors(property=cibExternalNameTable, readonly); } ++ (void)initialize +{ + if (self === CPViewController) + CPViewControllerCachedCibs = [CPDictionary dictionary]; +} + /*! Convenience initializer calls -initWithCibName:bundle: with nil for both parameters. */ @@ -113,11 +120,16 @@ { if (_view) return; + + // check if a cib is already cached for the current _cibName + var cib = [CPViewControllerCachedCibs objectForKey:_cibName]; -// if (_cibName) -// [CPException raise: reason:]; - - var cib = [[CPCib alloc] initWithContentsOfURL:[_cibBundle pathForResource:_cibName + @".cib"]]; + if (!cib) + { + // if the cib isn't cached yet : fetch it and cache it + cib = [[CPCib alloc] initWithContentsOfURL:[_cibBundle pathForResource:_cibName + @".cib"]]; + [CPViewControllerCachedCibs setObject:cib forKey:_cibName]; + } [cib instantiateCibWithExternalNameTable:_cibExternalNameTable]; } diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index b2af4f577..ea5c7b244 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -1745,6 +1745,9 @@ CPTexturedBackgroundWindowMask [[CPNotificationCenter defaultCenter] postNotificationName:CPWindowWillCloseNotification object:self]; [self orderOut:nil]; + + if ([self isFullBridge]) + [[self platformWindow] _propagateCurrentDOMEvent:YES]; } // Managing Main Status diff --git a/AppKit/Platform/CPPlatformWindow.j b/AppKit/Platform/CPPlatformWindow.j index 5ad005aad..f55be6360 100644 --- a/AppKit/Platform/CPPlatformWindow.j +++ b/AppKit/Platform/CPPlatformWindow.j @@ -30,6 +30,10 @@ var PrimaryPlatformWindow = NULL; Object _charCodes; unsigned _keyCode; + unsigned _lastKey; + BOOL _capsLockActive; + BOOL _ignoreNativeCopyOrCutEvent; + BOOL _ignoreNativePastePreparation; BOOL _DOMEventMode; diff --git a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j index fd651cb10..ff0acbffa 100644 --- a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j +++ b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j @@ -66,7 +66,7 @@ * until the first key is released. This can cause a key event to be fired with * a keyCode for the first key and a charCode for the second key. * - * Safari in keypress + * Safari 2 in keypress (not supported) * * charCode keyCode which * ENTER: 13 13 13 @@ -117,27 +117,10 @@ @import "CPPlatform.j" @import "CPPlatformWindow.j" +@import "CPPlatformWindow+DOMKeys.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"; - // Define up here so compressor knows about em. var CPDOMEventGetClickCount, CPDOMEventStop, @@ -148,9 +131,12 @@ var CPDOMEventGetClickCount, //might be mac only, we should investigate futher later. var KeyCodesToPrevent = {}, CharacterKeysToPrevent = {}, - KeyCodesWithoutKeyPressEvents = { '8':1, '9':1, '16':1, '33':1, '34':1, '35':1, '36':1, '37':1, '38':1, '39':1, '40':1, '46':1, '33':1, '34':1 }; + MozKeyCodeToKeyCodeMap = { + 61: 187, // =, equals + 59: 186 // ;, semicolon + }; -var CTRL_KEY_CODE = 17; +KeyCodesToPrevent[CPKeyCodes.A] = YES; var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; @@ -251,6 +237,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; _DOMBodyElement.webkitTouchCallout = "none"; + // This guy fixes an issue in Firefox where if you focus the URL field, we stop getting key events _DOMFocusElement = theDocument.createElement("input"); _DOMFocusElement.style.position = "absolute"; @@ -261,11 +248,11 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; _DOMBodyElement.appendChild(_DOMFocusElement); // Create Native Pasteboard handler. - _DOMPasteboardElement = theDocument.createElement("input"); + _DOMPasteboardElement = theDocument.createElement("textarea"); _DOMPasteboardElement.style.position = "absolute"; _DOMPasteboardElement.style.top = "-10000px"; - _DOMPasteboardElement.style.zIndex = "99"; + _DOMPasteboardElement.style.zIndex = "999"; _DOMBodyElement.appendChild(_DOMPasteboardElement); @@ -283,6 +270,14 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; resizeEventImplementation = class_getMethodImplementation(theClass, resizeEventSelector), resizeEventCallback = function (anEvent) { resizeEventImplementation(self, nil, anEvent); }, + copyEventSelector = @selector(copyEvent:), + copyEventImplementation = class_getMethodImplementation(theClass, copyEventSelector), + copyEventCallback = function (anEvent) {copyEventImplementation(self, nil, anEvent); }, + + pasteEventSelector = @selector(pasteEvent:), + pasteEventImplementation = class_getMethodImplementation(theClass, pasteEventSelector), + pasteEventCallback = function (anEvent) {pasteEventImplementation(self, nil, anEvent); }, + keyEventSelector = @selector(keyEvent:), keyEventImplementation = class_getMethodImplementation(theClass, keyEventSelector), keyEventCallback = function (anEvent) { keyEventImplementation(self, nil, anEvent); }, @@ -299,6 +294,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; touchEventImplementation = class_getMethodImplementation(theClass, touchEventSelector), touchEventCallback = function (anEvent) { touchEventImplementation(self, nil, anEvent); }; + if (theDocument.addEventListener) { if ([CPPlatform supportsDragAndDrop]) @@ -315,6 +311,10 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; theDocument.addEventListener("mousedown", mouseEventCallback, NO); theDocument.addEventListener("mousemove", mouseEventCallback, NO); + theDocument.addEventListener("beforecopy", copyEventCallback, NO); + theDocument.addEventListener("beforecut", copyEventCallback, NO); + theDocument.addEventListener("beforepaste", pasteEventCallback, NO); + theDocument.addEventListener("keyup", keyEventCallback, NO); theDocument.addEventListener("keydown", keyEventCallback, NO); theDocument.addEventListener("keypress", keyEventCallback, NO); @@ -342,6 +342,10 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; theDocument.removeEventListener("keydown", keyEventCallback, NO); theDocument.removeEventListener("keypress", keyEventCallback, NO); + theDocument.removeEventListener("beforecopy", copyEventCallback, NO); + theDocument.removeEventListener("beforecut", copyEventCallback, NO); + theDocument.removeEventListener("beforepaste", pasteEventCallback, NO); + theDocument.removeEventListener("touchstart", touchEventCallback, NO); theDocument.removeEventListener("touchend", touchEventCallback, NO); theDocument.removeEventListener("touchmove", touchEventCallback, NO); @@ -538,12 +542,11 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; (aDOMEvent.ctrlKey ? CPControlKeyMask : 0) | (aDOMEvent.altKey ? CPAlternateKeyMask : 0) | (aDOMEvent.metaKey ? CPCommandKeyMask : 0); - - - //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)) || + + //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]; + KeyCodesToPrevent[aDOMEvent.keyCode]); var isNativePasteEvent = NO, isNativeCopyOrCutEvent = NO, @@ -552,56 +555,80 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; switch (aDOMEvent.type) { case "keydown": // Grab and store the keycode now since it is correct and consistent at this point. - _keyCode = aDOMEvent.keyCode; + if (aDOMEvent.keyCode.keyCode in MozKeyCodeToKeyCodeMap) + _keyCode = MozKeyCodeToKeyCodeMap[aDOMEvent.keyCode]; + else + _keyCode = aDOMEvent.keyCode; var characters = String.fromCharCode(_keyCode).toLowerCase(); - overrideCharacters = modifierFlags & CPShiftKeyMask ? characters.toUpperCase() : characters; - - // 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)) + overrideCharacters = (modifierFlags & CPShiftKeyMask || _capsLockActive) ? characters.toUpperCase() : characters; + + // check for caps lock state + if (_keyCode === CPKeyCodes.CAPS_LOCK) + _capsLockActive = YES; + + if (modifierFlags & (CPControlKeyMask | CPCommandKeyMask | CPAlternateKeyMask)) { - _DOMPasteboardElement.select(); - _DOMPasteboardElement.value = ""; - - isNativePasteEvent = YES; + //we are simply going to skip all keypress events that use cmd/ctrl key + //this lets us be consistent in all browsers and send on the keydown + //which means we can cancel the event early enough, but only if sendEvent needs to + + var eligibleForCopyPaste = [self _validateCopyCutOrPasteEvent:aDOMEvent flags:modifierFlags]; + + // 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" && eligibleForCopyPaste) + { + if (!_ignoreNativePastePreparation) + { + _DOMPasteboardElement.select(); + _DOMPasteboardElement.value = ""; + } + + isNativePasteEvent = YES; + } + + // 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") && eligibleForCopyPaste) + { + isNativeCopyOrCutEvent = YES; + + if (_ignoreNativeCopyOrCutEvent) + break; + } + } + else if (CPKeyCodes.firesKeyPressEvent(_keyCode, _lastKey, aDOMEvent.shiftKey, aDOMEvent.ctrlKey, aDOMEvent.altKey)) + { + // this branch is taken by events which fire keydown, keypress, and keyup. + // this is the only time we'll ALLOW character keys to propagate (needed for text fields) + StopDOMEventPropagation = NO; + break; + } + else + { + //this branch is taken by "remedial" key events + // In this state we continue to keypress and send the CPEvent } - // 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; + case "keypress": + // we unconditionally break on keypress events with modifiers, + // because we forced the event to be sent on the keydown + if (aDOMEvent.type === "keypress" && (modifierFlags & (CPControlKeyMask | CPCommandKeyMask | CPAlternateKeyMask))) + break; - // 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); + _lastKey = keyCode; _charCodes[keyCode] = charCode; var characters = overrideCharacters || String.fromCharCode(charCode), charactersIgnoringModifiers = characters.toLowerCase(); // Safari won't send proper capitalization during cmd-key events - if (!overrideCharacters && (modifierFlags & CPCommandKeyMask) && (modifierFlags & CPShiftKeyMask)) + if (!overrideCharacters && (modifierFlags & CPCommandKeyMask) && ((modifierFlags & CPShiftKeyMask) || _capsLockActive)) characters = characters.toUpperCase(); event = [CPEvent keyEventWithType:CPKeyDown location:location modifierFlags:modifierFlags @@ -612,7 +639,6 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; { _pasteboardKeyDownEvent = event; window.setNativeTimeout(function () { [self _checkPasteboardElement] }, 0); - return; } break; @@ -620,12 +646,20 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; case "keyup": var keyCode = aDOMEvent.keyCode, charCode = _charCodes[keyCode]; + _keyCode = -1; + _lastKey = -1; _charCodes[keyCode] = nil; - + _ignoreNativeCopyOrCutEvent = NO; + _ignoreNativePastePreparation = NO; + + // check for caps lock state + if (keyCode === CPKeyCodes.CAPS_LOCK) + _capsLockActive = NO; + var characters = String.fromCharCode(charCode), charactersIgnoringModifiers = characters.toLowerCase(); - if (!(modifierFlags & CPShiftKeyMask)) + if (!(modifierFlags & CPShiftKeyMask) && (modifierFlags & CPCommandKeyMask) && !_capsLockActive) characters = charactersIgnoringModifiers; event = [CPEvent keyEventWithType:CPKeyUp location:location modifierFlags:modifierFlags @@ -633,40 +667,126 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; characters:characters charactersIgnoringModifiers:charactersIgnoringModifiers isARepeat:NO keyCode:keyCode]; break; } - - if (event) + + if (event && !isNativePasteEvent) { 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; + [self _primePasteboardElement]; } } - + if (StopDOMEventPropagation) CPDOMEventStop(aDOMEvent, self); [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; +} +- (void)copyEvent:(DOMEvent)aDOMEvent +{ + if ([self _validateCopyCutOrPasteEvent:aDOMEvent flags:CPPlatformActionKeyMask] && !_ignoreNativeCopyOrCutEvent) + { + //we have to send out a fake copy or cut event so that we can force the copy/cut mechanisms to take place + var cut = aDOMEvent.type === "beforecut", + keyCode = cut ? CPKeyCodes.X : CPKeyCodes.C, + characters = cut ? "x" : "c", + timestamp = aDOMEvent.timeStamp ? aDOMEvent.timeStamp : new Date(), + windowNumber = [[CPApp keyWindow] windowNumber], + modifierFlags = CPPlatformActionKeyMask; + + event = [CPEvent keyEventWithType:CPKeyDown location:location modifierFlags:modifierFlags + timestamp:timestamp windowNumber:windowNumber context:nil + characters:characters charactersIgnoringModifiers:characters isARepeat:NO keyCode:keyCode]; + + event._DOMEvent = aDOMEvent; + [CPApp sendEvent:event]; + + [self _primePasteboardElement]; + + //then we have to IGNORE the real keyboard event to prevent a double copy + //safari also sends the beforecopy event twice, so we additionally check here and prevent two events + _ignoreNativeCopyOrCutEvent = YES; + } + + [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; +} + +- (void)pasteEvent:(DOMEvent)aDOMEvent +{ + if ([self _validateCopyCutOrPasteEvent:aDOMEvent flags:CPPlatformActionKeyMask]) + { + _DOMPasteboardElement.focus(); + _DOMPasteboardElement.select(); + _DOMPasteboardElement.value = ""; + _ignoreNativePastePreparation = YES; + } + + [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; +} + +- (void)_validateCopyCutOrPasteEvent:(DOMEvent)aDOMEvent flags:(unsigned)modifierFlags +{ + return ( + ((aDOMEvent.target || aDOMEvent.srcElement).nodeName.toUpperCase() !== "INPUT" && + (aDOMEvent.target || aDOMEvent.srcElement).nodeName.toUpperCase() !== "TEXTAREA" + ) || aDOMEvent.target === _DOMPasteboardElement + ) && + (modifierFlags & CPPlatformActionKeyMask); +} + +- (void)_primePasteboardElement +{ + var pasteboard = [CPPasteboard generalPasteboard], + types = [pasteboard types]; + + if (types.length) + { + if ([types indexOfObjectIdenticalTo:CPStringPboardType] != CPNotFound) + _DOMPasteboardElement.value = [pasteboard stringForType:CPStringPboardType]; + else + _DOMPasteboardElement.value = [pasteboard _generateStateUID]; + + _DOMPasteboardElement.focus(); + _DOMPasteboardElement.select(); + + window.setNativeTimeout(function() { [self _clearPasteboardElement]; }, 0); + } +} + + +- (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(); } - (void)scrollEvent:(DOMEvent)aDOMEvent @@ -1077,8 +1197,16 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; StopDOMEventPropagation = !aFlag; } +- (BOOL)_willPropagateCurrentDOMEvent +{ + return !StopDOMEventPropagation; +} + - (CPWindow)hitTest:(CPPoint)location -{if (self._only) return self._only; +{ + if (self._only) + return self._only; + var levels = _windowLevels, layers = _windowLayers, levelCount = levels.length, @@ -1101,37 +1229,6 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; 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 diff --git a/AppKit/Platform/DOM/CPPlatformWindow+DOMKeys.j b/AppKit/Platform/DOM/CPPlatformWindow+DOMKeys.j new file mode 100644 index 000000000..88d93d84f --- /dev/null +++ b/AppKit/Platform/DOM/CPPlatformWindow+DOMKeys.j @@ -0,0 +1,231 @@ +/* + * CPPlatformWindow+DOMKeys.j + * AppKit + * + * Created by Ross Boucher. + * Copyright 2009, 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 + */ + +// Keycodes taken and modified from Google Closure, available under Apache 2 License + +CPKeyCodes = { + BACKSPACE: 8, + TAB: 9, + NUM_CENTER: 12, + ENTER: 13, + SHIFT: 16, + CTRL: 17, + ALT: 18, + PAUSE: 19, + CAPS_LOCK: 20, + ESC: 27, + SPACE: 32, + PAGE_UP: 33, // also NUM_NORTH_EAST + PAGE_DOWN: 34, // also NUM_SOUTH_EAST + END: 35, // also NUM_SOUTH_WEST + HOME: 36, // also NUM_NORTH_WEST + LEFT: 37, // also NUM_WEST + UP: 38, // also NUM_NORTH + RIGHT: 39, // also NUM_EAST + DOWN: 40, // also NUM_SOUTH + PRINT_SCREEN: 44, + INSERT: 45, // also NUM_INSERT + DELETE: 46, // also NUM_DELETE + ZERO: 48, + ONE: 49, + TWO: 50, + THREE: 51, + FOUR: 52, + FIVE: 53, + SIX: 54, + SEVEN: 55, + EIGHT: 56, + NINE: 57, + QUESTION_MARK: 63, // needs localization + A: 65, + B: 66, + C: 67, + D: 68, + E: 69, + F: 70, + G: 71, + H: 72, + I: 73, + J: 74, + K: 75, + L: 76, + M: 77, + N: 78, + O: 79, + P: 80, + Q: 81, + R: 82, + S: 83, + T: 84, + U: 85, + V: 86, + W: 87, + X: 88, + Y: 89, + Z: 90, + META: 91, + CONTEXT_MENU: 93, + NUM_ZERO: 96, + NUM_ONE: 97, + NUM_TWO: 98, + NUM_THREE: 99, + NUM_FOUR: 100, + NUM_FIVE: 101, + NUM_SIX: 102, + NUM_SEVEN: 103, + NUM_EIGHT: 104, + NUM_NINE: 105, + NUM_MULTIPLY: 106, + NUM_PLUS: 107, + NUM_MINUS: 109, + NUM_PERIOD: 110, + NUM_DIVISION: 111, + F1: 112, + F2: 113, + F3: 114, + F4: 115, + F5: 116, + F6: 117, + F7: 118, + F8: 119, + F9: 120, + F10: 121, + F11: 122, + F12: 123, + NUMLOCK: 144, + SEMICOLON: 186, // needs localization + DASH: 189, // needs localization + EQUALS: 187, // needs localization + COMMA: 188, // needs localization + PERIOD: 190, // needs localization + SLASH: 191, // needs localization + APOSTROPHE: 192, // needs localization + SINGLE_QUOTE: 222, // needs localization + OPEN_SQUARE_BRACKET: 219, // needs localization + BACKSLASH: 220, // needs localization + CLOSE_SQUARE_BRACKET: 221, // needs localization + WIN_KEY: 224, + MAC_FF_META: 224, // Firefox (Gecko) fires this for the meta key instead of 91 + WIN_IME: 229 +}; + + +/*! + * Returns true if the key fires a keypress event in the current browser. + * + * Accoridng to MSDN [1] IE only fires keypress events for the following keys: + * - Letters: A - Z (uppercase and lowercase) + * - Numerals: 0 - 9 + * - Symbols: ! @ # $ % ^ & * ( ) _ - + = < [ ] { } , . / ? \ | ' ` " ~ + * - System: ESC, SPACEBAR, ENTER + * + * That's not entirely correct though, for instance there's no distinction + * between upper and lower case letters. + * + * [1] http://msdn2.microsoft.com/en-us/library/ms536939(VS.85).aspx) + * + * Safari is similar to IE, but does not fire keypress for ESC. + * + * Additionally, IE6 does not fire keydown or keypress events for letters when + * the control or alt keys are held down and the shift key is not. IE7 does + * fire keydown in these cases, though, but not keypress. + * + * @param keyCode A key code. + * @param opt_heldKeyCode Key code of a currently-held key. + * @param opt_shiftKey Whether the shift key is held down. + * @param opt_ctrlKey Whether the control key is held down. + * @param opt_altKey Whether the alt key is held down. + * @return Returns YES if it's a key that fires a keypress event. + */ +CPKeyCodes.firesKeyPressEvent = function(keyCode, opt_heldKeyCode, opt_shiftKey, opt_ctrlKey, opt_altKey) +{ + if (!CPFeatureIsCompatible(CPJavascriptRemedialKeySupport)) + return true; + + if (CPBrowserIsOperatingSystem(CPMacOperatingSystem) && opt_altKey) + return CPKeyCodes.isCharacterKey(keyCode); + + // Alt but not AltGr which is represented as Alt+Ctrl. + if (opt_altKey && !opt_ctrlKey) + return false; + + // Saves Ctrl or Alt + key for IE7, which won't fire keypress. + if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine) && !opt_shiftKey && (opt_ctrlKey || opt_altKey)) + return false; + + // When Ctrl+ is held in IE, it only fires a keypress once, but it + // continues to fire keydown events as the event repeats. + if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine) && opt_ctrlKey && opt_heldKeyCode == keyCode) + return false; + + switch (keyCode) + { + case CPKeyCodes.ENTER: return true; + case CPKeyCodes.ESC: return !CPBrowserIsEngine(CPWebKitBrowserEngine); + } + + return CPKeyCodes.isCharacterKey(keyCode); +}; + + +/*! + * Test for whether or not a given keyCode represents a character key. + * + * @param keyCode A key code. + * @return Returns YES if the keyCode is a character key. + */ +CPKeyCodes.isCharacterKey = function(keyCode) +{ + if (keyCode >= CPKeyCodes.ZERO && keyCode <= CPKeyCodes.NINE) + return true; + + if (keyCode >= CPKeyCodes.NUM_ZERO && keyCode <= CPKeyCodes.NUM_MULTIPLY) + return true; + + if (keyCode >= CPKeyCodes.A && keyCode <= CPKeyCodes.Z) + return true; + + switch (keyCode) + { + case CPKeyCodes.SPACE: + case CPKeyCodes.QUESTION_MARK: + case CPKeyCodes.NUM_PLUS: + case CPKeyCodes.NUM_MINUS: + case CPKeyCodes.NUM_PERIOD: + case CPKeyCodes.NUM_DIVISION: + case CPKeyCodes.SEMICOLON: + case CPKeyCodes.DASH: + case CPKeyCodes.EQUALS: + case CPKeyCodes.COMMA: + case CPKeyCodes.PERIOD: + case CPKeyCodes.SLASH: + case CPKeyCodes.APOSTROPHE: + case CPKeyCodes.SINGLE_QUOTE: + case CPKeyCodes.OPEN_SQUARE_BRACKET: + case CPKeyCodes.BACKSLASH: + case CPKeyCodes.CLOSE_SQUARE_BRACKET: + return true; + + default: + return false; + } +} diff --git a/Objective-J/CommonJS/bin/cplutil b/Objective-J/CommonJS/bin/cplutil index f9ef478ac..194095d2b 100755 --- a/Objective-J/CommonJS/bin/cplutil +++ b/Objective-J/CommonJS/bin/cplutil @@ -8,12 +8,12 @@ function printUsage() print("this is where you say the usage"); } -function main() +exports.main = function(args) { - // FIXME: ARGS - system.args.shift(); + // TODO: args parser + args.shift(); - if (system.args.length < 1) + if (args.length < 1) return printUsage(); var allFiles = NO, @@ -23,11 +23,11 @@ function main() outExtension = nil; index = 0, - count = system.args.length; + count = args.length; for (; index < count; ++index) { - var argument = system.args[index]; + var argument = args[index]; if (argument.charAt(0) === '-' && !allFiles) { @@ -35,13 +35,13 @@ function main() return printUsage(); else if (argument === "-convert") - format = system.args[++index]; + format = args[++index]; else if (argument === "-o") - outPath = system.args[++index]; + outPath = args[++index]; else if (argument === "-e") - outExtension = system.args[++index]; + outExtension = args[++index]; else if (argument === "--") allFiles = YES; @@ -50,7 +50,7 @@ function main() return printUsage(); } else - filePaths.push(system.args[index]); + filePaths.push(args[index]); } index = 0; @@ -76,4 +76,5 @@ function main() } } -main(); +if (require.main == module.id) + exports.main(system.args); diff --git a/Objective-J/CommonJS/lib/objective-j.js b/Objective-J/CommonJS/lib/objective-j.js index f42cc5b1a..5927271db 100644 --- a/Objective-J/CommonJS/lib/objective-j.js +++ b/Objective-J/CommonJS/lib/objective-j.js @@ -1,6 +1,6 @@ var FILE = require("file"); -var window = require("browser/window"); +var window = exports.window = require("browser/window"); if (system.engine === "rhino") { @@ -104,37 +104,26 @@ with (window) exports.IS_FILE = function(aFragment) { return (aFragment.type & FRAGMENT_FILE); } exports.IS_LOCAL = function(aFragment) { return (aFragment.type & FRAGMENT_LOCAL); } exports.IS_IMPORT = function(aFragment) { return (aFragment.type & FRAGMENT_IMPORT); } - -/* - 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) + if (args && args.length > 1) { - 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()); - + var arg0 = args.slice(0,1), + argv = args.slice(1); + + while (argv.length && argv[0].indexOf('-I') === 0) + OBJJ_INCLUDE_PATHS = argv.shift().substr(2).split(':').concat(OBJJ_INCLUDE_PATHS); + + var mainFilePath = FILE.canonical(argv.shift()); + objj_import(mainFilePath, YES, function() { if (typeof main === "function") - main.apply(main, args); + main(arg0.concat(argv)); }); + + require("browser/timeout").serviceTimeouts(); } else { @@ -155,8 +144,6 @@ exports.run = function(args) require("browser/timeout").serviceTimeouts(); } } - - require("browser/timeout").serviceTimeouts(); } // synchronously evals Objective-J code diff --git a/Objective-J/CommonJS/lib/objective-j/compiler.js b/Objective-J/CommonJS/lib/objective-j/compiler.js index a5c88233e..b6462a17f 100644 --- a/Objective-J/CommonJS/lib/objective-j/compiler.js +++ b/Objective-J/CommonJS/lib/objective-j/compiler.js @@ -183,7 +183,7 @@ exports.compile = function(aFilePath, flags) exports.main = function(args) { - // FIXME: ARGS + // TODO: args parser args.shift(); var resolved = resolveFlags(args), @@ -200,4 +200,4 @@ exports.main = function(args) } if (require.main == module.id) - exports.main(system.args); \ No newline at end of file + exports.main(system.args); diff --git a/Tools/Utilities/bridge.js b/Tools/Utilities/bridge.js deleted file mode 100644 index 617b4b199..000000000 --- a/Tools/Utilities/bridge.js +++ /dev/null @@ -1,676 +0,0 @@ -if (typeof debug == "undefined") - debug = false; - -//window - -if (!this.window) - this.window = this; - -// DOMParser - -/*function DOMParser() {}; -DOMParser.prototype.parseFromString = function(text, contentType) { - return new DOMDocument( - new Packages.org.xml.sax.InputSource( - new Packages.java.io.StringReader(text))); -};*/ - -// Image - -function Image() { } - -// print, alert, prompt, confirm - -if (!this.print) -{ - if (this.Packages) - { - this.print = function(object) - { - Packages.java.lang.System.out.println(String(object)); - } - } -} - -window.alert = function(obj) -{ - if (this.print) - print(String(obj)); -} -// FIXME: prompt user for response? -window.confirm = function(obj) -{ - window.alert(obj); - return true; -} -window.prompt = function(obj) -{ - window.alert(obj); - return ""; -} - -// setTimeout, setInterval, clearTimeout, clearInterval - -// This implementation is single-threaded (like browsers) but requires a call to serviceTimeouts() -// Also includes beginning of a multithreaded implementation (commented out) - -window.setNativeTimeout = function(callback, delay) -{ - return _scheduleTimeout(callback, delay, false); -} - -window.setTimeout = window.setNativeTimeout; - -window.setNativeInterval = function(callback, delay) -{ - return _scheduleTimeout(callback, delay, true); -} - -window.setInterval = window.setInterval; - -window.clearTimeout = function(id) -{ - if (_timeouts[id]) - _timeouts[id] = null; -} -window.clearInterval = window.clearTimeout; - -var _nextId = 0, - _timeouts = {}, - _pendingTimeouts = []; - -var _scheduleTimeout = function(callback, delay, repeat) -{ - var date = new Date(new Date().getTime() + delay); - - if (typeof callback == "function") - var func = callback; - else if (typeof callback == "string") - var func = new Function(callback); - else - return; - - var timeout = { - callback: func, - date: date, - repeat: repeat, - interval: delay, - id : _nextId++ - } - - _timeouts[timeout.id] = timeout; - _pendingTimeouts.push(timeout); - -// if (!_timersBlock) -// serviceTimeouts(); - - return timeout.id; -} - -var _sortTimeouts = function() -{ - -} - -//var _timersBlock = false, -// _timerThread = null, -// _nextTimeout = null; - -function serviceTimeouts() -{ - while (_pendingTimeouts.length > 0) - { - _pendingTimeouts = _pendingTimeouts.sort(function (a,b) { return a.date - b.date; }); - - var timeout = _pendingTimeouts.shift(); - if (_timeouts[timeout.id]) - { - var wait = timeout.date - new Date(); - - if (wait > 0) - { - //if (_timersBlock) - //{ - Packages.java.lang.Thread.sleep(wait); - //} - //else - //{ - // _pendingTimeouts.splice(0, 0, timeout); - // - // if (!_nextTimeout || _nextTimeout > timeout.date) - // { - // _nextTimeout = timeout.date; - // - // - // _timerThread = new java.lang.Thread(new java.lang.Runnable({ - // run: function() { - // Packages.java.lang.Thread.sleep(wait); - // _nextTimeout = null; - // serviceTimeouts(); - // } - // })); - // - // _timerThread.start(); - // } - // - // return; - //} - } - - // perform the callback - timeout.callback(); - - // if its an interval, reschedule it, otherwise clear it - if (timeout.repeat) - { - var now = new Date(), - proposed = new Date(timeout.date.getTime() + timeout.interval); - timeout.date = (proposed < now) ? now : proposed; - _pendingTimeouts.push(timeout); - } - else - _timeouts[timeout.id] = null; - } - } -} - -// load - -if (!this.load) -{ - if (debug) - alert("Setting up 'load()'"); - - this.load = function(path) - { - var contents = readFile(path); - if (typeof Packages !== "undefined") - return Packages.org.mozilla.javascript.Context.getCurrentContext().evaluateString(window, contents, path, 0, null); - else - return eval(contents); - } -} - -// readFile - -if (!this.readFile) -{ - if (this.File) - { - if (debug) - alert("Setting up 'readFile()' for SpiderMonkey"); - - this.readFile = function(path) - { - var f = new File(path); - - if (!f.canRead) - { - if (debug) - alert("can't read: " + f.path); - - return ""; - } - - if (debug) - alert("reading: " + f.path); - - f.open("read", "text"); - - var result = f.readAll().join("\n"); - - f.close(); - - return result; - } - } - else if (this.Packages) - { - if (debug) - alert("Setting up 'readFile()' for Rhino"); - - this.readFile = function(path, characterCoding) - { - var f = new Packages.java.io.File(path); - - if (!f.canRead()) - { - if (debug) - alert("can't read: " + f.path); - - return ""; - } - - if (debug) - alert("reading: " + f.getAbsolutePath()); - - var fis = new Packages.java.io.FileInputStream(f), - b = Packages.java.lang.reflect.Array.newInstance(Packages.java.lang.Byte.TYPE, fis.available()); - - fis.read(b); - fis.close(); - - if (characterCoding) - return String(new Packages.java.lang.String(b, characterCoding)); - else - return String(new Packages.java.lang.String(b)); - } - } - else - { - alert("Warning: No 'readFile' implementation available.") - } -} - -var hex_lookup = "0123456789abcdef"; -function bytesToHexString(buf) -{ - var buffer = ""; - for (var i = 0 ; i < buf.length; i++) - buffer += hex_lookup[(buf[i] >> 4) & 0x0F] + hex_lookup[buf[i] & 0x0F]; - return buffer; -} - -// Rhino utilities -if (this.Packages) { - if (debug) - alert("Setting up Rhino utilties"); - - jsArrayToJavaArray = function(js_array, type) - { - var java_class = null; - var java_converter = null; - - switch (type || ((js_array && js_array.length > 0) && typeof js_array[0])) - { - case "string": - case "String": - java_class = Packages.java.lang.String; - java_converter = Packages.java.lang.String.valueOf; - break; - case "Boolean": - java_class = Packages.java.lang.Boolean; - java_converter = Packages.java.lang.Boolean.valueOf; - break; - case "boolean": - java_class = Packages.java.lang.Boolean.TYPE; - java_converter = function(input) { return Packages.java.lang.Boolean.valueOf(input).booleanValue(); }; - break; - default: - return null; - } - - if (js_array && js_array.length > 0) - { - var java_array = Packages.java.lang.reflect.Array.newInstance(java_class, js_array.length); - for (var i = 0; i < js_array.length; i++) - java_array[i] = java_converter ? java_converter(js_array[i]) : js_array[i]; - return java_array; - } - - return Packages.java.lang.reflect.Array.newInstance(java_class, 0); - } - - jsObjectToJavaHashMap = function(js_object) - { - var map = Packages.java.util.HashMap(); - for (var i in js_object) - map.put(i, js_object[i]); - return map; - } - - objj_console = function() - { - var br = new Packages.java.io.BufferedReader(new Packages.java.io.InputStreamReader(Packages.java.lang.System["in"], "UTF-8")); - - keepgoing = true; - while (keepgoing) - { - 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(); - } - - serviceTimeouts(); - } catch (e) { - print(e); - } - } - }; - - var _documentBuilderFactory = Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance(); - // setValidating to false doesn't seem to prevent it from downloading the DTD, but lets do it anyway - _documentBuilderFactory.setValidating(false); - - _documentBuilder = _documentBuilderFactory.newDocumentBuilder(); - // prevent the Java XML parser from downloading the plist DTD from Apple every time we parse a plist - _documentBuilder.setEntityResolver(new Packages.org.xml.sax.EntityResolver({ - resolveEntity: function(publicId, systemId) { - //Packages.java.lang.System.out.println("publicId=" + publicId + " systemId=" + systemId); - - // TODO: return a local copy of the DTD? - if (String(systemId) == "http://www.apple.com/DTDs/PropertyList-1.0.dtd") - return new Packages.org.xml.sax.InputSource(new Packages.java.io.StringReader("")); - - return null; - } - })); - // throw an exception on error - _documentBuilder.setErrorHandler(function(exception, methodName) { - throw exception; - }); - - copyInputStreamToOutputStream = function(is, os) - { - var buf = Packages.java.lang.reflect.Array.newInstance(Packages.java.lang.Byte.TYPE, 1024*10); - var len = 0; - while ((len = is.read(buf)) != -1) - { - os.write(buf, 0, len); - } - } - var lineEnd = "\r\n"; - var twoHyphens = "--"; - var boundary = "----------------------------b453b5d52446"; - //var boundary = "----CappuccinoBoundary" + (new Date().getTime()); - multipartRequest = function(method, url, headers, parts) - { - var bufferSize = 1024*10, - buffer = Packages.java.lang.reflect.Array.newInstance(Packages.java.lang.Byte.TYPE, bufferSize); - - var url = new Packages.java.net.URL(url), - connection = url.openConnection(); - - connection.setDoOutput(true); - connection.setDoInput(true); - connection.setRequestMethod(method); - - for (var i in headers) - { - print(i+":"+headers[i]); - connection.setRequestProperty(i, headers[i]); - } - - connection.setRequestProperty("Content-Type", "multipart/form-data; boundary="+ boundary); - - var output = new Packages.java.io.DataOutputStream(connection.getOutputStream()); - - for (var i = 0; parts && i < parts.length; i++) - { - var part = parts[i]; - - output.writeBytes(twoHyphens + boundary + lineEnd); - - if (part.headers) - { - for (var header in part.headers) - { - output.writeBytes(header +": " + part.headers[header] + lineEnd); - } - } - output.writeBytes(lineEnd); - - if (part.data) - { - output.writeBytes(part.data); - } - else if (part.stream) - { - var n; - while ((n = part.stream.read(buffer, 0, bufferSize)) > 0) - { - output.write(buffer, 0, n) - } - } - - output.writeBytes(lineEnd); - } - - output.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); - output.flush(); - output.close(); - - var buffer, - input = new Packages.java.io.DataInputStream(connection.getInputStream()), - result = new Packages.java.lang.StringBuffer(); - - while (null != (buffer = input.readLine())) - result.append(buffer); - - input.close(); - - return String(result.toString()); - } - - parseXMLString = function(string) { - return (_documentBuilder.parse( - new Packages.org.xml.sax.InputSource( - new Packages.java.io.StringReader(string))).getDocumentElement()); - } -} - -// Environment variables - -function getenv(variable) -{ - if (this.Packages) - return String(Packages.java.lang.System.getenv().get(variable) || "") || null; - else if (this.environment) - return environment[variable] || null; - return null; -} - - -// XMLHttpRequest - -function XMLHttpRequest() -{ - this.readyState = 0; - this.responseText = ""; - this.responseXML = null; - this.status = null; - this.statusText = null; - - this.onreadystatechange = null; - - this.method = null; - this.url = null; - this.async = null; - this.username = null; - this.password = null; -} -XMLHttpRequest.prototype.abort = function() -{ - this.readyState = 0; -} -XMLHttpRequest.prototype.open = function(method, url, async, username, password) -{ - this.readyState = 1; - - this.method = method; - this.url = url; - this.async = async; - this.username = username; - this.password = password; -} -XMLHttpRequest.prototype.send = function(body) -{ - this.readyState = 3; - - this.responseText = ""; - this.responseXML = null; - - try - { - this.responseText = readFile(this.url, "UTF-8"); // FIXME: should we really assume this is UTF-8? - - if (debug) - alert("xhr response: " + this.url + " (length="+this.responseText.length+")"); - } - catch (e) - { - if (debug) - alert("xhr exception: " + this.url); - this.responseText = ""; - this.responseXML = null; - } - - if (this.responseText.length > 0) - { - try - { - this.responseXML = _documentBuilder.parse(new Packages.org.xml.sax.InputSource(new Packages.java.io.StringReader(this.responseText))); - } - catch (e) - { - this.responseXML = null; - } - this.status = 200; - } - else { - if (debug) - alert("xhr empty: " + this.url); - this.status = 404; - } - - this.readyState = 4; - - if (this.onreadystatechange) - { - if (this.async) - setNativeTimeout(this.onreadystatechange, 0); - else - this.onreadystatechange(); - } -} -XMLHttpRequest.prototype.getResponseHeader = function(header) -{ - return (this.readyState < 3) ? "" : ""; -} -XMLHttpRequest.prototype.getAllResponseHeaders = function() -{ - return (this.readyState < 3) ? null : ""; -} -XMLHttpRequest.prototype.setRequestHeader = function(name, value) -{ -} - -objj_request_xmlhttp = function() -{ - return new XMLHttpRequest(); -} - - -OBJJ_HOME = getenv("OBJJ_HOME"); -if (!OBJJ_HOME) -{ - OBJJ_HOME = "/usr/local/share/objj"; - alert("OBJJ_HOME environment variable not set, defaulting to " + OBJJ_HOME); -} - -function exec(/*Array*/ command, /*Boolean*/ showOutput) -{ - var line = "", - output = "", - - process = Packages.java.lang.Runtime.getRuntime().exec(command),//jsArrayToJavaArray(command)); - reader = new Packages.java.io.BufferedReader(new Packages.java.io.InputStreamReader(process.getInputStream())); - - while (line = reader.readLine()) - { - if (showOutput) - Packages.java.lang.System.out.println(line); - - output += line + '\n'; - } - - reader = new Packages.java.io.BufferedReader(new Packages.java.io.InputStreamReader(process.getErrorStream())); - - while (line = reader.readLine()) - Packages.java.lang.System.out.println(line); - - try - { - if (process.waitFor() != 0) - Packages.java.lang.System.err.println("exit value = " + process.exitValue()); - } - catch (anException) - { - Packages.java.lang.System.err.println(anException); - } - - return output; -} - - -function getFiles(/*File*/ sourceDirectory, /*nil|String|Array*/ extensions, /*Array*/ exclusions) -{ - var matches = [], - files = sourceDirectory.listFiles(), - hasMultipleExtensions = typeof extensions !== "string"; - - if (files) - { - var index = 0, - count = files.length; - - for (; index < count; ++index) - { - var file = files[index].getCanonicalFile(), - name = String(file.getName()), - isValidExtension = !extensions; - - if (exclusions && fileArrayContainsFile(exclusions, file)) - continue; - - if (!isValidExtension) - if (hasMultipleExtensions) - { - var extensionCount = extensions.length; - - while (extensionCount-- && !isValidExtension) - { - var extension = extensions[extensionCount]; - - if (name.substring(name.length - extension.length - 1) === ("." + extension)) - isValidExtension = true; - } - } - else if (name.substring(name.length - extensions.length - 1) === ("." + extensions)) - isValidExtension = true; - - if (isValidExtension) - matches.push(file); - - if (file.isDirectory()) - matches = matches.concat(getFiles(file, extensions, exclusions)); - } - } - - return matches; -} diff --git a/Tools/Utilities/bundle.js b/Tools/Utilities/bundle.js deleted file mode 100644 index 73ea34928..000000000 --- a/Tools/Utilities/bundle.js +++ /dev/null @@ -1,131 +0,0 @@ - -function readContentsOfFile(/*File*/ aFile) -{ - var reader = new BufferedReader(new FileReader(aFile)), - fileContents = ""; - - // Get contents of the file - while (reader.ready()) - fileContents += reader.readLine() + '\n'; - - reader.close(); - - return fileContents; -} - -function writeContentsToFile(/*String*/ contents, /*File*/ aFile) -{ - var writer = new BufferedWriter(new FileWriter(aFile)); - - writer.write(contents); - - writer.close(); -} - -function readPlist(/*File*/ aFile) -{ - var fileContents = readFile(aFile); - - var data = new objj_data(); - data.string = fileContents; - - return new CPPropertyListCreateFromData(data); -} - -function readBundle(/*File*/ aFile, /*Boolean*/ shouldDecompile) -{ - var bundlePath = typeof aFile === "string" ? new File(aFile).getCanonicalPath() : aFile.getCanonicalPath(), - infoPath = bundlePath + "/Info.plist"; - - //err - var bundle = new objj_bundle(); - - bundle.path = infoPath; - bundle.info = readPlist(infoPath); - bundle._staticFilePaths = dictionary_getValue(bundle.info, "CPBundleReplacedFiles"); - - if (bundle._staticFilePaths.length) - { - bundle._staticContentPath = staticContentPath = bundlePath + '/' + dictionary_getValue(bundle.info, "CPBundleExecutable"); - - //err - - bundle._staticContent = readFile(staticContentPath); - - if (shouldDecompile) - bundle.files = objj_decompile(bundle._staticContent, bundle); - } - else - bundle._staticContent = ""; - - return bundle; -} - -function importFiles(files, aCallback) -{ - - if (files.length === 0) - aCallback(); - else - { - var file = files.shift(); - - if (typeof file === "string") - file = new File(file); - - objj_import(file.getCanonicalPath(), YES, function() { importFiles(files, aCallback) }); - } - return; - - var context = new objj_context(); - - if (aCallback) - context.didCompleteCallback = aCallback; - - var count = files.length; - - while (count--) - { - var file = files[count]; - - if (typeof file === "string") - file = new File(file); - - context.pushFragment(fragment_create_file(file, new objj_bundle(""), YES, NULL)); - } - - context.evaluate(); -} - -function loadFrameworks(frameworkPaths, aCallback) -{ - if (frameworkPaths.length === 0) - return aCallback(); - - var frameworkPath = frameworkPaths.shift(), - - infoPlist = new File(frameworkPath + "/Info.plist"); - - if (!infoPlist.exists()) - { - java.lang.System.out.println("'" + frameworkPath + "' is not a framework or could not be found."); - java.lang.System.exit(1); - } - - var infoDictionary = readPlist(new File(frameworkPath + "/Info.plist")); - - if (dictionary_getValue(infoDictionary, "CPBundlePackageType") !== "FMWK") - { - java.lang.System.out.println("'" + frameworkPath + "' is not a framework ."); - java.lang.System.exit(1); - } - - var files = dictionary_getValue(infoDictionary, "CPBundleReplacedFiles"), - index = 0, - count = files.length; - - for (; index < count; ++index) - files[index] = String(frameworkPath + '/' + files[index]); - - importFiles(files, function() { loadFrameworks(frameworkPaths, aCallback) }); -} diff --git a/Tools/Utilities/file.js b/Tools/Utilities/file.js deleted file mode 100644 index 990e37e33..000000000 --- a/Tools/Utilities/file.js +++ /dev/null @@ -1,99 +0,0 @@ - - -function readFile(/*File*/ aFile) -{ - var reader = new BufferedReader(new FileReader(aFile)), - fileContents = ""; - - // Get contents of the file - while (reader.ready()) - fileContents += reader.readLine() + '\n'; - - reader.close(); - - return fileContents; -} - -function writeContentsToFile(/*String*/ contents, /*File*/ aFile) -{ - -} - -function readPlist(/*File*/ aFile) -{ - var fileContents = readFile(aFile); - - var data = new objj_data(); - data.string = fileContents; - - return new CPPropertyListCreateFromData(data); -} - -function importFiles(files, aCallback) -{ - - if (files.length === 0) - aCallback(); - else - { - var file = files.shift(); - - if (typeof file === "string") - file = new File(file); - - objj_import(String(file.getCanonicalPath()), YES, function() { importFiles(files, aCallback) }); - } - return; - - var context = new objj_context(); - - if (aCallback) - context.didCompleteCallback = aCallback; - - var count = files.length; - - while (count--) - { - var file = files[count]; - - if (typeof file === "string") - file = new File(file); - - context.pushFragment(fragment_create_file(file, new objj_bundle(""), YES, NULL)); - } - - context.evaluate(); -} - -function loadFrameworks(frameworkPaths, aCallback) -{ - if (frameworkPaths.length === 0) - return aCallback(); - - var frameworkPath = frameworkPaths.shift(), - - infoPlist = new File(frameworkPath + "/Info.plist"); - - if (!infoPlist.exists()) - { - java.lang.System.out.println("'" + frameworkPath + "' is not a framework or could not be found."); - java.lang.System.exit(1); - } - - var infoDictionary = readPlist(new File(frameworkPath + "/Info.plist")); - - if (dictionary_getValue(infoDictionary, "CPBundlePackageType") !== "FMWK") - { - java.lang.System.out.println("'" + frameworkPath + "' is not a framework ."); - java.lang.System.exit(1); - } - - var files = dictionary_getValue(infoDictionary, "CPBundleReplacedFiles"), - index = 0, - count = files.length; - - for (; index < count; ++index) - files[index] = String(frameworkPath + '/' + files[index]); - - importFiles(files, function() { loadFrameworks(frameworkPaths, aCallback) }); -} diff --git a/Tools/Utilities/js.jar b/Tools/Utilities/js.jar deleted file mode 100644 index 2f4fad90c..000000000 Binary files a/Tools/Utilities/js.jar and /dev/null differ diff --git a/Tools/capp/main.j b/Tools/capp/main.j index 0d4715ee2..0d48ae1e3 100644 --- a/Tools/capp/main.j +++ b/Tools/capp/main.j @@ -5,17 +5,19 @@ @import "Generate.j" -function main() +function main(args) { - if (system.args.length < 1) + args.shift(); + + if (args.length < 1) return printUsage(); var index = 0, - count = system.args.length; + count = args.length; for (; index < count; ++index) { - var argument = system.args[index]; + var argument = args[index]; switch (argument) { @@ -25,9 +27,9 @@ function main() case "-h": case "--help": return printUsage(); - case "config": return config.apply(this, system.args.slice(index + 1)); + case "config": return config.apply(this, args.slice(index + 1)); - case "gen": return gen.apply(this, system.args.slice(index + 1)); + case "gen": return gen.apply(this, args.slice(index + 1)); default: print("unknown command " + argument); } diff --git a/Tools/nib2cib/main.j b/Tools/nib2cib/main.j index aaba68830..d41317cdb 100644 --- a/Tools/nib2cib/main.j +++ b/Tools/nib2cib/main.j @@ -69,11 +69,14 @@ function loadFrameworks(frameworkPaths, aCallback) aCallback(); } -function main() +function main(args) { - var count = arguments.length; + // TODO: args parser + args.shift(); + + var count = args.length; - if (count < 1) + if (count < 2) return printUsage(); var index = 0, @@ -83,7 +86,7 @@ function main() for (; index < count; ++index) { - switch(arguments[index]) + switch(args[index]) { case "-help": case "--help": printUsage(); @@ -92,16 +95,16 @@ function main() case "--mac": [converter setFormat:NibFormatMac]; break; - case "-F": frameworkPaths.push(arguments[++index]); + case "-F": frameworkPaths.push(args[++index]); break; - case "-R": [converter setResourcesPath:arguments[++index]]; + case "-R": [converter setResourcesPath:args[++index]]; break; default: if ([converter inputPath]) - [converter setOutputPath:arguments[index]]; + [converter setOutputPath:args[index]]; else - [converter setInputPath:arguments[index]]; + [converter setInputPath:args[index]]; } } diff --git a/Tools/press/env.js b/Tools/press/env.js deleted file mode 100644 index 0466201b4..000000000 --- a/Tools/press/env.js +++ /dev/null @@ -1,767 +0,0 @@ -/* - * Pure JavaScript Browser Environment - * By John Resig - * Copyright 2008 John Resig, under the MIT License - */ - -// The window Object -var window = this; - -(function(){ - - // Browser Navigator - - window.navigator = { - get userAgent(){ - return "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3"; - } - }; - - var curLocation = (new java.io.File("./")).toURL(); - - window.__defineSetter__("location", function(url){ - var xhr = new XMLHttpRequest(); - xhr.open("GET", url); - xhr.onreadystatechange = function(){ - curLocation = new java.net.URL( curLocation, url ); - window.document = xhr.responseXML; - - var event = document.createEvent(); - event.initEvent("load"); - window.dispatchEvent( event ); - }; - xhr.send(); - }); - - window.__defineGetter__("location", function(url){ - return { - get protocol(){ - return curLocation.getProtocol() + ":"; - }, - get href(){ - return curLocation.toString(); - }, - toString: function(){ - return this.href; - } - }; - }); - - // Timers - - var timers = []; - - window.setTimeout = function(fn, time){ - var num; - return num = setInterval(function(){ - fn(); - clearInterval(num); - }, time); - }; - - window.setInterval = function(fn, time){ - var num = timers.length; - - timers[num] = new java.lang.Thread(new java.lang.Runnable({ - run: function(){ - while (true){ - java.lang.Thread.currentThread().sleep(time); - fn(); - } - } - })); - - timers[num].start(); - - return num; - }; - - window.clearInterval = function(num){ - if ( timers[num] ) { - timers[num].stop(); - delete timers[num]; - } - }; - - // Window Events - - var events = [{}]; - - window.addEventListener = function(type, fn){ - if ( !this.uuid || this == window ) { - this.uuid = events.length; - events[this.uuid] = {}; - } - - if ( !events[this.uuid][type] ) - events[this.uuid][type] = []; - - if ( events[this.uuid][type].indexOf( fn ) < 0 ) - events[this.uuid][type].push( fn ); - }; - - window.removeEventListener = function(type, fn){ - if ( !this.uuid || this == window ) { - this.uuid = events.length; - events[this.uuid] = {}; - } - - if ( !events[this.uuid][type] ) - events[this.uuid][type] = []; - - events[this.uuid][type] = - events[this.uuid][type].filter(function(f){ - return f != fn; - }); - }; - - window.dispatchEvent = function(event){ - if ( event.type ) { - if ( this.uuid && events[this.uuid][event.type] ) { - var self = this; - - events[this.uuid][event.type].forEach(function(fn){ - fn.call( self, event ); - }); - } - - if ( this["on" + event.type] ) - this["on" + event.type].call( self, event ); - } - }; - - // DOM Document - - window.DOMDocument = function(file){ - this._file = file; - this._dom = Packages.javax.xml.parsers. - DocumentBuilderFactory.newInstance() - .newDocumentBuilder().parse(file); - - if ( !obj_nodes.containsKey( this._dom ) ) - obj_nodes.put( this._dom, this ); - }; - - DOMDocument.prototype = { - get nodeType(){ - return 9; - }, - createTextNode: function(text){ - return makeNode( this._dom.createTextNode( - text.replace(/&/g, "&").replace(//g, ">")) ); - }, - createElement: function(name){ - return makeNode( this._dom.createElement(name.toLowerCase()) ); - }, - getElementsByTagName: function(name){ - return new DOMNodeList( this._dom.getElementsByTagName( - name.toLowerCase()) ); - }, - getElementsByName: function(name){ - var elems = this._dom.getElementsByTagName("*"), ret = []; - ret.item = function(i){ return this[i]; }; - ret.getLength = function(){ return this.length; }; - - for ( var i = 0; i < elems.length; i++ ) { - var elem = elems.item(i); - if ( elem.getAttribute("name") == name ) - ret.push( elem ); - } - - return new DOMNodeList( ret ); - }, - getElementById: function(id){ - var elems = this._dom.getElementsByTagName("*"); - - for ( var i = 0; i < elems.length; i++ ) { - var elem = elems.item(i); - if ( elem.getAttribute("id") == id ) - return makeNode(elem); - } - - return null; - }, - get body(){ - return this.getElementsByTagName("body")[0]; - }, - get documentElement(){ - return makeNode( this._dom.getDocumentElement() ); - }, - get ownerDocument(){ - return null; - }, - addEventListener: window.addEventListener, - removeEventListener: window.removeEventListener, - dispatchEvent: window.dispatchEvent, - get nodeName() { - return "#document"; - }, - importNode: function(node, deep){ - return makeNode( this._dom.importNode(node._dom, deep) ); - }, - toString: function(){ - return "Document" + (typeof this._file == "string" ? - ": " + this._file : ""); - }, - get innerHTML(){ - return this.documentElement.outerHTML; - }, - - get defaultView(){ - return { - getComputedStyle: function(elem){ - return { - getPropertyValue: function(prop){ - prop = prop.replace(/\-(\w)/g,function(m,c){ - return c.toUpperCase(); - }); - var val = elem.style[prop]; - - if ( prop == "opacity" && val == "" ) - val = "1"; - - return val; - } - }; - } - }; - }, - - createEvent: function(){ - return { - type: "", - initEvent: function(type){ - this.type = type; - } - }; - } - }; - - function getDocument(node){ - return obj_nodes.get(node); - } - - // DOM NodeList - - window.DOMNodeList = function(list){ - this._dom = list; - this.length = list.getLength(); - - for ( var i = 0; i < this.length; i++ ) { - var node = list.item(i); - this[i] = makeNode( node ); - } - }; - - DOMNodeList.prototype = { - toString: function(){ - return "[ " + - Array.prototype.join.call( this, ", " ) + " ]"; - }, - get outerHTML(){ - return Array.prototype.map.call( - this, function(node){return node.outerHTML;}).join(''); - } - }; - - // DOM Node - - window.DOMNode = function(node){ - this._dom = node; - }; - - DOMNode.prototype = { - get nodeType(){ - return this._dom.getNodeType(); - }, - get nodeValue(){ - return this._dom.getNodeValue(); - }, - get nodeName() { - return this._dom.getNodeName(); - }, - get childNodes(){ - return new DOMNodeList( this._dom.getChildNodes() ); - }, - cloneNode: function(deep){ - return makeNode( this._dom.cloneNode(deep) ); - }, - get ownerDocument(){ - return getDocument( this._dom.ownerDocument ); - }, - get documentElement(){ - return makeNode( this._dom.documentElement ); - }, - get parentNode() { - return makeNode( this._dom.getParentNode() ); - }, - get nextSibling() { - return makeNode( this._dom.getNextSibling() ); - }, - get previousSibling() { - return makeNode( this._dom.getPreviousSibling() ); - }, - toString: function(){ - return '"' + this.nodeValue + '"'; - }, - get outerHTML(){ - return this.nodeValue; - } - }; - - window.DOMComment = function(node){ - this._dom = node; - }; - - DOMComment.prototype = extend(new DOMNode(), { - get nodeType(){ - return 8; - }, - get outerHTML(){ - return ""; - } - }); - - // DOM Element - - window.DOMElement = function(elem){ - this._dom = elem; - this.style = { - get opacity(){ return this._opacity; }, - set opacity(val){ this._opacity = val + ""; } - }; - - // Load CSS info - var styles = (this.getAttribute("style") || "").split(/\s*;\s*/); - - for ( var i = 0; i < styles.length; i++ ) { - var style = styles[i].split(/\s*:\s*/); - if ( style.length == 2 ) - this.style[ style[0] ] = style[1]; - } - - if ( this.nodeName == "FORM" ) { - this.__defineGetter__("elements", function(){ - return this.getElementsByTagName("*"); - }); - - this.__defineGetter__("length", function(){ - var elems = this.elements; - for ( var i = 0; i < elems.length; i++ ) { - this[i] = elems[i]; - } - - return elems.length; - }); - } - - if ( this.nodeName == "SELECT" ) { - this.__defineGetter__("options", function(){ - return this.getElementsByTagName("option"); - }); - } - - this.defaultValue = this.value; - }; - - DOMElement.prototype = extend( new DOMNode(), { - get nodeName(){ - return this.tagName; - }, - get tagName(){ - return this._dom.getTagName().toUpperCase(); - }, - toString: function(){ - return "<" + this.tagName + (this.id ? "#" + this.id : "" ) + ">"; - }, - get outerHTML(){ - var ret = "<" + this.tagName, attr = this.attributes; - - for ( var i in attr ) - ret += " " + i + "='" + attr[i] + "'"; - - if ( this.childNodes.length || this.nodeName == "SCRIPT" ) - ret += ">" + this.childNodes.outerHTML + - ""; - else - ret += "/>"; - - return ret; - }, - - get attributes(){ - var attr = {}, attrs = this._dom.getAttributes(); - - for ( var i = 0; i < attrs.getLength(); i++ ) - attr[ attrs.item(i).nodeName ] = attrs.item(i).nodeValue; - - return attr; - }, - - get innerHTML(){ - return this.childNodes.outerHTML; - }, - set innerHTML(html){ - html = html.replace(/<\/?([A-Z]+)/g, function(m){ - return m.toLowerCase(); - }).replace(/ /g, " "); - - var nodes = this.ownerDocument.importNode( - new DOMDocument( new java.io.ByteArrayInputStream( - (new java.lang.String("" + html + "")) - .getBytes("UTF8"))).documentElement, true).childNodes; - - while (this.firstChild) - this.removeChild( this.firstChild ); - - for ( var i = 0; i < nodes.length; i++ ) - this.appendChild( nodes[i] ); - }, - - get textContent(){ - return nav(this.childNodes); - - function nav(nodes){ - var str = ""; - for ( var i = 0; i < nodes.length; i++ ) - if ( nodes[i].nodeType == 3 ) - str += nodes[i].nodeValue; - else if ( nodes[i].nodeType == 1 ) - str += nav(nodes[i].childNodes); - return str; - } - }, - set textContent(text){ - while (this.firstChild) - this.removeChild( this.firstChild ); - this.appendChild( this.ownerDocument.createTextNode(text)); - }, - - style: {}, - clientHeight: 0, - clientWidth: 0, - offsetHeight: 0, - offsetWidth: 0, - - get disabled() { - var val = this.getAttribute("disabled"); - return val != "false" && !!val; - }, - set disabled(val) { return this.setAttribute("disabled",val); }, - - get checked() { - var val = this.getAttribute("checked"); - return val != "false" && !!val; - }, - set checked(val) { return this.setAttribute("checked",val); }, - - get selected() { - if ( !this._selectDone ) { - this._selectDone = true; - - if ( this.nodeName == "OPTION" && !this.parentNode.getAttribute("multiple") ) { - var opt = this.parentNode.getElementsByTagName("option"); - - if ( this == opt[0] ) { - var select = true; - - for ( var i = 1; i < opt.length; i++ ) - if ( opt[i].selected ) { - select = false; - break; - } - - if ( select ) - this.selected = true; - } - } - } - - var val = this.getAttribute("selected"); - return val != "false" && !!val; - }, - set selected(val) { return this.setAttribute("selected",val); }, - - get className() { return this.getAttribute("class") || ""; }, - set className(val) { - return this.setAttribute("class", - val.replace(/(^\s*|\s*$)/g,"")); - }, - - get type() { return this.getAttribute("type") || ""; }, - set type(val) { return this.setAttribute("type",val); }, - - get defaultValue() { return this.getAttribute("defaultValue") || ""; }, - set defaultValue(val) { return this.setAttribute("defaultValue",val); }, - - get value() { return this.getAttribute("value") || ""; }, - set value(val) { return this.setAttribute("value",val); }, - - get src() { return this.getAttribute("src") || ""; }, - set src(val) { return this.setAttribute("src",val); }, - - get id() { return this.getAttribute("id") || ""; }, - set id(val) { return this.setAttribute("id",val); }, - - getAttribute: function(name){ - return this._dom.hasAttribute(name) ? - new String( this._dom.getAttribute(name) ) : - null; - }, - setAttribute: function(name,value){ - this._dom.setAttribute(name,value); - }, - removeAttribute: function(name){ - this._dom.removeAttribute(name); - }, - - get childNodes(){ - return new DOMNodeList( this._dom.getChildNodes() ); - }, - get firstChild(){ - return makeNode( this._dom.getFirstChild() ); - }, - get lastChild(){ - return makeNode( this._dom.getLastChild() ); - }, - appendChild: function(node){ - this._dom.appendChild( node._dom ); - }, - insertBefore: function(node,before){ - this._dom.insertBefore( node._dom, before ? before._dom : before ); - - execScripts( node ); - - function execScripts( node ) { - if ( node.nodeName == "SCRIPT" ) { - if ( !node.getAttribute("src") ) { - eval.call( window, node.textContent ); - } - } else { - var scripts = node.getElementsByTagName("script"); - for ( var i = 0; i < scripts.length; i++ ) { - execScripts( node ); - } - } - } - }, - removeChild: function(node){ - this._dom.removeChild( node._dom ); - }, - - getElementsByTagName: DOMDocument.prototype.getElementsByTagName, - - addEventListener: window.addEventListener, - removeEventListener: window.removeEventListener, - dispatchEvent: window.dispatchEvent, - - click: function(){ - var event = document.createEvent(); - event.initEvent("click"); - this.dispatchEvent(event); - }, - submit: function(){ - var event = document.createEvent(); - event.initEvent("submit"); - this.dispatchEvent(event); - }, - focus: function(){ - var event = document.createEvent(); - event.initEvent("focus"); - this.dispatchEvent(event); - }, - blur: function(){ - var event = document.createEvent(); - event.initEvent("blur"); - this.dispatchEvent(event); - }, - get contentWindow(){ - return this.nodeName == "IFRAME" ? { - document: this.contentDocument - } : null; - }, - get contentDocument(){ - if ( this.nodeName == "IFRAME" ) { - if ( !this._doc ) - this._doc = new DOMDocument( - new java.io.ByteArrayInputStream((new java.lang.String( - "")) - .getBytes("UTF8"))); - return this._doc; - } else - return null; - } - }); - - // Helper method for extending one object with another - - function extend(a,b) { - for ( var i in b ) { - var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i); - - if ( g || s ) { - if ( g ) - a.__defineGetter__(i, g); - if ( s ) - a.__defineSetter__(i, s); - } else - a[i] = b[i]; - } - return a; - } - - // Helper method for generating the right - // DOM objects based upon the type - - var obj_nodes = new java.util.HashMap(); - - function makeNode(node){ - if ( node ) { - if ( !obj_nodes.containsKey( node ) ) - obj_nodes.put( node, node.getNodeType() == 1? - new DOMElement( node ) : - node.getNodeType() == 8 ? - new DOMComment( node ) : - new DOMNode( node ) ); - - return obj_nodes.get(node); - } else - return null; - } - - // XMLHttpRequest - // Originally implemented by Yehuda Katz - - window.XMLHttpRequest = function(){ - this.headers = {}; - this.responseHeaders = {}; - }; - - XMLHttpRequest.prototype = { - open: function(method, url, async, user, password){ - this.readyState = 1; - if (async) - this.async = true; - this.method = method || "GET"; - this.url = url; - this.onreadystatechange(); - }, - setRequestHeader: function(header, value){ - this.headers[header] = value; - }, - getResponseHeader: function(header){ }, - send: function(data){ - var self = this; - - function makeRequest(){ - var url = new java.net.URL(curLocation, self.url); - - if ( url.getProtocol() == "file" ) { - if ( self.method == "PUT" ) { - var out = new java.io.FileWriter( - new java.io.File( new java.net.URI( url.toString() ) ) ), - text = new java.lang.String( data || "" ); - - out.write( text, 0, text.length() ); - out.flush(); - out.close(); - } else if ( self.method == "DELETE" ) { - var file = new java.io.File( new java.net.URI( url.toString() ) ); - file["delete"](); - } else { - var connection = url.openConnection(); - connection.connect(); - handleResponse(); - } - } else { - var connection = url.openConnection(); - - connection.setRequestMethod( self.method ); - - // Add headers to Java connection - for (var header in self.headers) - connection.addRequestProperty(header, self.headers[header]); - - connection.connect(); - - // Stick the response headers into responseHeaders - for (var i = 0; ; i++) { - var headerName = connection.getHeaderFieldKey(i); - var headerValue = connection.getHeaderField(i); - if (!headerName && !headerValue) break; - if (headerName) - self.responseHeaders[headerName] = headerValue; - } - - handleResponse(); - } - - function handleResponse(){ - self.readyState = 4; - self.status = parseInt(connection.responseCode) || undefined; - self.statusText = connection.responseMessage || ""; - - var stream = new java.io.InputStreamReader(connection.getInputStream()), - buffer = new java.io.BufferedReader(stream), line; - - while ((line = buffer.readLine()) != null) - self.responseText += line; - - self.responseXML = null; - - if ( self.responseText.match(/^\s*