aboutsummaryrefslogtreecommitdiff
path: root/contexts/data/lib/closure-library/closure/goog/editor/plugins/undoredo_test.html
diff options
context:
space:
mode:
Diffstat (limited to 'contexts/data/lib/closure-library/closure/goog/editor/plugins/undoredo_test.html')
-rw-r--r--contexts/data/lib/closure-library/closure/goog/editor/plugins/undoredo_test.html525
1 files changed, 0 insertions, 525 deletions
diff --git a/contexts/data/lib/closure-library/closure/goog/editor/plugins/undoredo_test.html b/contexts/data/lib/closure-library/closure/goog/editor/plugins/undoredo_test.html
deleted file mode 100644
index 8afea69..0000000
--- a/contexts/data/lib/closure-library/closure/goog/editor/plugins/undoredo_test.html
+++ /dev/null
@@ -1,525 +0,0 @@
-goog.editor.plugins<!DOCTYPE html>
-<!--
- All Rights Reserved.
-
- @author ajp@google.com (Andy Perelson)
--->
-<html>
-<!--
-Copyright 2008 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<head>
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
-<title>Trogedit Unit Tests - goog.editor.plugins.UndoRedo</title>
-<script src="../../base.js"></script>
-<script>
- goog.require('goog.array');
- goog.require('goog.dom');
- goog.require('goog.editor.Field');
- goog.require('goog.editor.Field.EventType');
- goog.require('goog.events');
- goog.require('goog.events.BrowserEvent');
- goog.require('goog.testing.MockClock');
- goog.require('goog.testing.PropertyReplacer');
- goog.require('goog.testing.StrictMock');
- goog.require('goog.testing.jsunit');
- goog.require('goog.editor.plugins.LoremIpsum');
- goog.require('goog.editor.plugins.UndoRedo');
-
-</script>
-</head>
-<body>
-
-<div id="testField"></div>
-
-<script>
-
-var mockEditableField;
-var editableField;
-var fieldHashCode;
-var undoPlugin;
-var state
-var mockState;
-var commands;
-var clock;
-var stubs = new goog.testing.PropertyReplacer();
-
-
-function setUp() {
- mockEditableField = new goog.testing.StrictMock(goog.editor.Field);
-
- // Update the arg list verifier for dispatchCommandValueChange to
- // correctly compare arguments that are arrays (or other complex objects).
- mockEditableField.$registerArgumentListVerifier('dispatchEvent',
- function(expected, args) {
- return goog.array.equals(expected, args,
- function(a, b) { assertObjectEquals(a, b); return true; });
- });
- mockEditableField.getHashCode = function() {
- return 'fieldId';
- }
-
- undoPlugin = new goog.editor.plugins.UndoRedo();
- undoPlugin.registerFieldObject(mockEditableField);
- mockState = new goog.testing.StrictMock(
- goog.editor.plugins.UndoRedo.UndoState_);
- mockState.fieldHashCode = 'fieldId';
- mockState.isAsynchronous = function() {
- return false;
- };
- // Don't bother mocking the inherited event target pieces of the state.
- // If we don't do this, then mocked asynchronous undos are a lot harder and
- // that behavior is tested as part of the UndoRedoManager tests.
- mockState.addEventListener = goog.nullFunction;
-
- commands = [
- goog.editor.plugins.UndoRedo.COMMAND.REDO,
- goog.editor.plugins.UndoRedo.COMMAND.UNDO
- ];
- state = new goog.editor.plugins.UndoRedo.UndoState_('1', '', null,
- goog.nullFunction);
-
- clock = new goog.testing.MockClock(true);
-
- editableField = new goog.editor.Field('testField');
- fieldHashCode = editableField.getHashCode();
-}
-
-
-function tearDown() {
- // Reset field so any attempted access during disposes don't cause errors.
- mockEditableField.$reset();
- clock.dispose();
- undoPlugin.dispose();
-
- // 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) {}
-
- if (!editableField.isUneditable()) {
- editableField.makeUneditable();
- }
- editableField.dispose();
- goog.dom.getElement('testField').innerHTML = '';
- stubs.reset();
-}
-
-
-// undo-redo plugin tests
-
-
-function testQueryCommandValue() {
- assertFalse('Must return false for empty undo stack.',
- undoPlugin.queryCommandValue(goog.editor.plugins.UndoRedo.COMMAND.UNDO));
-
- assertFalse('Must return false for empty redo stack.',
- undoPlugin.queryCommandValue(goog.editor.plugins.UndoRedo.COMMAND.REDO));
-
- undoPlugin.undoManager_.addState(mockState);
-
- assertTrue('Must return true for a non-empty undo stack.',
- undoPlugin.queryCommandValue(goog.editor.plugins.UndoRedo.COMMAND.UNDO));
-}
-
-
-function testExecCommand() {
- undoPlugin.undoManager_.addState(mockState);
-
- mockState.undo();
- mockState.$replay();
-
- undoPlugin.execCommand(goog.editor.plugins.UndoRedo.COMMAND.UNDO);
- // Second undo should do nothing since only one item on stack.
- undoPlugin.execCommand(goog.editor.plugins.UndoRedo.COMMAND.UNDO);
- mockState.$verify();
-
- mockState.$reset();
- mockState.redo();
- mockState.$replay();
- undoPlugin.execCommand(goog.editor.plugins.UndoRedo.COMMAND.REDO);
- // Second redo should do nothing since only one item on stack.
- undoPlugin.execCommand(goog.editor.plugins.UndoRedo.COMMAND.REDO);
- mockState.$verify();
-}
-
-function testHandleKeyboardShortcut_TrogStates() {
- undoPlugin.undoManager_.addState(mockState);
- undoPlugin.undoManager_.addState(state);
- undoPlugin.undoManager_.undo();
- mockEditableField.$reset();
-
- var stubUndoEvent = {ctrlKey: true, altKey: false, shiftKey: false};
- var stubRedoEvent = {ctrlKey: true, altKey: false, shiftKey: true};
- var stubRedoEvent2 = {ctrlKey: true, altKey: false, shiftKey: false};
- var result;
-
- // Test handling Trogedit undos. Should always call EditableField's
- // execCommand. Since EditableField is mocked, this will not result in a call
- // to the mockState's undo and redo methods.
- mockEditableField.execCommand(goog.editor.plugins.UndoRedo.COMMAND.UNDO);
- mockEditableField.$replay();
- result = undoPlugin.handleKeyboardShortcut(stubUndoEvent, 'z', true);
- assertTrue('Plugin must return true when it handles shortcut.', result);
- mockEditableField.$verify();
- mockEditableField.$reset();
-
- mockEditableField.execCommand(goog.editor.plugins.UndoRedo.COMMAND.REDO);
- mockEditableField.$replay();
- result = undoPlugin.handleKeyboardShortcut(stubRedoEvent, 'z', true);
- assertTrue('Plugin must return true when it handles shortcut.', result);
- mockEditableField.$verify();
- mockEditableField.$reset();
-
- mockEditableField.execCommand(goog.editor.plugins.UndoRedo.COMMAND.REDO);
- mockEditableField.$replay();
- result = undoPlugin.handleKeyboardShortcut(stubRedoEvent2, 'y', true);
- assertTrue('Plugin must return true when it handles shortcut.', result);
- mockEditableField.$verify();
- mockEditableField.$reset();
-
- mockEditableField.$replay();
- result = undoPlugin.handleKeyboardShortcut(stubRedoEvent2, 'y', false);
- assertFalse('Plugin must return false when modifier is not pressed.', result);
- mockEditableField.$verify();
- mockEditableField.$reset();
-
- mockEditableField.$replay();
- result = undoPlugin.handleKeyboardShortcut(stubUndoEvent, 'f', true);
- assertFalse('Plugin must return false when it doesn\'t handle shortcut.',
- result);
- mockEditableField.$verify();
-}
-
-function testHandleKeyboardShortcut_NotTrogStates() {
- var stubUndoEvent = {ctrlKey: true, altKey: false, shiftKey: false};
-
- // Trogedit undo states all have a fieldHashCode, nulling that out makes this
- // state be treated as a non-Trogedit undo-redo state.
- state.fieldHashCode = null;
- undoPlugin.undoManager_.addState(state);
- mockEditableField.$reset();
-
- // Non-trog state shouldn't go through EditableField.execCommand, however,
- // we still exect command value change dispatch since undo-redo plugin
- // redispatches those anytime manager's state changes.
- mockEditableField.dispatchEvent({
- type: goog.editor.Field.EventType.COMMAND_VALUE_CHANGE,
- commands: commands});
- mockEditableField.$replay();
- var result = undoPlugin.handleKeyboardShortcut(stubUndoEvent, 'z', true);
- assertTrue('Plugin must return true when it handles shortcut.' , result);
- mockEditableField.$verify();
-}
-
-function testEnable() {
- assertFalse('Plugin must start disabled.',
- undoPlugin.isEnabled(editableField));
-
- editableField.makeEditable(editableField);
- editableField.setHtml(false, '<div>a</div>');
- undoPlugin.enable(editableField);
-
- assertTrue(undoPlugin.isEnabled(editableField));
- assertNotNull('Must have an event handler for enabled field.',
- undoPlugin.eventHandlers_[fieldHashCode]);
-
- var currentState = undoPlugin.currentStates_[fieldHashCode];
- assertNotNull('Enabled plugin must have a current state.', currentState);
- assertEquals('After enable, undo content must match the field content.',
- editableField.getElement().innerHTML, currentState.undoContent_);
-
- assertTrue('After enable, undo cursorPosition must match the field cursor' +
- 'position.', cursorPositionsEqual(getCurrentCursorPosition(),
- currentState.undoCursorPosition_));
-
- assertUndefined('Current state must never have redo content.',
- currentState.redoContent_);
- assertUndefined('Current state must never have redo cursor position.',
- currentState.redoCursorPosition_);
-};
-
-function testDisable() {
- editableField.makeEditable(editableField);
- undoPlugin.enable(editableField);
- assertTrue('Plugin must be enabled so we can test disabling.',
- undoPlugin.isEnabled(editableField));
-
- var delayedChangeFired = false;
- goog.events.listenOnce(editableField,
- goog.editor.Field.EventType.DELAYEDCHANGE,
- function(e) {
- delayedChangeFired = true;
- })
- editableField.setHtml(false, 'foo');
-
- undoPlugin.disable(editableField);
- assertTrue('disable must fire pending delayed changes.', delayedChangeFired);
- assertEquals('disable must add undo state from pending change.',
- 1, undoPlugin.undoManager_.undoStack_.length);
-
- assertFalse(undoPlugin.isEnabled(editableField));
- assertUndefined('Disabled plugin must not have current state.',
- undoPlugin.eventHandlers_[fieldHashCode]);
- assertUndefined('Disabled plugin must not have event handlers.',
- undoPlugin.eventHandlers_[fieldHashCode]);
-}
-
-function testUpdateCurrentState_() {
- editableField.registerPlugin(new goog.editor.plugins.LoremIpsum('LOREM'));
- editableField.makeEditable(editableField);
- editableField.getPluginByClassId('LoremIpsum').usingLorem_ = true;
- undoPlugin.updateCurrentState_(editableField);
- var currentState = undoPlugin.currentStates_[fieldHashCode];
- assertNotUndefined('Must create empty states for field using lorem ipsum.',
- undoPlugin.currentStates_[fieldHashCode]);
- assertEquals('', currentState.undoContent_);
- assertNull(currentState.undoCursorPosition_);
-
- editableField.getPluginByClassId('LoremIpsum').usingLorem_ = false;
-
- // Pretend foo is the default contents to test '' == default contents
- // behavior.
- editableField.getInjectableContents = function(contents, styles) {
- return contents == '' ? 'foo' : contents;
- }
- editableField.setHtml(false, 'foo');
- undoPlugin.updateCurrentState_(editableField);
- assertEquals(currentState, undoPlugin.currentStates_[fieldHashCode]);
-
- // NOTE(user): Because there is already a current state, this setHtml will add
- // a state to the undo stack.
- editableField.setHtml(false, '<div>a</div>');
- // Select some text so we have a valid selection that gets saved in the
- // UndoState.
- goog.dom.browserrange.createRangeFromNodeContents(
- editableField.getElement()).select();
-
- undoPlugin.updateCurrentState_(editableField);
- currentState = undoPlugin.currentStates_[fieldHashCode];
- assertNotNull('Must create state for field not using lorem ipsum',
- currentState);
- assertEquals(fieldHashCode, currentState.fieldHashCode);
- var content = editableField.getElement().innerHTML;
- var cursorPosition = getCurrentCursorPosition();
- assertEquals(content, currentState.undoContent_);
- assertTrue(cursorPositionsEqual(
- cursorPosition, currentState.undoCursorPosition_));
- assertUndefined(currentState.redoContent_);
- assertUndefined(currentState.redoCursorPosition_);
-
- undoPlugin.updateCurrentState_(editableField);
- assertEquals('Updating state when state has not changed must not add undo ' +
- 'state to stack.', 1, undoPlugin.undoManager_.undoStack_.length);
- assertEquals('Updating state when state has not changed must not create ' +
- 'a new state.', currentState, undoPlugin.currentStates_[fieldHashCode])
- assertUndefined('Updating state when state has not changed must not add ' +
- 'redo content.', currentState.redoContent_);
- assertUndefined('Updating state when state has not changed must not add ' +
- 'redo cursor position.', currentState.redoCursorPosition_);
-
- editableField.setHtml(false, '<div>b</div>');
- undoPlugin.updateCurrentState_(editableField);
- currentState = undoPlugin.currentStates_[fieldHashCode];
- assertNotNull('Must create state for field not using lorem ipsum',
- currentState);
- assertEquals(fieldHashCode, currentState.fieldHashCode);
- var newContent = editableField.getElement().innerHTML;
- var newCursorPosition = getCurrentCursorPosition();
- assertEquals(newContent, currentState.undoContent_);
- assertTrue(cursorPositionsEqual(
- newCursorPosition, currentState.undoCursorPosition_));
- assertUndefined(currentState.redoContent_);
- assertUndefined(currentState.redoCursorPosition_);
-
- var undoState = goog.array.peek(undoPlugin.undoManager_.undoStack_);
- assertNotNull('Must create state for field not using lorem ipsum',
- currentState);
- assertEquals(fieldHashCode, currentState.fieldHashCode);
- assertEquals(content, undoState.undoContent_);
- assertTrue(cursorPositionsEqual(
- cursorPosition, undoState.undoCursorPosition_));
- assertEquals(newContent, undoState.redoContent_);
- assertTrue(cursorPositionsEqual(
- newCursorPosition, undoState.redoCursorPosition_));
-}
-
-/**
- * Tests that change events get restarted properly after an undo call despite
- * an exception being thrown in the process (see bug/1991234).
- */
-function testUndoRestartsChangeEvents() {
- undoPlugin.registerFieldObject(editableField);
- editableField.makeEditable(editableField);
- editableField.setHtml(false, '<div>a</div>');
- clock.tick(1000);
- undoPlugin.enable(editableField);
-
- // Change content so we can undo it.
- editableField.setHtml(false, '<div>b</div>');
- clock.tick(1000);
-
- var currentState = undoPlugin.currentStates_[fieldHashCode];
- stubs.set(editableField, 'setCursorPosition',
- goog.functions.error('Faking exception during setCursorPosition()'));
- try {
- currentState.undo();
- } catch (e) {
- fail('Exception should not have been thrown during undo()');
- }
- assertEquals('Change events should be on', 0,
- editableField.stoppedEvents_[goog.editor.Field.EventType.CHANGE]);
- assertEquals('Delayed change events should be on', 0,
- editableField.stoppedEvents_[goog.editor.Field.EventType.DELAYEDCHANGE]);
-}
-
-function testRefreshCurrentState() {
- editableField.makeEditable(editableField);
- editableField.setHtml(false, '<div>a</div>');
- clock.tick(1000);
- undoPlugin.enable(editableField);
-
- // Create current state and verify it.
- var currentState = undoPlugin.currentStates_[fieldHashCode];
- assertEquals(fieldHashCode, currentState.fieldHashCode);
- var content = editableField.getElement().innerHTML;
- var cursorPosition = getCurrentCursorPosition();
- assertEquals(content, currentState.undoContent_);
- assertTrue(cursorPositionsEqual(
- cursorPosition, currentState.undoCursorPosition_));
-
- // Update the field w/o dispatching delayed change, and verify that the
- // current state hasn't changed to reflect new values.
- editableField.setHtml(false, '<div>b</div>', true);
- clock.tick(1000);
- currentState = undoPlugin.currentStates_[fieldHashCode];
- assertEquals('Content must match old state.',
- content, currentState.undoContent_);
- assertTrue('Cursor position must match old state.',
- cursorPositionsEqual(
- cursorPosition, currentState.undoCursorPosition_));
-
- undoPlugin.refreshCurrentState(editableField);
- assertFalse('Refresh must not cause states to go on the undo-redo stack.',
- undoPlugin.undoManager_.hasUndoState());
- currentState = undoPlugin.currentStates_[fieldHashCode];
- content = editableField.getElement().innerHTML;
- cursorPosition = getCurrentCursorPosition();
- assertEquals('Content must match current field state.',
- content, currentState.undoContent_);
- assertTrue('Cursor position must match current field state.',
- cursorPositionsEqual(cursorPosition, currentState.undoCursorPosition_));
-
- undoPlugin.disable(editableField);
- assertUndefined(undoPlugin.currentStates_[fieldHashCode]);
- undoPlugin.refreshCurrentState(editableField);
- assertUndefined('Must not refresh current state of fields that do not have ' +
- 'undo-redo enabled.', undoPlugin.currentStates_[fieldHashCode]);
-};
-
-/**
- * Returns the CursorPosition for the selection currently in the Field.
- * @return {goog.editor.plugins.UndoRedo.CursorPosition_}
- */
-function getCurrentCursorPosition() {
- return undoPlugin.getCursorPosition_(editableField);
-}
-
-/**
- * Compares two cursor positions and returns whether they are equal.
- * @param {goog.editor.plugins.UndoRedo.CursorPosition_} a
- * A cursor position.
- * @param {goog.editor.plugins.UndoRedo.CursorPosition_} b
- * A cursor position.
- * @return {boolean} Whether the positions are equal.
- */
-function cursorPositionsEqual(a, b) {
- if (!a && !b) {
- return true;
- } else if (a && b){
- return a.toString() == b.toString();
- }
- // Only one cursor position is an object, can't be equal.
- return false;
-}
-// Undo state tests
-
-
-function testSetUndoState() {
- state.setUndoState('content', 'position');
- assertEquals('Undo content incorrectly set', 'content', state.undoContent_);
- assertEquals('Undo cursor position incorrectly set', 'position',
- state.undoCursorPosition_);
-}
-
-function testSetRedoState() {
- state.setRedoState('content', 'position');
- assertEquals('Redo content incorrectly set', 'content', state.redoContent_);
- assertEquals('Redo cursor position incorrectly set', 'position',
- state.redoCursorPosition_);
-}
-
-function testEquals() {
- assertTrue('A state must equal itself', state.equals(state));
-
- var state2 = new goog.editor.plugins.UndoRedo.UndoState_('1', '', null);
- assertTrue('A state must equal a state with the same hash code and content.',
- state.equals(state2));
-
- state2 = new goog.editor.plugins.UndoRedo.UndoState_('1', '', 'foo');
- assertTrue('States with different cursor positions must be equal',
- state.equals(state2));
-
- state2.setRedoState('bar', null);
- assertFalse('States with different redo content must not be equal',
- state.equals(state2));
-
- state2 = new goog.editor.plugins.UndoRedo.UndoState_('3', '', null);
- assertFalse('States with different field hash codes must not be equal',
- state.equals(state2));
-
- state2 = new goog.editor.plugins.UndoRedo.UndoState_('1', 'baz', null);
- assertFalse('States with different undoContent must not be equal',
- state.equals(state2));
-}
-
-/** @bug 1359214 */
-function testClearUndoHistory() {
- var undoRedoPlugin = new goog.editor.plugins.UndoRedo();
- editableField.registerPlugin(undoRedoPlugin);
- editableField.makeEditable(editableField);
-
- editableField.dispatchChange();
- clock.tick(10000);
-
- editableField.getElement().innerHTML = 'y';
- editableField.dispatchChange();
- assertFalse(undoRedoPlugin.undoManager_.hasUndoState());
-
- clock.tick(10000);
- assertTrue(undoRedoPlugin.undoManager_.hasUndoState());
-
- editableField.getElement().innerHTML = 'z';
- editableField.dispatchChange();
-
- var numCalls = 0;
- goog.events.listen(editableField, goog.editor.Field.EventType.DELAYEDCHANGE,
- function() {
- numCalls++;
- });
- undoRedoPlugin.clearHistory();
- // 1 call from stopChangeEvents(). 0 calls from startChangeEvents().
- assertEquals('clearHistory must not cause delayed change when none pending',
- 1, numCalls);
-
- clock.tick(10000);
- assertFalse(undoRedoPlugin.undoManager_.hasUndoState());
-}
-</script>
-</body>
-</html>