dojox/editor/plugins/ResizeTableColumn.js

  • Provides:

    • dojox.editor.plugins.ResizeTableColumn
  • Requires:

    • dojox.editor.plugins.TablePlugins in common
  • dojox.editor.plugins.ResizeTableColumn

    • type
      Function
    • chains:
      • dojox.editor.plugins.TablePlugins: (prototype)
      • dojox.editor.plugins.TablePlugins: (call)
    • source: [view]
         this.isLtr = this.dir ? (this.dir == "ltr") : dojo._isBodyLtr();
         this.ruleDiv = dojo.create("div",
          {style: "top: -10000px; z-index: 10001"},
          dojo.body(), "last");
    • summary
      Because IE will ignore the cursor style when the editMode of the document is on,
      we need to create a div within the outer document to mimic the behavior of drag&drop
  • dojox.editor.plugins.ResizeTableColumn.setEditor

    • type
      Function
    • parameters:
      • editor: (typeof The)
        editor which this plugin belongs to
    • source: [view]
         var ruleDiv = this.ruleDiv;

         
         this.editor = editor;
         this.editor.customUndo = true;
         this.onEditorLoaded();

         
         // The content of the editor is loaded asynchronously, so the function
         // should be called when it is loaded.
         editor.onLoadDeferred.addCallback(dojo.hitch(this, function(){
          this.connect(this.editor.editNode, "onmousemove", function(evt){
           var editorCoords = dojo.coords(editor.iframe, true),
            ex = editorCoords.x, cx = evt.clientX;

           
           if(!this.isDragging){
            // If it is just a movement, put the div at the edge of the
            // target cell so that when the cursor hover on it, it will
            // change to the col-resize style.
            var obj = evt.target;

            
            if(obj.tagName && obj.tagName.toLowerCase() == "td"){
             var objCoords = dojo.coords(obj), ox = objCoords.x, ow = objCoords.w,
              pos = ex + objCoords.x - 2;
             if(this.isLtr){
              ruleDiv.headerColumn = true;
              if(!isBoundary(obj, "first") || cx > ox + ow / 2){
               pos += ow;
               ruleDiv.headerColumn = false;
              }
             }else{
              ruleDiv.headerColumn = false;
              if(isBoundary(obj, "first") && cx > ox + ow / 2){
               pos += ow;
               ruleDiv.headerColumn = true;
              }
             }
             dojo.style(ruleDiv, {
              position: "absolute",
              cursor: "col-resize",
              display: "block",
              width: "4px",
              backgroundColor: "transparent",
              top: editorCoords.y + objCoords.y + "px",
              left: pos + "px",
              height: objCoords.h + "px"
             });
             this.activeCell = obj;
            }else{
             dojo.style(ruleDiv, {display: "none", top: "-10000px"});
            }
           }else{
            // Begin to drag&drop
            var activeCell = this.activeCell,
             activeCoords = dojo.coords(activeCell), ax = activeCoords.x, aw = activeCoords.w,
             sibling = nextSibling(activeCell), siblingCoords, sx, sw,
             containerCoords = dojo.coords(getTable(activeCell).parentNode),
             ctx = containerCoords.x, ctw = containerCoords.w;

            
            if(sibling){
             siblingCoords = dojo.coords(sibling);
             sx = siblingCoords.x;
             sw = siblingCoords.w;
            }

            
            // The leading and trailing columns can only be sized to the extent of the containing div.
            if(this.isLtr &&
              ((ruleDiv.headerColumn && sibling && ctx < cx && cx < ax + aw) ||
               ((!sibling && ax < cx && cx < ctx + ctw) || (sibling && ax < cx && cx < sx + sw))) ||
             !this.isLtr &&
              ((ruleDiv.headerColumn && sibling && ctx > cx && cx > ax) ||
               ((!sibling && ax + aw > cx && cx > ctx) || (sibling && ax + aw > cx && cx > sx)))){
             dojo.style(ruleDiv, {left: ex + cx + "px"});
            }
           }
          });

          
          this.connect(ruleDiv, "onmousedown", function(evt){
           var editorCoords = dojo.coords(editor.iframe, true),
            tableCoords = dojo.coords(getTable(this.activeCell));

           
           this.isDragging = true;
           dojo.style(editor.editNode, {cursor: "col-resize"});
           dojo.style(ruleDiv, {
            width: "1px",
            left: evt.clientX + "px",
            top: editorCoords.y + tableCoords.y + "px",
            height: tableCoords.h + "px",
            backgroundColor: "#777"
           });
          });

          
          this.connect(ruleDiv, "onmouseup", function(evt){
           var activeCell = this.activeCell,
            activeCoords = dojo.coords(activeCell), aw = activeCoords.w, ax = activeCoords.x,
            sibling = nextSibling(activeCell), siblingCoords, sx, sw,
            editorCoords = dojo.coords(editor.iframe), ex = editorCoords.x,
            table = getTable(activeCell), tableCoords = dojo.coords(table),
            cs = table.getAttribute("cellspacing"),
            cx = evt.clientX,
            headerCell = getHeaderCell(activeCell), headerSibling,
            newWidth, newSiblingWidth;

           
           if(!cs || (cs = parseInt(cs, 10)) < 0){ cs = 2; }

           
           if(sibling){
            siblingCoords = dojo.coords(sibling);
            sx = siblingCoords.x;
            sw = siblingCoords.w;
            headerSibling = getHeaderCell(sibling);
           }

           
           // The delta width is either taken from or added to the adjacent column on the trailing edge.
           // Sizing the rightmost or leftmost columns affects only those columns.
           if(this.isLtr){
            if(ruleDiv.headerColumn){
             newWidth = ex + ax + aw - cx;
            }else{
             newWidth = cx - ex - ax;
             if(sibling) { newSiblingWidth = ex + sx + sw - cx - cs; }
            }
           }else{
            if(ruleDiv.headerColumn){
             newWidth = cx - ex - ax;
            }else{
             newWidth = ex + ax + aw - cx;
             if(sibling) { newSiblingWidth = cx - ex - sx - cs; }
            }
           }

           
           this.isDragging = false;
           marginBox(headerCell, newWidth);
           if(sibling){
            if(!ruleDiv.headerColumn){
             marginBox(headerSibling, newSiblingWidth);
            }
           }
           if(ruleDiv.headerColumn && isBoundary(activeCell, "first") || isBoundary(activeCell, "last")){
            dojo.marginBox(table, {w: tableCoords.w + newWidth - aw});
           }
           // Do it again to consolidate the result,
           // because maybe the cell cannot be so narrow as you specified.
           marginBox(headerCell, dojo.coords(activeCell).w);
           if(sibling){
            marginBox(headerSibling, dojo.coords(sibling).w);
           }
           dojo.style(editor.editNode, {cursor: "auto"});
           dojo.style(ruleDiv, {display: "none", top: "-10000px"});
           this.activeCell = null;
          });
         }));

         
         function isBoundary(/*DomNode*/ n, /*String*/ b){
          // summary:
          //  Check if the current cell is in the first column or
          //  in the last column.
          // n:
          //  The node of a table cell
          // b:
          //  Indicate if the cell node is compared with the first coluln
          //  or the last column
          var nodes = dojo.withGlobal(editor.window, "query", dojo, ["> td", n.parentNode]);
          switch(b){
           case "first":
            return nodes[0] == n;
           case "last":
            return nodes[nodes.length - 1] == n;
           default:
            return false;
          }
         }

         
         function nextSibling(/*DomNode*/ node){
          // summary:
          //  Get the next cell in row
          // node:
          //  The table cell
          node = node.nextSibling
          while(node){
           if(node.tagName && node.tagName.toLowerCase() == "td"){
            break;
           }
           node = node.nextSibling
          }
          return node;
         }

         
         function getTable(/*DomNode*/ t){
          // summary:
          //  Get the table that this cell belongs to.
          // t:
          //  The table cell
          while((t = t.parentNode) && t.tagName.toLowerCase() != "table"){}
          return t;
         }

         
         function getHeaderCell(/*DomNode*/ t){
          // summary:
          //  Get the table cell in the first row that shares the same
          //  column with the node t.
          // t:
          //  The node of the table cell
          var tds = dojo.withGlobal(editor.window, "query", dojo, ["td", getTable(t)]),
           len = tds.length;
          for(var i = 0; i < len; i++){
           if(dojo.coords(tds[i]).x == dojo.coords(t).x){
            return tds[i];
           }
          }
          return null;
         }

         
         function marginBox(/*DomNode*/ node, /*Number*/ width){
          // summary:
          //  In IE, if the border width of the td is not specified in table, the default value is 1px,
          //  though it is marked "medium".
          // node:
          //  The node to be set width
          // width:
          //  The new width of the node
          if(dojo.isIE){
           var s = node.currentStyle,
            bl = px(node, s.borderLeftWidth), br = px(node, s.borderRightWidth),
            pl = px(node, s.paddingLeft), pr = px(node, s.paddingRight);

           
           node.style.width = width - bl - br - pl - pr;
          }else{
           dojo.marginBox(node, {w: width});
          }

          
          function px(element, avalue){
           if(!avalue){ return 0; }
           if(avalue == "medium"){ return 1; }
           // style values can be floats, client code may
           // want to round this value for integer pixels.
           if(avalue.slice && avalue.slice(-2) == 'px'){ return parseFloat(avalue); }
           with(element){
            var sLeft = style.left;
            var rsLeft = runtimeStyle.left;
            runtimeStyle.left = currentStyle.left;
            try{
             // 'avalue' may be incompatible with style.left, which can cause IE to throw
             // this has been observed for border widths using "thin", "medium", "thick" constants
             // those particular constants could be trapped by a lookup
             // but perhaps there are more
             style.left = avalue;
             avalue = style.pixelLeft;
            }catch(e){
             avalue = 0;
            }
            style.left = sLeft;
            runtimeStyle.left = rsLeft;
           }
           return avalue;
          }
         }
    • summary
      Handle the drag&amp;drop events
    • tags:
  • dojox.editor.plugins.ResizeTableColumn.editor

    • summary
  • dojox.editor.plugins.ResizeTableColumn.editor.customUndo

    • summary
  • dojox.editor.plugins.ResizeTableColumn.activeCell

    • summary
  • dojox.editor.plugins.ResizeTableColumn.isDragging

    • summary
  • dojox.editor.plugins.ResizeTableColumn.setEditor.editor

    • type
      The
    • summary
      editor which this plugin belongs to
  • dojox.editor.plugins.ResizeTableColumn.isLtr

    • summary
  • dojox.editor.plugins.ResizeTableColumn.ruleDiv

    • summary
  • cmd

    • summary
  • o.plugin

    • summary
  • dojox.editor.plugins

    • type
      Object
    • summary
  • dojox.editor

    • type
      Object
    • summary
  • dojox

    • type
      Object
    • summary