aboutsummaryrefslogtreecommitdiff
path: root/contexts/data/lib/closure-library/closure/goog/editor/field_test.js
diff options
context:
space:
mode:
Diffstat (limited to 'contexts/data/lib/closure-library/closure/goog/editor/field_test.js')
-rw-r--r--contexts/data/lib/closure-library/closure/goog/editor/field_test.js1160
1 files changed, 0 insertions, 1160 deletions
diff --git a/contexts/data/lib/closure-library/closure/goog/editor/field_test.js b/contexts/data/lib/closure-library/closure/goog/editor/field_test.js
deleted file mode 100644
index c2c782c..0000000
--- a/contexts/data/lib/closure-library/closure/goog/editor/field_test.js
+++ /dev/null
@@ -1,1160 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Shared tests for goog.editor.Field and ContentEditableField.
- * Since ContentEditableField switches many of the internal code paths in Field
- * (such as via usesIframe()) it's important to re-run a lot of the same tests.
- *
- * @author nicksantos@google.com (Nick Santos)
- * @author jparent@google.com (Julie Parent)
- * @author gboyer@google.com (Garrett Boyer)
- */
-
-goog.provide('goog.editor.field_test');
-
-goog.require('goog.dom.Range');
-goog.require('goog.editor.Field');
-goog.require('goog.editor.Plugin');
-goog.require('goog.editor.Command');
-goog.require('goog.events');
-goog.require('goog.events.KeyCodes');
-goog.require('goog.functions');
-goog.require('goog.testing.LooseMock');
-goog.require('goog.testing.MockClock');
-goog.require('goog.testing.dom');
-goog.require('goog.testing.events');
-goog.require('goog.testing.recordFunction');
-goog.require('goog.userAgent');
-goog.require('goog.userAgent.product');
-goog.setTestOnly('Tests for goog.editor.*Field');
-
-
-/** Constructor to use for creating the field. Set by the test HTML file. */
-var FieldConstructor;
-
-
-/** Hard-coded HTML for the tests. */
-var HTML = '<div id="testField">I am text.</div>';
-
-
-function setUp() {
- goog.dom.getElement('parent').innerHTML = HTML;
- assertTrue('FieldConstructor should be set by the test HTML file',
- goog.isFunction(FieldConstructor));
-}
-
-
-function tearDown() {
- // NOTE(nicksantos): I think IE is blowing up on this call because
- // it is lame. It manifests its lameness by throwing an exception.
- // Kudos to XT for helping me to figure this out.
- try {
- goog.events.removeAll();
- } catch (e) {}
-}
-
-// Tests for the plugin interface.
-
-
-
-/**
- * Dummy plugin for test usage.
- * @constructor
- * @extends {goog.editor.Plugin}
- */
-function TestPlugin() {
- this.getTrogClassId = function() {
- return 'TestPlugin';
- };
-
- this.handleKeyDown = goog.nullFunction;
- this.handleKeyPress = goog.nullFunction;
- this.handleKeyUp = goog.nullFunction;
- this.handleKeyboardShortcut = goog.nullFunction;
- this.isSupportedCommand = goog.nullFunction;
- this.execCommandInternal = goog.nullFunction;
- this.queryCommandValue = goog.nullFunction;
- this.activeOnUneditableFields = goog.nullFunction;
- this.handleSelectionChange = goog.nullFunction;
-}
-goog.inherits(TestPlugin, goog.editor.Plugin);
-
-
-/**
- * Tests that calling registerPlugin will add the plugin to the
- * plugin map.
- */
-function testRegisterPlugin() {
- var editableField = new FieldConstructor('testField');
- var plugin = new TestPlugin();
-
- editableField.registerPlugin(plugin);
-
- assertEquals('Registered plugin must be in protected plugin map.',
- plugin, editableField.plugins_[plugin.getTrogClassId()]);
- assertEquals('Plugin has a keydown handler, should be in keydown map',
- plugin,
- editableField.indexedPlugins_[goog.editor.Plugin.Op.KEYDOWN][0]);
- assertEquals('Plugin has a keypress handler, should be in keypress map',
- plugin,
- editableField.indexedPlugins_[goog.editor.Plugin.Op.KEYPRESS][0]);
- assertEquals('Plugin has a keyup handler, should be in keuup map',
- plugin,
- editableField.indexedPlugins_[goog.editor.Plugin.Op.KEYUP][0]);
- assertEquals(
- 'Plugin has a selectionchange handler, should be in selectionchange map',
- plugin,
- editableField.indexedPlugins_[goog.editor.Plugin.Op.SELECTION][0]);
- assertEquals('Plugin has a shortcut handler, should be in shortcut map',
- plugin,
- editableField.indexedPlugins_[goog.editor.Plugin.Op.SHORTCUT][0]);
- assertEquals('Plugin has a execCommand, should be in execCommand map',
- plugin,
- editableField.indexedPlugins_[goog.editor.Plugin.Op.EXEC_COMMAND][0]);
- assertEquals('Plugin has a queryCommand, should be in queryCommand map',
- plugin,
- editableField.indexedPlugins_[goog.editor.Plugin.Op.QUERY_COMMAND][0]);
- assertEquals('Plugin does not have a prepareContentsHtml,' +
- 'should not be in prepareContentsHtml map',
- undefined,
- editableField.indexedPlugins_[
- goog.editor.Plugin.Op.PREPARE_CONTENTS_HTML][0]);
- assertEquals('Plugin does not have a cleanContentsDom,' +
- 'should not be in cleanContentsDom map',
- undefined,
- editableField.indexedPlugins_[
- goog.editor.Plugin.Op.CLEAN_CONTENTS_DOM][0]);
- assertEquals('Plugin does not have a cleanContentsHtml,' +
- 'should not be in cleanContentsHtml map',
- undefined,
- editableField.indexedPlugins_[
- goog.editor.Plugin.Op.CLEAN_CONTENTS_HTML][0]);
-
- editableField.dispose();
-}
-
-
-/**
- * Tests that calling unregisterPlugin will remove the plugin from
- * the map.
- */
-function testUnregisterPlugin() {
- var editableField = new FieldConstructor('testField');
- var plugin = new TestPlugin();
-
- editableField.registerPlugin(plugin);
- editableField.unregisterPlugin(plugin);
-
- assertUndefined('Unregistered plugin must not be in protected plugin map.',
- editableField.plugins_[plugin.getTrogClassId()]);
-
- editableField.dispose();
-}
-
-
-/**
- * Tests that registered plugins can be fetched by their id.
- */
-function testGetPluginByClassId() {
- var editableField = new FieldConstructor('testField');
- var plugin = new TestPlugin();
-
- assertUndefined('Must not be able to get unregistered plugins by class id.',
- editableField.getPluginByClassId(plugin.getTrogClassId()));
-
- editableField.registerPlugin(plugin);
- assertEquals('Must be able to get registered plugins by class id.',
- plugin, editableField.getPluginByClassId(plugin.getTrogClassId()));
- editableField.dispose();
-}
-
-
-/**
- * Tests that plugins get auto disposed by default when the field is disposed.
- * Tests that plugins with setAutoDispose(false) do not get disposed when the
- * field is disposed.
- */
-function testDisposed_PluginAutoDispose() {
- var editableField = new FieldConstructor('testField');
- var plugin = new TestPlugin();
-
- var noDisposePlugin = new goog.editor.Plugin();
- noDisposePlugin.getTrogClassId = function() {
- return 'noDisposeId';
- };
- noDisposePlugin.setAutoDispose(false);
-
- editableField.registerPlugin(plugin);
- editableField.registerPlugin(noDisposePlugin);
- editableField.dispose();
- assert(editableField.isDisposed());
- assertTrue(plugin.isDisposed());
- assertFalse(noDisposePlugin.isDisposed());
-}
-
-var STRING_KEY = String.fromCharCode(goog.events.KeyCodes.A).toLowerCase();
-
-/**
- * @return {goog.events.Event} Returns an event for a keyboard shortcut
- * for the letter 'a'
- */
-function getBrowserEvent() {
- var e = new goog.events.BrowserEvent();
- e.ctrlKey = true;
- e.metaKey = true;
- e.charCode = goog.events.KeyCodes.A;
- return e;
-}
-
-
-/**
- * Tests that plugins are disabled when the field is made uneditable.
- */
-
-function testMakeUneditableDisablesPlugins() {
- var editableField = new FieldConstructor('testField');
- var plugin = new TestPlugin();
-
- var calls = 0;
- plugin.disable = function(field) {
- assertEquals(editableField, field);
- assertTrue(field.isUneditable());
- calls++;
- };
-
- editableField.registerPlugin(plugin);
- editableField.makeEditable();
-
- assertEquals(0, calls);
- editableField.makeUneditable();
-
- assertEquals(1, calls);
-
- editableField.dispose();
-}
-
-
-/**
- * Test that if a plugin registers keyup, it gets called.
- */
-function testPluginKeyUp() {
- var editableField = new FieldConstructor('testField');
- var plugin = new TestPlugin();
- var e = getBrowserEvent();
-
- var mockPlugin = new goog.testing.LooseMock(plugin);
- mockPlugin.getTrogClassId().$returns('mockPlugin');
- mockPlugin.registerFieldObject(editableField);
- mockPlugin.isEnabled(editableField).$anyTimes().$returns(true);
- mockPlugin.handleKeyUp(e);
- mockPlugin.$replay();
-
- editableField.registerPlugin(mockPlugin);
-
- editableField.handleKeyUp_(e);
-
- mockPlugin.$verify();
-}
-
-
-/**
- * Test that if a plugin registers keydown, it gets called.
- */
-function testPluginKeyDown() {
- var editableField = new FieldConstructor('testField');
- var plugin = new TestPlugin();
- var e = getBrowserEvent();
-
- var mockPlugin = new goog.testing.LooseMock(plugin);
- mockPlugin.getTrogClassId().$returns('mockPlugin');
- mockPlugin.registerFieldObject(editableField);
- mockPlugin.isEnabled(editableField).$anyTimes().$returns(true);
- mockPlugin.handleKeyDown(e).$returns(true);
- mockPlugin.$replay();
-
- editableField.registerPlugin(mockPlugin);
-
- editableField.handleKeyDown_(e);
-
- mockPlugin.$verify();
-}
-
-
-/**
- * Test that if a plugin registers keypress, it gets called.
- */
-function testPluginKeyPress() {
- var editableField = new FieldConstructor('testField');
- var plugin = new TestPlugin();
- var e = getBrowserEvent();
-
- var mockPlugin = new goog.testing.LooseMock(plugin);
- mockPlugin.getTrogClassId().$returns('mockPlugin');
- mockPlugin.registerFieldObject(editableField);
- mockPlugin.isEnabled(editableField).$anyTimes().$returns(true);
- mockPlugin.handleKeyPress(e).$returns(true);
- mockPlugin.$replay();
-
- editableField.registerPlugin(mockPlugin);
-
- editableField.handleKeyPress_(e);
-
- mockPlugin.$verify();
-}
-
-
-/**
- * If one plugin handles a key event, the rest of the plugins do not get their
- * key handlers invoked.
- */
-function testHandledKeyEvent() {
- var editableField = new FieldConstructor('testField');
- var plugin = new TestPlugin();
- var e = getBrowserEvent();
-
- var mockPlugin1 = new goog.testing.LooseMock(plugin);
- mockPlugin1.getTrogClassId().$returns('mockPlugin1');
- mockPlugin1.registerFieldObject(editableField);
- mockPlugin1.isEnabled(editableField).$anyTimes().$returns(true);
- if (goog.editor.BrowserFeature.USES_KEYDOWN) {
- mockPlugin1.handleKeyDown(e).$returns(true);
- } else {
- mockPlugin1.handleKeyPress(e).$returns(true);
- }
- mockPlugin1.handleKeyUp(e).$returns(true);
- mockPlugin1.$replay();
-
- var mockPlugin2 = new goog.testing.LooseMock(plugin);
- mockPlugin2.getTrogClassId().$returns('mockPlugin2');
- mockPlugin2.registerFieldObject(editableField);
- mockPlugin2.isEnabled(editableField).$anyTimes().$returns(true);
- mockPlugin2.$replay();
-
- editableField.registerPlugin(mockPlugin1);
- editableField.registerPlugin(mockPlugin2);
-
- editableField.handleKeyUp_(e);
- if (goog.editor.BrowserFeature.USES_KEYDOWN) {
- editableField.handleKeyDown_(e);
- } else {
- editableField.handleKeyPress_(e);
- }
-
- mockPlugin1.$verify();
- mockPlugin2.$verify();
-}
-
-
-/**
- * Tests to make sure the cut and paste events are not dispatched immediately.
- */
-function testHandleCutAndPasteEvents() {
- if (goog.editor.BrowserFeature.USE_MUTATION_EVENTS) {
- // Cut and paste events do not raise events at all in Mozilla.
- return;
- }
- var editableField = new FieldConstructor('testField');
- var clock = new goog.testing.MockClock(true);
- var delayedChanges = goog.testing.recordFunction();
- goog.events.listen(editableField, goog.editor.Field.EventType.DELAYEDCHANGE,
- delayedChanges);
-
- editableField.makeEditable();
-
- goog.testing.events.fireBrowserEvent(
- new goog.testing.events.Event('cut', editableField.getElement()));
- assertEquals('Cut event should be on a timer', 0,
- delayedChanges.getCallCount());
- clock.tick(1000);
- assertEquals('delayed change event should fire within 1s after cut', 1,
- delayedChanges.getCallCount());
-
- goog.testing.events.fireBrowserEvent(
- new goog.testing.events.Event('paste', editableField.getElement()));
- assertEquals('Paste event should be on a timer', 1,
- delayedChanges.getCallCount());
- clock.tick(1000);
- assertEquals('delayed change event should fire within 1s after paste', 2,
- delayedChanges.getCallCount());
-
- clock.dispose();
- editableField.dispose();
-}
-
-
-/**
- * If the first plugin does not handle the key event, the next plugin gets
- * a chance to handle it.
- */
-function testNotHandledKeyEvent() {
- var editableField = new FieldConstructor('testField');
- var plugin = new TestPlugin();
- var e = getBrowserEvent();
-
- var mockPlugin1 = new goog.testing.LooseMock(plugin);
- mockPlugin1.getTrogClassId().$returns('mockPlugin1');
- mockPlugin1.registerFieldObject(editableField);
- mockPlugin1.isEnabled(editableField).$anyTimes().$returns(true);
- if (goog.editor.BrowserFeature.USES_KEYDOWN) {
- mockPlugin1.handleKeyDown(e).$returns(false);
- } else {
- mockPlugin1.handleKeyPress(e).$returns(false);
- }
- mockPlugin1.handleKeyUp(e).$returns(false);
- mockPlugin1.$replay();
-
- var mockPlugin2 = new goog.testing.LooseMock(plugin);
- mockPlugin2.getTrogClassId().$returns('mockPlugin2');
- mockPlugin2.registerFieldObject(editableField);
- mockPlugin2.isEnabled(editableField).$anyTimes().$returns(true);
- if (goog.editor.BrowserFeature.USES_KEYDOWN) {
- mockPlugin2.handleKeyDown(e).$returns(true);
- } else {
- mockPlugin2.handleKeyPress(e).$returns(true);
- }
- mockPlugin2.handleKeyUp(e).$returns(true);
- mockPlugin2.$replay();
-
- editableField.registerPlugin(mockPlugin1);
- editableField.registerPlugin(mockPlugin2);
-
- editableField.handleKeyUp_(e);
- if (goog.editor.BrowserFeature.USES_KEYDOWN) {
- editableField.handleKeyDown_(e);
- } else {
- editableField.handleKeyPress_(e);
- }
-
- mockPlugin1.$verify();
- mockPlugin2.$verify();
-}
-
-
-/**
- * Make sure that handleKeyboardShortcut is called if other key handlers
- * return false.
- */
-function testKeyboardShortcutCalled() {
- var editableField = new FieldConstructor('testField');
- var plugin = new TestPlugin();
- var e = getBrowserEvent();
-
- var mockPlugin = new goog.testing.LooseMock(plugin);
- mockPlugin.getTrogClassId().$returns('mockPlugin');
- mockPlugin.registerFieldObject(editableField);
- mockPlugin.isEnabled(editableField).$anyTimes().$returns(true);
- if (goog.editor.BrowserFeature.USES_KEYDOWN) {
- mockPlugin.handleKeyDown(e).$returns(false);
- } else {
- mockPlugin.handleKeyPress(e).$returns(false);
- }
- mockPlugin.handleKeyboardShortcut(e, STRING_KEY, true).$returns(false);
- mockPlugin.$replay();
-
- editableField.registerPlugin(mockPlugin);
-
- if (goog.editor.BrowserFeature.USES_KEYDOWN) {
- editableField.handleKeyDown_(e);
- } else {
- editableField.handleKeyPress_(e);
- }
-
- mockPlugin.$verify();
-}
-
-
-/**
- * Make sure that handleKeyboardShortcut is not called if other key handlers
- * return true.
- */
-function testKeyboardShortcutNotCalled() {
- var editableField = new FieldConstructor('testField');
- var plugin = new TestPlugin();
- var e = getBrowserEvent();
-
- var mockPlugin = new goog.testing.LooseMock(plugin);
- mockPlugin.getTrogClassId().$returns('mockPlugin');
- mockPlugin.registerFieldObject(editableField);
- mockPlugin.isEnabled(editableField).$anyTimes().$returns(true);
- if (goog.editor.BrowserFeature.USES_KEYDOWN) {
- mockPlugin.handleKeyDown(e).$returns(true);
- } else {
- mockPlugin.handleKeyPress(e).$returns(true);
- }
- mockPlugin.$replay();
-
- editableField.registerPlugin(mockPlugin);
-
- if (goog.editor.BrowserFeature.USES_KEYDOWN) {
- editableField.handleKeyDown_(e);
- } else {
- editableField.handleKeyPress_(e);
- }
-
- mockPlugin.$verify();
-}
-
-
-/**
- * Make sure that handleKeyboardShortcut is not called if alt is pressed.
- * @bug 1363959
- */
-function testKeyHandlingAlt() {
- var editableField = new FieldConstructor('testField');
- var plugin = new TestPlugin();
- var e = getBrowserEvent();
- e.altKey = true;
-
- var mockPlugin = new goog.testing.LooseMock(plugin);
- mockPlugin.getTrogClassId().$returns('mockPlugin');
- mockPlugin.registerFieldObject(editableField);
- mockPlugin.isEnabled(editableField).$anyTimes().$returns(true);
- if (goog.editor.BrowserFeature.USES_KEYDOWN) {
- mockPlugin.handleKeyDown(e).$returns(false);
- } else {
- mockPlugin.handleKeyPress(e).$returns(false);
- }
- mockPlugin.$replay();
-
- editableField.registerPlugin(mockPlugin);
-
- if (goog.editor.BrowserFeature.USES_KEYDOWN) {
- editableField.handleKeyDown_(e);
- } else {
- editableField.handleKeyPress_(e);
- }
-
- mockPlugin.$verify();
-}
-
-
-/**
- * Test that if a plugin has an execCommand function, it gets called
- * but only for supported commands.
- */
-function testPluginExecCommand() {
- var plugin = new TestPlugin();
- var passedCommand, passedArg;
- plugin.execCommand = function(command, arg) {
- passedCommand = command;
- passedArg = arg;
- }
-
- var editableField = new FieldConstructor('testField');
- editableField.registerPlugin(plugin);
- plugin.enable(editableField);
- plugin.isSupportedCommand = goog.functions.constant(true);
-
- editableField.execCommand('+indent', true);
- // Verify that the plugin's execCommand was called with the correct
- // args.
- assertEquals('+indent', passedCommand);
- assertTrue(passedArg);
-
- passedCommand = null;
- passedArg = null;
- plugin.isSupportedCommand = goog.functions.constant(false);
-
- editableField.execCommand('+outdent', false);
- // Verify that a plugin's execCommand is not called if it isn't a supported
- // command.
- assertNull(passedCommand);
- assertNull(passedArg);
-
- editableField.dispose();
- plugin.dispose();
-}
-
-
-/**
- * Test that if one plugin supports execCommand, no other plugins
- * get a chance to handle the execComand.
- */
-function testSupportedExecCommand() {
- var editableField = new FieldConstructor('testField');
- var plugin = new TestPlugin();
-
- var mockPlugin1 = new goog.testing.LooseMock(plugin);
- mockPlugin1.getTrogClassId().$returns('mockPlugin1');
- mockPlugin1.registerFieldObject(editableField);
- mockPlugin1.isEnabled(editableField).$anyTimes().$returns(true);
- mockPlugin1.isSupportedCommand('+indent').$returns(true);
- mockPlugin1.execCommandInternal('+indent').$returns(true);
- mockPlugin1.execCommand('+indent').$does(
- function() { mockPlugin1.execCommandInternal('+indent'); });
- mockPlugin1.$replay();
-
- var mockPlugin2 = new goog.testing.LooseMock(plugin);
- mockPlugin2.getTrogClassId().$returns('mockPlugin2');
- mockPlugin2.registerFieldObject(editableField);
- mockPlugin2.isEnabled(editableField).$anyTimes().$returns(true);
- mockPlugin2.$replay();
-
- editableField.registerPlugin(mockPlugin1);
- editableField.registerPlugin(mockPlugin2);
-
- editableField.execCommand('+indent');
-
- mockPlugin1.$verify();
- mockPlugin2.$verify();
-}
-
-
-/**
- * Test that if the first plugin does not support execCommand, the other
- * plugins get a chance to handle the execCommand.
- */
-function testNotSupportedExecCommand() {
- var editableField = new FieldConstructor('testField');
- var plugin = new TestPlugin();
-
- var mockPlugin1 = new goog.testing.LooseMock(plugin);
- mockPlugin1.getTrogClassId().$returns('mockPlugin1');
- mockPlugin1.registerFieldObject(editableField);
- mockPlugin1.isEnabled(editableField).$anyTimes().$returns(true);
- mockPlugin1.isSupportedCommand('+indent').$returns(false);
- mockPlugin1.$replay();
-
- var mockPlugin2 = new goog.testing.LooseMock(plugin);
- mockPlugin2.getTrogClassId().$returns('mockPlugin2');
- mockPlugin2.registerFieldObject(editableField);
- mockPlugin2.isEnabled(editableField).$anyTimes().$returns(true);
- mockPlugin2.isSupportedCommand('+indent').$returns(true);
- mockPlugin2.execCommandInternal('+indent').$returns(true);
- mockPlugin2.execCommand('+indent').$does(
- function() { mockPlugin2.execCommandInternal('+indent'); });
- mockPlugin2.$replay();
-
- editableField.registerPlugin(mockPlugin1);
- editableField.registerPlugin(mockPlugin2);
-
- editableField.execCommand('+indent');
-
- mockPlugin1.$verify();
- mockPlugin2.$verify();
-}
-
-
-/**
- * Tests that if a plugin supports a command that its queryCommandValue
- * gets called and no further plugins can handle the queryCommandValue.
- */
-function testSupportedQueryCommand() {
- var editableField = new FieldConstructor('testField');
- var plugin = new TestPlugin();
-
- var mockPlugin1 = new goog.testing.LooseMock(plugin);
- mockPlugin1.getTrogClassId().$returns('mockPlugin1');
- mockPlugin1.registerFieldObject(editableField);
- mockPlugin1.isEnabled(editableField).$anyTimes().$returns(true);
- mockPlugin1.isSupportedCommand('+indent').$returns(true);
- mockPlugin1.queryCommandValue('+indent').$returns(true);
- mockPlugin1.activeOnUneditableFields().$returns(true);
- mockPlugin1.$replay();
-
- var mockPlugin2 = new goog.testing.LooseMock(plugin);
- mockPlugin2.getTrogClassId().$returns('mockPlugin2');
- mockPlugin2.registerFieldObject(editableField);
- mockPlugin2.isEnabled(editableField).$anyTimes().$returns(true);
- mockPlugin2.$replay();
-
- editableField.registerPlugin(mockPlugin1);
- editableField.registerPlugin(mockPlugin2);
-
- editableField.queryCommandValue('+indent');
-
- mockPlugin1.$verify();
- mockPlugin2.$verify();
-}
-
-
-/**
- * Tests that if the first plugin does not support a command that its
- * queryCommandValue do not get called and the next plugin can handle the
- * queryCommandValue.
- */
-function testNotSupportedQueryCommand() {
- var editableField = new FieldConstructor('testField');
- var plugin = new TestPlugin();
-
- var mockPlugin1 = new goog.testing.LooseMock(plugin);
- mockPlugin1.getTrogClassId().$returns('mockPlugin1');
- mockPlugin1.registerFieldObject(editableField);
- mockPlugin1.isEnabled(editableField).$anyTimes().$returns(true);
- mockPlugin1.isSupportedCommand('+indent').$returns(false);
- mockPlugin1.$replay();
-
- var mockPlugin2 = new goog.testing.LooseMock(plugin);
- mockPlugin2.getTrogClassId().$returns('mockPlugin2');
- mockPlugin2.registerFieldObject(editableField);
- mockPlugin2.isEnabled(editableField).$anyTimes().$returns(true);
- mockPlugin2.isSupportedCommand('+indent').$returns(true);
- mockPlugin2.queryCommandValue('+indent').$returns(true);
- mockPlugin2.activeOnUneditableFields().$returns(true);
- mockPlugin2.$replay();
-
- editableField.registerPlugin(mockPlugin1);
- editableField.registerPlugin(mockPlugin2);
-
- editableField.queryCommandValue('+indent');
-
- mockPlugin1.$verify();
- mockPlugin2.$verify();
-}
-
-
-/**
- * Tests that if a plugin handles selectionChange that it gets called and
- * no further plugins can handle the selectionChange.
- */
-function testHandledSelectionChange() {
- var editableField = new FieldConstructor('testField');
- var plugin = new TestPlugin();
- var e = getBrowserEvent();
-
- var mockPlugin1 = new goog.testing.LooseMock(plugin);
- mockPlugin1.getTrogClassId().$returns('mockPlugin1');
- mockPlugin1.registerFieldObject(editableField);
- mockPlugin1.isEnabled(editableField).$anyTimes().$returns(true);
- mockPlugin1.handleSelectionChange(e, undefined).$returns(true);
- mockPlugin1.$replay();
-
- var mockPlugin2 = new goog.testing.LooseMock(plugin);
- mockPlugin2.getTrogClassId().$returns('mockPlugin2');
- mockPlugin2.registerFieldObject(editableField);
- mockPlugin2.isEnabled(editableField).$anyTimes().$returns(true);
- mockPlugin2.$replay();
-
- editableField.registerPlugin(mockPlugin1);
- editableField.registerPlugin(mockPlugin2);
-
- editableField.dispatchSelectionChangeEvent(e);
-
- mockPlugin1.$verify();
- mockPlugin2.$verify();
-}
-
-
-/**
- * Tests that if the first plugin does not handle selectionChange that
- * the next plugin gets a chance to handle it.
- */
-function testNotHandledSelectionChange() {
- var editableField = new FieldConstructor('testField');
- var plugin = new TestPlugin();
- var e = getBrowserEvent();
-
- var mockPlugin1 = new goog.testing.LooseMock(plugin);
- mockPlugin1.getTrogClassId().$returns('mockPlugin1');
- mockPlugin1.registerFieldObject(editableField);
- mockPlugin1.isEnabled(editableField).$anyTimes().$returns(true);
- mockPlugin1.handleSelectionChange(e, undefined).$returns(false);
- mockPlugin1.$replay();
-
- var mockPlugin2 = new goog.testing.LooseMock(plugin);
- mockPlugin2.getTrogClassId().$returns('mockPlugin2');
- mockPlugin2.registerFieldObject(editableField);
- mockPlugin2.isEnabled(editableField).$anyTimes().$returns(true);
- mockPlugin2.handleSelectionChange(e, undefined).$returns(true);
- mockPlugin2.$replay();
-
- editableField.registerPlugin(mockPlugin1);
- editableField.registerPlugin(mockPlugin2);
-
- editableField.dispatchSelectionChangeEvent(e);
-
- mockPlugin1.$verify();
- mockPlugin2.$verify();
-}
-
-
-// Tests for goog.editor.Field internals.
-
-function testSelectionChange() {
- var editableField = new FieldConstructor('testField', document);
- var clock = new goog.testing.MockClock(true);
- var selectionChanges = goog.testing.recordFunction();
- goog.events.listen(editableField, goog.editor.Field.EventType.SELECTIONCHANGE,
- selectionChanges);
-
- editableField.makeEditable();
-
- // Emulate pressing left arrow key, this should result in SELECTIONCHANGE
- // event after a short timeout.
- editableField.handleKeyUp_({keyCode: goog.events.KeyCodes.LEFT});
- assertEquals('Selection change should be on a timer', 0,
- selectionChanges.getCallCount());
- clock.tick(1000);
- assertEquals('Selection change should fire within 1s', 1,
- selectionChanges.getCallCount());
-
- // Programically place cursor at start. SELECTIONCHANGE event should be fired.
- editableField.placeCursorAtStart();
- assertEquals('Selection change should fire', 2,
- selectionChanges.getCallCount());
-
- clock.dispose();
- editableField.dispose();
-}
-
-
-function testSelectionChangeOnMouseUp() {
- var fakeEvent =
- new goog.events.BrowserEvent({type: 'mouseup', target: 'fakeTarget'});
- var editableField = new FieldConstructor('testField', document);
- var clock = new goog.testing.MockClock(true);
- var selectionChanges = goog.testing.recordFunction();
- goog.events.listen(editableField, goog.editor.Field.EventType.SELECTIONCHANGE,
- selectionChanges);
-
- var plugin = new TestPlugin();
- plugin.handleSelectionChange = goog.testing.recordFunction();
- editableField.registerPlugin(plugin);
-
- editableField.makeEditable();
-
- // Emulate a mouseup event, this should result in an immediate
- // SELECTIONCHANGE, plus a second one in IE after a short timeout.
- editableField.handleMouseUp_(fakeEvent);
- assertEquals('Selection change should fire immediately', 1,
- selectionChanges.getCallCount());
- assertEquals('Plugin should have handled selection change immediately', 1,
- plugin.handleSelectionChange.getCallCount());
- assertEquals('Plugin should have received original browser event to handle',
- fakeEvent, plugin.handleSelectionChange.getLastCall().getArguments()[0]);
-
- // Pretend another plugin fired a SELECTIONCHANGE in the meantime.
- editableField.dispatchSelectionChangeEvent();
- assertEquals('Second selection change should fire immediately', 2,
- selectionChanges.getCallCount());
- assertEquals('Plugin should have handled second selection change immediately',
- 2, plugin.handleSelectionChange.getCallCount());
- var args = plugin.handleSelectionChange.getLastCall().getArguments();
- assertTrue('Plugin should not have received data from extra firing',
- args.length == 0 ||
- !args[0] && (args.length == 1 || !args[1]));
-
- // Now check for the extra call in IE.
- clock.tick(1000);
- if (goog.userAgent.IE) {
- assertEquals('Additional selection change should fire within 1s', 3,
- selectionChanges.getCallCount());
- assertEquals('Plugin should have handled selection change within 1s', 3,
- plugin.handleSelectionChange.getCallCount());
- assertEquals('Plugin should have received target of original browser event',
- fakeEvent.target,
- plugin.handleSelectionChange.getLastCall().getArguments().pop());
- } else {
- assertEquals('No additional selection change should fire', 2,
- selectionChanges.getCallCount());
- assertEquals('Plugin should not have handled selection change again', 2,
- plugin.handleSelectionChange.getCallCount());
- }
-
- clock.dispose();
- editableField.dispose();
-}
-
-
-function testSelectionChangeBeforeUneditable() {
- var editableField = new FieldConstructor('testField', document);
- var clock = new goog.testing.MockClock(true);
- var selectionChanges = goog.testing.recordFunction();
- goog.events.listen(editableField, goog.editor.Field.EventType.SELECTIONCHANGE,
- selectionChanges);
-
- editableField.makeEditable();
- editableField.handleKeyUp_({keyCode: goog.events.KeyCodes.LEFT});
- assertEquals('Selection change should be on a timer', 0,
- selectionChanges.getCallCount());
- editableField.makeUneditable();
- assertEquals('Selection change should fire during make uneditable', 1,
- selectionChanges.getCallCount());
- clock.tick(1000);
- assertEquals('No additional selection change should fire', 1,
- selectionChanges.getCallCount());
-
- clock.dispose();
- editableField.dispose();
-}
-
-
-function testGetEditableDomHelper() {
- var editableField = new FieldConstructor('testField', document);
- assertNull('Before being made editable, we do not know the dom helper',
- editableField.getEditableDomHelper());
- editableField.makeEditable();
- assertNotNull('After being made editable, we know the dom helper',
- editableField.getEditableDomHelper());
- assertEquals('Document from domHelper should be the editable elements doc',
- goog.dom.getOwnerDocument(editableField.getElement()),
- editableField.getEditableDomHelper().getDocument());
- editableField.dispose();
-}
-
-
-function testQueryCommandValue() {
- var editableField = new FieldConstructor('testField', document);
- assertFalse(editableField.queryCommandValue('boo'));
- assertObjectEquals({'boo': false, 'aieee': false},
- editableField.queryCommandValue(['boo', 'aieee']));
-
- editableField.makeEditable();
- assertFalse(editableField.queryCommandValue('boo'));
-
- editableField.getElement().focus();
- editableField.dispatchSelectionChangeEvent();
- assertNull(editableField.queryCommandValue('boo'));
- assertObjectEquals({'boo': null, 'aieee': null},
- editableField.queryCommandValue(['boo', 'aieee']));
- editableField.dispose();
-}
-
-
-function testSetHtml() {
- var editableField = new FieldConstructor('testField', document);
- var clock = new goog.testing.MockClock(true);
-
- try {
- var delayedChangeCalled = false;
- goog.events.listen(editableField, goog.editor.Field.EventType.DELAYEDCHANGE,
- function() {
- delayedChangeCalled = true;
- });
-
- editableField.makeEditable();
- clock.tick(1000);
- assertFalse('Make editable must not fire delayed change.',
- delayedChangeCalled);
-
- editableField.setHtml(false, 'bar', true /* Don't fire delayed change */);
- goog.testing.dom.assertHtmlContentsMatch('bar', editableField.getElement());
- clock.tick(1000);
- assertFalse('setHtml must not fire delayed change if so configured.',
- delayedChangeCalled);
-
- editableField.setHtml(false, 'foo', false /* Fire delayed change */);
- goog.testing.dom.assertHtmlContentsMatch('foo', editableField.getElement());
- clock.tick(1000);
- assertTrue('setHtml must fire delayed change by default',
- delayedChangeCalled);
- } finally {
- clock.dispose();
- editableField.dispose();
- }
-}
-
-
-/**
- * Helper to test that the cursor is placed at the beginning of the editable
- * field's contents.
- * @param {string=} opt_html Html to replace the test file default field
- * contents with.
- * @param {string=} opt_parentId Id of the parent of the node where the cursor
- * is expected to be placed. If omitted, will expect cursor to be placed in
- * the first child of the field element (or, if the field has no content, in
- * the field element itself).
- */
-function doTestPlaceCursorAtStart(opt_html, opt_parentId) {
- var editableField = new FieldConstructor('testField', document);
- editableField.makeEditable();
- // Initially place selection not at the start of the editable field.
- var textNode = editableField.getElement().firstChild;
- goog.dom.Range.createFromNodes(textNode, 1, textNode, 2).select();
- if (opt_html != null) {
- editableField.getElement().innerHTML = opt_html;
- }
-
- editableField.placeCursorAtStart();
- var range = editableField.getRange();
- assertNotNull(
- 'Placing the cursor should result in a range object being available',
- range);
- assertTrue('The range should be collapsed', range.isCollapsed());
- textNode = editableField.getElement().firstChild;
-
- // We check whether getAttribute exist because textNode may be an actual
- // TextNode, which does not have getAttribute.
- if (textNode && textNode.getAttribute &&
- textNode.getAttribute('_moz_editor_bogus_node')) {
- // At least in FF >= 6, assigning '' to innerHTML of a contentEditable
- // element will results in textNode being modified into:
- // <br _moz_editor_bogus_node="TRUE" _moz_dirty=""> instead of nulling
- // it. So we should null it ourself.
- textNode = null;
- }
-
- var startNode = opt_parentId ?
- editableField.getEditableDomHelper().getElement(opt_parentId).firstChild :
- textNode ? textNode : editableField.getElement();
- if (goog.userAgent.WEBKIT && !goog.userAgent.isVersion('528')) {
- // Safari 3 seems to normalize the selection to the shallowest endpoint (in
- // this case the editable element) in all cases tested below. This is OK
- // because when you start typing it magically inserts the text at the
- // deepest endpoint, and even behaves as desired in the case tested by
- // testPlaceCursorAtStartNonImportantTextNode.
- startNode = editableField.getElement();
- }
- assertEquals('The range should start at the specified expected node',
- startNode, range.getStartNode());
- assertEquals('The range should start at the beginning of the node',
- 0, range.getStartOffset());
-}
-
-
-function testPlaceCursorAtStart() {
- doTestPlaceCursorAtStart();
-}
-
-
-function testPlaceCursorAtStartEmptyField() {
- doTestPlaceCursorAtStart('');
-}
-
-
-function testPlaceCursorAtStartNonImportantTextNode() {
- doTestPlaceCursorAtStart(
- '\n<span id="important">important text</span>', 'important');
-}
-
-
-/**
- * Helper to test that the cursor is placed at the beginning of the editable
- * field's contents.
- * @param {string=} opt_html Html to replace the test file default field
- * contents with.
- * @param {string=} opt_parentId Id of the parent of the node where the cursor
- * is expected to be placed. If omitted, will expect cursor to be placed in
- * the first child of the field element (or, if the field has no content, in
- * the field element itself).
- * @param {number=} The offset to expect for the end position.
- */
-function doTestPlaceCursorAtEnd(opt_html, opt_parentId, opt_offset) {
- var editableField = new FieldConstructor('testField', document);
- editableField.makeEditable();
-
- // Initially place selection not at the end of the editable field.
- var textNode = editableField.getElement().firstChild;
- goog.dom.Range.createFromNodes(textNode, 0, textNode, 1).select();
- if (opt_html != null) {
- editableField.getElement().innerHTML = opt_html;
- }
-
- editableField.placeCursorAtEnd();
- var range = editableField.getRange();
- assertNotNull(
- 'Placing the cursor should result in a range object being available',
- range);
- assertTrue('The range should be collapsed', range.isCollapsed());
- textNode = editableField.getElement().firstChild;
-
- // We check whether getAttribute exist because textNode may be an actual
- // TextNode, which does not have getAttribute.
- if (textNode && textNode.getAttribute &&
- textNode.getAttribute('_moz_editor_bogus_node')) {
- // At least in FF >= 6, assigning '' to innerHTML of a contentEditable
- // element will results in textNode being modified into:
- // <br _moz_editor_bogus_node="TRUE" _moz_dirty=""> instead of nulling
- // it. So we should null it ourself.
- textNode = null;
- }
-
- var endNode = opt_parentId ?
- editableField.getEditableDomHelper().getElement(opt_parentId).lastChild :
- textNode ? textNode : editableField.getElement();
- assertEquals('The range should end at the specified expected node',
- endNode, range.getEndNode());
- var offset = goog.isDefAndNotNull(opt_offset) ?
- opt_offset :
- textNode ? endNode.nodeValue.length : endNode.childNodes.length - 1;
- assertEquals('The range should end at the ending of the node',
- offset, range.getEndOffset());
-}
-
-
-function testPlaceCursorAtEnd() {
- doTestPlaceCursorAtEnd();
-}
-
-
-function testPlaceCursorAtEndEmptyField() {
- doTestPlaceCursorAtEnd('', null, 0);
-}
-
-
-function testPlaceCursorAtEndNonImportantTextNode() {
- doTestPlaceCursorAtStart(
- '\n<span id="important">important text</span>', 'important');
-}
-
-
-// Tests related to change/delayed change events.
-
-
-function testClearDelayedChange() {
- var clock = new goog.testing.MockClock(true);
- var editableField = new FieldConstructor('testField', document);
- editableField.makeEditable();
-
- var delayedChangeCalled = false;
- goog.events.listen(editableField, goog.editor.Field.EventType.DELAYEDCHANGE,
- function() {
- delayedChangeCalled = true;
- });
-
- // Clears delayed change timer.
- editableField.delayedChangeTimer_.start();
- editableField.clearDelayedChange();
- assertTrue(delayedChangeCalled);
- if (editableField.changeTimerGecko_) {
- assertFalse(editableField.changeTimerGecko_.isActive());
- }
- assertFalse(editableField.delayedChangeTimer_.isActive());
-
- // Clears delayed changes caused by changeTimerGecko_
- if (editableField.changeTimerGecko_) {
- delayedChangeCalled = false;
- editableField.changeTimerGecko_.start();
- editableField.clearDelayedChange();
- assertTrue(delayedChangeCalled);
- if (editableField.changeTimerGecko_) {
- assertFalse(editableField.changeTimerGecko_.isActive());
- }
- assertFalse(editableField.delayedChangeTimer_.isActive());
- }
- clock.dispose();
-}
-
-
-function testHandleChange() {
- if (goog.editor.BrowserFeature.USE_MUTATION_EVENTS) {
- var editableField = new FieldConstructor('testField', document);
- editableField.makeEditable();
-
- editableField.changeTimerGecko_.start();
- editableField.handleChange();
- assertFalse(editableField.changeTimerGecko_.isActive());
- }
-}
-
-
-function testDispatchDelayedChange() {
- var editableField = new FieldConstructor('testField', document);
- editableField.makeEditable();
-
- editableField.delayedChangeTimer_.start();
- editableField.dispatchDelayedChange_();
- assertFalse(editableField.delayedChangeTimer_.isActive());
-}