AutorÃa | Ultima modificación | Ver Log |
// 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]);