📄 enter-paragraphs.js
字号:
// are we done with the loop?
if ( done_flag )
{
break;
}
// Otherwise, pass to the next node
if ( fnReturnVal[1] )
{
next_node = fnReturnVal[1];
}
} // end of while loop
//this.ddt._ddt( "enter-paragraphs.js", "175", "forEachNode(): returning false." );
return false;
}; // end of forEachNode()
// -------------------------------------------------------------------
/**
* Find a post-insertion node, only if all nodes are empty, or the first content
*
* @param node node current node beinge examined.
* @param next_node node next node to be examined.
* @param node string "find_fill" or "find_cursorpoint"
* @param last_flag boolean is this the last node?
*/
EnterParagraphs.prototype._fenEmptySet = function( node, next_node, mode, last_flag)
{
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "263", "_fenEmptySet() : top with mode '" + mode + "' and last_flag '" + last_flag + "' and node:", node );
// Mark this if it's the first base
if ( !next_node && !node.firstChild )
{
next_node = node;
}
// Is it an element node and is it considered content? (br, hr, etc)
// or is it a text node that is not just whitespace?
// or is it not an element node and not a text node?
if ( (node.nodeType == 1 && this._elemSolid.test(node.nodeName)) ||
(node.nodeType == 3 && !this._whiteSpace.test(node.nodeValue)) ||
(node.nodeType != 1 && node.nodeType != 3) )
{
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "263", "_fenEmptySet() : found content in node:", node );
switch( mode )
{
case "find_fill":
// does not return content.
return new Array(true, false );
breal;
case "find_cursorpoint":
// returns content
return new Array(true, node );
break;
}
}
// In either case (fill or findcursor) we return the base node. The avoids
// problems in terminal cases (beginning or end of document or container tags)
if ( last_flag )
{
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "263", "_fenEmptySet() : return 'base' node:", next_node );
return new Array( true, next_node );
}
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "263", "_fenEmptySet() : bottom returning false and :", next_node );
return new Array( false, next_node );
}; // end of _fenEmptySet()
// ------------------------------------------------------------------------------
/**
* remove duplicate Id's.
*
* @param ep_ref enterparagraphs reference to enterparagraphs object
*/
EnterParagraphs.prototype._fenCullIds = function ( ep_ref, node, pong )
{
//this.ddt._ddt( "enter-paragraphs.js", "299", "_fenCullIds(): top" );
// Check for an id, blast it if it's in the store, otherwise add it
if ( node.id )
{
//this.ddt._ddt( "enter-paragraphs.js", "299", "_fenCullIds(): node '" + node.nodeName + "' has an id '" + node.id + "'" );
pong[node.id] ? node.id = '' : pong[node.id] = true;
}
return new Array(false,pong);
};
// ---------------------------------------------------------------------------------
/**
* Grabs a range suitable for paragraph stuffing
*
* @param rng Range
* @param search_direction string "left" or "right"
*
* @todo check blank node issue in roaming loop.
*/
EnterParagraphs.prototype.processSide = function( rng, search_direction)
{
//this.ddt._ddt( "enter-paragraphs.js", "329", "processSide(): top search_direction == '" + search_direction + "'" );
var next = function(element, search_direction)
{
return ( search_direction == "left" ? element.previousSibling : element.nextSibling );
};
var node = search_direction == "left" ? rng.startContainer : rng.endContainer;
var offset = search_direction == "left" ? rng.startOffset : rng.endOffset;
var roam, start = node;
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "337", "processSide(): starting with node:", node );
// Never start with an element, because then the first roaming node might
// be on the exclusion list and we wouldn't know until it was too late
while ( start.nodeType == 1 && !this._permEmpty.test(start.nodeName) )
{
start = ( offset ? start.lastChild : start.firstChild );
}
// Climb the tree, left or right, until our course of action presents itself
//
// if roam is NULL try start.
// if roam is NOT NULL, try next node in our search_direction
// If that node is NULL, get our parent node.
//
// If all the above turns out NULL end the loop.
//
// FIXME: gecko (firefox 1.0.3) - enter "test" into an empty document and press enter.
// sometimes this loop finds a blank text node, sometimes it doesn't.
while ( roam = roam ? ( next(roam,search_direction) ? next(roam,search_direction) : roam.parentNode ) : start )
{
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "357", "processSide(): roaming loop, search_direction is '" + search_direction + "' current node is: ", roam );
// next() is an inline function defined above that returns the next node depending
// on the direction we're searching.
if ( next(roam,search_direction) )
{
//this.ddt._ddt( "enter-paragraphs.js", "371", "processSide(): Checking next node '" + next(roam,search_direction).NodeName + "' for _pExclusions list." );
// If the next sibling's on the exclusion list, stop before it
if ( this._pExclusions.test(next(roam,search_direction).nodeName) )
{
//this.ddt._ddt( "enter-paragraphs.js", "371", "processSide(): Node '" + next(roam,search_direction).NodeName + "' is on the _pExclusions list. Stopping before it." );
return this.processRng(rng, search_direction, roam, next(roam,search_direction), (search_direction == "left"?'AfterEnd':'BeforeBegin'), true, false);
}
}
else
{
//this.ddt._ddt( "enter-paragraphs.js", "371", "processSide(): No next node, examing parent node '" + roam.parentNode.nodeName + "' for containers or exclusions." );
// If our parent's on the container list, stop inside it
if (this._pContainers.test(roam.parentNode.nodeName))
{
//this.ddt._ddt( "enter-paragraphs.js", "371", "processSide(): Parent Node '" + roam.parentNode.nodeName + "' is on the _pContainer list. Stopping inside it." );
return this.processRng(rng, search_direction, roam, roam.parentNode, (search_direction == "left"?'AfterBegin':'BeforeEnd'), true, false);
}
else if (this._pExclusions.test(roam.parentNode.nodeName))
{
//this.ddt._ddt( "enter-paragraphs.js", "371", "processSide(): Parent Node '" + roam.parentNode.nodeName + "' is on the _pExclusion list." );
// chop without wrapping
if (this._pBreak.test(roam.parentNode.nodeName))
{
//this.ddt._ddt( "enter-paragraphs.js", "371", "processSide(): Parent Node '" + roam.parentNode.nodeName + "' is on the _pBreak list." );
return this.processRng(rng, search_direction, roam, roam.parentNode,
(search_direction == "left"?'AfterBegin':'BeforeEnd'), false, (search_direction == "left" ?true:false));
}
else
{
//this.ddt._ddt( "enter-paragraphs.js", "371", "processSide(): Parent Node '" + roam.parentNode.nodeName + "' is not on the _pBreak list." );
// the next(roam,search_direction) in this call is redundant since we know it's false
// because of the "if next(roam,search_direction)" above.
//
// the final false prevents this range from being wrapped in <p>'s most likely
// because it's already wrapped.
return this.processRng(rng,
search_direction,
(roam = roam.parentNode),
(next(roam,search_direction) ? next(roam,search_direction) : roam.parentNode),
(next(roam,search_direction) ? (search_direction == "left"?'AfterEnd':'BeforeBegin') : (search_direction == "left"?'AfterBegin':'BeforeEnd')),
false,
false);
}
}
}
}
//this.ddt._ddt( "enter-paragraphs.js", "424", "processSide(): bottom" );
}; // end of processSide()
// ------------------------------------------------------------------------------
/**
* processRng - process Range.
*
* Neighbour and insertion identify where the new node, roam, needs to enter
* the document; landmarks in our selection will be deleted before insertion
*
* @param rn Range original selected range
* @param search_direction string Direction to search in.
* @param roam node
* @param insertion string may be AfterBegin of BeforeEnd
* @return array
*/
EnterParagraphs.prototype.processRng = function(rng, search_direction, roam, neighbour, insertion, pWrap, preBr)
{
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "398", "processRng(): top - roam arg is:", roam );
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "398", "processRng(): top - neighbor arg is:", neighbour );
//this.ddt._ddt( "enter-paragraphs.js", "398", "processRng(): top - insertion arg is: '" + insertion + "'" );
var node = search_direction == "left" ? rng.startContainer : rng.endContainer;
var offset = search_direction == "left" ? rng.startOffset : rng.endOffset;
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "447", "processRng(): range start (or end) is at offset '" + offset + "' is node :", node );
// Define the range to cut, and extend the selection range to the same boundary
var editor = this.editor;
var newRng = editor._doc.createRange();
newRng.selectNode(roam);
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "522", "processRng(): selecting newRng is:", newRng );
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "522", "processRng(): selecting original rng is:", rng );
// extend the range in the given direction.
if ( search_direction == "left")
{
newRng.setEnd(node, offset);
rng.setStart(newRng.startContainer, newRng.startOffset);
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "522", "processRng(): extending direction left - newRng is:", newRng );
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "522", "processRng(): extending direction left - rng is:", rng );
}
else if ( search_direction == "right" )
{
newRng.setStart(node, offset);
rng.setEnd(newRng.endContainer, newRng.endOffset);
//this.ddt._ddt( "enter-paragraphs.js", "522", "processRng(): right - new range start is '" + offset + "' end offset is '" + newRng.endOffset + "'" );
}
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "522", "processRng(): rng is:", rng );
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "522", "processRng(): newRng is:", newRng );
// Clone the range and remove duplicate ids it would otherwise produce
var cnt = newRng.cloneContents();
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "509", "processRng(): culling duplicate ids from:", cnt );
// in this case "init" is an object not a boolen.
this.forEachNodeUnder( cnt, "cullids", "ltr", this.takenIds, false, false);
// Special case, for inserting paragraphs before some blocks when caret is at
// their zero offset.
//
// Used to "open up space" in front of a list, table. Usefull if the list is at
// the top of the document. (otherwise you'd have no way of "moving it down").
var pify, pifyOffset, fill;
pify = search_direction == "left" ? (newRng.endContainer.nodeType == 3 ? true:false) : (newRng.startContainer.nodeType == 3 ? false:true);
pifyOffset = pify ? newRng.startOffset : newRng.endOffset;
pify = pify ? newRng.startContainer : newRng.endContainer;
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "521", "processRng(): pify is '" + pify.nodeName + "' pifyOffset is '" + pifyOffset + "':", pify );
if ( this._pifyParent.test(pify.nodeName) && pify.parentNode.childNodes.item(0) == pify )
{
while ( !this._pifySibling.test(pify.nodeName) )
{
pify = pify.parentNode;
}
}
// NODE TYPE 11 is DOCUMENT_FRAGMENT NODE
if ( cnt.nodeType == 11 && !cnt.firstChild )
{
cnt.appendChild(editor._doc.createElement(pify.nodeName));
}
// YmL: Added additional last parameter for fill case to work around logic
// error in forEachNode()
//this.ddt._ddt( "enter-paragraphs.js", "612", "processRng(): find_fill in cnt." );
fill = this.forEachNodeUnder(cnt, "find_fill", "ltr", false );
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "612", "processRng(): fill node:" , fill );
if ( fill &&
this._pifySibling.test(pify.nodeName) &&
( (pifyOffset == 0) || ( pifyOffset == 1 && this._pifyForced.test(pify.nodeName) ) ) )
{
//this.ddt._ddt( "enter-paragraphs.js", "544", "processRng(): pify handling. Creating p tag followed by nbsp tag" );
roam = editor._doc.createElement( 'p' );
roam.innerHTML = " ";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -