Changeset 682
- Timestamp:
- 01/22/07 02:29:11 (6 years ago)
- Location:
- trunk
- Files:
-
- 2 modified
-
XinhaCore.js (modified) (1 diff)
-
functionsMozilla.js (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/XinhaCore.js
r680 r682 4023 4023 4024 4024 // moved Xinha.prototype.checkBackspace() to browser specific file 4025 4026 /** The idea here is 4027 * 1. See if we are in a block element 4028 * 2. If we are not, then wrap the current "block" of text into a paragraph 4029 * 3. Now that we have a block element, select all the text between the insertion point 4030 * and just AFTER the end of the block 4031 * eg <p>The quick |brown fox jumped over the lazy dog.</p>| 4032 * --------------------------------------- 4033 * 4. Extract that from the document, making 4034 * <p>The quick </p> 4035 * and a document fragment with 4036 * <p>brown fox jumped over the lazy dog.</p> 4037 * 5. Reinsert it just after the block element 4038 * <p>The quick </p><p>brown fox jumped over the lazy dog.</p> 4039 * 4040 * Along the way, allow inserting blank paragraphs, which will look like <p><br/></p> 4041 */ 4042 4043 Xinha.prototype.dom_checkInsertP = function() 4044 { 4045 var p, body; 4046 // Get the insertion point, we'll scrub any highlighted text the user wants rid of while we are there. 4047 var sel = this.getSelection(); 4048 var range = this.createRange(sel); 4049 if ( !range.collapsed ) 4050 { 4051 range.deleteContents(); 4052 } 4053 this.deactivateEditor(); 4054 //sel.removeAllRanges(); 4055 //sel.addRange(range); 4056 4057 var SC = range.startContainer; 4058 var SO = range.startOffset; 4059 var EC = range.endContainer; 4060 var EO = range.endOffset; 4061 4062 // If the insertion point is character 0 of the 4063 // document, then insert a space character that we will wrap into a paragraph 4064 // in a bit. 4065 if ( SC == EC && SC == body && !SO && !EO ) 4066 { 4067 p = this._doc.createTextNode(" "); 4068 body.insertBefore(p, body.firstChild); 4069 range.selectNodeContents(p); 4070 SC = range.startContainer; 4071 SO = range.startOffset; 4072 EC = range.endContainer; 4073 EO = range.endOffset; 4074 } 4075 4076 // See if we are in a block element, if so, great. 4077 p = this.getAllAncestors(); 4078 4079 var block = null; 4080 body = this._doc.body; 4081 for ( var i = 0; i < p.length; ++i ) 4082 { 4083 if ( Xinha.isParaContainer(p[i]) ) 4084 { 4085 break; 4086 } 4087 else if ( Xinha.isBlockElement(p[i]) && ! ( /body|html/i.test(p[i].tagName) ) ) 4088 { 4089 block = p[i]; 4090 break; 4091 } 4092 } 4093 4094 // If not in a block element, we'll have to turn some stuff into a paragraph 4095 if ( !block ) 4096 { 4097 // We want to wrap as much stuff as possible into the paragraph in both directions 4098 // from the insertion point. We start with the start container and walk back up to the 4099 // node just before any of the paragraph containers. 4100 var wrap = range.startContainer; 4101 while ( wrap.parentNode && !Xinha.isParaContainer(wrap.parentNode) ) 4102 { 4103 wrap = wrap.parentNode; 4104 } 4105 var start = wrap; 4106 var end = wrap; 4107 4108 // Now we walk up the sibling list until we hit the top of the document 4109 // or an element that we shouldn't put in a p (eg other p, div, ul, ol, table) 4110 while ( start.previousSibling ) 4111 { 4112 if ( start.previousSibling.tagName ) 4113 { 4114 if ( !Xinha.isBlockElement(start.previousSibling) ) 4115 { 4116 start = start.previousSibling; 4117 } 4118 else 4119 { 4120 break; 4121 } 4122 } 4123 else 4124 { 4125 start = start.previousSibling; 4126 } 4127 } 4128 4129 // Same down the list 4130 while ( end.nextSibling ) 4131 { 4132 if ( end.nextSibling.tagName ) 4133 { 4134 if ( !Xinha.isBlockElement(end.nextSibling) ) 4135 { 4136 end = end.nextSibling; 4137 } 4138 else 4139 { 4140 break; 4141 } 4142 } 4143 else 4144 { 4145 end = end.nextSibling; 4146 } 4147 } 4148 4149 // Select the entire block 4150 range.setStartBefore(start); 4151 range.setEndAfter(end); 4152 4153 // Make it a paragraph 4154 range.surroundContents(this._doc.createElement('p')); 4155 4156 // Which becomes the block element 4157 block = range.startContainer.firstChild; 4158 4159 // And finally reset the insertion point to where it was originally 4160 range.setStart(SC, SO); 4161 } 4162 4163 // The start point is the insertion point, so just move the end point to immediatly 4164 // after the block 4165 range.setEndAfter(block); 4166 4167 // Extract the range, to split the block 4168 // If we just did range.extractContents() then Mozilla does wierd stuff 4169 // with selections, but if we clone, then remove the original range and extract 4170 // the clone, it's quite happy. 4171 var r2 = range.cloneRange(); 4172 sel.removeRange(range); 4173 var df = r2.extractContents(); 4174 4175 if ( df.childNodes.length === 0 ) 4176 { 4177 df.appendChild(this._doc.createElement('p')); 4178 df.firstChild.appendChild(this._doc.createElement('br')); 4179 } 4180 4181 if ( df.childNodes.length > 1 ) 4182 { 4183 var nb = this._doc.createElement('p'); 4184 while ( df.firstChild ) 4185 { 4186 var s = df.firstChild; 4187 df.removeChild(s); 4188 nb.appendChild(s); 4189 } 4190 df.appendChild(nb); 4191 } 4192 4193 // If the original block is empty, put a &nsbp; in it. 4194 // @fixme: why using a regex instead of : if (block.innerHTML.trim() == '') ? 4195 if ( ! ( /\S/.test(block.innerHTML) ) ) 4196 { 4197 block.innerHTML = " "; 4198 } 4199 4200 p = df.firstChild; 4201 // @fixme: why using a regex instead of : if (p.innerHTML.trim() == '') ? 4202 if ( ! ( /\S/.test(p.innerHTML) ) ) 4203 { 4204 p.innerHTML = "<br />"; 4205 } 4206 4207 // If the new block is empty and it's a heading, make it a paragraph 4208 // note, the new block is empty when you are hitting enter at the end of the existing block 4209 if ( ( /^\s*<br\s*\/?>\s*$/.test(p.innerHTML) ) && ( /^h[1-6]$/i.test(p.tagName) ) ) 4210 { 4211 df.appendChild(this.convertNode(p, "p")); 4212 df.removeChild(p); 4213 } 4214 4215 var newblock = block.parentNode.insertBefore(df.firstChild, block.nextSibling); 4216 4217 // Select the range (to set the insertion) 4218 // collapse to the start of the new block 4219 // (remember the block might be <p><br/></p>, so if we collapsed to the end the <br/> would be noticable) 4220 4221 //range.selectNode(newblock.firstChild); 4222 //range.collapse(true); 4223 4224 this.activateEditor(); 4225 4226 sel = this.getSelection(); 4227 sel.removeAllRanges(); 4228 sel.collapse(newblock,0); 4229 4230 // scroll into view 4231 this.scrollToElement(newblock); 4232 4233 //this.forceRedraw(); 4234 4235 }; 4025 // moved Xinha.prototype.dom_checkInsertP() to browser specific file 4236 4026 4237 4027 Xinha.prototype.scrollToElement = function(e) -
trunk/functionsMozilla.js
r678 r682 187 187 if( !ev.shiftKey && editor.config.mozParaHandler == 'dirty' ) 188 188 { 189 editor.dom_checkInsertP();189 this.dom_checkInsertP(); 190 190 Xinha._stopEvent(ev); 191 191 } … … 323 323 10); 324 324 }; 325 /** The idea here is 326 * 1. See if we are in a block element 327 * 2. If we are not, then wrap the current "block" of text into a paragraph 328 * 3. Now that we have a block element, select all the text between the insertion point 329 * and just AFTER the end of the block 330 * eg <p>The quick |brown fox jumped over the lazy dog.</p>| 331 * --------------------------------------- 332 * 4. Extract that from the document, making 333 * <p>The quick </p> 334 * and a document fragment with 335 * <p>brown fox jumped over the lazy dog.</p> 336 * 5. Reinsert it just after the block element 337 * <p>The quick </p><p>brown fox jumped over the lazy dog.</p> 338 * 339 * Along the way, allow inserting blank paragraphs, which will look like <p><br/></p> 340 */ 341 342 Gecko.prototype.dom_checkInsertP = function() 343 { 344 var editor = this.editor; 345 var p, body; 346 // Get the insertion point, we'll scrub any highlighted text the user wants rid of while we are there. 347 var sel = editor.getSelection(); 348 var range = editor.createRange(sel); 349 if ( !range.collapsed ) 350 { 351 range.deleteContents(); 352 } 353 editor.deactivateEditor(); 354 //sel.removeAllRanges(); 355 //sel.addRange(range); 356 357 var SC = range.startContainer; 358 var SO = range.startOffset; 359 var EC = range.endContainer; 360 var EO = range.endOffset; 361 362 // If the insertion point is character 0 of the 363 // document, then insert a space character that we will wrap into a paragraph 364 // in a bit. 365 if ( SC == EC && SC == body && !SO && !EO ) 366 { 367 p = editor._doc.createTextNode(" "); 368 body.insertBefore(p, body.firstChild); 369 range.selectNodeContents(p); 370 SC = range.startContainer; 371 SO = range.startOffset; 372 EC = range.endContainer; 373 EO = range.endOffset; 374 } 375 376 // See if we are in a block element, if so, great. 377 p = editor.getAllAncestors(); 378 379 var block = null; 380 body = editor._doc.body; 381 for ( var i = 0; i < p.length; ++i ) 382 { 383 if ( Xinha.isParaContainer(p[i]) ) 384 { 385 break; 386 } 387 else if ( Xinha.isBlockElement(p[i]) && ! ( /body|html/i.test(p[i].tagName) ) ) 388 { 389 block = p[i]; 390 break; 391 } 392 } 393 394 // If not in a block element, we'll have to turn some stuff into a paragraph 395 if ( !block ) 396 { 397 // We want to wrap as much stuff as possible into the paragraph in both directions 398 // from the insertion point. We start with the start container and walk back up to the 399 // node just before any of the paragraph containers. 400 var wrap = range.startContainer; 401 while ( wrap.parentNode && !Xinha.isParaContainer(wrap.parentNode) ) 402 { 403 wrap = wrap.parentNode; 404 } 405 var start = wrap; 406 var end = wrap; 407 408 // Now we walk up the sibling list until we hit the top of the document 409 // or an element that we shouldn't put in a p (eg other p, div, ul, ol, table) 410 while ( start.previousSibling ) 411 { 412 if ( start.previousSibling.tagName ) 413 { 414 if ( !Xinha.isBlockElement(start.previousSibling) ) 415 { 416 start = start.previousSibling; 417 } 418 else 419 { 420 break; 421 } 422 } 423 else 424 { 425 start = start.previousSibling; 426 } 427 } 428 429 // Same down the list 430 while ( end.nextSibling ) 431 { 432 if ( end.nextSibling.tagName ) 433 { 434 if ( !Xinha.isBlockElement(end.nextSibling) ) 435 { 436 end = end.nextSibling; 437 } 438 else 439 { 440 break; 441 } 442 } 443 else 444 { 445 end = end.nextSibling; 446 } 447 } 448 449 // Select the entire block 450 range.setStartBefore(start); 451 range.setEndAfter(end); 452 453 // Make it a paragraph 454 range.surroundContents(editor._doc.createElement('p')); 455 456 // Which becomes the block element 457 block = range.startContainer.firstChild; 458 459 // And finally reset the insertion point to where it was originally 460 range.setStart(SC, SO); 461 } 462 463 // The start point is the insertion point, so just move the end point to immediatly 464 // after the block 465 range.setEndAfter(block); 466 467 // Extract the range, to split the block 468 // If we just did range.extractContents() then Mozilla does wierd stuff 469 // with selections, but if we clone, then remove the original range and extract 470 // the clone, it's quite happy. 471 var r2 = range.cloneRange(); 472 sel.removeRange(range); 473 var df = r2.extractContents(); 474 475 if ( df.childNodes.length === 0 ) 476 { 477 df.appendChild(editor._doc.createElement('p')); 478 df.firstChild.appendChild(editor._doc.createElement('br')); 479 } 480 481 if ( df.childNodes.length > 1 ) 482 { 483 var nb = editor._doc.createElement('p'); 484 while ( df.firstChild ) 485 { 486 var s = df.firstChild; 487 df.removeChild(s); 488 nb.appendChild(s); 489 } 490 df.appendChild(nb); 491 } 492 493 // If the original block is empty, put a &nsbp; in it. 494 // @fixme: why using a regex instead of : if (block.innerHTML.trim() == '') ? 495 if ( ! ( /\S/.test(block.innerHTML) ) ) 496 { 497 block.innerHTML = " "; 498 } 499 500 p = df.firstChild; 501 // @fixme: why using a regex instead of : if (p.innerHTML.trim() == '') ? 502 if ( ! ( /\S/.test(p.innerHTML) ) ) 503 { 504 p.innerHTML = "<br />"; 505 } 506 507 // If the new block is empty and it's a heading, make it a paragraph 508 // note, the new block is empty when you are hitting enter at the end of the existing block 509 if ( ( /^\s*<br\s*\/?>\s*$/.test(p.innerHTML) ) && ( /^h[1-6]$/i.test(p.tagName) ) ) 510 { 511 df.appendChild(editor.convertNode(p, "p")); 512 df.removeChild(p); 513 } 514 515 var newblock = block.parentNode.insertBefore(df.firstChild, block.nextSibling); 516 517 // Select the range (to set the insertion) 518 // collapse to the start of the new block 519 // (remember the block might be <p><br/></p>, so if we collapsed to the end the <br/> would be noticable) 520 521 //range.selectNode(newblock.firstChild); 522 //range.collapse(true); 523 524 editor.activateEditor(); 525 526 sel = editor.getSelection(); 527 sel.removeAllRanges(); 528 sel.collapse(newblock,0); 529 530 // scroll into view 531 editor.scrollToElement(newblock); 532 533 //editor.forceRedraw(); 534 535 }; 325 536 326 537 Gecko.prototype.inwardHtml = function(html)
