Best Python code snippet using uiautomator
factories.js
Source:factories.js  
...3045        return new SessionRenewalHttp($http, $timeout);3046    }]).factory("specificationCache", [function () {3047        var currentSpecification = null;3048        var currentProject = null;3049        function getSuiteEstimation(suite) {3050            var time = 0;3051            for (var i = 0, max = suite.testCases.length; i < max; i++) {3052                time += suite.testCases[i].duration;3053            }3054            return time;3055        }3056        return {3057            getCurrentSpecificationId: function () {3058                return currentSpecification !== null ? parseInt(currentSpecification.id, 10) : -1;3059            },3060            setCurrentSpecification: function (spec, project) {3061                currentSpecification = spec;3062                currentProject = project;3063            },3064            getCurrentSpecification: function () {3065                return currentSpecification;3066            },3067            resetCurrentSpecification: function () {3068                currentSpecification = null;3069                currentProject = null;3070            },3071            getCurrentProjectName: function () {3072                return currentProject !== null ? currentProject.name : null;3073            },3074            getCurrentProject: function () {3075                return currentProject;3076            },3077            getCurrentSuite: function (suiteId) {3078                if (currentSpecification) {3079                    for (var i = 0, max = currentSpecification.testSuites.length; i < max; i++) {3080                        if (currentSpecification.testSuites[i].id === suiteId) {3081                            var s = currentSpecification.testSuites[i];3082                            s.version = currentSpecification.version;3083                            s.specificationTitle = currentSpecification.title;3084                            s.estimation = getSuiteEstimation(s);3085                            return s;3086                        }3087                    }3088                }3089                return null;3090            },3091            getCurrentCase: function (caseId, suiteId) {3092                if (currentSpecification) {3093                    for (var i = 0, max = currentSpecification.testSuites.length; i < max; i++) {3094                        if (currentSpecification.testSuites[i].id === suiteId) {3095                            var s = currentSpecification.testSuites[i];3096                            for (var j = 0, max2 = s.testCases.length; j < max2; j++) {3097                                if (s.testCases[j].id === caseId) {3098                                    var c = s.testCases[j];...Editor.Events.js
Source:Editor.Events.js  
...6 *7 * License: http://www.tinymce.com/license8 * Contributing: http://www.tinymce.com/contributing9 */10(function(tinymce) {11	var each = tinymce.each;12	/**13	 * Creates all event dispatcher instances for the editor instance and also adds14	 * passthoughs for legacy callback handlers.15	 */16	tinymce.Editor.prototype.setupEvents = function() {17		var self = this, settings = self.settings;18		// Add events to the editor19		each([20			/**21			 * Fires before the initialization of the editor.22			 *23			 * @event onPreInit24			 * @param {tinymce.Editor} sender Editor instance.25			 * @see #onInit26			 * @example27			 * // Adds an observer to the onPreInit event using tinyMCE.init28			 * tinyMCE.init({29			 *    ...30			 *    setup : function(ed) {31			 *       ed.onPreInit.add(function(ed) {32			 *           console.debug('PreInit: ' + ed.id);33			 *       });34			 *    }35			 * });36			 */37			'onPreInit',38			/**39			 * Fires before the initialization of the editor.40			 *41			 * @event onBeforeRenderUI42			 * @param {tinymce.Editor} sender Editor instance.43			 * @example44			 * // Adds an observer to the onBeforeRenderUI event using tinyMCE.init45			 * tinyMCE.init({46			 *    ...47			 *    setup : function(ed) {48			 *      ed.onBeforeRenderUI.add(function(ed, cm) {49			 *          console.debug('Before render: ' + ed.id);50			 *      });51			 *    }52			 * });53			 */54			'onBeforeRenderUI',55			/**56			 * Fires after the rendering has completed.57			 *58			 * @event onPostRender59			 * @param {tinymce.Editor} sender Editor instance.60			 * @example61			 * // Adds an observer to the onPostRender event using tinyMCE.init62			 * tinyMCE.init({63			 *    ...64			 *    setup : function(ed) {65			 *       ed.onPostRender.add(function(ed, cm) {66			 *           console.debug('After render: ' + ed.id);67			 *       });68			 *    }69			 * });70			 */71			'onPostRender',72			/**73			 * Fires when the onload event on the body occurs.74			 *75			 * @event onLoad76			 * @param {tinymce.Editor} sender Editor instance.77			 * @example78			 * // Adds an observer to the onLoad event using tinyMCE.init79			 * tinyMCE.init({80			 *    ...81			 *    setup : function(ed) {82			 *       ed.onLoad.add(function(ed, cm) {83			 *           console.debug('Document loaded: ' + ed.id);84			 *       });85			 *    }86			 * });87			 */88			'onLoad',89			/**90			 * Fires after the initialization of the editor is done.91			 *92			 * @event onInit93			 * @param {tinymce.Editor} sender Editor instance.94			 * @see #onPreInit95			 * @example96			 * // Adds an observer to the onInit event using tinyMCE.init97			 * tinyMCE.init({98			 *    ...99			 *    setup : function(ed) {100			 *       ed.onInit.add(function(ed) {101			 *           console.debug('Editor is done: ' + ed.id);102			 *       });103			 *    }104			 * });105			 */106			'onInit',107			/**108			 * Fires when the editor instance is removed from page.109			 *110			 * @event onRemove111			 * @param {tinymce.Editor} sender Editor instance.112			 * @example113			 * // Adds an observer to the onRemove event using tinyMCE.init114			 * tinyMCE.init({115			 *    ...116			 *    setup : function(ed) {117			 *       ed.onRemove.add(function(ed) {118			 *           console.debug('Editor was removed: ' + ed.id);119			 *       });120			 *    }121			 * });122			 */123			'onRemove',124			/**125			 * Fires when the editor is activated.126			 *127			 * @event onActivate128			 * @param {tinymce.Editor} sender Editor instance.129			 * @example130			 * // Adds an observer to the onActivate event using tinyMCE.init131			 * tinyMCE.init({132			 *    ...133			 *    setup : function(ed) {134			 *       ed.onActivate.add(function(ed) {135			 *           console.debug('Editor was activated: ' + ed.id);136			 *       });137			 *    }138			 * });139			 */140			'onActivate',141			/**142			 * Fires when the editor is deactivated.143			 *144			 * @event onDeactivate145			 * @param {tinymce.Editor} sender Editor instance.146			 * @example147			 * // Adds an observer to the onDeactivate event using tinyMCE.init148			 * tinyMCE.init({149			 *    ...150			 *    setup : function(ed) {151			 *       ed.onDeactivate.add(function(ed) {152			 *           console.debug('Editor was deactivated: ' + ed.id);153			 *       });154			 *    }155			 * });156			 */157			'onDeactivate',158			/**159			 * Fires when something in the body of the editor is clicked.160			 *161			 * @event onClick162			 * @param {tinymce.Editor} sender Editor instance.163			 * @param {Event} evt W3C DOM Event instance.164			 * @example165			 * // Adds an observer to the onClick event using tinyMCE.init166			 * tinyMCE.init({167			 *    ...168			 *    setup : function(ed) {169			 *       ed.onClick.add(function(ed, e) {170			 *           console.debug('Editor was clicked: ' + e.target.nodeName);171			 *       });172			 *    }173			 * });174			 */175			'onClick',176			/**177			 * Fires when a registered event is intercepted.178			 *179			 * @event onEvent180			 * @param {tinymce.Editor} sender Editor instance.181			 * @param {Event} evt W3C DOM Event instance.182			 * @example183			 * // Adds an observer to the onEvent event using tinyMCE.init184			 * tinyMCE.init({185			 *    ...186			 *    setup : function(ed) {187			 *       ed.onEvent.add(function(ed, e) {188			 *          console.debug('Editor event occurred: ' + e.target.nodeName);189			 *       });190			 *    }191			 * });192			 */193			'onEvent',194			/**195			 * Fires when a mouseup event is intercepted inside the editor.196			 *197			 * @event onMouseUp198			 * @param {tinymce.Editor} sender Editor instance.199			 * @param {Event} evt W3C DOM Event instance.200			 * @example201			 * // Adds an observer to the onMouseUp event using tinyMCE.init202			 * tinyMCE.init({203			 *    ...204			 *    setup : function(ed) {205			 *       ed.onMouseUp.add(function(ed, e) {206			 *           console.debug('Mouse up event: ' + e.target.nodeName);207			 *       });208			 *    }209			 * });210			 */211			'onMouseUp',212			/**213			 * Fires when a mousedown event is intercepted inside the editor.214			 *215			 * @event onMouseDown216			 * @param {tinymce.Editor} sender Editor instance.217			 * @param {Event} evt W3C DOM Event instance.218			 * @example219			 * // Adds an observer to the onMouseDown event using tinyMCE.init220			 * tinyMCE.init({221			 *    ...222			 *    setup : function(ed) {223			 *       ed.onMouseDown.add(function(ed, e) {224			 *           console.debug('Mouse down event: ' + e.target.nodeName);225			 *       });226			 *    }227			 * });228			 */229			'onMouseDown',230			/**231			 * Fires when a dblclick event is intercepted inside the editor.232			 *233			 * @event onDblClick234			 * @param {tinymce.Editor} sender Editor instance.235			 * @param {Event} evt W3C DOM Event instance.236			 * @example237			 * // Adds an observer to the onDblClick event using tinyMCE.init238			 * tinyMCE.init({239			 *    ...240			 *    setup : function(ed) {241			 *       ed.onDblClick.add(function(ed, e) {242			 *          console.debug('Double click event: ' + e.target.nodeName);243			 *       });244			 *    }245			 * });246			 */247			'onDblClick',248			/**249			 * Fires when a keydown event is intercepted inside the editor.250			 *251			 * @event onKeyDown252			 * @param {tinymce.Editor} sender Editor instance.253			 * @param {Event} evt W3C DOM Event instance.254			 * @example255			 * // Adds an observer to the onKeyDown event using tinyMCE.init256			 * tinyMCE.init({257			 *    ...258			 *    setup : function(ed) {259			 *       ed.onKeyDown.add(function(ed, e) {260			 *           console.debug('Key down event: ' + e.keyCode);261			 *       });262			 *    }263			 * });264			 */265			'onKeyDown',266			/**267			 * Fires when a keydown event is intercepted inside the editor.268			 *269			 * @event onKeyUp270			 * @param {tinymce.Editor} sender Editor instance.271			 * @param {Event} evt W3C DOM Event instance.272			 * @example273			 * // Adds an observer to the onKeyUp event using tinyMCE.init274			 * tinyMCE.init({275			 *    ...276			 *    setup : function(ed) {277			 *       ed.onKeyUp.add(function(ed, e) {278			 *           console.debug('Key up event: ' + e.keyCode);279			 *       });280			 *    }281			 * });282			 */283			'onKeyUp',284			/**285			 * Fires when a keypress event is intercepted inside the editor.286			 *287			 * @event onKeyPress288			 * @param {tinymce.Editor} sender Editor instance.289			 * @param {Event} evt W3C DOM Event instance.290			 * @example291			 * // Adds an observer to the onKeyPress event using tinyMCE.init292			 * tinyMCE.init({293			 *    ...294			 *    setup : function(ed) {295			 *       ed.onKeyPress.add(function(ed, e) {296			 *           console.debug('Key press event: ' + e.keyCode);297			 *       });298			 *    }299			 * });300			 */301			'onKeyPress',302			/**303			 * Fires when a contextmenu event is intercepted inside the editor.304			 *305			 * @event onContextMenu306			 * @param {tinymce.Editor} sender Editor instance.307			 * @param {Event} evt W3C DOM Event instance.308			 * @example309			 * // Adds an observer to the onContextMenu event using tinyMCE.init310			 * tinyMCE.init({311			 *    ...312			 *    setup : function(ed) {313			 *       ed.onContextMenu.add(function(ed, e) {314			 *            console.debug('Context menu event:' + e.target);315			 *       });316			 *    }317			 * });318			 */319			'onContextMenu',320			/**321			 * Fires when a form submit event is intercepted.322			 *323			 * @event onSubmit324			 * @param {tinymce.Editor} sender Editor instance.325			 * @param {Event} evt W3C DOM Event instance.326			 * @example327			 * // Adds an observer to the onSubmit event using tinyMCE.init328			 * tinyMCE.init({329			 *    ...330			 *    setup : function(ed) {331			 *       ed.onSubmit.add(function(ed, e) {332			 *            console.debug('Form submit:' + e.target);333			 *       });334			 *    }335			 * });336			 */337			'onSubmit',338			/**339			 * Fires when a form reset event is intercepted.340			 *341			 * @event onReset342			 * @param {tinymce.Editor} sender Editor instance.343			 * @param {Event} evt W3C DOM Event instance.344			 * @example345			 * // Adds an observer to the onReset event using tinyMCE.init346			 * tinyMCE.init({347			 *    ...348			 *    setup : function(ed) {349			 *       ed.onReset.add(function(ed, e) {350			 *            console.debug('Form reset:' + e.target);351			 *       });352			 *    }353			 * });354			 */355			'onReset',356			/**357			 * Fires when a paste event is intercepted inside the editor.358			 *359			 * @event onPaste360			 * @param {tinymce.Editor} sender Editor instance.361			 * @param {Event} evt W3C DOM Event instance.362			 * @example363			 * // Adds an observer to the onPaste event using tinyMCE.init364			 * tinyMCE.init({365			 *    ...366			 *    setup : function(ed) {367			 *       ed.onPaste.add(function(ed, e) {368			 *            console.debug('Pasted plain text');369			 *       });370			 *    }371			 * });372			 */373			'onPaste',374			/**375			 * Fires when the Serializer does a preProcess on the contents.376			 *377			 * @event onPreProcess378			 * @param {tinymce.Editor} sender Editor instance.379			 * @param {Object} obj PreProcess object.380			 * @option {Node} node DOM node for the item being serialized.381			 * @option {String} format The specified output format normally "html".382			 * @option {Boolean} get Is true if the process is on a getContent operation.383			 * @option {Boolean} set Is true if the process is on a setContent operation.384			 * @option {Boolean} cleanup Is true if the process is on a cleanup operation.385			 * @example386			 * // Adds an observer to the onPreProcess event using tinyMCE.init387			 * tinyMCE.init({388			 *    ...389			 *    setup : function(ed) {390			 *       ed.onPreProcess.add(function(ed, o) {391			 *            // Add a class to each paragraph in the editor392			 *            ed.dom.addClass(ed.dom.select('p', o.node), 'myclass');393			 *       });394			 *    }395			 * });396			 */397			'onPreProcess',398			/**399			 * Fires when the Serializer does a postProcess on the contents.400			 *401			 * @event onPostProcess402			 * @param {tinymce.Editor} sender Editor instance.403			 * @param {Object} obj PreProcess object.404			 * @example405			 * // Adds an observer to the onPostProcess event using tinyMCE.init406			 * tinyMCE.init({407			 *    ...408			 *    setup : function(ed) {409			 *       ed.onPostProcess.add(function(ed, o) {410			 *            // Remove all paragraphs and replace with BR411			 *            o.content = o.content.replace(/<p[^>]+>|<p>/g, '');412			 *            o.content = o.content.replace(/<\/p>/g, '<br />');413			 *       });414			 *    }415			 * });416			 */417			'onPostProcess',418			/**419			 * Fires before new contents is added to the editor. Using for example setContent.420			 *421			 * @event onBeforeSetContent422			 * @param {tinymce.Editor} sender Editor instance.423			 * @example424			 * // Adds an observer to the onBeforeSetContent event using tinyMCE.init425			 * tinyMCE.init({426			 *    ...427			 *    setup : function(ed) {428			 *       ed.onBeforeSetContent.add(function(ed, o) {429			 *            // Replaces all a characters with b characters430			 *            o.content = o.content.replace(/a/g, 'b');431			 *       });432			 *    }433			 * });434			 */435			'onBeforeSetContent',436			/**437			 * Fires before contents is extracted from the editor using for example getContent.438			 *439			 * @event onBeforeGetContent440			 * @param {tinymce.Editor} sender Editor instance.441			 * @param {Event} evt W3C DOM Event instance.442			 * @example443			 * // Adds an observer to the onBeforeGetContent event using tinyMCE.init444			 * tinyMCE.init({445			 *    ...446			 *    setup : function(ed) {447			 *       ed.onBeforeGetContent.add(function(ed, o) {448			 *            console.debug('Before get content.');449			 *       });450			 *    }451			 * });452			 */453			'onBeforeGetContent',454			/**455			 * Fires after the contents has been added to the editor using for example onSetContent.456			 *457			 * @event onSetContent458			 * @param {tinymce.Editor} sender Editor instance.459			 * @example460			 * // Adds an observer to the onSetContent event using tinyMCE.init461			 * tinyMCE.init({462			 *    ...463			 *    setup : function(ed) {464			 *       ed.onSetContent.add(function(ed, o) {465			 *            // Replaces all a characters with b characters466			 *            o.content = o.content.replace(/a/g, 'b');467			 *       });468			 *    }469			 * });470			 */471			'onSetContent',472			/**473			 * Fires after the contents has been extracted from the editor using for example getContent.474			 *475			 * @event onGetContent476			 * @param {tinymce.Editor} sender Editor instance.477			 * @example478			 * // Adds an observer to the onGetContent event using tinyMCE.init479			 * tinyMCE.init({480			 *    ...481			 *    setup : function(ed) {482			 *       ed.onGetContent.add(function(ed, o) {483			 *           // Replace all a characters with b484			 *           o.content = o.content.replace(/a/g, 'b');485			 *       });486			 *    }487			 * });488			 */489			'onGetContent',490			/**491			 * Fires when the editor gets loaded with contents for example when the load method is executed.492			 *493			 * @event onLoadContent494			 * @param {tinymce.Editor} sender Editor instance.495			 * @example496			 * // Adds an observer to the onLoadContent event using tinyMCE.init497			 * tinyMCE.init({498			 *    ...499			 *    setup : function(ed) {500			 *       ed.onLoadContent.add(function(ed, o) {501			 *           // Output the element name502			 *           console.debug(o.element.nodeName);503			 *       });504			 *    }505			 * });506			 */507			'onLoadContent',508			/**509			 * Fires when the editor contents gets saved for example when the save method is executed.510			 *511			 * @event onSaveContent512			 * @param {tinymce.Editor} sender Editor instance.513			 * @example514			 * // Adds an observer to the onSaveContent event using tinyMCE.init515			 * tinyMCE.init({516			 *    ...517			 *    setup : function(ed) {518			 *       ed.onSaveContent.add(function(ed, o) {519			 *           // Output the element name520			 *           console.debug(o.element.nodeName);521			 *       });522			 *    }523			 * });524			 */525			'onSaveContent',526			/**527			 * Fires when the user changes node location using the mouse or keyboard.528			 *529			 * @event onNodeChange530			 * @param {tinymce.Editor} sender Editor instance.531			 * @example532			 * // Adds an observer to the onNodeChange event using tinyMCE.init533			 * tinyMCE.init({534			 *    ...535			 *    setup : function(ed) {536			 *       ed.onNodeChange.add(function(ed, cm, e) {537			 *           // Activates the link button when the caret is placed in a anchor element538			 *           if (e.nodeName == 'A')539			 *              cm.setActive('link', true);540			 *       });541			 *    }542			 * });543			 */544			'onNodeChange',545			/**546			 * Fires when a new undo level is added to the editor.547			 *548			 * @event onChange549			 * @param {tinymce.Editor} sender Editor instance.550			 * @example551			 * // Adds an observer to the onChange event using tinyMCE.init552			 * tinyMCE.init({553			 *    ...554			 *    setup : function(ed) {555			 *       ed.onChange.add(function(ed, l) {556			 *          console.debug('Editor contents was modified. Contents: ' + l.content);557			 *       });558			 *    }559			 * });560			 */561			'onChange',562			/**563			 * Fires before a command gets executed for example "Bold".564			 *565			 * @event onBeforeExecCommand566			 * @param {tinymce.Editor} sender Editor instance.567			 * @example568			 * // Adds an observer to the onBeforeExecCommand event using tinyMCE.init569			 * tinyMCE.init({570			 *    ...571			 *    setup : function(ed) {572			 *       ed.onBeforeExecCommand.add(function(ed, cmd, ui, val) {573			 *           console.debug('Command is to be executed: ' + cmd);574			 *       });575			 *    }576			 * });577			 */578			'onBeforeExecCommand',579			/**580			 * Fires after a command is executed for example "Bold".581			 *582			 * @event onExecCommand583			 * @param {tinymce.Editor} sender Editor instance.584			 * @example585			 * // Adds an observer to the onExecCommand event using tinyMCE.init586			 * tinyMCE.init({587			 *    ...588			 *    setup : function(ed) {589			 *       ed.onExecCommand.add(function(ed, cmd, ui, val) {590			 *           console.debug('Command was executed: ' + cmd);591			 *       });592			 *    }593			 * });594			 */595			'onExecCommand',596			/**597			 * Fires when the contents is undo:ed.598			 *599			 * @event onUndo600			 * @param {tinymce.Editor} sender Editor instance.601			 * @param {Object} level Undo level object.602			 * @ example603			 * // Adds an observer to the onUndo event using tinyMCE.init604			 * tinyMCE.init({605			 *    ...606			 *    setup : function(ed) {607			 *       ed.onUndo.add(function(ed, level) {608			 *           console.debug('Undo was performed: ' + level.content);609			 *       });610			 *    }611			 * });612			 */613			'onUndo',614			/**615			 * Fires when the contents is redo:ed.616			 *617			 * @event onRedo618			 * @param {tinymce.Editor} sender Editor instance.619			 * @param {Object} level Undo level object.620			 * @example621			 * // Adds an observer to the onRedo event using tinyMCE.init622			 * tinyMCE.init({623			 *    ...624			 *    setup : function(ed) {625			 *       ed.onRedo.add(function(ed, level) {626			 *           console.debug('Redo was performed: ' +level.content);627			 *       });628			 *    }629			 * });630			 */631			'onRedo',632			/**633			 * Fires when visual aids is enabled/disabled.634			 *635			 * @event onVisualAid636			 * @param {tinymce.Editor} sender Editor instance.637			 * @example638			 * // Adds an observer to the onVisualAid event using tinyMCE.init639			 * tinyMCE.init({640			 *    ...641			 *    setup : function(ed) {642			 *       ed.onVisualAid.add(function(ed, e, s) {643			 *           console.debug('onVisualAid event: ' + ed.id + ", State: " + s);644			 *       });645			 *    }646			 * });647			 */648			'onVisualAid',649			/**650			 * Fires when the progress throbber is shown above the editor.651			 *652			 * @event onSetProgressState653			 * @param {tinymce.Editor} sender Editor instance.654			 * @example655			 * // Adds an observer to the onSetProgressState event using tinyMCE.init656			 * tinyMCE.init({657			 *    ...658			 *    setup : function(ed) {659			 *       ed.onSetProgressState.add(function(ed, b) {660			 *            if (b)661			 *                 console.debug('SHOW!');662			 *            else663			 *                 console.debug('HIDE!');664			 *       });665			 *    }666			 * });667			 */668			'onSetProgressState',669			/**670			 * Fires after an attribute is set using setAttrib.671			 *672			 * @event onSetAttrib673			 * @param {tinymce.Editor} sender Editor instance.674			 * @example675			 * // Adds an observer to the onSetAttrib event using tinyMCE.init676			 *tinyMCE.init({677			 *    ...678			 *    setup : function(ed) {679			 *       ed.onSetAttrib.add(function(ed, node, attribute, attributeValue) {680			 *            console.log('onSetAttrib tag');681			 *       });682			 *    }683			 * });684			 */685			'onSetAttrib'686		], function(name) {687			self[name] = new tinymce.util.Dispatcher(self);688		});689		// Handle legacy cleanup_callback option690		if (settings.cleanup_callback) {691			self.onBeforeSetContent.add(function(ed, o) {692				o.content = ed.execCallback('cleanup_callback', 'insert_to_editor', o.content, o);693			});694			self.onPreProcess.add(function(ed, o) {695				if (o.set)696					ed.execCallback('cleanup_callback', 'insert_to_editor_dom', o.node, o);697				if (o.get)698					ed.execCallback('cleanup_callback', 'get_from_editor_dom', o.node, o);699			});700			self.onPostProcess.add(function(ed, o) {701				if (o.set)702					o.content = ed.execCallback('cleanup_callback', 'insert_to_editor', o.content, o);703				if (o.get)						704					o.content = ed.execCallback('cleanup_callback', 'get_from_editor', o.content, o);705			});706		}707		// Handle legacy save_callback option708		if (settings.save_callback) {709			self.onGetContent.add(function(ed, o) {710				if (o.save)711					o.content = ed.execCallback('save_callback', ed.id, o.content, ed.getBody());712			});713		}714		// Handle legacy handle_event_callback option715		if (settings.handle_event_callback) {716			self.onEvent.add(function(ed, e, o) {717				if (self.execCallback('handle_event_callback', e, ed, o) === false) {718					e.preventDefault();719					e.stopPropagation();720				}721			});722		}723		// Handle legacy handle_node_change_callback option724		if (settings.handle_node_change_callback) {725			self.onNodeChange.add(function(ed, cm, n) {726				ed.execCallback('handle_node_change_callback', ed.id, n, -1, -1, true, ed.selection.isCollapsed());727			});728		}729		// Handle legacy save_callback option730		if (settings.save_callback) {731			self.onSaveContent.add(function(ed, o) {732				var h = ed.execCallback('save_callback', ed.id, o.content, ed.getBody());733				if (h)734					o.content = h;735			});736		}737		// Handle legacy onchange_callback option738		if (settings.onchange_callback) {739			self.onChange.add(function(ed, l) {740				ed.execCallback('onchange_callback', ed, l);741			});742		}743	};744	/**745	 * Binds native DOM events and sends these out to the dispatchers.746	 */747	tinymce.Editor.prototype.bindNativeEvents = function() {748		// 'focus', 'blur', 'dblclick', 'beforedeactivate', submit, reset749		var self = this, i, settings = self.settings, dom = self.dom, nativeToDispatcherMap;750		nativeToDispatcherMap = {751			mouseup : 'onMouseUp',752			mousedown : 'onMouseDown',753			click : 'onClick',754			keyup : 'onKeyUp',755			keydown : 'onKeyDown',756			keypress : 'onKeyPress',757			submit : 'onSubmit',758			reset : 'onReset',759			contextmenu : 'onContextMenu',760			dblclick : 'onDblClick',761			paste : 'onPaste' // Doesn't work in all browsers yet762		};763		// Handler that takes a native event and sends it out to a dispatcher like onKeyDown764		function eventHandler(evt, args) {765			var type = evt.type;766			// Don't fire events when it's removed767			if (self.removed)768				return;769			// Sends the native event out to a global dispatcher then to the specific event dispatcher770			if (self.onEvent.dispatch(self, evt, args) !== false) {771				self[nativeToDispatcherMap[evt.fakeType || evt.type]].dispatch(self, evt, args);772			}773		};774		// Opera doesn't support focus event for contentEditable elements so we need to fake it775		function doOperaFocus(e) {776			self.focus(true);777		};778		function nodeChanged(ed, e) {779			// Normalize selection for example <b>a</b><i>|a</i> becomes <b>a|</b><i>a</i> except for Ctrl+A since it selects everything780			if (e.keyCode != 65 || !tinymce.VK.metaKeyPressed(e)) {781				self.selection.normalize();782			}783			self.nodeChanged();784		}785		// Add DOM events786		each(nativeToDispatcherMap, function(dispatcherName, nativeName) {787			var root = settings.content_editable ? self.getBody() : self.getDoc();788			switch (nativeName) {789				case 'contextmenu':790					dom.bind(root, nativeName, eventHandler);791					break;792				case 'paste':793					dom.bind(self.getBody(), nativeName, eventHandler);794					break;795				case 'submit':796				case 'reset':797					dom.bind(self.getElement().form || tinymce.DOM.getParent(self.id, 'form'), nativeName, eventHandler);798					break;799				default:800					dom.bind(root, nativeName, eventHandler);801			}802		});803		// Set the editor as active when focused804		dom.bind(settings.content_editable ? self.getBody() : (tinymce.isGecko ? self.getDoc() : self.getWin()), 'focus', function(e) {805			self.focus(true);806		});807		if (settings.content_editable && tinymce.isOpera) {808			dom.bind(self.getBody(), 'click', doOperaFocus);809			dom.bind(self.getBody(), 'keydown', doOperaFocus);810		}811		// Add node change handler812		self.onMouseUp.add(nodeChanged);813		self.onKeyUp.add(function(ed, e) {814			var keyCode = e.keyCode;815			if ((keyCode >= 33 && keyCode <= 36) || (keyCode >= 37 && keyCode <= 40) || keyCode == 13 || keyCode == 45 || keyCode == 46 || keyCode == 8 || (tinymce.isMac && (keyCode == 91 || keyCode == 93)) || e.ctrlKey)816				nodeChanged(ed, e);817		});818		// Add reset handler819		self.onReset.add(function() {820			self.setContent(self.startContent, {format : 'raw'});821		});822		// Add shortcuts823		function handleShortcut(e, execute) {824			if (e.altKey || e.ctrlKey || e.metaKey) {825				each(self.shortcuts, function(shortcut) {826					var ctrlState = tinymce.isMac ? e.metaKey : e.ctrlKey;827					if (shortcut.ctrl != ctrlState || shortcut.alt != e.altKey || shortcut.shift != e.shiftKey)828						return;829					if (e.keyCode == shortcut.keyCode || (e.charCode && e.charCode == shortcut.charCode)) {830						e.preventDefault();831						if (execute) {832							shortcut.func.call(shortcut.scope);833						}834						return true;835					}836				});837			}838		};839		self.onKeyUp.add(function(ed, e) {840			handleShortcut(e);841		});842		self.onKeyPress.add(function(ed, e) {843			handleShortcut(e);844		});845		self.onKeyDown.add(function(ed, e) {846			handleShortcut(e, true);847		});848		if (tinymce.isOpera) {849			self.onClick.add(function(ed, e) {850				e.preventDefault();851			});852		}853	};...mobileTextEditorSpec.js
Source:mobileTextEditorSpec.js  
1  describe("MobileTextEditor", function () {2    var id = 'testContainer';3    beforeEach(function () {4      this.$container = $('<div id="' + id + '"></div>').appendTo('body');5    });6    afterEach(function () {7      if (this.$container) {8        destroy();9        this.$container.remove();10      }11    });12    describe("at init: ", function () {13      it("should recognize a mobile browser by a useragent string", function () {14        var mobileUserAgentStrings = [15          'Mozilla/5.0 (iPhone; CPU iPhone OS 8_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B411 Safari/600.1.4',16          'Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D257 Safari/9537.53',17          'Mozilla/5.0 (iPad; CPU OS 8_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B410 Safari/600.1.4',18          'Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B435 Safari/600.1.4',19          'Mozilla/5.0 (Linux; U; Android 4.0.3; ko-kr; LG-L160L Build/IML74K) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',20          'Mozilla/5.0 (Linux; U; Android 4.0.3; de-ch; HTC Sensation Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',21          'Mozilla/5.0 (Linux; U; Android 2.3.5; en-us; HTC Vision Build/GRI40) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',22          'Mozilla/5.0 (Linux; U; Android 2.3.4; fr-fr; HTC Desire Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',23          'Mozilla/5.0 (Linux; U; Android 2.3.3; zh-tw; HTC_Pyramid Build/GRI40) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari',24          'Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0)',25          'HTC_Touch_3G Mozilla/4.0 (compatible; MSIE 6.0; Windows CE; IEMobile 7.11)',26          'Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0; Nokia;N70)'27        ];28        var desktopUserAgentStrings = [29          'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36',30          'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0',31          'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10) AppleWebKit/600.1.25 (KHTML, like Gecko) Version/8.0 Safari/600.1.25',32          'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36',33          'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/600.1.25 (KHTML, like Gecko) Version/8.0 Safari/600.1.25',34          'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36',35          'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko',36          'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/600.1.17 (KHTML, like Gecko) Version/7.1 Safari/537.85.10',37          'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:33.0) Gecko/20100101 Firefox/33.0',38          'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36'39        ];40        for(var i = 0, mobileCount = mobileUserAgentStrings.length; i < mobileCount; i++) {41          expect(Handsontable.helper.isMobileBrowser(mobileUserAgentStrings[i])).toEqual(true);42        }43        for(var i = 0, desktopCount = desktopUserAgentStrings.length; i < desktopCount; i++) {44          expect(Handsontable.helper.isMobileBrowser(desktopUserAgentStrings[i])).toEqual(false);45        }46      });47      it("tap (touchstart) should be translated to mousedown", function () {48        var onAfterOnCellMouseDown = jasmine.createSpy('onAfterOnCellMouseDown');49        var hot = handsontable({50          data: Handsontable.helper.createSpreadsheetObjectData(10, 5),51          width: 400,52          height: 400,53          afterOnCellMouseDown: onAfterOnCellMouseDown54        });55        var cell = hot.getCell(1, 1);56        expect(getSelected()).toBeUndefined();57        triggerTouchEvent('touchstart', cell);58        waitsFor(function () {59          return onAfterOnCellMouseDown.calls.length > 0;60        }, 'Mousedown on Cell event', 1000);61        runs(function () {62          expect(getSelected()).toBeDefined();63        });64      });65      it("should close the editor on tap outside the editor", function () {66        var onAfterOnCellMouseDown = jasmine.createSpy('onAfterOnCellMouseDown');67        var hot = handsontable({68          data: Handsontable.helper.createSpreadsheetObjectData(10, 5),69          width: 400,70          height: 400,71          afterOnCellMouseDown: onAfterOnCellMouseDown72        });73        var cell = hot.getCell(1, 1);74        mouseDoubleClick(cell); // should test it properly, if touch->mousedown translation works75        waitsFor(function () {76          return onAfterOnCellMouseDown.calls.length > 1;77        }, 'Mousedown on Cell event', 1000);78        runs(function () {79          expect(document.querySelector(".htMobileEditorContainer")).toBeTruthy();80          expect(document.querySelector(".htMobileEditorContainer").offsetParent).toBeTruthy();81          triggerTouchEvent('touchstart', getCell(0, 4));82          waitsFor(function () {83            return onAfterOnCellMouseDown.calls.length > 2;84          }, 'Mousedown on Cell event', 1000);85          runs(function () {86            expect(document.querySelector(".htMobileEditorContainer").offsetParent).toBeFalsy();87          });88        });89      });90      it("should set the cell pointer's position to point to the edited cell", function () {91        var onAfterOnCellMouseDown = jasmine.createSpy('onAfterOnCellMouseDown');92        var hot = handsontable({93          data: Handsontable.helper.createSpreadsheetObjectData(10, 5),94          width: 400,95          height: 400,96          afterOnCellMouseDown: onAfterOnCellMouseDown97        });98        var cell = hot.getCell(2, 3);99        mouseDoubleClick(cell);100        waitsFor(function () {101          return onAfterOnCellMouseDown.calls.length > 1; // doubleclicked on a cell -> editor should open102        }, 'Mousedown on Cell event', 1000);103        runs(function () {104          var cellPosition = Handsontable.Dom.offset(cell)105            , cellWidth = Handsontable.Dom.outerWidth(cell)106            , cellPointer = getActiveEditor().cellPointer107            , cellPointerPosition = Handsontable.Dom.offset(getActiveEditor().cellPointer)108            , cellPointerWidth = Handsontable.Dom.outerWidth(getActiveEditor().cellPointer);109          expect(Math.ceil(cellPosition.left + cellWidth / 2)).toEqual(Math.ceil(cellPointerPosition.left + cellPointerWidth / 2));110        });111      });112      it("should center the editor after opening if the edited cell horizontal position is within editor boundaries", function () {113        var onAfterOnCellMouseDown = jasmine.createSpy('onAfterOnCellMouseDown');114        var hot = handsontable({115          data: Handsontable.helper.createSpreadsheetObjectData(10, 5),116          width: 400,117          height: 400,118          afterOnCellMouseDown: onAfterOnCellMouseDown119        });120        var cell = hot.getCell(2, 4);121        mouseDoubleClick(cell);122        waitsFor(function () {123          return onAfterOnCellMouseDown.calls.length > 1; // doubleclicked on a cell -> editor should open124        }, 'Mousedown on Cell event', 1000);125        runs(function () {126          var editor = getActiveEditor()127            , editorWidth = Handsontable.Dom.outerWidth(editor.editorContainer)128            , editorPosition = Handsontable.Dom.offset(editor.editorContainer);129          expect(Math.ceil(editorPosition.left + editorWidth / 2)).toEqual(Math.ceil(window.innerWidth / 2));130        });131      });132      it("should snap the editor to the right side of the screen if the edited cell is on the right side of the editor", function () {133        var onAfterOnCellMouseDown = jasmine.createSpy('onAfterOnCellMouseDown');134        var hot = handsontable({135          data: Handsontable.helper.createSpreadsheetObjectData(10, 24),136          width: window.innerWidth,137          height: 400,138          afterOnCellMouseDown: onAfterOnCellMouseDown139        });140        var cell = hot.getCell(2, 23);141        mouseDoubleClick(cell);142        waitsFor(function () {143          return onAfterOnCellMouseDown.calls.length > 1; // doubleclicked on a cell -> editor should open144        }, 'Mousedown on Cell event', 1000);145        runs(function () {146          var editor = getActiveEditor()147            , editorWidth = Handsontable.Dom.outerWidth(editor.editorContainer)148            , editorPosition = Handsontable.Dom.offset(editor.editorContainer);149          expect(Math.ceil(editorPosition.left + editorWidth)).toEqual(window.innerWidth);150        });151      });152      it("should snap the editor to the left side of the screen if the edited cell is on the left side of the editor", function () {153        var onAfterOnCellMouseDown = jasmine.createSpy('onAfterOnCellMouseDown');154        var hot = handsontable({155          data: Handsontable.helper.createSpreadsheetObjectData(10, 5),156          width: 400,157          height: 400,158          afterOnCellMouseDown: onAfterOnCellMouseDown159        });160        var cell = hot.getCell(2, 0);161        mouseDoubleClick(cell);162        waitsFor(function () {163          return onAfterOnCellMouseDown.calls.length > 1; // doubleclicked on a cell -> editor should open164        }, 'Mousedown on Cell event', 1000);165        runs(function () {166          var editor = getActiveEditor()167            , editorPosition = Handsontable.Dom.offset(editor.editorContainer);168          expect(editorPosition.left).toEqual(0);169        });170      });171      it("should be positioned right below the edited cell", function () {172        var onAfterOnCellMouseDown = jasmine.createSpy('onAfterOnCellMouseDown');173        var hot = handsontable({174          data: Handsontable.helper.createSpreadsheetObjectData(10, 5),175          width: 400,176          height: 400,177          afterOnCellMouseDown: onAfterOnCellMouseDown178        });179        var cell = hot.getCell(2, 3);180        mouseDoubleClick(cell);181        waitsFor(function () {182          return onAfterOnCellMouseDown.calls.length > 1; // doubleclicked on a cell -> editor should open183        }, 'Mousedown on Cell event', 1000);184        runs(function () {185          var editor = getActiveEditor()186            , cellPosition = Handsontable.Dom.offset(cell)187            , cellHeight = Handsontable.Dom.outerHeight(cell)188            , editorPosition = Handsontable.Dom.offset(editor.editorContainer)189            , cellPointerHeight = Handsontable.Dom.outerHeight(editor.cellPointer);190          expect(editorPosition.top - cellPointerHeight).toEqual(cellPosition.top + cellHeight);191        });192      });193      it("should apply the changes after tapping outside the editor", function () {194        var onAfterOnCellMouseDown = jasmine.createSpy('onAfterOnCellMouseDown');195        var hot = handsontable({196          data: Handsontable.helper.createSpreadsheetObjectData(10, 5),197          width: 400,198          height: 400,199          afterOnCellMouseDown: onAfterOnCellMouseDown200        });201        var cell = hot.getCell(2, 3);202        mouseDoubleClick(cell);203        waitsFor(function () {204          return onAfterOnCellMouseDown.calls.length > 1; // doubleclicked on a cell -> editor should open205        }, 'Mousedown on Cell event', 1000);206        runs(function () {207          var editor = getActiveEditor();208          editor.setValue('done!');209          expect(cell.innerText).toEqual('D3');210          triggerTouchEvent('touchstart', getCell(0, 0));211          waitsFor(function () {212            return onAfterOnCellMouseDown.calls.length > 2;213          }, 'Mousedown on Cell event', 1000);214          runs(function () {215            expect(cell.innerText).toEqual('done!');216          });217        });218      });219      describe(" Move Controls:", function () {220        it("should change the selected cell in the appropriate direction after hitting the controller button", function () {221          var onAfterOnCellMouseDown = jasmine.createSpy('onAfterOnCellMouseDown');222          var hot = handsontable({223            data: Handsontable.helper.createSpreadsheetObjectData(10, 5),224            width: 400,225            height: 400,226            afterOnCellMouseDown: onAfterOnCellMouseDown227          });228          var cell = hot.getCell(2, 3);229          mouseDoubleClick(cell);230          waitsFor(function () {231            return onAfterOnCellMouseDown.calls.length > 1; // doubleclicked on a cell -> editor should open232          }, 'Mousedown on Cell event', 1000);233          runs(function () {234            var editor = getActiveEditor()235              , selected = getSelected();236            expect(selected[1]).toEqual(3);237            triggerTouchEvent('touchend', editor.controls.leftButton);238            waits(10);239            runs(function () {240              selected = getSelected();241              expect(selected[1]).toEqual(2);242            });243          });244          runs(function () {245            var editor = getActiveEditor()246              , selected = getSelected();247            expect(selected[0]).toEqual(2);248            expect(selected[1]).toEqual(2);249            triggerTouchEvent('touchend', editor.controls.upButton);250            waits(10);251            runs(function () {252              selected = getSelected();253              expect(selected[0]).toEqual(1);254              expect(selected[1]).toEqual(2);255            });256          });257          runs(function () {258            var editor = getActiveEditor()259              , selected = getSelected();260            expect(selected[0]).toEqual(1);261            expect(selected[1]).toEqual(2);262            triggerTouchEvent('touchend', editor.controls.rightButton);263            waits(10);264            runs(function () {265              selected = getSelected();266              expect(selected[0]).toEqual(1);267              expect(selected[1]).toEqual(3);268            });269          });270          runs(function () {271            var editor = getActiveEditor()272              , selected = getSelected();273            expect(selected[0]).toEqual(1);274            expect(selected[1]).toEqual(3);275            triggerTouchEvent('touchend', editor.controls.downButton);276            waits(10);277            runs(function () {278              selected = getSelected();279              expect(selected[0]).toEqual(2);280              expect(selected[1]).toEqual(3);281            });282          });283        });284        it("should change the editor's input value to the value of the newly selected cell", function () {285          var onAfterOnCellMouseDown = jasmine.createSpy('onAfterOnCellMouseDown');286          var hot = handsontable({287            data: Handsontable.helper.createSpreadsheetObjectData(10, 5),288            width: 400,289            height: 400,290            afterOnCellMouseDown: onAfterOnCellMouseDown291          });292          var cell = hot.getCell(2, 3);293          mouseDoubleClick(cell);294          waitsFor(function () {295            return onAfterOnCellMouseDown.calls.length > 1; // doubleclicked on a cell -> editor should open296          }, 'Mousedown on Cell event', 1000);297          runs(function () {298            var editor = getActiveEditor();299            expect(editor.getValue()).toEqual(cell.innerText);300            triggerTouchEvent('touchend', editor.controls.leftButton);301            waits(10);302            runs(function () {303              var newSelection = getSelected();304              expect(editor.getValue()).toEqual(getCell(newSelection[0], newSelection[1]).innerText);305            });306            runs(function () {307              triggerTouchEvent('touchend', editor.controls.upButton);308              waits(10);309              runs(function () {310                var newSelection = getSelected();311                expect(editor.getValue()).toEqual(getCell(newSelection[0], newSelection[1]).innerText);312              });313            });314            runs(function () {315              triggerTouchEvent('touchend', editor.controls.rightButton);316              waits(10);317              runs(function () {318                var newSelection = getSelected();319                expect(editor.getValue()).toEqual(getCell(newSelection[0], newSelection[1]).innerText);320              });321            });322            runs(function () {323              triggerTouchEvent('touchend', editor.controls.downButton);324              waits(10);325              runs(function () {326                var newSelection = getSelected();327                expect(editor.getValue()).toEqual(getCell(newSelection[0], newSelection[1]).innerText);328              });329            });330          });331        });332        it("should apply the changes after moving selection elsewhere", function () {333          var onAfterOnCellMouseDown = jasmine.createSpy('onAfterOnCellMouseDown');334          var hot = handsontable({335            data: Handsontable.helper.createSpreadsheetObjectData(10, 5),336            width: 400,337            height: 400,338            afterOnCellMouseDown: onAfterOnCellMouseDown339          });340          var cell = hot.getCell(2, 3);341          mouseDoubleClick(cell);342          waitsFor(function () {343            return onAfterOnCellMouseDown.calls.length > 1; // doubleclicked on a cell -> editor should open344          }, 'Mousedown on Cell event', 1000);345          runs(function () {346            var editor = getActiveEditor();347            expect(cell.innerText).toEqual('D3');348            editor.TEXTAREA.value = 'done!';349            triggerTouchEvent('touchend', editor.controls.leftButton);350            waits(10);351            runs(function () {352              expect(cell.innerText).toEqual('done!');353            });354            runs(function () {355              var newSelection = getSelected();356              expect(getCell(newSelection[0], newSelection[1]).innerText).toEqual('C3');357              editor.TEXTAREA.value = 'done!';358              triggerTouchEvent('touchend', editor.controls.upButton);359              waits(10);360              runs(function () {361                expect(getCell(newSelection[0], newSelection[1]).innerText).toEqual('done!');362              });363            });364            runs(function () {365              var newSelection = getSelected();366              expect(getCell(newSelection[0], newSelection[1]).innerText).toEqual('C2');367              editor.TEXTAREA.value = 'done!';368              triggerTouchEvent('touchend', editor.controls.rightButton);369              waits(10);370              runs(function () {371                expect(getCell(newSelection[0], newSelection[1]).innerText).toEqual('done!');372              });373            });374            runs(function () {375              var newSelection = getSelected();376              expect(getCell(newSelection[0], newSelection[1]).innerText).toEqual('D2');377              editor.TEXTAREA.value = 'done!';378              triggerTouchEvent('touchend', editor.controls.downButton);379              waits(10);380              runs(function () {381                expect(getCell(newSelection[0], newSelection[1]).innerText).toEqual('done!');382              });383            });384            runs(function () {385              var newSelection = getSelected();386              expect(getCell(newSelection[0], newSelection[1]).innerText).toEqual('done!');387              editor.TEXTAREA.value = 'done.';388              triggerTouchEvent('touchend', editor.controls.downButton);389              waits(10);390              runs(function () {391                expect(getCell(newSelection[0], newSelection[1]).innerText).toEqual('done.');392              });393            });394          });395        });396      });397      describe("Editor moving:", function () {398        it("should move the editor after touch-and-dragging the position handle", function () {399          var onAfterOnCellMouseDown = jasmine.createSpy('onAfterOnCellMouseDown');400          var hot = handsontable({401            data: Handsontable.helper.createSpreadsheetObjectData(10, 5),402            width: 400,403            height: 400,404            afterOnCellMouseDown: onAfterOnCellMouseDown405          });406          var targetCoords;407          var editor;408          var cell = hot.getCell(2, 3);409          mouseDoubleClick(cell); // should work fine as a doubletouch if previous tests passed410          waitsFor(function () {411            return onAfterOnCellMouseDown.calls.length > 1; // doubleclicked on a cell -> editor should open412          }, 'Mousedown on Cell event', 1000);413          runs(function () {414            editor = getActiveEditor();415            triggerTouchEvent('touchstart', editor.moveHandle);416          });417          waits(10);418          runs(function () {419            targetCoords = getCell(3, 1).getBoundingClientRect();420            var pageX = parseInt(targetCoords.left + 3, 10);421            var pageY = parseInt(targetCoords.top + 3, 10);422            triggerTouchEvent('touchmove', editor.moveHandle, pageX, pageY);423          });424          waits(10);425          runs(function () {426            expect(parseInt(editor.editorContainer.style.left, 10)).toBeLessThan(targetCoords.left);427            expect(parseInt(editor.editorContainer.style.top, 10)).toBeLessThan(targetCoords.top);428          });429        });430        it("should hide the editor's cell pointer after manually moving the editor", function () {431          var onAfterOnCellMouseDown = jasmine.createSpy('onAfterOnCellMouseDown');432          var hot = handsontable({433            data: Handsontable.helper.createSpreadsheetObjectData(10, 5),434            width: 400,435            height: 400,436            afterOnCellMouseDown: onAfterOnCellMouseDown437          });438          var targetCoords;439          var editor;440          var cell = hot.getCell(2, 3);441          mouseDoubleClick(cell); // should work fine as a doubletouch if previous tests passed442          waitsFor(function () {443            return onAfterOnCellMouseDown.calls.length > 1; // doubleclicked on a cell -> editor should open444          }, 'Mousedown on Cell event', 1000);445          runs(function () {446            editor = getActiveEditor();447            expect(Handsontable.Dom.hasClass(editor.cellPointer, 'hidden')).toEqual(false);448            triggerTouchEvent('touchstart', editor.moveHandle);449          });450          waits(10);451          runs(function () {452            targetCoords = getCell(3, 1).getBoundingClientRect();453            var pageX = parseInt(targetCoords.left + 3, 10);454            var pageY = parseInt(targetCoords.top + 3, 10);455            triggerTouchEvent('touchmove', editor.moveHandle, pageX, pageY);456          });457          waits(10);458          runs(function () {459            expect(Handsontable.Dom.hasClass(editor.cellPointer, 'hidden')).toEqual(true);460          });461        });462      });463    });...BidiEngine.js
Source:BidiEngine.js  
1//>>built2define("dojox/string/BidiEngine",["dojo/_base/lang","dojo/_base/declare"],function(_1,_2){3_1.getObject("string",true,dojox);4var _3=_2("dojox.string.BidiEngine",null,{bidiTransform:function(_4,_5,_6){5if(!_4){6return "";7}8if(!_5&&!_6){9return _4;10}11var _7=/^[(I|V)][(L|R|C|D)][(Y|N)][(S|N)][N]$/;12if(!_7.test(_5)||!_7.test(_6)){13throw new Error("dojox.string.BidiEngine: the bidi layout string is wrong!");14}15if(_5==_6){16return _4;17}18var _8=_9(_5.charAt(1)),_a=_9(_6.charAt(1)),_b=(_5.charAt(0)=="I")?"L":_5.charAt(0),_c=(_6.charAt(0)=="I")?"L":_6.charAt(0),_d=_b+_8,_e=_c+_a,_f=_5.charAt(2)+_6.charAt(2);19if(_d){20bdx.defInFormat=_d;21}22if(_e){23bdx.defOutFormat=_e;24}25if(_f){26bdx.defSwap=_f;27}28var _10=_11(_4,_b+_8,_c+_a,_5.charAt(2)+_6.charAt(2)),_12=false;29if(_6.charAt(1)=="R"){30_12=true;31}else{32if(_6.charAt(1)=="C"||_6.charAt(1)=="D"){33_12=this.checkContextual(_10);34}35}36if(_5.charAt(3)==_6.charAt(3)){37return _10;38}else{39if(_6.charAt(3)=="S"){40return _13(_12,_10,true);41}42}43if(_6.charAt(3)=="N"){44return _14(_10,_12,true);45}46},checkContextual:function(_15){47var dir=_16(_15);48if(dir!="ltr"&&dir!="rtl"){49dir=document.dir.toLowerCase();50if(dir!="ltr"&&dir!="rtl"){51dir="ltr";52}53}54return dir;55},hasBidiChar:function(_17){56var _18=null,uc=null,hi=null;57for(var i=0;i<_17.length;i++){58uc=_17.charAt(i).charCodeAt(0);59hi=_19[uc>>8];60_18=hi<_1a?hi:_1b[hi-_1a][uc&255];61if(_18==_1c||_18==_1d){62return true;63}64if(_18==_1e){65break;66}67}68return false;69}});...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
