blob: 9dc8530ab6ceaeb6686afec780d03478ab9af8b5 [file] [log] [blame]
// 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">&nbsp;</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">&nbsp;</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&gt; English</div>' +
'<div id="text2">2&gt;</div>' +
'<div id="text3">3&gt;</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&gt; עברית</div>' +
'<div dir="rtl" id="text2">2&gt;</div>' +
'<div dir="rtl" id="text3">3&gt;</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&gt; English</div>' +
'<ul id="list">' +
'<li>10&gt;</li>' +
'<li id="li2"></li>' +
'<li>30</li>' +
'</ul>' +
'<div id="text3">3&gt;</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&gt; English</div>' +
'<ul dir="rtl" id="list">' +
'<li>10&gt;</li>' +
'<li id="li2"></li>' +
'<li>30</li>' +
'</ul>' +
'<div dir="rtl" id="text3">3&gt;</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&gt;</li>' +
'<li id="li2"></li>' +
'<li>30<b>3<i>Hidden English</i>32</b></li>' +
'</ul>' +
'<div id="text3">3&gt;</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&gt; English</div>' +
'<ul dir="rtl" id="list">' +
'<li>10&gt;</li>' +
'<li id="li2"></li>' +
'<li>30<b>3<i>עברית סמויה</i>32</b></li>' +
'</ul>' +
'<div dir="rtl" id="text3">3&gt;</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);
}