0
Fork 0
mirror of https://github.com/fastmail/Squire.git synced 2024-12-22 23:40:35 -05:00

Update to latest Squire build.

This commit is contained in:
Neil Jenkins 2015-12-09 15:17:00 +11:00
parent fca4202e45
commit 2d44b9af2d
2 changed files with 101 additions and 47 deletions

View file

@ -698,7 +698,7 @@ var insertNodeInRange = function ( range, node ) {
childCount = children.length; childCount = children.length;
if ( startOffset === childCount) { if ( startOffset === childCount ) {
startContainer.appendChild( node ); startContainer.appendChild( node );
} else { } else {
startContainer.insertBefore( node, children[ startOffset ] ); startContainer.insertBefore( node, children[ startOffset ] );
@ -1390,18 +1390,6 @@ var keyHandlers = {
range = self._createRange( nodeAfterSplit, 0 ); range = self._createRange( nodeAfterSplit, 0 );
self.setSelection( range ); self.setSelection( range );
self._updatePath( range, true ); 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 );
}
}, },
backspace: function ( self, event, range ) { backspace: function ( self, event, range ) {
self._removeZWS(); self._removeZWS();
@ -1528,10 +1516,8 @@ var keyHandlers = {
tab: function ( self, event, range ) { tab: function ( self, event, range ) {
var node, parent; var node, parent;
self._removeZWS(); self._removeZWS();
// If no selection and in an empty block // If no selection and at start of block
if ( range.collapsed && if ( range.collapsed && rangeDoesStartAtBlockBoundary( range ) ) {
rangeDoesStartAtBlockBoundary( range ) &&
rangeDoesEndAtBlockBoundary( range ) ) {
node = getStartBlockOfRange( range ); node = getStartBlockOfRange( range );
// Iterate through the block's parents // Iterate through the block's parents
while ( parent = node.parentNode ) { while ( parent = node.parentNode ) {
@ -1549,6 +1535,18 @@ var keyHandlers = {
} }
} }
}, },
'shift-tab': function ( self, event, range ) {
self._removeZWS();
// If no selection and at start of block
if ( range.collapsed && rangeDoesStartAtBlockBoundary( range ) ) {
// Break list
var node = range.startContainer;
if ( getNearest( node, 'UL' ) || getNearest( node, 'OL' ) ) {
event.preventDefault();
self.modifyBlocks( decreaseListLevel, range );
}
}
},
space: function ( self, _, range ) { space: function ( self, _, range ) {
var node, parent; var node, parent;
self._recordUndoState( range ); self._recordUndoState( range );
@ -1632,7 +1630,7 @@ var spanToSemantic = {
replace: function ( doc, colour ) { replace: function ( doc, colour ) {
return createElement( doc, 'SPAN', { return createElement( doc, 'SPAN', {
'class': 'highlight', 'class': 'highlight',
style: 'background-color: ' + colour style: 'background-color:' + colour
}); });
} }
}, },
@ -2163,7 +2161,6 @@ function Squire ( doc, config ) {
this._events = {}; this._events = {};
this._sel = win.getSelection();
this._lastSelection = null; this._lastSelection = null;
// IE loses selection state of iframe on blur, so make sure we // IE loses selection state of iframe on blur, so make sure we
@ -2426,6 +2423,25 @@ proto._createRange =
return domRange; return domRange;
}; };
proto.scrollRangeIntoView = function ( range ) {
var win = this._win;
var top = range.getBoundingClientRect().top;
var height = win.innerHeight;
var node, parent;
if ( !top ) {
node = this._doc.createElement( 'SPAN' );
range = range.cloneRange();
insertNodeInRange( range, node );
top = node.getBoundingClientRect().top;
parent = node.parentNode;
parent.removeChild( node );
parent.normalize();
}
if ( top > height ) {
win.scrollBy( 0, top - height + 20 );
}
};
proto._moveCursorTo = function ( toStart ) { proto._moveCursorTo = function ( toStart ) {
var body = this._body, var body = this._body,
range = this._createRange( body, toStart ? 0 : body.childNodes.length ); range = this._createRange( body, toStart ? 0 : body.childNodes.length );
@ -2449,17 +2465,24 @@ proto.setSelection = function ( range ) {
if ( isIOS ) { if ( isIOS ) {
this._win.focus(); this._win.focus();
} }
var sel = this._sel; var sel = this._getWindowSelection();
if ( sel ) {
sel.removeAllRanges(); sel.removeAllRanges();
sel.addRange( range ); sel.addRange( range );
this.scrollRangeIntoView( range );
}
} }
return this; return this;
}; };
proto._getWindowSelection = function () {
return this._win.getSelection() || null;
};
proto.getSelection = function () { proto.getSelection = function () {
var sel = this._sel, var sel = this._getWindowSelection(),
selection, startContainer, endContainer; selection, startContainer, endContainer;
if ( sel.rangeCount ) { if ( sel && sel.rangeCount ) {
selection = sel.getRangeAt( 0 ).cloneRange(); selection = sel.getRangeAt( 0 ).cloneRange();
startContainer = selection.startContainer; startContainer = selection.startContainer;
endContainer = selection.endContainer; endContainer = selection.endContainer;
@ -2544,6 +2567,7 @@ var removeZWS = function ( root ) {
parent = node.parentNode; parent = node.parentNode;
parent.removeChild( node ); parent.removeChild( node );
node = parent; node = parent;
walker.currentNode = parent;
} while ( isInline( node ) && !getLength( node ) ); } while ( isInline( node ) && !getLength( node ) );
break; break;
} else { } else {
@ -2734,7 +2758,7 @@ proto._recordUndoState = function ( range ) {
undoStack = this._undoStack; undoStack = this._undoStack;
// Truncate stack if longer (i.e. if has been previously undone) // Truncate stack if longer (i.e. if has been previously undone)
if ( undoIndex < this._undoStackLength) { if ( undoIndex < this._undoStackLength ) {
undoStack.length = this._undoStackLength = undoIndex; undoStack.length = this._undoStackLength = undoIndex;
} }
@ -2803,6 +2827,20 @@ proto.hasFormat = function ( tag, attributes, range ) {
return false; return false;
} }
// Sanitize range to prevent weird IE artifacts
if ( !range.collapsed &&
range.startContainer.nodeType === TEXT_NODE &&
range.startOffset === range.startContainer.length &&
range.startContainer.nextSibling ) {
range.setStartBefore( range.startContainer.nextSibling );
}
if ( !range.collapsed &&
range.endContainer.nodeType === TEXT_NODE &&
range.endOffset === 0 &&
range.endContainer.previousSibling ) {
range.setEndAfter( range.endContainer.previousSibling );
}
// If the common ancestor is inside the tag we require, we definitely // If the common ancestor is inside the tag we require, we definitely
// have the format. // have the format.
var root = range.commonAncestorContainer, var root = range.commonAncestorContainer,
@ -2838,10 +2876,13 @@ proto.hasFormat = function ( tag, attributes, range ) {
// holding the cursor. If there's a selection, returns an empty object. // holding the cursor. If there's a selection, returns an empty object.
proto.getFontInfo = function ( range ) { proto.getFontInfo = function ( range ) {
var fontInfo = { var fontInfo = {
color: undefined,
backgroundColor: undefined,
family: undefined, family: undefined,
size: undefined size: undefined
}, };
element, style; var seenAttributes = 0;
var element, style;
if ( !range && !( range = this.getSelection() ) ) { if ( !range && !( range = this.getSelection() ) ) {
return fontInfo; return fontInfo;
@ -2852,13 +2893,22 @@ proto.getFontInfo = function ( range ) {
if ( element.nodeType === TEXT_NODE ) { if ( element.nodeType === TEXT_NODE ) {
element = element.parentNode; element = element.parentNode;
} }
while ( !( fontInfo.family && fontInfo.size ) && while ( seenAttributes < 4 && element && ( style = element.style ) ) {
element && ( style = element.style ) ) { if ( !fontInfo.color ) {
fontInfo.color = style.color;
seenAttributes += 1;
}
if ( !fontInfo.backgroundColor ) {
fontInfo.backgroundColor = style.backgroundColor;
seenAttributes += 1;
}
if ( !fontInfo.family ) { if ( !fontInfo.family ) {
fontInfo.family = style.fontFamily; fontInfo.family = style.fontFamily;
seenAttributes += 1;
} }
if ( !fontInfo.size ) { if ( !fontInfo.size ) {
fontInfo.size = style.fontSize; fontInfo.size = style.fontSize;
seenAttributes += 1;
} }
element = element.parentNode; element = element.parentNode;
} }
@ -2898,9 +2948,9 @@ proto._addFormat = function ( tag, attributes, range ) {
SHOW_TEXT|SHOW_ELEMENT, SHOW_TEXT|SHOW_ELEMENT,
function ( node ) { function ( node ) {
return ( node.nodeType === TEXT_NODE || return ( node.nodeType === TEXT_NODE ||
node.nodeName === 'BR'|| node.nodeName === 'BR' ||
node.nodeName === 'IMG' ) && node.nodeName === 'IMG'
isNodeContainedInRange( range, node, true ); ) && isNodeContainedInRange( range, node, true );
}, },
false false
); );
@ -3641,14 +3691,18 @@ proto.insertHTML = function ( html, isPaste ) {
proto.insertPlainText = function ( plainText, isPaste ) { proto.insertPlainText = function ( plainText, isPaste ) {
var lines = plainText.split( '\n' ), var lines = plainText.split( '\n' ),
i, l; i, l, line;
for ( i = 1, l = lines.length - 1; i < l; i += 1 ) { for ( i = 0, l = lines.length; i < l; i += 1 ) {
lines[i] = '<DIV>' + line = lines[i];
lines[i].split( '&' ).join( '&amp;' ) line = line.split( '&' ).join( '&amp;' )
.split( '<' ).join( '&lt;' ) .split( '<' ).join( '&lt;' )
.split( '>' ).join( '&gt;' ) .split( '>' ).join( '&gt;' )
.replace( / (?= )/g, '&nbsp;' ) + .replace( / (?= )/g, '&nbsp;' );
'</DIV>'; // Wrap all but first/last lines in <div></div>
if ( i && i + 1 < l ) {
line = '<DIV>' + ( line || '<BR>' ) + '</DIV>';
}
lines[i] = line;
} }
return this.insertHTML( lines.join( '' ), isPaste ); return this.insertHTML( lines.join( '' ), isPaste );
}; };
@ -3754,7 +3808,7 @@ proto.setTextColour = function ( colour ) {
tag: 'SPAN', tag: 'SPAN',
attributes: { attributes: {
'class': 'colour', 'class': 'colour',
style: 'color: ' + colour style: 'color:' + colour
} }
}, { }, {
tag: 'SPAN', tag: 'SPAN',
@ -3768,7 +3822,7 @@ proto.setHighlightColour = function ( colour ) {
tag: 'SPAN', tag: 'SPAN',
attributes: { attributes: {
'class': 'highlight', 'class': 'highlight',
style: 'background-color: ' + colour style: 'background-color:' + colour
} }
}, { }, {
tag: 'SPAN', tag: 'SPAN',

File diff suppressed because one or more lines are too long