Best JavaScript code snippet using playwright-internal
getDraftEditorSelection-test.js
Source:getDraftEditorSelection-test.js
1/**2 * Copyright (c) Facebook, Inc. and its affiliates.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 *7 * @emails oncall+draft_js8 * @format9 */10'use strict';11const getDraftEditorSelection = require('getDraftEditorSelection');12const getSampleSelectionMocksForTesting = require('getSampleSelectionMocksForTesting');13const getSampleSelectionMocksForTestingNestedBlocks = require('getSampleSelectionMocksForTestingNestedBlocks');14let editorState = null;15let root = null;16let contents = null;17let blocks = null;18let leafs = null;19let leafChildren = null;20let textNodes = null;21const resetRootNodeMocks = () => {22 ({23 editorState,24 root,25 contents,26 blocks,27 leafs,28 leafChildren,29 textNodes,30 } = getSampleSelectionMocksForTesting());31};32const resetNestedNodeMocks = () => {33 ({34 editorState,35 root,36 contents,37 blocks,38 leafs,39 leafChildren,40 textNodes,41 } = getSampleSelectionMocksForTestingNestedBlocks());42};43const assertGetDraftEditorSelection = getSelectionReturnValue => {44 document.selection = null;45 window.getSelection = jest.fn();46 window.getSelection.mockReturnValueOnce(getSelectionReturnValue);47 const selection = getDraftEditorSelection(editorState, root);48 expect({49 ...selection,50 selectionState: selection.selectionState.toJS(),51 }).toMatchSnapshot();52};53beforeEach(() => {54 resetRootNodeMocks();55});56/**57 * Test possible selection states for the text editor. This is based on58 * far too many hours of manual testing and bug fixes, and still may not be59 * a completely accurate representation of all subtle and bizarre differences60 * in implementations and APIs across browsers and operating systems.61 *62 * Welcome to the jungle.63 */64test('must find offsets when collapsed at start', () => {65 const textNode = textNodes[0];66 assertGetDraftEditorSelection({67 rangeCount: 1,68 anchorNode: textNode,69 focusNode: textNode,70 anchorOffset: 0,71 focusOffset: 0,72 });73});74test('must find offsets when collapsed at start of nested node', () => {75 resetNestedNodeMocks();76 const textNode = textNodes[1];77 assertGetDraftEditorSelection({78 rangeCount: 1,79 anchorNode: textNode,80 focusNode: textNode,81 anchorOffset: 0,82 focusOffset: 0,83 });84});85test('must find offsets when collapsed at end', () => {86 const textNode = textNodes[0];87 assertGetDraftEditorSelection({88 rangeCount: 1,89 anchorNode: textNode,90 focusNode: textNode,91 anchorOffset: textNode.length,92 focusOffset: textNode.length,93 });94});95test('must find offsets when collapsed at end of nested node', () => {96 resetNestedNodeMocks();97 const textNode = textNodes[1];98 assertGetDraftEditorSelection({99 rangeCount: 1,100 anchorNode: textNode,101 focusNode: textNode,102 anchorOffset: textNode.length,103 focusOffset: textNode.length,104 });105});106test('must find offsets for non-collapsed selection', () => {107 const textNode = textNodes[0];108 assertGetDraftEditorSelection({109 rangeCount: 1,110 anchorNode: textNode,111 anchorOffset: 1,112 focusNode: textNode,113 focusOffset: 6,114 });115});116test('must find offsets for non-collapsed selection of nested node', () => {117 resetNestedNodeMocks();118 const textNode = textNodes[1];119 assertGetDraftEditorSelection({120 rangeCount: 1,121 anchorNode: textNode,122 anchorOffset: 1,123 focusNode: textNode,124 focusOffset: 2,125 });126});127test('must find offsets for reversed selection', () => {128 const textNode = textNodes[0];129 assertGetDraftEditorSelection({130 rangeCount: 1,131 anchorNode: textNode,132 anchorOffset: 6,133 focusNode: textNode,134 focusOffset: 1,135 });136});137test('must find offsets for reversed selection of nested node', () => {138 resetNestedNodeMocks();139 const textNode = textNodes[1];140 assertGetDraftEditorSelection({141 rangeCount: 1,142 anchorNode: textNode,143 anchorOffset: 2,144 focusNode: textNode,145 focusOffset: 1,146 });147});148test('must find offsets for selection on entire text node', () => {149 const textNode = textNodes[0];150 assertGetDraftEditorSelection({151 rangeCount: 1,152 anchorNode: textNode,153 anchorOffset: 0,154 focusNode: textNode,155 focusOffset: textNode.length,156 });157});158test('must find offsets for selection on entire text node of nested node', () => {159 resetNestedNodeMocks();160 const textNode = textNodes[1];161 assertGetDraftEditorSelection({162 rangeCount: 1,163 anchorNode: textNode,164 anchorOffset: 0,165 focusNode: textNode,166 focusOffset: textNode.length,167 });168});169test('starts at head of one node and ends at head of another', () => {170 assertGetDraftEditorSelection({171 rangeCount: 1,172 anchorNode: textNodes[0],173 anchorOffset: 0,174 focusNode: textNodes[4],175 focusOffset: 0,176 });177});178test('starts at head of one nested node and ends at head of another nested node', () => {179 resetNestedNodeMocks();180 assertGetDraftEditorSelection({181 rangeCount: 1,182 anchorNode: textNodes[1],183 anchorOffset: 0,184 focusNode: textNodes[3],185 focusOffset: 0,186 });187});188test('extends from head of one node to end of another', () => {189 assertGetDraftEditorSelection({190 rangeCount: 1,191 anchorNode: textNodes[0],192 anchorOffset: 0,193 focusNode: textNodes[2],194 focusOffset: textNodes[2].textContent.length,195 });196});197test('extends from head of one nested node to end of another nested node', () => {198 resetNestedNodeMocks();199 assertGetDraftEditorSelection({200 rangeCount: 1,201 anchorNode: textNodes[1],202 anchorOffset: 0,203 focusNode: textNodes[3],204 focusOffset: textNodes[3].textContent.length,205 });206});207test('starts within one text node and ends within another block', () => {208 assertGetDraftEditorSelection({209 rangeCount: 1,210 anchorNode: textNodes[0],211 anchorOffset: 4,212 focusNode: textNodes[4],213 focusOffset: 6,214 });215});216test('starts within one nested text node and ends within another nested block', () => {217 resetNestedNodeMocks();218 assertGetDraftEditorSelection({219 rangeCount: 1,220 anchorNode: textNodes[1],221 anchorOffset: 2,222 focusNode: textNodes[3],223 focusOffset: 3,224 });225});226test('is a reversed selection across multiple text nodes', () => {227 assertGetDraftEditorSelection({228 rangeCount: 1,229 anchorNode: textNodes[4],230 anchorOffset: 4,231 focusNode: textNodes[0],232 focusOffset: 6,233 });234});235test('is a reversed selection across multiple nested text nodes', () => {236 resetNestedNodeMocks();237 assertGetDraftEditorSelection({238 rangeCount: 1,239 anchorNode: textNodes[1],240 anchorOffset: 2,241 focusNode: textNodes[3],242 focusOffset: 3,243 });244});245// I'm not even certain this is possible, but let's handle it anyway.246test('starts at head of text node, ends at head of leaf child', () => {247 assertGetDraftEditorSelection({248 rangeCount: 1,249 anchorNode: textNodes[0],250 anchorOffset: 0,251 focusNode: leafChildren[4],252 focusOffset: 0,253 });254});255test('starts at head of a nested text node, ends at head of leaf child of another nested node', () => {256 resetNestedNodeMocks();257 assertGetDraftEditorSelection({258 rangeCount: 1,259 anchorNode: textNodes[1],260 anchorOffset: 0,261 focusNode: leafChildren[3],262 focusOffset: 0,263 });264});265test('starts at head of text node, ends at end of leaf child', () => {266 const leaf = leafChildren[4];267 assertGetDraftEditorSelection({268 rangeCount: 1,269 anchorNode: textNodes[0],270 anchorOffset: 0,271 focusNode: leaf,272 focusOffset: leaf.childNodes.length,273 });274});275test('starts at head of nested text node, ends at end of nested leaf child', () => {276 resetNestedNodeMocks();277 const leaf = leafChildren[3];278 assertGetDraftEditorSelection({279 rangeCount: 1,280 anchorNode: textNodes[1],281 anchorOffset: 0,282 focusNode: leaf,283 focusOffset: leaf.childNodes.length,284 });285});286test('starts within text node, ends at start of leaf child', () => {287 const leaf = leafChildren[4];288 assertGetDraftEditorSelection({289 rangeCount: 1,290 anchorNode: textNodes[0],291 anchorOffset: 4,292 focusNode: leaf,293 focusOffset: 0,294 });295});296test('starts within nested text node, ends at start of nested leaf child', () => {297 resetNestedNodeMocks();298 const leaf = leafChildren[3];299 assertGetDraftEditorSelection({300 rangeCount: 1,301 anchorNode: textNodes[1],302 anchorOffset: 2,303 focusNode: leaf,304 focusOffset: 0,305 });306});307test('starts within text node, ends at end of leaf child', () => {308 const leaf = leafChildren[4];309 assertGetDraftEditorSelection({310 rangeCount: 1,311 anchorNode: textNodes[0],312 anchorOffset: 4,313 focusNode: leaf,314 focusOffset: leaf.childNodes.length,315 });316});317test('starts within nested text node, ends at end of nested leaf child', () => {318 resetNestedNodeMocks();319 const leaf = leafChildren[3];320 assertGetDraftEditorSelection({321 rangeCount: 1,322 anchorNode: textNodes[1],323 anchorOffset: 2,324 focusNode: leaf,325 focusOffset: leaf.childNodes.length,326 });327});328test('is a reversed text-to-leaf-child selection', () => {329 const leaf = leafChildren[4];330 assertGetDraftEditorSelection({331 rangeCount: 1,332 anchorNode: leaf,333 anchorOffset: 0,334 focusNode: textNodes[0],335 focusOffset: 4,336 });337});338test('is a reversed text-to-leaf-child selection of nested node', () => {339 resetNestedNodeMocks();340 const leaf = leafChildren[3];341 assertGetDraftEditorSelection({342 rangeCount: 1,343 anchorNode: leaf,344 anchorOffset: 0,345 focusNode: textNodes[1],346 focusOffset: 4,347 });348});349test('starts at head of text node, ends at head of leaf span', () => {350 assertGetDraftEditorSelection({351 rangeCount: 1,352 anchorNode: textNodes[0],353 anchorOffset: 0,354 focusNode: leafs[4],355 focusOffset: 0,356 });357});358test('starts at head of nested text node, ends at head of nested leaf span', () => {359 resetNestedNodeMocks();360 assertGetDraftEditorSelection({361 rangeCount: 1,362 anchorNode: textNodes[1],363 anchorOffset: 0,364 focusNode: leafs[3],365 focusOffset: 0,366 });367});368test('starts at head of text node, ends at end of leaf span', () => {369 const leaf = leafs[4];370 assertGetDraftEditorSelection({371 rangeCount: 1,372 anchorNode: textNodes[0],373 anchorOffset: 0,374 focusNode: leaf,375 focusOffset: leaf.childNodes.length,376 });377});378test('starts at head of nested text node, ends at end of nested leaf span', () => {379 resetNestedNodeMocks();380 const leaf = leafs[3];381 assertGetDraftEditorSelection({382 rangeCount: 1,383 anchorNode: textNodes[1],384 anchorOffset: 0,385 focusNode: leaf,386 focusOffset: leaf.childNodes.length,387 });388});389test('starts within text node, ends at start of leaf span', () => {390 const leaf = leafs[4];391 assertGetDraftEditorSelection({392 rangeCount: 1,393 anchorNode: textNodes[0],394 anchorOffset: 4,395 focusNode: leaf,396 focusOffset: 0,397 });398});399test('starts within nested text node, ends at start of nested leaf span', () => {400 resetNestedNodeMocks();401 const leaf = leafs[3];402 assertGetDraftEditorSelection({403 rangeCount: 1,404 anchorNode: textNodes[1],405 anchorOffset: 2,406 focusNode: leaf,407 focusOffset: 0,408 });409});410test('starts within text node, ends at end of leaf span', () => {411 const leaf = leafs[4];412 assertGetDraftEditorSelection({413 rangeCount: 1,414 anchorNode: textNodes[0],415 anchorOffset: 4,416 focusNode: leaf,417 focusOffset: leaf.childNodes.length,418 });419});420test('starts within nested text node, ends at end of nested leaf span', () => {421 resetNestedNodeMocks();422 const leaf = leafs[3];423 assertGetDraftEditorSelection({424 rangeCount: 1,425 anchorNode: textNodes[1],426 anchorOffset: 2,427 focusNode: leaf,428 focusOffset: leaf.childNodes.length,429 });430});431test('is a reversed text-to-leaf selection', () => {432 const leaf = leafs[4];433 assertGetDraftEditorSelection({434 rangeCount: 1,435 anchorNode: leaf,436 anchorOffset: 0,437 focusNode: textNodes[0],438 focusOffset: 4,439 });440});441test('is a reversed nested text-to-leaf selection', () => {442 resetNestedNodeMocks();443 const leaf = leafs[3];444 assertGetDraftEditorSelection({445 rangeCount: 1,446 anchorNode: leaf,447 anchorOffset: 0,448 focusNode: textNodes[1],449 focusOffset: 2,450 });451});452test('is collapsed at start of single span', () => {453 const leaf = leafs[0];454 assertGetDraftEditorSelection({455 rangeCount: 1,456 anchorNode: leaf,457 anchorOffset: 0,458 focusNode: leaf,459 focusOffset: 0,460 });461});462test('is collapsed at start of nested single span', () => {463 resetNestedNodeMocks();464 const leaf = leafs[1];465 assertGetDraftEditorSelection({466 rangeCount: 1,467 anchorNode: leaf,468 anchorOffset: 0,469 focusNode: leaf,470 focusOffset: 0,471 });472});473test('is collapsed at end of single span', () => {474 const leaf = leafs[0];475 assertGetDraftEditorSelection({476 rangeCount: 1,477 anchorNode: leaf,478 anchorOffset: leaf.childNodes.length,479 focusNode: leaf,480 focusOffset: leaf.childNodes.length,481 });482});483test('is collapsed at end of nested single span', () => {484 resetNestedNodeMocks();485 const leaf = leafs[1];486 assertGetDraftEditorSelection({487 rangeCount: 1,488 anchorNode: leaf,489 anchorOffset: leaf.childNodes.length,490 focusNode: leaf,491 focusOffset: leaf.childNodes.length,492 });493});494test('contains an entire leaf', () => {495 const leaf = leafs[4];496 assertGetDraftEditorSelection({497 rangeCount: 1,498 anchorNode: leaf,499 anchorOffset: 0,500 focusNode: leaf,501 focusOffset: leaf.childNodes.length,502 });503});504test('contains an entire nested leaf', () => {505 resetNestedNodeMocks();506 const leaf = leafs[3];507 assertGetDraftEditorSelection({508 rangeCount: 1,509 anchorNode: leaf,510 anchorOffset: 0,511 focusNode: leaf,512 focusOffset: leaf.childNodes.length,513 });514});515test('is reversed on entire leaf', () => {516 const leaf = leafs[4];517 assertGetDraftEditorSelection({518 rangeCount: 1,519 anchorNode: leaf,520 anchorOffset: leaf.childNodes.length,521 focusNode: leaf,522 focusOffset: 0,523 });524});525test('is reversed on nested entire leaf', () => {526 resetNestedNodeMocks();527 const leaf = leafs[3];528 assertGetDraftEditorSelection({529 rangeCount: 1,530 anchorNode: leaf,531 anchorOffset: leaf.childNodes.length,532 focusNode: leaf,533 focusOffset: 0,534 });535});536test('from start of one block to start of another', () => {537 assertGetDraftEditorSelection({538 rangeCount: 1,539 anchorNode: leafs[0],540 anchorOffset: 0,541 focusNode: leafs[4],542 focusOffset: 0,543 });544});545test('from start of one nested block to start of another', () => {546 resetNestedNodeMocks();547 assertGetDraftEditorSelection({548 rangeCount: 1,549 anchorNode: leafs[1],550 anchorOffset: 0,551 focusNode: leafs[3],552 focusOffset: 0,553 });554});555test('from start of one block to end of other block', () => {556 assertGetDraftEditorSelection({557 rangeCount: 1,558 anchorNode: leafs[0],559 anchorOffset: 0,560 focusNode: leafs[4],561 focusOffset: leafs[4].childNodes.length,562 });563});564test('from start of one nestd block to end of other nested block', () => {565 resetNestedNodeMocks();566 assertGetDraftEditorSelection({567 rangeCount: 1,568 anchorNode: leafs[1],569 anchorOffset: 0,570 focusNode: leafs[3],571 focusOffset: leafs[3].childNodes.length,572 });573});574test('reversed leaf to leaf', () => {575 assertGetDraftEditorSelection({576 rangeCount: 1,577 anchorNode: leafs[4],578 anchorOffset: leafs[4].childNodes.length,579 focusNode: leafs[0],580 focusOffset: 0,581 });582});583test('reversed leaf to nested leaf', () => {584 resetNestedNodeMocks();585 assertGetDraftEditorSelection({586 rangeCount: 1,587 anchorNode: leafs[3],588 anchorOffset: leafs[3].childNodes.length,589 focusNode: leafs[1],590 focusOffset: 0,591 });592});593test('is collapsed at start at single block', () => {594 const block = blocks[0];595 assertGetDraftEditorSelection({596 rangeCount: 1,597 anchorNode: block,598 anchorOffset: 0,599 focusNode: block,600 focusOffset: 0,601 });602});603test('is collapsed at start at nested single block', () => {604 resetNestedNodeMocks();605 const block = blocks[1];606 assertGetDraftEditorSelection({607 rangeCount: 1,608 anchorNode: block,609 anchorOffset: 0,610 focusNode: block,611 focusOffset: 0,612 });613});614test('is collapsed at end at single block', () => {615 const block = blocks[0];616 const decorators = block.childNodes;617 assertGetDraftEditorSelection({618 rangeCount: 1,619 anchorNode: block,620 anchorOffset: decorators.length,621 focusNode: block,622 focusOffset: decorators.length,623 });624});625test('is collapsed at end at nested single block', () => {626 resetNestedNodeMocks();627 const block = blocks[1];628 const decorators = block.childNodes;629 assertGetDraftEditorSelection({630 rangeCount: 1,631 anchorNode: block,632 anchorOffset: decorators.length,633 focusNode: block,634 focusOffset: decorators.length,635 });636});637test('is entirely selected', () => {638 const block = blocks[0];639 const decorators = block.childNodes;640 assertGetDraftEditorSelection({641 rangeCount: 1,642 anchorNode: block,643 anchorOffset: 0,644 focusNode: block,645 focusOffset: decorators.length,646 });647});648test('is entirely selected with nested blocks', () => {649 resetNestedNodeMocks();650 const block = blocks[1];651 const decorators = block.childNodes;652 assertGetDraftEditorSelection({653 rangeCount: 1,654 anchorNode: block,655 anchorOffset: 0,656 focusNode: block,657 focusOffset: decorators.length,658 });659});660/**661 * FF: Triple-clicking a block leads to an entire block being selected,662 * with the first text node as the anchor (0 offset) and the block element663 * as the focus (childNodes.length offset)664 */665test('begins at text node zero, ends at end of block', () => {666 const textNode = textNodes[0];667 const block = blocks[0];668 assertGetDraftEditorSelection({669 rangeCount: 1,670 anchorNode: textNode,671 anchorOffset: 0,672 focusNode: block,673 focusOffset: block.childNodes.length,674 });675});676test('begins at nested text node zero, ends at end of nested block', () => {677 resetNestedNodeMocks();678 const textNode = textNodes[1];679 const block = blocks[1];680 assertGetDraftEditorSelection({681 rangeCount: 1,682 anchorNode: textNode,683 anchorOffset: 0,684 focusNode: block,685 focusOffset: block.childNodes.length,686 });687});688// No idea if this is possible.689test('begins within text node, ends at end of block', () => {690 const textNode = textNodes[0];691 const block = blocks[0];692 assertGetDraftEditorSelection({693 rangeCount: 1,694 anchorNode: textNode,695 anchorOffset: 5,696 focusNode: block,697 focusOffset: block.childNodes.length,698 });699});700test('begins within nested text node, ends at end of nested block', () => {701 resetNestedNodeMocks();702 const textNode = textNodes[1];703 const block = blocks[1];704 assertGetDraftEditorSelection({705 rangeCount: 1,706 anchorNode: textNode,707 anchorOffset: 2,708 focusNode: block,709 focusOffset: block.childNodes.length,710 });711});712// No idea if this is possible.713test('is reversed from the first case', () => {714 const textNode = textNodes[0];715 const block = blocks[0];716 assertGetDraftEditorSelection({717 rangeCount: 1,718 anchorNode: block,719 anchorOffset: block.childNodes.length,720 focusNode: textNode,721 focusOffset: 0,722 });723});724test('is reversed from the first nested case', () => {725 resetNestedNodeMocks();726 const textNode = textNodes[1];727 const block = blocks[1];728 assertGetDraftEditorSelection({729 rangeCount: 1,730 anchorNode: block,731 anchorOffset: block.childNodes.length,732 focusNode: textNode,733 focusOffset: 0,734 });735});736test('goes from start of one block to end of other block', () => {737 assertGetDraftEditorSelection({738 rangeCount: 1,739 anchorNode: blocks[0],740 anchorOffset: 0,741 focusNode: blocks[2],742 focusOffset: blocks[2].childNodes.length,743 });744});745test('goes from start of one nested block to end of other nested block', () => {746 resetNestedNodeMocks();747 assertGetDraftEditorSelection({748 rangeCount: 1,749 anchorNode: blocks[1],750 anchorOffset: 0,751 focusNode: blocks[3],752 focusOffset: blocks[3].childNodes.length,753 });754});755test('goes from start of one block to start of other', () => {756 assertGetDraftEditorSelection({757 rangeCount: 1,758 anchorNode: blocks[0],759 anchorOffset: 0,760 focusNode: blocks[2],761 focusOffset: 0,762 });763});764test('goes from start of one nested block to start of other', () => {765 resetNestedNodeMocks();766 assertGetDraftEditorSelection({767 rangeCount: 1,768 anchorNode: blocks[1],769 anchorOffset: 0,770 focusNode: blocks[3],771 focusOffset: 0,772 });773});774test('goes from end of one to end of other block', () => {775 assertGetDraftEditorSelection({776 rangeCount: 1,777 anchorNode: blocks[0],778 anchorOffset: blocks[0].childNodes.length,779 focusNode: blocks[2],780 focusOffset: blocks[2].childNodes.length,781 });782});783test('goes from end of one nested block to end of other nested block', () => {784 resetNestedNodeMocks();785 assertGetDraftEditorSelection({786 rangeCount: 1,787 anchorNode: blocks[1],788 anchorOffset: blocks[1].childNodes.length,789 focusNode: blocks[3],790 focusOffset: blocks[3].childNodes.length,791 });792});793test('goes from within one block to within another block', () => {794 assertGetDraftEditorSelection({795 rangeCount: 1,796 anchorNode: blocks[0],797 anchorOffset: 1,798 focusNode: blocks[2].firstChild.firstChild,799 focusOffset: 1,800 });801});802test('goes from within one nested block to within another nested block', () => {803 resetNestedNodeMocks();804 assertGetDraftEditorSelection({805 rangeCount: 1,806 anchorNode: blocks[1],807 anchorOffset: 1,808 focusNode: blocks[3].firstChild.firstChild,809 focusOffset: 1,810 });811});812test('is the same as above but reversed', () => {813 assertGetDraftEditorSelection({814 rangeCount: 1,815 anchorNode: blocks[2].firstChild.firstChild,816 anchorOffset: 1,817 focusNode: blocks[0],818 focusOffset: 1,819 });820});821test('is the same as above but nested and reversed', () => {822 resetNestedNodeMocks();823 assertGetDraftEditorSelection({824 rangeCount: 1,825 anchorNode: blocks[3].firstChild.firstChild,826 anchorOffset: 1,827 focusNode: blocks[1],828 focusOffset: 1,829 });830});831test('is collapsed at the start of the contents', () => {832 assertGetDraftEditorSelection({833 rangeCount: 1,834 anchorNode: contents,835 anchorOffset: 0,836 focusNode: contents,837 focusOffset: 0,838 });839});840test('is collapsed at the start of the contents with nesting blocks', () => {841 resetNestedNodeMocks();842 assertGetDraftEditorSelection({843 rangeCount: 1,844 anchorNode: contents,845 anchorOffset: 0,846 focusNode: contents,847 focusOffset: 0,848 });849});850test('occupies a single child of the contents', () => {851 assertGetDraftEditorSelection({852 rangeCount: 1,853 anchorNode: contents,854 anchorOffset: 0,855 focusNode: contents,856 focusOffset: 1,857 });858});859test('occupies a single child of the contents with nested blocks', () => {860 resetNestedNodeMocks();861 assertGetDraftEditorSelection({862 rangeCount: 1,863 anchorNode: contents,864 anchorOffset: 0,865 focusNode: contents,866 focusOffset: 1,867 });868});869test('is collapsed at the end of a child', () => {870 assertGetDraftEditorSelection({871 rangeCount: 1,872 anchorNode: contents,873 anchorOffset: 1,874 focusNode: contents,875 focusOffset: 1,876 });877});878test('is collapsed at the end of a nested child', () => {879 resetNestedNodeMocks();880 assertGetDraftEditorSelection({881 rangeCount: 1,882 anchorNode: contents,883 anchorOffset: 1,884 focusNode: contents,885 focusOffset: 1,886 });887});888test('is contains multiple children', () => {889 assertGetDraftEditorSelection({890 rangeCount: 1,891 anchorNode: contents,892 anchorOffset: 0,893 focusNode: contents,894 focusOffset: 3,895 });896});897test('is contains multiple nested children', () => {898 resetNestedNodeMocks();899 assertGetDraftEditorSelection({900 rangeCount: 1,901 anchorNode: contents,902 anchorOffset: 0,903 focusNode: contents,904 focusOffset: 2,905 });906});907/**908 * In some scenarios, the entire editor may be selected by command-A.909 */910test('is collapsed at start with full selection', () => {911 assertGetDraftEditorSelection({912 rangeCount: 1,913 anchorNode: root,914 anchorOffset: 0,915 focusNode: root,916 focusOffset: 0,917 });918});919test('is collapsed at start with full selection with nested blocks', () => {920 resetNestedNodeMocks();921 assertGetDraftEditorSelection({922 rangeCount: 1,923 anchorNode: root,924 anchorOffset: 0,925 focusNode: root,926 focusOffset: 0,927 });928});929test('is collapsed at end with full selection', () => {930 assertGetDraftEditorSelection({931 rangeCount: 1,932 anchorNode: root,933 anchorOffset: root.childNodes.length,934 focusNode: root,935 focusOffset: root.childNodes.length,936 });937});938test('is collapsed at end with full selection with nested blocks', () => {939 resetNestedNodeMocks();940 assertGetDraftEditorSelection({941 rangeCount: 1,942 anchorNode: root,943 anchorOffset: root.childNodes.length,944 focusNode: root,945 focusOffset: root.childNodes.length,946 });947});948test('is completely selected', () => {949 assertGetDraftEditorSelection({950 rangeCount: 1,951 anchorNode: root,952 anchorOffset: 0,953 focusNode: root,954 focusOffset: root.childNodes.length,955 });956});957test('is completely selected with nested blocks', () => {958 resetNestedNodeMocks();959 assertGetDraftEditorSelection({960 rangeCount: 1,961 anchorNode: root,962 anchorOffset: 0,963 focusNode: root,964 focusOffset: root.childNodes.length,965 });966});967test('is reversed from above', () => {968 assertGetDraftEditorSelection({969 rangeCount: 1,970 anchorNode: root,971 anchorOffset: root.childNodes.length,972 focusNode: root,973 focusOffset: 0,974 });975});976test('is reversed from above nested blocks', () => {977 resetNestedNodeMocks();978 assertGetDraftEditorSelection({979 rangeCount: 1,980 anchorNode: root,981 anchorOffset: root.childNodes.length,982 focusNode: root,983 focusOffset: 0,984 });985});986/**987 * A selection possibility that defies logic. In IE11, triple clicking a988 * block leads to the text node being selected as the anchor, and the989 * **entire editor** being selected as the focus. Ludicrous.990 */991test('does the crazy stuff described above', () => {992 assertGetDraftEditorSelection({993 rangeCount: 1,994 anchorNode: textNodes[0],995 anchorOffset: 0,996 focusNode: root,997 focusOffset: root.childNodes.length,998 });999});1000test('does the crazy stuff described above with nested blocks', () => {1001 resetNestedNodeMocks();1002 assertGetDraftEditorSelection({1003 rangeCount: 1,1004 anchorNode: textNodes[1],1005 anchorOffset: 0,1006 focusNode: root,1007 focusOffset: root.childNodes.length,1008 });...
mentions.js
Source:mentions.js
1if (!window.Node) {2 Node = {'ELEMENT_NODE': 1, 'TEXT_NODE': 3};3}4function initMentionClass() {5 /* Mini wysiwyg editor for statuses */6 createChildClass('MentionAutocomplete', UiControl, {7 /* Standart object fields */8 CSS: {9 },10 defaultOptions: {11 height: 0,12 minHeight: 0,13 padding: 014 },15 controlName: 'MentionAutocomplete',16 /* Standart object methods */17 beforeInit: function (textarea) {18 this.guid = _ui.reg(this);19 },20 initOptions: function (textarea, options) {21 this.options = options;22 },23 init: function (textarea) {24 this.textareaEl = ge(textarea);25 this.width = this.options.width || getSize(this.textareaEl, true)[0];26 this.cache = new Cache({cacheLength: 100});27 },28 initDOM: function (input) {29 this.textareaEl.parentNode.insertBefore(30 this.cont = ce('div', {className: 'mini_editor_cont selector_container'}),31 this.textareaEl.nextSibling32 );33 this.cont.appendChild(34 this.rtaEl = ce('div', {className: 'mention_rich_ta', contentEditable: true}, {'width': this.width, 'minHeight': this.options.minHeight})35 );36 if (browser.msie6) {37 setStyle(this.rtaEl, 'height', this.options.minHeight);38 }39 var resultContainer = ce('div', {className: 'results_container', innerHTML: '<div class="result_list"></div><div class="result_list_shadow"><div class="shadow1"></div><div class="shadow2"></div></div>'});40 this.cont.appendChild(resultContainer);41 this.resultList = geByClass('result_list', resultContainer)[0];42 this.resultListShadow = geByClass('result_list_shadow', resultContainer)[0];43 if (browser.chrome) this.resultList.style.opacity = 1;44 else if (!browser.safari) setStyle(this.resultListShadow, 'top', browser.mozilla ? 0 : (browser.msie && browser.version < 8) ? 0 : -1);45 this.resultList.style.width = this.resultListShadow.style.width = resultContainer.style.width = this.textareaEl.offsetWidth + 'px';46 this.select = new Select(this.resultList, this.resultListShadow, {47 selectFirst: false,48 height: this.options.listHeight,49 onItemSelect: this.onFriendSelect.bind(this),50 onShow: _ui.sel.pbind(this.guid),51 onHide: _ui.sel.pbind(false)52 });53 },54 initEvents: function () {55 var self = this;56 var keyev = browser.opera || browser.mozilla ? 'keypress' : 'keydown';57 this.onEvent = function(e) {58 if (e.type == keyev) {59 self.select.handleKeyEvent(e);60 }61 }62 /* Initial TA click results new rich textarea open */63 removeEvent(this.textareaEl, 'focus');64 removeEvent(this.textareaEl, 'blur');65 if (this.textareaEl.onfocus) addEvent(this.textareaEl, 'focus', this.textareaEl.onfocus);66 if (this.textareaEl.onblur) addEvent(this.textareaEl, 'blur', this.textareaEl.onblur);67 this.textareaEl.onfocus = null;68 var blurTO;69 addEvent(this.textareaEl, 'focus', function (e) {70 clearTimeout(blurTO);71 hide(this);72 show(self.cont);73 this.style.color = '#777';74 var v = trim(self.textareaEl.value);75 if (self.options.startVal) {76 v = self.options.startVal;77 self.options.startVal = false;78 }79 self.rtaEl.innerHTML = v ? v.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/\n/g, '<br/>').replace(/\[((?:id|club)[1-9]\d*)\|([^\]]+)\]/g, '<a href="/$1">$2</a>') : (browser.mozilla ? '<br/>' : ' ');80 setTimeout(function () {81 if (self.textareaEl.phonfocus) {82 self.textareaEl.phonfocus(true);83 }84 self.rtaEl.focus();85 if (!browser.msie) {86 if (v) {87 var spaceNode = document.createTextNode('\u00A0'), sel = window.getSelection();88 self.rtaEl.appendChild(spaceNode);89 sel.collapse(spaceNode, 1);90 } else {91 window.getSelection().collapse(self.rtaEl, 0);92 }93 } else {94 var range = document.selection.createRange();95 range.moveToElementText(self.rtaEl);96 range.collapse(v ? false : true);97 range.select();98 }99 if (v) {100 self.updateWikiValue();101 }102 }, 50);103 cancelEvent(e);104 return false;105 });106 addEvent(this.rtaEl, 'keypress keydown', function (e) {107 if (e.keyCode == KEY.RETURN || e.keyCode == 10) {108 if (!self.select || !self.select.isVisible()) {109 if (!self.blurred && e.ctrlKey && isFunction(self.options.onSubmit)) {110 self.rtaEl.blur();111 self.options.onSubmit();112 }113 } else {114 triggerEvent(document, e.type, e);115 return cancelEvent(e);116 }117 }118 return true;119 });120 addEvent(this.rtaEl, 'keyup mouseup', function (e) {121 if (!self.select) return;122 if (self.select.isVisible() && e.type == 'keyup') {123 if (inArray(e.keyCode, [KEY.UP, KEY.DOWN, KEY.PAGEUP, KEY.PAGEDOWN, KEY.RETURN])) return;124 else if (indexOf([KEY.SPACE, KEY.HOME, 190, 191, 78, 55, 49], e.keyCode) != -1) self.select.hide();125 }126 if (!browser.msie) self.updateWikiValue();127 clearTimeout(this.requestTimeout);128 self.currentTerm = null;129 var sel, range, focusNode, focusValue, focusOffset, matches;130 // fixing anchors beginnings - only opera and mozilla131 if (browser.opera || browser.mozilla) {132 sel = window.getSelection();133 range = sel.rangeCount > 0 ? sel.getRangeAt(0) : null;134 focusNode = range && range.endContainer;135 focusOffset = range.endOffset || 0;136 var anchor = focusNode;137 while (anchor && anchor.tagName != 'A' && anchor != self.rtaEl && anchor.tagName != 'BODY') anchor = anchor.parentNode;138 if (anchor && anchor.tagName == 'A' && !focusOffset) {139 //debugLog('exiting from anchor');140 self.rtaEl.normalize();141 var a = anchor.previousSibling;142 //if (a) debugLog([a, a.nodeType == Node.TEXT_NODE, a.nodeValue, a.nodeValue.charAt(a.nodeValue.length - 1), a.nodeValue.charAt(a.nodeValue.length - 2), a.nodeValue.charAt(a.nodeValue.length - 1) == ' ']);143 if (a && a.nodeType == Node.TEXT_NODE && (a.nodeValue.charAt(a.nodeValue.length - 1) == '\u00A0' || a.nodeValue.charAt(a.nodeValue.length - 1) == ' ')) a.nodeValue = a.nodeValue.substr(0, a.nodeValue.length - 1);144 a = document.createTextNode('\u00A0');145 anchor.parentNode.insertBefore(a, anchor);146 window.getSelection().collapse(a, 0);147 return;148 }149 }150 // fixing anchors endings - actual for all browsers151 if (window.getSelection) { // normal browsers152 sel = window.getSelection();153 range = sel.rangeCount > 0 ? sel.getRangeAt(0) : null;154 focusNode = range && range.endContainer || null;155 focusOffset = range && range.endOffset || 0;156 if (focusNode) {157 if (focusNode == self.rtaEl && self.rtaEl.childNodes) {158 //debugLog('case 1');159 var anchor = self.rtaEl.childNodes[focusOffset];160 anchor.normalize();161 if (anchor.tagName == 'A') window.getSelection().collapse(anchor, 1);162 } else if (focusNode.nodeType == Node.TEXT_NODE && focusNode.parentNode == self.rtaEl) {163 //debugLog('case 2');164 var anchor = focusNode.previousSibling;165 if (anchor && anchor.tagName == 'A') {166 if (focusOffset) {167 //debugLog('case 2 with offset');168 focusValue = focusNode.nodeValue.substr(0, focusOffset);169 if ((matches = focusValue.match(/^([^&\s,.:?! ]+)/))) {170 //debugLog('case 2 with offset matches');171 focusNode.nodeValue = focusNode.nodeValue.substr(matches[1].length);172 anchor.innerHTML += matches[1];173 anchor.normalize();174 window.getSelection().collapse(anchor, 1);175 }176 } else {177 anchor.normalize();178 window.getSelection().collapse(anchor, 1);179 }180 }181 } else if (focusNode.tagName == 'A' || (focusNode.parentNode && focusNode.parentNode.tagName == 'A')) {182 //debugLog('case 3');183 var anchor = focusNode.tagName == 'A' ? focusNode : focusNode.parentNode;184 clearTimeout(self.anchorCheckTimeout);185 self.anchorCheckTimeout = setTimeout(function () {186 if ((matches = anchor.innerHTML.match(/(([\s,.:?! ]| )+)$/))) {187 //debugLog('case 3 matches');188 anchor.innerHTML = anchor.innerHTML.substr(0, anchor.innerHTML.length - matches[1].length);189 var nextText = document.createTextNode(matches[1].replace(' ', ' '));190 anchor.parentNode.insertBefore(nextText, anchor.nextSibling);191 window.getSelection().collapse(nextText, 1);192 }193 }, 5);194 }195 }196 } else if (document.selection) { // ie197 range = document.selection.createRange();198 focusNode = range.parentElement();199 if (focusNode == self.rtaEl) {200 var matches = null;201 while (!matches) {202 range.moveStart('character', -1);203 if (range.htmlText.match(/^[\s,.:?! &]+/i)) {matches = null; break;}204 matches = range.htmlText.match(/<a.+?>(.)<\/a>([^\s,.:?! &]+)$/i);205 }206 if (matches) {207 range.moveStart('character');208 range.pasteHTML('');209 range.moveStart('character', -1);210 range.pasteHTML(matches[1]+matches[2]);211 range.collapse(false);212 range.select();213 }214 }215 }216 clearTimeout(self.getTermTimeout);217 self.getTermTimeout = setTimeout(self.getTerm.bind(self), 200);218 });219 addEvent(this.rtaEl, 'blur', function (e) {220 self.blurred = true;221 if (!stripHTML(this.innerHTML).replace(/( |[\s\n \u00A0])+/gi, '')) {222 blurTO = setTimeout(function () {223 hide(self.cont);224 setStyle(self.textareaEl, 'height', self.options.minHeight);225 show(self.textareaEl);226 if (self.textareaEl.phonblur) {227 setTimeout(self.textareaEl.phonblur, 70);228 }229 }, 40);230 }231 setTimeout(function() { self.blurred = false; }, 1);232 self.rtaEl.normalize();233 self.fixContents();234 self.rtaEl.normalize();235 self.updateWikiValue(true, false, true);236 self.select.hide();237 });238 addEvent(this.rtaEl, 'paste', function (e) {239 setTimeout(function () {240 self.fixContents();241 self.updateWikiValue(true);242 } , 20);243 });244 if (!self.options.startVal) {245 self.options.startVal = val(self.textareaEl);246 }247 this.textareaEl.getValue = function () { return self.updateWikiValue(true, true);};248 var oldSV = this.textareaEl.setValue;249 this.textareaEl.setValue = function (v) {self.rtaEl.innerHTML = v ? v : (browser.mozilla ? '<br/>' : ' '); self.updateWikiValue(true); if(oldSV)oldSV(v);}250 },251 afterInit: function() {252 data(this.textareaEl, 'mention', this);253 },254 getTerm: function() {255 if (browser.msie) this.updateWikiValue();256 if (!this.rtaEl.innerHTML.match(/\*|@/)) return this.select.hide();257 var sel, range, focusNode, focusValue, focusOffset, self = this;258 if (window.getSelection) { // normal browsers259 sel = window.getSelection();260 range = sel.rangeCount > 0 ? sel.getRangeAt(0) : null;261 focusNode = range && range.endContainer;262 if (!focusNode) return;263 focusValue = focusNode.data;264 focusOffset = range.endOffset || 0;265 } else if (document.selection) { // ie266 range = document.selection.createRange();267 focusNode = range.parentElement()//; || this.rtaEl;268 if (!focusNode) return;269 var a = focusNode;270 while (a.tagName != 'BODY' && a != this.rtaEl) {271 a = a.parentNode;272 }273 if (a.tagName == 'BODY') return '';274 focusValue = focusNode.innerText;275 a = focusNode;276 while (a == focusNode) {277 range.moveStart('character', -1);278 a = range.parentElement();279 }280 focusOffset = range.text.length;281 }282 if (!range || range.collapsed === false || focusNode.tagName == 'A' || focusNode.parentNode.tagName == 'A') return self.select.hide();283 this.lastNode = focusNode;284 this.lastOffset = focusOffset;285 if (focusNode == this.rtaEl && !browser.msie) {286 focusNode = focusNode.childNodes[Math.max(focusOffset-1, 0)];287 focusValue = focusNode ? ((focusNode.nodeValue ? focusNode.nodeValue : focusNode.innerText) || '') : '';288 focusOffset = focusValue.length;289 }290 this.lastNode = focusNode;291 this.lastOffset = focusOffset;292 var a = focusNode;293 if (!a || !focusValue) return self.select.hide();294 while ((a = a.previousSibling) && a.nodeType == Node.TEXT_NODE && Math.max(focusValue.indexOf('*'), focusValue.indexOf('@')) < 0) {295 focusValue = a.nodeValue + focusValue;296 focusOffset += a.nodeValue.length;297 }298 if (focusNode.nodeType == Node.TEXT_NODE && focusNode.previousSibling && focusNode.previousSibling.nodeType == Node.TEXT_NODE) {299 focusValue = focusNode.previousSibling.nodeValue + focusValue;300 focusOffset += focusNode.previousSibling.nodeValue.length;301 }302 if (!focusNode || !focusValue || !focusOffset || focusNode.tagName == 'A') return self.select.hide();303 var pos = Math.max(focusValue.lastIndexOf('*', focusOffset), focusValue.lastIndexOf('@', focusOffset));304 if (pos < 0 || focusValue.substr(pos, focusOffset - pos).match(/([\s,.:?! ]| )/)) return self.select.hide();305 var term = trim(focusValue.slice(pos, focusOffset)).substr(1).toLowerCase();306 this.currentTerm = term;307 if (!term) {308 this.showSelectList(term, data);309 } else {310 var data = this.cache.getData(term);311 if (!term) data = [];312 if (data == null) {313 this.requestTimeout = setTimeout(function() {314 ajax.post('hints.php', {act: 'a_json_friends', str: term, from: 'mentions'}, {onDone: function(data) {315 self.cache.setData(term, data);316 if (self.currentTerm == term) self.showSelectList(term, data);317 }});318 }, 150);319 } else if (data != null) {320 this.showSelectList(term, data);321 }322 }323 },324 showSelectList: function (term, items) {325 var self = this;326 if (!this.select) return;327 items = isArray(items) && items.length ? items : [];328 var adding = [];329 this.select.clear();330 this.lastItems = items;331 if (term && items.length) {332 var itemsToShow = 5;333 var re = new RegExp("(^|[\\s\-])(" + term + ")", "i");334 for (var i = 0; i < items.length; ++i) {335 var it = items[i];336 if (!itemsToShow) break;337 var formatted = it[1];338 if (term) {339 var termRus = parseLatin(term);340 if (termRus != null) {341 term = term + '|' + termRus;342 }343 try {344 formatted = formatted.replace(re, '$1<em>$2</em>');345 } catch (e) {}346 }347 if (!formatted) continue;348 --itemsToShow;349 adding.push([it[0], formatted]);350 }351 } else {352 adding.push(['', term ? this.options.noResult : this.options.introText, true]);353 }354 this.select.content(adding);355 this.select.show();356 },357 onFriendSelect: function(friendId) {358 if (!this.lastNode || !this.select) return;359 var focusNode = this.lastNode, focusOffset = this.lastOffset, focusValue = focusNode.data ? focusNode.data : focusNode.innerText;360 if (!focusValue.substr) focusValue = '';361 var friendName = (friendId > 0) ? ('id' + friendId) : ('club' + (-friendId)), href = friendName;362 each(this.lastItems, function(i) {363 if (this[0] == friendId) {364 friendName = this[1];365 return false;366 }367 });368 if (!browser.msie) {369 if (focusNode == this.rtaEl) {370 focusNode = focusNode.childNodes[focusOffset-1];371 focusValue = focusNode.nodeValue;372 focusOffset = focusValue.length;373 }374 var nextNode, prevNode;375 if (focusOffset != focusValue.length) {376 nextNode = document.createTextNode(focusValue.substr(focusOffset));377 focusNode.parentNode.insertBefore(nextNode, focusNode.nextSibling);378 } else {379 nextNode = focusNode.nextSibling;380 }381 var a = focusNode;382 while (a && a.nodeType == Node.TEXT_NODE) {383 if (Math.max(a.nodeValue.indexOf('*'), a.nodeValue.indexOf('@')) >= 0) {384 prevNode = a;385 a.nodeValue = a.nodeValue.substr(0, Math.max(a.nodeValue.lastIndexOf('*'), a.nodeValue.lastIndexOf('@')));386 break;387 }388 a = a.previousSibling;389 }390 if (!prevNode) {391 debugLog('asterisk was not found');392 return;393 }394 while (prevNode.nextSibling && prevNode.nextSibling != nextNode) {395 prevNode.parentNode.removeChild(prevNode.nextSibling);396 }397 var anchor = document.createElement('A'), spaceNode = document.createTextNode('\u00A0'), sel = window.getSelection();398 anchor.href = href;399 anchor.innerHTML = friendName;400 anchor.onclick = cancelEvent;401 prevNode.parentNode.insertBefore(anchor, nextNode);402 prevNode.parentNode.insertBefore(spaceNode, nextNode);403 sel.collapse(spaceNode, 1);404 } else {405 var range = document.selection.createRange();406 focusNode = range.parentElement() || this.rtaEl;407 if (focusNode.tagName == 'A') return;408 var a = focusNode;409 while (range.text.charAt(0) != '*' && range.text.charAt(0) != '@' && a == focusNode) {410 range.moveStart('character', -1);411 a = range.parentElement();412 }413 range.pasteHTML('<a href="' + href + '">' + friendName + '</a>\u00A0');414 range.collapse(false);415 setTimeout(function () {416 this.rtaEl.focus();417 range.select();418 }.bind(this), 10);419 }420 this.select.hide();421 this.updateWikiValue();422 },423 fixContents: function () {424 var self = this;425 var extractChilds = function (el) {426 debugLog('extracting childs, ' + el.tagName + ', ' + el.parentNode.tagName);427 while (el.firstChild) {428 el.parentNode.insertBefore(el.firstChild, el);429 }430 if (el.parentNode) el.parentNode.removeChild(el);431 }432 var fixEl = function () {433 if (this.nodeType == Node.TEXT_NODE || this == window) return;434 if (this.nodeType != Node.ELEMENT_NODE) {435 this.parentNode.removeChild(this);436 return;437 }438 if (!inArray(this.tagName, ['A', 'P', 'BR', 'DIV']) || this.parentNode != self.rtaEl && this.parentNode.tagName != 'P' && this.parentNode.parentNode != self.rtaEl) {439 extractChilds(this);440 counter++;441 }442 // resetting styles for pasted content443 if (this.tagName == 'A' || this.tagName == 'P') for (var s in this.style) {try {this[s] = '';} catch (e) {debugLog(e);}}444 var repeat = false;445 each(this.childNodes, fixEl);446 }447 var counter = 1;448 while (counter > 0) {449 each(this.rtaEl.childNodes, fixEl);450 counter--;451 }452 },453 updateWikiValue: function(noFocus, noCb, force) {454 var sel, range, focusNode, focusValue, focusOffset, self = this, wikiValue = '', wikiValueWithCursor = '', mid, findCursor = false, cursorPos = false;455 if (!noCb && !noFocus && this.options.onValueChange) {456 if (window.getSelection) { // normal browsers457 sel = window.getSelection();458 range = sel.rangeCount > 0 ? sel.getRangeAt(0) : null;459 focusNode = range && range.endContainer;460 focusOffset = range && range.endOffset || 0;461 } else if (document.selection) { // ie462 range = document.selection.createRange();463 if (!range.text.length) {464 focusNode = range.parentElement()//; || this.rtaEl;465 var a = focusNode;466 while (a.tagName != 'BODY' && a != this.rtaEl) {467 a = a.parentNode;468 }469 if (a.tagName == 'BODY') return '';470 a = focusNode;471 while (a == focusNode) {472 range.moveStart('character', -1);473 a = range.parentElement();474 }475 focusOffset = range.text.length;476 } else {477 focusNode = this.rtaEl;478 range = null;479 focusOffset = 0;480 }481 }482 if (!range || range.collapsed === false || focusNode.tagName == 'A' || (focusNode.parentNode && focusNode.parentNode.tagName == 'A')) focusNode = null;483 findCursor = true;484 }485 var parseWikiValue = function() {486 var html = this.innerHTML;487 if (this.nodeType == Node.TEXT_NODE) {488 if (focusNode == this) {489 cursorPos = wikiValue.length + focusOffset;490 }491 wikiValue += this.nodeValue.replace(/\n/g, ' ');492 } else if (this.tagName == 'A' && trim(html)) {493 var data;494 if ((data = this.href.match(/^https?:\/\/(?:[a-z0-9\.]+\.)?(vkontakte\.ru|vk\.com)\/(.*)/i)) && html) {495 var query = (data[2] || '').toLowerCase();496 if (mid = query.match(/^id(\d+)/)) {497 if (html.match(/((https?:\/\/)?)(?:[a-z0-9\.]+\.)?(vkontakte\.ru|vk\.com)\/id(\d+)/ig)) {498 wikiValue += html;499 } else {500 wikiValue += '[id' + mid[1] + '|' + stripHTML(html).replace(/\]/g, '').replace(/\n/g, ' ') + ']';501 }502 return;503 } else if (gid = query.match(/^(?:club|event|public)(\d+)/)) {504 if (html.match(/((https?:\/\/)?)(?:[a-z0-9\.]+\.)?(vkontakte\.ru|vk\.com)\/(?:club|event|public)(\d+)/ig)) {505 wikiValue += html;506 } else {507 wikiValue += '[club' + gid[1] + '|' + stripHTML(html).replace(/\]/g, '').replace(/\n/g, ' ') + ']';508 }509 return;510 } else if (page = query.match(/^(page\-?\d+|pages\?|ru\/|en\/|dev\/)/)) {511 var actHtml = replaceEntities(html);512 actHtml = actHtml.replace(/(&[a-zA-Z0-9]*)?\.+$/, '');513 actHtml = actHtml.replace(/^http:\/\//, '');514 wikiValue += ' '+actHtml;515 //setTimeout(re.pbind(this), 0);516 return;517 }518 }519 var href = this.href,520 act_html = replaceEntities(html).replace(/(&[a-zA-Z0-9]*)?\.+$/, '').replace(/^http:\/\//, ''),521 away = href.match(/away\.php\?to=(.*?)(&|$)/);522 if (away) {523 try {524 href = decodeURIComponent(away[1]);525 } catch(e) {526 href = '';527 }528 }529 href = replaceEntities(href).replace(/^http:\/\//, '');530 if (href && act_html && act_html != href && !href.indexOf(act_html)) {531 wikiValue += ' ' + href;532 } else {533 wikiValue += ' ' + act_html;534 }535 } else if (this.tagName == 'BR') {536 wikiValue += '\n';537 } else {538 if (focusNode == this) {539 cursorPos = wikiValue.length + focusOffset;540 }541 if (this.tagName == 'DIV' || this.tagName == 'P') {542 if (wikiValue.substr(-1) != '\n') {543 wikiValue += '\n';544 }545 }546 each(this.childNodes, arguments.callee);547 }548 };549 each(this.rtaEl.childNodes, parseWikiValue);550 wikiValue = trim(wikiValue);551 if (findCursor || noFocus && this.options.onValueChange && !noCb) {552 this.options.onValueChange(cursorPos ? wikiValue.substr(0, cursorPos) : wikiValue, noFocus);553 }554 wikiValue = trim(wikiValue.replace(/( | |[ \t\r \u00A0])+/gi, ' ')); // -> space555 this.textareaEl.value = wikiValue || this.textareaEl.getAttribute('placeholder') || '';556 if (isFunction(this.options.checkLen)) this.options.checkLen(wikiValue, force);557 if (this.textareaEl.phonsize) this.textareaEl.phonsize();558 return wikiValue;559 }560 });561}562try{jsDispatcher.triggerOnload('mentions',initMentionClass);}catch(e){}...
wysiwygmdab.js
Source:wysiwygmdab.js
1var canDestroy = function (event) {2 var target = event.target;3 return !mw.tools.hasAnyOfClassesOnNodeOrParent(event, ['safe-element'])4 && mw.tools.parentsOrCurrentOrderMatchOrOnlyFirstOrNone(target, ['allow-drop', 'nodrop']);5};6mw.wysiwyg._manageDeleteAndBackspaceInSafeMode = {7 emptyNode: function (event, node, sel, range) {8 if(!canDestroy(node)) {9 return;10 }11 var todelete = node;12 if(mw.tools.hasAnyOfClasses(node.parentNode, ['text', 'title'])){13 todelete = node.parentNode;14 }15 var transfer, transferPosition;16 if (mw.event.is.delete(event)) {17 transfer = todelete.nextElementSibling;18 transferPosition = 'start';19 } else {20 transfer = todelete.previousElementSibling;21 transferPosition = 'end';22 }23 var parent = todelete.parentNode;24 mw.liveEditState.record({25 target: parent,26 value: parent.innerHTML27 });28 $(todelete).remove();29 if(transfer && mw.tools.isEditable(transfer)) {30 setTimeout(function () {31 mw.wysiwyg.cursorToElement(transfer, transferPosition);32 });33 }34 mw.liveEditState.record({35 target: parent,36 value: parent.innerHTML37 });38 },39 nodeBoundaries: function (event, node, sel, range) {40 var isStart = range.startOffset === 0 || !((sel.anchorNode.data || '').substring(0, range.startOffset).replace(/\s/g, ''));41 var curr, content;42 if(mw.event.is.backSpace(event) && isStart && range.collapsed){ // is at the beginning43 curr = node;44 if(mw.tools.hasAnyOfClasses(node.parentNode, ['text', 'title'])){45 curr = node.parentNode;46 }47 var prev = curr.previousElementSibling;48 if(prev && prev.nodeName === node.nodeName && canDestroy(node)) {49 content = node.innerHTML;50 mw.wysiwyg.cursorToElement(prev, 'end');51 prev.appendChild(range.createContextualFragment(content));52 $(curr).remove();53 }54 } else if(mw.event.is.delete(event)55 && range.collapsed56 && range.startOffset === sel.anchorNode.data.replace(/\s*$/,'').length // is at the end57 && canDestroy(node)){58 curr = node;59 if(mw.tools.hasAnyOfClasses(node.parentNode, ['text', 'title'])){60 curr = node.parentNode;61 }62 var next = curr.nextElementSibling, deleteParent;63 if(mw.tools.hasAnyOfClasses(next, ['text', 'title'])){64 next = next.firstElementChild;65 deleteParent = true;66 }67 if(next && next.nodeName === curr.nodeName) {68 content = next.innerHTML;69 setTimeout(function(){70 var parent = deleteParent ? next.parentNode.parentNode : next.parentNode;71 mw.liveEditState.actionRecord(function() {72 return {73 target: parent,74 value: parent.innerHTML75 };76 }, function () {77 curr.append(range.createContextualFragment(content));78 }79 );80 });81 }82 }83 }84};85mw.wysiwyg.manageDeleteAndBackspaceInSafeMode = function (event, sel) {86 var node = mw.wysiwyg.validateCommonAncestorContainer(sel.focusNode);87 var range = sel.getRangeAt(0);88 if(!node.innerText.replace(/\s/gi, '')){89 mw.wysiwyg._manageDeleteAndBackspaceInSafeMode.emptyNode(event, node, sel, range);90 return false;91 }92 mw.wysiwyg._manageDeleteAndBackspaceInSafeMode.nodeBoundaries(event, node, sel, range);93 return true;94};95mw.wysiwyg.manageDeleteAndBackspace = function (event, sel) {96 if (mw.event.is.delete(event) || mw.event.is.backSpace(event)) {97 if(!sel.rangeCount) return;98 var r = sel.getRangeAt(0);99 var isSafe = mw.wysiwyg.isSafeMode();100 if(isSafe) {101 return mw.wysiwyg.manageDeleteAndBackspaceInSafeMode(event, sel);102 }103 if (!mw.settings.liveEdit) {104 return true;105 }106 var nextNode = null, nextchar, nextnextchar, nextel;107 if (mw.event.is.delete(event)) {108 nextchar = sel.focusNode.textContent.charAt(sel.focusOffset);109 nextnextchar = sel.focusNode.textContent.charAt(sel.focusOffset + 1);110 nextel = sel.focusNode.nextSibling || sel.focusNode.nextElementSibling;111 } else {112 nextchar = sel.focusNode.textContent.charAt(sel.focusOffset - 1);113 nextnextchar = sel.focusNode.textContent.charAt(sel.focusOffset - 2);114 nextel = sel.focusNode.previouSibling || sel.focusNode.previousElementSibling;115 }116 if ((nextchar == ' ' || /\r|\n/.exec(nextchar) !== null) && sel.focusNode.nodeType === 3 && !nextnextchar) {117 event.preventDefault();118 return false;119 }120 if (nextnextchar == '') {121 if (nextchar.replace(/\s/g, '') == '' && r.collapsed) {122 if (nextel && !mw.ea.helpers.isBlockLevel(nextel) && ( typeof nextel.className === 'undefined' || !nextel.className.trim())) {123 return true;124 }125 else if (nextel && nextel.nodeName !== 'BR') {126 if (sel.focusNode.nodeName === 'P') {127 if (event.keyCode === 46) {128 if (sel.focusNode.nextElementSibling.nodeName === 'P') {129 return true;130 }131 }132 if (event.keyCode === 8) {133 if (sel.focusNode.previousElementSibling.nodeName === 'P') {134 return true;135 }136 }137 }138 event.preventDefault();139 return false;140 }141 }142 else if ((focus.previousElementSibling === null && rootfocus.previousElementSibling === null) && mw.tools.hasAnyOfClassesOnNodeOrParent(rootfocus, ['nodrop', 'allow-drop'])) {143 return false;144 }145 else {146 }147 }148 if (nextchar == '') {149 //continue check nodes150 if (mw.event.is.delete(event)) {151 nextNode = mw.wysiwyg.merge.getNext(sel.focusNode);152 }153 if (mw.event.is.backSpace(event)) {154 nextNode = mw.wysiwyg.merge.getPrev(sel.focusNode);155 }156 if (mw.wysiwyg.merge.alwaysMergeable(nextNode)) {157 return true;158 }159 var nonbr = mw.wysiwyg.merge.isInNonbreakable(nextNode)160 if (nonbr) {161 event.preventDefault();162 return false;163 }164 if (nextNode.nodeValue == '') {165 }166 if (nextNode !== null && mw.wysiwyg.merge.isMergeable(nextNode)) {167 if (mw.event.is.delete(event)) {168 mw.wysiwyg.merge.manageBreakables(sel.focusNode, nextNode, 'next', event)169 }170 else {171 mw.wysiwyg.merge.manageBreakables(sel.focusNode, nextNode, 'prev', event)172 }173 }174 else {175 event.preventDefault()176 }177 // }178 if (nextNode === null) {179 nextNode = sel.focusNode.parentNode.nextSibling;180 if (!mw.wysiwyg.merge.isMergeable(nextNode)) {181 event.preventDefault();182 }183 if (mw.event.is.delete(event)) {184 mw.wysiwyg.merge.manageBreakables(sel.focusNode, nextNode, 'next', event)185 }186 else {187 mw.wysiwyg.merge.manageBreakables(sel.focusNode, nextNode, 'prev', event)188 }189 }190 } else {191 }192 }193 return true;...
InlineEditingUtil.js
Source:InlineEditingUtil.js
1if (typeof (Sitecore.PageModes) == "undefined") {2 Sitecore.PageModes = new Object();3}4Sitecore.PageModes.InlineEditingUtil = new function () {5 this.processNewLineBreaks = function (editableElement) {6 if (typeof document.getSelection != 'function') {7 return;8 }9 editableElement.addEventListener('keydown', this.onKeyDown);10 editableElement.addEventListener('keypress', this.onKeyPress);11 };12 this.onKeyPress = function (e) {13 if (!Sitecore.PageModes.InlineEditingUtil.checkContentEditable(e.target)) {14 return false;15 }16 if ((e.returnValue || Sitecore.PageModes.InlineEditingUtil.isPrintableKey(e))) {17 if (Sitecore.PageModes.InlineEditingUtil.checkEmptyEditableElement(e.target)) {18 return;19 }20 }21 if (e.keyCode === 13) {22 var lineBreakTag = Sitecore.WebEditSettings.newLineBreak;23 if (lineBreakTag != "p" && lineBreakTag != "div" && lineBreakTag != "br") {24 return;25 }26 e.preventDefault();27 var selection = document.getSelection();28 var range = selection.getRangeAt(0);29 if (lineBreakTag == "br") {30 Sitecore.PageModes.InlineEditingUtil.insertBrLineBreak(selection, range);31 selection.removeAllRanges();32 selection.addRange(range);33 return;34 }35 var focusNode = selection.focusNode.parentNode;36 var contentEditable = focusNode.getAttribute("contenteditable");37 if (contentEditable) {38 focusNode = selection.focusNode;39 }40 var length = selection.focusNode.length;41 var startOrMiddlePosition = selection.focusOffset < length;42 var isParagraph = Sitecore.PageModes.InlineEditingUtil.isParagraph(focusNode);43 if (startOrMiddlePosition || !isParagraph) {44 Sitecore.PageModes.InlineEditingUtil.insertBrLineBreak(selection, range);45 selection.removeAllRanges();46 selection.addRange(range);47 return;48 }49 var focusNode = Sitecore.PageModes.InlineEditingUtil.resolveFocusNode(selection);50 var node = document.createElement(lineBreakTag);51 Sitecore.PageModes.InlineEditingUtil.applyAttributes(focusNode, node);52 range.setStartAfter(focusNode);53 range.insertNode(node);54 var placeholder = document.createElement("br");;55 node.appendChild(placeholder);56 range.collapse(true);57 range.selectNodeContents(node);58 selection.removeAllRanges();59 selection.addRange(range);60 return;61 }62 };63 this.resolveFocusNode = function (selection) {64 var focusNode = selection.focusNode;65 var goToParent = true;66 while (goToParent) {67 var isParagraph = Sitecore.PageModes.InlineEditingUtil.isParagraph(focusNode);68 if (isParagraph) {69 goToParent = false;70 }71 else {72 focusNode = focusNode.parentNode;73 }74 }75 return focusNode;76 };77 this.isParagraph = function (node) {78 var isNotParagraph = false;79 if (node.nodeName) {80 var nodeName = node.nodeName.toLowerCase();81 if (nodeName == "p" || nodeName == "div") {82 return true;83 }84 }85 return false;86 };87 this.onKeyDown = function (e) {88 if (e.keyCode === 8) {89 var selection = document.getSelection();90 var focusNode = selection.focusNode;91 if (!focusNode) {92 return;93 }94 if (typeof focusNode.getAttribute == 'function') {95 if (Sitecore.PageModes.InlineEditingUtil.checkContentEditable(focusNode)) {96 return;97 }98 }99 if (focusNode.nodeName) {100 var focusNodeName = focusNode.nodeName.toLowerCase();101 if (focusNodeName == "p" || focusNodeName == "div") {102 return;103 }104 }105 var parentNode = focusNode.parentNode;106 if (parentNode.textContent == "" && selection.focusOffset == 0) {107 var range = document.createRange();108 range.selectNode(parentNode);109 selection.removeAllRanges();110 selection.addRange(range);111 return false;112 }113 }114 };115 this.applyAttributes = function (focusNode, newTag) {116 if (!focusNode.tagName) {117 return;118 }119 if (focusNode.tagName.toLowerCase() != newTag.tagName.toLowerCase()) {120 return;121 }122 var attributes = focusNode.attributes;123 for (var i = 0; i < attributes.length; i++) {124 var attribute = attributes[i];125 newTag.setAttribute(attribute.name, attribute.value);126 }127 };128 this.insertBrLineBreak = function (selection, range) {129 var brNode = document.createElement("br");130 range.insertNode(brNode);131 range.setStartAfter(brNode);132 range.collapse(true);133 };134 this.checkEmptyEditableElement = function (target) {135 if (!target) {136 return false;137 }138 if (target.textContent != "") {139 return false;140 }141 Sitecore.PageModes.InlineEditingUtil.clearNonPrintableTags(target);142 var newLineNode = Sitecore.WebEditSettings.newLineBreak;143 if (newLineNode.toLowerCase() == "p" || newLineNode.toLowerCase() == "div") {144 var selection = document.getSelection();145 var range = selection.getRangeAt(0);146 if (!Sitecore.PageModes.InlineEditingUtil.checkContentEditable(selection.focusNode)) {147 return true;148 }149 var node = document.createElement(newLineNode);150 range.insertNode(node);151 range.collapse(true);152 node.innerHTML = "<br />";153 range.selectNodeContents(node);154 selection.removeAllRanges();155 selection.addRange(range);156 return true;157 }158 };159 this.clearNonPrintableTags = function (focusNode) {160 if (!focusNode) {161 return;162 }163 var brNodes = [];164 for (var n = 0; n < focusNode.childNodes.length; n++) {165 var child = focusNode.childNodes[n];166 if (!child) {167 continue;168 }169 if (!child.nodeName) {170 continue;171 }172 if (child.nodeName.toLowerCase() != "br") {173 continue;174 }175 brNodes.push(child);176 }177 for (var n = 0; n < brNodes.length; n++) {178 focusNode.removeChild(brNodes[n]);179 }180 };181 this.isPrintableKey = function (keyPressEventArgs) {182 if (typeof keyPressEventArgs.which == "undefined") {183 return true;184 } else if (typeof keyPressEventArgs.which == "number" && keyPressEventArgs.which > 0) {185 return !keyPressEventArgs.ctrlKey && !keyPressEventArgs.metaKey && !keyPressEventArgs.altKey && keyPressEventArgs.which != 8;186 }187 return false;188 };189 this.checkContentEditable = function (target) {190 if (typeof target.getAttribute != "function") {191 return false;192 }193 var attribute = target.getAttribute("contenteditable");194 if (!attribute) {195 return false;196 }197 return attribute === "true";198 };...
ipad-numeric-keypad.js
Source:ipad-numeric-keypad.js
1(function() {2 var focusNode=null;3 var focusScrollBy=0;4 var keypadVisible=false;5 function showIPadNumericKeyboard(evt) {6 var keypad = document.getElementById('ipad-numeric-keypad');7 8 var spacerNodes = document.getElementsByClassName('ipad-numeric-keypad-spacer');9 10 for (var i = 0; i < spacerNodes.length; i ++) {11 var spacerNode = spacerNodes[i];12 spacerNode.style.visibility = 'visible';13 spacerNode.style.height = keypad.offsetHeight + 'px';14 }15 16 if (focusNode) { 17 var top = focusNode.offsetTop;18 var left = focusNode.offsetLeft;19 var height = focusNode.offsetHeight;20 21 var p = focusNode;22 while(p.offsetParent) {23 p = p.offsetParent;24 top += p.offsetTop;25 left += p.offsetLeft;26 }27 28 var bottom = top + height + 20;29 var keypadTop = window.pageYOffset + keypad.offsetTop;30 31 if (bottom > keypadTop) {32 //focusScrollBy = bottom - keypadTop;33 //window.scrollBy(0, focusScrollBy);34 } else {35 focusScrollBy = 0;36 }37 38 //keypad.style.left = (left + (focusNode.offsetWidth - keypad.offsetWidth) / 2) + 'px';39 keypad.style.left = ((window.innerWidth - keypad.offsetWidth) / 2) + 'px';40 }41 42 43 keypad.style.visibility = 'visible';44 45 keypadVisible = true;46 }47 48 function hideIPadNumericKeyboard() {49 var keypad = document.getElementById('ipad-numeric-keypad');50 51 keypad.style.visibility = 'hidden';52 53 var spacerNodes = document.getElementsByClassName('ipad-numeric-keypad-spacer');54 55 for (var i = 0; i < spacerNodes.length; i ++) {56 var spacerNode = spacerNodes[i];57 spacerNode.style.visibility = 'hidden';58 spacerNode.style.height = '0px';59 }60 61 //window.scrollBy(0, -focusScrollBy);62 63 keypadVisible = false;64 }65 66 function onInputFocus(evt) {67 evt.preventDefault();68 69 if (focusNode) {70 focusNode.className = focusNode.className.split(' focused').join('');71 focusNode = null;72 }73 74 focusNode = evt.target;75 76 focusNode.className += ' focused';77 focusNode.blur();78 79 var prevNodes = document.getElementById('ipad-numeric-keypad-specials').getElementsByClassName('prev');80 for (var i = 0; i < prevNodes.length; i++) {81 var prevNode = prevNodes[i];82 if (focusNode.attributes['onPrevV']) {83 prevNode.className = prevNode.className.split(' inactive').join('');84 } else {85 prevNode.className += ' inactive';86 }87 }88 89 var nextNodes = document.getElementById('ipad-numeric-keypad-specials').getElementsByClassName('next');90 for (var i = 0; i < prevNodes.length; i++) {91 var nextNode = nextNodes[i];92 if (focusNode.attributes['onNextV']) {93 nextNode.className = nextNode.className.split(' inactive').join('');94 } else {95 nextNode.className += ' inactive';96 }97 }98 99 showIPadNumericKeyboard();100 }101 102 function onTouchStart(evt) {103 var keypad = document.getElementById('ipad-numeric-keypad');104 if (keypadVisible && evt.target.nodeName.toLowerCase() != 'input' && 105 (evt.pageY < window.pageYOffset + keypad.offsetTop ||106 evt.pageX < window.pageXOffset + keypad.offsetLeft ||107 evt.pageX > window.pageXOffset + keypad.offsetLeft + keypad.offsetWidth)) {108 109 hideIPadNumericKeyboard();110 111 if (focusNode) {112 focusNode.className = focusNode.className.split(' focused').join('');113 focusNode = null;114 }115 }116 }117 118 function onOrientationChange(evt) {119 if (keypadVisible) {120 hideIPadNumericKeyboard();121 122 if (focusNode) {123 focusNode.className = focusNode.className.split(' focused').join('');124 focusNode = null;125 }126 }127 }128 129 window.onload = function() {130 131 var inputNodes = document.getElementsByTagName('input');132 var tabIndex = 0;133 134 for (var i = 0; i < inputNodes.length; i++) {135 var n = inputNodes[i];136 137 if(n.attributes['type'].value == 'number') {138 n.setAttribute('readonly', 'true');139 140 n.setAttribute('tabIndex', tabIndex);141 tabIndex++;142 143 n.addEventListener('focus', onInputFocus, false);144 }145 }146 147 var buttonNodes = document.getElementById('ipad-numeric-keypad').getElementsByTagName('button');148 149 for (var n = 0; n < buttonNodes.length; n++) {150 var b = buttonNodes[n];151 152 b.addEventListener('touchstart', function(evt) {153 evt.preventDefault();154 155 var t = evt.target;156 while(t.nodeName.toLowerCase() != 'button' && t.parentNode) {157 t = t.parentNode;158 }159 160 if (t.className.indexOf('backspace') > -1) {161 var v = focusNode.value;162 focusNode.value = v.substr(0, v.length-1);163 } else if (t.className.indexOf('close') > -1) {164 hideIPadNumericKeyboard();165 166 if (focusNode) {167 focusNode.className = focusNode.className.split(' focused').join('');168 focusNode = null;169 }170 } else if (t.className.indexOf('prev') > -1) {171 if (focusNode && focusNode.attributes['onPrevV']) {172 eval(focusNode.attributes['onPrevV'].value);173 }174 } else if (t.className.indexOf('next') > -1) {175 if (focusNode && focusNode.attributes['onNextV']) {176 eval(focusNode.attributes['onNextV'].value);177 }178 } else {179 if (focusNode.value.length < 5) {180 if (focusNode.value == '' || focusNode.value == '0') {181 focusNode.value = t.innerHTML;182 } else {183 focusNode.value += t.innerHTML;184 }185 186 var evt = document.createEvent("HTMLEvents");187 evt.initEvent("input",true,true);188 focusNode.dispatchEvent( evt );189 }190 }191 }, false);192 } 193 194 };195 196 document.ontouchstart = onTouchStart;197 window.onorientationchange = onOrientationChange;...
main.js
Source:main.js
1window.addEventListener('load', (event) => {2 let SELECTED = null; // contenteditableè¦ç´ ãselectionchangeããã¨ãã®Range3 let IME_YOMI = null; // IMEã§å
¨åã²ãããªã®ã¨ãã»ãããã4 let IS_IME_END = false;5 document.addEventListener('selectionchange', ()=>{6 const sel = document.getSelection();7 const range = sel.getRangeAt(0);8 SELECTED = range;9 console.log('selectionchange', document.getSelection().focusNode);10 if (IS_IME_END) {11 console.log('sel.focusNode', sel.focusNode);12 console.log('sel.focusNode.parentNode', sel.focusNode.parentNode);13 console.log('sel.focusNode.parentNode.nextSibling', sel.focusNode.parentNode.nextSibling);14 console.log('sel.focusNode.parentNode.parentNode', sel.focusNode.parentNode.parentNode);15 console.log('sel.focusNode.parentNode.parentNode.nextSibling', sel.focusNode.parentNode.parentNode.nextSibling);16// sel.selectNode(sel.focusNode.parentNode.nextSibling);17// sel.selectNode(sel.focusNode.parentNode.parentNode.nextSibling);18 range.selectNode(sel.focusNode.parentNode.parentNode.nextSibling);19 console.log('after sel.focusNode', sel.focusNode);20// sel.collapse(sel.focusNode, 0);21 sel.collapseToStart(sel.focusNode, 0);22// sel.collapseToEnd(sel.focusNode, 0);23// sel.collapse(sel.focusNode, 2);24// sel.collapse(sel.focusNode.parentNode.parentNode.nextSibling, 1);25// range.setStart(sel.focusNode, 1);26// range.setEnd(sel.focusNode, 1);27// range.setStart(sel.focusNode.parentNode.parentNode.nextSibling, 0);28// range.setEnd(sel.focusNode.parentNode.parentNode.nextSibling, 0);29 IS_IME_END = false;30 }31 });32 document.addEventListener('compositionstart', (event)=>{33 console.log('compositionstart', event);34 });35 document.addEventListener('compositionupdate', (event)=>{36 console.log('compositionupdate', event);37 if (Japanese.isHiragana(event.data)) { IME_YOMI = event.data; }38 });39 document.addEventListener('compositionend', (event)=>{40 console.log('compositionend', event);41 if (Japanese.isHiragana(event.data)) { IME_YOMI = event.data; }42 IS_IME_END = true;43 appendRuby(event);44 removeImeString(event);45// event.stopImmediatePropagation(); //cancel next event//46// event.preventDefault();47// }, {passive: false});48 });49 document.querySelector('#editor').addEventListener('input', (event)=>{50 console.log('input', event);51 });52 function appendRuby(event) {53 SELECTED.insertNode(Ruby.toDom(event.data, IME_YOMI));54 }55 function removeImeString(event) {56 const sel = document.getSelection();57 const range = sel.getRangeAt(0);58 console.log('sel.focusNode', sel.focusNode);59 console.log('sel.focusNode.parentElement', sel.focusNode.parentElement);60 console.log('sel.focusNode.parentElement.nodeName', sel.focusNode.parentElement.nodeName);61 if (IS_IME_END && 'ruby' !== sel.focusNode.parentElement.nodeName || 'rt' !== sel.focusNode.parentElement.nodeName || 'rb' !== sel.focusNode.parentElement.nodeName) {62 range.setStart(sel.focusNode, sel.focusOffset - event.data.length);63 range.setEnd(sel.focusNode, sel.focusOffset);64 range.deleteContents();65 // ãã£ã¬ããä½ç½®ãããã²ã¨ã¤å
ã«ããããããã<rt>è¦ç´ ã®æ¬¡ãæå®ããæ¹æ³ãããããªãã66// range.setStart(sel.focusNode.parentNode, sel.focusOffset);67 // ç¾å¨ã®é¸æè¦ç´ ï¼<rt>68 // <ruby>ã®æ¬¡ã®è¦ç´ : sel.focusNode.parentNode.nextSibling69// console.log('sel.focusNode', sel.focusNode);70// console.log('sel.focusNode.parentNode', sel.focusNode.parentNode);71// console.log('sel.focusNode.parentNode.nextSibling', sel.focusNode.parentNode.nextSibling);72// sel.selectNode(sel.focusNode.parentNode.nextSibling);73// range.selectNode(sel.focusNode.parentNode.nextSibling);74// sel.getRangeAt(0).setStart(sel.focusNode, 0);75// sel.selectNode(sel.focusNode.parentNode.nextSibling);76// sel.getRangeAt(0).setStart(sel.focusNode, 0);77// range.setStart(sel.focusNode, sel.focusOffset - event.data.length);78// IS_IME_END = false;79 }80 if ('editor' === sel.focusNode.parentElement.id) {81 }82 if (1 === sel.focusNode.nodeType) {83 console.log(`nodeType: Element: name=${sel.focusNode.nodeName}`);84 } else if (3 === sel.focusNode.nodeType) {85 console.log('nodeType: TextNode');86 }87 }...
ve.SelectionState.js
Source:ve.SelectionState.js
1/*!2 * VisualEditor DOM selection-like class3 *4 * @copyright 2011-2018 VisualEditor Team and others; see http://ve.mit-license.org5 */6/**7 * Like the DOM Selection object, but not updated live from the actual selection8 *9 * WARNING: the Nodes are still live and mutable, which can change the meaning10 * of the offsets or invalidate the value of isBackwards.11 *12 * @class13 *14 * @constructor15 * @param {ve.SelectionState|Selection|Object} selection DOM Selection-like object16 * @param {Node|null} selection.anchorNode The anchor node (null if no selection)17 * @param {number} selection.anchorOffset The anchor offset (0 if no selection)18 * @param {Node|null} selection.focusNode The focus node (null if no selection)19 * @param {number} selection.focusOffset The focus offset (0 if no selection)20 * @param {boolean} [selection.isCollapsed] Whether the anchor and focus are the same21 * @param {boolean} [selection.isBackwards] Whether the focus is before the anchor in document order22 */23ve.SelectionState = function VeSelectionState( selection ) {24 this.anchorNode = selection.anchorNode;25 this.anchorOffset = selection.anchorOffset;26 this.focusNode = selection.focusNode;27 this.focusOffset = selection.focusOffset;28 this.isCollapsed = selection.isCollapsed;29 if ( this.isCollapsed === undefined ) {30 // Set to true if nodes are null (matches DOM Selection object's behaviour)31 this.isCollapsed = this.anchorNode === this.focusNode &&32 this.anchorOffset === this.focusOffset;33 }34 this.isBackwards = selection.isBackwards;35 if ( this.isBackwards === undefined ) {36 // Set to false if nodes are null or focus is no earlier than anchor37 this.isBackwards = ve.compareDocumentOrder(38 this.focusNode,39 this.focusOffset,40 this.anchorNode,41 this.anchorOffset42 ) < 0;43 }44};45/* Inheritance */46OO.initClass( ve.SelectionState );47/* Static methods */48/**49 * Create a selection state object representing no selection50 *51 * @return {ve.SelectionState} Object representing no selection52 */53ve.SelectionState.static.newNullSelection = function () {54 return new ve.SelectionState( {55 focusNode: null,56 focusOffset: 0,57 anchorNode: null,58 anchorOffset: 059 } );60};61/* Methods */62/**63 * Returns the selection with the anchor and focus swapped64 *65 * @return {ve.SelectionState} selection with anchor/focus swapped. Object-identical to this if isCollapsed66 */67ve.SelectionState.prototype.flip = function () {68 if ( this.isCollapsed ) {69 return this;70 }71 return new ve.SelectionState( {72 anchorNode: this.focusNode,73 anchorOffset: this.focusOffset,74 focusNode: this.anchorNode,75 focusOffset: this.anchorOffset,76 isCollapsed: false,77 isBackwards: !this.isBackwards78 } );79};80/**81 * Whether the selection represents is the same range as another DOM Selection-like object82 *83 * @param {Object} other DOM Selection-like object84 * @return {boolean} True if the anchors/focuses are equal (including null)85 */86ve.SelectionState.prototype.equalsSelection = function ( other ) {87 return this.anchorNode === other.anchorNode &&88 this.anchorOffset === other.anchorOffset &&89 this.focusNode === other.focusNode &&90 this.focusOffset === other.focusOffset;91};92/**93 * Get a range representation of the selection94 *95 * N.B. Range objects do not show whether the selection is backwards96 *97 * @param {HTMLDocument} doc The owner document of the selection nodes98 * @return {Range|null} Range99 */100ve.SelectionState.prototype.getNativeRange = function ( doc ) {101 var range;102 if ( this.anchorNode === null ) {103 return null;104 }105 range = doc.createRange();106 if ( this.isBackwards ) {107 range.setStart( this.focusNode, this.focusOffset );108 range.setEnd( this.anchorNode, this.anchorOffset );109 } else {110 range.setStart( this.anchorNode, this.anchorOffset );111 if ( !this.isCollapsed ) {112 range.setEnd( this.focusNode, this.focusOffset );113 }114 }115 return range;...
_FormWidgetMixin.js
Source:_FormWidgetMixin.js
1//>>built2define("dijit/form/_FormWidgetMixin",["dojo/_base/array","dojo/_base/declare","dojo/dom-attr","dojo/dom-style","dojo/_base/lang","dojo/mouse","dojo/on","dojo/sniff","dojo/window","../a11y"],function(_1,_2,_3,_4,_5,_6,on,_7,_8,_9){3return _2("dijit.form._FormWidgetMixin",null,{name:"",alt:"",value:"",type:"text","aria-label":"focusNode",tabIndex:"0",_setTabIndexAttr:"focusNode",disabled:false,intermediateChanges:false,scrollOnFocus:true,_setIdAttr:"focusNode",_setDisabledAttr:function(_a){4this._set("disabled",_a);5if(/^(button|input|select|textarea|optgroup|option|fieldset)$/i.test(this.focusNode.tagName)){6_3.set(this.focusNode,"disabled",_a);7if(_7("trident")&&"readOnly" in this){8_3.set(this.focusNode,"readonly",_a||this.readOnly);9}10}else{11this.focusNode.setAttribute("aria-disabled",_a?"true":"false");12}13if(this.valueNode){14_3.set(this.valueNode,"disabled",_a);15}16if(_a){17this._set("hovering",false);18this._set("active",false);19var _b="tabIndex" in this.attributeMap?this.attributeMap.tabIndex:("_setTabIndexAttr" in this)?this._setTabIndexAttr:"focusNode";20_1.forEach(_5.isArray(_b)?_b:[_b],function(_c){21var _d=this[_c];22if(_7("webkit")||_9.hasDefaultTabStop(_d)){23_d.setAttribute("tabIndex","-1");24}else{25_d.removeAttribute("tabIndex");26}27},this);28}else{29if(this.tabIndex!=""){30this.set("tabIndex",this.tabIndex);31}32}33},_onFocus:function(by){34if(by=="mouse"&&this.isFocusable()){35var _e=this.own(on(this.focusNode,"focus",function(){36_f.remove();37_e.remove();38}))[0];39var _10=_7("pointer-events")?"pointerup":_7("MSPointer")?"MSPointerUp":_7("touch-events")?"touchend, mouseup":"mouseup";40var _f=this.own(on(this.ownerDocumentBody,_10,_5.hitch(this,function(evt){41_f.remove();42_e.remove();43if(this.focused){44if(evt.type=="touchend"){45this.defer("focus");46}else{47this.focus();48}49}50})))[0];51}52if(this.scrollOnFocus){53this.defer(function(){54_8.scrollIntoView(this.domNode);55});56}57this.inherited(arguments);58},isFocusable:function(){59return !this.disabled&&this.focusNode&&(_4.get(this.domNode,"display")!="none");60},focus:function(){61if(!this.disabled&&this.focusNode.focus){62try{63this.focusNode.focus();64}65catch(e){66}67}68},compare:function(_11,_12){69if(typeof _11=="number"&&typeof _12=="number"){70return (isNaN(_11)&&isNaN(_12))?0:_11-_12;71}else{72if(_11>_12){73return 1;74}else{75if(_11<_12){76return -1;77}else{78return 0;79}80}81}82},onChange:function(){83},_onChangeActive:false,_handleOnChange:function(_13,_14){84if(this._lastValueReported==undefined&&(_14===null||!this._onChangeActive)){85this._resetValue=this._lastValueReported=_13;86}87this._pendingOnChange=this._pendingOnChange||(typeof _13!=typeof this._lastValueReported)||(this.compare(_13,this._lastValueReported)!=0);88if((this.intermediateChanges||_14||_14===undefined)&&this._pendingOnChange){89this._lastValueReported=_13;90this._pendingOnChange=false;91if(this._onChangeActive){92if(this._onChangeHandle){93this._onChangeHandle.remove();94}95this._onChangeHandle=this.defer(function(){96this._onChangeHandle=null;97this.onChange(_13);98});99}100}101},create:function(){102this.inherited(arguments);103this._onChangeActive=true;104},destroy:function(){105if(this._onChangeHandle){106this._onChangeHandle.remove();107this.onChange(this._lastValueReported);108}109this.inherited(arguments);110}});...
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.focus('input[name="q"]');7 await page.type('input[name="q"]', 'Hello World!');8 await page.screenshot({ path: 'google.png' });9 await browser.close();10})();11page.focusNode(selector[, options])12page.setDefaultTimeout(timeout)13const { chromium } = require('playwright');14(async () => {15 const browser = await chromium.launch();16 const context = await browser.newContext();17 const page = await context.newPage();18 await page.focusNode('input[name="q"]');19 await page.type('input[name="q"]', 'Hello World!');20 await page.screenshot({ path: 'google.png' });21 await browser.close();22})();23page.hoverNode(selector[, options])24page.clickNode(selector[, options])25page.pressNode(selector, key[, options])26page.checkNode(selector[, options])27page.uncheckNode(selector[, options])
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.focus('#search_input_react');7 await page.type('#search_input_react', 'Hello');8 await page.screenshot({ path: 'screenshot.png' });9 await browser.close();10})();11const { chromium } = require('playwright');12(async () => {13 const browser = await chromium.launch({ headless: false });14 const context = await browser.newContext();15 const page = await context.newPage();16 await page.focus('#search_input_react');17 await page.type('#search_input_react', 'Hello');18 await page.screenshot({ path: 'screenshot.png' });19 await browser.close();20})();21const { chromium } = require('playwright');22(async () => {23 const browser = await chromium.launch({ headless: false });24 const context = await browser.newContext();25 const page = await context.newPage();26 await page.focus('#search_input_react');27 await page.type('#search_input_react', 'Hello');28 await page.screenshot({ path: 'screenshot.png' });29 await browser.close();30})();31const { chromium } = require('playwright');32(async () => {33 const browser = await chromium.launch({ headless: false });34 const context = await browser.newContext();35 const page = await context.newPage();36 await page.focus('#search_input_react');37 await page.type('#search_input_react', 'Hello');38 await page.screenshot({ path: 'screenshot.png' });39 await browser.close();40})();41const { chromium } = require('playwright');42(async () => {43 const browser = await chromium.launch({ headless:
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.focus('input[name="q"]');7 await page.keyboard.type('Hello World!');8 await page.screenshot({ path: `example.png` });9 await browser.close();10})();11const { chromium } = require('playwright');12(async () => {13 const browser = await chromium.launch();14 const context = await browser.newContext();15 const page = await context.newPage();16 const input = await page.$('input[name="q"]');17 await input.focus();18 await page.keyboard.type('Hello World!');19 await page.screenshot({ path: `example.png` });20 await browser.close();21})();
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const page = await browser.newPage();5 await browser.close();6})();
Using AI Code Generation
1const { focusNode } = require('playwright/lib/server/dom.js');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch({ headless: false });5 const page = await browser.newPage();6 await page.focus('#lst-ib');7 await page.keyboard.type('Hello World');8 await page.waitForTimeout(3000);9 await page.keyboard.press('Enter');10 await page.waitForTimeout(3000);11 await browser.close();12})();13const { focusNode } = require('playwright/lib/server/dom.js');14const { chromium } = require('playwright');15(async () => {16 const browser = await chromium.launch({ headless: false });17 const page = await browser.newPage();18 await page.focus('#lst-ib');19 await page.keyboard.type('Hello World');20 await page.waitForTimeout(3000);21 await page.keyboard.press('Enter');22 await page.waitForTimeout(3000);23 await browser.close();24})();25const { focusNode } = require('playwright/lib/server/dom.js');26const { chromium } = require('playwright');27(async () => {28 const browser = await chromium.launch({ headless: false });29 const page = await browser.newPage();30 await page.focus('#lst-ib');31 await page.keyboard.type('Hello World');32 await page.waitForTimeout(3000);33 await page.keyboard.press('Enter');34 await page.waitForTimeout(3000);35 await browser.close();36})();37const { focusNode } = require('playwright/lib/server/dom.js');38const { chromium } = require('playwright');39(async () => {40 const browser = await chromium.launch({ headless: false });41 const page = await browser.newPage();42 await page.focus('#lst-ib');43 await page.keyboard.type('Hello World');44 await page.waitForTimeout(3000);45 await page.keyboard.press('Enter');
Using AI Code Generation
1const { chromium } = require('playwright');2const { focusNode } = require('playwright/lib/internal/inspector');3(async () => {4 const browser = await chromium.launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 await focusNode(page, {8 });9 await page.keyboard.type('Hello World');10 await browser.close();11})();
Using AI Code Generation
1const { focusNode } = require('playwright/lib/internal/protocol');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch();5 const page = await browser.newPage();6 await focusNode(page, { selector: '#tsf > div:nth-child(2) > div > div.RNNXgb > div > div.a4bIc > input' });7 await page.keyboard.type('Hello world!');8 await browser.close();9})();10const { focusNode } = require('playwright/lib/internal/protocol');11const { chromium } = require('playwright');12(async () => {13 const browser = await chromium.launch();14 const page = await browser.newPage();15 await focusNode(page, { selector: '#tsf > div:nth-child(2) > div > div.RNNXgb > div > div.a4bIc > input' });16 await page.keyboard.type('Hello world!');17 await browser.close();18})();19const { focusNode } = require('playwright/lib/internal/protocol');20const { chromium } = require('playwright');21(async () => {22 const browser = await chromium.launch();23 const page = await browser.newPage();24 await focusNode(page, { selector: '#tsf > div:nth-child(2) > div > div.RNNXgb > div > div.a4bIc > input' });25 await page.keyboard.type('Hello world!');26 await browser.close();27})();28const { focusNode } = require('playwright/lib/internal/protocol');29const { chromium } = require('playwright');30(async () => {31 const browser = await chromium.launch();32 const page = await browser.newPage();33 await focusNode(page, { selector: '#tsf > div:nth-child(2) > div > div.RNNXgb > div > div.a4bIc > input' });34 await page.keyboard.type('Hello
Using AI Code Generation
1const { focusNode } = require('playwright/lib/protocol/protocol.api');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch({ headless: false });5 const context = await browser.newContext();6 const page = await context.newPage();7 await page.focus('#navbar > div > div > div > div > div > div > div > div > div > a:nth-child(1)');8 await focusNode(page, { selector: '#navbar > div > div > div > div > div > div > div > div > div > a:nth-child(1)' });
Using AI Code Generation
1const { focusNode } = require('playwright');2const { focusNode } = require('playwright');3const { chromium } = require('playwright');4(async () => {5 const browser = await chromium.launch();6 const page = await browser.newPage();7 await page.focus('#search_form_input_homepage');8 await focusNode(page, '#search_form_input_homepage');9 await page.type('#search_form_input_homepage', 'Playwright');10 await page.click('#search_button_homepage');11 await browser.close();12})();13The focusNode() method takes two parameters:14const { focusNode } = require('playwright');15const { chromium } = require('playwright');16(async () => {17 const browser = await chromium.launch();18 const page = await browser.newPage();19 await page.click('text=More');20 await focusNode(page, 'text=More');21 await page.click('text=Accessibility');22 await browser.close();23})();24Playwright’s focusNode() method is a Playwright internal API method. It can be used to focus an element in the DOM. The focusNode() method takes two parameters:25const { focusNode } = require('playwright');26const { chromium }
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.focus('input[name="q"]');7 await page.keyboard.type('Hello World!');8 await browser.close();9})();10const { chromium } = require('playwright');11const browser = await chromium.launch({12});13const page = await browser.newPage();14const context = await page._context();
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!!