Best JavaScript code snippet using playwright-internal
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}});...
typeahead.js
Source:typeahead.js
2 * typeahead.js3 * https://github.com/twitter/typeahead.js4 * Copyright 2013-2014 Twitter, Inc. and other contributors; Licensed MIT5 */6var Typeahead = (function() {7 'use strict';8 // constructor9 // -----------10 function Typeahead(o, www) {11 var onFocused, onBlurred, onEnterKeyed, onTabKeyed, onEscKeyed, onUpKeyed,12 onDownKeyed, onLeftKeyed, onRightKeyed, onQueryChanged,13 onWhitespaceChanged;14 o = o || {};15 if (!o.input) {16 $.error('missing input');17 }18 if (!o.menu) {19 $.error('missing menu');20 }21 if (!o.eventBus) {22 $.error('missing event bus');23 }24 www.mixin(this);25 this.eventBus = o.eventBus;26 this.minLength = _.isNumber(o.minLength) ? o.minLength : 1;27 this.input = o.input;28 this.menu = o.menu;29 this.enabled = true;30 // activate the typeahead on init if the input has focus31 this.active = false;32 this.input.hasFocus() && this.activate();33 // detect the initial lang direction34 this.dir = this.input.getLangDir();35 this._hacks();36 this.menu.bind()37 .onSync('selectableClicked', this._onSelectableClicked, this)38 .onSync('asyncRequested', this._onAsyncRequested, this)39 .onSync('asyncCanceled', this._onAsyncCanceled, this)40 .onSync('asyncReceived', this._onAsyncReceived, this)41 .onSync('datasetRendered', this._onDatasetRendered, this)42 .onSync('datasetCleared', this._onDatasetCleared, this);43 // composed event handlers for input44 onFocused = c(this, 'activate', 'open', '_onFocused');45 onBlurred = c(this, 'deactivate', '_onBlurred');46 onEnterKeyed = c(this, 'isActive', 'isOpen', '_onEnterKeyed');47 onTabKeyed = c(this, 'isActive', 'isOpen', '_onTabKeyed');48 onEscKeyed = c(this, 'isActive', '_onEscKeyed');49 onUpKeyed = c(this, 'isActive', 'open', '_onUpKeyed');50 onDownKeyed = c(this, 'isActive', 'open', '_onDownKeyed');51 onLeftKeyed = c(this, 'isActive', 'isOpen', '_onLeftKeyed');52 onRightKeyed = c(this, 'isActive', 'isOpen', '_onRightKeyed');53 onQueryChanged = c(this, '_openIfActive', '_onQueryChanged');54 onWhitespaceChanged = c(this, '_openIfActive', '_onWhitespaceChanged');55 this.input.bind()56 .onSync('focused', onFocused, this)57 .onSync('blurred', onBlurred, this)58 .onSync('enterKeyed', onEnterKeyed, this)59 .onSync('tabKeyed', onTabKeyed, this)60 .onSync('escKeyed', onEscKeyed, this)61 .onSync('upKeyed', onUpKeyed, this)62 .onSync('downKeyed', onDownKeyed, this)63 .onSync('leftKeyed', onLeftKeyed, this)64 .onSync('rightKeyed', onRightKeyed, this)65 .onSync('queryChanged', onQueryChanged, this)66 .onSync('whitespaceChanged', onWhitespaceChanged, this)67 .onSync('langDirChanged', this._onLangDirChanged, this);68 }69 // instance methods70 // ----------------71 _.mixin(Typeahead.prototype, {72 // here's where hacks get applied and we don't feel bad about it73 _hacks: function hacks() {74 var $input, $menu;75 // these default values are to make testing easier76 $input = this.input.$input || $('<div>');77 $menu = this.menu.$node || $('<div>');78 // #705: if there's scrollable overflow, ie doesn't support79 // blur cancellations when the scrollbar is clicked80 //81 // #351: preventDefault won't cancel blurs in ie <= 882 $input.on('blur.tt', function($e) {83 var active, isActive, hasActive;84 active = document.activeElement;85 isActive = $menu.is(active);86 hasActive = $menu.has(active).length > 0;87 if (_.isMsie() && (isActive || hasActive)) {88 $e.preventDefault();89 // stop immediate in order to prevent Input#_onBlur from90 // getting exectued91 $e.stopImmediatePropagation();92 _.defer(function() { $input.focus(); });93 }94 });95 // #351: prevents input blur due to clicks within menu96 $menu.on('mousedown.tt', function($e) { $e.preventDefault(); });97 },98 // ### event handlers99 _onSelectableClicked: function onSelectableClicked(type, $el) {100 this.select($el);101 },102 _onDatasetCleared: function onDatasetCleared() {103 this._updateHint();104 },105 _onDatasetRendered: function onDatasetRendered(type, dataset, suggestions, async) {106 this._updateHint();107 this.eventBus.trigger('render', suggestions, async, dataset);108 },109 _onAsyncRequested: function onAsyncRequested(type, dataset, query) {110 this.eventBus.trigger('asyncrequest', query, dataset);111 },112 _onAsyncCanceled: function onAsyncCanceled(type, dataset, query) {113 this.eventBus.trigger('asynccancel', query, dataset);114 },115 _onAsyncReceived: function onAsyncReceived(type, dataset, query) {116 this.eventBus.trigger('asyncreceive', query, dataset);117 },118 _onFocused: function onFocused() {119 this._minLengthMet() && this.menu.update(this.input.getQuery());120 },121 _onBlurred: function onBlurred() {122 if (this.input.hasQueryChangedSinceLastFocus()) {123 this.eventBus.trigger('change', this.input.getQuery());124 }125 },126 _onEnterKeyed: function onEnterKeyed(type, $e) {127 var $selectable;128 if ($selectable = this.menu.getActiveSelectable()) {129 this.select($selectable) && $e.preventDefault();130 }131 },132 _onTabKeyed: function onTabKeyed(type, $e) {133 var $selectable;134 if ($selectable = this.menu.getActiveSelectable()) {135 this.select($selectable) && $e.preventDefault();136 }137 else if ($selectable = this.menu.getTopSelectable()) {138 this.autocomplete($selectable) && $e.preventDefault();139 }140 },141 _onEscKeyed: function onEscKeyed() {142 this.close();143 },144 _onUpKeyed: function onUpKeyed() {145 this.moveCursor(-1);146 },147 _onDownKeyed: function onDownKeyed() {148 this.moveCursor(+1);149 },150 _onLeftKeyed: function onLeftKeyed() {151 if (this.dir === 'rtl' && this.input.isCursorAtEnd()) {152 this.autocomplete(this.menu.getTopSelectable());153 }154 },155 _onRightKeyed: function onRightKeyed() {156 if (this.dir === 'ltr' && this.input.isCursorAtEnd()) {157 this.autocomplete(this.menu.getTopSelectable());158 }159 },160 _onQueryChanged: function onQueryChanged(e, query) {161 this._minLengthMet(query) ? this.menu.update(query) : this.menu.empty();162 },163 _onWhitespaceChanged: function onWhitespaceChanged() {164 this._updateHint();165 },166 _onLangDirChanged: function onLangDirChanged(e, dir) {167 if (this.dir !== dir) {168 this.dir = dir;169 this.menu.setLanguageDirection(dir);170 }171 },172 // ### private173 _openIfActive: function openIfActive() {174 this.isActive() && this.open();175 },176 _minLengthMet: function minLengthMet(query) {177 query = _.isString(query) ? query : (this.input.getQuery() || '');178 return query.length >= this.minLength;179 },180 _updateHint: function updateHint() {181 var $selectable, data, val, query, escapedQuery, frontMatchRegEx, match;182 $selectable = this.menu.getTopSelectable();183 data = this.menu.getSelectableData($selectable);184 val = this.input.getInputValue();185 if (data && !_.isBlankString(val) && !this.input.hasOverflow()) {186 query = Input.normalizeQuery(val);187 escapedQuery = _.escapeRegExChars(query);188 // match input value, then capture trailing text189 frontMatchRegEx = new RegExp('^(?:' + escapedQuery + ')(.+$)', 'i');190 match = frontMatchRegEx.exec(data.val);191 // clear hint if there's no trailing text192 match && this.input.setHint(val + match[1]);193 }194 else {195 this.input.clearHint();196 }197 },198 // ### public199 isEnabled: function isEnabled() {200 return this.enabled;201 },202 enable: function enable() {203 this.enabled = true;204 },205 disable: function disable() {206 this.enabled = false;207 },208 isActive: function isActive() {209 return this.active;210 },211 activate: function activate() {212 // already active213 if (this.isActive()) {214 return true;215 }216 // unable to activate either due to the typeahead being disabled217 // or due to the active event being prevented218 else if (!this.isEnabled() || this.eventBus.before('active')) {219 return false;220 }221 // activate222 else {223 this.active = true;224 this.eventBus.trigger('active');225 return true;226 }227 },228 deactivate: function deactivate() {229 // already idle230 if (!this.isActive()) {231 return true;232 }233 // unable to deactivate due to the idle event being prevented234 else if (this.eventBus.before('idle')) {235 return false;236 }237 // deactivate238 else {239 this.active = false;240 this.close();241 this.eventBus.trigger('idle');242 return true;243 }244 },245 isOpen: function isOpen() {246 return this.menu.isOpen();247 },248 open: function open() {249 if (!this.isOpen() && !this.eventBus.before('open')) {250 this.menu.open();251 this._updateHint();252 this.eventBus.trigger('open');253 }254 return this.isOpen();255 },256 close: function close() {257 if (this.isOpen() && !this.eventBus.before('close')) {258 this.menu.close();259 this.input.clearHint();260 this.input.resetInputValue();261 this.eventBus.trigger('close');262 }263 return !this.isOpen();264 },265 setVal: function setVal(val) {266 // expect val to be a string, so be safe, and coerce267 this.input.setQuery(_.toStr(val));268 },269 getVal: function getVal() {270 return this.input.getQuery();271 },272 select: function select($selectable) {273 var data = this.menu.getSelectableData($selectable);274 if (data && !this.eventBus.before('select', data.obj)) {275 this.input.setQuery(data.val, true);276 this.eventBus.trigger('select', data.obj);277 this.close();278 // return true if selection succeeded279 return true;280 }281 return false;282 },283 autocomplete: function autocomplete($selectable) {284 var query, data, isValid;285 query = this.input.getQuery();286 data = this.menu.getSelectableData($selectable);287 isValid = data && query !== data.val;288 if (isValid && !this.eventBus.before('autocomplete', data.obj)) {289 this.input.setQuery(data.val);290 this.eventBus.trigger('autocomplete', data.obj);291 // return true if autocompletion succeeded292 return true;293 }294 return false;295 },296 moveCursor: function moveCursor(delta) {297 var query, $candidate, data, payload, cancelMove;298 query = this.input.getQuery();299 $candidate = this.menu.selectableRelativeToCursor(delta);300 data = this.menu.getSelectableData($candidate);301 payload = data ? data.obj : null;302 // update will return true when it's a new query and new suggestions303 // need to be fetched â in this case we don't want to move the cursor304 cancelMove = this._minLengthMet() && this.menu.update(query);305 if (!cancelMove && !this.eventBus.before('cursorchange', payload)) {306 this.menu.setCursor($candidate);307 // cursor moved to different selectable308 if (data) {309 this.input.setInputValue(data.val);310 }311 // cursor moved off of selectables, back to input312 else {313 this.input.resetInputValue();314 this._updateHint();315 }316 this.eventBus.trigger('cursorchange', payload);317 // return true if move succeeded318 return true;319 }320 return false;321 },322 destroy: function destroy() {323 this.input.destroy();324 this.menu.destroy();325 }326 });327 return Typeahead;328 // helper functions329 // ----------------330 function c(ctx) {331 var methods = [].slice.call(arguments, 1);332 return function() {333 var args = [].slice.call(arguments);334 _.each(methods, function(method) {335 return ctx[method].apply(ctx, args);336 });337 };338 }...
dateValidatorSpec.js
Source:dateValidatorSpec.js
...149 runs(function () {150 expect(onAfterValidate).toHaveBeenCalledWith(true, '23/03/15', 1, 'date', undefined, undefined);151 });152 });153 describe("allowEmpty", function() {154 it("should not validate an empty string when allowEmpty is set as `false`", function () {155 var onAfterValidate = jasmine.createSpy('onAfterValidate');156 handsontable({157 data: arrayOfObjects(),158 columns: [159 {data: 'date', type: 'date', dateFormat: 'DD/MM/YY', allowEmpty: false},160 {data: 'name'},161 {data: 'lastName'}162 ],163 afterValidate: onAfterValidate164 });165 setDataAtCell(1, 0, '');166 waitsFor(function () {167 return onAfterValidate.calls.length > 0;168 }, 'Cell validation', 1000);169 runs(function () {170 expect(onAfterValidate).toHaveBeenCalledWith(false, '', 1, 'date', undefined, undefined);171 });172 });173 it("should not validate `null` when allowEmpty is set as `false`", function () {174 var onAfterValidate = jasmine.createSpy('onAfterValidate');175 handsontable({176 data: arrayOfObjects(),177 columns: [178 {data: 'date', type: 'date', dateFormat: 'DD/MM/YY', allowEmpty: false},179 {data: 'name'},180 {data: 'lastName'}181 ],182 afterValidate: onAfterValidate183 });184 setDataAtCell(1, 0, null);185 waitsFor(function () {186 return onAfterValidate.calls.length > 0;187 }, 'Cell validation', 1000);188 runs(function () {189 expect(onAfterValidate).toHaveBeenCalledWith(false, null, 1, 'date', undefined, undefined);190 });191 });192 it("should not validate `undefined` when allowEmpty is set as `false`", function () {193 var onAfterValidate = jasmine.createSpy('onAfterValidate');194 handsontable({195 data: arrayOfObjects(),196 columns: [197 {data: 'date', type: 'date', dateFormat: 'DD/MM/YY', allowEmpty: false},198 {data: 'name'},199 {data: 'lastName'}200 ],201 afterValidate: onAfterValidate202 });203 setDataAtCell(1, 0, void 0);204 waitsFor(function () {205 return onAfterValidate.calls.length > 0;206 }, 'Cell validation', 1000);207 runs(function () {208 expect(onAfterValidate).toHaveBeenCalledWith(false, void 0, 1, 'date', undefined, undefined);209 });210 });211 });212 describe("correctFormat", function() {213 it("should not make any changes to entered string if correctFormat is not set", function () {214 var onAfterValidate = jasmine.createSpy('onAfterValidate');215 handsontable({216 data: arrayOfObjects(),217 columns: [218 {data: 'date', type: 'date', dateFormat: "MM/DD/YY"},219 {data: 'name'},220 {data: 'lastName'}221 ],222 afterValidate: onAfterValidate223 });224 setDataAtCell(1, 0, '11/23/2013');225 waitsFor(function () {226 return onAfterValidate.calls.length > 0;...
index.js
Source:index.js
...74 proxyReq[kRes] = res75 proxyReq[kConnected] = false76 proxyReq[kOnRes] = onRes77 res78 .on('close', onComplete)79 .on('finish', onComplete)80 .on('error', onComplete)81 req82 .on('aborted', onComplete)83 .on('error', onComplete)84 proxyReq85 .on('error', onProxyReqError)86 .on('timeout', onProxyReqTimeout)87 .on('response', onProxyReqResponse)88 .on('upgrade', onProxyReqUpgrade)89 deferToConnect.call(proxyReq)90 return promise91}92function onSocket (socket) {93 if (!socket.connecting) {94 onProxyConnect.call(this)95 } else {96 socket.once('connect', onProxyConnect.bind(this))97 }98}99function deferToConnect () {100 if (this.socket) {101 onSocket.call(this, this.socket)102 } else {103 this.once('socket', onSocket)104 }105}106function onComplete (err) {107 const res = this[kRes]108 const req = res[kReq]109 if (!res[kProxyCallback]) {110 return111 }112 const proxyReq = req[kProxyReq]113 const proxySocket = res[kProxySocket]114 const proxyRes = res[kProxyRes]115 const callback = res[kProxyCallback]116 req[kProxyReq] = null117 res[kProxySocket] = null118 res[kProxyRes] = null119 res[kProxyCallback] = null120 res121 .off('close', onComplete)122 .off('finish', onComplete)123 .off('error', onComplete)124 req125 .off('close', onComplete)126 .off('aborted', onComplete)127 .off('error', onComplete)128 .off('data', onReqData)129 .off('end', onReqEnd)130 if (err) {131 err.connectedSocket = Boolean(proxyReq && proxyReq[kConnected])132 err.reusedSocket = Boolean(proxyReq && proxyReq.reusedSocket)133 }134 if (proxyReq) {135 proxyReq.off('drain', onProxyReqDrain)136 if (proxyReq.abort) {137 proxyReq.abort()138 } else if (proxyReq.destroy) {139 proxyReq.destroy()140 }141 }142 if (proxySocket) {143 proxySocket.destroy()144 }145 if (proxyRes) {146 proxyRes.destroy()147 }148 callback(err)149}150function onProxyConnect () {151 this[kConnected] = true152 if (153 this.method === 'GET' ||154 this.method === 'HEAD' ||155 this.method === 'OPTIONS'156 ) {157 // Dump request.158 this[kReq].resume()159 this.end()160 } else {161 this[kReq]162 .on('data', onReqData)163 .on('end', onReqEnd)164 this165 .on('drain', onProxyReqDrain)166 }167}168function onReqEnd () {169 this[kProxyReq].end()170}171function onReqData (buf) {172 if (!this[kProxyReq].write(buf)) {173 this.pause()174 }175}176function onProxyReqDrain () {177 this[kReq].resume()178}179function onProxyReqError (err) {180 err.statusCode = this[kConnected] ? 502 : 503181 onComplete.call(this, err)182}183function onProxyReqTimeout () {184 onComplete.call(this, new HttpError('proxy timeout', 'ETIMEDOUT', 504))185}186async function onProxyReqResponse (proxyRes) {187 const res = this[kRes]188 res[kProxyRes] = proxyRes189 proxyRes[kRes] = res190 const headers = setupHeaders(proxyRes.headers)191 proxyRes.on('aborted', onProxyResAborted).on('error', onProxyResError)192 if (this[kOnRes]) {193 try {194 await this[kOnRes](proxyRes, headers)195 } catch (err) {196 onComplete.call(this, err)197 }198 } else if (!res.writeHead) {199 if (!proxyRes.upgrade) {200 res.write(201 createHttpHeader(202 `HTTP/${proxyRes.httpVersion} ${proxyRes.statusCode} ${proxyRes.statusMessage}`,203 proxyRes.headers204 )205 )206 proxyRes.pipe(res)207 }208 } else {209 res.statusCode = proxyRes.statusCode210 for (const [key, value] of Object.entries(headers)) {211 res.setHeader(key, value)212 }213 proxyRes.on('end', onProxyResEnd).pipe(res)214 }215}216function onProxyReqUpgrade (proxyRes, proxySocket, proxyHead) {217 const res = this[kRes]218 res[kProxySocket] = proxySocket219 proxySocket[kRes] = res220 setupSocket(proxySocket)221 if (proxyHead && proxyHead.length) {222 proxySocket.unshift(proxyHead)223 }224 res.write(225 createHttpHeader('HTTP/1.1 101 Switching Protocols', proxyRes.headers)226 )227 proxySocket228 .on('error', onProxyResError)229 .on('close', onProxyResAborted)230 .pipe(res)231 .pipe(proxySocket)232}233function onProxyResError (err) {234 err.statusCode = 502235 onComplete.call(this, err)236}237function onProxyResAborted () {238 onComplete.call(this, new HttpError('proxy aborted', 'ECONNRESET', 502))239}240function onProxyResEnd () {241 if (this.trailers) {242 this[kRes].addTrailers(this.trailers)243 }...
_Events.js
Source:_Events.js
...5*/6if(!dojo._hasResource["dojox.grid._Events"]){7dojo._hasResource["dojox.grid._Events"]=true;8dojo.provide("dojox.grid._Events");9dojo.declare("dojox.grid._Events",null,{cellOverClass:"dojoxGridCellOver",onKeyEvent:function(e){10this.dispatchKeyEvent(e);11},onContentEvent:function(e){12this.dispatchContentEvent(e);13},onHeaderEvent:function(e){14this.dispatchHeaderEvent(e);15},onStyleRow:function(_1){16var i=_1;17i.customClasses+=(i.odd?" dojoxGridRowOdd":"")+(i.selected?" dojoxGridRowSelected":"")+(i.over?" dojoxGridRowOver":"");18this.focus.styleRow(_1);19this.edit.styleRow(_1);20},onKeyDown:function(e){21if(e.altKey||e.metaKey){22return;23}24var dk=dojo.keys;25var _2;26switch(e.keyCode){27case dk.ESCAPE:28this.edit.cancel();29break;30case dk.ENTER:31if(!this.edit.isEditing()){32_2=this.focus.getHeaderIndex();33if(_2>=0){34this.setSortIndex(_2);35break;36}else{37this.selection.clickSelect(this.focus.rowIndex,dojo.isCopyKey(e),e.shiftKey);38}39dojo.stopEvent(e);40}41if(!e.shiftKey){42var _3=this.edit.isEditing();43this.edit.apply();44if(!_3){45this.edit.setEditCell(this.focus.cell,this.focus.rowIndex);46}47}48if(!this.edit.isEditing()){49var _4=this.focus.focusView||this.views.views[0];50_4.content.decorateEvent(e);51this.onRowClick(e);52}53break;54case dk.SPACE:55if(!this.edit.isEditing()){56_2=this.focus.getHeaderIndex();57if(_2>=0){58this.setSortIndex(_2);59break;60}else{61this.selection.clickSelect(this.focus.rowIndex,dojo.isCopyKey(e),e.shiftKey);62}63dojo.stopEvent(e);64}65break;66case dk.TAB:67this.focus[e.shiftKey?"previousKey":"nextKey"](e);68break;69case dk.LEFT_ARROW:70case dk.RIGHT_ARROW:71if(!this.edit.isEditing()){72var _5=e.keyCode;73dojo.stopEvent(e);74_2=this.focus.getHeaderIndex();75if(_2>=0&&(e.shiftKey&&e.ctrlKey)){76this.focus.colSizeAdjust(e,_2,(_5==dk.LEFT_ARROW?-1:1)*5);77}else{78var _6=(_5==dk.LEFT_ARROW)?1:-1;79if(dojo._isBodyLtr()){80_6*=-1;81}82this.focus.move(0,_6);83}84}85break;86case dk.UP_ARROW:87if(!this.edit.isEditing()&&this.focus.rowIndex!==0){88dojo.stopEvent(e);89this.focus.move(-1,0);90}91break;92case dk.DOWN_ARROW:93if(!this.edit.isEditing()&&this.focus.rowIndex+1!=this.rowCount){94dojo.stopEvent(e);95this.focus.move(1,0);96}97break;98case dk.PAGE_UP:99if(!this.edit.isEditing()&&this.focus.rowIndex!==0){100dojo.stopEvent(e);101if(this.focus.rowIndex!=this.scroller.firstVisibleRow+1){102this.focus.move(this.scroller.firstVisibleRow-this.focus.rowIndex,0);103}else{104this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex-1));105this.focus.move(this.scroller.firstVisibleRow-this.scroller.lastVisibleRow+1,0);106}107}108break;109case dk.PAGE_DOWN:110if(!this.edit.isEditing()&&this.focus.rowIndex+1!=this.rowCount){111dojo.stopEvent(e);112if(this.focus.rowIndex!=this.scroller.lastVisibleRow-1){113this.focus.move(this.scroller.lastVisibleRow-this.focus.rowIndex-1,0);114}else{115this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex+1));116this.focus.move(this.scroller.lastVisibleRow-this.scroller.firstVisibleRow-1,0);117}118}119break;120default:121break;122}123},onMouseOver:function(e){124e.rowIndex==-1?this.onHeaderCellMouseOver(e):this.onCellMouseOver(e);125},onMouseOut:function(e){126e.rowIndex==-1?this.onHeaderCellMouseOut(e):this.onCellMouseOut(e);127},onMouseDown:function(e){128e.rowIndex==-1?this.onHeaderCellMouseDown(e):this.onCellMouseDown(e);129},onMouseOverRow:function(e){130if(!this.rows.isOver(e.rowIndex)){131this.rows.setOverRow(e.rowIndex);132e.rowIndex==-1?this.onHeaderMouseOver(e):this.onRowMouseOver(e);133}134},onMouseOutRow:function(e){135if(this.rows.isOver(-1)){136this.onHeaderMouseOut(e);137}else{138if(!this.rows.isOver(-2)){139this.rows.setOverRow(-2);140this.onRowMouseOut(e);141}142}143},onMouseDownRow:function(e){144if(e.rowIndex!=-1){145this.onRowMouseDown(e);146}147},onCellMouseOver:function(e){148if(e.cellNode){149dojo.addClass(e.cellNode,this.cellOverClass);150}151},onCellMouseOut:function(e){152if(e.cellNode){153dojo.removeClass(e.cellNode,this.cellOverClass);154}155},onCellMouseDown:function(e){156},onCellClick:function(e){157this._click[0]=this._click[1];158this._click[1]=e;159if(!this.edit.isEditCell(e.rowIndex,e.cellIndex)){160this.focus.setFocusCell(e.cell,e.rowIndex);161}162this.onRowClick(e);163},onCellDblClick:function(e){164if(this._click.length>1&&dojo.isIE){165this.edit.setEditCell(this._click[1].cell,this._click[1].rowIndex);166}else{167if(this._click.length>1&&this._click[0].rowIndex!=this._click[1].rowIndex){168this.edit.setEditCell(this._click[0].cell,this._click[0].rowIndex);169}else{170this.edit.setEditCell(e.cell,e.rowIndex);171}172}173this.onRowDblClick(e);174},onCellContextMenu:function(e){175this.onRowContextMenu(e);176},onCellFocus:function(_7,_8){177this.edit.cellFocus(_7,_8);178},onRowClick:function(e){179this.edit.rowClick(e);180this.selection.clickSelectEvent(e);181},onRowDblClick:function(e){182},onRowMouseOver:function(e){183},onRowMouseOut:function(e){184},onRowMouseDown:function(e){185},onRowContextMenu:function(e){186dojo.stopEvent(e);187},onHeaderMouseOver:function(e){188},onHeaderMouseOut:function(e){189},onHeaderCellMouseOver:function(e){190if(e.cellNode){191dojo.addClass(e.cellNode,this.cellOverClass);192}193},onHeaderCellMouseOut:function(e){194if(e.cellNode){195dojo.removeClass(e.cellNode,this.cellOverClass);196}197},onHeaderCellMouseDown:function(e){198},onHeaderClick:function(e){199},onHeaderCellClick:function(e){200this.setSortIndex(e.cell.index);201this.onHeaderClick(e);202},onHeaderDblClick:function(e){203},onHeaderCellDblClick:function(e){204this.onHeaderDblClick(e);205},onHeaderCellContextMenu:function(e){206this.onHeaderContextMenu(e);207},onHeaderContextMenu:function(e){208if(!this.headerMenu){209dojo.stopEvent(e);210}211},onStartEdit:function(_9,_a){212},onApplyCellEdit:function(_b,_c,_d){213},onCancelEdit:function(_e){214},onApplyEdit:function(_f){215},onCanSelect:function(_10){216return true;217},onCanDeselect:function(_11){218return true;219},onSelected:function(_12){220this.updateRowStyles(_12);221},onDeselected:function(_13){222this.updateRowStyles(_13);223},onSelectionChanged:function(){224}});...
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch({ headless: false });4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.screenshot({ path: `example.png` });7 await browser.close();8})();
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch({ headless: false, slowMo: 50 });4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.screenshot({ path: `example.png` });7 await browser.close();8})();9const { test, expect } = require('@playwright/test');10test('basic test', async ({ page }) => {11 const title = page.locator('title');12 await expect(title).toHaveText('Google');13});
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch({ headless: false });4 const page = await browser.newPage();5 const elementHandle = await page.$('text=Get started');6 await elementHandle.screenshot({ path: `example.png` });7 await browser.close();8})();9const { chromium } = require('playwright');10(async () => {11 const browser = await chromium.launch({ headless: false });12 const page = await browser.newPage();13 const elementHandle = await page.$('text=Get started');14 const box = await elementHandle.boundingBox();15 await page.screenshot({ path: `example.png`, clip: box });16 await browser.close();17})();18const { chromium } = require('playwright');19(async () => {20 const browser = await chromium.launch({ headless: false });21 const page = await browser.newPage();22 const elementHandle = await page.$('text=Get started');23 const box = await elementHandle.boundingBox();24 await page.screenshot({ path: `example.png`, clip: box });25 await browser.close();26})();27const { chromium } = require('playwright');28(async () => {29 const browser = await chromium.launch({ headless: false });30 const context = await browser.newContext();31 const page = await context.newPage();32 const elementHandle = await page.$('text=Get started');33 const box = await elementHandle.boundingBox();34 await page.screenshot({ path: `example.png`, clip: box });35 await browser.close();36})();37const { chromium } = require('playwright');38(async () => {39 const browser = await chromium.launch({ headless: false });40 const context = await browser.newContext();
Using AI Code Generation
1const { test, expect } = require('@playwright/test');2test('test', async ({ page }) => {3 const name = await page.innerText('.navbar__inner .navbar__title');4 expect(name).toBe('Playwright');5});6Then you can run the tests using `npm run test-{browser}`:7Then you can run the tests using `npm run test-{environment}`:8Then you can run the tests using `npm run test-{browser}-{environment}`:9Then you can run the tests using `npm run test-{environment}-parallel`:
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const page = await browser.newPage();5 await page.screenshot({ path: `example.png` });6 await browser.close();7})();
Using AI Code Generation
1const { test, expect } = require('@playwright/test');2test('Test Name', async ({ page }) => {3 const title = page.locator('.navbar__inner .navbar__title');4 await expect(title).toHaveText('Playwright');5});6{7 "scripts": {8 }9}10{11 "devDependencies": {12 }13}14module.exports = {15}16{17 "devDependencies": {18 }19}
Using AI Code Generation
1const { _electron: electron } = require('playwright');2(async () => {3 const app = await electron.launch({ args: ['path/to/my/app'] });4 const window = app.firstWindow();5 await window.click('button');6 await app.stop();7})();8const { test, expect } = require('@playwright/test');9const { _electron: electron } = require('playwright-electron');10test('should launch Electron app', async ({}) => {11 const app = await electron.launch({12 });13 const window = app.firstWindow();14 await window.click('button');15 await app.stop();16});17const app = await electron.launch({18});19await app.stop();20const window = app.firstWindow();21const context = window.context();22const page = window.page();23await window.click('button');24await window.type('input', 'text');25await window.waitForSelector('button');26await window.waitForEvent('load');27await window.waitForFunction('() => window.location.pathname === "/about"');28const title = await window.evaluate(() => document.title);29const body = await window.evaluateHandle(() => document.body);30const title = await window.title();31const url = await window.url();32const isClosed = await window.isClosed();33await window.close();34await window.selectOption('select', 'option');35await window.press('input', 'Enter');36await window.check('input');
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!!