dojox/editor/plugins/Blockquote.js

  • Provides:

    • dojox.editor.plugins.Blockquote
  • dojox.editor.plugins.Blockquote

    • type
      Function
    • chains:
      • dijit._editor._Plugin: (prototype)
      • dijit._editor._Plugin: (call)
    • summary
      This plugin provides Blockquote cabability to the editor.
      window/tab
  • dojox.editor.plugins.Blockquote.iconClassPrefix

    • tags: const
    • type
      String
    • summary
      The CSS class name for the button node icon.
  • dojox.editor.plugins.Blockquote._initButton

    • type
      Function
    • source: [view]
        this._nlsResources = dojo.i18n.getLocalization("dojox.editor.plugins", "Blockquote");
        this.button = new dijit.form.ToggleButton({
         label: this._nlsResources["blockquote"],
         showLabel: false,
         iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "Blockquote",
         tabIndex: "-1",
         onClick: dojo.hitch(this, "_toggleQuote")
        });
    • summary
      Over-ride for creation of the preview button.
  • dojox.editor.plugins.Blockquote.setEditor

    • type
      Function
    • parameters:
      • editor: (typeof Object)
        The editor to configure for this plugin to use.
    • source: [view]
        this.editor = editor;
        this._initButton();
        this.connect(this.editor, "onNormalizedDisplayChanged", "updateState");
        // We need the custom undo code since we manipulate the dom
        // outside of the browser natives and only customUndo really handles
        // that. It will incur a performance hit, but should hopefully be
        // relatively small.
        editor.customUndo = true;
    • summary
      Over-ride for the setting of the editor.
  • dojox.editor.plugins.Blockquote._toggleQuote

    • type
      Function
    • parameters:
      • arg: (typeof )
    • source: [view]
        try{
         var ed = this.editor;
         ed.focus();


         var quoteIt = this.button.get("checked");
         var sel = dijit.range.getSelection(ed.window);
         var range, elem, start, end;
         if(sel && sel.rangeCount > 0){
          range = sel.getRangeAt(0);
         }
         if(range){
          ed.beginEditing();
          if(quoteIt){
           // Lets see what we've got as a selection...
           var bq, tag;
           if(range.startContainer === range.endContainer){
            // No selection, just cursor point, we need to see if we're
            // in an indentable block, or similar.
            if(this._isRootInline(range.startContainer)){
             // Text at the 'root' of the document, so we need to gather all of it.,

        
             // First, we need to find the toplevel inline element that is rooted
             // to the document 'editNode'
             start = range.startContainer;
             while(start && start.parentNode !== ed.editNode){
              start = start.parentNode;
             }
             // Now we need to walk up its siblings and look for the first one in the rooting
             // that isn't inline or text, as we want to grab all of that for indent.
             while(start && start.previousSibling && (
               this._isTextElement(start) ||
               (start.nodeType === 1 &&
                this._isInlineFormat(this._getTagName(start))
              ))){
              start = start.previousSibling;
             }
             if(start && start.nodeType === 1 &&
              !this._isInlineFormat(this._getTagName(start))){
              // Adjust slightly, we're one node too far back in this case.
              start = start.nextSibling;
             }

        
             // Okay, we have a configured start, lets grab everything following it that's
             // inline and make it part of the blockquote!
             if(start){
              bq = ed.document.createElement("blockquote");
              dojo.place(bq, start, "after");
              bq.appendChild(start);
              end = bq.nextSibling;
              while(end && (
               this._isTextElement(end) ||
               (end.nodeType === 1 &&
                this._isInlineFormat(this._getTagName(end)))
               )){
               // Add it.
               bq.appendChild(end);
               end = bq.nextSibling;
              }
             }
            }else{
             // Figure out what to do when not root inline....
             var node = range.startContainer;
             while ((this._isTextElement(node) ||
               this._isInlineFormat(this._getTagName(node))
               || this._getTagName(node) === "li") &&
              node !== ed.editNode && node !== ed.document.body){
              node = node.parentNode;
             }
             if(node !== ed.editNode && node !== node.ownerDocument.documentElement){
              bq = ed.document.createElement("blockquote");
              dojo.place(bq, node, "after");
              bq.appendChild(node);
             }
            }
            if(bq){
             dojo.withGlobal(ed.window,
              "selectElementChildren", dijit._editor.selection, [bq]);
             dojo.withGlobal(ed.window,
              "collapse", dijit._editor.selection, [true]);
            }
           }else{
            var curNode;
            // multi-node select. We need to scan over them.
            // Find the two containing nodes at start and end.
            // then move the end one node past. Then ... lets see
            // what we can blockquote!
            start = range.startContainer;
            end = range.endContainer;
            // Find the non-text nodes.


            while(start && this._isTextElement(start) && start.parentNode !== ed.editNode){
             start = start.parentNode;
            }


            // Try to find the end node. We have to check the selection junk
            curNode = start;
            while(curNode.nextSibling && dojo.withGlobal(ed.window,
             "inSelection", dijit._editor.selection, [curNode])){
             curNode = curNode.nextSibling;
            }
            end = curNode;
            if(end === ed.editNode || end === ed.document.body){
             // Unable to determine real selection end, so just make it
             // a single node indent of start + all following inline styles, if
             // present, then just exit.
             bq = ed.document.createElement("blockquote");
             dojo.place(bq, start, "after");
             tag = this._getTagName(start);
             if(this._isTextElement(start) || this._isInlineFormat(tag)){
              // inline element or textnode
              // Find and move all inline tags following the one we inserted also into the
              // blockquote so we don't split up content funny.
              var next = start;
              while(next && (
               this._isTextElement(next) ||
               (next.nodeType === 1 &&
               this._isInlineFormat(this._getTagName(next))))){
               bq.appendChild(next);
               next = bq.nextSibling;
              }
             }else{
              bq.appendChild(start);
             }
             return;
            }


            // Has a definite end somewhere, so lets try to blockquote up to it.
            // requires looking at the selections and in some cases, moving nodes
            // into separate blockquotes.
            end = end.nextSibling;
            curNode = start;
            while(curNode && curNode !== end){
             if(curNode.nodeType === 1){
              tag = this._getTagName(curNode);
              if(tag !== "br"){
               if(!window.getSelection){
                // IE sometimes inserts blank P tags, which we want to skip
                // as they end up blockquoted, which messes up layout.
                if(tag === "p" && this._isEmpty(curNode)){
                 curNode = curNode.nextSibling;
                 continue;
                }
               }
               if(this._isInlineFormat(tag)){
                // inline tag.
                if(!bq){
                 bq = ed.document.createElement("blockquote");
                 dojo.place(bq, curNode, "after");
                 bq.appendChild(curNode);
                }else{
                 bq.appendChild(curNode);
                }
                curNode = bq;
               }else{
                if(bq){
                 if(this._isEmpty(bq)){
                  bq.parentNode.removeChild(bq);
                 }
                }
                bq = ed.document.createElement("blockquote");
                dojo.place(bq, curNode, "after");
                bq.appendChild(curNode);
                curNode = bq;
               }
              }
             }else if(this._isTextElement(curNode)){
              if(!bq){
               bq = ed.document.createElement("blockquote");
               dojo.place(bq, curNode, "after");
               bq.appendChild(curNode);
              }else{
               bq.appendChild(curNode);
              }
              curNode = bq;
             }
             curNode = curNode.nextSibling;
            }
            // Okay, check the last bq, remove it if no content.
            if(bq){
             if(this._isEmpty(bq)){
              bq.parentNode.removeChild(bq);
             }else{
              dojo.withGlobal(ed.window,
               "selectElementChildren", dijit._editor.selection, [bq]);
              dojo.withGlobal(ed.window,
               "collapse", dijit._editor.selection, [true]);
             }
             bq = null;
            }
           }
          }else{
           var found = false;
           if(range.startContainer === range.endContainer){
            elem = range.endContainer;
            // Okay, now see if we can find one of the formatting types we're in.
            while(elem && elem !== ed.editNode && elem !== ed.document.body){
             var tg = elem.tagName?elem.tagName.toLowerCase():"";
             if(tg === "blockquote"){
              found = true;
              break;
             }
             elem = elem.parentNode;
            }
            if(found){
             var lastChild;
             while(elem.firstChild){
              lastChild = elem.firstChild;
              dojo.place(lastChild, elem, "before");
             }
             elem.parentNode.removeChild(elem);
             if(lastChild){
              dojo.withGlobal(ed.window,
               "selectElementChildren", dijit._editor.selection, [lastChild]);
              dojo.withGlobal(ed.window,
               "collapse", dijit._editor.selection, [true]);
             }
            }
           }else{
            // Multi-select! Gotta find all the blockquotes contained within the selection area.
            start = range.startContainer;
            end = range.endContainer;
            while(start && this._isTextElement(start) && start.parentNode !== ed.editNode){
             start = start.parentNode;
            }
            var selectedNodes = [];
            var cNode = start;
            while(cNode && cNode.nextSibling && dojo.withGlobal(ed.window,
             "inSelection", dijit._editor.selection, [cNode])){
             if(cNode.parentNode && this._getTagName(cNode.parentNode) === "blockquote"){
              cNode = cNode.parentNode;
             }
             selectedNodes.push(cNode);
             cNode = cNode.nextSibling;
            }

            
            // Find all the blocknodes now that we know the selection area.
            var bnNodes = this._findBlockQuotes(selectedNodes);
            while(bnNodes.length){
             var bn = bnNodes.pop();
             if(bn.parentNode){
              // Make sure we haven't seen this before and removed it.
              while(bn.firstChild){
               dojo.place(bn.firstChild, bn, "before");
              }
              bn.parentNode.removeChild(bn);
             }
            }
           }
          }
          ed.endEditing();
         }
         ed.onNormalizedDisplayChanged();
        }catch(e){ /* Squelch */ }
    • summary
      Function to trigger previewing of the editor document
    • tags:
  • dojox.editor.plugins.Blockquote.updateState

    • type
      Function
    • source: [view]
        var ed = this.editor;
        var disabled = this.get("disabled");

        
        if(!ed || !ed.isLoaded){ return; }
        if(this.button){
         this.button.set("disabled", disabled);
         if(disabled){
          return;
         }


         // Some browsers (WebKit) doesn't actually get the tag info right.
         // So ... lets check it manually.
         var elem;
         var found = false;

         
         // Try to find the ansestor element (and see if it is blockquote)
         var sel = dijit.range.getSelection(ed.window);
         if(sel && sel.rangeCount > 0){
          var range = sel.getRangeAt(0);
          if(range){
           elem = range.endContainer;
          }
         }
         // Okay, now see if we can find one of the formatting types we're in.
         while(elem && elem !== ed.editNode && elem !== ed.document){
          var tg = elem.tagName?elem.tagName.toLowerCase():"";
          if(tg === "blockquote"){
           found = true;
           break;
          }
          elem = elem.parentNode;
         }
         // toggle whether or not the current selection is blockquoted.
         this.button.set("checked", found);
        }
    • summary
      Overrides _Plugin.updateState().  This controls whether or not the current
      cursor position should toggle on the quote button or not.
    • tags:
  • dojox.editor.plugins.Blockquote._findBlockQuotes

    • type
      Function
    • parameters:
      • nodeList: (typeof The)
        list of nodes.
    • source: [view]
        var bnList = [];
        if(nodeList){
         var i;
         for(i = 0; i < nodeList.length; i++){
          var node = nodeList[i];
          if(node.nodeType === 1){
           if(this._getTagName(node) === "blockquote"){
            bnList.push(node);
           }
           if(node.childNodes && node.childNodes.length > 0){
            bnList = bnList.concat(this._findBlockQuotes(node.childNodes));
           }
          }
         }
        }
        return bnList;
    • summary
      function to find a ll the blocknode elements in a collection of
      nodes
    • tags:
  • dojox.editor.plugins.Blockquote._getTagName

    • type
      Function
    • parameters:
      • node: (typeof The)
        node to look at.
    • source: [view]
        var tag = "";
        if(node && node.nodeType === 1){
         tag = node.tagName?node.tagName.toLowerCase():"";
        }
        return tag;
    • summary
      Internal function to get the tag name of an element
      if any.
    • tags:
  • dojox.editor.plugins.Blockquote._isRootInline

    • type
      Function
    • parameters:
      • node: (typeof The)
        node to start at.
    • source: [view]
        var ed = this.editor;
        if(this._isTextElement(node) && node.parentNode === ed.editNode){
         return true;
        }else if(node.nodeType === 1 && this._isInlineFormat(node) && node.parentNode === ed.editNode){
         return true;
        }else if(this._isTextElement(node) && this._isInlineFormat(this._getTagName(node.parentNode))){
         node = node.parentNode;
         while(node && node !== ed.editNode && this._isInlineFormat(this._getTagName(node))){
          node = node.parentNode;
         }
         if(node === ed.editNode){
          return true;
         }
        }
        return false;
    • summary
      This functions tests whether an indicated node is in root as inline
      or rooted inline elements in the page.
    • tags:
  • dojox.editor.plugins.Blockquote._isTextElement

    • type
      Function
    • parameters:
      • node: (typeof The)
        node to check.
    • source: [view]
        if(node && node.nodeType === 3 || node.nodeType === 4){
         return true;
        }
        return false;
    • summary
      Helper function to check for text nodes.
    • tags:
  • dojox.editor.plugins.Blockquote._isEmpty

    • type
      Function
    • parameters:
      • node: (typeof The)
        node to check.
    • source: [view]
        if(node.childNodes){
         var empty = true;
         var i;
         for(i = 0; i < node.childNodes.length; i++){
          var n = node.childNodes[i];
          if(n.nodeType === 1){
           if(this._getTagName(n) === "p"){
            if(!dojo.trim(n.innerHTML)){
             continue;
            }
           }
           empty = false;
           break;
          }else if(this._isTextElement(n)){
           // Check for empty text.
           var nv = dojo.trim(n.nodeValue);
           if(nv && nv !==" " && nv !== "\u00A0"){
            empty = false;
            break;
           }
          }else{
           empty = false;
           break;
          }
         }
         return empty;
        }else{
         return true;
        }
    • summary
      Internal function to determine if a node is 'empty'
      Eg, contains only blank text.  Used to determine if
      an empty list element should be removed or not.
    • tags:
  • dojox.editor.plugins.Blockquote._isInlineFormat

    • type
      Function
    • parameters:
      • tag: (typeof The)
        tag to examine
    • source: [view]
        switch(tag){
         case "a":
         case "b":
         case "strong":
         case "s":
         case "strike":
         case "i":
         case "u":
         case "em":
         case "sup":
         case "sub":
         case "span":
         case "font":
         case "big":
         case "cite":
         case "q":
         case "img":
         case "small":
          return true;
         default:
          return false;
        }
    • summary
      Function to determine if the current tag is an inline
      element that does formatting, as we don't want to
      break/indent around it, as it can screw up text.
    • tags:
  • dojox.editor.plugins.Blockquote._nlsResources

    • summary
  • dojox.editor.plugins.Blockquote.button

    • summary
  • dojox.editor.plugins.Blockquote.editor

    • summary
  • dojox.editor.plugins.Blockquote.setEditor.editor

    • type
      Object
    • summary
      The editor to configure for this plugin to use.
  • name

    • summary
  • o.plugin

    • summary
  • dojox.editor.plugins

    • type
      Object
    • summary
  • dojox.editor

    • type
      Object
    • summary
  • dojox

    • type
      Object
    • summary