JS: Suggestion popup synonym, Updated

SO Question #36049942; http://stackoverflow.com/questions/36049942/how-to-create-a-suggestion-box-prompt-box-in-javascript-inside-a-html-box-with

by abhitalks

HTML

<div class="wrap">
	<p>
	I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. 
	</p>
	<p>
	I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms"...

CSS

* { font-family: sans-serif; box-sizing: border-box; }
html, body { height: 100%; }
div.wrap { 
	border: 1px solid #ddd; max-height: 480px; 
	padding: 4px 22px 4px 4px; font-size: 0.9em;
	overflow: hidden; overflow-y: auto;
}
i.synonyms { cursor: pointer; color: #333; }
div#menuWrapper {
	position: absolute; display: none; width: 128px; 
	padding: 4px; margin: 0; 
	border: 1px solid #bbb; background-color: #efefef;
	box-shadow: 0px 0px 6px 1px rgba(128,128,128,0.3);
}
ul#synonymMenu {
	max-height: 120px; 
	overflow: hidden; overflow-y: auto;
	list-style: none; padding: 0; margin: 0; 
}
ul#synonymMenu > li { display: block; }
ul#synonymMenu label { 
	display: block; color: #333; font-size: 0.9em; 
	padding: 2px 18px 2px 4px; 
}
ul#synonymMenu label:hover { background-color: #99b; }
button#synOk { padding: 2px; width: 100%; }

JavaScript

(function() {
	var menu = document.getElementById('synonymMenu'), 
		menuWrap = document.getElementById('menuWrapper'),
		okButton = document.getElementById('synOk'), 
		words = [].slice.call(document.querySelectorAll('i.synonyms')), 
		currentWord = null
	;
	
	words.forEach(function(wrd) {
		wrd.setAttribute('data-word', wrd.textContent);
		wrd.addEventListener('click', manageMenu);
	});
	okButton.addEventListener('click', applySynonym);
	document.body.addEventListener('click', function(e) { 
		if (isDescendant(menuWrapper, e.target)) {
			return;
		}
		toggleMenu('hide');
	});

	function manageMenu(e) {
		var synonyms, opt, lbl, chk, txt, position, existing; 
		clearMenu(); toggleMenu('show'); 
		currentWord = e.target;
		position = currentWord.getBoundingClientRect();
		menuWrap.style.top = position.top + 20 + 'px';
		menuWrap.style.left = position.left + 2 + 'px';
		existing = currentWord.textContent;
		synonyms = currentWord.getAttribute('title').split('|');
		synonyms.forEach(function(syn) {
			opt = document.createElement('li'); 
			lbl = document.createElement('label');
			chk = document.createElement('input'); 
			chk.setAttribute('type', 'checkbox'); 
			txt = document.createTextNode(syn);
			lbl.appendChild(chk); 
			lbl.appendChild(txt); 
			opt.appendChild(lbl); 
			menu.appendChild(opt);
		});
		preSelect(existing);
		e.stopPropagation();
	}
	
	function preSelect(existing) {
		var labels = [].slice.call(menu.querySelectorAll('label'));
		labels.forEach(function(lbl) {
			if (existing.indexOf(lbl.textContent) > -1) {
				lbl.firstChild.checked = true;
			}
		});
	}
	
	function applySynonym(e) {
		var txt = '', labels, checked, selected;
		labels = [].slice.call(menu.querySelectorAll('label'));
		checked = labels.filter(function(lbl){
			return lbl.firstChild.checked;
		});
		selected = checked.map(function(lbl){
			return lbl.textContent;
		}).join('|');
		
		txt += '{' + currentWord.getAttribute('data-word') + '|';
		txt += selected +...