"use strict"; //2024-08-21: //this script is responsible for allowing the user interface //to function with touchscreen interactivity. event listeners //are added to various elements to ensure that touchscreen //interactivity is implemented for the entire interface. //instead of manually assigning touch event listeners to each //individual element that uses a mousemove, mousedown, and mouseup //mouse event listener, this solution comprehensively achieves //the same functionality in a single script. when a touchstart, //touchmove, or touchend event occurs on the interface, this script //creates the corresponding mouse event synthetically and //dispatches that mouse event as though the user is performing //these mouse actions by using a mouse. essentially, this script //maps touchscreen events to corresponding mouse events. /* ----------------------------------------------------------------------------------------------- FUNCTIONS TO ADD EVENT HANDLERS ----------------------------------------------------------------------------------------------- */ //this function adds touchscreen event listeners to //the window element. by doing this, all elements //that are child objects of the window element are //enabled to handle touchscreen events and map them //to their corresponding mouse events automatically. function add_touch_event_listeners_window() { add_touch_event_listener_touchstart_window(); add_touch_event_listener_touchmove_window(); add_touch_event_listener_touchend_window(); } //touchscreen event listeners are assigned to a web-window's //title bar to facilitate the X, and Y movement of a web-window //as though the user was moving the window using their mouse. function add_touch_event_listeners_title_bar(win_id) { add_touch_event_listener_touchstart_title_bar(win_id); add_touch_event_listener_touchmove_title_bar(win_id); add_touch_event_listener_touchend_title_bar(win_id); } //sometimes it may be necessary to place a blank image //on top of the entire interface to prevent unwanted //user interaction from impeding the performance of //actions that move or resize a web-window. these event //listeners are assigned to the UI blocking element to handle //touchscreen events. this allows for control over the UI blocking //layer using touchscreen events as though they were mouse //events. function add_touch_event_listeners_ui_blocker() { add_touch_event_listener_touchstart_ui_blocker(); add_touch_event_listener_touchend_ui_blocker(); } //when a user performs touchscreen events to resize a web-window's //height and/or width, these event listeners are mapped to their //corresponding mouse events that allow for such functionality. function add_touch_event_listeners_resize_web_window(win_id) { add_touch_event_listener_touchstart_resize_web_window(win_id); add_touch_event_listener_touchmove_resize_web_window(win_id); add_touch_event_listener_touchend_resize_web_window(win_id); } /* ----------------------------------------------------------------------------------------------- END FUNCTIONS TO ADD EVENT HANDLERS ----------------------------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------------------------- WEB WINDOW TITLE BAR ----------------------------------------------------------------------------------------------- */ //this function adds an event listener to a web-window's title //bar that maps the "touchstart" event to a "mousedown" event. //this event listener is set to function in 'passive' mode and //the event should not be canceled. function add_touch_event_listener_touchstart_title_bar(win_id) { var window_title_bar = null; window_title_bar = document.getElementById(win_id + "_tbl_0000_tr_0000_td_0001"); if (window_title_bar !== null) { window_title_bar.addEventListener("touchstart", function (event) { if (event.cancelable === true) { event.preventDefault(); //event.stopPropagation(); } touchstart_title_bar_event_handler(event, win_id); }, { passive: false, capture: false, cancelable: true, bubbles: false }); } } //when a touchscreen 'touchmove' event occurs over a web-window's //title bar, the event handler maps this event to a 'mousemove' //event. this allows the user to use touchscreen touchmove events //to move the web-window's X, Y location on the page. although these //event and event listener are 'passive', the 'touchmove' event is //cancelled and event propagation is disallowed in order to prevent //degradation to performance. if the event is not canceled, the //movement of the web-window is glitchy, and not smooth as it should //be. keep in mind that in order to cancel this event, the event needs //be cancelable. if the event is not cancelable, then attempting to //cancel the event returns an error. function add_touch_event_listener_touchmove_title_bar(win_id) { var window_title_bar = null; window_title_bar = document.getElementById(win_id + "_tbl_0000_tr_0000_td_0001"); if (window_title_bar !== null) { window_title_bar.addEventListener("touchmove", function (event) { if (event.cancelable === true) { event.preventDefault(); event.stopPropagation(); } touchmove_title_bar_event_handler(event); }, { passive: false, capture: false, cancelable: true, bubbles: false }); } } //when a user ceases touching the screen over the web-window title //bar, the 'touchend' event is fired. the 'touchend' is mapped to //a 'mouseup' event. this event and event listener are set to 'passive' //and the event should not be canceled. function add_touch_event_listener_touchend_title_bar(win_id) { var window_title_bar = null; window_title_bar = document.getElementById(win_id + "_tbl_0000_tr_0000_td_0001"); if (window_title_bar !== null) { window_title_bar.addEventListener("touchend", function (event) { if (event.cancelable === true) { event.preventDefault(); //event.stopPropagation(); } touchend_title_bar_event_handler(event); }, { passive: false, capture: false, cancelable: true, bubbles: false }); } } //when a user touches the web-window's title bar, a 'touchstart' //event fires, and is mapped to a 'mousedown' synthetic event //which originates at the web-window's title bar element. //the event is set to bubble, and is not set as 'passive' //and not set to 'cancelable'. the event's target element //is the web-window's title bar. it's important that the //'update_global_first_touch_point_coords(touch_event)' //function is called to update the global variables that store //the X, and Y location of the 'touchstart' event. function touchstart_title_bar_event_handler(event, win_id) { var event_type = null; var touch_event = null; touch_event = event; event_type = touch_event.type; update_global_first_touch_point_coords(touch_event); if (event_type === "touchstart") { invoke_element_synthetic_mouse_event(touch_event, touch_event.target.id, "mousedown", true, false, true, false, false); } } //when a user invokes the 'touchmove' touchscreen event over the //web-window's title bar, a synthetic 'mousemove' event is generated //at the window element allowing the web-window to move its X, and Y //location on the page. this event, and event handler are set to be //'passive', and 'cancelable' with event 'bubbling' set to true. function touchmove_title_bar_event_handler(event) { if (event.cancelable === true) { event.preventDefault(); event.stopPropagation(); } invoke_window_synthetic_mouse_event(event, "mousemove", true, false, true, false, false); } //when a user discontinues touching the screen, a synthetic 'mouseup' //event is dispatched originating at the target element. event 'bubbling' //is set to true, and the event is set to 'non-passive', and not 'cancelable'. //it's important that the 'update_global_first_touch_point_coords(touch_event)' //function is called to update the global variables that store the X, and Y //location of the 'touchend' event. function touchend_title_bar_event_handler(event) { var event_type = null; var touch_event = null; touch_event = event; event_type = touch_event.type; update_global_first_touch_point_coords(touch_event); if (event_type === "touchend") { invoke_element_synthetic_mouse_event(touch_event, touch_event.target.id, "mouseup", true, false, true, false, false); } } /* ----------------------------------------------------------------------------------------------- END WEB WINDOW TITLE BAR ----------------------------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------------------------- UI BLOCKER ----------------------------------------------------------------------------------------------- */ //in certain scenarios, such as when a web-window's X, and Y //location changes (moved on the screen) by a user, or when a web-window's //height and/or width change by a user, a blank image is placed over the //top of the entire user interface. this UI blocking layer prevents //unwanted interaction from occuring to other elements that are not //intended to participate in the user interaction. if this UI blocking //layer is not placed over the interface during web-window move, and //resize actions, then the movement becomes extremely glitchy with //poor performance. with the UI blocking layer in place, moving and //resizing web-windows is smooth, fast, and efficient. this function //adds an event listener to the UI blocking layer so that when a //'touchstart' user action occurs, a synthetic 'mousedown' event is //mapped and originates from the UI blocking layer. this event listener //is set to 'passive'. Upon moving or resizing a web window, //this UI blocking layer is automatically set into place. when a //'mousedown' event occurs on the UI blocking layer, the layer //remains in place. function add_touch_event_listener_touchstart_ui_blocker() { var blocking_layer_obj = null; blocking_layer_obj = document.getElementById("blocking_layer"); if (blocking_layer_obj !== null) { blocking_layer_obj.addEventListener("touchstart", function (event) { if (event.cancelable === true) { event.preventDefault(); //event.stopPropagation(); } touchstart_screen_ui_blocker_event_handler(event); }, { passive: false, capture: false, cancelable: true, bubbles: false }); } } //when the user lifts their finger/touchpoint from the screen, //this event listener that is assigned to the window element //automatically removes the UI blocking layer if it currently //exists. this allows for user interaction to become enabled //for the interface. event capture is set to true, but the //event handler doesn't use the event object in any way upon //being triggered. It simply removed the UI blocking layer //if it is present. see file: 'ui_interaction_screen_block.js' function add_touch_event_listener_touchend_ui_blocker() { var blocking_layer_obj = null; blocking_layer_obj = document.getElementById("blocking_layer"); if (blocking_layer_obj !== null) { window.addEventListener("touchend", function () { touchend_screen_ui_blocker_event_handler(); }, { passive: false, capture: false, cancelable: true, bubbles: false }); } } //this function is an event handler that maps a touchscreen //'touchstart' event to a 'mousedown' event which originates //at the UI blocking layer. the synthetic mouse event ('mousedown') //is set to 'bubble', not 'passive', and not 'cancelable'. it's important //that the 'update_global_first_touch_point_coords(touch_event)' //function is called to update the global variables that store the X, and Y //location of the 'touchstart' event. function touchstart_screen_ui_blocker_event_handler(event) { var event_type = null; var touch_event = null; touch_event = event; event_type = touch_event.type; update_global_first_touch_point_coords(touch_event); if (event_type === "touchstart") { invoke_element_synthetic_mouse_event(touch_event, touch_event.target.id, "mousedown", true, false, true, false, false); } } //this event handler occurs when the user removes their //finger/pointer from the screen which invokes a 'touchend' //event. the 'touchend' event for the UI screen blocking //layer does not map the touch event to any other event. //it doesn't utilize the event object. instead, it removes //the UI blocking layer if it is present with no further action. function touchend_screen_ui_blocker_event_handler() { var blocking_layer_obj = null; blocking_layer_obj = document.getElementById("blocking_layer"); if (blocking_layer_obj !== null) { remove_blocking_layer(); } } /* ----------------------------------------------------------------------------------------------- END UI BLOCKER ----------------------------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------------------------- WINDOW ELEMENT ----------------------------------------------------------------------------------------------- */ //this function assigns a 'touchstart' touch event to the window //element. the event listener is set to 'passive' and the 'touchstart' //event is mapped to a 'mousedown' event originating at the window //element. its event handler invokes a synthetic 'mousedown' event //with 'bubbling' set to true, 'passive' set to false, and 'cancelable' //set to false. function add_touch_event_listener_touchstart_window() { window.addEventListener("touchstart", function (event) { if (event.cancelable === true) { //event.preventDefault(); //event.stopPropagation(); } touchstart_window_event_handler_function(event); }, { passive: false, capture: true, cancelable: true, bubbles: true }); } //this function assigns an event listener to the window //element for when a 'touchmove' touchscreen event occurs at //the window element level. event capturing in this event //listener needs to be set to true, as the touch events //need to be invoked by the window element's children. //if event capture was not set to true, then the //touchscreen events would not trickle down to the child //elements of the window element. this event handler is //what allows the entire user interface to map all 'touchmove' //touch events on all elements in the DOM that are a //child element of the window element. in this case, the //'touchmove' event that originates at the window element //maps that 'touchmove' event to every element in the DOM //as a 'mousemove' event. function add_touch_event_listener_touchmove_window() { window.addEventListener("touchmove", function (event) { if (event.cancelable === true) { event.preventDefault(); //event.stopPropagation(); } touchmove_window_event_handler(event); }, { passive: false, capture: true, cancelable: true, bubbles: false }); } //when a user removes finger/pointer contact with the screen, //this event listener triggers the 'touchend' event at the //window element level. the event listener is set to 'passive'. function add_touch_event_listener_touchend_window() { window.addEventListener("touchend", function (event) { if (event.cancelable === true) { ////event.preventDefault(); //event.stopPropagation(); } touchend_window_event_handler(event); }, { passive: false, capture: true, cancelable: true, bubbles: false }); } //for reasons that I do not understand, this function indicates //that there are over 450 references pointing to this event handler //function. there should only be one reference, and that reference //is located within the event listener set by the function named: //'add_touch_event_listener_touchstart_window()'. To be sure that //a duplicate function with the same name doesn't exist in scripts //that are built-in to the browser window, I changed this function's //name. I appended '_function' to the name of this function to ensure //that no conflicts can happen. //this event handler maps the 'touchstart' event that originates at the //window element level, to a synthetic 'mousedown' event that originates //at the window element level. 'bubbling' is set to true, 'passive' is set //to false, and 'cancelable' is set to false. function touchstart_window_event_handler_function(event) { var touch_event = null; touch_event = event; invoke_window_synthetic_mouse_event(touch_event, "mousedown", true, false, true, false, false); } //this event handler function is triggered when a 'touchmove' //event is invoked at the window element level. this 'touchmove' //event that occurs at the window element level doesn't map to //any mouse event. instead, when the 'touchmove' event occurs at //the window element level, this event handler updates the global //variables that store the X, and Y location of where the 'touchmove' //event is occuring. it's important that the //'update_global_first_touch_point_coords(touch_event)' function is //called to update the global variables that store the X, and Y //location of the 'touchmove' event. function touchmove_window_event_handler(event) { var touch_event = null; touch_event = event; if (typeof (touch_event.type) === "string" && touch_event.type.length > 0) { update_global_first_touch_point_coords(touch_event); } } //this event handler is called at the window element level //when a user removes their finger/pointer from the screen //causing a 'touchend' event to occur. the 'touchend' event //is mapped to a 'mouseup' event originating at the window //element level. 'bubbling' for the synthetic 'mouseup' event //is set to true, 'cancelable' is set to false, and 'passive' //is set to false. it's important that the //'update_global_first_touch_point_coords(touch_event)' function //is called to update the global variables that store the X, and Y //location of the 'touchend' event. function touchend_window_event_handler(event) { var event_type = null; var touch_event = null; touch_event = event; event_type = touch_event.type; update_global_first_touch_point_coords(touch_event); if (event_type === "touchend") { invoke_window_synthetic_mouse_event(touch_event, "mouseup", true, false, true, false, false); } } /* ----------------------------------------------------------------------------------------------- END WINDOW ELEMENT ----------------------------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------------------------- WEB WINDOW RESIZE ----------------------------------------------------------------------------------------------- */ //this function assigns an event listener to a web-window's 'resize' icon, //in additon to the 'resize X' and 'resize Y' bars which are placed at the //web-window's right edge, and bottom edge. normally, these resize bars //are transparent, and only visible when test mode is set to 'on'. for each //of these three elements, a 'touchstart' event listener is assigned. //depending on which resize element is triggering the 'touchstart' event, //an attribute in the web-window's html specifies whether the web-window //is to resize in both width, and height ('xy'), or only width ('x'), or //only height ('y'). once the attribute has been set accordingly, an event //handler is called to map any 'touchstart' event originating from any of //the three 'resize web-window' elements to trigger a synthetic mouse event //which originates from the 'resize web-window' element that triggers the //'touchstart' event. the event listener is set to 'passive'. function add_touch_event_listener_touchstart_resize_web_window(win_id) { var window_resize_web_window_object = null; var window_resize_web_window_x_object = null; var window_resize_web_window_y_object = null; window_resize_web_window_object = document.getElementById(win_id + "_tbl_0000_tr_0002_td_0001"); if (window_resize_web_window_object !== null) { window_resize_web_window_object.addEventListener("touchstart", function (event) { if (event.cancelable === true) { event.preventDefault(); //event.stopPropagation(); } //2024-08-20: //set an attribute in the window's HTML specifying //the default value of resize window to resize //both width (x), and height (y). //See file: 'resize_window`.js' set_win_resize_xy_attribute(win_id, "xy"); touchstart_resize_web_window_event_handler(event, win_id); }, { passive: false, capture: false, cancelable: true, bubbles: false }); } window_resize_web_window_x_object = document.getElementById(win_id + "_resize_bar_x"); if (window_resize_web_window_x_object !== null) { window_resize_web_window_x_object.addEventListener("touchstart", function (event) { if (event.cancelable === true) { event.preventDefault(); //event.stopPropagation(); } //2024-08-20: //set an attribute in the window's HTML specifying //the default value of resize window to resize //width (x). //See file: 'resize_window`.js' set_win_resize_xy_attribute(win_id, "x"); touchstart_resize_web_window_event_handler(event, win_id); }, { passive: false, capture: false, cancelable: true, bubbles: false }); } window_resize_web_window_y_object = document.getElementById(win_id + "_resize_bar_y"); if (window_resize_web_window_y_object !== null) { window_resize_web_window_y_object.addEventListener("touchstart", function (event) { if (event.cancelable === true) { event.preventDefault(); //event.stopPropagation(); } //2024-08-20: //set an attribute in the window's HTML specifying //the default value of resize window to resize //height (y). //See file: 'resize_window`.js' set_win_resize_xy_attribute(win_id, "y"); touchstart_resize_web_window_event_handler(event, win_id); }, { passive: false, capture: false, cancelable: true, bubbles: false }); } } //to resize a web-window using touch events, the elements that are responsible //for resizing a web-window need to be assigned an event listener to handle //any 'touchmove' event they trigger. for performance purposes, it is imperitive //that the 'touchmove' event listener be canceled by using the 'event.preventDefault()' //method only after checking to see if the 'touchmove' event is 'cancelable'. //if the event is 'cancelable', then it is 'canceled' and event propagation is //stopped. these event canceling methods must be called inside the 'touchmove' //event listener; not from inside the event handler function that is called when //'a 'touchmove' event is triggered by any of the 'resize web-window' elements. //although event propagation is stopped, the event listener has its 'capture event' //parameter set to false for redundancy purposes. function add_touch_event_listener_touchmove_resize_web_window(win_id) { var window_resize_web_window_object = null; var window_resize_web_window_x_object = null; var window_resize_web_window_y_object = null; window_resize_web_window_object = document.getElementById(win_id + "_tbl_0000_tr_0002_td_0001"); if (window_resize_web_window_object !== null) { window_resize_web_window_object.addEventListener("touchmove", function (event) { if (event.cancelable === true) { event.preventDefault(); event.stopPropagation(); } touchmove_resize_web_window_event_handler(event, win_id); }, { passive: false, capture: false, cancelable: true, bubbles: false }); } window_resize_web_window_x_object = document.getElementById(win_id + "_resize_bar_x"); if (window_resize_web_window_x_object !== null) { window_resize_web_window_x_object.addEventListener("touchmove", function (event) { if (event.cancelable === true) { event.preventDefault(); event.stopPropagation(); } touchmove_resize_web_window_event_handler(event, win_id); }, { passive: false, capture: false, cancelable: true, bubbles: false }); } window_resize_web_window_y_object = document.getElementById(win_id + "_resize_bar_y"); if (window_resize_web_window_y_object !== null) { window_resize_web_window_y_object.addEventListener("touchmove", function (event) { if (event.cancelable === true) { event.preventDefault(); event.stopPropagation(); } touchmove_resize_web_window_event_handler(event, win_id); }, { passive: false, capture: false, cancelable: true, bubbles: false }); } } //when any of the three 'resize web-window' elements trigger a 'touchend' event, //the event is mapped to a 'mouseup' event originating from the 'resize web-window' //element. the 'touchend' event listeners are set to 'passive'. function add_touch_event_listener_touchend_resize_web_window(win_id) { var window_resize_web_window_object = null; var window_resize_web_window_x_object = null; var window_resize_web_window_y_object = null; window_resize_web_window_object = document.getElementById(win_id + "_tbl_0000_tr_0002_td_0001"); if (window_resize_web_window_object !== null) { window_resize_web_window_object.addEventListener("touchend", function (event) { if (event.cancelable === true) { event.preventDefault(); //event.stopPropagation(); } touchend_resize_web_window_event_handler(event, win_id); }, { passive: false, capture: false, cancelable: true, bubbles: false }); } window_resize_web_window_x_object = document.getElementById(win_id + "_resize_bar_x"); if (window_resize_web_window_x_object !== null) { window_resize_web_window_x_object.addEventListener("touchend", function (event) { if (event.cancelable === true) { event.preventDefault(); //event.stopPropagation(); } touchend_resize_web_window_event_handler(event, win_id); }, { passive: false, capture: false, cancelable: true, bubbles: false }); } window_resize_web_window_y_object = document.getElementById(win_id + "_resize_bar_y"); if (window_resize_web_window_y_object !== null) { window_resize_web_window_y_object.addEventListener("touchend", function (event) { if (event.cancelable === true) { event.preventDefault(); //event.stopPropagation(); } touchend_resize_web_window_event_handler(event, win_id); }, { passive: false, capture: false, cancelable: true, bubbles: false }); } } //when any of the three 'resize web-window' elements trigger a 'touchstart' //event, this event handler invokes a 'mousedown' event originating from //whichever 'resize web_window' element that triggers the 'touchstart' event. //it's important that the 'update_global_first_touch_point_coords(touch_event)' //function is called to update the global variables that store the X, and Y //location of the 'touchstart' event. function touchstart_resize_web_window_event_handler(event, win_id) { var event_type = null; var touch_event = null; touch_event = event; event_type = touch_event.type; update_global_first_touch_point_coords(touch_event); if (event_type === "touchstart") { invoke_element_synthetic_mouse_event(touch_event, touch_event.target.id, "mousedown", true, false, true, false, false); } } //when a 'touchmove' event is triggered by any one of the three elements //used to resize a web-window's width and/or height, the touch event is passed //into the event handler function. the touch event maps to a synthetic 'mousemove' //event originating from the window element. for performance reasons, this event //handler checks to see if the event variable can be canceled. if it can be canceled, then //call the 'event.preventDefault()' method to cancel it, and stop the event from //propagating. if the event isn't 'cancelable', then calling the 'event.preventDefault()' //method with throw an error. this event handler maps the 'touchmove' event to //a synthetic 'mousemove' event originating from the window element. the synthetic //mouse event is set to 'bubble', the 'cancelable' parameter is set to true, and //the 'passive' parameter is set to true. function touchmove_resize_web_window_event_handler(event, win_id) { if (event.cancelable === true) { event.preventDefault(); event.stopPropagation(); } invoke_window_synthetic_mouse_event(event, "mousemove", true, false, true, false, false); } //a 'touchend' event is generated when the user removes their finger/pointer //from the screen. the event originates from any of the three 'resize web-window' //elements. the 'touchend' event is mapped to a synthetic 'mouseup' event that //originates from one of the three 'resize web-window' elements. the synthetic //mouse event is set to 'bubble', 'passive' is set to false, and 'cancelable' //is set to false. it's important for the 'update_global_first_touch_point_coords(touch_event)' //function is called in order to update the global variables that store the //touch event's X, and Y location. function touchend_resize_web_window_event_handler(event) { var event_type = null; var touch_event = null; touch_event = event; event_type = touch_event.type; update_global_first_touch_point_coords(touch_event); if (event_type === "touchend") { invoke_element_synthetic_mouse_event(touch_event, touch_event.target.id, "mouseup", true, false, true, false, false); } } /* ----------------------------------------------------------------------------------------------- END WEB WINDOW RESIZE ----------------------------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------------------------- CORE FUNCTIONS ----------------------------------------------------------------------------------------------- */ //this function invokes and dispatches a synthetic mouse event which //originates from the WINDOW element. the first argument passed to the //function ('mapped_from_event') is the original touchscreen event. //the 'event_type' argument is a string value that designates what //type of synthetic mouse event is to be dispatched originating on //the window element level. the 'can_event_bubble' argument designates //whether the synthetic mouse event is to 'bubble' or not. its value //needs to be either true or false. the 'is_passive' argument also needs //to be true or false. the 'event_cancels' argument needs to be a //boolean value as well. most often, if the 'is_passive' argument //has a value of true, then the 'event_cancels' argument has the same //value of true as well. it's just the same if 'is_passive' has a //value of false. if any of the boolean arguments are not a valid boolean //value, then they are set to a default value of either true, or false. //it's important to call the 'update_global_first_touch_point_coords(mapped_from_event);' //function so that the global variables that store the X, and Y coordinates //of the touch event are updated. these global variables are used to set //the clientX, and clientY properties of the synthetic mouse event. function invoke_window_synthetic_mouse_event(mapped_from_event = null, event_type = "mousemove", can_event_bubble = true, is_passive = true, event_can_cancel = true, event_prevent_default = false, event_stop_propagation = false) { var mouse_event_type = null; var mouse_event = null; var event_bubbles = null; var is_passive_true = null; var is_cancelable = null; var prevent_default = null; var stop_propagation = null; prevent_default = event_prevent_default; stop_propagation = event_stop_propagation; event_bubbles = validate_can_event_bubble_value(can_event_bubble); is_passive_true = validate_is_passive_value(is_passive); is_cancelable = validate_can_cancel_value(event_can_cancel); mouse_event_type = event_type; mouse_event = new Event(mouse_event_type, { bubbles: event_bubbles, passive: is_passive_true, cancelable: is_cancelable }); if (typeof (mapped_from_event.type) === "string" && mapped_from_event.type.length > 0) { update_global_first_touch_point_coords(mapped_from_event); } if (prevent_default === true) { mouse_event.preventDefault(); } if (stop_propagation === true) { mouse_event.stopPropagation(); } mouse_event.clientX = global_touch_move_client_x; mouse_event.clientY = global_touch_move_client_y; window.dispatchEvent(mouse_event); } //this function invokes and dispatches a synthetic mouse event which //originates from ANY ELEMENT which is designated by the function's //'elem_id' argument. this way, the target element of the synthetic //mouse event origin element can be designated using an element's //id attribute. the first argument passed to the function ('mapped_from_event') //is the original touchscreen event. as mention previously, the second //argument (elem_id) is the id attribute of the element that we want //the synthetic mouse event to originate from. the 'event_type' argument //is a string value that designates the type of synthetic mouse event //that is to be dispatched. the 'can_event_bubble' argument designates //whether the synthetic mouse event is to 'bubble' or not. its value //needs to be either true or false. the 'is_passive' argument also needs //to be true or false. the 'event_cancels' argument needs to be a //boolean value as well. most often, if the 'is_passive' argument //has a value of true, then the 'event_cancels' argument has the same //value of true as well. it's just the same if 'is_passive' has a //value of false. if any of the boolean arguments are not a valid boolean //value, then they are set to a default value of either true, or false. //it's important to call the 'update_global_first_touch_point_coords(mapped_from_event);' //function so that the global variables that store the X, and Y coordinates //of the touch event are updated. these global variables are used to set //the clientX, and clientY properties of the synthetic mouse event. function invoke_element_synthetic_mouse_event(mapped_from_event = null, elem_id = null, event_type = "mousemove", can_event_bubble = true, is_passive = false, event_cancelable = false, event_prevent_default = false, event_stop_propagation = false) { var mouse_event_type = null; var mouse_event = null; var elem = null; var event_bubbles = null; var is_passive_true = null; var is_cancelable = null; var prevent_default = null; var stop_propagation = null; prevent_default = event_prevent_default; stop_propagation = event_stop_propagation; elem = document.getElementById(elem_id); if (elem !== null) { event_bubbles = validate_can_event_bubble_value(can_event_bubble); is_passive_true = validate_is_passive_value(is_passive); is_cancelable = validate_can_cancel_value(event_cancelable); mouse_event_type = event_type; mouse_event = new Event(mouse_event_type, { bubbles: event_bubbles, passive: is_passive_true, cancelable: is_cancelable, }); if (typeof(mapped_from_event.type) === "string" && mapped_from_event.type.length > 0) { update_global_first_touch_point_coords(mapped_from_event); } mouse_event.clientX = global_touch_move_client_x; mouse_event.clientY = global_touch_move_client_y; if (prevent_default === true) { mouse_event.preventDefault(); } if (stop_propagation === true) { mouse_event.stopPropagation(); } elem.dispatchEvent(mouse_event); } } //when creating a synthetic mouse event, several boolean arguments //are passed into a function as arguments. if any of the three boolean //arguments have a value other than true, or false, then a default //value of true or false is set by default function validate_can_event_bubble_value(can_event_bubble) { var event_bubbles = null; if (can_event_bubble === true || can_event_blubble === false) { event_bubbles = can_event_bubble; } else { event_bubbles = true; } return event_bubbles; } function validate_is_passive_value(is_passive) { var is_passive_true = null; if (is_passive === true || is_passive === false) { is_passive_true = is_passive; } else { is_passive_true = false; } return is_passive_true; } function validate_can_cancel_value(can_event_cancel) { var is_event_cancel_true = null; if (can_event_cancel === true || can_event_cancel === false) { is_event_cancel_true = can_event_cancel; } else { is_event_cancel_true = false; } return is_event_cancel_true; } //this function is responsible for setting the touch event's //X, and Y location to global variables. when this function //is called, it automatically updates the global variables //to match the location of where a touch event has occured. //the touch event is passed into the function as an argument //and is used to determine the X, and Y coorinates of the //touch event. in addition, the global variables that hold //the value of the mouse cursor X, and Y are set to the same //respective values so that touch events and dispatched synthetic //mouse events occur in the same X, and Y location as one another. function update_global_first_touch_point_coords(event_object = null) { var touches_list = null; var first_touch_point = null; var touch_event = null; touch_event = event_object; if (typeof (touch_event.type) === "string" && touch_event.type.length > 0) { touches_list = touch_event.changedTouches; first_touch_point = touches_list[0]; get_touch_point_event_clientX(first_touch_point); get_touch_point_event_clientY(first_touch_point); } } //this function is responsible for getting a thouch //event's X, and Y location. It returns the X location //as the function's output. the default CSS zoom setting //for the document has an effect upon X, and Y location //values. to adjust for this, we get the document's pixel //ratio which is a numeric value that changes when the //document's CSS zoom value is set to a value other than 100%. //the CSS zoom value set as the default for the page is 80%. //the pixel_ratio is a value that is inverse to the CSS //zoom value. Hence, it returns a value of 1.25, or 125%. //if it is a different value than 1.25, then we adjust the //X, and Y location values accordingly. this function //updates both X, and Y locations of touch events, but it //returns the X value as output. the global variables that //store the X, and Y location of the mouse cursor are set //to equal the value of a touchscreen event's X, and Y. //this allows for touch events to map and dispatch //synthetic mouse events at the same X, and Y location. function get_touch_point_event_clientX(touch_point) { var touch_point_clientX = null; global_touch_move_client_x = touch_point.clientX; global_touch_move_client_y = touch_point.clientY; global_mouse_coords_x = global_touch_move_client_x; global_mouse_coords_y = global_touch_move_client_y; touch_point_clientX = global_touch_move_client_x; return touch_point_clientX; } //this function is responsible for getting a thouch //event's X, and Y location. It returns the Y location //as the function's output. the default CSS zoom setting //for the document has an effect upon X, and Y location //values. to adjust for this, we get the document's pixel //ratio which is a numeric value that changes when the //document's CSS zoom value is set to a value other than 100%. //the CSS zoom value set as the default for the page is 80%. //the pixel_ratio is a value that is inverse to the CSS //zoom value. Hence, it returns a value of 1.25, or 125%. //if it is a different value than 1.25, then we adjust the //X, and Y location values accordingly. this function //updates both X, and Y locations of touch events, but it //returns the Y value as output. the global variables that //store the X, and Y location of the mouse cursor are set //to equal the value of a touchscreen event's X, and Y. //this allows for touch events to map and dispatch //synthetic mouse events at the same X, and Y location. function get_touch_point_event_clientY(touch_point) { var touch_point_clientY = null; global_touch_move_client_x = touch_point.clientX; global_touch_move_client_y = touch_point.clientY; global_mouse_coords_x = global_touch_move_client_x; global_mouse_coords_y = global_touch_move_client_y; touch_point_clientY = global_touch_move_client_y; return touch_point_clientY; } /* ----------------------------------------------------------------------------------------------- END CORE FUNCTIONS ----------------------------------------------------------------------------------------------- */