+ // If a table or list is fully selected.\r
+ function()\r
+ {\r
+ var root,\r
+ retval,\r
+ range = self.getRanges()[ 0 ],\r
+ ancestor = range.getCommonAncestor( 1, 1 ),\r
+ tags = { table:1,ul:1,ol:1,dl:1 };\r
+\r
+ for ( var t in tags )\r
+ {\r
+ if ( root = ancestor.getAscendant( t, 1 ) )\r
+ break;\r
+ }\r
+\r
+ if ( root )\r
+ {\r
+ // Enlarging the start boundary.\r
+ var testRange = new CKEDITOR.dom.range( this.document );\r
+ testRange.setStartAt( root, CKEDITOR.POSITION_AFTER_START );\r
+ testRange.setEnd( range.startContainer, range.startOffset );\r
+\r
+ var enlargeables = CKEDITOR.tools.extend( tags, CKEDITOR.dtd.$listItem, CKEDITOR.dtd.$tableContent ),\r
+ walker = new CKEDITOR.dom.walker( testRange ),\r
+ // Check the range is at the inner boundary of the structural element.\r
+ guard = function( walker, isEnd )\r
+ {\r
+ return function( node, isWalkOut )\r
+ {\r
+ if ( node.type == CKEDITOR.NODE_TEXT && ( !CKEDITOR.tools.trim( node.getText() ) || node.getParent().data( 'cke-bookmark' ) ) )\r
+ return true;\r
+\r
+ var tag;\r
+ if ( node.type == CKEDITOR.NODE_ELEMENT )\r
+ {\r
+ tag = node.getName();\r
+\r
+ // Bypass bogus br at the end of block.\r
+ if ( tag == 'br' && isEnd && node.equals( node.getParent().getBogus() ) )\r
+ return true;\r
+\r
+ if ( isWalkOut && tag in enlargeables || tag in CKEDITOR.dtd.$removeEmpty )\r
+ return true;\r
+ }\r
+\r
+ walker.halted = 1;\r
+ return false;\r
+ };\r
+ };\r
+\r
+ walker.guard = guard( walker );\r
+\r
+ if ( walker.checkBackward() && !walker.halted )\r
+ {\r
+ walker = new CKEDITOR.dom.walker( testRange );\r
+ testRange.setStart( range.endContainer, range.endOffset );\r
+ testRange.setEndAt( root, CKEDITOR.POSITION_BEFORE_END );\r
+ walker.guard = guard( walker, 1 );\r
+ if ( walker.checkForward() && !walker.halted )\r
+ retval = root.$;\r
+ }\r
+ }\r
+\r
+ if ( !retval )\r
+ throw 0;\r
+\r
+ return retval;\r
+ },\r