etc. at the beginning of the split
- // make sure we focus inside it.
- while ( nodeAfterSplit.nodeType === ELEMENT_NODE ) {
- var child = nodeAfterSplit.firstChild,
- next;
-
- // Don't continue links over a block break; unlikely to be the
- // desired outcome.
- if ( nodeAfterSplit.nodeName === 'A' ) {
- replaceWith( nodeAfterSplit, empty( nodeAfterSplit ) );
- nodeAfterSplit = child;
- continue;
- }
-
- while ( child && child.nodeType === TEXT_NODE && !child.data ) {
- next = child.nextSibling;
- if ( !next || next.nodeName === 'BR' ) {
- break;
- }
- detach( child );
- child = next;
- }
-
- // 'BR's essentially don't count; they're a browser hack.
- // If you try to select the contents of a 'BR', FF will not let
- // you type anything!
- if ( !child || child.nodeName === 'BR' ||
- ( child.nodeType === TEXT_NODE && !isOpera ) ) {
- break;
- }
- nodeAfterSplit = child;
- }
- range = self._createRange( nodeAfterSplit, 0 );
- self.setSelection( range );
- self._updatePath( range, true );
-
- // Scroll into view
- if ( nodeAfterSplit.nodeType === TEXT_NODE ) {
- nodeAfterSplit = nodeAfterSplit.parentNode;
- }
- var doc = self._doc,
- body = self._body;
- if ( nodeAfterSplit.offsetTop + nodeAfterSplit.offsetHeight >
- ( doc.documentElement.scrollTop || body.scrollTop ) +
- body.offsetHeight ) {
- nodeAfterSplit.scrollIntoView( false );
- }
-
- // We're not still in an undo state
- self._docWasChanged();
- },
- backspace: function ( self, event ) {
- var range = self.getSelection();
- // If not collapsed, delete contents
- if ( !range.collapsed ) {
- self._recordUndoState( range );
- self._getRangeAndRemoveBookmark( range );
- event.preventDefault();
- deleteContentsOfRange( range );
- self._ensureBottomLine();
- self.setSelection( range );
- self._updatePath( range, true );
- }
- // If at beginning of block, merge with previous
- else if ( rangeDoesStartAtBlockBoundary( range ) ) {
- self._recordUndoState( range );
- self._getRangeAndRemoveBookmark( range );
- event.preventDefault();
- var current = getStartBlockOfRange( range ),
- previous = current && getPreviousBlock( current );
- // Must not be at the very beginning of the text area.
- if ( previous ) {
- // If not editable, just delete whole block.
- if ( !previous.isContentEditable ) {
- detach( previous );
- return;
- }
- // Otherwise merge.
- mergeWithBlock( previous, current, range );
- // If deleted line between containers, merge newly adjacent
- // containers.
- current = previous.parentNode;
- while ( current && !current.nextSibling ) {
- current = current.parentNode;
- }
- if ( current && ( current = current.nextSibling ) ) {
- mergeContainers( current );
- }
- self.setSelection( range );
- }
- // If at very beginning of text area, allow backspace
- // to break lists/blockquote.
- else if ( current ) {
- // Break list
- if ( getNearest( current, 'UL' ) ||
- getNearest( current, 'OL' ) ) {
- return self.modifyBlocks( decreaseListLevel, range );
- }
- // Break blockquote
- else if ( getNearest( current, 'BLOCKQUOTE' ) ) {
- return self.modifyBlocks( decreaseBlockQuoteLevel, range );
- }
- self.setSelection( range );
- self._updatePath( range, true );
- }
- }
- // Otherwise, leave to browser but check afterwards whether it has
- // left behind an empty inline tag.
- else {
- var text = range.startContainer.data || '';
- if ( !notWS.test( text.charAt( range.startOffset - 1 ) ) ) {
- self._recordUndoState( range );
- self._getRangeAndRemoveBookmark( range );
- self.setSelection( range );
- }
- setTimeout( function () { afterDelete( self ); }, 0 );
- }
- },
- 'delete': function ( self, event ) {
- var range = self.getSelection();
- // If not collapsed, delete contents
- if ( !range.collapsed ) {
- self._recordUndoState( range );
- self._getRangeAndRemoveBookmark( range );
- event.preventDefault();
- deleteContentsOfRange( range );
- self._ensureBottomLine();
- self.setSelection( range );
- self._updatePath( range, true );
- }
- // If at end of block, merge next into this block
- else if ( rangeDoesEndAtBlockBoundary( range ) ) {
- self._recordUndoState( range );
- self._getRangeAndRemoveBookmark( range );
- event.preventDefault();
- var current = getStartBlockOfRange( range ),
- next = current && getNextBlock( current );
- // Must not be at the very end of the text area.
- if ( next ) {
- // If not editable, just delete whole block.
- if ( !next.isContentEditable ) {
- detach( next );
- return;
- }
- // Otherwise merge.
- mergeWithBlock( current, next, range );
- // If deleted line between containers, merge newly adjacent
- // containers.
- next = current.parentNode;
- while ( next && !next.nextSibling ) {
- next = next.parentNode;
- }
- if ( next && ( next = next.nextSibling ) ) {
- mergeContainers( next );
- }
- self.setSelection( range );
- self._updatePath( range, true );
- }
- }
- // Otherwise, leave to browser but check afterwards whether it has
- // left behind an empty inline tag.
- else {
- // Record undo point if deleting whitespace
- var text = range.startContainer.data || '';
- if ( !notWS.test( text.charAt( range.startOffset ) ) ) {
- self._recordUndoState( range );
- self._getRangeAndRemoveBookmark( range );
- self.setSelection( range );
- }
- setTimeout( function () { afterDelete( self ); }, 0 );
- }
- },
- tab: function ( self, event ) {
- var range = self.getSelection(),
- node, parent;
- // If no selection and in an empty block
- if ( range.collapsed &&
- rangeDoesStartAtBlockBoundary( range ) &&
- rangeDoesEndAtBlockBoundary( range ) ) {
- node = getStartBlockOfRange( range );
- // Iterate through the block's parents
- while ( parent = node.parentNode ) {
- // If we find a UL or OL (so are in a list, node must be an LI)
- if ( parent.nodeName === 'UL' || parent.nodeName === 'OL' ) {
- // AND the LI is not the first in the list
- if ( node.previousSibling ) {
- // Then increase the list level
- event.preventDefault();
- self.modifyBlocks( increaseListLevel, range );
- }
- break;
- }
- node = parent;
- }
- event.preventDefault();
- }
- },
- space: function ( self ) {
- var range = self.getSelection();
- self._recordUndoState( range );
- addLinks( range.startContainer );
- self._getRangeAndRemoveBookmark( range );
- self.setSelection( range );
- },
- left: function ( self ) {
- self._removeZWS();
- },
- right: function ( self ) {
- self._removeZWS();
- }
-};
-// Firefox incorrectly handles Cmd-left/Cmd-right on Mac:
-// it goes back/forward in history! Override to do the right
-// thing.
-// https://bugzilla.mozilla.org/show_bug.cgi?id=289384
-if ( isMac && isGecko && win.getSelection().modify ) {
- keyHandlers[ 'meta-left' ] = function ( self, event ) {
- event.preventDefault();
- self._win.getSelection().modify( 'move', 'backward', 'lineboundary' );
- };
- keyHandlers[ 'meta-right' ] = function ( self, event ) {
- event.preventDefault();
- self._win.getSelection().modify( 'move', 'forward', 'lineboundary' );
- };
-}
-
-keyHandlers[ ctrlKey + 'b' ] = mapKeyToFormat( 'B' );
-keyHandlers[ ctrlKey + 'i' ] = mapKeyToFormat( 'I' );
-keyHandlers[ ctrlKey + 'u' ] = mapKeyToFormat( 'U' );
-keyHandlers[ ctrlKey + 'shift-7' ] = mapKeyToFormat( 'S' );
-keyHandlers[ ctrlKey + 'shift-5' ] = mapKeyToFormat( 'SUB', { tag: 'SUP' } );
-keyHandlers[ ctrlKey + 'shift-6' ] = mapKeyToFormat( 'SUP', { tag: 'SUB' } );
-keyHandlers[ ctrlKey + 'shift-8' ] = mapKeyTo( 'makeUnorderedList' );
-keyHandlers[ ctrlKey + 'shift-9' ] = mapKeyTo( 'makeOrderedList' );
-keyHandlers[ ctrlKey + '[' ] = mapKeyTo( 'decreaseQuoteLevel' );
-keyHandlers[ ctrlKey + ']' ] = mapKeyTo( 'increaseQuoteLevel' );
-keyHandlers[ ctrlKey + 'y' ] = mapKeyTo( 'redo' );
-keyHandlers[ ctrlKey + 'z' ] = mapKeyTo( 'undo' );
-keyHandlers[ ctrlKey + 'shift-z' ] = mapKeyTo( 'redo' );
-
-// Ref: http://unixpapa.com/js/key.html
-proto._onKey = function ( event ) {
- var code = event.keyCode,
- key = keys[ code ],
- modifiers = '';
-
- if ( !key ) {
- key = String.fromCharCode( code ).toLowerCase();
- // Only reliable for letters and numbers
- if ( !/^[A-Za-z0-9]$/.test( key ) ) {
- key = '';
- }
- }
-
- // On keypress, delete and '.' both have event.keyCode 46
- // Must check event.which to differentiate.
- if ( isOpera && event.which === 46 ) {
- key = '.';
- }
-
- // Function keys
- if ( 111 < code && code < 124 ) {
- key = 'f' + ( code - 111 );
- }
-
- if ( event.altKey ) { modifiers += 'alt-'; }
- if ( event.ctrlKey ) { modifiers += 'ctrl-'; }
- if ( event.metaKey ) { modifiers += 'meta-'; }
- if ( event.shiftKey ) { modifiers += 'shift-'; }
-
- key = modifiers + key;
-
- if ( keyHandlers[ key ] ) {
- keyHandlers[ key ]( this, event );
- }
-};
-
-// --- Get/Set data ---
-
-proto._getHTML = function () {
- return this._body.innerHTML;
-};
-
-proto._setHTML = function ( html ) {
- var node = this._body;
- node.innerHTML = html;
- do {
- fixCursor( node );
- } while ( node = getNextBlock( node ) );
-};
-
-proto.getHTML = function ( withBookMark ) {
- var brs = [],
- node, fixer, html, l, range;
- if ( withBookMark && ( range = this.getSelection() ) ) {
- this._saveRangeToBookmark( range );
- }
- if ( useTextFixer ) {
- node = this._body;
- while ( node = getNextBlock( node ) ) {
- if ( !node.textContent && !node.querySelector( 'BR' ) ) {
- fixer = this.createElement( 'BR' );
- node.appendChild( fixer );
- brs.push( fixer );
- }
- }
- }
- html = this._getHTML().replace( /\u200B/g, '' );
- if ( useTextFixer ) {
- l = brs.length;
- while ( l-- ) {
- detach( brs[l] );
- }
- }
- if ( range ) {
- this._getRangeAndRemoveBookmark( range );
- }
- return html;
-};
-
-proto.setHTML = function ( html ) {
- var frag = this._doc.createDocumentFragment(),
- div = this.createElement( 'DIV' ),
- child;
-
- // Parse HTML into DOM tree
- div.innerHTML = html;
- frag.appendChild( empty( div ) );
-
- cleanTree( frag, true );
- cleanupBRs( frag );
-
- fixContainer( frag );
-
- // Fix cursor
- var node = frag;
- while ( node = getNextBlock( node ) ) {
- fixCursor( node );
- }
-
- // Remove existing body children
- var body = this._body;
- while ( child = body.lastChild ) {
- body.removeChild( child );
- }
-
- // And insert new content
- body.appendChild( frag );
- fixCursor( body );
-
- // Reset the undo stack
- this._undoIndex = -1;
- this._undoStack.length = 0;
- this._undoStackLength = 0;
- this._isInUndoState = false;
-
- // Record undo state
- var range = this._getRangeAndRemoveBookmark() ||
- this._createRange( body.firstChild, 0 );
- this._recordUndoState( range );
- this._getRangeAndRemoveBookmark( range );
- // IE will also set focus when selecting text so don't use
- // setSelection. Instead, just store it in lastSelection, so if
- // anything calls getSelection before first focus, we have a range
- // to return.
- if ( losesSelectionOnBlur ) {
- this._lastSelection = range;
- } else {
- this.setSelection( range );
- }
- this._updatePath( range, true );
-
- return this;
-};
-
-proto.insertElement = function ( el, range ) {
- if ( !range ) { range = this.getSelection(); }
- range.collapse( true );
- if ( isInline( el ) ) {
- insertNodeInRange( range, el );
- range.setStartAfter( el );
- } else {
- // Get containing block node.
- var body = this._body,
- splitNode = getStartBlockOfRange( range ) || body,
- parent, nodeAfterSplit;
- // While at end of container node, move up DOM tree.
- while ( splitNode !== body && !splitNode.nextSibling ) {
- splitNode = splitNode.parentNode;
- }
- // If in the middle of a container node, split up to body.
- if ( splitNode !== body ) {
- parent = splitNode.parentNode;
- nodeAfterSplit = split( parent, splitNode.nextSibling, body );
- }
- if ( nodeAfterSplit ) {
- body.insertBefore( el, nodeAfterSplit );
- range.setStart( nodeAfterSplit, 0 );
- range.setStart( nodeAfterSplit, 0 );
- moveRangeBoundariesDownTree( range );
- } else {
- body.appendChild( el );
- // Insert blank line below block.
- body.appendChild( this.createDefaultBlock() );
- range.setStart( el, 0 );
- range.setEnd( el, 0 );
- }
- this.focus();
- this.setSelection( range );
- this._updatePath( range );
- }
- return this;
-};
-
-proto.insertImage = function ( src ) {
- var img = this.createElement( 'IMG', {
- src: src
- });
- this.insertElement( img );
- return img;
-};
-
-// --- Formatting ---
-
-var command = function ( method, arg, arg2 ) {
- return function () {
- this[ method ]( arg, arg2 );
- return this.focus();
- };
-};
-
-proto.addStyles = function ( styles ) {
- if ( styles ) {
- var head = this._doc.documentElement.firstChild,
- style = this.createElement( 'STYLE', {
- type: 'text/css'
- });
- if ( style.styleSheet ) {
- // IE8: must append to document BEFORE adding styles
- // or you get the IE7 CSS parser!
- head.appendChild( style );
- style.styleSheet.cssText = styles;
- } else {
- // Everyone else
- style.appendChild( this._doc.createTextNode( styles ) );
- head.appendChild( style );
- }
- }
- return this;
-};
-
-proto.bold = command( 'changeFormat', { tag: 'B' } );
-proto.italic = command( 'changeFormat', { tag: 'I' } );
-proto.underline = command( 'changeFormat', { tag: 'U' } );
-proto.strikethrough = command( 'changeFormat', { tag: 'S' } );
-proto.subscript = command( 'changeFormat', { tag: 'SUB' }, { tag: 'SUP' } );
-proto.superscript = command( 'changeFormat', { tag: 'SUP' }, { tag: 'SUB' } );
-
-proto.removeBold = command( 'changeFormat', null, { tag: 'B' } );
-proto.removeItalic = command( 'changeFormat', null, { tag: 'I' } );
-proto.removeUnderline = command( 'changeFormat', null, { tag: 'U' } );
-proto.removeStrikethrough = command( 'changeFormat', null, { tag: 'S' } );
-proto.removeSubscript = command( 'changeFormat', null, { tag: 'SUB' } );
-proto.removeSuperscript = command( 'changeFormat', null, { tag: 'SUP' } );
-
-proto.makeLink = function ( url ) {
- var range = this.getSelection();
- if ( range.collapsed ) {
- var protocolEnd = url.indexOf( ':' ) + 1;
- if ( protocolEnd ) {
- while ( url[ protocolEnd ] === '/' ) { protocolEnd += 1; }
- }
- insertNodeInRange(
- range,
- this._doc.createTextNode( url.slice( protocolEnd ) )
- );
- }
- this.changeFormat({
- tag: 'A',
- attributes: {
- href: url
- }
- }, {
- tag: 'A'
- }, range );
- return this.focus();
-};
-proto.removeLink = function () {
- this.changeFormat( null, {
- tag: 'A'
- }, this.getSelection(), true );
- return this.focus();
-};
-
-proto.setFontFace = function ( name ) {
- this.changeFormat({
- tag: 'SPAN',
- attributes: {
- 'class': 'font',
- style: 'font-family: ' + name + ', sans-serif;'
- }
- }, {
- tag: 'SPAN',
- attributes: { 'class': 'font' }
- });
- return this.focus();
-};
-proto.setFontSize = function ( size ) {
- this.changeFormat({
- tag: 'SPAN',
- attributes: {
- 'class': 'size',
- style: 'font-size: ' +
- ( typeof size === 'number' ? size + 'px' : size )
- }
- }, {
- tag: 'SPAN',
- attributes: { 'class': 'size' }
- });
- return this.focus();
-};
-
-proto.setTextColour = function ( colour ) {
- this.changeFormat({
- tag: 'SPAN',
- attributes: {
- 'class': 'colour',
- style: 'color: ' + colour
- }
- }, {
- tag: 'SPAN',
- attributes: { 'class': 'colour' }
- });
- return this.focus();
-};
-
-proto.setHighlightColour = function ( colour ) {
- this.changeFormat({
- tag: 'SPAN',
- attributes: {
- 'class': 'highlight',
- style: 'background-color: ' + colour
- }
- }, {
- tag: 'SPAN',
- attributes: { 'class': 'highlight' }
- });
- return this.focus();
-};
-
-proto.setTextAlignment = function ( alignment ) {
- this.forEachBlock( function ( block ) {
- block.className = ( block.className
- .split( /\s+/ )
- .filter( function ( klass ) {
- return !( /align/.test( klass ) );
- })
- .join( ' ' ) +
- ' align-' + alignment ).trim();
- block.style.textAlign = alignment;
- }, true );
- return this.focus();
-};
-
-proto.setTextDirection = function ( direction ) {
- this.forEachBlock( function ( block ) {
- block.className = ( block.className
- .split( /\s+/ )
- .filter( function ( klass ) {
- return !( /dir/.test( klass ) );
- })
- .join( ' ' ) +
- ' dir-' + direction ).trim();
- block.dir = direction;
- }, true );
- return this.focus();
-};
-
-proto.increaseQuoteLevel = command( 'modifyBlocks', increaseBlockQuoteLevel );
-proto.decreaseQuoteLevel = command( 'modifyBlocks', decreaseBlockQuoteLevel );
-
-proto.makeUnorderedList = command( 'modifyBlocks', makeUnorderedList );
-proto.makeOrderedList = command( 'modifyBlocks', makeOrderedList );
-proto.removeList = command( 'modifyBlocks', removeList );
-
-proto.increaseListLevel = command( 'modifyBlocks', increaseListLevel );
-proto.decreaseListLevel = command( 'modifyBlocks', decreaseListLevel );
diff --git a/source/Node.js b/source/Node.js
deleted file mode 100644
index ebca6e2..0000000
--- a/source/Node.js
+++ /dev/null
@@ -1,460 +0,0 @@
-/*global
- ELEMENT_NODE,
- TEXT_NODE,
- SHOW_ELEMENT,
- FILTER_ACCEPT,
- FILTER_SKIP,
- win,
- isOpera,
- useTextFixer,
- cantFocusEmptyTextNodes,
-
- TreeWalker,
-
- Text
-*/
-/*jshint strict:false */
-
-var inlineNodeNames = /^(?:#text|A(?:BBR|CRONYM)?|B(?:R|D[IO])?|C(?:ITE|ODE)|D(?:ATA|FN|EL)|EM|FONT|HR|I(?:NPUT|MG|NS)?|KBD|Q|R(?:P|T|UBY)|S(?:U[BP]|PAN|TR(?:IKE|ONG)|MALL|AMP)?|U|VAR|WBR)$/;
-
-var leafNodeNames = {
- BR: 1,
- IMG: 1,
- INPUT: 1
-};
-
-function every ( nodeList, fn ) {
- var l = nodeList.length;
- while ( l-- ) {
- if ( !fn( nodeList[l] ) ) {
- return false;
- }
- }
- return true;
-}
-
-// ---
-
-function hasTagAttributes ( node, tag, attributes ) {
- if ( node.nodeName !== tag ) {
- return false;
- }
- for ( var attr in attributes ) {
- if ( node.getAttribute( attr ) !== attributes[ attr ] ) {
- return false;
- }
- }
- return true;
-}
-function areAlike ( node, node2 ) {
- return (
- node.nodeType === node2.nodeType &&
- node.nodeName === node2.nodeName &&
- node.className === node2.className &&
- ( ( !node.style && !node2.style ) ||
- node.style.cssText === node2.style.cssText )
- );
-}
-
-function isLeaf ( node ) {
- return node.nodeType === ELEMENT_NODE &&
- !!leafNodeNames[ node.nodeName ];
-}
-function isInline ( node ) {
- return inlineNodeNames.test( node.nodeName );
-}
-function isBlock ( node ) {
- return node.nodeType === ELEMENT_NODE &&
- !isInline( node ) && every( node.childNodes, isInline );
-}
-function isContainer ( node ) {
- return node.nodeType === ELEMENT_NODE &&
- !isInline( node ) && !isBlock( node );
-}
-
-function acceptIfBlock ( el ) {
- return isBlock( el ) ? FILTER_ACCEPT : FILTER_SKIP;
-}
-function getBlockWalker ( node ) {
- var doc = node.ownerDocument,
- walker = new TreeWalker(
- doc.body, SHOW_ELEMENT, acceptIfBlock, false );
- walker.currentNode = node;
- return walker;
-}
-
-function getPreviousBlock ( node ) {
- return getBlockWalker( node ).previousNode();
-}
-function getNextBlock ( node ) {
- return getBlockWalker( node ).nextNode();
-}
-function getNearest ( node, tag, attributes ) {
- do {
- if ( hasTagAttributes( node, tag, attributes ) ) {
- return node;
- }
- } while ( node = node.parentNode );
- return null;
-}
-
-function getPath ( node ) {
- var parent = node.parentNode,
- path, id, className, classNames;
- if ( !parent || node.nodeType !== ELEMENT_NODE ) {
- path = parent ? getPath( parent ) : '';
- } else {
- path = getPath( parent );
- path += ( path ? '>' : '' ) + node.nodeName;
- if ( id = node.id ) {
- path += '#' + id;
- }
- if ( className = node.className.trim() ) {
- classNames = className.split( /\s\s*/ );
- classNames.sort();
- path += '.';
- path += classNames.join( '.' );
- }
- }
- return path;
-}
-
-function getLength ( node ) {
- var nodeType = node.nodeType;
- return nodeType === ELEMENT_NODE ?
- node.childNodes.length : node.length || 0;
-}
-
-function detach ( node ) {
- var parent = node.parentNode;
- if ( parent ) {
- parent.removeChild( node );
- }
- return node;
-}
-function replaceWith ( node, node2 ) {
- var parent = node.parentNode;
- if ( parent ) {
- parent.replaceChild( node2, node );
- }
-}
-function empty ( node ) {
- var frag = node.ownerDocument.createDocumentFragment(),
- childNodes = node.childNodes,
- l = childNodes ? childNodes.length : 0;
- while ( l-- ) {
- frag.appendChild( node.firstChild );
- }
- return frag;
-}
-
-function fixCursor ( node ) {
- // In Webkit and Gecko, block level elements are collapsed and
- // unfocussable if they have no content. To remedy this, a
must be
- // inserted. In Opera and IE, we just need a textnode in order for the
- // cursor to appear.
- var doc = node.ownerDocument,
- root = node,
- fixer, child;
-
- if ( node.nodeName === 'BODY' ) {
- if ( !( child = node.firstChild ) || child.nodeName === 'BR' ) {
- fixer = doc.createElement( 'DIV' );
- if ( child ) {
- node.replaceChild( fixer, child );
- }
- else {
- node.appendChild( fixer );
- }
- node = fixer;
- fixer = null;
- }
- }
-
- if ( isInline( node ) ) {
- if ( !node.firstChild ) {
- if ( cantFocusEmptyTextNodes ) {
- fixer = doc.createTextNode( '\u200B' );
- if ( win.editor ) {
- win.editor._didAddZWS();
- }
- } else {
- fixer = doc.createTextNode( '' );
- }
- }
- } else {
- if ( useTextFixer ) {
- while ( node.nodeType !== TEXT_NODE && !isLeaf( node ) ) {
- child = node.firstChild;
- if ( !child ) {
- fixer = doc.createTextNode( '' );
- break;
- }
- node = child;
- }
- if ( node.nodeType === TEXT_NODE ) {
- // Opera will collapse the block element if it contains
- // just spaces (but not if it contains no data at all).
- if ( /^ +$/.test( node.data ) ) {
- node.data = '';
- }
- } else if ( isLeaf( node ) ) {
- node.parentNode.insertBefore( doc.createTextNode( '' ), node );
- }
- }
- else if ( !node.querySelector( 'BR' ) ) {
- fixer = doc.createElement( 'BR' );
- while ( ( child = node.lastElementChild ) && !isInline( child ) ) {
- node = child;
- }
- }
- }
- if ( fixer ) {
- node.appendChild( fixer );
- }
-
- return root;
-}
-
-function split ( node, offset, stopNode ) {
- var nodeType = node.nodeType,
- parent, clone, next;
- if ( nodeType === TEXT_NODE && node !== stopNode ) {
- return split( node.parentNode, node.splitText( offset ), stopNode );
- }
- if ( nodeType === ELEMENT_NODE ) {
- if ( typeof( offset ) === 'number' ) {
- offset = offset < node.childNodes.length ?
- node.childNodes[ offset ] : null;
- }
- if ( node === stopNode ) {
- return offset;
- }
-
- // Clone node without children
- parent = node.parentNode;
- clone = node.cloneNode( false );
-
- // Add right-hand siblings to the clone
- while ( offset ) {
- next = offset.nextSibling;
- clone.appendChild( offset );
- offset = next;
- }
-
- // DO NOT NORMALISE. This may undo the fixCursor() call
- // of a node lower down the tree!
-
- // We need something in the element in order for the cursor to appear.
- fixCursor( node );
- fixCursor( clone );
-
- // Inject clone after original node
- if ( next = node.nextSibling ) {
- parent.insertBefore( clone, next );
- } else {
- parent.appendChild( clone );
- }
-
- // Keep on splitting up the tree
- return split( parent, clone, stopNode );
- }
- return offset;
-}
-
-function mergeInlines ( node, range ) {
- if ( node.nodeType !== ELEMENT_NODE ) {
- return;
- }
- var children = node.childNodes,
- l = children.length,
- frags = [],
- child, prev, len;
- while ( l-- ) {
- child = children[l];
- prev = l && children[ l - 1 ];
- if ( l && isInline( child ) && areAlike( child, prev ) &&
- !leafNodeNames[ child.nodeName ] ) {
- if ( range.startContainer === child ) {
- range.startContainer = prev;
- range.startOffset += getLength( prev );
- }
- if ( range.endContainer === child ) {
- range.endContainer = prev;
- range.endOffset += getLength( prev );
- }
- if ( range.startContainer === node ) {
- if ( range.startOffset > l ) {
- range.startOffset -= 1;
- }
- else if ( range.startOffset === l ) {
- range.startContainer = prev;
- range.startOffset = getLength( prev );
- }
- }
- if ( range.endContainer === node ) {
- if ( range.endOffset > l ) {
- range.endOffset -= 1;
- }
- else if ( range.endOffset === l ) {
- range.endContainer = prev;
- range.endOffset = getLength( prev );
- }
- }
- detach( child );
- if ( child.nodeType === TEXT_NODE ) {
- prev.appendData( child.data );
- }
- else {
- frags.push( empty( child ) );
- }
- }
- else if ( child.nodeType === ELEMENT_NODE ) {
- len = frags.length;
- while ( len-- ) {
- child.appendChild( frags.pop() );
- }
- mergeInlines( child, range );
- }
- }
-}
-
-function mergeWithBlock ( block, next, range ) {
- var container = next,
- last, offset, _range;
- while ( container.parentNode.childNodes.length === 1 ) {
- container = container.parentNode;
- }
- detach( container );
-
- offset = block.childNodes.length;
-
- // Remove extra
fixer if present.
- last = block.lastChild;
- if ( last && last.nodeName === 'BR' ) {
- block.removeChild( last );
- offset -= 1;
- }
-
- _range = {
- startContainer: block,
- startOffset: offset,
- endContainer: block,
- endOffset: offset
- };
-
- block.appendChild( empty( next ) );
- mergeInlines( block, _range );
-
- range.setStart( _range.startContainer, _range.startOffset );
- range.collapse( true );
-
- // Opera inserts a BR if you delete the last piece of text
- // in a block-level element. Unfortunately, it then gets
- // confused when setting the selection subsequently and
- // refuses to accept the range that finishes just before the
- // BR. Removing the BR fixes the bug.
- // Steps to reproduce bug: Type "a-b-c" (where - is return)
- // then backspace twice. The cursor goes to the top instead
- // of after "b".
- if ( isOpera && ( last = block.lastChild ) && last.nodeName === 'BR' ) {
- block.removeChild( last );
- }
-}
-
-function mergeContainers ( node ) {
- var prev = node.previousSibling,
- first = node.firstChild,
- doc = node.ownerDocument,
- isListItem = ( node.nodeName === 'LI' ),
- needsFix, block;
-
- // Do not merge LIs, unless it only contains a UL
- if ( isListItem && ( !first || !/^[OU]L$/.test( first.nodeName ) ) ) {
- return;
- }
-
- if ( prev && areAlike( prev, node ) ) {
- if ( !isContainer( prev ) ) {
- if ( isListItem ) {
- block = doc.createElement( 'DIV' );
- block.appendChild( empty( prev ) );
- prev.appendChild( block );
- } else {
- return;
- }
- }
- detach( node );
- needsFix = !isContainer( node );
- prev.appendChild( empty( node ) );
- if ( needsFix ) {
- fixContainer( prev );
- }
- if ( first ) {
- mergeContainers( first );
- }
- } else if ( isListItem ) {
- prev = doc.createElement( 'DIV' );
- node.insertBefore( prev, first );
- fixCursor( prev );
- }
-}
-
-// Recursively examine container nodes and wrap any inline children.
-function fixContainer ( container ) {
- var children = container.childNodes,
- doc = container.ownerDocument,
- wrapper = null,
- i, l, child, isBR;
- for ( i = 0, l = children.length; i < l; i += 1 ) {
- child = children[i];
- isBR = child.nodeName === 'BR';
- if ( !isBR && isInline( child ) ) {
- if ( !wrapper ) { wrapper = createElement( doc, 'DIV' ); }
- wrapper.appendChild( child );
- i -= 1;
- l -= 1;
- } else if ( isBR || wrapper ) {
- if ( !wrapper ) { wrapper = createElement( doc, 'DIV' ); }
- fixCursor( wrapper );
- if ( isBR ) {
- container.replaceChild( wrapper, child );
- } else {
- container.insertBefore( wrapper, child );
- i += 1;
- l += 1;
- }
- wrapper = null;
- }
- if ( isContainer( child ) ) {
- fixContainer( child );
- }
- }
- if ( wrapper ) {
- container.appendChild( fixCursor( wrapper ) );
- }
- return container;
-}
-
-function createElement ( doc, tag, props, children ) {
- var el = doc.createElement( tag ),
- attr, value, i, l;
- if ( props instanceof Array ) {
- children = props;
- props = null;
- }
- if ( props ) {
- for ( attr in props ) {
- value = props[ attr ];
- if ( value !== undefined ) {
- el.setAttribute( attr, props[ attr ] );
- }
- }
- }
- if ( children ) {
- for ( i = 0, l = children.length; i < l; i += 1 ) {
- el.appendChild( children[i] );
- }
- }
- return el;
-}
diff --git a/source/Range.js b/source/Range.js
deleted file mode 100644
index 3efdde1..0000000
--- a/source/Range.js
+++ /dev/null
@@ -1,511 +0,0 @@
-/*global
- ELEMENT_NODE,
- TEXT_NODE,
- SHOW_TEXT,
- FILTER_ACCEPT,
- START_TO_START,
- START_TO_END,
- END_TO_END,
- END_TO_START,
- indexOf,
-
- TreeWalker,
-
- isLeaf,
- isInline,
- isBlock,
- getPreviousBlock,
- getNextBlock,
- getLength,
- fixCursor,
- split,
- mergeWithBlock,
- mergeContainers
-*/
-/*jshint strict:false */
-
-var getNodeBefore = function ( node, offset ) {
- var children = node.childNodes;
- while ( offset && node.nodeType === ELEMENT_NODE ) {
- node = children[ offset - 1 ];
- children = node.childNodes;
- offset = children.length;
- }
- return node;
-};
-
-var getNodeAfter = function ( node, offset ) {
- if ( node.nodeType === ELEMENT_NODE ) {
- var children = node.childNodes;
- if ( offset < children.length ) {
- node = children[ offset ];
- } else {
- while ( node && !node.nextSibling ) {
- node = node.parentNode;
- }
- if ( node ) { node = node.nextSibling; }
- }
- }
- return node;
-};
-
-// ---
-
-var forEachTextNodeInRange = function ( range, fn ) {
- range = range.cloneRange();
- moveRangeBoundariesDownTree( range );
-
- var startContainer = range.startContainer,
- endContainer = range.endContainer,
- root = range.commonAncestorContainer,
- walker = new TreeWalker(
- root, SHOW_TEXT, function ( node ) {
- return FILTER_ACCEPT;
- }, false ),
- textnode = walker.currentNode = startContainer;
-
- while ( !fn( textnode, range ) &&
- textnode !== endContainer &&
- ( textnode = walker.nextNode() ) ) {}
-};
-
-var getTextContentInRange = function ( range ) {
- var textContent = '';
- forEachTextNodeInRange( range, function ( textnode, range ) {
- var value = textnode.data;
- if ( value && ( /\S/.test( value ) ) ) {
- if ( textnode === range.endContainer ) {
- value = value.slice( 0, range.endOffset );
- }
- if ( textnode === range.startContainer ) {
- value = value.slice( range.startOffset );
- }
- textContent += value;
- }
- });
- return textContent;
-};
-
-// ---
-
-var insertNodeInRange = function ( range, node ) {
- // Insert at start.
- var startContainer = range.startContainer,
- startOffset = range.startOffset,
- endContainer = range.endContainer,
- endOffset = range.endOffset,
- parent, children, childCount, afterSplit;
-
- // If part way through a text node, split it.
- if ( startContainer.nodeType === TEXT_NODE ) {
- parent = startContainer.parentNode;
- children = parent.childNodes;
- if ( startOffset === startContainer.length ) {
- startOffset = indexOf.call( children, startContainer ) + 1;
- if ( range.collapsed ) {
- endContainer = parent;
- endOffset = startOffset;
- }
- } else {
- if ( startOffset ) {
- afterSplit = startContainer.splitText( startOffset );
- if ( endContainer === startContainer ) {
- endOffset -= startOffset;
- endContainer = afterSplit;
- }
- else if ( endContainer === parent ) {
- endOffset += 1;
- }
- startContainer = afterSplit;
- }
- startOffset = indexOf.call( children, startContainer );
- }
- startContainer = parent;
- } else {
- children = startContainer.childNodes;
- }
-
- childCount = children.length;
-
- if ( startOffset === childCount) {
- startContainer.appendChild( node );
- } else {
- startContainer.insertBefore( node, children[ startOffset ] );
- }
- if ( startContainer === endContainer ) {
- endOffset += children.length - childCount;
- }
-
- range.setStart( startContainer, startOffset );
- range.setEnd( endContainer, endOffset );
-};
-
-var extractContentsOfRange = function ( range, common ) {
- var startContainer = range.startContainer,
- startOffset = range.startOffset,
- endContainer = range.endContainer,
- endOffset = range.endOffset;
-
- if ( !common ) {
- common = range.commonAncestorContainer;
- }
-
- if ( common.nodeType === TEXT_NODE ) {
- common = common.parentNode;
- }
-
- var endNode = split( endContainer, endOffset, common ),
- startNode = split( startContainer, startOffset, common ),
- frag = common.ownerDocument.createDocumentFragment(),
- next;
-
- // End node will be null if at end of child nodes list.
- while ( startNode !== endNode ) {
- next = startNode.nextSibling;
- frag.appendChild( startNode );
- startNode = next;
- }
-
- range.setStart( common, endNode ?
- indexOf.call( common.childNodes, endNode ) :
- common.childNodes.length );
- range.collapse( true );
-
- fixCursor( common );
-
- return frag;
-};
-
-var deleteContentsOfRange = function ( range ) {
- // Move boundaries up as much as possible to reduce need to split.
- moveRangeBoundariesUpTree( range );
-
- // Remove selected range
- extractContentsOfRange( range );
-
- // If we split into two different blocks, merge the blocks.
- var startBlock = getStartBlockOfRange( range ),
- endBlock = getEndBlockOfRange( range );
- if ( startBlock && endBlock && startBlock !== endBlock ) {
- mergeWithBlock( startBlock, endBlock, range );
- }
-
- // Ensure block has necessary children
- if ( startBlock ) {
- fixCursor( startBlock );
- }
-
- // Ensure body has a block-level element in it.
- var body = range.endContainer.ownerDocument.body,
- child = body.firstChild;
- if ( !child || child.nodeName === 'BR' ) {
- fixCursor( body );
- range.selectNodeContents( body.firstChild );
- }
-
- // Ensure valid range (must have only block or inline containers)
- var isCollapsed = range.collapsed;
- moveRangeBoundariesDownTree( range );
- if ( isCollapsed ) {
- // Collapse
- range.collapse( true );
- }
-};
-
-// ---
-
-var insertTreeFragmentIntoRange = function ( range, frag ) {
- // Check if it's all inline content
- var allInline = true,
- children = frag.childNodes,
- l = children.length;
- while ( l-- ) {
- if ( !isInline( children[l] ) ) {
- allInline = false;
- break;
- }
- }
-
- // Delete any selected content
- if ( !range.collapsed ) {
- deleteContentsOfRange( range );
- }
-
- // Move range down into text ndoes
- moveRangeBoundariesDownTree( range );
-
- // If inline, just insert at the current position.
- if ( allInline ) {
- insertNodeInRange( range, frag );
- range.collapse( false );
- }
- // Otherwise, split up to body, insert inline before and after split
- // and insert block in between split, then merge containers.
- else {
- var nodeAfterSplit = split( range.startContainer, range.startOffset,
- range.startContainer.ownerDocument.body ),
- nodeBeforeSplit = nodeAfterSplit.previousSibling,
- startContainer = nodeBeforeSplit,
- startOffset = startContainer.childNodes.length,
- endContainer = nodeAfterSplit,
- endOffset = 0,
- parent = nodeAfterSplit.parentNode,
- child, node;
-
- while ( ( child = startContainer.lastChild ) &&
- child.nodeType === ELEMENT_NODE &&
- child.nodeName !== 'BR' ) {
- startContainer = child;
- startOffset = startContainer.childNodes.length;
- }
- while ( ( child = endContainer.firstChild ) &&
- child.nodeType === ELEMENT_NODE &&
- child.nodeName !== 'BR' ) {
- endContainer = child;
- }
- while ( ( child = frag.firstChild ) && isInline( child ) ) {
- startContainer.appendChild( child );
- }
- while ( ( child = frag.lastChild ) && isInline( child ) ) {
- endContainer.insertBefore( child, endContainer.firstChild );
- endOffset += 1;
- }
-
- // Fix cursor then insert block(s)
- node = frag;
- while ( node = getNextBlock( node ) ) {
- fixCursor( node );
- }
- parent.insertBefore( frag, nodeAfterSplit );
-
- // Remove empty nodes created by split and merge inserted containers
- // with edges of split
- node = nodeAfterSplit.previousSibling;
- if ( !nodeAfterSplit.textContent ) {
- parent.removeChild( nodeAfterSplit );
- } else {
- mergeContainers( nodeAfterSplit );
- }
- if ( !nodeAfterSplit.parentNode ) {
- endContainer = node;
- endOffset = getLength( endContainer );
- }
-
- if ( !nodeBeforeSplit.textContent) {
- startContainer = nodeBeforeSplit.nextSibling;
- startOffset = 0;
- parent.removeChild( nodeBeforeSplit );
- } else {
- mergeContainers( nodeBeforeSplit );
- }
-
- range.setStart( startContainer, startOffset );
- range.setEnd( endContainer, endOffset );
- moveRangeBoundariesDownTree( range );
- }
-};
-
-// ---
-
-var isNodeContainedInRange = function ( range, node, partial ) {
- var nodeRange = node.ownerDocument.createRange();
-
- nodeRange.selectNode( node );
-
- if ( partial ) {
- // Node must not finish before range starts or start after range
- // finishes.
- var nodeEndBeforeStart = ( range.compareBoundaryPoints(
- END_TO_START, nodeRange ) > -1 ),
- nodeStartAfterEnd = ( range.compareBoundaryPoints(
- START_TO_END, nodeRange ) < 1 );
- return ( !nodeEndBeforeStart && !nodeStartAfterEnd );
- }
- else {
- // Node must start after range starts and finish before range
- // finishes
- var nodeStartAfterStart = ( range.compareBoundaryPoints(
- START_TO_START, nodeRange ) < 1 ),
- nodeEndBeforeEnd = ( range.compareBoundaryPoints(
- END_TO_END, nodeRange ) > -1 );
- return ( nodeStartAfterStart && nodeEndBeforeEnd );
- }
-};
-
-var moveRangeBoundariesDownTree = function ( range ) {
- var startContainer = range.startContainer,
- startOffset = range.startOffset,
- endContainer = range.endContainer,
- endOffset = range.endOffset,
- child;
-
- while ( startContainer.nodeType !== TEXT_NODE ) {
- child = startContainer.childNodes[ startOffset ];
- if ( !child || isLeaf( child ) ) {
- break;
- }
- startContainer = child;
- startOffset = 0;
- }
- if ( endOffset ) {
- while ( endContainer.nodeType !== TEXT_NODE ) {
- child = endContainer.childNodes[ endOffset - 1 ];
- if ( !child || isLeaf( child ) ) {
- break;
- }
- endContainer = child;
- endOffset = getLength( endContainer );
- }
- } else {
- while ( endContainer.nodeType !== TEXT_NODE ) {
- child = endContainer.firstChild;
- if ( !child || isLeaf( child ) ) {
- break;
- }
- endContainer = child;
- }
- }
-
- // If collapsed, this algorithm finds the nearest text node positions
- // *outside* the range rather than inside, but also it flips which is
- // assigned to which.
- if ( range.collapsed ) {
- range.setStart( endContainer, endOffset );
- range.setEnd( startContainer, startOffset );
- } else {
- range.setStart( startContainer, startOffset );
- range.setEnd( endContainer, endOffset );
- }
-};
-
-var moveRangeBoundariesUpTree = function ( range, common ) {
- var startContainer = range.startContainer,
- startOffset = range.startOffset,
- endContainer = range.endContainer,
- endOffset = range.endOffset,
- parent;
-
- if ( !common ) {
- common = range.commonAncestorContainer;
- }
-
- while ( startContainer !== common && !startOffset ) {
- parent = startContainer.parentNode;
- startOffset = indexOf.call( parent.childNodes, startContainer );
- startContainer = parent;
- }
-
- while ( endContainer !== common &&
- endOffset === getLength( endContainer ) ) {
- parent = endContainer.parentNode;
- endOffset = indexOf.call( parent.childNodes, endContainer ) + 1;
- endContainer = parent;
- }
-
- range.setStart( startContainer, startOffset );
- range.setEnd( endContainer, endOffset );
-};
-
-// Returns the first block at least partially contained by the range,
-// or null if no block is contained by the range.
-var getStartBlockOfRange = function ( range ) {
- var container = range.startContainer,
- block;
-
- // If inline, get the containing block.
- if ( isInline( container ) ) {
- block = getPreviousBlock( container );
- } else if ( isBlock( container ) ) {
- block = container;
- } else {
- block = getNodeBefore( container, range.startOffset );
- block = getNextBlock( block );
- }
- // Check the block actually intersects the range
- return block && isNodeContainedInRange( range, block, true ) ? block : null;
-};
-
-// Returns the last block at least partially contained by the range,
-// or null if no block is contained by the range.
-var getEndBlockOfRange = function ( range ) {
- var container = range.endContainer,
- block, child;
-
- // If inline, get the containing block.
- if ( isInline( container ) ) {
- block = getPreviousBlock( container );
- } else if ( isBlock( container ) ) {
- block = container;
- } else {
- block = getNodeAfter( container, range.endOffset );
- if ( !block ) {
- block = container.ownerDocument.body;
- while ( child = block.lastChild ) {
- block = child;
- }
- }
- block = getPreviousBlock( block );
-
- }
- // Check the block actually intersects the range
- return block && isNodeContainedInRange( range, block, true ) ? block : null;
-};
-
-var rangeDoesStartAtBlockBoundary = function ( range ) {
- var startContainer = range.startContainer,
- startOffset = range.startOffset,
- parent, child;
-
- while ( isInline( startContainer ) ) {
- if ( startOffset ) {
- return false;
- }
- parent = startContainer.parentNode;
- startOffset = indexOf.call( parent.childNodes, startContainer );
- startContainer = parent;
- }
- // Skip empty text nodes and
s.
- while ( startOffset &&
- ( child = startContainer.childNodes[ startOffset - 1 ] ) &&
- ( child.data === '' || child.nodeName === 'BR' ) ) {
- startOffset -= 1;
- }
- return !startOffset;
-};
-
-var rangeDoesEndAtBlockBoundary = function ( range ) {
- var endContainer = range.endContainer,
- endOffset = range.endOffset,
- length = getLength( endContainer ),
- parent, child;
-
- while ( isInline( endContainer ) ) {
- if ( endOffset !== length ) {
- return false;
- }
- parent = endContainer.parentNode;
- endOffset = indexOf.call( parent.childNodes, endContainer ) + 1;
- endContainer = parent;
- length = endContainer.childNodes.length;
- }
- // Skip empty text nodes and
s.
- while ( endOffset < length &&
- ( child = endContainer.childNodes[ endOffset ] ) &&
- ( child.data === '' || child.nodeName === 'BR' ) ) {
- endOffset += 1;
- }
- return endOffset === length;
-};
-
-var expandRangeToBlockBoundaries = function ( range ) {
- var start = getStartBlockOfRange( range ),
- end = getEndBlockOfRange( range ),
- parent;
-
- if ( start && end ) {
- parent = start.parentNode;
- range.setStart( parent, indexOf.call( parent.childNodes, start ) );
- parent = end.parentNode;
- range.setEnd( parent, indexOf.call( parent.childNodes, end ) + 1 );
- }
-};
diff --git a/source/Squire-UI.css b/source/Squire-UI.css
deleted file mode 100644
index 1ca2907..0000000
--- a/source/Squire-UI.css
+++ /dev/null
@@ -1,148 +0,0 @@
-body {
- margin: 0;
- font-family: 'Lato', sans-serif !important;
-}
-
-.header {
- padding: 50px 0 30px;
- color: #fff;
- text-align: center;
- background: #1d193d;
- margin-bottom: 20px;
-}
-
-.header h1 {
- font-size: 8em;
- line-height: 1em;
- font-weight: 900;
-}
-
-.header h2 {
- margin-bottom: 1em;
- font-size: 3em;
- font-weight: 300;
- text-transform: lowercase;
- color: #afaedf;
-}
-
- .col-centered{
- float: none;
- margin: 0 auto;
- width: 80%;
- }
-
-.alignCenter {
- text-align: center;
-}
-
-iframe {
- width: 100%;
- border: 1px #919191 solid;
- border-radius: 4px;
- -webkit-border-radius: 4px;
- padding: 7px 8px;
- color: #333;
- background-color: #fff;
- background-repeat: no-repeat;
- background-position: right center;
- border: 1px solid #ccc;
- border-radius: 3px;
- outline: none;
- box-shadow: inset 0 1px 2px rgba(0,0,0,0.075);
-}
-
-.menu .item {
- color:#000;
- float:left;
- background:#FFF;
- padding:10px;
- border-left:1px #EEE solid;
- -webkit-font-smoothing:subpixel-antialiased
-}
-
-.menu .group {
- border-radius:3px;
- display:inline-block;
- border:1px #EEE solid;
- margin:5px
-}
-
-.menu .group .item .flip {
- -ms-transform:rotateY(180deg);
- -webkit-transform:rotateY(180deg);
- -moz-transform:rotateY(180deg);
- transform:rotateY(180deg)
-}
-
-.btn {
- background: #516066;
- display: block;
- position: relative;
- padding: 10px 15px;
- margin-top: 10px;
- text-transform: uppercase;
- font-size: 11px;
- font-weight: 500;
- color: #fff;
- text-align: center;
- overflow: hidden;
- letter-spacing: 1px;
- border-radius: 4px;
-}
-
-input[type=text] {
- background-color: #fff;
- vertical-align: middle;
- max-width: 100%;
- border: 1px solid #a8afb2;
- border-color: #a8afb2 #d4d7d9 #d4d7d9;
- color: #516066;
- -webkit-box-sizing: border-box;
- box-sizing: border-box;
- -webkit-transition: border linear 150ms;
- -moz-transition: border linear 150ms;
- -o-transition: border linear 150ms;
- transition: border linear 150ms;
- font-size: 14px;
- padding: 5px;
- width: 100%;
-}
-
-.menu .group .item:hover, .menu .item:first-child:hover {
- border-left: 3px #55ACEE solid;
-}
-
-.menu .item:first-child {
- border-left:none;
-}
-.menu {
- text-align: center;
- -webkit-touch-callout: none;
- -webkit-user-select: none;
- -khtml-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
-}
-.drop {
- border: 1px solid #dbdbdb;
- padding: 14px;
- background: white;
- box-shadow: 0 1px 0 rgba(255,255,255,0),0 0 10px rgba(0,0,0,0.1);
- -webkit-border-radius: 4px;
- border-radius: 4px;
- margin-top: 5px;
-}
-
-.hidden {
- display: none;
-}
-
-.quit {
- float: right;
- top:0;
- right:0;
- margin-bottom: 5px;
-}
-
-
\ No newline at end of file
diff --git a/source/Squire-UI.html b/source/Squire-UI.html
deleted file mode 100644
index 8956790..0000000
--- a/source/Squire-UI.html
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-
-
Change Font
-
- Text Size:
-
-
Font:
-
-
-
Apply
-
-
-
Insert Link
-
-
-
Insert
-
-
-
Insert Image
-
-
-
Insert
-
-
diff --git a/source/Squire-UI.js b/source/Squire-UI.js
deleted file mode 100644
index 17fff00..0000000
--- a/source/Squire-UI.js
+++ /dev/null
@@ -1,167 +0,0 @@
-$(document).ready(function() {
- Squire.prototype.testPresenceinSelection = function(name, action, format,
- validation) {
- var path = this.getPath(),
- test = (validation.test(path) | this.hasFormat(format));
- if (name == action && test) {
- return true;
- } else {
- return false;
- }
- };
- SquireUI = function(options) {
- if (typeof options.buildPath == "undefined") {
- options.buildPath = 'build/';
- }
- // Create instance of iFrame
- var container, editor;
- if (options.replace) {
- container = $(options.replace).parent();
- $(options.replace).remove();
- } else if (options.div) {
- container = $(options.div);
- } else {
- throw new Error(
- "No element was defined for the editor to inject to.");
- }
- var iframe = document.createElement('iframe');
- var div = document.createElement('div');
- div.className = 'Squire-UI';
- iframe.height = options.height;
-
- $(div).load(options.buildPath + 'Squire-UI.html', function() {
- this.linkDrop = new Drop({
- target: $('#makeLink').first()[0],
- content: $('#drop-link').html(),
- position: 'bottom center',
- openOn: 'click'
- });
-
- this.linkDrop.on('open', function () {
- $('.quit').click(function () {
- $(this).parent().parent().removeClass('drop-open');
- });
-
- $('.submitLink').click(function () {
- var editor = iframe.contentWindow.editor;
- editor.makeLink($(this).parent().children('#url').first().val());
- $(this).parent().parent().removeClass('drop-open');
- $(this).parent().children('#url').attr('value', '');
- });
- });
-
- this.imageDrop = new Drop({
- target: $('#insertImage').first()[0],
- content: $('#drop-image').html(),
- position: 'bottom center',
- openOn: 'click'
- });
-
- this.imageDrop.on('open', function () {
- $('.quit').unbind().click(function () {
- $(this).parent().parent().removeClass('drop-open');
- });
-
- $('.sumbitImageURL').unbind().click(function () {
- console.log("Passed through .sumbitImageURL");
- var editor = iframe.contentWindow.editor;
- url = $(this).parent().children('#imageUrl').first()[0];
- editor.insertImage(url.value);
- $(this).parent().parent().removeClass('drop-open');
- $(this).parent().children('#imageUrl').attr('value', '');
- });
-
- });
-
- this.fontDrop = new Drop({
- target: $('#selectFont').first()[0],
- content: $('#drop-font').html(),
- position: 'bottom center',
- openOn: 'click'
- });
-
- this.fontDrop.on('open', function () {
- $('.quit').click(function () {
- $(this).parent().parent().removeClass('drop-open');
- });
-
- $('.submitFont').unbind().click(function () {
- var editor = iframe.contentWindow.editor;
- var selectedFonts = $('select#fontSelect option:selected').last().data('fonts');
- var fontSize = $('select#textSelector option:selected').last().data('size') + 'px';
- editor.setFontSize(fontSize);
-
- try {
- editor.setFontFace(selectedFonts);
- } catch (e) {
- alert('Please make a selection of text.');
- } finally {
- $(this).parent().parent().removeClass('drop-open');
- }
-
- });
-
-
- });
-
- $('.item').click(function() {
- var iframe = $(this).parents('.Squire-UI').next('iframe').first()[0];
- var editor = iframe.contentWindow.editor;
- var action = $(this).data('action');
-
- test = {
- value: $(this).data('action'),
- testBold: editor.testPresenceinSelection('bold',
- action, 'B', (/>B\b/)),
- testItalic: editor.testPresenceinSelection('italic',
- action, 'I', (/>I\b/)),
- testUnderline: editor.testPresenceinSelection(
- 'underline', action, 'U', (/>U\b/)),
- testOrderedList: editor.testPresenceinSelection(
- 'makeOrderedList', action, 'OL', (/>OL\b/)),
- testLink: editor.testPresenceinSelection('makeLink',
- action, 'A', (/>A\b/)),
- testQuote: editor.testPresenceinSelection(
- 'increaseQuoteLevel', action, 'blockquote', (
- />blockquote\b/)),
- isNotValue: function (a) {return (a == action && this.value !== ''); }
- };
-
- editor.alignRight = function () { editor.setTextAlignment('right'); };
- editor.alignCenter = function () { editor.setTextAlignment('center'); };
- editor.alignLeft = function () { editor.setTextAlignment('left'); };
- editor.alignJustify = function () { editor.setTextAlignment('justify'); };
- editor.makeHeading = function () { editor.setFontSize('2em'); editor.bold(); };
-
- if (test.testBold | test.testItalic | test.testUnderline | test.testOrderedList | test.testLink | test.testQuote) {
- if (test.testBold) editor.removeBold();
- if (test.testItalic) editor.removeItalic();
- if (test.testUnderline) editor.removeUnderline();
- if (test.testLink) editor.removeLink();
- if (test.testOrderedList) editor.removeList();
- if (test.testQuote) editor.decreaseQuoteLevel();
- } else if (test.isNotValue('makeLink') | test.isNotValue('insertImage') | test.isNotValue('selectFont')) {
- // do nothing these are dropdowns.
- } else {
- if (editor.getSelectedText() === '' && !(action == 'insertImage' || action == 'makeOrderedList' || action == 'increaseQuoteLevel' || action == 'redo' || action == 'undo')) return;
- editor[action]();
- }
- });
- });
-
- $(container).append(div);
- $(container).append(iframe);
-
- var style = document.createElement('style');
- style.innerHTML = 'blockquote { border-left: 3px green solid; padding-left: 5px; }';
-
-
- iframe.contentWindow.editor = new Squire(iframe.contentWindow.document);
- iframe.addEventListener('load', function() {
- iframe.contentWindow.editor = new Squire(iframe.contentWindow.document);
- });
-
- iframe.contentWindow.document.head.appendChild(style);
- return iframe.contentWindow.editor;
- };
-});
\ No newline at end of file
diff --git a/source/TreeWalker.js b/source/TreeWalker.js
deleted file mode 100644
index 8bf7ffc..0000000
--- a/source/TreeWalker.js
+++ /dev/null
@@ -1,91 +0,0 @@
-/*global FILTER_ACCEPT */
-/*jshint strict:false */
-
-/*
- Native TreeWalker is buggy in IE and Opera:
- * IE9/10 sometimes throw errors when calling TreeWalker#nextNode or
- TreeWalker#previousNode. No way to feature detect this.
- * Some versions of Opera have a bug in TreeWalker#previousNode which makes
- it skip to the wrong node.
-
- Rather than risk further bugs, it's easiest just to implement our own
- (subset) of the spec in all browsers.
-*/
-
-var typeToBitArray = {
- // ELEMENT_NODE
- 1: 1,
- // ATTRIBUTE_NODE
- 2: 2,
- // TEXT_NODE
- 3: 4,
- // COMMENT_NODE
- 8: 128,
- // DOCUMENT_NODE
- 9: 256,
- // DOCUMENT_FRAGMENT_NODE
- 11: 1024
-};
-
-function TreeWalker ( root, nodeType, filter ) {
- this.root = this.currentNode = root;
- this.nodeType = nodeType;
- this.filter = filter;
-}
-
-TreeWalker.prototype.nextNode = function () {
- var current = this.currentNode,
- root = this.root,
- nodeType = this.nodeType,
- filter = this.filter,
- node;
- while ( true ) {
- node = current.firstChild;
- while ( !node && current ) {
- if ( current === root ) {
- break;
- }
- node = current.nextSibling;
- if ( !node ) { current = current.parentNode; }
- }
- if ( !node ) {
- return null;
- }
- if ( ( typeToBitArray[ node.nodeType ] & nodeType ) &&
- filter( node ) === FILTER_ACCEPT ) {
- this.currentNode = node;
- return node;
- }
- current = node;
- }
-};
-
-TreeWalker.prototype.previousNode = function () {
- var current = this.currentNode,
- root = this.root,
- nodeType = this.nodeType,
- filter = this.filter,
- node;
- while ( true ) {
- if ( current === root ) {
- return null;
- }
- node = current.previousSibling;
- if ( node ) {
- while ( current = node.lastChild ) {
- node = current;
- }
- } else {
- node = current.parentNode;
- }
- if ( !node ) {
- return null;
- }
- if ( ( typeToBitArray[ node.nodeType ] & nodeType ) &&
- filter( node ) === FILTER_ACCEPT ) {
- this.currentNode = node;
- return node;
- }
- current = node;
- }
-};
diff --git a/source/document.html b/source/document.html
deleted file mode 100644
index 428e909..0000000
--- a/source/document.html
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/source/ie8dom.js b/source/ie8dom.js
deleted file mode 100644
index 0b6fd9e..0000000
--- a/source/ie8dom.js
+++ /dev/null
@@ -1,157 +0,0 @@
-/* Copyright © 2011-2012 by Neil Jenkins. Licensed under the MIT license. */
-
-( function () {
-
-/*global window, document, Element, HTMLDocument */
-/*jshint strict: false */
-
-var doc = document;
-
-// Add JS hook
-window.ie = 8;
-
-// Add defaultView property to document
-doc.defaultView = window;
-
-// Fake W3C events support
-var translate = {
- focus: 'focusin',
- blur: 'focusout'
-};
-
-var returnTrue = function () { return true; };
-var returnFalse = function () { return false; };
-
-var toCopy = 'altKey ctrlKey metaKey shiftKey clientX clientY charCode keyCode'.split( ' ' );
-
-var DOMEvent = function ( event ) {
- var type = event.type,
- doc = document,
- target = event.srcElement || doc,
- html = ( target.ownerDocument || doc ).documentElement,
- l = toCopy.length,
- property;
-
- while ( l-- ) {
- property = toCopy[l];
- this[ property ] = event[ property ];
- }
-
- if ( type === 'propertychange' ) {
- type = ( target.nodeName === 'INPUT' &&
- target.type !== 'text' && target.type !== 'password' ) ?
- 'change' : 'input';
- }
-
- this.type = Object.keyOf( translate, type ) || type;
- this.target = target;
- this.pageX = event.clientX + html.scrollLeft;
- this.pageY = event.clientY + html.scrollTop;
-
- if ( event.button ) {
- this.button = ( event.button & 4 ? 1 :
- ( event.button & 2 ? 2 : 0 ) );
- this.which = this.button + 1;
- }
-
- this.relatedTarget = event.fromElement === target ?
- event.toElement : event.fromElement;
- this._event = event;
-};
-
-DOMEvent.prototype = {
- constructor: DOMEvent,
- isEvent: true,
- preventDefault: function () {
- this.isDefaultPrevented = returnTrue;
- this._event.returnValue = false;
- },
- stopPropagation: function () {
- this.isPropagationStopped = returnTrue;
- this._event.cancelBubble = true;
- },
- isDefaultPrevented: returnFalse,
- isPropagationStopped: returnFalse
-};
-
-// Add W3C event add/remove methods to elements and document.
-[ doc, Element.prototype ].forEach(
- function ( dom ) {
- dom.addEventListener = function ( type, handler, capture ) {
- var fn = handler._ie_handleEvent || ( handler._ie_handleEvent =
- function () {
- var event = new DOMEvent( window.event );
- if ( typeof handler === 'object' ) {
- handler.handleEvent( event );
- } else {
- handler.call( this, event );
- }
- }
- ),
- node = /paste|cut/.test( type ) ? this.body || this : this;
-
- handler._ie_registeredCount = ( handler._ie_registeredCount || 0 ) + 1;
-
- node.attachEvent( 'on' + ( translate[ type ] || type ), fn );
- };
- dom.addEventListener.isFake = true;
-
- dom.removeEventListener = function ( type, handler, capture ) {
- var fn = handler._ie_handleEvent,
- node = /paste|cut/.test( type ) ? this.body || this : this;
- if ( !( handler._ie_registeredCount -= 1 ) ) {
- delete handler._ie_handleEvent;
- }
- if ( fn ) {
- node.detachEvent( 'on' + ( translate[ type ] || type ), fn );
- }
- };
- dom.removeEventListener.isFake = true;
-});
-
-// The events that we normally attach to the window object, IE8 wants on the
-// body.
-doc.defaultView.addEventListener = function ( type, handler, capture ) {
- return doc.addEventListener( type, handler, capture );
-};
-
-// Add textContent property to elements.
-Object.defineProperty( Element.prototype, 'textContent', {
- get: function () {
- return this.innerText;
- },
-
- set: function ( text ) {
- this.innerText = text;
- }
-});
-
-// Add compareDocumentPosition method to elements.
-Element.prototype.compareDocumentPosition = function ( b ) {
- if ( b.nodeType !== 1 ) { b = b.parentNode; }
- var a = this,
- different = ( a !== b ),
- aIndex = a.sourceIndex,
- bIndex = b.sourceIndex;
-
- return ( different && a.contains( b ) ? 16 : 0 ) +
- ( different && b.contains( a ) ? 8 : 0 ) +
- ( aIndex < bIndex ? 4 : 0 ) +
- ( bIndex < aIndex ? 2 : 0 );
-};
-
-// Add normalize method to document fragments
-HTMLDocument.prototype.normalize = function () {
- var children = this.childNodes,
- l = children.length,
- child;
-
- while ( l-- ) {
- child = children[l];
- if ( child.nodeType === 1 ) {
- child.normalize();
- }
- }
-};
-
-}() );
diff --git a/source/ie8range.js b/source/ie8range.js
deleted file mode 100644
index 1c54e52..0000000
--- a/source/ie8range.js
+++ /dev/null
@@ -1,487 +0,0 @@
-/* Copyright © 2011-2012 by Neil Jenkins. Licensed under the MIT license.
-
- IE TextRange <-> W3C Range code adapted from Rangy:
- http://code.google.com/p/rangy/
- Copyright 2012, Tim Down. Licensed under the MIT license.
-*/
-
-var Range;
-
-( function () {
-
-/*global window, document */
-/*jshint strict: false */
-
-var indexOf = Array.prototype.indexOf;
-
-var START_TO_START = 0;
-var START_TO_END = 1;
-var END_TO_START = 3;
-
-var contains = function ( a, b ) {
- while ( b = b.parentNode ) {
- if ( a === b ) { return true; }
- }
- return false;
-};
-
-var getCommonAncestor = function ( a, b ) {
- var commonAncestor,
- aParents, bParents,
- aL, bL;
-
- if ( a === b || contains( a, b ) ) {
- commonAncestor = a;
- } else if ( contains( b, a ) ) {
- commonAncestor = b;
- } else {
- aParents = [];
- bParents = [];
- while ( a = a.parentNode ) {
- aParents.push( a );
- }
- while ( b = b.parentNode ) {
- bParents.push( b );
- }
- aL = aParents.length;
- bL = bParents.length;
- while ( aL-- && bL-- ) {
- if ( aParents[ aL ] !== bParents[ bL ] ) {
- commonAncestor = aParents[ aL + 1 ];
- break;
- }
- }
- if ( !commonAncestor ) {
- commonAncestor = ( aL === -1 ? aParents[0] : bParents[0] );
- }
- }
- return commonAncestor;
-};
-
-Range = function ( startContainer, startOffset, endContainer, endOffset ) {
- startContainer = startContainer || document;
- startOffset = startOffset || 0;
-
- this.startContainer = startContainer;
- this.startOffset = startOffset;
- this.endContainer = endContainer || startContainer;
- this.endOffset = endOffset !== undefined ? endOffset : startOffset;
- this._updateCollapsedAndAncestor();
-};
-
-Range.prototype = {
- constructor: Range,
-
- _updateCollapsedAndAncestor: function () {
- this.collapsed = (
- this.startContainer === this.endContainer &&
- this.startOffset === this.endOffset
- );
- this.commonAncestorContainer =
- getCommonAncestor( this.startContainer, this.endContainer );
- },
- setStart: function ( node, offset ) {
- this.startContainer = node;
- this.startOffset = offset;
- this._updateCollapsedAndAncestor();
- },
- setEnd: function ( node, offset ) {
- this.endContainer = node;
- this.endOffset = offset;
- this._updateCollapsedAndAncestor();
- },
- setStartAfter: function ( node ) {
- var parent = node.parentNode;
- this.setStart( parent, indexOf.call( parent.childNodes, node ) + 1 );
- },
- setEndBefore: function ( node ) {
- var parent = node.parentNode;
- this.setEnd( parent, indexOf.call( parent.childNodes, node ) );
- },
- selectNode: function ( node ) {
- var parent = node.parentNode,
- offset = indexOf.call( parent.childNodes, node );
- this.setStart( parent, offset );
- this.setEnd( parent, offset + 1 );
- },
- selectNodeContents: function ( node ) {
- this.setStart( node, 0 );
- this.setEnd( node, node.childNodes.length );
- },
- cloneRange: function () {
- return new Range(
- this.startContainer,
- this.startOffset,
- this.endContainer,
- this.endOffset
- );
- },
- collapse: function ( toStart ) {
- if ( toStart ) {
- this.setEnd( this.startContainer, this.startOffset );
- } else {
- this.setStart( this.endContainer, this.endOffset );
- }
- },
- compareBoundaryPoints: function ( how, sourceRange ) {
- var aContainer, aOffset, bContainer, bOffset, node, parent;
- if ( how === START_TO_START || how === END_TO_START ) {
- aContainer = this.startContainer;
- aOffset = this.startOffset;
- } else {
- aContainer = this.endContainer;
- aOffset = this.endOffset;
- }
- if ( how === START_TO_START || how === START_TO_END ) {
- bContainer = sourceRange.startContainer;
- bOffset = sourceRange.startOffset;
- } else {
- bContainer = sourceRange.endContainer;
- bOffset = sourceRange.endOffset;
- }
- if ( aContainer === bContainer ) {
- return aOffset < bOffset ? -1 :
- aOffset > bOffset ? 1 : 0;
- }
-
- node = aContainer;
- while ( parent = node.parentNode ) {
- if ( parent === bContainer ) {
- return indexOf.call( parent.childNodes, node ) < bOffset ?
- -1 : 1;
- }
- node = parent;
- }
- node = bContainer;
- while ( parent = node.parentNode ) {
- if ( parent === aContainer ) {
- return indexOf.call( parent.childNodes, node ) < aOffset ?
- 1 : -1;
- }
- node = parent;
- }
- if ( aContainer.nodeType !== 1 ) {
- aContainer = aContainer.parentNode;
- }
- if ( bContainer.nodeType !== 1 ) {
- bContainer = bContainer.parentNode;
- }
- return aContainer.sourceIndex < bContainer.sourceIndex ? -1 :
- aContainer.sourceIndex > bContainer.sourceIndex ? 1 : 0;
- }
-};
-
-document.createRange = function () {
- return new Range();
-};
-
-// ---
-
-var isAncestorOf = function ( ancestor, descendant ) {
- return ancestor === descendant || contains( ancestor, descendant );
-};
-
-var isCharacterDataNode = function ( node ) {
- var nodeType = node.nodeType;
- // Text, CDataSection or Comment
- return nodeType === 3 || nodeType === 4 || nodeType === 8;
-};
-
-var DomPosition = function ( node, offset ) {
- this.node = node;
- this.offset = offset;
-};
-
-var getTextRangeContainerElement = function ( textRange ) {
- var parentEl = textRange.parentElement(),
- range, startEl, endEl, startEndContainer;
-
- range = textRange.duplicate();
- range.collapse( true );
- startEl = range.parentElement();
- range = textRange.duplicate();
- range.collapse( false );
- endEl = range.parentElement();
- startEndContainer = ( startEl === endEl ) ?
- startEl : getCommonAncestor( startEl, endEl );
-
- return startEndContainer === parentEl ?
- startEndContainer : getCommonAncestor( parentEl, startEndContainer );
-};
-
-// Gets the boundary of a TextRange expressed as a node and an offset within
-// that node. This function started out as an improved version of code found in
-// Tim Cameron Ryan's IERange (http://code.google.com/p/ierange/) but has grown,
-// fixing problems with line breaks in preformatted text, adding workaround for
-// IE TextRange bugs, handling for inputs and images, plus optimizations.
-var getTextRangeBoundaryPosition = function (
- textRange, wholeRangeContainerElement, isStart, isCollapsed ) {
- var workingRange = textRange.duplicate();
-
- workingRange.collapse( isStart );
-
- var containerElement = workingRange.parentElement();
-
- // Sometimes collapsing a TextRange that's at the start of a text node can
- // move it into the previous node, so check for that TODO: Find out when.
- // Workaround for wholeRangeContainerElement may break this
- if ( !isAncestorOf( wholeRangeContainerElement, containerElement ) ) {
- containerElement = wholeRangeContainerElement;
- }
-
- // Deal with nodes that cannot "contain rich HTML markup". In practice, this
- // means form inputs, images and similar. See
- // http://msdn.microsoft.com/en-us/library/aa703950%28VS.85%29.aspx
- if ( !containerElement.canHaveHTML ) {
- return new DomPosition(
- containerElement.parentNode,
- indexOf.call(
- containerElement.parentNode.childNodes, containerElement )
- );
- }
-
- var workingNode = document.createElement( 'span' ),
- workingComparisonType = isStart ? 'StartToStart' : 'StartToEnd',
- comparison, previousNode, nextNode, boundaryPosition, boundaryNode;
-
- // Move the working range through the container's children, starting at the
- // end and working backwards, until the working range reaches or goes past
- // the boundary we're interested in
- do {
- containerElement.insertBefore(
- workingNode, workingNode.previousSibling );
- workingRange.moveToElementText( workingNode );
- comparison =
- workingRange.compareEndPoints( workingComparisonType, textRange );
- } while ( comparison > 0 && workingNode.previousSibling );
-
- // We've now reached or gone past the boundary of the text range we're
- // interested in so have identified the node we want
- boundaryNode = workingNode.nextSibling;
-
- if ( comparison === -1 && boundaryNode &&
- isCharacterDataNode( boundaryNode ) ) {
- // This is a character data node (text, comment, cdata). The working
- // range is collapsed at the start of the node containing the text
- // range's boundary, so we move the end of the working range to the
- // boundary point and measure the length of its text to get the
- // boundary's offset within the node.
- workingRange.setEndPoint(
- isStart ? 'EndToStart' : 'EndToEnd', textRange );
-
- var offset;
-
- if ( /[\r\n]/.test( boundaryNode.data ) ||
- /[\r\n]/.test( workingRange.text ) ) {
- /*
- For the particular case of a boundary within a text node containing
- line breaks (within a element, for example), we need a
- slightly complicated approach to get the boundary's offset in IE.
- The facts:
-
- - Each line break is represented as \r in the text node's
- data/nodeValue properties
- - Each line break is represented as \r\n in the TextRange's 'text'
- property
- - The 'text' property of the TextRange does not contain trailing
- line breaks
-
- To get round the problem presented by the final fact above, we can
- use the fact that TextRange's moveStart() and moveEnd() methods
- return the actual number of characters moved, which is not
- necessarily the same as the number of characters it was instructed
- to move. The simplest approach is to use this to store the
- characters moved when moving both the start and end of the range to
- the start of the document body and subtracting the start offset from
- the end offset (the "move-negative-gazillion" method). However, this
- is extremely slow when the document is large and the range is near
- the end of it. Clearly doing the mirror image (i.e. moving the range
- boundaries to the end of the document) has the same problem.
-
- Another approach that works is to use moveStart() to move the start
- boundary of the range up to the end boundary one character at a time
- and incrementing a counter with the value returned by the
- moveStart() call. However, the check for whether the start boundary
- has reached the end boundary is expensive, so this method is slow
- (although unlike "move-negative-gazillion" is largely unaffected by
- the location of the range within the document).
-
- The method below is a hybrid of the two methods above. It uses the
- fact that a string containing the TextRange's 'text' property with
- each \r\n converted to a single \r character cannot be longer than
- the text of the TextRange, so the start of the range is moved that
- length initially and then a character at a time to make up for any
- trailing line breaks not contained in the 'text' property. This has
- good performance in most situations compared to the previous two
- methods.
- */
- var tempRange = workingRange.duplicate();
- var rangeLength = tempRange.text.replace( /\r\n/g, '\r' ).length;
-
- offset = tempRange.moveStart( 'character', rangeLength);
- while ( ( comparison =
- tempRange.compareEndPoints( 'StartToEnd', tempRange )
- ) === -1 ) {
- offset += 1;
- tempRange.moveStart( 'character', 1 );
- }
- } else {
- offset = workingRange.text.length;
- }
- boundaryPosition = new DomPosition( boundaryNode, offset );
- }
- else {
- // If the boundary immediately follows a character data node and this is
- // the end boundary, we should favour a position within that, and
- // likewise for a start boundary preceding a character data node
- previousNode = ( isCollapsed || !isStart ) &&
- workingNode.previousSibling;
- nextNode = ( isCollapsed || isStart ) && workingNode.nextSibling;
-
- if ( nextNode && isCharacterDataNode( nextNode ) ) {
- boundaryPosition = new DomPosition( nextNode, 0 );
- } else if ( previousNode && isCharacterDataNode( previousNode ) ) {
- // Strange bug: if we don't read the data property, the length
- // property is often returned incorrectly as 0. Don't ask me why.
- // Therefore get the length from the data property rather than
- // reading it directly from the node.
- boundaryPosition = new DomPosition(
- previousNode, previousNode.data.length );
- } else {
- boundaryPosition = new DomPosition(
- containerElement,
- indexOf.call( containerElement.childNodes, workingNode )
- );
- }
- }
-
- // Clean up
- workingNode.parentNode.removeChild( workingNode );
-
- return boundaryPosition;
-};
-
-// Returns a TextRange representing the boundary of a TextRange expressed as a
-// node and an offset within that node. This function started out as an
-// optimized version of code found in Tim Cameron Ryan's IERange
-// (http://code.google.com/p/ierange/)
-var createBoundaryTextRange = function ( boundaryPosition, isStart ) {
- var boundaryNode, boundaryParent, boundaryOffset = boundaryPosition.offset;
- var doc = document;
- var workingNode, childNodes, workingRange = doc.body.createTextRange();
- var nodeIsDataNode = isCharacterDataNode( boundaryPosition.node );
-
- if ( nodeIsDataNode ) {
- boundaryNode = boundaryPosition.node;
- boundaryParent = boundaryNode.parentNode;
- } else {
- childNodes = boundaryPosition.node.childNodes;
- boundaryNode = ( boundaryOffset < childNodes.length ) ?
- childNodes[ boundaryOffset ] : null;
- boundaryParent = boundaryPosition.node;
- }
-
- // Position the range immediately before the node containing the boundary
- workingNode = doc.createElement( 'span' );
-
- // Making the working element non-empty element persuades IE to consider the
- // TextRange boundary to be within the element rather than immediately
- // before or after it, which is what we want
- workingNode.innerHTML = '';
-
- // insertBefore is supposed to work like appendChild if the second parameter
- // is null. However, a bug report for IERange suggests that it can crash the
- // browser: http://code.google.com/p/ierange/issues/detail?id=12
- if ( boundaryNode ) {
- boundaryParent.insertBefore( workingNode, boundaryNode );
- } else {
- boundaryParent.appendChild( workingNode );
- }
-
- workingRange.moveToElementText( workingNode );
- workingRange.collapse( !isStart );
-
- // Clean up
- boundaryParent.removeChild( workingNode );
-
- // Move the working range to the text offset, if required
- if ( nodeIsDataNode ) {
- workingRange[ isStart ? 'moveStart' : 'moveEnd' ](
- 'character', boundaryOffset );
- }
-
- return workingRange;
-};
-
-var toDOMRange = function ( textRange ) {
- var rangeContainerElement = getTextRangeContainerElement( textRange ),
- start, end;
-
- if ( textRange.compareEndPoints( 'StartToEnd', textRange ) === 0 ) {
- start = end = getTextRangeBoundaryPosition(
- textRange, rangeContainerElement, true, true );
- } else {
- start = getTextRangeBoundaryPosition(
- textRange, rangeContainerElement, true, false );
- end = getTextRangeBoundaryPosition(
- textRange, rangeContainerElement, false, false );
- }
- return new Range(
- start.node,
- start.offset,
- end.node,
- end.offset
- );
-};
-
-var toTextRange = function ( range ) {
- var textRange, startRange, endRange;
- if ( range.collapsed ) {
- textRange = createBoundaryTextRange(
- new DomPosition( range.startContainer, range.startOffset ), true);
- } else {
- startRange = createBoundaryTextRange(
- new DomPosition( range.startContainer, range.startOffset ), true);
- endRange = createBoundaryTextRange(
- new DomPosition( range.endContainer, range.endOffset ), false );
- textRange = document.body.createTextRange();
- textRange.setEndPoint( 'StartToStart', startRange);
- textRange.setEndPoint( 'EndToEnd', endRange);
- }
- return textRange;
-};
-
-var selection = {
- rangeCount: 0,
- getRangeAt: function ( index ) {
- if ( index !== 0 ) { return undefined; }
- var sel = document.selection.createRange();
- // Check if we have a control range.
- if ( sel.add ) {
- var range = document.createRange();
- range.moveToElementText( sel.item( 0 ) );
- range.collapse( false );
- range.select();
- sel = range;
- }
- return toDOMRange( sel );
- },
- removeAllRanges: function () {},
- addRange: function ( range ) {
- toTextRange( range ).select();
- }
-};
-
-document.attachEvent( 'onbeforeactivate', function () {
- selection.rangeCount = 1;
-});
-
-document.attachEvent( 'ondeactivate', function () {
- selection.rangeCount = 0;
-});
-
-window.getSelection = function () {
- return selection;
-};
-
-}() );
diff --git a/source/ie8types.js b/source/ie8types.js
deleted file mode 100644
index 7a3361c..0000000
--- a/source/ie8types.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Copyright © 2011-2012 by Neil Jenkins. Licensed under the MIT license. */
-
-( function () {
-
-/*jshint strict: false */
-
-// Note: Does not inclue the `if ( i in this ) {}` check these function should
-// have, as IE8 will return false if this[i] is undefined (at least if the array
-// was defined with a literal, e.g. `[ undefined, undefined ]`).
-
-Array.prototype.indexOf = function ( item, from ) {
- var l = this.length;
- for ( var i = ( from < 0 ) ? Math.max( 0, l + from ) : from || 0;
- i < l; i += 1 ) {
- if ( this[i] === item ) {
- return i;
- }
- }
- return -1;
-};
-
-Array.prototype.forEach = function ( fn, bind ) {
- var l = this.length >>> 0;
- if ( typeof fn !== 'function' ) {
- throw new TypeError();
- }
- for ( var i = 0; i < l; i += 1 ) {
- fn.call( bind, this[i], i, this );
- }
-};
-
-Array.prototype.filter = function ( fn, bind ) {
- var results = [];
- for ( var i = 0, l = this.length; i < l; i += 1 ) {
- var value = this[i];
- if ( fn.call( bind, value, i, this ) ) {
- results.push( value );
- }
- }
- return results;
-};
-
-Object.keyOf = function ( object, value ) {
- for ( var key in object ) {
- if ( object[ key ] === value ) {
- return key;
- }
- }
-};
-
-Date.now = function () {
- return +( new Date() );
-};
-
-String.prototype.trim = function () {
- var str = this.replace( /^\s\s*/, '' ),
- ws = /\s/,
- i = str.length;
- while ( ws.test( str.charAt( i -= 1 ) ) ) {/* Empty! */}
- return str.slice( 0, i + 1 );
-};
-
-}() );
diff --git a/source/intro.js b/source/intro.js
deleted file mode 100644
index f14b523..0000000
--- a/source/intro.js
+++ /dev/null
@@ -1,5 +0,0 @@
-/* Copyright © 2011-2013 by Neil Jenkins. MIT Licensed. */
-
-( function ( doc, undefined ) {
-
-"use strict";
diff --git a/source/outro.js b/source/outro.js
deleted file mode 100644
index a8f1a62..0000000
--- a/source/outro.js
+++ /dev/null
@@ -1,13 +0,0 @@
-/*global top, win, doc, Squire */
-
-if ( top !== win ) {
- win.editor = new Squire( doc );
- if ( win.onEditorLoad ) {
- win.onEditorLoad( win.editor );
- win.onEditorLoad = null;
- }
-} else {
- win.Squire = Squire;
-}
-
-}( document ) );