| // Copyright 2012 The Closure Library Authors. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS-IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| goog.provide('goog.editor.plugins.FirstStrongTest'); |
| goog.setTestOnly('goog.editor.plugins.FirstStrongTest'); |
| |
| goog.require('goog.dom.Range'); |
| goog.require('goog.editor.Command'); |
| goog.require('goog.editor.Field'); |
| goog.require('goog.editor.plugins.FirstStrong'); |
| goog.require('goog.editor.range'); |
| goog.require('goog.events.KeyCodes'); |
| goog.require('goog.testing.MockClock'); |
| goog.require('goog.testing.editor.TestHelper'); |
| goog.require('goog.testing.events'); |
| goog.require('goog.testing.jsunit'); |
| goog.require('goog.userAgent'); |
| |
| // The key code for the Hebrew א, a strongly RTL letter. |
| var ALEPH_KEYCODE = 1488; |
| var field; |
| var fieldElement; |
| var dom; |
| var helper; |
| var triggeredCommand = null; |
| var clock; |
| |
| function setUp() { |
| field = new goog.editor.Field('field'); |
| field.registerPlugin(new goog.editor.plugins.FirstStrong()); |
| field.makeEditable(); |
| |
| fieldElement = field.getElement(); |
| |
| helper = new goog.testing.editor.TestHelper(fieldElement); |
| |
| dom = field.getEditableDomHelper(); |
| |
| // Mock out execCommand to see if a direction change has been triggered. |
| field.execCommand = function(command) { |
| if (command == goog.editor.Command.DIR_LTR || |
| command == goog.editor.Command.DIR_RTL) |
| triggeredCommand = command; |
| }; |
| } |
| |
| function tearDown() { |
| goog.dispose(field); |
| goog.dispose(helper); |
| triggeredCommand = null; |
| goog.dispose(clock); // Make sure clock is disposed. |
| |
| } |
| |
| function testFirstCharacter_RTL() { |
| field.setHtml(false, '<div id="text"> </div>'); |
| field.focusAndPlaceCursorAtStart(); |
| goog.testing.events.fireNonAsciiKeySequence(fieldElement, |
| goog.events.KeyCodes.T, ALEPH_KEYCODE); |
| assertRTL(); |
| } |
| |
| function testFirstCharacter_LTR() { |
| field.setHtml(false, '<div dir="rtl" id="text"> </div>'); |
| field.focusAndPlaceCursorAtStart(); |
| goog.testing.events.fireKeySequence(fieldElement, |
| goog.events.KeyCodes.A); |
| assertLTR(); |
| } |
| |
| function testFirstStrongCharacter_RTL() { |
| field.setHtml(false, '<div id="text">123.7 3121, <b><++{}></b> - $45</div>'); |
| field.focusAndPlaceCursorAtStart(); |
| goog.testing.events.fireNonAsciiKeySequence(fieldElement, |
| goog.events.KeyCodes.T, ALEPH_KEYCODE); |
| assertRTL(); |
| } |
| |
| function testFirstStrongCharacter_LTR() { |
| field.setHtml(false, |
| '<div dir="rtl" id="text">123.7 3121, <b><++{}></b> - $45</div>'); |
| field.focusAndPlaceCursorAtStart(); |
| goog.testing.events.fireKeySequence(fieldElement, |
| goog.events.KeyCodes.A); |
| assertLTR(); |
| } |
| |
| function testNotStrongCharacter_RTL() { |
| field.setHtml(false, '<div id="text">123.7 3121, - $45</div>'); |
| field.focusAndPlaceCursorAtStart(); |
| goog.testing.events.fireKeySequence(fieldElement, goog.events.KeyCodes.NINE); |
| assertNoCommand(); |
| } |
| |
| function testNotStrongCharacter_LTR() { |
| field.setHtml(false, '<div dir="rtl" id="text">123.7 3121 $45</div>'); |
| field.focusAndPlaceCursorAtStart(); |
| goog.testing.events.fireKeySequence(fieldElement, goog.events.KeyCodes.NINE); |
| assertNoCommand(); |
| } |
| |
| function testNotFirstStrongCharacter_RTL() { |
| field.setHtml(false, '<div id="text">123.7 3121, <b>English</b> - $45</div>'); |
| field.focusAndPlaceCursorAtStart(); |
| goog.testing.events.fireNonAsciiKeySequence(fieldElement, |
| goog.events.KeyCodes.T, ALEPH_KEYCODE); |
| assertNoCommand(); |
| } |
| |
| function testNotFirstStrongCharacter_LTR() { |
| field.setHtml(false, |
| '<div dir="rtl" id="text">123.7 3121, <b>עברית</b> - $45</div>'); |
| field.focusAndPlaceCursorAtStart(); |
| goog.testing.events.fireKeySequence(fieldElement, |
| goog.events.KeyCodes.A); |
| assertNoCommand(); |
| } |
| |
| function testFirstStrongCharacterWithInnerDiv_RTL() { |
| field.setHtml(false, |
| '<div id="text">123.7 3121, <b id="b"><++{}></b>' + |
| '<div id="inner">English</div>' + |
| '</div>'); |
| field.focusAndPlaceCursorAtStart(); |
| goog.testing.events.fireNonAsciiKeySequence(fieldElement, |
| goog.events.KeyCodes.T, ALEPH_KEYCODE); |
| assertRTL(); |
| } |
| |
| function testFirstStrongCharacterWithInnerDiv_LTR() { |
| field.setHtml(false, |
| '<div dir="rtl" id="text">123.7 3121, <b id="b"><++{}></b>' + |
| '<div id="inner">English</div>' + |
| '</div>'); |
| field.focusAndPlaceCursorAtStart(); |
| goog.testing.events.fireKeySequence(fieldElement, |
| goog.events.KeyCodes.A); |
| assertLTR(); |
| } |
| |
| |
| /** |
| * Regression test for {@link http://b/7549696} |
| */ |
| function testFirstStrongCharacterInNewLine_RTL() { |
| field.setHtml(false, '<div><b id="cur">English<br>1</b></div>'); |
| goog.dom.Range.createCaret(dom.$('cur'), 2).select(); |
| |
| goog.testing.events.fireNonAsciiKeySequence(fieldElement, |
| goog.events.KeyCodes.T, ALEPH_KEYCODE); |
| // Only GECKO treats <br> as a new paragraph. |
| if (goog.userAgent.GECKO) { |
| assertRTL(); |
| } else { |
| assertNoCommand(); |
| } |
| } |
| |
| function testFirstStrongCharacterInParagraph_RTL() { |
| field.setHtml(false, |
| '<div id="text1">1> English</div>' + |
| '<div id="text2">2></div>' + |
| '<div id="text3">3></div>'); |
| goog.dom.Range.createCaret(dom.$('text2'), 0).select(); |
| |
| goog.testing.events.fireNonAsciiKeySequence(fieldElement, |
| goog.events.KeyCodes.T, ALEPH_KEYCODE); |
| assertRTL(); |
| } |
| |
| function testFirstStrongCharacterInParagraph_LTR() { |
| field.setHtml(false, |
| '<div dir="rtl" id="text1">1> עברית</div>' + |
| '<div dir="rtl" id="text2">2></div>' + |
| '<div dir="rtl" id="text3">3></div>'); |
| goog.dom.Range.createCaret(dom.$('text2'), 0).select(); |
| |
| goog.testing.events.fireKeySequence(fieldElement, |
| goog.events.KeyCodes.A); |
| assertLTR(); |
| } |
| |
| function testFirstStrongCharacterInList_RTL() { |
| field.setHtml(false, |
| '<div id="text1">1> English</div>' + |
| '<ul id="list">' + |
| '<li>10></li>' + |
| '<li id="li2"></li>' + |
| '<li>30</li>' + |
| '</ul>' + |
| '<div id="text3">3></div>'); |
| goog.editor.range.placeCursorNextTo(dom.$('li2'), true); |
| |
| goog.testing.events.fireNonAsciiKeySequence(fieldElement, |
| goog.events.KeyCodes.T, ALEPH_KEYCODE); |
| assertRTL(); |
| } |
| |
| function testFirstStrongCharacterInList_LTR() { |
| field.setHtml(false, |
| '<div dir="rtl" id="text1">1> English</div>' + |
| '<ul dir="rtl" id="list">' + |
| '<li>10></li>' + |
| '<li id="li2"></li>' + |
| '<li>30</li>' + |
| '</ul>' + |
| '<div dir="rtl" id="text3">3></div>'); |
| goog.editor.range.placeCursorNextTo(dom.$('li2'), true); |
| |
| goog.testing.events.fireKeySequence(fieldElement, |
| goog.events.KeyCodes.A); |
| assertLTR(); |
| } |
| |
| function testNotFirstStrongCharacterInList_RTL() { |
| field.setHtml(false, |
| '<div id="text1">1</div>' + |
| '<ul id="list">' + |
| '<li>10></li>' + |
| '<li id="li2"></li>' + |
| '<li>30<b>3<i>Hidden English</i>32</b></li>' + |
| '</ul>' + |
| '<div id="text3">3></div>'); |
| goog.editor.range.placeCursorNextTo(dom.$('li2'), true); |
| |
| goog.testing.events.fireNonAsciiKeySequence(fieldElement, |
| goog.events.KeyCodes.T, ALEPH_KEYCODE); |
| assertNoCommand(); |
| } |
| |
| function testNotFirstStrongCharacterInList_LTR() { |
| field.setHtml(false, |
| '<div dir="rtl" id="text1">1> English</div>' + |
| '<ul dir="rtl" id="list">' + |
| '<li>10></li>' + |
| '<li id="li2"></li>' + |
| '<li>30<b>3<i>עברית סמויה</i>32</b></li>' + |
| '</ul>' + |
| '<div dir="rtl" id="text3">3></div>'); |
| goog.editor.range.placeCursorNextTo(dom.$('li2'), true); |
| |
| goog.testing.events.fireKeySequence(fieldElement, |
| goog.events.KeyCodes.A); |
| assertNoCommand(); |
| } |
| |
| function testFirstStrongCharacterWithBR_RTL() { |
| field.setHtml(false, |
| '<div id="container">' + |
| '<div id="text1">ABC</div>' + |
| '<div id="text2">' + |
| '1<br>' + |
| '2<b id="inner">3</b><i>4<u>5<br>' + |
| '6</u>7</i>8</b>9<br>' + |
| '10' + |
| '</div>' + |
| '<div id="text3">11</div>' + |
| '</div>'); |
| |
| goog.editor.range.placeCursorNextTo(dom.$('inner'), true); |
| goog.testing.events.fireNonAsciiKeySequence(fieldElement, |
| goog.events.KeyCodes.T, ALEPH_KEYCODE); |
| assertRTL(); |
| } |
| |
| function testFirstStrongCharacterWithBR_LTR() { |
| field.setHtml(false, |
| '<div dir="rtl" id="container">' + |
| '<div dir="rtl" id="text1">אבג</div>' + |
| '<div dir="rtl" id="text2">' + |
| '1<br>' + |
| '2<b id="inner">3</b><i>4<u>5<br>' + |
| '6</u>7</i>8</b>9<br>' + |
| '10' + |
| '</div>' + |
| '<div dir="rtl" id="text3">11</div>' + |
| '</div>'); |
| |
| goog.editor.range.placeCursorNextTo(dom.$('inner'), true); |
| goog.testing.events.fireKeySequence(fieldElement, |
| goog.events.KeyCodes.A); |
| assertLTR(); |
| } |
| |
| function testNotFirstStrongCharacterInBR_RTL() { |
| field.setHtml(false, |
| '<div id="container">' + |
| '<div id="text1">ABC</div>' + |
| '<div id="text2">' + |
| '1<br>' + |
| '2<b id="inner">3</b><i><em>4G</em><u>5<br>' + |
| '6</u>7</i>8</b>9<br>' + |
| '10' + |
| '</div>' + |
| '<div id="text3">11</div>' + |
| '</div>'); |
| |
| goog.editor.range.placeCursorNextTo(dom.$('inner'), true); |
| goog.testing.events.fireNonAsciiKeySequence(fieldElement, |
| goog.events.KeyCodes.T, ALEPH_KEYCODE); |
| assertNoCommand(); |
| } |
| |
| function testNotFirstStrongCharacterInBR_LTR() { |
| field.setHtml(false, |
| '<div dir="rtl" id="container">' + |
| '<div dir="rtl" id="text1">ABC</div>' + |
| '<div dir="rtl" id="text2">' + |
| '1<br>' + |
| '2<b id="inner">3</b><i><em>4G</em><u>5<br>' + |
| '6</u>7</i>8</b>9<br>' + |
| '10' + |
| '</div>' + |
| '<div dir="rtl" id="text3">11</div>' + |
| '</div>'); |
| |
| goog.editor.range.placeCursorNextTo(dom.$('inner'), true); |
| goog.testing.events.fireKeySequence(fieldElement, |
| goog.events.KeyCodes.A); |
| assertNoCommand(); |
| } |
| |
| |
| /** |
| * Regression test for {@link http://b/7530985} |
| */ |
| function testFirstStrongCharacterWithPreviousBlockSibling_RTL() { |
| field.setHtml(false, '<div>Te<div>xt</div>1<b id="cur">2</b>3</div>'); |
| goog.editor.range.placeCursorNextTo(dom.$('cur'), true); |
| goog.testing.events.fireNonAsciiKeySequence(fieldElement, |
| goog.events.KeyCodes.T, ALEPH_KEYCODE); |
| assertRTL(); |
| } |
| |
| function testFirstStrongCharacterWithPreviousBlockSibling_LTR() { |
| field.setHtml( |
| false, '<div dir="rtl">טק<div>סט</div>1<b id="cur">2</b>3</div>'); |
| goog.editor.range.placeCursorNextTo(dom.$('cur'), true); |
| goog.testing.events.fireKeySequence(fieldElement, goog.events.KeyCodes.A); |
| assertLTR(); |
| } |
| |
| function testFirstStrongCharacterWithFollowingBlockSibling_RTL() { |
| field.setHtml(false, '<div>1<b id="cur">2</b>3<div>Te</div>xt</div>'); |
| goog.editor.range.placeCursorNextTo(dom.$('cur'), true); |
| goog.testing.events.fireNonAsciiKeySequence(fieldElement, |
| goog.events.KeyCodes.T, ALEPH_KEYCODE); |
| assertRTL(); |
| } |
| |
| function testFirstStrongCharacterWithFollowingBlockSibling_RTL() { |
| field.setHtml(false, '<div dir="rtl">1<b id="cur">2</b>3<div>א</div>ב</div>'); |
| goog.editor.range.placeCursorNextTo(dom.$('cur'), true); |
| goog.testing.events.fireKeySequence(fieldElement, goog.events.KeyCodes.A); |
| assertLTR(); |
| } |
| |
| function testFirstStrongCharacterFromIME_RTL() { |
| field.setHtml(false, '<div id="text">123.7 3121, </div>'); |
| field.focusAndPlaceCursorAtStart(); |
| var attributes = {}; |
| attributes[goog.editor.plugins.FirstStrong.INPUT_ATTRIBUTE] = 'אבג'; |
| goog.testing.events.fireNonAsciiKeySequence(fieldElement, 0, 0, attributes); |
| if (goog.userAgent.IE) { |
| // goog.testing.events.fireNonAsciiKeySequence doesn't send KEYPRESS event |
| // so no command is expected. |
| assertNoCommand(); |
| } else { |
| assertRTL(); |
| } |
| } |
| |
| function testFirstCharacterFromIME_LTR() { |
| field.setHtml(false, '<div dir="rtl" id="text"> 1234 </div>'); |
| field.focusAndPlaceCursorAtStart(); |
| var attributes = {}; |
| attributes[goog.editor.plugins.FirstStrong.INPUT_ATTRIBUTE] = 'ABC'; |
| goog.testing.events.fireNonAsciiKeySequence(fieldElement, 0, 0, attributes); |
| if (goog.userAgent.IE) { |
| // goog.testing.events.fireNonAsciiKeySequence doesn't send KEYPRESS event |
| // so no command is expected. |
| assertNoCommand(); |
| } else { |
| assertLTR(); |
| } |
| } |
| |
| |
| /** |
| * Regression test for {@link http://b/19297723} |
| */ |
| function testLTRShortlyAfterRTLAndEnter() { |
| clock = new goog.testing.MockClock(); |
| field.focusAndPlaceCursorAtStart(); |
| goog.testing.events.fireNonAsciiKeySequence(fieldElement, |
| goog.events.KeyCodes.T, ALEPH_KEYCODE); |
| assertRTL(); |
| clock.tick(1000); // Make sure no pending selection change event. |
| goog.testing.events.fireKeySequence(fieldElement, goog.events.KeyCodes.ENTER); |
| assertRTL(); |
| goog.testing.events.fireKeySequence(fieldElement, goog.events.KeyCodes.A); |
| assertLTR(); |
| // Verify no RTL for first keypress on already-striong paragraph after |
| // delayed selection change event. |
| clock.tick(1000); // Let delayed selection change event fire. |
| goog.testing.events.fireNonAsciiKeySequence(fieldElement, |
| goog.events.KeyCodes.T, ALEPH_KEYCODE); |
| assertLTR(); |
| } |
| |
| function testRTLShortlyAfterLTRAndEnter() { |
| clock = new goog.testing.MockClock(); |
| field.focusAndPlaceCursorAtStart(); |
| goog.testing.events.fireKeySequence(fieldElement, goog.events.KeyCodes.A); |
| assertLTR(); |
| clock.tick(1000); // Make sure no pending selection change event. |
| goog.testing.events.fireKeySequence(fieldElement, goog.events.KeyCodes.ENTER); |
| assertLTR(); |
| goog.testing.events.fireNonAsciiKeySequence(fieldElement, |
| goog.events.KeyCodes.T, ALEPH_KEYCODE); |
| assertRTL(); |
| // Verify no LTR for first keypress on already-strong paragraph after |
| // delayed selection change event. |
| clock.tick(1000); // Let delayed selection change event fire. |
| goog.testing.events.fireKeySequence(fieldElement, goog.events.KeyCodes.A); |
| assertRTL(); |
| } |
| |
| function assertRTL() { |
| assertEquals(goog.editor.Command.DIR_RTL, triggeredCommand); |
| } |
| |
| function assertLTR() { |
| assertEquals(goog.editor.Command.DIR_LTR, triggeredCommand); |
| } |
| |
| function assertNoCommand() { |
| assertNull(triggeredCommand); |
| } |