Changeset 1040 for branches/new-dialogs


Ignore:
Timestamp:
10/01/08 20:01:08 (11 years ago)
Author:
douglas
Message:

FIXED Ticket #1280 Introduce workarounds for bug in IE's TextRange?.select() method.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/new-dialogs/modules/InternetExplorer/InternetExplorer.js

    r1001 r1040  
    146146   // make sure there is something before the first script on the page 
    147147   html = html.replace(/(<script|<!--)/i,"&nbsp;$1"); 
     148 
     149   // We've got a workaround for certain issues with saving and restoring 
     150   // selections that may cause us to fill in junk span tags.  We'll clean 
     151   // those here 
     152   html = html.replace(/<span[^>]+id="__InsertSpan_Workaround_[a-z]+".*?><\/span>/i,""); 
    148153    
    149154   return html; 
     
    154159   // remove space added before first script on the page 
    155160   html = html.replace(/&nbsp;(\s*)(<script|<!--)/i,"$1$2"); 
     161 
     162   // We've got a workaround for certain issues with saving and restoring 
     163   // selections that may cause us to fill in junk span tags.  We'll clean 
     164   // those here 
     165   html = html.replace(/<span[^>]+id="__InsertSpan_Workaround_[a-z]+".*?><\/span>/i,""); 
    156166    
    157167   return html; 
     
    441451Xinha.prototype.restoreSelection = function(savedSelection) 
    442452{ 
     453  // In order to prevent triggering the IE bug mentioned below, we will try to 
     454  // optimize by not restoring the selection if it happens to match the current 
     455  // selection. 
     456  var range = this.createRange(this.getSelection()); 
     457 
     458  // We can't compare two selections that come from different documents, so we 
     459  // must make sure they're from the same document. 
     460  var findDoc = function(el) 
     461  { 
     462    for (var root=el; root; root=root.parentNode) 
     463    { 
     464      if (root.tagName.toLowerCase() == 'html') 
     465      { 
     466        return root.parentNode; 
     467      } 
     468    } 
     469    return null; 
     470  } 
     471 
     472  if (findDoc(savedSelection.parentElement()) == findDoc(range.parentElement())) 
     473  { 
     474    if ((0 == range.compareEndPoints('StartToStart',savedSelection)) && 
     475        (0 == range.compareEndPoints('EndToEnd',savedSelection))) 
     476    { 
     477      // The selection hasn't moved, no need to restore. 
     478      return; 
     479    } 
     480  } 
     481 
    443482  try { savedSelection.select() } catch (e) {}; 
     483  range = this.createRange(this.getSelection()); 
     484  if (range.parentElement() != savedSelection.parentElement()) 
     485  { 
     486    // IE has a problem with selections at the end of text nodes that 
     487    // immediately precede block nodes. Example markup: 
     488    // <div>Text Node<p>Text in Block</p></div> 
     489    //               ^ 
     490    // The problem occurs when the cursor is after the 'e' in Node. 
     491 
     492    var solution = editor.config.selectWorkaround || 'InsertSpan'; 
     493    switch (solution) 
     494    { 
     495      case 'SimulateClick': 
     496        // Try to get the bounding box of the selection and then simulate a 
     497        // mouse click in the upper right corner to return the cursor to the 
     498        // correct location. 
     499 
     500        // No code yet, fall through to InsertSpan 
     501      case 'InsertSpan': 
     502        // This workaround inserts an empty span element so that we are no 
     503        // longer trying to select a text node, 
     504        var parentDoc = findDoc(savedSelection.parentElement()); 
     505 
     506        // A function used to generate a unique ID for our temporary span. 
     507        var randLetters = function(count) 
     508        { 
     509          // Build a list of 26 letters. 
     510          var Letters = ''; 
     511          for (var index = 0; index<26; ++index) 
     512          { 
     513            Letters += String.fromCharCode('a'.charCodeAt(0) + index); 
     514          } 
     515 
     516          var result = ''; 
     517          for (var index=0; index<count; ++index) 
     518          { 
     519            result += Letters.substr(Math.floor(Math.random()*26 + 1), 1); 
     520          } 
     521          return result; 
     522        } 
     523 
     524        // We'll try to find a unique ID to use for finding our element. 
     525        var keyLength = 1; 
     526        var tempId = '__InsertSpan_Workaround_' + randLetters(keyLength); 
     527        while (parentDoc.getElementById(tempId)) 
     528        { 
     529          // Each time there's a collision, we'll increase our key length by 
     530          // one, making the chances of a collision exponentially more rare. 
     531          keyLength += 1; 
     532          tempId = '__InsertSpan_Workaround_' + randLetters(keyLength); 
     533        } 
     534 
     535        // Now that we have a uniquely identifiable element, we'll stick it and 
     536        // and use it to orient our selection. 
     537        savedSelection.pasteHTML('<span id="' + tempId + '"></span>'); 
     538        var tempSpan = parentDoc.getElementById(tempId); 
     539        savedSelection.moveToElementText(tempSpan); 
     540        savedSelection.select(); 
     541        break; 
     542      case 'JustificationHack': 
     543        // Setting the justification on an element causes IE to alter the 
     544        // markup so that the selection we want to make is possible. 
     545        // Unfortunately, this can force block elements to be kicked out of 
     546        // their containing element, so it is not recommended. 
     547 
     548        // Set a non-valid character and use it to anchor our selection. 
     549        var magicString = String.fromCharCode(1); 
     550        savedSelection.pasteHTML(magicString); 
     551        savedSelection.findText(magicString,-1); 
     552        savedSelection.select(); 
     553 
     554        // I don't know how to find out if there's an existing justification on 
     555        // this element.  Hopefully, you're doing all of your styling outside, 
     556        // so I'll just clear.  I already told you this was a hack. 
     557        savedSelection.execCommand('JustifyNone'); 
     558        savedSelection.pasteHTML(''); 
     559        break; 
     560      case 'VisiblePrompt': 
     561      default: 
     562        // This method will insert a little box character to hold our selection 
     563        // in the desired spot.  We're depending on the user to see this ugly 
     564        // box and delete it themselves. 
     565        var magicString = String.fromCharCode(1); 
     566        savedSelection.pasteHTML(magicString); 
     567        savedSelection.findText(magicString,-1); 
     568        savedSelection.select(); 
     569    } 
     570  } 
    444571} 
    445572 
Note: See TracChangeset for help on using the changeset viewer.