BVB Source Codes

Squire Show Node.js Source code

Return Download Squire: download Node.js Source code - Download Squire Source code - Type:.js
  1. /*jshint strict:false, undef:false, unused:false */
  2.  
  3. var inlineNodeNames  = /^(?:#text|A(?:BBR|CRONYM)?|B(?:R|D[IO])?|C(?:ITE|ODE)|D(?:ATA|EL|FN)|EM|FONT|HR|I(?:FRAME|MG|NPUT|NS)?|KBD|Q|R(?:P|T|UBY)|S(?:AMP|MALL|PAN|TR(?:IKE|ONG)|U[BP])?|TIME|U|VAR|WBR)$/;
  4.  
  5. var leafNodeNames = {
  6.     BR: 1,
  7.     HR: 1,
  8.     IFRAME: 1,
  9.     IMG: 1,
  10.     INPUT: 1
  11. };
  12.  
  13. function every ( nodeList, fn ) {
  14.     var l = nodeList.length;
  15.     while ( l-- ) {
  16.         if ( !fn( nodeList[l] ) ) {
  17.             return false;
  18.         }
  19.     }
  20.     return true;
  21. }
  22.  
  23. // ---
  24.  
  25. var UNKNOWN = 0;
  26. var INLINE = 1;
  27. var BLOCK = 2;
  28. var CONTAINER = 3;
  29.  
  30. var nodeCategoryCache = canWeakMap ? new WeakMap() : null;
  31.  
  32. function isLeaf ( node ) {
  33.     return node.nodeType === ELEMENT_NODE && !!leafNodeNames[ node.nodeName ];
  34. }
  35. function getNodeCategory ( node ) {
  36.     switch ( node.nodeType ) {
  37.     case TEXT_NODE:
  38.         return INLINE;
  39.     case ELEMENT_NODE:
  40.     case DOCUMENT_FRAGMENT_NODE:
  41.         if ( canWeakMap && nodeCategoryCache.has( node ) ) {
  42.             return nodeCategoryCache.get( node );
  43.         }
  44.         break;
  45.     default:
  46.         return UNKNOWN;
  47.     }
  48.  
  49.     var nodeCategory;
  50.     if ( !every( node.childNodes, isInline ) ) {
  51.         // Malformed HTML can have block tags inside inline tags. Need to treat
  52.         // these as containers rather than inline. See #239.
  53.         nodeCategory = CONTAINER;
  54.     } else if ( inlineNodeNames.test( node.nodeName ) ) {
  55.         nodeCategory = INLINE;
  56.     } else {
  57.         nodeCategory = BLOCK;
  58.     }
  59.     if ( canWeakMap ) {
  60.         nodeCategoryCache.set( node, nodeCategory );
  61.     }
  62.     return nodeCategory;
  63. }
  64. function isInline ( node ) {
  65.     return getNodeCategory( node ) === INLINE;
  66. }
  67. function isBlock ( node ) {
  68.     return getNodeCategory( node ) === BLOCK;
  69. }
  70. function isContainer ( node ) {
  71.     return getNodeCategory( node ) === CONTAINER;
  72. }
  73.  
  74. function getBlockWalker ( node, root ) {
  75.     var walker = new TreeWalker( root, SHOW_ELEMENT, isBlock );
  76.     walker.currentNode = node;
  77.     return walker;
  78. }
  79. function getPreviousBlock ( node, root ) {
  80.     node = getBlockWalker( node, root ).previousNode();
  81.     return node !== root ? node : null;
  82. }
  83. function getNextBlock ( node, root ) {
  84.     node = getBlockWalker( node, root ).nextNode();
  85.     return node !== root ? node : null;
  86. }
  87.  
  88. function areAlike ( node, node2 ) {
  89.     return !isLeaf( node ) && (
  90.         node.nodeType === node2.nodeType &&
  91.         node.nodeName === node2.nodeName &&
  92.         node.nodeName !== 'A' &&
  93.         node.className === node2.className &&
  94.         ( ( !node.style && !node2.style ) ||
  95.           node.style.cssText === node2.style.cssText )
  96.     );
  97. }
  98. function hasTagAttributes ( node, tag, attributes ) {
  99.     if ( node.nodeName !== tag ) {
  100.         return false;
  101.     }
  102.     for ( var attr in attributes ) {
  103.         if ( node.getAttribute( attr ) !== attributes[ attr ] ) {
  104.             return false;
  105.         }
  106.     }
  107.     return true;
  108. }
  109. function getNearest ( node, root, tag, attributes ) {
  110.     while ( node && node !== root ) {
  111.         if ( hasTagAttributes( node, tag, attributes ) ) {
  112.             return node;
  113.         }
  114.         node = node.parentNode;
  115.     }
  116.     return null;
  117. }
  118. function isOrContains ( parent, node ) {
  119.     while ( node ) {
  120.         if ( node === parent ) {
  121.             return true;
  122.         }
  123.         node = node.parentNode;
  124.     }
  125.     return false;
  126. }
  127.  
  128. function getPath ( node, root ) {
  129.     var path = '';
  130.     var id, className, classNames, dir;
  131.     if ( node && node !== root ) {
  132.         path = getPath( node.parentNode, root );
  133.         if ( node.nodeType === ELEMENT_NODE ) {
  134.             path += ( path ? '>' : '' ) + node.nodeName;
  135.             if ( id = node.id ) {
  136.                 path += '#' + id;
  137.             }
  138.             if ( className = node.className.trim() ) {
  139.                 classNames = className.split( /\s\s*/ );
  140.                 classNames.sort();
  141.                 path += '.';
  142.                 path += classNames.join( '.' );
  143.             }
  144.             if ( dir = node.dir ) {
  145.                 path += '[dir=' + dir + ']';
  146.             }
  147.             if ( classNames ) {
  148.                 if ( indexOf.call( classNames, HIGHLIGHT_CLASS ) > -1 ) {
  149.                     path += '[backgroundColor=' +
  150.                         node.style.backgroundColor.replace( / /g,'' ) + ']';
  151.                 }
  152.                 if ( indexOf.call( classNames, COLOUR_CLASS ) > -1 ) {
  153.                     path += '[color=' +
  154.                         node.style.color.replace( / /g,'' ) + ']';
  155.                 }
  156.                 if ( indexOf.call( classNames, FONT_FAMILY_CLASS ) > -1 ) {
  157.                     path += '[fontFamily=' +
  158.                         node.style.fontFamily.replace( / /g,'' ) + ']';
  159.                 }
  160.                 if ( indexOf.call( classNames, FONT_SIZE_CLASS ) > -1 ) {
  161.                     path += '[fontSize=' + node.style.fontSize + ']';
  162.                 }
  163.             }
  164.         }
  165.     }
  166.     return path;
  167. }
  168.  
  169. function getLength ( node ) {
  170.     var nodeType = node.nodeType;
  171.     return nodeType === ELEMENT_NODE ?
  172.         node.childNodes.length : node.length || 0;
  173. }
  174.  
  175. function detach ( node ) {
  176.     var parent = node.parentNode;
  177.     if ( parent ) {
  178.         parent.removeChild( node );
  179.     }
  180.     return node;
  181. }
  182. function replaceWith ( node, node2 ) {
  183.     var parent = node.parentNode;
  184.     if ( parent ) {
  185.         parent.replaceChild( node2, node );
  186.     }
  187. }
  188. function empty ( node ) {
  189.     var frag = node.ownerDocument.createDocumentFragment(),
  190.         childNodes = node.childNodes,
  191.         l = childNodes ? childNodes.length : 0;
  192.     while ( l-- ) {
  193.         frag.appendChild( node.firstChild );
  194.     }
  195.     return frag;
  196. }
  197.  
  198. function createElement ( doc, tag, props, children ) {
  199.     var el = doc.createElement( tag ),
  200.         attr, value, i, l;
  201.     if ( props instanceof Array ) {
  202.         children = props;
  203.         props = null;
  204.     }
  205.     if ( props ) {
  206.         for ( attr in props ) {
  207.             value = props[ attr ];
  208.             if ( value !== undefined ) {
  209.                 el.setAttribute( attr, props[ attr ] );
  210.             }
  211.         }
  212.     }
  213.     if ( children ) {
  214.         for ( i = 0, l = children.length; i < l; i += 1 ) {
  215.             el.appendChild( children[i] );
  216.         }
  217.     }
  218.     return el;
  219. }
  220.  
  221. function fixCursor ( node, root ) {
  222.     // In Webkit and Gecko, block level elements are collapsed and
  223.     // unfocussable if they have no content. To remedy this, a <BR> must be
  224.     // inserted. In Opera and IE, we just need a textnode in order for the
  225.     // cursor to appear.
  226.     var self = root.__squire__;
  227.     var doc = node.ownerDocument;
  228.     var originalNode = node;
  229.     var fixer, child;
  230.  
  231.     if ( node === root ) {
  232.         if ( !( child = node.firstChild ) || child.nodeName === 'BR' ) {
  233.             fixer = self.createDefaultBlock();
  234.             if ( child ) {
  235.                 node.replaceChild( fixer, child );
  236.             }
  237.             else {
  238.                 node.appendChild( fixer );
  239.             }
  240.             node = fixer;
  241.             fixer = null;
  242.         }
  243.     }
  244.  
  245.     if ( node.nodeType === TEXT_NODE ) {
  246.         return originalNode;
  247.     }
  248.  
  249.     if ( isInline( node ) ) {
  250.         child = node.firstChild;
  251.         while ( cantFocusEmptyTextNodes && child &&
  252.                 child.nodeType === TEXT_NODE && !child.data ) {
  253.             node.removeChild( child );
  254.             child = node.firstChild;
  255.         }
  256.         if ( !child ) {
  257.             if ( cantFocusEmptyTextNodes ) {
  258.                 fixer = doc.createTextNode( ZWS );
  259.                 self._didAddZWS();
  260.             } else {
  261.                 fixer = doc.createTextNode( '' );
  262.             }
  263.         }
  264.     } else {
  265.         if ( useTextFixer ) {
  266.             while ( node.nodeType !== TEXT_NODE && !isLeaf( node ) ) {
  267.                 child = node.firstChild;
  268.                 if ( !child ) {
  269.                     fixer = doc.createTextNode( '' );
  270.                     break;
  271.                 }
  272.                 node = child;
  273.             }
  274.             if ( node.nodeType === TEXT_NODE ) {
  275.                 // Opera will collapse the block element if it contains
  276.                 // just spaces (but not if it contains no data at all).
  277.                 if ( /^ +$/.test( node.data ) ) {
  278.                     node.data = '';
  279.                 }
  280.             } else if ( isLeaf( node ) ) {
  281.                 node.parentNode.insertBefore( doc.createTextNode( '' ), node );
  282.             }
  283.         }
  284.         else if ( !node.querySelector( 'BR' ) ) {
  285.             fixer = createElement( doc, 'BR' );
  286.             while ( ( child = node.lastElementChild ) && !isInline( child ) ) {
  287.                 node = child;
  288.             }
  289.         }
  290.     }
  291.     if ( fixer ) {
  292.         try {
  293.             node.appendChild( fixer );
  294.         } catch ( error ) {
  295.             self.didError({
  296.                 name: 'Squire: fixCursor 鈥撀? + error,
  297.                message: 'Parent: ' + node.nodeName + '/' + node.innerHTML +
  298.                    ' appendChild: ' + fixer.nodeName
  299.            });
  300.        }
  301.    }
  302.  
  303.    return originalNode;
  304. }
  305.  
  306. // Recursively examine container nodes and wrap any inline children.
  307. function fixContainer ( container, root ) {
  308.    var children = container.childNodes;
  309.    var doc = container.ownerDocument;
  310.    var wrapper = null;
  311.    var i, l, child, isBR;
  312.    var config = root.__squire__._config;
  313.  
  314.    for ( i = 0, l = children.length; i < l; i += 1 ) {
  315.        child = children[i];
  316.        isBR = child.nodeName === 'BR';
  317.        if ( !isBR && isInline( child ) ) {
  318.            if ( !wrapper ) {
  319.                 wrapper = createElement( doc,
  320.                    config.blockTag, config.blockAttributes );
  321.            }
  322.            wrapper.appendChild( child );
  323.            i -= 1;
  324.            l -= 1;
  325.        } else if ( isBR || wrapper ) {
  326.            if ( !wrapper ) {
  327.                wrapper = createElement( doc,
  328.                    config.blockTag, config.blockAttributes );
  329.            }
  330.            fixCursor( wrapper, root );
  331.            if ( isBR ) {
  332.                container.replaceChild( wrapper, child );
  333.            } else {
  334.                container.insertBefore( wrapper, child );
  335.                i += 1;
  336.                l += 1;
  337.            }
  338.            wrapper = null;
  339.        }
  340.        if ( isContainer( child ) ) {
  341.            fixContainer( child, root );
  342.        }
  343.    }
  344.    if ( wrapper ) {
  345.        container.appendChild( fixCursor( wrapper, root ) );
  346.    }
  347.    return container;
  348. }
  349.  
  350. function split ( node, offset, stopNode, root ) {
  351.    var nodeType = node.nodeType,
  352.        parent, clone, next;
  353.    if ( nodeType === TEXT_NODE && node !== stopNode ) {
  354.        return split(
  355.            node.parentNode, node.splitText( offset ), stopNode, root );
  356.    }
  357.    if ( nodeType === ELEMENT_NODE ) {
  358.        if ( typeof( offset ) === 'number' ) {
  359.            offset = offset < node.childNodes.length ?
  360.                node.childNodes[ offset ] : null;
  361.        }
  362.        if ( node === stopNode ) {
  363.            return offset;
  364.        }
  365.  
  366.        // Clone node without children
  367.        parent = node.parentNode;
  368.        clone = node.cloneNode( false );
  369.  
  370.        // Add right-hand siblings to the clone
  371.        while ( offset ) {
  372.            next = offset.nextSibling;
  373.            clone.appendChild( offset );
  374.            offset = next;
  375.        }
  376.  
  377.        // Maintain li numbering if inside a quote.
  378.        if ( node.nodeName === 'OL' &&
  379.                getNearest( node, root, 'BLOCKQUOTE' ) ) {
  380.            clone.start = ( +node.start || 1 ) + node.childNodes.length - 1;
  381.        }
  382.  
  383.        // DO NOT NORMALISE. This may undo the fixCursor() call
  384.        // of a node lower down the tree!
  385.  
  386.        // We need something in the element in order for the cursor to appear.
  387.        fixCursor( node, root );
  388.        fixCursor( clone, root );
  389.  
  390.        // Inject clone after original node
  391.        if ( next = node.nextSibling ) {
  392.            parent.insertBefore( clone, next );
  393.        } else {
  394.            parent.appendChild( clone );
  395.        }
  396.  
  397.        // Keep on splitting up the tree
  398.        return split( parent, clone, stopNode, root );
  399.    }
  400.    return offset;
  401. }
  402.  
  403. function _mergeInlines ( node, fakeRange ) {
  404.    var children = node.childNodes,
  405.        l = children.length,
  406.        frags = [],
  407.        child, prev, len;
  408.    while ( l-- ) {
  409.        child = children[l];
  410.        prev = l && children[ l - 1 ];
  411.        if ( l && isInline( child ) && areAlike( child, prev ) &&
  412.                !leafNodeNames[ child.nodeName ] ) {
  413.            if ( fakeRange.startContainer === child ) {
  414.                fakeRange.startContainer = prev;
  415.                fakeRange.startOffset += getLength( prev );
  416.            }
  417.            if ( fakeRange.endContainer === child ) {
  418.                fakeRange.endContainer = prev;
  419.                fakeRange.endOffset += getLength( prev );
  420.            }
  421.            if ( fakeRange.startContainer === node ) {
  422.                if ( fakeRange.startOffset > l ) {
  423.                    fakeRange.startOffset -= 1;
  424.                }
  425.                else if ( fakeRange.startOffset === l ) {
  426.                    fakeRange.startContainer = prev;
  427.                    fakeRange.startOffset = getLength( prev );
  428.                }
  429.            }
  430.            if ( fakeRange.endContainer === node ) {
  431.                if ( fakeRange.endOffset > l ) {
  432.                    fakeRange.endOffset -= 1;
  433.                }
  434.                else if ( fakeRange.endOffset === l ) {
  435.                    fakeRange.endContainer = prev;
  436.                    fakeRange.endOffset = getLength( prev );
  437.                }
  438.            }
  439.            detach( child );
  440.            if ( child.nodeType === TEXT_NODE ) {
  441.                prev.appendData( child.data );
  442.            }
  443.            else {
  444.                frags.push( empty( child ) );
  445.            }
  446.        }
  447.        else if ( child.nodeType === ELEMENT_NODE ) {
  448.            len = frags.length;
  449.            while ( len-- ) {
  450.                child.appendChild( frags.pop() );
  451.            }
  452.            _mergeInlines( child, fakeRange );
  453.        }
  454.    }
  455. }
  456.  
  457. function mergeInlines ( node, range ) {
  458.    if ( node.nodeType === TEXT_NODE ) {
  459.        node = node.parentNode;
  460.    }
  461.    if ( node.nodeType === ELEMENT_NODE ) {
  462.        var fakeRange = {
  463.            startContainer: range.startContainer,
  464.            startOffset: range.startOffset,
  465.            endContainer: range.endContainer,
  466.            endOffset: range.endOffset
  467.        };
  468.        _mergeInlines( node, fakeRange );
  469.        range.setStart( fakeRange.startContainer, fakeRange.startOffset );
  470.        range.setEnd( fakeRange.endContainer, fakeRange.endOffset );
  471.    }
  472. }
  473.  
  474. function mergeWithBlock ( block, next, range ) {
  475.    var container = next,
  476.        last, offset;
  477.    while ( container.parentNode.childNodes.length === 1 ) {
  478.        container = container.parentNode;
  479.    }
  480.    detach( container );
  481.  
  482.    offset = block.childNodes.length;
  483.  
  484.    // Remove extra <BR> fixer if present.
  485.    last = block.lastChild;
  486.    if ( last && last.nodeName === 'BR' ) {
  487.        block.removeChild( last );
  488.        offset -= 1;
  489.    }
  490.  
  491.    block.appendChild( empty( next ) );
  492.  
  493.    range.setStart( block, offset );
  494.    range.collapse( true );
  495.    mergeInlines( block, range );
  496.  
  497.    // Opera inserts a BR if you delete the last piece of text
  498.    // in a block-level element. Unfortunately, it then gets
  499.    // confused when setting the selection subsequently and
  500.    // refuses to accept the range that finishes just before the
  501.    // BR. Removing the BR fixes the bug.
  502.    // Steps to reproduce bug: Type "a-b-c" (where - is return)
  503.    // then backspace twice. The cursor goes to the top instead
  504.    // of after "b".
  505.    if ( isPresto && ( last = block.lastChild ) && last.nodeName === 'BR' ) {
  506.        block.removeChild( last );
  507.    }
  508. }
  509.  
  510. function mergeContainers ( node, root ) {
  511.    var prev = node.previousSibling,
  512.        first = node.firstChild,
  513.        doc = node.ownerDocument,
  514.        isListItem = ( node.nodeName === 'LI' ),
  515.        needsFix, block;
  516.  
  517.    // Do not merge LIs, unless it only contains a UL
  518.    if ( isListItem && ( !first || !/^[OU]L$/.test( first.nodeName ) ) ) {
  519.        return;
  520.    }
  521.  
  522.    if ( prev && areAlike( prev, node ) ) {
  523.        if ( !isContainer( prev ) ) {
  524.            if ( isListItem ) {
  525.                block = createElement( doc, 'DIV' );
  526.                block.appendChild( empty( prev ) );
  527.                prev.appendChild( block );
  528.            } else {
  529.                return;
  530.            }
  531.        }
  532.        detach( node );
  533.        needsFix = !isContainer( node );
  534.        prev.appendChild( empty( node ) );
  535.        if ( needsFix ) {
  536.            fixContainer( prev, root );
  537.        }
  538.        if ( first ) {
  539.            mergeContainers( first, root );
  540.        }
  541.    } else if ( isListItem ) {
  542.        prev = createElement( doc, 'DIV' );
  543.        node.insertBefore( prev, first );
  544.        fixCursor( prev, root );
  545.    }
  546. }
  547.  
downloadNode.js Source code - Download Squire Source code
Related Source Codes/Software:
thor - Thor is a toolkit for building powerful command-li... 2017-01-08
glide - Package Management for Golang h... 2017-01-08
TextFieldEffects - Custom UITextFields effects inspired by Codrops, b... 2017-01-08
flowchart.js - Draws simple SVG flow chart diagrams from textual ... 2017-01-08
RoundedImageView - A fast ImageView that supports rounded corners, ov... 2017-01-07
webpack-demos - a collection of simple demos of Webpack 2017-01-08
amazon-dsstne - Deep Scalable Sparse Tensor Network Engine (DSSTNE... 2017-01-08
rq - Simple job queues for Python ht... 2017-01-08
emmet-vim - emmet for vim: http://emmet.io/ ... 2017-01-08
prose - A Content Editor for GitHub. ht... 2017-01-08
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top