📄 enter-paragraphs.js
字号:
// tabs 2
/**
* @fileoverview By Adam Wright, for The University of Western Australia
*
* Distributed under the same terms as HTMLArea itself.
* This notice MUST stay intact for use (see license.txt).
*
* Heavily modified by Yermo Lamers of DTLink, LLC, College Park, Md., USA.
* For more info see http://www.areaedit.com
*/
/**
* plugin Info
*/
EnterParagraphs._pluginInfo =
{
name : "EnterParagraphs",
version : "1.0",
developer : "Adam Wright",
developer_url : "http://www.hipikat.org/",
sponsor : "The University of Western Australia",
sponsor_url : "http://www.uwa.edu.au/",
license : "htmlArea"
};
// ------------------------------------------------------------------
// "constants"
/**
* Whitespace Regex
*/
EnterParagraphs.prototype._whiteSpace = /^\s*$/;
/**
* The pragmatic list of which elements a paragraph may not contain
*/
EnterParagraphs.prototype._pExclusions = /^(address|blockquote|body|dd|div|dl|dt|fieldset|form|h1|h2|h3|h4|h5|h6|hr|li|noscript|ol|p|pre|table|ul)$/i;
/**
* elements which may contain a paragraph
*/
EnterParagraphs.prototype._pContainers = /^(body|del|div|fieldset|form|ins|map|noscript|object|td|th)$/i;
/**
* Elements which may not contain paragraphs, and would prefer a break to being split
*/
EnterParagraphs.prototype._pBreak = /^(address|pre|blockquote)$/i;
/**
* Elements which may not contain children
*/
EnterParagraphs.prototype._permEmpty = /^(area|base|basefont|br|col|frame|hr|img|input|isindex|link|meta|param)$/i;
/**
* Elements which count as content, as distinct from whitespace or containers
*/
EnterParagraphs.prototype._elemSolid = /^(applet|br|button|hr|img|input|table)$/i;
/**
* Elements which should get a new P, before or after, when enter is pressed at either end
*/
EnterParagraphs.prototype._pifySibling = /^(address|blockquote|del|div|dl|fieldset|form|h1|h2|h3|h4|h5|h6|hr|ins|map|noscript|object|ol|p|pre|table|ul|)$/i;
EnterParagraphs.prototype._pifyForced = /^(ul|ol|dl|table)$/i;
/**
* Elements which should get a new P, before or after a close parent, when enter is pressed at either end
*/
EnterParagraphs.prototype._pifyParent = /^(dd|dt|li|td|th|tr)$/i;
// ---------------------------------------------------------------------
/**
* EnterParagraphs Constructor
*/
function EnterParagraphs(editor)
{
this.editor = editor;
// [STRIP
// create a ddt debug trace object. There may be multiple editors on
// the page each EnterParagraphs .. to distinguish which instance
// is generating the message we tack on the name of the textarea.
//this.ddt = new DDT( editor._textArea + ":EnterParagraphs Plugin" );
// uncomment to turn on debugging messages.
//this.ddt._ddtOn();
//this.ddt._ddt( "enter-paragraphs.js","23", "EnterParagraphs(): constructor" );
// STRIP]
// hook into the event handler to intercept key presses if we are using
// gecko (Mozilla/FireFox)
if (HTMLArea.is_gecko)
{
//this.ddt._ddt( "enter-paragraphs.js","23", "EnterParagraphs(): we are gecko. Setting event handler." );
this.onKeyPress = this.__onKeyPress;
}
} // end of constructor.
// ------------------------------------------------------------------
/**
* name member for debugging
*
* This member is used to identify objects of this class in debugging
* messages.
*/
EnterParagraphs.prototype.name = "EnterParagraphs";
/**
* Gecko's a bit lacking in some odd ways...
*/
EnterParagraphs.prototype.insertAdjacentElement = function(ref,pos,el)
{
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "122", "insertAdjacentElement(): top with pos '" + pos + "' ref:", ref );
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "122", "insertAdjacentElement(): top with el:", el );
if ( pos == 'BeforeBegin' )
{
ref.parentNode.insertBefore(el,ref);
}
else if ( pos == 'AfterEnd' )
{
ref.nextSibling ? ref.parentNode.insertBefore(el,ref.nextSibling) : ref.parentNode.appendChild(el);
}
else if ( pos == 'AfterBegin' && ref.firstChild )
{
ref.insertBefore(el,ref.firstChild);
}
else if ( pos == 'BeforeEnd' || pos == 'AfterBegin' )
{
ref.appendChild(el);
}
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "122", "insertAdjacentElement(): bottom with ref:", ref );
}; // end of insertAdjacentElement()
// ----------------------------------------------------------------
/**
* Passes a global parent node or document fragment to forEachNode
*
* @param root node root node to start search from.
* @param mode string function to apply to each node.
* @param direction string traversal direction "ltr" (left to right) or "rtl" (right_to_left)
* @param init boolean
*/
EnterParagraphs.prototype.forEachNodeUnder = function ( root, mode, direction, init )
{
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "144", "forEachNodeUnder(): top mode is '" + mode + "' direction is '" + direction + "' starting with root node:", root );
// Identify the first and last nodes to deal with
var start, end;
// nodeType 11 is DOCUMENT_FRAGMENT_NODE which is a container.
if ( root.nodeType == 11 && root.firstChild )
{
start = root.firstChild;
end = root.lastChild;
}
else
{
start = end = root;
}
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "144", "forEachNodeUnder(): start node is:", start );
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "144", "forEachNodeUnder(): initial end node is:", end );
// traverse down the right hand side of the tree getting the last child of the last
// child in each level until we reach bottom.
while ( end.lastChild )
end = end.lastChild;
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "144", "forEachNodeUnder(): end node after descent is:", end );
return this.forEachNode( start, end, mode, direction, init);
}; // end of forEachNodeUnder()
// -----------------------------------------------------------------------
/**
* perform a depth first descent in the direction requested.
*
* @param left_node node "start node"
* @param right_node node "end node"
* @param mode string function to apply to each node. cullids or emptyset.
* @param direction string traversal direction "ltr" (left to right) or "rtl" (right_to_left)
* @param init boolean or object.
*/
EnterParagraphs.prototype.forEachNode = function (left_node, right_node, mode, direction, init)
{
//this.ddt._ddt( "enter-paragraphs.js", "175", "forEachNode(): top - mode is:" + mode + "' direction '" + direction + "'" );
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "175", "forEachNode(): top - left node is:", left_node );
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "175", "forEachNode(): top - right node is:", right_node );
// returns "Brother" node either left or right.
var getSibling = function(elem, direction)
{
return ( direction == "ltr" ? elem.nextSibling : elem.previousSibling );
};
var getChild = function(elem, direction)
{
return ( direction == "ltr" ? elem.firstChild : elem.lastChild );
};
var walk, lookup, fnReturnVal;
// FIXME: init is a boolean in the emptyset case and an object in
// the cullids case. Used inconsistently.
var next_node = init;
// used to flag having reached the last node.
var done_flag = false;
// loop ntil we've hit the last node in the given direction.
// if we're going left to right that's the right_node and visa-versa.
while ( walk != direction == "ltr" ? right_node : left_node )
{
// on first entry, walk here is null. So this is how
// we prime the loop with the first node.
if ( !walk )
{
walk = direction == "ltr" ? left_node : right_node;
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "175", "forEachNode(): !walk - current node is:", walk );
}
else
{
// is there a child node?
if ( getChild(walk,direction) )
{
// descend down into the child.
walk = getChild(walk,direction);
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "175", "forEachNode():descending to child node:", walk );
}
else
{
// is there a sibling node on this level?
if ( getSibling(walk,direction) )
{
// move to the sibling.
walk = getSibling(walk,direction);
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "175", "forEachNode(): moving to sibling node:", walk );
}
else
{
lookup = walk;
// climb back up the tree until we find a level where we are not the end
// node on the level (i.e. that we have a sibling in the direction
// we are searching) or until we reach the end.
while ( !getSibling(lookup,direction) && lookup != (direction == "ltr" ? right_node : left_node) )
{
lookup = lookup.parentNode;
}
// did we find a level with a sibling?
// walk = ( lookup.nextSibling ? lookup.nextSibling : lookup ) ;
walk = ( getSibling(lookup,direction) ? getSibling(lookup,direction) : lookup ) ;
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "175", "forEachNode(): climbed back up (or found right node):", walk );
}
}
} // end of else walk.
// have we reached the end? either as a result of the top while loop or climbing
// back out above.
done_flag = (walk==( direction == "ltr" ? right_node : left_node));
// call the requested function on the current node. Functions
// return an array.
//
// Possible functions are _fenCullIds, _fenEmptySet
//
// The situation is complicated by the fact that sometimes we want to
// return the base node and sometimes we do not.
//
// next_node can be an object (this.takenIds), a node (text, el, etc) or false.
//this.ddt._ddt( "enter-paragraphs.js", "175", "forEachNode(): calling function" );
switch( mode )
{
case "cullids":
fnReturnVal = this._fenCullIds(walk, next_node );
break;
case "find_fill":
fnReturnVal = this._fenEmptySet(walk, next_node, mode, done_flag);
break;
case "find_cursorpoint":
fnReturnVal = this._fenEmptySet(walk, next_node, mode, done_flag);
break;
}
// If this node wants us to return, return next_node
if ( fnReturnVal[0] )
{
//this.ddt._ddtDumpNode( "enter-paragraphs.js", "175", "forEachNode(): returning node:", fnReturnVal[1] );
return fnReturnVal[1];
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -