//////////////////////////////////////////////////////////////////////////////// // Constants //////////////////////////////////////////////////////////////////////////////// var __CFMOUSE_BUTTON_HOLD_REPEAT_INTERVAL = 100; var __CFMOUSE_BUTTON_HOLD_REPEAT_START = 500; var __CFMOUSE_ERROR_DOCUMENT = "document mouse position is unavailable"; var __CFMOUSE_ERROR_SCREEN = "screen mouse position is unavailable"; //////////////////////////////////////////////////////////////////////////////// // Static variables //////////////////////////////////////////////////////////////////////////////// var __cfMouseDocumentPositionX = undefined; var __cfMouseDocumentPositionY = undefined; var __cfMouseLeftButtonHoldTimer = undefined; var __cfMouseLeftButtonsDown = new Array(); var __cfMouseOnMouseDownHandlerSet = new CFEventHandlerSet(); var __cfMouseOnMouseDownLeftHandlerSet = new CFEventHandlerSet(); var __cfMouseOnMouseDownRightHandlerSet = new CFEventHandlerSet(); var __cfMouseOnMouseHoldHandlerSet = new CFEventHandlerSet(); var __cfMouseOnMouseHoldLeftHandlerSet = new CFEventHandlerSet(); var __cfMouseOnMouseHoldRightHandlerSet = new CFEventHandlerSet(); var __cfMouseOnMouseMoveHandlerSet = new CFEventHandlerSet(); var __cfMouseOnMouseUpHandlerSet = new CFEventHandlerSet(); var __cfMouseOnMouseUpLeftHandlerSet = new CFEventHandlerSet(); var __cfMouseOnMouseUpRightHandlerSet = new CFEventHandlerSet(); var __cfMouseOverDocument = undefined; var __cfMouseRightButtonDown = false; var __cfMouseRightButtonHoldTimer = undefined; var __cfMouseScreenPositionX = undefined; var __cfMouseScreenPositionY = undefined; //////////////////////////////////////////////////////////////////////////////// // Private //////////////////////////////////////////////////////////////////////////////// function __cfMouseGetEventResult(results) { var trueBias = 0; var value; for (var i = 0; i < results.length; i++) { value = results[i]; if (typeof(value) != "undefined") { trueBias += value ? 1 : -1; } } return trueBias >= 0; } function __cfMouseHandleLeftButtonDown(button) { var buttonDown = cfMouseIsLeftButtonDown(); var results = new Array(); __cfMouseLeftButtonsDown[button] = true; if (! buttonDown) { results = results.concat(__cfMouseOnMouseDownLeftHandlerSet.execute(), __cfMouseOnMouseDownHandlerSet.execute()); if (__cfMouseOnMouseHoldLeftHandlerSet.getLength() || __cfMouseOnMouseHoldHandlerSet.getLength()) { __cfMouseLeftButtonHoldTimer = window.setTimeout("__cfMouseHandleOnMouseHoldLeftEvent()", __CFMOUSE_BUTTON_HOLD_REPEAT_START); } } return __cfMouseGetEventResult(results); } function __cfMouseHandleLeftButtonUp(button) { var results = new Array(); __cfMouseLeftButtonsDown[button] = false; if (! cfMouseIsLeftButtonDown()) { if (__cfMouseLeftButtonHoldTimer) { window.clearTimeout(__cfMouseLeftButtonHoldTimer); __cfMouseLeftButtonHoldTimer = undefined; } results = results.concat(__cfMouseOnMouseUpLeftHandlerSet.execute(), __cfMouseOnMouseUpHandlerSet.execute()); } return __cfMouseGetEventResult(results); } function __cfMouseHandleMove(docX, docY, screenX, screenY) { __cfMouseDocumentPositionX = docX; __cfMouseDocumentPositionY = docY; __cfMouseScreenPositionX = screenX; __cfMouseScreenPositionY = screenY; return __cfMouseGetEventResult(__cfMouseOnMouseMoveHandlerSet.execute()); } function __cfMouseHandleRightButtonDown() { __cfMouseRightButtonDown = true; var results = new Array(); results = results.concat(__cfMouseOnMouseDownRightHandlerSet.execute(), __cfMouseOnMouseDownHandlerSet.execute()); if (__cfMouseOnMouseHoldRightHandlerSet.getLength() || __cfMouseOnMouseHoldHandlerSet.getLength()) { __cfMouseRightButtonHoldTimer = window.setTimeout("__cfMouseHandleOnMouseHoldRightEvent()", __CFMOUSE_BUTTON_HOLD_REPEAT_START); } return __cfMouseGetEventResult(results); } function __cfMouseHandleRightButtonUp() { __cfMouseRightButtonDown = false; if (__cfMouseRightButtonHoldTimer) { window.clearTimeout(__cfMouseRightButtonHoldTimer); __cfMouseRightButtonHoldTimer = undefined; } var results = new Array(); results = results.concat(__cfMouseOnMouseUpRightHandlerSet.execute(), __cfMouseOnMouseUpHandlerSet.execute()); return __cfMouseGetEventResult(results); } function __cfMousePatchMouseClickEvents(e, isDown) { var mouseDownFunc; var mouseUpFunc; var result; if (e) { if (typeof(e.which) == "number") { mouseDownFunc = __cfMouseHandleOnMouseDownEventWhich; mouseUpFunc = __cfMouseHandleOnMouseUpEventWhich; } else if (typeof(e.button) == "number") { mouseDownFunc = __cfMouseHandleOnMouseDownEventButtonArg; mouseUpFunc = __cfMouseHandleOnMouseUpEventButtonArg; } else { mouseDownFunc = __cfMouseHandleOnMouseDownEventUndefinedArg; mouseUpFunc = __cfMouseHandleOnMouseUpEventUndefinedArg; } if (isDown) { result = mouseDownFunc(e); } else { result = mouseUpFunc(e); } } else { e = window.event; if (! e) { mouseDownFunc = __cfMouseHandleOnMouseDownEventUndefinedNoArg; mouseUpFunc = __cfMouseHandleOnMouseUpEventUndefinedNoArg; } else if (typeof(e.button) == "number") { mouseDownFunc = __cfMouseHandleOnMouseDownEventButtonNoArg; mouseUpFunc = __cfMouseHandleOnMouseUpEventButtonNoArg; } else { mouseDownFunc = __cfMouseHandleOnMouseDownEventUndefinedNoArg; mouseUpFunc = __cfMouseHandleOnMouseUpEventUndefinedNoArg; } if (isDown) { result = mouseDownFunc(); } else { result = mouseUpFunc(); } } document.onmousedown = __cfMouseHandleOnMouseDownEvent = mouseDownFunc; document.onmouseup = __cfMouseHandleOnMouseUpEvent = mouseUpFunc; return result; } //////////////////////////////////////////////////////////////////////////////// // Patches //////////////////////////////////////////////////////////////////////////////// // __cfMouseHandleOnMouseDownEvent patches function __cfMouseHandleOnMouseDownEventButtonArg(e) { var button = e.button; if (button == 2) { return __cfMouseHandleRightButtonDown(); } return __cfMouseHandleLeftButtonDown(button); } function __cfMouseHandleOnMouseDownEventButtonNoArg() { return __cfMouseHandleOnMouseDownEventButtonArg(window.event); } function __cfMouseHandleOnMouseDownEventUndefinedArg(e) { return __cfMouseHandleOnMouseDownEventUndefinedNoArg(); } function __cfMouseHandleOnMouseDownEventUndefinedNoArg() { return __cfMouseHandleLeftButtonDown(1); } function __cfMouseHandleOnMouseDownEventWhich(e) { var button = e.which; if (button == 3) { return __cfMouseHandleRightButtonDown(); } return __cfMouseHandleLeftButtonDown(button); } // __cfMouseHandleOnMouseMoveEvent patches function __cfMouseHandleOnMouseMoveEventClient(e) { return __cfMouseHandleMove(e.clientX, e.clientY, e.screenX, e.screenY); } function __cfMouseHandleOnMouseMoveEventClientScrollElement() { var e = window.event; var offsets = cfViewportGetScrollOffsets(); var x = e.clientX; var y = e.clientY; if (typeof(x) == "number") { x += offsets.x; } if (typeof(y) == "number") { y += offsets.y; } return __cfMouseHandleMove(x, y, e.screenX, e.screenY); } function __cfMouseHandleOnMouseMoveEventPage(e) { return __cfMouseHandleMove(e.pageX, e.pageY, e.screenX, e.screenY); } function __cfMouseHandleOnMouseMoveEventScreenOnly() { e = window.event; return __cfMouseHandleMove(undefined, undefined, e.screenX, e.screenY); } function __cfMouseHandleOnMouseMoveEventUndefinedArg(e) { return __cfMouseHandleOnMouseMoveEventUndefinedNoArg(); } function __cfMouseHandleOnMouseMoveEventUndefinedNoArg() { return __cfMouseHandleMove(undefined, undefined, undefined, undefined); } // __cfMouseHandleOnMouseUpEvent patches function __cfMouseHandleOnMouseUpEventButtonArg(e) { var button = e.button; if (button == 2) { return __cfMouseHandleRightButtonUp(); } return __cfMouseHandleLeftButtonUp(button); } function __cfMouseHandleOnMouseUpEventButtonNoArg() { return __cfMouseHandleOnMouseUpEventButtonArg(window.event); } function __cfMouseHandleOnMouseUpEventUndefinedArg(e) { return __cfMouseHandleOnMouseUpEventUndefinedNoArg(); } function __cfMouseHandleOnMouseUpEventUndefinedNoArg() { return __cfMouseHandleLeftButtonUp(1); } function __cfMouseHandleOnMouseUpEventWhich(e) { var button = e.which; if (button == 3) { return __cfMouseHandleRightButtonUp(); } return __cfMouseHandleLeftButtonUp(button); } //////////////////////////////////////////////////////////////////////////////// // Events //////////////////////////////////////////////////////////////////////////////// function __cfMouseHandleOnLoadEvent() { document.onmousedown = __cfMouseHandleOnMouseDownEvent; document.onmousemove = __cfMouseHandleOnMouseMoveEvent; document.onmouseout = __cfMouseHandleOnMouseOutEvent; document.onmouseover = __cfMouseHandleOnMouseOverEvent; document.onmouseup = __cfMouseHandleOnMouseUpEvent; if (document.captureEvents) { document.captureEvents(Event.MOUSEDOWN); document.captureEvents(Event.MOUSEMOVE); document.captureEvents(Event.MOUSEOUT); document.captureEvents(Event.MOUSEOVER); document.captureEvents(Event.MOUSEUP); } } function __cfMouseHandleOnMouseDownEvent(e) { return __cfMousePatchMouseClickEvents(e, true); } function __cfMouseHandleOnMouseHoldLeftEvent() { var results = new Array(); if (cfMouseIsLeftButtonDown()) { __cfMouseOnMouseHoldLeftHandlerSet.execute(); __cfMouseOnMouseHoldHandlerSet.execute(); __cfMouseLeftButtonHoldTimer = window.setTimeout("__cfMouseHandleOnMouseHoldLeftEvent()", __CFMOUSE_BUTTON_HOLD_REPEAT_INTERVAL); } } function __cfMouseHandleOnMouseHoldRightEvent() { if (cfMouseIsRightButtonDown()) { __cfMouseOnMouseHoldRightHandlerSet.execute(); __cfMouseOnMouseHoldHandlerSet.execute(); __cfMouseRightButtonHoldTimer = window.setTimeout("__cfMouseHandleOnMouseHoldRightEvent()", __CFMOUSE_BUTTON_HOLD_REPEAT_INTERVAL); } } function __cfMouseHandleOnMouseMoveEvent(e) { var func; var result; if (e) { if ((typeof(e.pageX) == "number") || (typeof(e.pageY) == "number")) { func = __cfMouseHandleOnMouseMoveEventPage; } else if ((typeof(e.clientX) == "number") || (typeof(e.clientY) == "number")) { func = __cfMouseHandleOnMouseMoveEventClient; } else { func = __cfMouseHandleOnMouseMoveEventUndefinedArg; } result = func(e); } else { e = window.event; if (! e) { func = __cfMouseHandleOnMouseMoveEventUndefinedNoArg; } else if ((typeof(e.clientX) == "number") || (typeof(e.clientY) == "number")) { func = __cfMouseHandleOnMouseMoveEventClientScrollElement; } else { func = __cfMouseHandleOnMouseMoveEventScreenOnly; } result = func(); } document.onmousemove = __cfMouseHandleOnMouseMoveEvent = func; return result; } function __cfMouseHandleOnMouseOutEvent(e) { __cfMouseOverDocument = false; __cfMouseDocumentPositionX = undefined; __cfMouseDocumentPositionY = undefined; return true; } function __cfMouseHandleOnMouseOverEvent(e) { __cfMouseOverDocument = true; return __cfMouseHandleOnMouseMoveEvent(e); } function __cfMouseHandleOnMouseUpEvent(e) { return __cfMousePatchMouseClickEvents(e, false); } //////////////////////////////////////////////////////////////////////////////// // Public API //////////////////////////////////////////////////////////////////////////////// function cfMouseAddOnMouseDownCallback() { var handlerSet = __cfMouseOnMouseDownHandlerSet; handlerSet.add.apply(handlerSet, arguments); } function cfMouseAddOnMouseDownLeftCallback() { var handlerSet = __cfMouseOnMouseDownLeftHandlerSet; handlerSet.add.apply(handlerSet, arguments); } function cfMouseAddOnMouseDownRightCallback() { var handlerSet = __cfMouseOnMouseDownRightHandlerSet; handlerSet.add.apply(handlerSet, arguments); } function cfMouseAddOnMouseHoldCallback() { var handlerSet = __cfMouseOnMouseHoldHandlerSet; handlerSet.add.apply(handlerSet, arguments); } function cfMouseAddOnMouseHoldLeftCallback() { var handlerSet = __cfMouseOnMouseHoldLeftHandlerSet; handlerSet.add.apply(handlerSet, arguments); } function cfMouseAddOnMouseHoldRightCallback() { var handlerSet = __cfMouseOnMouseHoldRightHandlerSet; handlerSet.add.apply(handlerSet, arguments); } function cfMouseAddOnMouseMoveCallback() { var handlerSet = __cfMouseOnMouseMoveHandlerSet; handlerSet.add.apply(handlerSet, arguments); } function cfMouseAddOnMouseUpCallback() { var handlerSet = __cfMouseOnMouseUpHandlerSet; handlerSet.add.apply(handlerSet, arguments); } function cfMouseAddOnMouseUpLeftCallback() { var handlerSet = __cfMouseOnMouseUpLeftHandlerSet; handlerSet.add.apply(handlerSet, arguments); } function cfMouseAddOnMouseUpRightCallback() { var handlerSet = __cfMouseOnMouseUpRightHandlerSet; handlerSet.add.apply(handlerSet, arguments); } function cfMouseGetDocumentPosition(ignoreError) { var x = __cfMouseDocumentPositionX; var y = __cfMouseDocumentPositionY; if ((typeof(x) != "number") || (typeof(y) != "number")) { if (ignoreError) { return undefined; } return cfErrorTrigger("cfMouseGetDocumentPosition: " + __CFMOUSE_ERROR_DOCUMENT); } return {x: x, y: y}; } function cfMouseGetElementPosition(element, ignoreError) { var documentPosition = cfMouseGetDocumentPosition(ignoreError); if (documentPosition) { var elementPosition = cfElementGetDocumentPosition(element, ignoreError); if (elementPosition) { return { x: documentPosition.x - elementPosition.x, y: documentPosition.y - elementPosition.y }; } } return undefined; } function cfMouseGetScreenPosition(ignoreError) { var x = __cfMouseScreenPositionX; var y = __cfMouseScreenPositionY; if ((typeof(x) != "number") || (typeof(y) != "number")) { if (ignoreError) { return undefined; } return cfErrorTrigger("cfMouseGetScreenPosition: " + __CFMOUSE_ERROR_SCREEN); } return {x: x, y: y}; } function cfMouseGetViewportPosition(ignoreError) { var offsets = cfViewportGetScrollOffsets(ignoreError); if (offsets) { var position = cfMouseGetDocumentPosition(ignoreError); if (position) { return {x: position.x - offsets.x, y: position.y - offsets.y}; } } return undefined; } function cfMouseIsLeftButtonDown() { for (var i = 0; i < __cfMouseLeftButtonsDown.length; i++) { if (__cfMouseLeftButtonsDown[i]) { return true; } } return false; } function cfMouseIsRightButtonDown() { return __cfMouseRightButtonDown; } //////////////////////////////////////////////////////////////////////////////// // Initialization //////////////////////////////////////////////////////////////////////////////// cfDocumentAddOnLoadCallback(__cfMouseHandleOnLoadEvent);