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:
parent
fca4202e45
commit
2d44b9af2d
2 changed files with 101 additions and 47 deletions
|
@ -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( '&' )
|
line = line.split( '&' ).join( '&' )
|
||||||
.split( '<' ).join( '<' )
|
.split( '<' ).join( '<' )
|
||||||
.split( '>' ).join( '>' )
|
.split( '>' ).join( '>' )
|
||||||
.replace( / (?= )/g, ' ' ) +
|
.replace( / (?= )/g, ' ' );
|
||||||
'</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
Loading…
Reference in a new issue