%PDF- %PDF-
Direktori : /home/vacivi36/ava/lib/editor/atto/yui/src/editor/js/ |
Current File : /home/vacivi36/ava/lib/editor/atto/yui/src/editor/js/commands.js |
// This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * @module moodle-editor_atto-editor * @submodule commands */ /** * Selection functions for the Atto editor. * * See {{#crossLink "M.editor_atto.Editor"}}{{/crossLink}} for details. * * @namespace M.editor_atto * @class EditorCommand */ function EditorCommand() {} EditorCommand.ATTRS = { }; EditorCommand.prototype = { /** * Applies a callback method to editor if selection is uncollapsed or waits for input to select first. * @method applyFormat * @param e EventTarget Event to be passed to callback if selection is uncollapsed * @param method callback A callback method which changes editor when text is selected. * @param object context Context to be used for callback method * @param array args Array of arguments to pass to callback */ applyFormat: function(e, callback, context, args) { function handleInsert(e, callback, context, args, anchorNode, anchorOffset) { // After something is inputed, select it and apply the formating function. Y.soon(Y.bind(function(e, callback, context, args, anchorNode, anchorOffset) { var selection = window.rangy.getSelection(); // Set the start of the selection to where it was when the method was first called. var range = selection.getRangeAt(0); range.setStart(anchorNode, anchorOffset); selection.setSingleRange(range); // Now apply callback to the new text that is selected. callback.apply(context, [e, args]); // Collapse selection so cursor is at end of inserted material. selection.collapseToEnd(); // Save save selection and editor contents. this.saveSelection(); this.updateOriginal(); }, this, e, callback, context, args, anchorNode, anchorOffset)); } // Set default context for the method. context = context || this; // Check whether range is collapsed. var selection = window.rangy.getSelection(); if (selection.isCollapsed) { // Selection is collapsed so listen for input into editor. var handle = this.editor.once('input', handleInsert, this, callback, context, args, selection.anchorNode, selection.anchorOffset); // Cancel if selection changes before input. this.editor.onceAfter(['click', 'selectstart'], handle.detach, handle); return; } // The range is not collapsed; so apply callback method immediately. callback.apply(context, [e, args]); // Save save selection and editor contents. this.saveSelection(); this.updateOriginal(); }, /** * Replaces all the tags in a node list with new type. * @method replaceTags * @param NodeList nodelist * @param String tag */ replaceTags: function(nodelist, tag) { // We mark elements in the node list for iterations. nodelist.setAttribute('data-iterate', true); var node = this.editor.one('[data-iterate="true"]'); while (node) { var clone = Y.Node.create('<' + tag + ' />') .setAttrs(node.getAttrs()) .removeAttribute('data-iterate'); // Copy class and style if not blank. if (node.getAttribute('style')) { clone.setAttribute('style', node.getAttribute('style')); } if (node.getAttribute('class')) { clone.setAttribute('class', node.getAttribute('class')); } // We use childNodes here because we are interested in both type 1 and 3 child nodes. var children = node.getDOMNode().childNodes; var child; child = children[0]; while (typeof child !== "undefined") { clone.append(child); child = children[0]; } node.replace(clone); node = this.editor.one('[data-iterate="true"]'); } }, /** * Change all tags with given type to a span with CSS class attribute. * @method changeToCSS * @param String tag Tag type to be changed to span * @param String markerClass CSS class that corresponds to desired tag */ changeToCSS: function(tag, markerClass) { // Save the selection. var selection = window.rangy.saveSelection(); // Remove display:none from rangy markers so browser doesn't delete them. this.editor.all('.rangySelectionBoundary').setStyle('display', null); // Replace tags with CSS classes. this.editor.all(tag).addClass(markerClass); this.replaceTags(this.editor.all('.' + markerClass), 'span'); // Restore selection and toggle class. window.rangy.restoreSelection(selection); }, /** * Change spans with CSS classes in editor into elements with given tag. * @method changeToCSS * @param String markerClass CSS class that corresponds to desired tag * @param String tag New tag type to be created */ changeToTags: function(markerClass, tag) { // Save the selection. var selection = window.rangy.saveSelection(); // Remove display:none from rangy markers so browser doesn't delete them. this.editor.all('.rangySelectionBoundary').setStyle('display', null); // Replace spans with given tag. this.replaceTags(this.editor.all('span[class="' + markerClass + '"]'), tag); this.editor.all(tag + '[class="' + markerClass + '"]').removeAttribute('class'); this.editor.all('.' + markerClass).each(function(n) { n.wrap('<' + tag + '/>'); n.removeClass(markerClass); }); // Remove CSS classes. this.editor.all('[class="' + markerClass + '"]').removeAttribute('class'); this.editor.all(tag).removeClass(markerClass); // Restore selection. window.rangy.restoreSelection(selection); } }; Y.Base.mix(Y.M.editor_atto.Editor, [EditorCommand]);