[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/editor/atto/plugins/indent/yui/src/button/js/ -> button.js (source)

   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  });


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1