Changeset 769

Show
Ignore:
Timestamp:
2007-09-04 07:08:28 (13 months ago)
Author:
martinkou
Message:

Added logic for separating vertically spaced text into paragraphs, which should be useful for applying block type formats and formatting lists.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • FCKeditor/branches/features/style/editor/_source/classes/fckstyle.js

    r768 r769  
    12081208 
    12091209                return ( matchCount == styleAttribs._length ) ; 
     1210        }, 
     1211 
     1212        _CheckIsParagraphBoundary : function( node ) 
     1213        { 
     1214                if ( node.nodeType == 1 ) 
     1215                { 
     1216                        var tagName = node.tagName.toLowerCase() ; 
     1217                        return ! ( FCKListsLib.InlineNonEmptyElements[tagName] || tagName == 'img' ) ; 
     1218                } 
     1219                return false ; 
     1220        }, 
     1221 
     1222        _GenerateParagraphRange : function( paragraphList, targetWindow, startNode, endNode ) 
     1223        { 
     1224                if ( ! startNode || ! endNode ) 
     1225                        return ; 
     1226                var range = new FCKDomRange( targetWindow ) ; 
     1227                range._Range = new FCKW3CRange( targetWindow.document ) ; 
     1228                range._Range.setStart( startNode, 0 ) ; 
     1229                range._Range.setEnd( endNode, endNode.nodeType == 1 ? endNode.childNodes.length : endNode.nodeValue.length ) ; 
     1230                range._UpdateElementInfo() ; 
     1231                paragraphList.push( range ) ; 
     1232        }, 
     1233 
     1234        _GetSelectedParagraphs : function( targetWindow ) 
     1235        { 
     1236                var range = new FCKDomRange( targetWindow ) ; 
     1237                range.MoveToSelection() ; 
     1238 
     1239                var startNode = range._Range.startContainer ; 
     1240                var endNode = range._Range.endContainer ; 
     1241                var startOffset = range._Range.startOffset ; 
     1242                var endOffset = range._Range.endOffset ; 
     1243                if ( startNode.childNodes && startNode.childNodes[startOffset] ) 
     1244                        startNode = startNode.childNodes[startOffset] ; 
     1245                if ( endNode.childNodes && endNode.childNodes[endOffset] ) 
     1246                        endNode = endNode.childNodes[endOffset] ; 
     1247 
     1248                // Get the starting point of the selection's paragraph. 
     1249                var paragraphStartNode = startNode ; 
     1250                while ( paragraphStartNode ) 
     1251                { 
     1252                        var candidate = null ; 
     1253                        if ( paragraphStartNode.previousSibling ) 
     1254                        { 
     1255                                if ( ! this._CheckIsParagraphBoundary( paragraphStartNode.previousSibling ) ) 
     1256                                        candidate = paragraphStartNode.previousSibling ; 
     1257                                while ( candidate && candidate.lastChild && ! this._CheckIsParagraphBoundary( candidate.lastChild ) ) 
     1258                                        candidate = candidate.lastChild ; 
     1259                        } 
     1260                        else 
     1261                        { 
     1262                                if ( ! this._CheckIsParagraphBoundary( paragraphStartNode.parentNode ) ) 
     1263                                        candidate = paragraphStartNode.parentNode ; 
     1264                        } 
     1265 
     1266                        if ( candidate ) 
     1267                                paragraphStartNode = candidate ; 
     1268                        else 
     1269                                break ; 
     1270                } 
     1271 
     1272                // Get the ending point of the selection's paragraph. 
     1273                var paragraphEndNode = endNode ; 
     1274                while ( paragraphEndNode ) 
     1275                { 
     1276                        var candidate = null ; 
     1277                        if ( paragraphEndNode.firstChild ) 
     1278                        { 
     1279                                if ( ! this._CheckIsParagraphBoundary( paragraphEndNode.firstChild ) ) 
     1280                                        candidate = paragraphEndNode.firstChild ; 
     1281                        } 
     1282                        else if ( paragraphEndNode.nextSibling ) 
     1283                        { 
     1284                                if ( ! this._CheckIsParagraphBoundary( paragraphEndNode.nextSibling ) ) 
     1285                                        candidate = paragraphEndNode.nextSibling ; 
     1286                        } 
     1287                        else 
     1288                        { 
     1289                                var ancestor = paragraphEndNode.parentNode ; 
     1290                                while ( ancestor ) 
     1291                                { 
     1292                                        if ( this._CheckIsParagraphBoundary( ancestor ) ) 
     1293                                                break ; 
     1294                                        if ( ancestor.nextSibling ) 
     1295                                        { 
     1296                                                if ( this._CheckIsParagraphBoundary( ancestor.nextSibling ) ) 
     1297                                                        break ; 
     1298                                                candidate = ancestor.nextSibling ; 
     1299                                                break ; 
     1300                                        } 
     1301                                        else 
     1302                                                ancestor = ancestor.parentNode ; 
     1303                                } 
     1304                        } 
     1305 
     1306                        if ( candidate ) 
     1307                                paragraphEndNode = candidate ; 
     1308                        else 
     1309                                break ; 
     1310                } 
     1311 
     1312                // Break up the range between paragraphStartNode and paragraphEndNode into paragraphs represented by ranges. 
     1313                var retval = [] ; 
     1314                var currentStart = paragraphStartNode ; 
     1315                var currentEnd = currentStart ; 
     1316 
     1317                // Each iteration advances the position by one node in a DFS tree walk. 
     1318                while ( currentEnd != paragraphEndNode ) 
     1319                { 
     1320                        // 1. if we come across a <br> node, save a new paragraph 
     1321                        // 2. if we come across a block element boundary, save a new paragraph 
     1322                        // 3. set currentStart to null after saving a new paragraph 
     1323                        // 4. set currentStart to currentEnd if currentStart is null and currentEnd is not boundary node 
     1324                        if ( currentStart == null && currentEnd.nodeType == 3 ) 
     1325                        { 
     1326                                // Ignore normal whitespaces (i.e. not including &nbsp; or other unicode whitespaces) after a block node. 
     1327                                if ( currentEnd.nodeValue.search( /^[\r\n\t ]*$/ ) == 0 ) 
     1328                                { 
     1329                                        var prevNode = currentEnd.previousSibling ; 
     1330                                        if ( prevNode ) 
     1331                                        { 
     1332                                                var prevTag = String( prevNode.tagName ).toLowerCase() ; 
     1333                                                if ( ! ( FCKListsLib.BlockElements[prevTag] || FCKListsLib.NonEmptyBlockElements[prevTag] ) ) 
     1334                                                        currentStart = currentEnd ; 
     1335                                        } 
     1336                                } 
     1337                                else 
     1338                                        currentStart = currentEnd ; 
     1339                        } 
     1340 
     1341                        if ( currentEnd.firstChild ) 
     1342                        { 
     1343                                if ( this._CheckIsParagraphBoundary( currentEnd.firstChild ) ) 
     1344                                { 
     1345                                        this._GenerateParagraphRange( retval, targetWindow, currentStart, currentEnd ) ; 
     1346                                        currentStart = null ; 
     1347                                } 
     1348                                currentEnd = currentEnd.firstChild ; 
     1349                        } 
     1350                        else if ( currentEnd.nextSibling ) 
     1351                        { 
     1352                                if ( this._CheckIsParagraphBoundary( currentEnd.nextSibling ) ) 
     1353                                { 
     1354                                        this._GenerateParagraphRange( retval, targetWindow, currentStart, currentEnd ) ; 
     1355                                        currentStart = null ; 
     1356                                } 
     1357                                currentEnd = currentEnd.nextSibling ; 
     1358                        } 
     1359                        else 
     1360                        { 
     1361                                var ancestor = currentEnd.parentNode ; 
     1362                                while ( ancestor ) 
     1363                                { 
     1364                                        if ( this._CheckIsParagraphBoundary( ancestor ) ) 
     1365                                        { 
     1366                                                this._GenerateParagraphRange( retval, targetWindow, currentStart, currentEnd ) ; 
     1367                                                currentStart = null ; 
     1368                                        } 
     1369                                        if ( ancestor.nextSibling ) 
     1370                                        { 
     1371                                                if ( this._CheckIsParagraphBoundary( ancestor.nextSibling ) ) 
     1372                                                { 
     1373                                                        this._GenerateParagraphRange( retval, targetWindow, currentStart, currentEnd ) ; 
     1374                                                        currentStart = null ; 
     1375                                                } 
     1376                                                currentEnd = ancestor.nextSibling ; 
     1377                                                break ; 
     1378                                        } 
     1379                                        else 
     1380                                                ancestor = ancestor.parentNode ; 
     1381                                } 
     1382                        } 
     1383                } 
     1384                // Record the final range as well. 
     1385                if ( currentStart == null && currentEnd.nodeType == 3 ) 
     1386                        currentStart = currentEnd ; 
     1387                this._GenerateParagraphRange( retval, targetWindow, currentStart, currentEnd ) ; 
     1388 
     1389                return retval ; 
    12101390        } 
    12111391} ;