/Frameworks/Debug/AppKit/browser.platform/CPDOMWindowBridge.j

http://github.com/jfahrenkrug/MapKit-HelloWorld · Unknown · 655 lines · 654 code · 1 blank · 0 comment · 0 complexity · 9ea7c74c126d1e8ff6cf3f41fa3fe680 MD5 · raw file

  1. I;21;Foundation/CPObject.jI;22;Foundation/CPRunLoop.ji;9;CPEvent.ji;17;CPCompatibility.ji;18;CPDOMWindowLayer.jc;33553;
  2. CPSharedDOMWindowBridge = nil;
  3. var ExcludedDOMElements = [];
  4. var CPDOMWindowGetFrame,
  5. CPDOMEventGetClickCount,
  6. CPDOMEventStop;
  7. {var the_class = objj_allocateClassPair(CPObject, "CPDOMWindowBridge"),
  8. meta_class = the_class.isa;class_addIvars(the_class, [new objj_ivar("_orderedWindows"), new objj_ivar("_mouseDownWindow"), new objj_ivar("_DOMWindow"), new objj_ivar("_DOMBodyElement"), new objj_ivar("_DOMFocusElement"), new objj_ivar("_windowLevels"), new objj_ivar("_windowLayers"), new objj_ivar("_frame"), new objj_ivar("_contentBounds"), new objj_ivar("_mouseIsDown"), new objj_ivar("_lastMouseUp"), new objj_ivar("_lastMouseDown"), new objj_ivar("_charCodes"), new objj_ivar("_keyCode"), new objj_ivar("_DOMEventMode"), new objj_ivar("_DOMPasteboardElement"), new objj_ivar("_pasteboardKeyDownEvent"), new objj_ivar("_overriddenEventType")]);
  9. objj_registerClassPair(the_class);
  10. objj_addClassForBundle(the_class, objj_getBundleWithPath(OBJJ_CURRENT_BUNDLE.path));
  11. class_addMethods(the_class, [new objj_method(sel_getUid("initWithFrame:"), function $CPDOMWindowBridge__initWithFrame_(self, _cmd, aFrame)
  12. { with(self)
  13. {
  14. alert("unimplemented");
  15. }
  16. }), new objj_method(sel_getUid("_initWithDOMWindow:"), function $CPDOMWindowBridge___initWithDOMWindow_(self, _cmd, aDOMWindow)
  17. { with(self)
  18. {
  19. self = objj_msgSendSuper({ receiver:self, super_class:objj_getClass("CPObject") }, "init");
  20. if (self)
  21. {
  22. _DOMWindow = aDOMWindow;
  23. _windowLevels = [];
  24. _windowLayers = objj_msgSend(CPDictionary, "dictionary");
  25. _DOMBodyElement = document.getElementsByTagName("body")[0];
  26. _DOMBodyElement.innerHTML = "";
  27. _DOMBodyElement.style.overflow = "hidden";
  28. _DOMBodyElement.style.webkitTouchCallout = "none";
  29. objj_msgSend(CPString, "_resetSize");
  30. if (document.documentElement)
  31. document.documentElement.style.overflow = "hidden";
  32. _frame = CPDOMWindowGetFrame(_DOMWindow);
  33. _contentBounds = CGRectMake(0.0, 0.0, CPRectGetWidth(_frame), CPRectGetHeight(_frame));
  34. _DOMFocusElement = document.createElement("input");
  35. _DOMFocusElement.style.position = "absolute";
  36. _DOMFocusElement.style.zIndex = "-1000";
  37. _DOMFocusElement.style.opacity = "0";
  38. _DOMFocusElement.style.filter = "alpha(opacity=0)";
  39. _DOMBodyElement.appendChild(_DOMFocusElement);
  40. _DOMPasteboardElement = document.createElement("input");
  41. _DOMPasteboardElement.style.position = "absolute";
  42. _DOMPasteboardElement.style.top = "-10000px";
  43. _DOMPasteboardElement.style.zIndex = "99";
  44. _DOMBodyElement.appendChild(_DOMPasteboardElement);
  45. _DOMPasteboardElement.blur();
  46. _charCodes = {};
  47. var theClass = objj_msgSend(self, "class"),
  48. keyEventSelector = sel_getUid("_bridgeKeyEvent:"),
  49. keyEventImplementation = class_getMethodImplementation(theClass, keyEventSelector),
  50. keyEventCallback = function (anEvent) { keyEventImplementation(self, nil, anEvent); },
  51. mouseEventSelector = sel_getUid("_bridgeMouseEvent:"),
  52. mouseEventImplementation = class_getMethodImplementation(theClass, mouseEventSelector),
  53. mouseEventCallback = function (anEvent) { mouseEventImplementation(self, nil, anEvent); },
  54. scrollEventSelector = sel_getUid("_bridgeScrollEvent:"),
  55. scrollEventImplementation = class_getMethodImplementation(theClass, scrollEventSelector),
  56. scrollEventCallback = function (anEvent) { scrollEventImplementation(self, nil, anEvent); },
  57. resizeEventSelector = sel_getUid("_bridgeResizeEvent:"),
  58. resizeEventImplementation = class_getMethodImplementation(theClass, resizeEventSelector),
  59. resizeEventCallback = function (anEvent) { resizeEventImplementation(self, nil, anEvent); },
  60. touchEventSelector = sel_getUid("_bridgeTouchEvent:"),
  61. touchEventImplementation = class_getMethodImplementation(theClass, touchEventSelector),
  62. touchEventCallback = function (anEvent) { touchEventImplementation(self, nil, anEvent); },
  63. theDocument = _DOMWindow.document;
  64. if (document.addEventListener)
  65. {
  66. _DOMWindow.addEventListener("resize", resizeEventCallback, NO);
  67. theDocument.addEventListener(CPDOMEventMouseUp, mouseEventCallback, NO);
  68. theDocument.addEventListener(CPDOMEventMouseDown, mouseEventCallback, NO);
  69. theDocument.addEventListener(CPDOMEventMouseMoved, mouseEventCallback, NO);
  70. theDocument.addEventListener(CPDOMEventKeyUp, keyEventCallback, NO);
  71. theDocument.addEventListener(CPDOMEventKeyDown, keyEventCallback, NO);
  72. theDocument.addEventListener(CPDOMEventKeyPress, keyEventCallback, NO);
  73. theDocument.addEventListener(CPDOMEventTouchStart, touchEventCallback, NO);
  74. theDocument.addEventListener(CPDOMEventTouchEnd, touchEventCallback, NO);
  75. theDocument.addEventListener(CPDOMEventTouchMove, touchEventCallback, NO);
  76. theDocument.addEventListener(CPDOMEventTouchCancel, touchEventCallback, NO);
  77. _DOMWindow.addEventListener("DOMMouseScroll", scrollEventCallback, NO);
  78. _DOMWindow.addEventListener(CPDOMEventScrollWheel, scrollEventCallback, NO);
  79. }
  80. else if(document.attachEvent)
  81. {
  82. _DOMWindow.attachEvent("onresize", resizeEventCallback);
  83. theDocument.attachEvent("on" + CPDOMEventMouseUp, mouseEventCallback);
  84. theDocument.attachEvent("on" + CPDOMEventMouseDown, mouseEventCallback);
  85. theDocument.attachEvent("on" + CPDOMEventMouseMoved, mouseEventCallback);
  86. theDocument.attachEvent("on" + CPDOMEventDoubleClick, mouseEventCallback);
  87. theDocument.attachEvent("on" + CPDOMEventKeyUp, keyEventCallback);
  88. theDocument.attachEvent("on" + CPDOMEventKeyDown, keyEventCallback);
  89. theDocument.attachEvent("on" + CPDOMEventKeyPress, keyEventCallback);
  90. _DOMWindow.onmousewheel = scrollEventCallback;
  91. theDocument.onmousewheel = scrollEventCallback;
  92. theDocument.body.ondrag = function () { return NO; };
  93. theDocument.body.onselectstart = function () { return window.event.srcElement == _DOMPasteboardElement; };
  94. }
  95. ExcludedDOMElements["INPUT"] = YES;
  96. ExcludedDOMElements["SELECT"] = YES;
  97. ExcludedDOMElements["TEXTAREA"] = YES;
  98. ExcludedDOMElements["OPTION"] = YES;
  99. }
  100. return self;
  101. }
  102. }), new objj_method(sel_getUid("frame"), function $CPDOMWindowBridge__frame(self, _cmd)
  103. { with(self)
  104. {
  105. return CGRectMakeCopy(_frame);
  106. }
  107. }), new objj_method(sel_getUid("visibleFrame"), function $CPDOMWindowBridge__visibleFrame(self, _cmd)
  108. { with(self)
  109. {
  110. var frame = objj_msgSend(self, "frame");
  111. frame.origin = CGPointMakeZero();
  112. if (objj_msgSend(CPMenu, "menuBarVisible"))
  113. {
  114. var menuBarHeight = objj_msgSend(objj_msgSend(CPApp, "mainMenu"), "menuBarHeight");
  115. frame.origin.y += menuBarHeight;
  116. frame.size.height -= menuBarHeight;
  117. }
  118. return frame;
  119. }
  120. }), new objj_method(sel_getUid("contentBounds"), function $CPDOMWindowBridge__contentBounds(self, _cmd)
  121. { with(self)
  122. {
  123. return CPRectCreateCopy(_contentBounds);
  124. }
  125. }), new objj_method(sel_getUid("orderedWindowsAtLevel:"), function $CPDOMWindowBridge__orderedWindowsAtLevel_(self, _cmd, aLevel)
  126. { with(self)
  127. {
  128. var layer = objj_msgSend(self, "layerAtLevel:create:", aLevel, NO);
  129. if (!layer)
  130. return [];
  131. return objj_msgSend(layer, "orderedWindows");
  132. }
  133. }), new objj_method(sel_getUid("layerAtLevel:create:"), function $CPDOMWindowBridge__layerAtLevel_create_(self, _cmd, aLevel, aFlag)
  134. { with(self)
  135. {
  136. var layer = objj_msgSend(_windowLayers, "objectForKey:", aLevel);
  137. if (!layer && aFlag)
  138. {
  139. layer = objj_msgSend(objj_msgSend(CPDOMWindowLayer, "alloc"), "initWithLevel:", aLevel);
  140. objj_msgSend(_windowLayers, "setObject:forKey:", layer, aLevel);
  141. var low = 0,
  142. high = _windowLevels.length - 1,
  143. middle;
  144. while (low <= high)
  145. {
  146. middle = FLOOR((low + high) / 2);
  147. if (_windowLevels[middle] > aLevel)
  148. high = middle - 1;
  149. else
  150. low = middle + 1;
  151. }
  152. objj_msgSend(_windowLevels, "insertObject:atIndex:", aLevel, _windowLevels[middle] > aLevel ? middle : middle + 1);
  153. layer._DOMElement.style.zIndex = aLevel;
  154. _DOMBodyElement.appendChild(layer._DOMElement);
  155. }
  156. return layer;
  157. }
  158. }), new objj_method(sel_getUid("order:window:relativeTo:"), function $CPDOMWindowBridge__order_window_relativeTo_(self, _cmd, aPlace, aWindow, otherWindow)
  159. { with(self)
  160. {
  161. var layer = objj_msgSend(self, "layerAtLevel:create:", objj_msgSend(aWindow, "level"), aPlace != CPWindowOut);
  162. if (aPlace == CPWindowOut)
  163. return objj_msgSend(layer, "removeWindow:", aWindow);
  164. objj_msgSend(layer, "insertWindow:atIndex:", aWindow, (otherWindow ? (aPlace == CPWindowAbove ? otherWindow._index + 1 : otherWindow._index) : CPNotFound));
  165. }
  166. }), new objj_method(sel_getUid("_dragHitTest:pasteboard:"), function $CPDOMWindowBridge___dragHitTest_pasteboard_(self, _cmd, aPoint, aPasteboard)
  167. { with(self)
  168. {
  169. var levels = _windowLevels,
  170. layers = _windowLayers,
  171. levelCount = levels.length;
  172. while (levelCount--)
  173. {
  174. if (levels[levelCount] >= CPDraggingWindowLevel)
  175. continue;
  176. var windows = objj_msgSend(layers, "objectForKey:", levels[levelCount])._windows,
  177. windowCount = windows.length;
  178. while (windowCount--)
  179. {
  180. var theWindow = windows[windowCount];
  181. if (objj_msgSend(theWindow, "containsPoint:", aPoint))
  182. return objj_msgSend(theWindow, "_dragHitTest:pasteboard:", aPoint, aPasteboard);
  183. }
  184. }
  185. return nil;
  186. }
  187. }), new objj_method(sel_getUid("_propagateCurrentDOMEvent:"), function $CPDOMWindowBridge___propagateCurrentDOMEvent_(self, _cmd, aFlag)
  188. { with(self)
  189. {
  190. StopDOMEventPropagation = !aFlag;
  191. }
  192. }), new objj_method(sel_getUid("hitTest:"), function $CPDOMWindowBridge__hitTest_(self, _cmd, location)
  193. { with(self)
  194. {
  195. var levels = _windowLevels,
  196. layers = _windowLayers,
  197. levelCount = levels.length,
  198. theWindow = nil;
  199. while (levelCount-- && !theWindow)
  200. {
  201. var windows = objj_msgSend(layers, "objectForKey:", levels[levelCount])._windows,
  202. windowCount = windows.length;
  203. while (windowCount-- && !theWindow)
  204. {
  205. var candidateWindow = windows[windowCount];
  206. if (!candidateWindow._ignoresMouseEvents && objj_msgSend(candidateWindow, "containsPoint:", location))
  207. theWindow = candidateWindow;
  208. }
  209. }
  210. return theWindow;
  211. }
  212. })]);
  213. class_addMethods(meta_class, [new objj_method(sel_getUid("sharedDOMWindowBridge"), function $CPDOMWindowBridge__sharedDOMWindowBridge(self, _cmd)
  214. { with(self)
  215. {
  216. if (!CPSharedDOMWindowBridge)
  217. CPSharedDOMWindowBridge = objj_msgSend(objj_msgSend(CPDOMWindowBridge, "alloc"), "_initWithDOMWindow:", window);
  218. return CPSharedDOMWindowBridge;
  219. }
  220. })]);
  221. }
  222. var CPDOMWindowGetFrame = function(_DOMWindow)
  223. {
  224. var frame = nil;
  225. if (_DOMWindow.outerWidth)
  226. frame = CGRectMake(0, 0, _DOMWindow.outerWidth, _DOMWindow.outerHeight);
  227. else
  228. frame = CGRectMake(0, 0, -1, -1);
  229. if (window.screenTop)
  230. frame.origin = CGPointMake(_DOMWindow.screenLeft, _DOMWindow.screenTop, 0);
  231. else if (window.screenX)
  232. frame.origin = CGPointMake(_DOMWindow.screenX, _DOMWindow.screenY, 0);
  233. if (_DOMWindow.innerWidth)
  234. frame.size = CGSizeMake(_DOMWindow.innerWidth, _DOMWindow.innerHeight);
  235. else if (document.documentElement && document.documentElement.clientWidth)
  236. frame.size = CGSizeMake(_DOMWindow.document.documentElement.clientWidth, _DOMWindow.document.documentElement.clientHeight);
  237. else
  238. frame.size = CGSizeMake(_DOMWindow.document.body.clientWidth, _DOMWindow.document.body.clientHeight);
  239. return frame;
  240. }
  241. var KeyCodesToPrevent = {},
  242. CharacterKeysToPrevent = {},
  243. KeyCodesWithoutKeyPressEvents = { '8':1, '9':1, '37':1, '38':1, '39':1, '40':1, '46':1, '33':1, '34':1 };
  244. var CTRL_KEY_CODE = 17;
  245. {
  246. var the_class = objj_getClass("CPDOMWindowBridge")
  247. if(!the_class) objj_exception_throw(new objj_exception(OBJJClassNotFoundException, "*** Could not find definition for class \"CPDOMWindowBridge\""));
  248. var meta_class = the_class.isa;class_addMethods(the_class, [new objj_method(sel_getUid("preventCharacterKeysFromPropagating:"), function $CPDOMWindowBridge__preventCharacterKeysFromPropagating_(self, _cmd, characters)
  249. { with(self)
  250. {
  251. for(var i=characters.length; i>0; i--)
  252. CharacterKeysToPrevent[""+characters[i-1].toLowerCase()] = YES;
  253. }
  254. }), new objj_method(sel_getUid("preventCharacterKeyFromPropagating:"), function $CPDOMWindowBridge__preventCharacterKeyFromPropagating_(self, _cmd, character)
  255. { with(self)
  256. {
  257. CharacterKeysToPrevent[character.toLowerCase()] = YES;
  258. }
  259. }), new objj_method(sel_getUid("clearCharacterKeysToPreventFromPropagating"), function $CPDOMWindowBridge__clearCharacterKeysToPreventFromPropagating(self, _cmd)
  260. { with(self)
  261. {
  262. CharacterKeysToPrevent = {};
  263. }
  264. }), new objj_method(sel_getUid("preventKeyCodesFromPropagating:"), function $CPDOMWindowBridge__preventKeyCodesFromPropagating_(self, _cmd, keyCodes)
  265. { with(self)
  266. {
  267. for(var i=keyCodes.length; i>0; i--)
  268. KeyCodesToPrevent[keyCodes[i-1]] = YES;
  269. }
  270. }), new objj_method(sel_getUid("preventKeyCodeFromPropagating:"), function $CPDOMWindowBridge__preventKeyCodeFromPropagating_(self, _cmd, keyCode)
  271. { with(self)
  272. {
  273. KeyCodesToPrevent[keyCode] = YES;
  274. }
  275. }), new objj_method(sel_getUid("clearKeyCodesToPreventFromPropagating"), function $CPDOMWindowBridge__clearKeyCodesToPreventFromPropagating(self, _cmd)
  276. { with(self)
  277. {
  278. KeyCodesToPrevent = {};
  279. }
  280. }), new objj_method(sel_getUid("_bridgeMouseEvent:"), function $CPDOMWindowBridge___bridgeMouseEvent_(self, _cmd, aDOMEvent)
  281. { with(self)
  282. {
  283. var theType = _overriddenEventType || aDOMEvent.type;
  284. if (theType == CPDOMEventDoubleClick)
  285. {
  286. _overriddenEventType = CPDOMEventMouseDown;
  287. objj_msgSend(self, "_bridgeMouseEvent:", aDOMEvent);
  288. _overriddenEventType = CPDOMEventMouseUp;
  289. objj_msgSend(self, "_bridgeMouseEvent:", aDOMEvent);
  290. _overriddenEventType = nil;
  291. return;
  292. }
  293. try
  294. {
  295. var event,
  296. location = { x:aDOMEvent.clientX, y:aDOMEvent.clientY },
  297. timestamp = aDOMEvent.timeStamp ? aDOMEvent.timeStamp : new Date(),
  298. sourceElement = (aDOMEvent.target || aDOMEvent.srcElement),
  299. windowNumber = 0,
  300. modifierFlags = (aDOMEvent.shiftKey ? CPShiftKeyMask : 0) |
  301. (aDOMEvent.ctrlKey ? CPControlKeyMask : 0) |
  302. (aDOMEvent.altKey ? CPAlternateKeyMask : 0) |
  303. (aDOMEvent.metaKey ? CPCommandKeyMask : 0);
  304. StopDOMEventPropagation = YES;
  305. if (_mouseDownWindow)
  306. windowNumber = objj_msgSend(_mouseDownWindow, "windowNumber");
  307. else
  308. {
  309. var theWindow = objj_msgSend(self, "hitTest:", location);
  310. if (aDOMEvent.type == CPDOMEventMouseDown && theWindow)
  311. _mouseDownWindow = theWindow;
  312. windowNumber = objj_msgSend(theWindow, "windowNumber");
  313. }
  314. if (windowNumber)
  315. {
  316. var windowFrame = CPApp._windows[windowNumber]._frame;
  317. location.x -= (windowFrame.origin.x);
  318. location.y -= (windowFrame.origin.y);
  319. }
  320. switch (theType)
  321. {
  322. case CPDOMEventMouseUp: if(_mouseIsDown)
  323. {
  324. event = objj_msgSend(CPEvent, "mouseEventWithType:location:modifierFlags:timestamp:windowNumber:context:eventNumber:clickCount:pressure:", CPLeftMouseUp, location, modifierFlags, timestamp, windowNumber, nil, -1, CPDOMEventGetClickCount(_lastMouseUp, timestamp, location), 0);
  325. _mouseIsDown = NO;
  326. _lastMouseUp = event;
  327. _mouseDownWindow = nil;
  328. }
  329. if(_DOMEventMode)
  330. {
  331. _DOMEventMode = NO;
  332. return;
  333. }
  334. break;
  335. case CPDOMEventMouseDown: if (ExcludedDOMElements[sourceElement.tagName] && sourceElement != _DOMFocusElement)
  336. {
  337. _DOMEventMode = YES;
  338. _mouseIsDown = YES;
  339. objj_msgSend(CPApp, "sendEvent:", objj_msgSend(CPEvent, "mouseEventWithType:location:modifierFlags:timestamp:windowNumber:context:eventNumber:clickCount:pressure:", CPLeftMouseDown, location, modifierFlags, timestamp, windowNumber, nil, -1, CPDOMEventGetClickCount(_lastMouseDown, timestamp, location), 0));
  340. objj_msgSend(CPApp, "sendEvent:", objj_msgSend(CPEvent, "mouseEventWithType:location:modifierFlags:timestamp:windowNumber:context:eventNumber:clickCount:pressure:", CPLeftMouseUp, location, modifierFlags, timestamp, windowNumber, nil, -1, CPDOMEventGetClickCount(_lastMouseDown, timestamp, location), 0));
  341. return;
  342. }
  343. event = objj_msgSend(CPEvent, "mouseEventWithType:location:modifierFlags:timestamp:windowNumber:context:eventNumber:clickCount:pressure:", CPLeftMouseDown, location, modifierFlags, timestamp, windowNumber, nil, -1, CPDOMEventGetClickCount(_lastMouseDown, timestamp, location), 0);
  344. _mouseIsDown = YES;
  345. _lastMouseDown = event;
  346. break;
  347. case CPDOMEventMouseMoved: if (_DOMEventMode)
  348. return;
  349. event = objj_msgSend(CPEvent, "mouseEventWithType:location:modifierFlags:timestamp:windowNumber:context:eventNumber:clickCount:pressure:", _mouseIsDown ? CPLeftMouseDragged : CPMouseMoved, location, modifierFlags, timestamp, windowNumber, nil, -1, 1, 0);
  350. break;
  351. }
  352. if (event)
  353. {
  354. event._DOMEvent = aDOMEvent;
  355. objj_msgSend(CPApp, "sendEvent:", event);
  356. }
  357. if (StopDOMEventPropagation)
  358. CPDOMEventStop(aDOMEvent);
  359. objj_msgSend(objj_msgSend(CPRunLoop, "currentRunLoop"), "limitDateForMode:", CPDefaultRunLoopMode);
  360. }
  361. catch (anException)
  362. {
  363. objj_exception_report(anException, {path:"CPDOMWindowBridge.j"});
  364. }
  365. }
  366. }), new objj_method(sel_getUid("_bridgeKeyEvent:"), function $CPDOMWindowBridge___bridgeKeyEvent_(self, _cmd, aDOMEvent)
  367. { with(self)
  368. {
  369. try
  370. {
  371. var event,
  372. timestamp = aDOMEvent.timeStamp ? aDOMEvent.timeStamp : new Date(),
  373. sourceElement = (aDOMEvent.target || aDOMEvent.srcElement),
  374. windowNumber = objj_msgSend(objj_msgSend(CPApp, "keyWindow"), "windowNumber"),
  375. modifierFlags = (aDOMEvent.shiftKey ? CPShiftKeyMask : 0) |
  376. (aDOMEvent.ctrlKey ? CPControlKeyMask : 0) |
  377. (aDOMEvent.altKey ? CPAlternateKeyMask : 0) |
  378. (aDOMEvent.metaKey ? CPCommandKeyMask : 0);
  379. if (ExcludedDOMElements[sourceElement.tagName] && sourceElement != _DOMFocusElement && sourceElement != _DOMPasteboardElement)
  380. return;
  381. StopDOMEventPropagation = !(modifierFlags & (CPControlKeyMask | CPCommandKeyMask)) ||
  382. CharacterKeysToPrevent[String.fromCharCode(aDOMEvent.keyCode || aDOMEvent.charCode).toLowerCase()] ||
  383. KeyCodesToPrevent[aDOMEvent.keyCode];
  384. var isNativePasteEvent = NO,
  385. isNativeCopyOrCutEvent = NO;
  386. switch (aDOMEvent.type)
  387. {
  388. case CPDOMEventKeyDown:
  389. _keyCode = aDOMEvent.keyCode;
  390. var characters = String.fromCharCode(_keyCode).toLowerCase();
  391. if (characters == "v" && (modifierFlags & CPPlatformActionKeyMask))
  392. {
  393. _DOMPasteboardElement.select();
  394. _DOMPasteboardElement.value = "";
  395. isNativePasteEvent = YES;
  396. }
  397. else if ((characters == "c" || characters == "x") && (modifierFlags & CPPlatformActionKeyMask))
  398. isNativeCopyOrCutEvent = YES;
  399. else if (!CPFeatureIsCompatible(CPJavascriptRemedialKeySupport))
  400. return;
  401. else if (!KeyCodesWithoutKeyPressEvents[_keyCode] && (_keyCode == CTRL_KEY_CODE || !(modifierFlags & CPControlKeyMask)))
  402. return;
  403. case CPDOMEventKeyPress:
  404. if ((aDOMEvent.target || aDOMEvent.srcElement) == _DOMPasteboardElement)
  405. return;
  406. var keyCode = _keyCode,
  407. charCode = aDOMEvent.keyCode || aDOMEvent.charCode,
  408. isARepeat = (_charCodes[keyCode] != nil);
  409. _charCodes[keyCode] = charCode;
  410. var characters = String.fromCharCode(charCode),
  411. charactersIgnoringModifiers = characters.toLowerCase();
  412. event = objj_msgSend(CPEvent, "keyEventWithType:location:modifierFlags:timestamp:windowNumber:context:characters:charactersIgnoringModifiers:isARepeat:keyCode:", CPKeyDown, location, modifierFlags, timestamp, windowNumber, nil, characters, charactersIgnoringModifiers, isARepeat, keyCode);
  413. if (isNativePasteEvent)
  414. {
  415. _pasteboardKeyDownEvent = event;
  416. window.setNativeTimeout(function () { objj_msgSend(self, "_checkPasteboardElement") }, 0);
  417. return;
  418. }
  419. break;
  420. case CPDOMEventKeyUp: var keyCode = aDOMEvent.keyCode,
  421. charCode = _charCodes[keyCode];
  422. _charCodes[keyCode] = nil;
  423. var characters = String.fromCharCode(charCode),
  424. charactersIgnoringModifiers = characters.toLowerCase();
  425. if (!(modifierFlags & CPShiftKeyMask))
  426. characters = charactersIgnoringModifiers;
  427. event = objj_msgSend(CPEvent, "keyEventWithType:location:modifierFlags:timestamp:windowNumber:context:characters:charactersIgnoringModifiers:isARepeat:keyCode:", CPKeyUp, location, modifierFlags, timestamp, windowNumber, nil, characters, charactersIgnoringModifiers, NO, keyCode);
  428. break;
  429. }
  430. if (event)
  431. {
  432. event._DOMEvent = aDOMEvent;
  433. objj_msgSend(CPApp, "sendEvent:", event);
  434. if (isNativeCopyOrCutEvent)
  435. {
  436. var pasteboard = objj_msgSend(CPPasteboard, "generalPasteboard"),
  437. types = objj_msgSend(pasteboard, "types");
  438. if (types.length)
  439. {
  440. if (objj_msgSend(types, "indexOfObjectIdenticalTo:", CPStringPboardType) != CPNotFound)
  441. _DOMPasteboardElement.value = objj_msgSend(pasteboard, "stringForType:", CPStringPboardType);
  442. else
  443. _DOMPasteboardElement.value = objj_msgSend(pasteboard, "_generateStateUID");
  444. _DOMPasteboardElement.select();
  445. window.setNativeTimeout(function() { objj_msgSend(self, "_clearPasteboardElement"); }, 0);
  446. }
  447. return;
  448. }
  449. }
  450. if (StopDOMEventPropagation)
  451. CPDOMEventStop(aDOMEvent);
  452. objj_msgSend(objj_msgSend(CPRunLoop, "currentRunLoop"), "limitDateForMode:", CPDefaultRunLoopMode);
  453. }
  454. catch (anException)
  455. {
  456. objj_exception_report(anException, {path:"CPDOMWindowBridge.j"});
  457. }
  458. }
  459. }), new objj_method(sel_getUid("_bridgeScrollEvent:"), function $CPDOMWindowBridge___bridgeScrollEvent_(self, _cmd, aDOMEvent)
  460. { with(self)
  461. {
  462. if(!aDOMEvent)
  463. aDOMEvent = window.event;
  464. try
  465. {
  466. if (CPFeatureIsCompatible(CPJavaScriptMouseWheelValues_8_15))
  467. {
  468. var x = 0.0,
  469. y = 0.0,
  470. element = aDOMEvent.target;
  471. while (element.nodeType !== 1)
  472. element = element.parentNode;
  473. if (element.offsetParent)
  474. {
  475. do
  476. {
  477. x += element.offsetLeft;
  478. y += element.offsetTop;
  479. } while (element = element.offsetParent);
  480. }
  481. var location = { x:(x + ((aDOMEvent.clientX - 8) / 15)), y:(y + ((aDOMEvent.clientY - 8) / 15)) };}
  482. else
  483. var location = { x:aDOMEvent.clientX, y:aDOMEvent.clientY };
  484. var deltaX = 0.0,
  485. deltaY = 0.0,
  486. windowNumber = 0,
  487. timestamp = aDOMEvent.timeStamp ? aDOMEvent.timeStamp : new Date(),
  488. modifierFlags = (aDOMEvent.shiftKey ? CPShiftKeyMask : 0) |
  489. (aDOMEvent.ctrlKey ? CPControlKeyMask : 0) |
  490. (aDOMEvent.altKey ? CPAlternateKeyMask : 0) |
  491. (aDOMEvent.metaKey ? CPCommandKeyMask : 0);
  492. StopDOMEventPropagation = YES;
  493. windowNumber = objj_msgSend(objj_msgSend(self, "hitTest:", location), "windowNumber");
  494. if (!windowNumber)
  495. return;
  496. var windowFrame = CPApp._windows[windowNumber]._frame;
  497. location.x -= CGRectGetMinX(windowFrame);
  498. location.y -= CGRectGetMinY(windowFrame);
  499. if(typeof aDOMEvent.wheelDeltaX != "undefined")
  500. {
  501. deltaX = aDOMEvent.wheelDeltaX / 120.0;
  502. deltaY = aDOMEvent.wheelDeltaY / 120.0;
  503. }
  504. else if (aDOMEvent.wheelDelta)
  505. deltaY = aDOMEvent.wheelDelta / 120.0;
  506. else if (aDOMEvent.detail)
  507. deltaY = -aDOMEvent.detail / 3.0;
  508. else
  509. return;
  510. if(!CPFeatureIsCompatible(CPJavaScriptNegativeMouseWheelValues))
  511. {
  512. deltaX = -deltaX;
  513. deltaY = -deltaY;
  514. }
  515. var event = objj_msgSend(CPEvent, "mouseEventWithType:location:modifierFlags:timestamp:windowNumber:context:eventNumber:clickCount:pressure:", CPScrollWheel, location, modifierFlags, timestamp, windowNumber, nil, -1, 1, 0 );
  516. event._DOMEvent = aDOMEvent;
  517. event._deltaX = ROUND(deltaX * 1.5);
  518. event._deltaY = ROUND(deltaY * 1.5);
  519. objj_msgSend(CPApp, "sendEvent:", event);
  520. if (StopDOMEventPropagation)
  521. CPDOMEventStop(aDOMEvent);
  522. objj_msgSend(objj_msgSend(CPRunLoop, "currentRunLoop"), "limitDateForMode:", CPDefaultRunLoopMode);
  523. }
  524. catch (anException)
  525. {
  526. objj_exception_report(anException, {path:"CPDOMWindowBridge.j"});
  527. }
  528. }
  529. }), new objj_method(sel_getUid("_bridgeResizeEvent:"), function $CPDOMWindowBridge___bridgeResizeEvent_(self, _cmd, aDOMEvent)
  530. { with(self)
  531. {
  532. try
  533. {
  534. var oldSize = _frame.size;
  535. _frame = CPDOMWindowGetFrame(_DOMWindow);
  536. _contentBounds.size = CGSizeCreateCopy(_frame.size);
  537. var levels = _windowLevels,
  538. layers = _windowLayers,
  539. levelCount = levels.length;
  540. while (levelCount--)
  541. {
  542. var windows = objj_msgSend(layers, "objectForKey:", levels[levelCount])._windows,
  543. windowCount = windows.length;
  544. while (windowCount--)
  545. objj_msgSend(windows[windowCount], "resizeWithOldBridgeSize:", oldSize);
  546. }
  547. objj_msgSend(objj_msgSend(CPRunLoop, "currentRunLoop"), "limitDateForMode:", CPDefaultRunLoopMode);
  548. }
  549. catch (anException)
  550. {
  551. objj_exception_report(anException, {path:"CPDOMWindowBridge.j"});
  552. }
  553. }
  554. }), new objj_method(sel_getUid("_bridgeTouchEvent:"), function $CPDOMWindowBridge___bridgeTouchEvent_(self, _cmd, aDOMEvent)
  555. { with(self)
  556. {
  557. try
  558. {
  559. if (aDOMEvent.touches && (aDOMEvent.touches.length == 1 || (aDOMEvent.touches.length == 0 && aDOMEvent.changedTouches.length == 1)))
  560. {
  561. var newEvent = {};
  562. switch(aDOMEvent.type)
  563. {
  564. case CPDOMEventTouchStart: newEvent.type = CPDOMEventMouseDown;
  565. break;
  566. case CPDOMEventTouchEnd: newEvent.type = CPDOMEventMouseUp;
  567. break;
  568. case CPDOMEventTouchMove: newEvent.type = CPDOMEventMouseMoved;
  569. break;
  570. case CPDOMEventTouchCancel: newEvent.type = CPDOMEventMouseUp;
  571. break;
  572. }
  573. var touch = aDOMEvent.touches.length ? aDOMEvent.touches[0] : aDOMEvent.changedTouches[0];
  574. newEvent.clientX = touch.clientX;
  575. newEvent.clientY = touch.clientY;
  576. newEvent.timestamp = aDOMEvent.timestamp;
  577. newEvent.target = aDOMEvent.target;
  578. newEvent.shiftKey = newEvent.ctrlKey = newEvent.altKey = newEvent.metaKey = false;
  579. newEvent.preventDefault = function(){if(aDOMEvent.preventDefault) aDOMEvent.preventDefault()};
  580. newEvent.stopPropagation = function(){if(aDOMEvent.stopPropagation) aDOMEvent.stopPropagation()};
  581. objj_msgSend(self, "_bridgeMouseEvent:", newEvent);
  582. return;
  583. }
  584. else
  585. {
  586. if (aDOMEvent.preventDefault)
  587. aDOMEvent.preventDefault();
  588. if (aDOMEvent.stopPropagation)
  589. aDOMEvent.stopPropagation();
  590. }
  591. }
  592. catch(e)
  593. {
  594. objj_exception_report(e, {path:"CPDOMWindowBridge.j"});
  595. }
  596. }
  597. }), new objj_method(sel_getUid("_checkPasteboardElement"), function $CPDOMWindowBridge___checkPasteboardElement(self, _cmd)
  598. { with(self)
  599. {
  600. try
  601. {
  602. var value = _DOMPasteboardElement.value;
  603. if (objj_msgSend(value, "length"))
  604. {
  605. var pasteboard = objj_msgSend(CPPasteboard, "generalPasteboard");
  606. if (objj_msgSend(pasteboard, "_stateUID") != value)
  607. {
  608. objj_msgSend(pasteboard, "declareTypes:owner:", [CPStringPboardType], self);
  609. objj_msgSend(pasteboard, "setString:forType:", value, CPStringPboardType);
  610. }
  611. }
  612. objj_msgSend(self, "_clearPasteboardElement");
  613. objj_msgSend(CPApp, "sendEvent:", _pasteboardKeyDownEvent);
  614. _pasteboardKeyDownEvent = nil;
  615. objj_msgSend(objj_msgSend(CPRunLoop, "currentRunLoop"), "limitDateForMode:", CPDefaultRunLoopMode);
  616. }
  617. catch (anException)
  618. {
  619. objj_exception_report(anException, {path:"CPDOMWindowBridge.j"});
  620. }
  621. }
  622. }), new objj_method(sel_getUid("_clearPasteboardElement"), function $CPDOMWindowBridge___clearPasteboardElement(self, _cmd)
  623. { with(self)
  624. {
  625. _DOMPasteboardElement.value = "";
  626. _DOMPasteboardElement.blur();
  627. }
  628. })]);
  629. }
  630. var CLICK_SPACE_DELTA = 5.0,
  631. CLICK_TIME_DELTA = (typeof document != "undefined" && document.addEventListener) ? 350.0 : 1000.0;
  632. var CPDOMEventGetClickCount = function(aComparisonEvent, aTimestamp, aLocation)
  633. {
  634. if (!aComparisonEvent)
  635. return 1;
  636. var comparisonLocation = objj_msgSend(aComparisonEvent, "locationInWindow");
  637. return (aTimestamp - objj_msgSend(aComparisonEvent, "timestamp") < CLICK_TIME_DELTA &&
  638. ABS(comparisonLocation.x - aLocation.x) < CLICK_SPACE_DELTA &&
  639. ABS(comparisonLocation.y - aLocation.y) < CLICK_SPACE_DELTA) ? objj_msgSend(aComparisonEvent, "clickCount") + 1 : 1;
  640. }
  641. var CPDOMEventStop = function(aDOMEvent)
  642. {
  643. aDOMEvent.cancelBubble = true;
  644. aDOMEvent.returnValue = false;
  645. if (aDOMEvent.preventDefault)
  646. aDOMEvent.preventDefault();
  647. if (aDOMEvent.stopPropagation)
  648. aDOMEvent.stopPropagation();
  649. if (aDOMEvent.type == CPDOMEventMouseDown)
  650. {
  651. CPSharedDOMWindowBridge._DOMFocusElement.focus();
  652. CPSharedDOMWindowBridge._DOMFocusElement.blur();
  653. }
  654. }