• Jump To … +
    Arte.js Commands.js Configuration.js PluginManager.js TextArea.js Util.js jquery-dom-cleanup.js jquery-dom-manipulation.js jquery-dom-traversal.js rangy-blockElementApplier.js rangy-elementApplierOptions.js rangy-extensions.js rangy-inlineElementApplier.js richtextCommandApplier.js InsertCommand.js StateDetector.js UndoManager.js keyboardEventHandler.js pasteHandler.js Button.js ButtonWithDialog.js ButtonWithDropDown.js Configuration.js SelectionManager.js toolbar.js
  • richtextCommandApplier.js

  • ¶
    /**
     * @fileoverview Encapsulates applying a rich text command
     */
    (function($) {
        $.Arte = $.Arte || {};
        $.Arte.RichTextCommandApplier = function(options) {
  • ¶
            var dom = $.Arte.dom;
            var util = $.Arte.util;
            var constants = $.Arte.constants;
            var configuration = $.Arte.configuration;
    
            var applyToTextNodes = function(commandInfo, type) {
                var selection = rangy.getSelection();
                var textArea = commandInfo.textArea;
  • ¶

    If the selection is not in the content editable element and ops of collapsed selection aren’t allowed, return

                var selectionIsInContentEditable = util.isSelectionInElement(textArea.$el);
    
                var range = null;
                if (selection.isCollapsed) {
                    var selectedRange = selection.getAllRanges()[0];
                    var selectedContainer;
                    if (selectedRange && selectionIsInContentEditable) {
  • ¶

    The cursor is inside the contentEditable; select the node around the cursor

                        selectedContainer = selectedRange.startContainer;
                        selectedContainer = selectedContainer.nodeType === constants.nodeType.TEXT ?
                            selectedContainer.parentNode :
                            selectedContainer;
    
                    } else {
                        selectedContainer = textArea.$el.get(0);
                    }
  • ¶

    if selection is collapsed, construct a range from the first parent

                    range = rangy.util.createRangeFromElements(selectedContainer, selectedContainer);
                }
  • ¶

    Explicitly define the contentEditable parent

                var contentEditableParent = textArea.$el;
    
                var contentEditableContainer = contentEditableParent.get(0);
                var commandOptions = {
                    topEditableParent: contentEditableContainer
                };
    
                $.extend(commandOptions, commandInfo);
                var commandType = constants.commandType;
                var commandToExecute = null;
                switch (type) {
                    case commandType.inline:
                        commandToExecute = function() {
                            return range ?
                                rangy.toggleStyleOnRange(range, commandOptions) :
                                rangy.toggleStyleOnSelection(commandOptions);
                        };
                        break;
                    case commandType.block:
                        commandToExecute = function() {
                            return range ?
                                rangy.toggleSurroundRange(range, commandOptions) :
                                rangy.toggleSurroundSelection(commandOptions, contentEditableContainer);
                        };
                        break;
                    case commandType.complex:
                        commandToExecute = function() {
                            return range ?
                                rangy.toggleSurroundRangeSet(range, commandOptions) :
                                rangy.toggleSurroundSelectionSet(commandOptions, contentEditableContainer);
                        };
                        break;
                }
    
                var sel = rangy.saveSelection();
                commandToExecute();
                dom.cleanup($(commandOptions.topEditableParent));
                rangy.restoreSelection(sel);
            };
    
            var applyCommand = function(commandInfo, type) {
                var textField = commandInfo.textArea;
                var editorTypes = constants.editorTypes;
                var applyToElement = textField.editorType === editorTypes.plainText || !textField.$el.html();
  • ¶

    If the selection is not in the content editable element and focus is required return

                var selectionIsInContentEditable = util.isSelectionInElement(textField.$el);
                if (!selectionIsInContentEditable && configuration.requireFocus) {
                    return;
                }
  • ¶

    Apply to element if focus is not required

                if (!selectionIsInContentEditable && !configuration.requireFocus &&
                    commandInfo.commandAttrType != "tagName") {
                    applyToElement = true;
                }
    
                if (applyToElement) {
                    textField.toggleStyleOnElement(commandInfo);
                } else {
                    applyToTextNodes(commandInfo, type);
                }
            };
    
            /*
             * Execute a rich text command
             */
            this.execute = function() {
                if (!options.commandName) {
                    throw "commandName not specified.";
                }
    
                var commandConfig = configuration.commands[options.commandName];
                if (!commandConfig) {
                    throw "unrecognized command: " + options.commandName;
                }
    
                applyCommand(options, commandConfig.commandType);
            };
        };
    
        /*
         * Create an execute a rich text command
         */
        $.Arte.RichTextCommandApplier.createAndExecute = function(options) {
            var command = new $.Arte.RichTextCommandApplier(options);
            command.execute();
            return command;
        };
    })(jQuery);