mirror of
https://github.com/fastmail/Squire.git
synced 2024-12-22 07:13:08 -05:00
Memoize node category with weak map
Fix horrendous performance of isInline etc.
This commit is contained in:
parent
5d24e3eb4d
commit
f46dee1255
5 changed files with 78 additions and 24 deletions
|
@ -47,6 +47,7 @@ var cantFocusEmptyTextNodes = isIElt11 || isWebKit;
|
|||
var losesSelectionOnBlur = isIElt11;
|
||||
|
||||
var canObserveMutations = typeof MutationObserver !== 'undefined';
|
||||
var canWeakMap = typeof WeakMap !== 'undefined';
|
||||
|
||||
// Use [^ \t\r\n] instead of \S so that nbsp does not count as white-space
|
||||
var notWS = /[^ \t\r\n]/;
|
||||
|
@ -201,25 +202,48 @@ function every ( nodeList, fn ) {
|
|||
|
||||
// ---
|
||||
|
||||
var UNKNOWN = 0;
|
||||
var INLINE = 1;
|
||||
var BLOCK = 2;
|
||||
var CONTAINER = 3;
|
||||
|
||||
var nodeCategoryCache = canWeakMap ? new WeakMap() : null;
|
||||
|
||||
function isLeaf ( node ) {
|
||||
return node.nodeType === ELEMENT_NODE &&
|
||||
!!leafNodeNames[ node.nodeName ];
|
||||
return node.nodeType === ELEMENT_NODE && !!leafNodeNames[ node.nodeName ];
|
||||
}
|
||||
function isInline ( node ) {
|
||||
return inlineNodeNames.test( node.nodeName ) &&
|
||||
function getNodeCategory ( node ) {
|
||||
if ( canWeakMap && nodeCategoryCache.has( node ) ) {
|
||||
return nodeCategoryCache.get( node );
|
||||
}
|
||||
var type = node.nodeType;
|
||||
var nodeCategory;
|
||||
if ( type === TEXT_NODE ) {
|
||||
nodeCategory = INLINE;
|
||||
} else if ( type !== ELEMENT_NODE && type !== DOCUMENT_FRAGMENT_NODE ) {
|
||||
nodeCategory = UNKNOWN;
|
||||
} else if ( !every( node.childNodes, isInline ) ) {
|
||||
// Malformed HTML can have block tags inside inline tags. Need to treat
|
||||
// these as containers rather than inline. See #239.
|
||||
( node.nodeType === TEXT_NODE || every( node.childNodes, isInline ) );
|
||||
nodeCategory = CONTAINER;
|
||||
} else if ( inlineNodeNames.test( node.nodeName ) ) {
|
||||
nodeCategory = INLINE;
|
||||
} else {
|
||||
nodeCategory = BLOCK;
|
||||
}
|
||||
if ( canWeakMap ) {
|
||||
nodeCategoryCache.set( node, nodeCategory );
|
||||
}
|
||||
return nodeCategory;
|
||||
}
|
||||
function isInline ( node ) {
|
||||
return getNodeCategory( node ) === INLINE;
|
||||
}
|
||||
function isBlock ( node ) {
|
||||
var type = node.nodeType;
|
||||
return ( type === ELEMENT_NODE || type === DOCUMENT_FRAGMENT_NODE ) &&
|
||||
!isInline( node ) && every( node.childNodes, isInline );
|
||||
return getNodeCategory( node ) === BLOCK;
|
||||
}
|
||||
function isContainer ( node ) {
|
||||
var type = node.nodeType;
|
||||
return ( type === ELEMENT_NODE || type === DOCUMENT_FRAGMENT_NODE ) &&
|
||||
!isInline( node ) && !isBlock( node );
|
||||
return getNodeCategory( node ) === CONTAINER;
|
||||
}
|
||||
|
||||
function getBlockWalker ( node, root ) {
|
||||
|
@ -3110,6 +3134,9 @@ proto._keyUpDetectChange = function ( event ) {
|
|||
};
|
||||
|
||||
proto._docWasChanged = function () {
|
||||
if ( canWeakMap ) {
|
||||
nodeCategoryCache = new WeakMap();
|
||||
}
|
||||
if ( this._ignoreAllChanges ) {
|
||||
return;
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -43,6 +43,7 @@ var cantFocusEmptyTextNodes = isIElt11 || isWebKit;
|
|||
var losesSelectionOnBlur = isIElt11;
|
||||
|
||||
var canObserveMutations = typeof MutationObserver !== 'undefined';
|
||||
var canWeakMap = typeof WeakMap !== 'undefined';
|
||||
|
||||
// Use [^ \t\r\n] instead of \S so that nbsp does not count as white-space
|
||||
var notWS = /[^ \t\r\n]/;
|
||||
|
|
|
@ -746,6 +746,9 @@ proto._keyUpDetectChange = function ( event ) {
|
|||
};
|
||||
|
||||
proto._docWasChanged = function () {
|
||||
if ( canWeakMap ) {
|
||||
nodeCategoryCache = new WeakMap();
|
||||
}
|
||||
if ( this._ignoreAllChanges ) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -22,25 +22,48 @@ function every ( nodeList, fn ) {
|
|||
|
||||
// ---
|
||||
|
||||
var UNKNOWN = 0;
|
||||
var INLINE = 1;
|
||||
var BLOCK = 2;
|
||||
var CONTAINER = 3;
|
||||
|
||||
var nodeCategoryCache = canWeakMap ? new WeakMap() : null;
|
||||
|
||||
function isLeaf ( node ) {
|
||||
return node.nodeType === ELEMENT_NODE &&
|
||||
!!leafNodeNames[ node.nodeName ];
|
||||
return node.nodeType === ELEMENT_NODE && !!leafNodeNames[ node.nodeName ];
|
||||
}
|
||||
function isInline ( node ) {
|
||||
return inlineNodeNames.test( node.nodeName ) &&
|
||||
function getNodeCategory ( node ) {
|
||||
if ( canWeakMap && nodeCategoryCache.has( node ) ) {
|
||||
return nodeCategoryCache.get( node );
|
||||
}
|
||||
var type = node.nodeType;
|
||||
var nodeCategory;
|
||||
if ( type === TEXT_NODE ) {
|
||||
nodeCategory = INLINE;
|
||||
} else if ( type !== ELEMENT_NODE && type !== DOCUMENT_FRAGMENT_NODE ) {
|
||||
nodeCategory = UNKNOWN;
|
||||
} else if ( !every( node.childNodes, isInline ) ) {
|
||||
// Malformed HTML can have block tags inside inline tags. Need to treat
|
||||
// these as containers rather than inline. See #239.
|
||||
( node.nodeType === TEXT_NODE || every( node.childNodes, isInline ) );
|
||||
nodeCategory = CONTAINER;
|
||||
} else if ( inlineNodeNames.test( node.nodeName ) ) {
|
||||
nodeCategory = INLINE;
|
||||
} else {
|
||||
nodeCategory = BLOCK;
|
||||
}
|
||||
if ( canWeakMap ) {
|
||||
nodeCategoryCache.set( node, nodeCategory );
|
||||
}
|
||||
return nodeCategory;
|
||||
}
|
||||
function isInline ( node ) {
|
||||
return getNodeCategory( node ) === INLINE;
|
||||
}
|
||||
function isBlock ( node ) {
|
||||
var type = node.nodeType;
|
||||
return ( type === ELEMENT_NODE || type === DOCUMENT_FRAGMENT_NODE ) &&
|
||||
!isInline( node ) && every( node.childNodes, isInline );
|
||||
return getNodeCategory( node ) === BLOCK;
|
||||
}
|
||||
function isContainer ( node ) {
|
||||
var type = node.nodeType;
|
||||
return ( type === ELEMENT_NODE || type === DOCUMENT_FRAGMENT_NODE ) &&
|
||||
!isInline( node ) && !isBlock( node );
|
||||
return getNodeCategory( node ) === CONTAINER;
|
||||
}
|
||||
|
||||
function getBlockWalker ( node, root ) {
|
||||
|
|
Loading…
Reference in a new issue