Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 404277

Summary: Embeddable Editor and getSelectionText does not work correctly if style is display:none
Product: [ECD] Orion Reporter: Simon Kaegi <simon_kaegi>
Component: EditorAssignee: Silenio Quarti <Silenio_Quarti>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: Silenio_Quarti
Version: 2.0   
Target Milestone: 3.0 M1   
Hardware: PC   
OS: Windows 7   
Whiteboard:

Description Simon Kaegi CLA 2013-03-25 11:36:35 EDT
While embedding the editor in a reveal.js presentation we found that the editor did not re-display the original text if the slide was initially not shown. We tracked this down to getSelectionText returning "" if the style on the <pre> in this case was display:none.

It might be that the range calculation simply will not work when display is none so in this case and we directly used element.innerText || element.textContent directly however this needs to be understood better.
Comment 1 Silenio Quarti CLA 2013-03-25 12:21:39 EDT
The problem is that setting the selection to a node that is not displayed (display=none) fails.  This should fix it, but it will get HTML tags as well if the element content is not plain text.  Getting plain text of complex HTML (img, ul, li, etc) is hard, that is why the range selection is used.   I guess nobody we try to put complex HTML in the editor, so we should be fine.

	function getTextFromElement(element) {
		var firstChild = element.firstChild;
		if (firstChild && firstChild.tagName === "TEXTAREA") { //$NON-NLS-0$
			return firstChild.value;
		}
		var document = element.ownerDocument;
		var window = document.defaultView || document.parentWindow;
		var display;
		var temp = element;
		while (temp && temp !== document && display !== "none") {
			var style = window.getComputedStyle(temp, null);
			display = style.getPropertyValue("display"); //$NON-NLS-0$
			temp = temp.parentNode;
		}
		if (display === "none" || !window.getSelection) {
			return element.innerText || element.textContent;
		}
		var newRange = document.createRange();
		newRange.selectNode(element);
		var selection = window.getSelection();
		var oldRanges = [], i;
		for (i = 0; i < selection.rangeCount; i++) {
			oldRanges.push(selection.getRangeAt(i));
		}
		selection.removeAllRanges();
		selection.addRange(newRange);
		var text = selection.toString();
		selection.removeAllRanges();
		for (i = 0; i < oldRanges.length; i++) {
			selection.addRange(oldRanges[i]);
		}
		return text;
	}
Comment 2 Silenio Quarti CLA 2013-03-25 14:40:16 EDT
Added another check to sure that if the element only has plain text we do not run the range code.  This is should take care of most common cases.

Fixed

http://git.eclipse.org/c/orion/org.eclipse.orion.client.git/commit/?id=55054461f4cd2e22e903cedde9ed9ff1e479478d