1 /**
  2  * This file contains hacks for IE7 or IE8 and IE9 in either compatibility mode or IE7 mode.
  3  */
  4 define(['aloha/core', 'aloha/jquery'], function(Aloha, $){
  5 
  6 	/**
  7 	 * The problem is that with a DOM like the following:
  8 	 *
  9 	 * <style>p { margin-top: 2em; }</style>
 10 	 * <p><br class='aloha-end-br'/></p>
 11 	 * <p></p>
 12 	 *
 13 	 * The margin between the paragraphs will not take effect because
 14 	 * IE8 in compatibility mode considers the paragraph with the <br>
 15 	 * in it empty. Normal IE8 will render the margin.
 16 	 *
 17 	 * To make IE8 in compatibility mode render the margin, some content
 18 	 * must be put into the <p>. That is not a big problem, since there
 19 	 * usually should be no reason to have empty paragraphs in your
 20 	 * content.
 21 	 *
 22 	 * However, if the content is entered by hand (if it is not there to
 23 	 * begin with) then the margin will not be immediately updated. Only
 24 	 * when, after entering some content into the first paragraph, the
 25 	 * selection is put into the second paragraph, will the margin be
 26 	 * updated.
 27 	 *
 28 	 * Although I don't see an easy workaround for the first problem
 29 	 * (that the margin is not displayed when the paragraph is empty)
 30 	 * there is an easy workaround for the second problem (that the
 31 	 * margin isn't updated even after some content has been
 32 	 * entered). The workaround is simply, when some content is entered,
 33 	 * to insert and remove an arbitrary DOM node into the second
 34 	 * paragraph, which will force IE to re-render the paragraph.
 35 	 *
 36 	 * Problem was verified to exist on IE7 and IE8 in compatibility
 37 	 * mode with IE7 document type. May also exist in other IE7 modes.
 38 	 */
 39 	Aloha.bind('aloha-selection-changed', function(event, rangeObject){
 40 		var container = rangeObject.startContainer;
 41 		// Only apply the hack on IE7 (and IE8 in compatibility mode) and
 42 		// only to a collapsed selection.
 43 		if (!($.browser.msie && $.browser.version <= 7
 44 			  && container && container === rangeObject.endContainer
 45 			  && rangeObject.startOffset === rangeObject.endOffset)) {
 46 			return;
 47 		}
 48 		// Ignore text nodes
 49 		if (3 === container.nodeType) {
 50 			container = container.parentNode;
 51 		}
 52 		var nextSibling = container.nextSibling;
 53 		var firstChild = container.firstChild;
 54 		// For safety, limit the hack to the following DOM structure where the
 55 		// first <P> is the container.
 56 		// <P><!-- possibly an empty text node here --><BR.../></P><P></P>
 57 		if ('P' === container.nodeName
 58 			&& nextSibling && 'P' === nextSibling.nodeName
 59 			&& firstChild
 60 			&& (   ('BR' === firstChild.nodeName && !firstChild.nextSibling)
 61 				|| (   3 === firstChild.nodeType && !firstChild.length
 62 					&& firstChild.nextSibling && 'BR' === firstChild.nextSibling.nodeName && !firstChild.nextSibling.nextSibling))) {
 63 			// \ufeff should be invisible
 64 			nextSibling.insertBefore(document.createTextNode("\ufeff"), nextSibling.firstChild);
 65 			nextSibling.removeChild(nextSibling.firstChild);
 66 		}
 67 	});
 68 });
 69