[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 // This file is part of Moodle - http://moodle.org/ 2 // 3 // Moodle is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU General Public License as published by 5 // the Free Software Foundation, either version 3 of the License, or 6 // (at your option) any later version. 7 // 8 // Moodle is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU General Public License for more details. 12 // 13 // You should have received a copy of the GNU General Public License 14 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 15 16 /* 17 * @package atto_indent 18 * @copyright 2013 Damyon Wiese <damyon@moodle.com> 19 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 20 */ 21 22 /** 23 * @module moodle-atto_indent-button 24 */ 25 26 /** 27 * Atto text editor indent plugin. 28 * 29 * @namespace M.atto_indent 30 * @class button 31 * @extends M.editor_atto.EditorPlugin 32 */ 33 34 Y.namespace('M.atto_indent').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], { 35 initializer: function() { 36 37 this.addButton({ 38 icon: 'e/decrease_indent', 39 title: 'outdent', 40 buttonName: 'outdent', 41 callback: this.outdent 42 }); 43 44 this.addButton({ 45 icon: 'e/increase_indent', 46 title: 'indent', 47 buttonName: 'indent', 48 callback: this.indent 49 }); 50 }, 51 52 /** 53 * Indents the currently selected content. 54 * 55 * @method indent 56 */ 57 indent: function() { 58 // Save the current selection - we want to restore this. 59 var selection = window.rangy.saveSelection(), 60 blockquotes = this.editor.all('blockquote'), 61 count = blockquotes.size(); 62 63 // Remove display:none from rangy markers so browser doesn't delete them. 64 this.editor.all('.rangySelectionBoundary').setStyle('display', null); 65 66 // Mark all existing block quotes in case the user has actually added some. 67 blockquotes.addClass('pre-existing'); 68 69 // Run the indent command. 70 document.execCommand('indent', false, null); 71 72 // Get all blockquotes, both existing and new. 73 blockquotes = this.editor.all('blockquote'); 74 75 if (blockquotes.size() !== count) { 76 // There are new block quotes, the indent exec has wrapped some content in block quotes in order 77 // to indent the selected content. 78 // We don't want blockquotes, we're going to convert them to divs. 79 this.replaceBlockquote(this.editor); 80 // Finally restore the seelction. The content has changed - sometimes this works - but not always :( 81 window.rangy.restoreSelection(selection); 82 } else if (blockquotes.size() > 0) { 83 // There were no new blockquotes, this happens if the user is indenting/outdenting a list. 84 blockquotes.removeClass('pre-existing'); 85 } 86 87 // Remove the selection markers - a clean up really. 88 window.rangy.removeMarkers(selection); 89 90 // Mark the text as having been updated. 91 this.markUpdated(); 92 }, 93 94 /** 95 * Outdents the currently selected content. 96 * 97 * @method outdent 98 */ 99 outdent: function() { 100 // Save the selection we will want to restore it. 101 var selection = window.rangy.saveSelection(), 102 blockquotes = this.editor.all('blockquote'), 103 count = blockquotes.size(); 104 105 // Mark existing blockquotes so that we don't convert them later. 106 blockquotes.addClass('pre-existing'); 107 108 // Replace all div indents with blockquote indents so that we can rely on the browser functionality. 109 this.replaceEditorIndents(this.editor); 110 111 // Restore the users selection - otherwise the next outdent operation won't work! 112 window.rangy.restoreSelection(selection); 113 // And save it once more. 114 selection = window.rangy.saveSelection(); 115 116 // Outdent. 117 document.execCommand('outdent', false, null); 118 119 // Get all blockquotes so that we can work out what happened. 120 blockquotes = this.editor.all('blockquote'); 121 122 if (blockquotes.size() !== count) { 123 // The number of blockquotes hasn't changed. 124 // This occurs when the user has outdented a list item. 125 this.replaceBlockquote(this.editor); 126 window.rangy.restoreSelection(selection); 127 } else if (blockquotes.size() > 0) { 128 // The number of blockquotes is the same and is more than 0 we just need to clean up the class 129 // we added to mark pre-existing blockquotes. 130 blockquotes.removeClass('pre-existing'); 131 } 132 133 // Clean up any left over selection markers. 134 window.rangy.removeMarkers(selection); 135 136 // Mark the text as having been updated. 137 this.markUpdated(); 138 }, 139 140 /** 141 * Replaces all blockquotes within an editor with div indents. 142 * @method replaceBlockquote 143 * @param Editor editor 144 */ 145 replaceBlockquote: function(editor) { 146 editor.all('blockquote').setAttribute('data-iterate', true); 147 var blockquote = editor.one('blockquote'), 148 margindir = (Y.one('body.dir-ltr')) ? 'marginLeft' : 'marginRight'; 149 while (blockquote) { 150 blockquote.removeAttribute('data-iterate'); 151 if (blockquote.hasClass('pre-existing')) { 152 blockquote.removeClass('pre-existing'); 153 } else { 154 var clone = Y.Node.create('<div></div>') 155 .setAttrs(blockquote.getAttrs()) 156 .setStyle(margindir, '30px') 157 .addClass('editor-indent'); 158 // We use childNodes here because we are interested in both type 1 and 3 child nodes. 159 var children = blockquote.getDOMNode().childNodes; 160 var child; 161 child = children[0]; 162 while (typeof child !== "undefined") { 163 clone.append(child); 164 child = children[0]; 165 } 166 blockquote.replace(clone); 167 } 168 blockquote = editor.one('blockquote[data-iterate]'); 169 } 170 }, 171 172 /** 173 * Replaces all div indents with blockquotes. 174 * @method replaceEditorIndents 175 * @param Editor editor 176 */ 177 replaceEditorIndents: function(editor) { 178 // We use the editor-indent class because it is preserved between saves. 179 var indent = editor.one('.editor-indent'); 180 while (indent) { 181 var clone = Y.Node.create('<blockquote></blockquote>') 182 .setAttrs(indent 183 .getAttrs()) 184 .removeClass('editor-indent'); 185 // We use childNodes here because we are interested in both type 1 and 3 child nodes. 186 var children = indent.getDOMNode().childNodes; 187 var child; 188 child = children[0]; 189 while (typeof child !== "undefined") { 190 clone.append(child); 191 child = children[0]; 192 } 193 indent.replace(clone); 194 indent = editor.one('.editor-indent'); 195 } 196 } 197 });
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |