Best Python code snippet using playwright-python
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}});...LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!
