tinymce.full.js
function getCaretRect(rng) {
          var rects, textNode, node, container = rng.startContainer;

          rects = rng.getClientRects();
          if (rects.length) {
            return rects[0];
          }

          if (!rng.collapsed || container.nodeType != 1) {
            return;
          }

          node = container.childNodes[lastRng.startOffset];

          // Skip empty whitespace nodes
          while (node && node.nodeType == 3 && !node.data.length) {
            node = node.nextSibling;
          }

          if (!node) {
            return;
          }

          // Check if the location is |<br>
          // TODO: Might need to expand this to say |<table>
          if (node.tagName == 'BR') {
            textNode = dom.doc.createTextNode('\uFEFF');
            node.parentNode.insertBefore(textNode, node);

            rng = dom.createRng();
            rng.setStartBefore(textNode);
            rng.setEndAfter(textNode);

            rects = rng.getClientRects();
            dom.remove(textNode);
          }

          if (rects.length) {
            return rects[0];
          }
        }
function getCaretRect(rng) {
          var rects, textNode, node, container = rng.startContainer;

          rects = rng.getClientRects();
          if (rects.length) {
            return rects[0];
          }

          if (!rng.collapsed || container.nodeType != 1) {
            return;
          }

          node = container.childNodes[lastRng.startOffset];

          // Skip empty whitespace nodes
          while (node && node.nodeType == 3 && !node.data.length) {
            node = node.nextSibling;
          }

          if (!node) {
            return;
          }

          // Check if the location is |<br>
          // TODO: Might need to expand this to say |<table>
          if (node.tagName == 'BR') {
            textNode = dom.doc.createTextNode('\uFEFF');
            node.parentNode.insertBefore(textNode, node);

            rng = dom.createRng();
            rng.setStartBefore(textNode);
            rng.setEndAfter(textNode);

            rects = rng.getClientRects();
            dom.remove(textNode);
          }

          if (rects.length) {
            return rects[0];
          }
        }
function getCaretRect ( rng ) { var rects , textNode , node , container = rng . startContainer ; rects = rng . getClientRects ( ) ; if ( rects . length ) { return rects [ 0 ] ; } if ( ! rng . collapsed || container . nodeType != 1 ) { return ; } node = container . childNodes [ lastRng . startOffset ] ; // Skip empty whitespace nodes while ( node && node . nodeType == 3 && ! node . data . length ) { node = node . nextSibling ; } if ( ! node ) { return ; } // Check if the location is |<br> // TODO: Might need to expand this to say |<table> if ( node . tagName == 'BR' ) { textNode = dom . doc . createTextNode ( '\uFEFF' ) ; node . parentNode . insertBefore ( textNode , node ) ; rng = dom . createRng ( ) ; rng . setStartBefore ( textNode ) ; rng . setEndAfter ( textNode ) ; rects = rng . getClientRects ( ) ; dom . remove ( textNode ) ; } if ( rects . length ) { return rects [ 0 ] ; } }
Returns the rect of the current caret if the caret is in an empty block before a
BR we insert a temporary invisible character that we get the rect this way we always get a proper rect.

TODO: This might be useful in core.
Returns the rect of the current caret if the caret is in an empty block before a BR we insert a temporary invisible character that we get the rect this way we always get a proper rect .