Best JavaScript code snippet using playwright-internal
lists.js
Source:lists.js  
...59	editor.getBody().innerHTML = trimBrs(60		'<p>a</p>'61	);62	editor.focus();63	Utils.setSelection('p', 0);64	execCommand('InsertUnorderedList');65	equal(editor.getContent(), '<ul><li>a</li></ul>');66	equal(editor.selection.getNode().nodeName, 'LI');67});68test('Apply UL list to single empty P', function() {69	editor.getBody().innerHTML = trimBrs(70		'<p><br></p>'71	);72	editor.focus();73	Utils.setSelection('p', 0);74	execCommand('InsertUnorderedList');75	equal(trimBrs(editor.getContent({format: 'raw'})), '<ul><li></li></ul>');76	equal(editor.selection.getNode().nodeName, 'LI');77});78test('Apply UL list to multiple Ps', function() {79	editor.getBody().innerHTML = trimBrs(80		'<p>a</p>' +81		'<p>b</p>' +82		'<p>c</p>'83	);84	editor.focus();85	Utils.setSelection('p', 0, 'p:last', 0);86	execCommand('InsertUnorderedList');87	equal(editor.getContent(),88		'<ul>' +89			'<li>a</li>' +90			'<li>b</li>' +91			'<li>c</li>' +92		'</ul>'93	);94	equal(editor.selection.getStart().nodeName, 'LI');95});96test('Apply OL list to single P', function() {97	editor.getBody().innerHTML = trimBrs(98		'<p>a</p>'99	);100	editor.focus();101	Utils.setSelection('p', 0);102	execCommand('InsertOrderedList');103	equal(editor.getContent(), '<ol><li>a</li></ol>');104	equal(editor.selection.getNode().nodeName, 'LI');105});106test('Apply OL list to single empty P', function() {107	editor.getBody().innerHTML = trimBrs(108		'<p><br></p>'109	);110	editor.focus();111	Utils.setSelection('p', 0);112	execCommand('InsertOrderedList');113	equal(trimBrs(editor.getContent({format: 'raw'})), '<ol><li></li></ol>');114	equal(editor.selection.getNode().nodeName, 'LI');115});116test('Apply OL list to multiple Ps', function() {117	editor.getBody().innerHTML = trimBrs(118		'<p>a</p>' +119		'<p>b</p>' +120		'<p>c</p>'121	);122	editor.focus();123	Utils.setSelection('p', 0, 'p:last', 0);124	execCommand('InsertOrderedList');125	equal(editor.getContent(),126		'<ol>' +127			'<li>a</li>' +128			'<li>b</li>' +129			'<li>c</li>' +130		'</ol>'131	);132	equal(editor.selection.getStart().nodeName, 'LI');133});134test('Apply OL to UL list', function() {135	editor.getBody().innerHTML = trimBrs(136		'<ul>' +137			'<li>a</li>' +138			'<li>b</li>' +139			'<li>c</li>' +140		'</ul>'141	);142	editor.focus();143	Utils.setSelection('li', 0, 'li:last', 0);144	execCommand('InsertOrderedList');145	equal(editor.getContent(),146		'<ol>' +147			'<li>a</li>' +148			'<li>b</li>' +149			'<li>c</li>' +150		'</ol>'151	);152	equal(editor.selection.getStart().nodeName, 'LI');153});154test('Apply OL to UL list with collapsed selection', function() {155	editor.getBody().innerHTML = trimBrs(156		'<ul>' +157			'<li>a</li>' +158			'<li>b</li>' +159			'<li>c</li>' +160		'</ul>'161	);162	editor.focus();163	Utils.setSelection('li:nth-child(2)');164	execCommand('InsertOrderedList');165	equal(editor.getContent(),166		'<ol>' +167			'<li>a</li>' +168			'<li>b</li>' +169			'<li>c</li>' +170		'</ol>'171	);172	equal(editor.selection.getStart().nodeName, 'LI');173});174test('Apply UL to OL list', function() {175	editor.getBody().innerHTML = trimBrs(176		'<ol>' +177			'<li>a</li>' +178			'<li>b</li>' +179			'<li>c</li>' +180		'</ol>'181	);182	editor.focus();183	Utils.setSelection('li', 0, 'li:last', 0);184	execCommand('InsertUnorderedList');185	equal(editor.getContent(),186		'<ul>' +187			'<li>a</li>' +188			'<li>b</li>' +189			'<li>c</li>' +190		'</ul>'191	);192	equal(editor.selection.getStart().nodeName, 'LI');193});194test('Apply UL to OL list collapsed selection', function() {195	editor.getBody().innerHTML = trimBrs(196		'<ol>' +197			'<li>a</li>' +198			'<li>b</li>' +199			'<li>c</li>' +200		'</ol>'201	);202	editor.focus();203	Utils.setSelection('li:nth-child(2)');204	execCommand('InsertUnorderedList');205	equal(editor.getContent(),206		'<ul>' +207			'<li>a</li>' +208			'<li>b</li>' +209			'<li>c</li>' +210		'</ul>'211	);212	equal(editor.selection.getStart().nodeName, 'LI');213});214test('Apply UL to P and merge with adjacent lists', function() {215	editor.getBody().innerHTML = trimBrs(216		'<ul>' +217			'<li>a</li>' +218		'</ul>' +219		'<p>b</p>' +220		'<ul>' +221			'<li>c</li>' +222		'</ul>'223	);224	editor.focus();225	Utils.setSelection('p', 1);226	execCommand('InsertUnorderedList');227	equal(editor.getContent(),228		'<ul>' +229			'<li>a</li>' +230			'<li>b</li>' +231			'<li>c</li>' +232		'</ul>'233	);234	equal(editor.selection.getStart().nodeName, 'LI');235});236test('Apply UL to OL and merge with adjacent lists', function() {237	editor.getBody().innerHTML = trimBrs(238		'<ul>' +239			'<li>a</li>' +240		'</ul>' +241		'<ol><li>b</li></ol>' +242		'<ul>' +243			'<li>c</li>' +244		'</ul>'245	);246	editor.focus();247	Utils.setSelection('ol li', 1);248	execCommand('InsertUnorderedList');249	equal(editor.getContent(),250		'<ul>' +251			'<li>a</li>' +252			'<li>b</li>' +253			'<li>c</li>' +254		'</ul>'255	);256	equal(editor.selection.getStart().nodeName, 'LI');257});258test('Apply OL to P and merge with adjacent lists', function() {259	editor.getBody().innerHTML = trimBrs(260		'<ol>' +261			'<li>a</li>' +262		'</ol>' +263		'<p>b</p>' +264		'<ol>' +265			'<li>c</li>' +266		'</ol>'267	);268	editor.focus();269	Utils.setSelection('p', 1);270	execCommand('InsertOrderedList');271	equal(editor.getContent(),272		'<ol>' +273			'<li>a</li>' +274			'<li>b</li>' +275			'<li>c</li>' +276		'</ol>'277	);278	equal(editor.selection.getStart().nodeName, 'LI');279});280test('Apply OL to UL and merge with adjacent lists', function() {281	editor.getBody().innerHTML = trimBrs(282		'<ol>' +283			'<li>a</li>' +284		'</ol>' +285		'<ul><li>b</li></ul>' +286		'<ol>' +287			'<li>c</li>' +288		'</ol>'289	);290	editor.focus();291	Utils.setSelection('ul li', 1);292	execCommand('InsertOrderedList');293	equal(editor.getContent(),294		'<ol>' +295			'<li>a</li>' +296			'<li>b</li>' +297			'<li>c</li>' +298		'</ol>'299	);300	equal(editor.selection.getStart().nodeName, 'LI');301});302test('Apply UL list to single text line', function() {303	editor.settings.forced_root_block = false;304	editor.getBody().innerHTML = (305		'a'306	);307	editor.focus();308	Utils.setSelection('body', 0);309	execCommand('InsertUnorderedList');310	equal(editor.getContent(), '<ul><li>a</li></ul>');311	equal(editor.selection.getNode().nodeName, 'LI');312});313test('Apply UL list to single text line with BR', function() {314	editor.settings.forced_root_block = false;315	editor.getBody().innerHTML = (316		'a<br>'317	);318	editor.focus();319	Utils.setSelection('body', 0);320	execCommand('InsertUnorderedList');321	equal(editor.getContent(), '<ul><li>a</li></ul>');322	equal(editor.selection.getNode().nodeName, 'LI');323});324test('Apply UL list to multiple lines separated by BR', function() {325	editor.settings.forced_root_block = false;326	editor.getBody().innerHTML = (327		'a<br>' +328		'b<br>' +329		'c'330	);331	editor.focus();332	editor.execCommand('SelectAll');333	execCommand('InsertUnorderedList');334	equal(editor.getContent(),335		'<ul>' +336			'<li>a</li>' +337			'<li>b</li>' +338			'<li>c</li>' +339		'</ul>'340	);341	equal(editor.selection.getStart().nodeName, 'LI');342});343test('Apply UL list to multiple lines separated by BR and with trailing BR', function() {344	editor.settings.forced_root_block = false;345	editor.getBody().innerHTML = (346		'a<br>' +347		'b<br>' +348		'c<br>'349	);350	editor.focus();351	editor.execCommand('SelectAll');352	execCommand('InsertUnorderedList');353	equal(editor.getContent(),354		'<ul>' +355			'<li>a</li>' +356			'<li>b</li>' +357			'<li>c</li>' +358		'</ul>'359	);360	equal(editor.selection.getStart().nodeName, 'LI');361});362test('Apply UL list to multiple formatted lines separated by BR', function() {363	editor.settings.forced_root_block = false;364	editor.getBody().innerHTML = (365		'<strong>a</strong><br>' +366		'<span>b</span><br>' +367		'<em>c</em>'368	);369	editor.focus();370	Utils.setSelection('strong', 0, 'em', 0);371	execCommand('InsertUnorderedList');372	equal(editor.getContent(),373		'<ul>' +374			'<li><strong>a</strong></li>' +375			'<li><span>b</span></li>' +376			'<li><em>c</em></li>' +377		'</ul>'378	);379	equal(editor.selection.getStart().nodeName, 'STRONG');380	equal(editor.selection.getEnd().nodeName, tinymce.Env.ie && tinymce.Env.ie < 9 ? 'LI' : 'EM'); // Old IE will return the end LI not a big deal381});382// Ignore on IE 7, 8 this is a known bug not worth fixing383if (!tinymce.Env.ie || tinymce.Env.ie > 8) {384	test('Apply UL list to br line and text block line', function() {385		editor.settings.forced_root_block = false;386		editor.setContent(387			'a' +388			'<p>b</p>'389		);390		var rng = editor.dom.createRng();391		rng.setStart(editor.getBody().firstChild, 0);392		rng.setEnd(editor.getBody().lastChild.firstChild, 1);393		editor.selection.setRng(rng);394		execCommand('InsertUnorderedList');395		equal(editor.getContent(),396			'<ul>' +397				'<li>a</li>' +398				'<li>b</li>' +399			'</ul>'400		);401		equal(editor.selection.getStart().nodeName, 'LI');402		equal(editor.selection.getEnd().nodeName, 'LI');403	});404}405test('Apply UL list to text block line and br line', function() {406	editor.settings.forced_root_block = false;407	editor.getBody().innerHTML = (408		'<p>a</p>' +409		'b'410	);411	editor.focus();412	var rng = editor.dom.createRng();413	rng.setStart(editor.getBody().firstChild.firstChild, 0);414	rng.setEnd(editor.getBody().lastChild, 1);415	editor.selection.setRng(rng);416	execCommand('InsertUnorderedList');417	equal(editor.getContent(),418		'<ul>' +419			'<li>a</li>' +420			'<li>b</li>' +421		'</ul>'422	);423	equal(editor.selection.getStart().nodeName, 'LI');424	equal(editor.selection.getEnd().nodeName, 'LI');425});426test('Apply UL list to all BR lines (SelectAll)', function() {427	editor.settings.forced_root_block = false;428	editor.getBody().innerHTML = (429		'a<br>' +430		'b<br>' +431		'c<br>'432	);433	editor.focus();434	editor.execCommand('SelectAll');435	execCommand('InsertUnorderedList');436	equal(editor.getContent(),437		'<ul>' +438			'<li>a</li>' +439			'<li>b</li>' +440			'<li>c</li>' +441		'</ul>'442	);443});444test('Apply UL list to all P lines (SelectAll)', function() {445	editor.getBody().innerHTML = (446		'<p>a</p>' +447		'<p>b</p>' +448		'<p>c</p>'449	);450	editor.focus();451	editor.execCommand('SelectAll');452	execCommand('InsertUnorderedList');453	equal(editor.getContent(),454		'<ul>' +455			'<li>a</li>' +456			'<li>b</li>' +457			'<li>c</li>' +458		'</ul>'459	);460});461// Remove462test('Remove UL at single LI', function() {463	editor.getBody().innerHTML = trimBrs(464		'<ul>' +465			'<li>a</li>' +466		'</ul>'467	);468	editor.focus();469	Utils.setSelection('li');470	execCommand('InsertUnorderedList');471	equal(editor.getContent(),472		'<p>a</p>'473	);474	equal(editor.selection.getStart().nodeName, 'P');475});476test('Remove UL at start LI', function() {477	editor.getBody().innerHTML = trimBrs(478		'<ul>' +479			'<li>a</li>' +480			'<li>b</li>' +481			'<li>c</li>' +482		'</ul>'483	);484	editor.focus();485	Utils.setSelection('li');486	execCommand('InsertUnorderedList');487	equal(editor.getContent(),488		'<p>a</p>' +489		'<ul>' +490			'<li>b</li>' +491			'<li>c</li>' +492		'</ul>'493	);494	equal(editor.selection.getStart().nodeName, 'P');495});496test('Remove UL at start empty LI', function() {497	editor.getBody().innerHTML = trimBrs(498		'<ul>' +499			'<li><br></li>' +500			'<li>b</li>' +501			'<li>c</li>' +502		'</ul>'503	);504	editor.focus();505	Utils.setSelection('li');506	execCommand('InsertUnorderedList');507	equal(editor.getContent(),508		'<p>\u00a0</p>' +509		'<ul>' +510			'<li>b</li>' +511			'<li>c</li>' +512		'</ul>'513	);514	equal(editor.selection.getNode().nodeName, 'P');515});516test('Remove UL at middle LI', function() {517	editor.getBody().innerHTML = trimBrs(518		'<ul>' +519			'<li>a</li>' +520			'<li>b</li>' +521			'<li>c</li>' +522		'</ul>'523	);524	editor.focus();525	Utils.setSelection('li:nth-child(2)', 1);526	execCommand('InsertUnorderedList');527	equal(editor.getContent(),528		'<ul>' +529			'<li>a</li>' +530		'</ul>' +531		'<p>b</p>' +532		'<ul>' +533			'<li>c</li>' +534		'</ul>'535	);536	equal(editor.selection.getStart().nodeName, 'P');537});538test('Remove UL at middle empty LI', function() {539	editor.getBody().innerHTML = trimBrs(540		'<ul>' +541			'<li>a</li>' +542			'<li><br></li>' +543			'<li>c</li>' +544		'</ul>'545	);546	editor.focus();547	Utils.setSelection('li:nth-child(2)', 0);548	execCommand('InsertUnorderedList');549	equal(editor.getContent(),550		'<ul>' +551			'<li>a</li>' +552		'</ul>' +553		'<p>\u00a0</p>' +554		'<ul>' +555			'<li>c</li>' +556		'</ul>'557	);558	equal(editor.selection.getNode().nodeName, 'P');559});560test('Remove UL at end LI', function() {561	editor.getBody().innerHTML = trimBrs(562		'<ul>' +563			'<li>a</li>' +564			'<li>b</li>' +565			'<li>c</li>' +566		'</ul>'567	);568	editor.focus();569	Utils.setSelection('li:last', 1);570	execCommand('InsertUnorderedList');571	equal(editor.getContent(),572		'<ul>' +573			'<li>a</li>' +574			'<li>b</li>' +575		'</ul>' +576		'<p>c</p>'577	);578	equal(editor.selection.getStart().nodeName, 'P');579});580test('Remove UL at end empty LI', function() {581	editor.getBody().innerHTML = trimBrs(582		'<ul>' +583			'<li>a</li>' +584			'<li>b</li>' +585			'<li><br></li>' +586		'</ul>'587	);588	editor.focus();589	Utils.setSelection('li:last', 0);590	execCommand('InsertUnorderedList');591	equal(editor.getContent(),592		'<ul>' +593			'<li>a</li>' +594			'<li>b</li>' +595		'</ul>' +596		'<p>\u00a0</p>'597	);598	equal(editor.selection.getNode().nodeName, 'P');599});600test('Remove UL at middle LI inside parent OL', function() {601	editor.getBody().innerHTML = trimBrs(602		'<ol>' +603			'<li>a</li>' +604			'<ul>' +605				'<li>b</li>' +606				'<li>c</li>' +607				'<li>d</li>' +608			'</ul>' +609			'<li>e</li>' +610		'</ol>'611	);612	editor.focus();613	Utils.setSelection('ul li:nth-child(2)', 1);614	execCommand('InsertUnorderedList');615	equal(editor.getContent(),616		'<ol>' +617			'<li>a</li>' +618			'<ul>' +619				'<li>b</li>' +620			'</ul>' +621		'</ol>' +622		'<p>c</p>' +623		'<ol>' +624			'<ul>' +625				'<li>d</li>' +626			'</ul>' +627			'<li>e</li>' +628		'</ol>'629	);630	equal(editor.selection.getStart().nodeName, 'P');631});632test('Remove UL at middle LI inside parent OL (html5)', function() {633	editor.getBody().innerHTML = trimBrs(634		'<ol>' +635			'<li>a' +636				'<ul>' +637					'<li>b</li>' +638					'<li>c</li>' +639					'<li>d</li>' +640				'</ul>' +641			'</li>' +642			'<li>e</li>' +643		'</ol>'644	);645	editor.focus();646	Utils.setSelection('ul li:nth-child(2)', 1);647	execCommand('InsertUnorderedList');648	equal(editor.getContent(),649		'<ol>' +650			'<li>a' +651				'<ul>' +652					'<li>b</li>' +653				'</ul>' +654			'</li>' +655		'</ol>' +656		'<p>c</p>' +657		'<ol>' +658			'<li>' +659				'<ul>' +660					'<li>d</li>' +661				'</ul>' +662			'</li>' +663			'<li>e</li>' +664		'</ol>'665	);666	equal(editor.selection.getStart().nodeName, 'P');667});668test('Remove UL with single LI in BR mode', function() {669	editor.settings.forced_root_block = false;670	editor.getBody().innerHTML = trimBrs(671		'<ul>' +672			'<li>a</li>' +673		'</ul>'674	);675	editor.focus();676	Utils.setSelection('li', 1);677	execCommand('InsertUnorderedList');678	equal(editor.getContent(),679		'a'680	);681	equal(editor.selection.getStart().nodeName, 'BODY');682});683test('Remove UL with multiple LI in BR mode', function() {684	editor.settings.forced_root_block = false;685	editor.getBody().innerHTML = trimBrs(686		'<ul>' +687			'<li>a</li>' +688			'<li>b</li>' +689		'</ul>'690	);691	editor.focus();692	Utils.setSelection('li:first', 1, 'li:last', 1);693	execCommand('InsertUnorderedList');694	equal(editor.getContent(),695		'a<br />' +696		'b'697	);698	equal(editor.selection.getStart().nodeName, 'BODY');699});700test('Remove empty UL between two textblocks', function() {701	editor.getBody().innerHTML = trimBrs(702		'<div>a</div>' +703		'<ul>' +704			'<li></li>' +705		'</ul>' +706		'<div>b</div>'707	);708	editor.focus();709	Utils.setSelection('li:first', 0);710	execCommand('InsertUnorderedList');711	equal(editor.getContent(),712		'<div>a</div>' +713		'<p>\u00a0</p>' +714		'<div>b</div>'715	);716	equal(editor.selection.getNode().nodeName, 'P');717});718test('Remove indented list with single item', function() {719	editor.getBody().innerHTML = trimBrs(720		'<ul>' +721			'<li>a' +722				'<ul>' +723					'<li>b</li>' +724				'</ul>' +725			'</li>' +726			'<li>c</li>' +727		'</ul>'728	);729	editor.focus();730	Utils.setSelection('li li', 0, 'li li', 1);731	execCommand('InsertUnorderedList');732	equal(editor.getContent(),733		'<ul>' +734			'<li>a</li>' +735		'</ul>' +736		'<p>b</p>' +737		'<ul>' +738			'<li>c</li>' +739		'</ul>'740	);741	equal(editor.selection.getNode().nodeName, 'P');742});743test('Remove indented list with multiple items', function() {744	editor.getBody().innerHTML = trimBrs(745		'<ul>' +746			'<li>a' +747				'<ul>' +748					'<li>b</li>' +749					'<li>c</li>' +750				'</ul>' +751			'</li>' +752			'<li>d</li>' +753		'</ul>'754	);755	editor.focus();756	Utils.setSelection('li li:first', 0, 'li li:last', 1);757	execCommand('InsertUnorderedList');758	equal(editor.getContent(),759		'<ul>' +760			'<li>a</li>' +761		'</ul>' +762		'<p>b</p>' +763		'<p>c</p>' +764		'<ul>' +765			'<li>d</li>' +766		'</ul>'767	);768	equal(editor.selection.getStart().firstChild.data, 'b');769	equal(editor.selection.getEnd().firstChild.data, 'c');770});771// Ignore on IE 7, 8 this is a known bug not worth fixing772if (!tinymce.Env.ie || tinymce.Env.ie > 8) {773	test('Remove empty UL between two textblocks in BR mode', function() {774		editor.settings.forced_root_block = false;775		editor.getBody().innerHTML = trimBrs(776			'<div>a</div>' +777			'<ul>' +778				'<li></li>' +779			'</ul>' +780			'<div>b</div>'781		);782		editor.focus();783		Utils.setSelection('li:first', 0);784		execCommand('InsertUnorderedList');785		equal(editor.getContent(),786			'<div>a</div>' +787			'<br />' +788			'<div>b</div>'789		);790		equal(editor.selection.getStart().nodeName, 'BR');791	});792}793// Outdent794test('Outdent inside LI in beginning of OL in LI', function() {795	editor.getBody().innerHTML = trimBrs(796		'<ol>' +797			'<li>a' +798				'<ol>' +799					'<li>b</li>' +800					'<li>c</li>' +801				'</ol>' +802			'</li>' +803		'</ol>'804	);805	editor.focus();806	Utils.setSelection('li li', 1);807	execCommand('Outdent');808	equal(editor.getContent(),809		'<ol>' +810			'<li>a</li>' +811			'<li>b' +812				'<ol>' +813					'<li>c</li>' +814				'</ol>' +815			'</li>' +816		'</ol>'817	);818	equal(editor.selection.getNode().nodeName, 'LI');819});820test('Outdent inside LI in middle of OL in LI', function() {821	editor.getBody().innerHTML = trimBrs(822		'<ol>' +823			'<li>a' +824				'<ol>' +825					'<li>b</li>' +826					'<li>c</li>' +827					'<li>d</li>' +828				'</ol>' +829			'</li>' +830		'</ol>'831	);832	editor.focus();833	Utils.setSelection('li li:nth-child(2)', 1);834	execCommand('Outdent');835	equal(editor.getContent(),836		'<ol>' +837			'<li>a' +838				'<ol>' +839					'<li>b</li>' +840				'</ol>' +841			'</li>' +842			'<li>c' +843				'<ol>' +844					'<li>d</li>' +845				'</ol>' +846			'</li>' +847		'</ol>'848	);849	equal(editor.selection.getNode().nodeName, 'LI');850});851test('Outdent inside LI in end of OL in LI', function() {852	editor.getBody().innerHTML = trimBrs(853		'<ol>' +854			'<li>a' +855				'<ol>' +856					'<li>b</li>' +857					'<li>c</li>' +858				'</ol>' +859			'</li>' +860		'</ol>'861	);862	editor.focus();863	Utils.setSelection('li li:last', 1);864	execCommand('Outdent');865	equal(editor.getContent(),866		'<ol>' +867			'<li>a' +868				'<ol>' +869					'<li>b</li>' +870				'</ol>' +871			'</li>' +872			'<li>c</li>' +873		'</ol>'874	);875	equal(editor.selection.getNode().nodeName, 'LI');876});877// Nested lists in OL elements878test('Outdent inside LI in beginning of OL in OL', function() {879	editor.getBody().innerHTML = trimBrs(880		'<ol>' +881			'<li>a</li>' +882			'<ol>' +883				'<li>b</li>' +884				'<li>c</li>' +885			'</ol>' +886		'</ol>'887	);888	editor.focus();889	Utils.setSelection('ol ol li', 1);890	execCommand('Outdent');891	equal(editor.getContent(),892		'<ol>' +893			'<li>a</li>' +894			'<li>b</li>' +895			'<ol>' +896				'<li>c</li>' +897			'</ol>' +898		'</ol>'899	);900	equal(editor.selection.getNode().nodeName, 'LI');901});902test('Outdent inside LI in middle of OL in OL', function() {903	editor.getBody().innerHTML = trimBrs(904		'<ol>' +905			'<li>a</li>' +906			'<ol>' +907				'<li>b</li>' +908				'<li>c</li>' +909				'<li>d</li>' +910			'</ol>' +911		'</ol>'912	);913	editor.focus();914	Utils.setSelection('ol ol li:nth-child(2)', 1);915	execCommand('Outdent');916	equal(editor.getContent(),917		'<ol>' +918			'<li>a</li>' +919			'<ol>' +920				'<li>b</li>' +921			'</ol>' +922			'<li>c</li>' +923			'<ol>' +924				'<li>d</li>' +925			'</ol>' +926		'</ol>'927	);928	equal(editor.selection.getNode().nodeName, 'LI');929});930test('Outdent inside first/last LI in inner OL', function() {931	editor.getBody().innerHTML = trimBrs(932		'<ol>' +933			'<li>1' +934			'<ol>' +935				'<li>2</li>' +936				'<li>3</li>' +937			'</ol>' +938			'</li>' +939			'<li>4</li>' +940		'</ol>'941	);942	editor.focus();943	Utils.setSelection('ol ol li:nth-child(1)', 0, 'ol ol li:nth-child(2)', 1);944	execCommand('Outdent');945	equal(editor.getContent(),946		'<ol>' +947			'<li>1</li>' +948			'<li>2</li>' +949			'<li>3</li>' +950			'<li>4</li>' +951		'</ol>'952	);953	equal(editor.selection.getRng(true).startContainer.nodeValue, '2');954	equal(editor.selection.getRng(true).endContainer.nodeValue, '3');955});956test('Outdent inside first LI in inner OL where OL is single child of parent LI', function() {957	editor.getBody().innerHTML = trimBrs(958		'<ol>' +959			'<li>a</li>' +960			'<li>' +961				'<ol>' +962					'<li>b</li>' +963					'<li>c</li>' +964				'</ol>' +965			'</li>' +966		'</ol>'967	);968	editor.focus();969	Utils.setSelection('ol ol li:first', 0);970	execCommand('Outdent');971	equal(editor.getContent(),972		'<ol>' +973			'<li>a</li>' +974			'<li>b' +975				'<ol>' +976					'<li>c</li>' +977				'</ol>' +978			'</li>' +979		'</ol>'980	);981	equal(editor.selection.getNode().nodeName, 'LI');982});983test('Outdent inside LI in end of OL in OL', function() {984	editor.getBody().innerHTML = trimBrs(985		'<ol>' +986			'<li>a</li>' +987			'<ol>' +988				'<li>b</li>' +989				'<li>c</li>' +990			'</ol>' +991		'</ol>'992	);993	editor.focus();994	Utils.setSelection('ol ol li:last', 1);995	execCommand('Outdent');996	equal(editor.getContent(),997		'<ol>' +998			'<li>a</li>' +999			'<ol>' +1000				'<li>b</li>' +1001			'</ol>' +1002			'<li>c</li>' +1003		'</ol>'1004	);1005	equal(editor.selection.getNode().nodeName, 'LI');1006});1007test('Outdent inside only child LI in OL in OL', function() {1008	editor.getBody().innerHTML = trimBrs(1009		'<ol>' +1010			'<li>a' +1011				'<ol>' +1012					'<li>b</li>' +1013				'</ol>' +1014			'</li>' +1015		'</ol>'1016	);1017	editor.focus();1018	Utils.setSelection('ol ol li', 0);1019	execCommand('Outdent');1020	equal(editor.getContent(),1021		'<ol>' +1022			'<li>a</li>' +1023			'<li>b</li>' +1024		'</ol>'1025	);1026	equal(editor.selection.getNode().nodeName, 'LI');1027});1028test('Outdent multiple LI in OL and nested OL', function() {1029	editor.getBody().innerHTML = trimBrs(1030		'<ol>' +1031			'<li>a' +1032				'<ol>' +1033					'<li>b</li>' +1034				'</ol>' +1035			'</li>' +1036		'</ol>'1037	);1038	editor.focus();1039	Utils.setSelection('li', 0, 'li li', 1);1040	execCommand('Outdent');1041	equal(editor.getContent(),1042		'<p>a</p>' +1043		'<ol>' +1044			'<li>b</li>' +1045		'</ol>'1046	);1047});1048// Indent1049test('Indent single LI in OL', function() {1050	editor.getBody().innerHTML = trimBrs(1051		'<ol>' +1052			'<li>a</li>' +1053		'</ol>'1054	);1055	editor.focus();1056	Utils.setSelection('li', 0);1057	execCommand('Indent');1058	equal(editor.getContent(),1059		'<ol>' +1060			'<li>a</li>' +1061		'</ol>'1062	);1063	equal(editor.selection.getNode().nodeName, 'LI');1064});1065test('Indent middle LI in OL', function() {1066	editor.getBody().innerHTML = trimBrs(1067		'<ol>' +1068			'<li>a</li>' +1069			'<li>b</li>' +1070			'<li>c</li>' +1071		'</ol>'1072	);1073	editor.focus();1074	Utils.setSelection('li:nth-child(2)', 0);1075	execCommand('Indent');1076	equal(editor.getContent(),1077		'<ol>' +1078			'<li>a' +1079				'<ol>' +1080					'<li>b</li>' +1081				'</ol>' +1082			'</li>' +1083			'<li>c</li>' +1084		'</ol>'1085	);1086	equal(editor.selection.getNode().nodeName, 'LI');1087});1088test('Indent last LI in OL', function() {1089	editor.getBody().innerHTML = trimBrs(1090		'<ol>' +1091			'<li>a</li>' +1092			'<li>b</li>' +1093		'</ol>'1094	);1095	editor.focus();1096	Utils.setSelection('li:last', 0);1097	execCommand('Indent');1098	equal(editor.getContent(),1099		'<ol>' +1100			'<li>a' +1101				'<ol>' +1102					'<li>b</li>' +1103				'</ol>' +1104			'</li>' +1105		'</ol>'1106	);1107	equal(editor.selection.getNode().nodeName, 'LI');1108});1109test('Indent last LI to same level as middle LI', function() {1110	editor.getBody().innerHTML = trimBrs(1111		'<ol>' +1112			'<li>a' +1113				'<ol>' +1114					'<li>b</li>' +1115				'</ol>' +1116			'</li>' +1117			'<li>c</li>' +1118		'</ol>'1119	);1120	editor.focus();1121	Utils.setSelection('li:last', 1);1122	execCommand('Indent');1123	equal(editor.getContent(),1124		'<ol>' +1125			'<li>a' +1126				'<ol>' +1127					'<li>b</li>' +1128					'<li>c</li>' +1129				'</ol>' +1130			'</li>' +1131		'</ol>'1132	);1133	equal(editor.selection.getNode().nodeName, 'LI');1134});1135test('Indent first LI and nested LI OL', function() {1136	editor.getBody().innerHTML = trimBrs(1137		'<ol>' +1138			'<li>a' +1139				'<ol>' +1140					'<li>b</li>' +1141				'</ol>' +1142			'</li>' +1143		'</ol>'1144	);1145	editor.focus();1146	Utils.setSelection('li', 0, 'li li', 0);1147	execCommand('Indent');1148	equal(editor.getContent(),1149		'<ol>' +1150			'<li>a' +1151				'<ol>' +1152					'<li>b</li>' +1153				'</ol>' +1154			'</li>' +1155		'</ol>'1156	);1157	equal(editor.selection.getNode().nodeName, 'LI');1158});1159test('Indent second LI to same level as nested LI', function() {1160	editor.getBody().innerHTML = trimBrs(1161		'<ul>' +1162			'<li>a</li>' +1163			'<li>b' +1164				'<ul>' +1165					'<li>c</li>' +1166				'</ul>' +1167			'</li>' +1168		'</ul>'1169	);1170	editor.focus();1171	Utils.setSelection('li:nth-child(2)', 0);1172	execCommand('Indent');1173	equal(editor.getContent(),1174		'<ul>' +1175			'<li>a' +1176				'<ul>' +1177					'<li>b</li>' +1178					'<li>c</li>' +1179				'</ul>' +1180			'</li>' +1181		'</ul>'1182	);1183	equal(editor.selection.getNode().nodeName, 'LI');1184});1185test('Indent second LI to same level as nested LI 2', function() {1186	editor.getBody().innerHTML = trimBrs(1187		'<ul>' +1188			'<li>a' +1189				'<ul>' +1190					'<li>b</li>' +1191				'</ul>' +1192			'</li>' +1193			'<li>cd' +1194				'<ul>' +1195					'<li>e</li>' +1196				'</ul>' +1197			'</li>' +1198		'</ul>'1199	);1200	editor.focus();1201	Utils.setSelection('li:nth-child(2)', 1);1202	execCommand('Indent');1203	equal(editor.getContent(),1204		'<ul>' +1205			'<li>a' +1206				'<ul>' +1207					'<li>b</li>' +1208					'<li>cd</li>' +1209					'<li>e</li>' +1210				'</ul>' +1211			'</li>' +1212		'</ul>'1213	);1214	equal(editor.selection.getNode().nodeName, 'LI');1215});1216test('Indent second and third LI', function() {1217	editor.getBody().innerHTML = trimBrs(1218		'<ul>' +1219			'<li>a</li>' +1220			'<li>b</li>' +1221			'<li>c</li>' +1222		'</ul>'1223	);1224	editor.focus();1225	Utils.setSelection('li:nth-child(2)', 0, 'li:last', 0);1226	execCommand('Indent');1227	equal(editor.getContent(),1228		'<ul>' +1229			'<li>a' +1230				'<ul>' +1231					'<li>b</li>' +1232					'<li>c</li>' +1233				'</ul>' +1234			'</li>' +1235		'</ul>'1236	);1237});1238// Backspace1239test('Backspace at beginning of single LI in UL', function() {1240	editor.getBody().innerHTML = trimBrs(1241		'<ul>' +1242			'<li>a</li>' +1243		'</ul>'1244	);1245	editor.focus();1246	Utils.setSelection('li', 0);1247	editor.plugins.lists.backspaceDelete();1248	equal(editor.getContent(),1249		'<p>a</p>'1250	);1251	equal(editor.selection.getNode().nodeName, 'P');1252});1253test('Backspace at beginning of first LI in UL', function() {1254	editor.getBody().innerHTML = trimBrs(1255		'<ul>' +1256			'<li>a</li>' +1257			'<li>b</li>' +1258		'</ul>'1259	);1260	editor.focus();1261	Utils.setSelection('li', 0);1262	editor.plugins.lists.backspaceDelete();1263	equal(editor.getContent(),1264		'<p>a</p>' +1265		'<ul>' +1266			'<li>b</li>' +1267		'</ul>'1268	);1269	equal(editor.selection.getNode().nodeName, 'P');1270});1271test('Backspace at beginning of middle LI in UL', function() {1272	editor.getBody().innerHTML = trimBrs(1273		'<ul>' +1274			'<li>a</li>' +1275			'<li>b</li>' +1276			'<li>c</li>' +1277		'</ul>'1278	);1279	editor.focus();1280	Utils.setSelection('li:nth-child(2)', 0);1281	editor.plugins.lists.backspaceDelete();1282	equal(editor.getContent(),1283		'<ul>' +1284			'<li>ab</li>' +1285			'<li>c</li>' +1286		'</ul>'1287	);1288	equal(editor.selection.getNode().nodeName, 'LI');1289});1290test('Backspace at beginning of start LI in UL inside UL', function() {1291	editor.getBody().innerHTML = trimBrs(1292		'<ul>' +1293			'<li>a' +1294				'<ul>' +1295					'<li>b</li>' +1296					'<li>c</li>' +1297				'</ul>' +1298			'</li>' +1299		'</ul>'1300	);1301	editor.focus();1302	Utils.setSelection('li li', 0);1303	editor.plugins.lists.backspaceDelete();1304	equal(editor.getContent(),1305		'<ul>' +1306			'<li>ab' +1307				'<ul>' +1308					'<li>c</li>' +1309				'</ul>' +1310			'</li>' +1311		'</ul>'1312	);1313	equal(editor.selection.getNode().nodeName, 'LI');1314});1315test('Backspace at beginning of middle LI in UL inside UL', function() {1316	editor.getBody().innerHTML = trimBrs(1317		'<ul>' +1318			'<li>a' +1319				'<ul>' +1320					'<li>b</li>' +1321					'<li>c</li>' +1322					'<li>d</li>' +1323				'</ul>' +1324			'</li>' +1325		'</ul>'1326	);1327	editor.focus();1328	Utils.setSelection('li li:nth-child(2)', 0);1329	editor.plugins.lists.backspaceDelete();1330	equal(editor.getContent(),1331		'<ul>' +1332			'<li>a' +1333				'<ul>' +1334					'<li>bc</li>' +1335					'<li>d</li>' +1336				'</ul>' +1337			'</li>' +1338		'</ul>'1339	);1340	equal(editor.selection.getNode().nodeName, 'LI');1341});1342test('Backspace at beginning of single LI in UL', function() {1343	editor.getBody().innerHTML = trimBrs(1344		'<ul>' +1345			'<li>a</li>' +1346		'</ul>'1347	);1348	editor.focus();1349	Utils.setSelection('li', 0);1350	editor.plugins.lists.backspaceDelete();1351	equal(editor.getContent(),1352		'<p>a</p>'1353	);1354	equal(editor.selection.getNode().nodeName, 'P');1355});1356test('Backspace at beginning of first LI in UL', function() {1357	editor.getBody().innerHTML = trimBrs(1358		'<ul>' +1359			'<li>a</li>' +1360			'<li>b</li>' +1361		'</ul>'1362	);1363	editor.focus();1364	Utils.setSelection('li', 0);1365	editor.plugins.lists.backspaceDelete();1366	equal(editor.getContent(),1367		'<p>a</p>' +1368		'<ul>' +1369			'<li>b</li>' +1370		'</ul>'1371	);1372	equal(editor.selection.getNode().nodeName, 'P');1373});1374test('Backspace at beginning of middle LI in UL', function() {1375	editor.getBody().innerHTML = trimBrs(1376		'<ul>' +1377			'<li>a</li>' +1378			'<li>b</li>' +1379			'<li>c</li>' +1380		'</ul>'1381	);1382	editor.focus();1383	Utils.setSelection('li:nth-child(2)', 0);1384	editor.plugins.lists.backspaceDelete();1385	equal(editor.getContent(),1386		'<ul>' +1387			'<li>ab</li>' +1388			'<li>c</li>' +1389		'</ul>'1390	);1391	equal(editor.selection.getNode().nodeName, 'LI');1392});1393test('Backspace at beginning of start LI in UL inside UL', function() {1394	editor.getBody().innerHTML = trimBrs(1395		'<ul>' +1396			'<li>a' +1397				'<ul>' +1398					'<li>b</li>' +1399					'<li>c</li>' +1400				'</ul>' +1401			'</li>' +1402		'</ul>'1403	);1404	editor.focus();1405	Utils.setSelection('li li', 0);1406	editor.plugins.lists.backspaceDelete();1407	equal(editor.getContent(),1408		'<ul>' +1409			'<li>ab' +1410				'<ul>' +1411					'<li>c</li>' +1412				'</ul>' +1413			'</li>' +1414		'</ul>'1415	);1416	equal(editor.selection.getNode().nodeName, 'LI');1417});1418test('Backspace at beginning of middle LI in UL inside UL', function() {1419	editor.getBody().innerHTML = trimBrs(1420		'<ul>' +1421			'<li>a' +1422				'<ul>' +1423					'<li>b</li>' +1424					'<li>c</li>' +1425					'<li>d</li>' +1426				'</ul>' +1427			'</li>' +1428		'</ul>'1429	);1430	editor.focus();1431	Utils.setSelection('li li:nth-child(2)', 0);1432	editor.plugins.lists.backspaceDelete();1433	equal(editor.getContent(),1434		'<ul>' +1435			'<li>a' +1436				'<ul>' +1437					'<li>bc</li>' +1438					'<li>d</li>' +1439				'</ul>' +1440			'</li>' +1441		'</ul>'1442	);1443	equal(editor.selection.getNode().nodeName, 'LI');1444});1445test('Backspace at beginning of LI with empty LI above in UL', function() {1446	editor.getBody().innerHTML = trimBrs(1447		'<ul>' +1448			'<li>a</li>' +1449			'<li></li>' +1450			'<li>b</li>' +1451		'</ul>'1452	);1453	editor.focus();1454	Utils.setSelection('li:nth-child(3)', 0);1455	editor.plugins.lists.backspaceDelete();1456	equal(editor.getContent(),1457		'<ul>' +1458			'<li>a</li>' +1459			'<li>b</li>' +1460		'</ul>'1461	);1462	equal(editor.selection.getNode().innerHTML, 'b');1463});1464test('Backspace at beginning of LI with BR padded empty LI above in UL', function() {1465	editor.getBody().innerHTML = (1466		'<ul>' +1467			'<li>a</li>' +1468			'<li><br></li>' +1469			'<li>b</li>' +1470		'</ul>'1471	);1472	editor.focus();1473	Utils.setSelection('li:nth-child(3)', 0);1474	editor.plugins.lists.backspaceDelete();1475	equal(editor.getContent(),1476		'<ul>' +1477			'<li>a</li>' +1478			'<li>b</li>' +1479		'</ul>'1480	);1481	equal(editor.selection.getNode().innerHTML, 'b');1482});1483test('Backspace at empty LI (IE)', function() {1484	editor.getBody().innerHTML = (1485		'<ul>' +1486			'<li>a</li>' +1487			'<li></li>' +1488			'<li>b</li>' +1489		'</ul>'1490	);1491	editor.focus();1492	Utils.setSelection('li:nth-child(2)', 0);1493	editor.plugins.lists.backspaceDelete();1494	equal(editor.getContent(),1495		'<ul>' +1496			'<li>a</li>' +1497			'<li>b</li>' +1498		'</ul>'1499	);1500	equal(editor.selection.getNode().innerHTML, 'a');1501});1502test('Backspace at beginning of LI with empty LI with STRING and BR above in UL', function() {1503	editor.getBody().innerHTML = (1504		'<ul>' +1505			'<li>a</li>' +1506			'<li><strong><br></strong></li>' +1507			'<li>b</li>' +1508		'</ul>'1509	);1510	editor.focus();1511	Utils.setSelection('li:nth-child(3)', 0);1512	editor.plugins.lists.backspaceDelete();1513	equal(editor.getContent(),1514		'<ul>' +1515			'<li>a</li>' +1516			'<li>b</li>' +1517		'</ul>'1518	);1519	equal(editor.selection.getNode().innerHTML, 'b');1520});1521// Delete1522test('Delete at end of single LI in UL', function() {1523	editor.getBody().innerHTML = trimBrs(1524		'<ul>' +1525			'<li>a</li>' +1526		'</ul>'1527	);1528	editor.focus();1529	Utils.setSelection('li', 1);1530	editor.plugins.lists.backspaceDelete(true);1531	equal(editor.getContent(),1532		'<ul>' +1533			'<li>a</li>' +1534		'</ul>'1535	);1536	equal(editor.selection.getNode().nodeName, 'LI');1537});1538test('Delete at end of first LI in UL', function() {1539	editor.getBody().innerHTML = trimBrs(1540		'<ul>' +1541			'<li>a</li>' +1542			'<li>b</li>' +1543		'</ul>'1544	);1545	editor.focus();1546	Utils.setSelection('li', 1);1547	editor.plugins.lists.backspaceDelete(true);1548	equal(editor.getContent(),1549		'<ul>' +1550			'<li>ab</li>' +1551		'</ul>'1552	);1553	equal(editor.selection.getNode().nodeName, 'LI');1554});1555test('Delete at end of middle LI in UL', function() {1556	editor.getBody().innerHTML = trimBrs(1557		'<ul>' +1558			'<li>a</li>' +1559			'<li>b</li>' +1560			'<li>c</li>' +1561		'</ul>'1562	);1563	editor.focus();1564	Utils.setSelection('li:nth-child(2)', 1);1565	editor.plugins.lists.backspaceDelete(true);1566	equal(editor.getContent(),1567		'<ul>' +1568			'<li>a</li>' +1569			'<li>bc</li>' +1570		'</ul>'1571	);1572	equal(editor.selection.getNode().nodeName, 'LI');1573});1574test('Delete at end of start LI in UL inside UL', function() {1575	editor.getBody().innerHTML = trimBrs(1576		'<ul>' +1577			'<li>a' +1578				'<ul>' +1579					'<li>b</li>' +1580					'<li>c</li>' +1581				'</ul>' +1582			'</li>' +1583		'</ul>'1584	);1585	editor.focus();1586	Utils.setSelection('li li', 1);1587	editor.plugins.lists.backspaceDelete(true);1588	equal(editor.getContent(),1589		'<ul>' +1590			'<li>a' +1591				'<ul>' +1592					'<li>bc</li>' +1593				'</ul>' +1594			'</li>' +1595		'</ul>'1596	);1597	equal(editor.selection.getNode().nodeName, 'LI');1598});1599test('Delete at end of middle LI in UL inside UL', function() {1600	editor.getBody().innerHTML = trimBrs(1601		'<ul>' +1602			'<li>a' +1603				'<ul>' +1604					'<li>b</li>' +1605					'<li>c</li>' +1606					'<li>d</li>' +1607				'</ul>' +1608			'</li>' +1609		'</ul>'1610	);1611	editor.focus();1612	Utils.setSelection('li li:nth-child(2)', 1);1613	editor.plugins.lists.backspaceDelete(true);1614	equal(editor.getContent(),1615		'<ul>' +1616			'<li>a' +1617				'<ul>' +1618					'<li>b</li>' +1619					'<li>cd</li>' +1620				'</ul>' +1621			'</li>' +1622		'</ul>'1623	);1624	equal(editor.selection.getNode().nodeName, 'LI');1625});1626test('Delete at end of LI before empty LI', function() {1627	editor.getBody().innerHTML = (1628		'<ul>' +1629			'<li>a</li>' +1630			'<li></li>' +1631			'<li>b</li>' +1632		'</ul>'1633	);1634	editor.focus();1635	Utils.setSelection('li', 1);1636	editor.plugins.lists.backspaceDelete(true);1637	equal(editor.getContent(),1638		'<ul>' +1639			'<li>a</li>' +1640			'<li>b</li>' +1641		'</ul>'1642	);1643	equal(editor.selection.getNode().innerHTML, 'a');1644});1645test('Delete at end of LI before BR padded empty LI', function() {1646	editor.getBody().innerHTML = (1647		'<ul>' +1648			'<li>a</li>' +1649			'<li><br></li>' +1650			'<li>b</li>' +1651		'</ul>'1652	);1653	editor.focus();1654	Utils.setSelection('li', 1);1655	editor.plugins.lists.backspaceDelete(true);1656	equal(editor.getContent(),1657		'<ul>' +1658			'<li>a</li>' +1659			'<li>b</li>' +1660		'</ul>'1661	);1662	equal(editor.selection.getNode().innerHTML, 'a');1663});1664test('Delete at end of LI before empty LI with STRONG', function() {1665	editor.getBody().innerHTML = (1666		'<ul>' +1667			'<li>a</li>' +1668			'<li><strong><br></strong></li>' +1669			'<li>b</li>' +1670		'</ul>'1671	);1672	editor.focus();1673	Utils.setSelection('li', 1);1674	editor.plugins.lists.backspaceDelete(true);1675	equal(editor.getContent(),1676		'<ul>' +1677			'<li>a</li>' +1678			'<li>b</li>' +1679		'</ul>'1680	);1681	equal(editor.selection.getNode().innerHTML, 'a');1682});1683test('Remove UL in inline body element contained in LI', function() {1684	inlineEditor.setContent('<ul><li>a</li></ul>');1685	inlineEditor.selection.setCursorLocation();1686	inlineEditor.execCommand('InsertUnorderedList');1687	equal(inlineEditor.getContent(), '<p>a</p>');1688});1689test('Backspace in LI in UL in inline body element contained within LI', function() {1690	inlineEditor.setContent('<ul><li>a</li></ul>');1691	inlineEditor.focus();1692	inlineEditor.selection.select(inlineEditor.getBody(), true);1693	inlineEditor.selection.collapse(true);1694	inlineEditor.plugins.lists.backspaceDelete();1695	equal(inlineEditor.getContent(), '<p>a</p>');1696});1697test('Apply DL list to multiple Ps', function() {1698	editor.getBody().innerHTML = trimBrs(1699		'<p>a</p>' +1700		'<p>b</p>' +1701		'<p>c</p>'1702	);1703	editor.focus();1704	Utils.setSelection('p', 0, 'p:last', 0);1705	execCommand('InsertDefinitionList');1706	equal(editor.getContent(),1707		'<dl>' +1708			'<dt>a</dt>' +1709			'<dt>b</dt>' +1710			'<dt>c</dt>' +1711		'</dl>'1712	);1713	equal(editor.selection.getStart().nodeName, 'DT');1714});1715test('Apply OL list to single P', function() {1716	editor.getBody().innerHTML = trimBrs(1717		'<p>a</p>'1718	);1719	editor.focus();1720	Utils.setSelection('p', 0);1721	execCommand('InsertDefinitionList');1722	equal(editor.getContent(), '<dl><dt>a</dt></dl>');1723	equal(editor.selection.getNode().nodeName, 'DT');1724});1725test('Apply DL to P and merge with adjacent lists', function() {1726	editor.getBody().innerHTML = trimBrs(1727		'<dl>' +1728			'<dt>a</dt>' +1729		'</dl>' +1730		'<p>b</p>' +1731		'<dl>' +1732			'<dt>c</dt>' +1733		'</dl>'1734	);1735	editor.focus();1736	Utils.setSelection('p', 1);1737	execCommand('InsertDefinitionList');1738	equal(editor.getContent(),1739		'<dl>' +1740			'<dt>a</dt>' +1741			'<dt>b</dt>' +1742			'<dt>c</dt>' +1743		'</dl>'1744	);1745	equal(editor.selection.getStart().nodeName, 'DT');1746});1747test('Indent single DT in DL', function() {1748	editor.getBody().innerHTML = trimBrs(1749		'<dl>' +1750			'<dt>a</dt>' +1751		'</dl>'1752	);1753	editor.focus();1754	Utils.setSelection('dt', 0);1755	execCommand('Indent');1756	equal(editor.getContent(),1757		'<dl>' +1758			'<dd>a</dd>' +1759		'</dl>'1760	);1761	equal(editor.selection.getNode().nodeName, 'DD');1762});1763test('Outdent single DD in DL', function() {1764	editor.getBody().innerHTML = trimBrs(1765		'<dl>' +1766			'<dd>a</dd>' +1767		'</dl>'1768	);1769	editor.focus();1770	Utils.setSelection('dd', 1);1771	execCommand('Outdent');1772	equal(editor.getContent(),1773		'<dl>' +1774			'<dt>a</dt>' +1775		'</dl>'1776	);1777	equal(editor.selection.getNode().nodeName, 'DT');...EnterKey.js
Source:EnterKey.js  
...29	}30});31test('Enter at end of H1', function() {32	editor.setContent('<h1>abc</h1>');33	Utils.setSelection('h1', 3);34	Utils.pressEnter();35	equal(editor.getContent(),'<h1>abc</h1><p>\u00a0</p>');36	equal(editor.selection.getRng(true).startContainer.nodeName, 'P');37});38test('Enter in midde of H1', function() {39	editor.setContent('<h1>abcd</h1>');40	Utils.setSelection('h1', 2);41	Utils.pressEnter();42	equal(editor.getContent(),'<h1>ab</h1><h1>cd</h1>');43	equal(editor.selection.getRng(true).startContainer.parentNode.nodeName, 'H1');44});45test('Enter before text after EM', function() {46	editor.setContent('<p><em>a</em>b</p>');47	editor.selection.setCursorLocation(editor.getBody().firstChild, 1);48	Utils.pressEnter();49	equal(editor.getContent(),'<p><em>a</em></p><p>b</p>');50	var rng = editor.selection.getRng(true);51	equal(rng.startContainer.nodeValue, 'b');52});53test('Enter before first IMG in P', function() {54	editor.setContent('<p><img alt="" src="about:blank" /></p>');55	editor.selection.setCursorLocation(editor.getBody().firstChild, 0);56	Utils.pressEnter();57	equal(editor.getContent(),'<p>\u00a0</p><p><img src="about:blank" alt="" /></p>');58});59test('Enter before last IMG in P with text', function() {60	editor.setContent('<p>abc<img alt="" src="about:blank" /></p>');61	editor.selection.setCursorLocation(editor.getBody().firstChild, 1);62	Utils.pressEnter();63	equal(editor.getContent(),'<p>abc</p><p><img src="about:blank" alt="" /></p>');64	var rng = editor.selection.getRng(true);65	equal(rng.startContainer.nodeName, 'P');66	equal(rng.startContainer.childNodes[rng.startOffset].nodeName, 'IMG');67});68test('Enter before last IMG in P with IMG sibling', function() {69	editor.setContent('<p><img src="about:blank" alt="" /><img src="about:blank" alt="" /></p>');70	editor.selection.setCursorLocation(editor.getBody().firstChild, 1);71	Utils.pressEnter();72	equal(editor.getContent(),'<p><img src="about:blank" alt="" /></p><p><img src="about:blank" alt="" /></p>');73	var rng = editor.selection.getRng(true);74	equal(rng.startContainer.nodeName, 'P');75	equal(rng.startContainer.childNodes[rng.startOffset].nodeName, 'IMG');76});77test('Enter after last IMG in P', function() {78	editor.setContent('<p>abc<img alt="" src="about:blank" /></p>');79	editor.selection.setCursorLocation(editor.getBody().firstChild, 2);80	Utils.pressEnter();81	equal(editor.getContent(),'<p>abc<img src="about:blank" alt="" /></p><p>\u00a0</p>');82});83test('Enter before last INPUT in P with text', function() {84	editor.setContent('<p>abc<input type="text" /></p>');85	editor.selection.setCursorLocation(editor.getBody().firstChild, 1);86	Utils.pressEnter();87	equal(editor.getContent(),'<p>abc</p><p><input type="text" /></p>');88	var rng = editor.selection.getRng(true);89	equal(rng.startContainer.nodeName, 'P');90	equal(rng.startContainer.childNodes[rng.startOffset].nodeName, 'INPUT');91});92test('Enter before last INPUT in P with IMG sibling', function() {93	editor.setContent('<p><input type="text" /><input type="text" /></p>');94	editor.selection.setCursorLocation(editor.getBody().firstChild, 1);95	Utils.pressEnter();96	equal(editor.getContent(),'<p><input type="text" /></p><p><input type="text" /></p>');97	var rng = editor.selection.getRng(true);98	equal(rng.startContainer.nodeName, 'P');99	equal(rng.startContainer.childNodes[rng.startOffset].nodeName, 'INPUT');100});101test('Enter after last INPUT in P', function() {102	editor.setContent('<p>abc<input type="text" /></p>');103	editor.selection.setCursorLocation(editor.getBody().firstChild, 2);104	Utils.pressEnter();105	equal(editor.getContent(),'<p>abc<input type="text" /></p><p>\u00a0</p>');106});107test('Enter at end of P', function() {108	editor.setContent('<p>abc</p>');109	Utils.setSelection('p', 3);110	Utils.pressEnter();111	equal(editor.getContent(),'<p>abc</p><p>\u00a0</p>');112	equal(editor.selection.getRng(true).startContainer.nodeName, 'P');113});114test('Enter at end of EM inside P', function() {115	editor.setContent('<p><em>abc</em></p>');116	Utils.setSelection('em', 3);117	Utils.pressEnter();118	equal(Utils.cleanHtml(editor.getBody().innerHTML).replace(/<br([^>]+|)>| /g, ''), '<p><em>abc</em></p><p><em></em></p>');119	equal(editor.selection.getRng(true).startContainer.nodeName, 'EM');120});121test('Enter at middle of EM inside P', function() {122	editor.setContent('<p><em>abcd</em></p>');123	Utils.setSelection('em', 2);124	Utils.pressEnter();125	equal(editor.getContent(),'<p><em>ab</em></p><p><em>cd</em></p>');126	equal(editor.selection.getRng(true).startContainer.parentNode.nodeName, 'EM');127});128test('Enter at beginning EM inside P', function() {129	editor.setContent('<p><em>abc</em></p>');130	Utils.setSelection('em', 0);131	Utils.pressEnter();132	equal(Utils.cleanHtml(editor.getBody().innerHTML).replace(/<br([^>]+|)>| /g, ''), '<p><em></em></p><p><em>abc</em></p>');133	equal(editor.selection.getRng(true).startContainer.nodeValue, 'abc');134});135test('Enter at end of STRONG in EM inside P', function() {136	editor.setContent('<p><em><strong>abc</strong></em></p>');137	Utils.setSelection('strong', 3);138	Utils.pressEnter();139	equal(Utils.cleanHtml(editor.getBody().innerHTML).replace(/<br([^>]+|)>| /g, ''), '<p><em><strong>abc</strong></em></p><p><em><strong></strong></em></p>');140	equal(editor.selection.getRng(true).startContainer.nodeName, 'STRONG');141});142test('Enter at middle of STRONG in EM inside P', function() {143	editor.setContent('<p><em><strong>abcd</strong></em></p>');144	Utils.setSelection('strong', 2);145	Utils.pressEnter();146	equal(editor.getContent(),'<p><em><strong>ab</strong></em></p><p><em><strong>cd</strong></em></p>');147	equal(editor.selection.getRng(true).startContainer.parentNode.nodeName, 'STRONG');148});149test('Enter at beginning STRONG in EM inside P', function() {150	editor.setContent('<p><em><strong>abc</strong></em></p>');151	Utils.setSelection('strong', 0);152	Utils.pressEnter();153	equal(Utils.cleanHtml(editor.getBody().innerHTML).replace(/<br([^>]+|)>| /g, ''), '<p><em><strong></strong></em></p><p><em><strong>abc</strong></em></p>');154	equal(editor.selection.getRng(true).startContainer.nodeValue, 'abc');155});156test('Enter at beginning of P', function() {157	editor.setContent('<p>abc</p>');158	Utils.setSelection('p', 0);159	Utils.pressEnter();160	equal(editor.getContent(),'<p>\u00a0</p><p>abc</p>');161	equal(editor.selection.getRng(true).startContainer.nodeValue, 'abc');162});163test('Enter at middle of P with style, id and class attributes', function() {164	editor.setContent('<p id="a" class="b" style="color:#000">abcd</p>');165	Utils.setSelection('p', 2);166	Utils.pressEnter();167	equal(editor.getContent(),'<p id="a" class="b" style="color: #000;">ab</p><p class="b" style="color: #000;">cd</p>');168	equal(editor.selection.getRng(true).startContainer.parentNode.nodeName, 'P');169});170test('Enter at a range between H1 and P', function() {171	editor.setContent('<h1>abcd</h1><p>efgh</p>');172	Utils.setSelection('h1', 2, 'p', 2);173	Utils.pressEnter();174	equal(editor.getContent(),'<h1>abgh</h1>');175	equal(editor.selection.getNode().nodeName, 'H1');176});177test('Enter at end of H1 in HGROUP', function() {178	editor.setContent('<hgroup><h1>abc</h1></hgroup>');179	Utils.setSelection('h1', 3);180	Utils.pressEnter();181	equal(editor.getContent(),'<hgroup><h1>abc</h1><h1>\u00a0</h1></hgroup>');182	equal(editor.selection.getRng(true).startContainer.nodeName, 'H1');183});184test('Enter inside empty TD', function() {185	editor.getBody().innerHTML = '<table><tr><td></td></tr></table>';186	Utils.setSelection('td', 0);187	Utils.pressEnter();188	equal(Utils.cleanHtml(editor.getBody().innerHTML).replace(/<br([^>]+|)>| /g, ''), '<table><tbody><tr><td><p></p><p></p></td></tr></tbody></table>');189	equal(editor.selection.getNode().nodeName, 'P');190});191test('Shift+Enter inside STRONG inside TD with BR', function() {192	editor.getBody().innerHTML = '<table><tr><td>d <strong>e</strong><br></td></tr></table>';193	Utils.setSelection('strong', 1);194	Utils.pressEnter({shiftKey: true});195	equal(Utils.cleanHtml(editor.getBody().innerHTML), '<table><tbody><tr><td>d <strong>e<br></strong><br></td></tr></tbody></table>');196	equal(editor.selection.getNode().nodeName, 'STRONG');197});198test('Enter inside middle of text node in body', function() {199	editor.getBody().innerHTML = 'abcd';200	Utils.setSelection('body', 2);201	Utils.pressEnter();202	equal(editor.getContent(),'<p>ab</p><p>cd</p>');203	equal(editor.selection.getNode().nodeName, 'P');204});205test('Enter inside at beginning of text node in body', function() {206	editor.getBody().innerHTML = 'abcd';207	Utils.setSelection('body', 0);208	Utils.pressEnter();209	equal(editor.getContent(),'<p>\u00a0</p><p>abcd</p>');210	equal(editor.selection.getNode().nodeName, 'P');211});212test('Enter inside at end of text node in body', function() {213	editor.getBody().innerHTML = 'abcd';214	Utils.setSelection('body', 4);215	Utils.pressEnter();216	equal(editor.getContent(),'<p>abcd</p><p>\u00a0</p>');217	equal(editor.selection.getNode().nodeName, 'P');218});219test('Enter inside empty body', function() {220	editor.getBody().innerHTML = '';221	Utils.setSelection('body', 0);222	Utils.pressEnter();223	equal(editor.getContent(),'<p>\u00a0</p><p>\u00a0</p>');224	equal(editor.selection.getNode().nodeName, 'P');225});226test('Enter inside empty li in beginning of ol', function() {227	editor.getBody().innerHTML = (tinymce.isIE && tinymce.Env.ie < 11) ? '<ol><li></li><li>a</li></ol>': '<ol><li><br></li><li>a</li></ol>';228	Utils.setSelection('li', 0);229	Utils.pressEnter();230	equal(editor.getContent(),'<p>\u00a0</p><ol><li>a</li></ol>');231	equal(editor.selection.getNode().nodeName, 'P');232});233test('Enter inside empty li at the end of ol', function() {234	editor.getBody().innerHTML = (tinymce.isIE && tinymce.Env.ie < 11) ? '<ol><li>a</li><li></li></ol>': '<ol><li>a</li><li><br></li></ol>';235	Utils.setSelection('li:last', 0);236	Utils.pressEnter();237	equal(editor.getContent(),'<ol><li>a</li></ol><p>\u00a0</p>');238	equal(editor.selection.getNode().nodeName, 'P');239});240test('Shift+Enter inside empty li in the middle of ol', function() {241	editor.getBody().innerHTML = (tinymce.isIE && tinymce.Env.ie < 11) ? '<ol><li>a</li><li></li><li>b</li></ol>':  '<ol><li>a</li><li><br></li><li>b</li></ol>';242	Utils.setSelection('li:nth-child(2)', 0);243	Utils.pressEnter({shiftKey: true});244	equal(editor.getContent(),'<ol><li>a</li></ol><p>\u00a0</p><ol><li>b</li></ol>');245	equal(editor.selection.getNode().nodeName, 'P');246});247test('Shift+Enter inside empty li in beginning of ol', function() {248	editor.getBody().innerHTML = (tinymce.isIE && tinymce.Env.ie < 11) ? '<ol><li></li><li>a</li></ol>': '<ol><li><br></li><li>a</li></ol>';249	Utils.setSelection('li', 0);250	Utils.pressEnter({shiftKey: true});251	equal(editor.getContent(),'<p>\u00a0</p><ol><li>a</li></ol>');252	equal(editor.selection.getNode().nodeName, 'P');253});254test('Shift+Enter inside empty li at the end of ol', function() {255	editor.getBody().innerHTML = (tinymce.isIE && tinymce.Env.ie < 11) ? '<ol><li>a</li><li></li></ol>': '<ol><li>a</li><li><br></li></ol>';256	Utils.setSelection('li:last', 0);257	Utils.pressEnter({shiftKey: true});258	equal(editor.getContent(),'<ol><li>a</li></ol><p>\u00a0</p>');259	equal(editor.selection.getNode().nodeName, 'P');260});261test('Enter inside empty li in the middle of ol with forced_root_block: false', function() {262	editor.settings.forced_root_block = false;263	editor.getBody().innerHTML = (tinymce.isIE && tinymce.Env.ie < 11) ? '<ol><li>a</li><li></li><li>b</li></ol>':  '<ol><li>a</li><li><br></li><li>b</li></ol>';264	Utils.setSelection('li:nth-child(2)', 0);265	Utils.pressEnter();266	equal(editor.getContent(),'<ol><li>a</li></ol><br /><ol><li>b</li></ol>');267	equal(editor.selection.getNode().nodeName, 'BODY');268});269test('Enter inside empty li in beginning of ol with forced_root_block: false', function() {270	editor.settings.forced_root_block = false;271	editor.getBody().innerHTML = (tinymce.isIE && tinymce.Env.ie < 11) ? '<ol><li></li><li>a</li></ol>': '<ol><li><br></li><li>a</li></ol>';272	Utils.setSelection('li', 0);273	Utils.pressEnter();274	equal(editor.getContent(),'<br /><ol><li>a</li></ol>');275	equal(editor.selection.getNode().nodeName, 'BODY');276});277test('Enter inside empty li at the end of ol with forced_root_block: false', function() {278	editor.settings.forced_root_block = false;279	editor.getBody().innerHTML = (tinymce.isIE && tinymce.Env.ie < 11) ? '<ol><li>a</li><li></li></ol>': '<ol><li>a</li><li><br></li></ol>';280	Utils.setSelection('li:last', 0);281	Utils.pressEnter();282	equal(Utils.cleanHtml(editor.getBody().innerHTML), '<ol><li>a</li></ol><br>');283	equal(editor.selection.getNode().nodeName, 'BODY');284});285test('Enter inside empty li in the middle of ol', function() {286	editor.getBody().innerHTML = (tinymce.isIE && tinymce.Env.ie < 11) ? '<ol><li>a</li><li></li><li>b</li></ol>':  '<ol><li>a</li><li><br></li><li>b</li></ol>';287	Utils.setSelection('li:nth-child(2)', 0);288	Utils.pressEnter();289	equal(editor.getContent(),'<ol><li>a</li></ol><p>\u00a0</p><ol><li>b</li></ol>');290	equal(editor.selection.getNode().nodeName, 'P');291});292// Nested lists in LI elements293test('Enter inside empty LI in beginning of OL in LI', function() {294	editor.getBody().innerHTML = Utils.trimBrsOnIE(295		'<ol>' +296			'<li>a' +297				'<ol>' +298					'<li><br></li>' +299					'<li>a</li>' +300				'</ol>' +301			'</li>' +302		'</ol>'303	);304	Utils.setSelection('li li', 0);305	editor.focus();306	Utils.pressEnter();307	equal(editor.getContent(),308		'<ol>' +309			'<li>a</li>' +310			'<li>' +311				'<ol>' +312					'<li>a</li>' +313				'</ol>' +314			'</li>' +315		'</ol>'316	);317	equal(editor.selection.getNode().nodeName, 'LI');318});319test('Enter inside empty LI in middle of OL in LI', function() {320	editor.getBody().innerHTML = Utils.trimBrsOnIE(321		'<ol>' +322			'<li>a' +323				'<ol>' +324					'<li>a</li>' +325					'<li><br></li>' +326					'<li>b</li>' +327				'</ol>' +328			'</li>' +329		'</ol>'330	);331	Utils.setSelection('li li:nth-child(2)', 0);332	editor.focus();333	Utils.pressEnter();334	equal(editor.getContent(),335		'<ol>' +336			'<li>a' +337				'<ol>' +338					'<li>a</li>' +339				'</ol>' +340			'</li>' +341			'<li>\u00a0' +342				'<ol>' +343					'<li>b</li>' +344				'</ol>' +345			'</li>' +346		'</ol>'347	);348	// Ignore on IE 7, 8 this is a known bug not worth fixing349	if (!tinymce.Env.ie || tinymce.Env.ie > 8) {350		equal(editor.selection.getNode().nodeName, 'LI');351	}352});353test('Enter inside empty LI in end of OL in LI', function() {354	editor.getBody().innerHTML = Utils.trimBrsOnIE(355		'<ol>' +356			'<li>a' +357				'<ol>' +358					'<li>a</li>' +359					'<li><br></li>' +360				'</ol>' +361			'</li>' +362		'</ol>'363	);364	Utils.setSelection('li li:last', 0);365	editor.focus();366	Utils.pressEnter();367	equal(editor.getContent(),368		'<ol>' +369			'<li>a' +370				'<ol>' +371					'<li>a</li>' +372				'</ol>' +373			'</li>' +374			'<li></li>' +375		'</ol>'376	);377	equal(editor.selection.getNode().nodeName, 'LI');378});379// Nested lists in OL elements380// Ignore on IE 7, 8 this is a known bug not worth fixing381if (!tinymce.Env.ie || tinymce.Env.ie > 8) {382	test('Enter before nested list', function() {383		editor.getBody().innerHTML = Utils.trimBrsOnIE(384			'<ol>' +385				'<li>a' +386					'<ul>' +387						'<li>b</li>' +388						'<li>c</li>' +389					'</ul>' +390				'</li>' +391			'</ol>'392		);393		Utils.setSelection('ol > li', 1);394		editor.focus();395		Utils.pressEnter();396		equal(editor.getContent(),397			'<ol>' +398				'<li>a</li>' +399				'<li>\u00a0' +400					'<ul>' +401						'<li>b</li>' +402						'<li>c</li>' +403					'</ul>' +404				'</li>' +405			'</ol>'406		);407		equal(editor.selection.getNode().nodeName, 'LI');408	});409}410test('Enter inside empty LI in beginning of OL in OL', function() {411	editor.getBody().innerHTML = Utils.trimBrsOnIE(412		'<ol>' +413			'<li>a</li>' +414			'<ol>' +415				'<li><br></li>' +416				'<li>a</li>' +417			'</ol>' +418		'</ol>'419	);420	Utils.setSelection('ol ol li', 0);421	editor.focus();422	Utils.pressEnter();423	equal(editor.getContent(),424		'<ol>' +425			'<li>a</li>' +426			'<li></li>' +427			'<ol>' +428				'<li>a</li>' +429			'</ol>' +430		'</ol>'431	);432	equal(editor.selection.getNode().nodeName, 'LI');433});434test('Enter inside empty LI in middle of OL in OL', function() {435	editor.getBody().innerHTML = Utils.trimBrsOnIE(436		'<ol>' +437			'<li>a</li>' +438			'<ol>' +439				'<li>a</li>' +440				'<li><br></li>' +441				'<li>b</li>' +442			'</ol>' +443		'</ol>'444	);445	Utils.setSelection('ol ol li:nth-child(2)', 0);446	editor.focus();447	Utils.pressEnter();448	equal(editor.getContent(),449		'<ol>' +450			'<li>a</li>' +451			'<ol>' +452				'<li>a</li>' +453			'</ol>' +454			'<li></li>' +455			'<ol>' +456				'<li>b</li>' +457			'</ol>' +458		'</ol>'459	);460	equal(editor.selection.getNode().nodeName, 'LI');461});462test('Enter inside empty LI in end of OL in OL', function() {463	editor.getBody().innerHTML = Utils.trimBrsOnIE(464		'<ol>' +465			'<li>a</li>' +466			'<ol>' +467				'<li>a</li>' +468				'<li><br></li>' +469			'</ol>' +470		'</ol>'471	);472	Utils.setSelection('ol ol li:last', 0);473	editor.focus();474	Utils.pressEnter();475	equal(editor.getContent(),476		'<ol>' +477			'<li>a</li>' +478			'<ol>' +479				'<li>a</li>' +480			'</ol>' +481			'<li></li>' +482		'</ol>'483	);484	equal(editor.selection.getNode().nodeName, 'LI');485});486test('Enter at beginning of first DT inside DL', function() {487	editor.getBody().innerHTML = '<dl><dt>a</dt></dl>';488	Utils.setSelection('dt', 0);489	Utils.pressEnter();490	equal(editor.getContent(),'<dl><dt>\u00a0</dt><dt>a</dt></dl>');491	equal(editor.selection.getNode().nodeName, 'DT');492});493test('Enter at beginning of first DD inside DL', function() {494	editor.getBody().innerHTML = '<dl><dd>a</dd></dl>';495	Utils.setSelection('dd', 0);496	Utils.pressEnter();497	equal(editor.getContent(),'<dl><dd>\u00a0</dd><dd>a</dd></dl>');498	equal(editor.selection.getNode().nodeName, 'DD');499});500test('Enter at beginning of middle DT inside DL', function() {501	editor.getBody().innerHTML = '<dl><dt>a</dt><dt>b</dt><dt>c</dt></dl>';502	Utils.setSelection('dt:nth-child(2)', 0);503	Utils.pressEnter();504	equal(editor.getContent(),'<dl><dt>a</dt><dt>\u00a0</dt><dt>b</dt><dt>c</dt></dl>');505	equal(editor.selection.getNode().nodeName, 'DT');506});507test('Enter at beginning of middle DD inside DL', function() {508	editor.getBody().innerHTML = '<dl><dd>a</dd><dd>b</dd><dd>c</dd></dl>';509	Utils.setSelection('dd:nth-child(2)', 0);510	Utils.pressEnter();511	equal(editor.getContent(),'<dl><dd>a</dd><dd>\u00a0</dd><dd>b</dd><dd>c</dd></dl>');512	equal(editor.selection.getNode().nodeName, 'DD');513});514test('Enter at end of last DT inside DL', function() {515	editor.getBody().innerHTML = '<dl><dt>a</dt></dl>';516	Utils.setSelection('dt', 1);517	Utils.pressEnter();518	equal(editor.getContent(),'<dl><dt>a</dt><dt>\u00a0</dt></dl>');519	equal(editor.selection.getNode().nodeName, 'DT');520});521test('Enter at end of last DD inside DL', function() {522	editor.getBody().innerHTML = '<dl><dd>a</dd></dl>';523	Utils.setSelection('dd', 1);524	Utils.pressEnter();525	equal(editor.getContent(),'<dl><dd>a</dd><dd>\u00a0</dd></dl>');526	equal(editor.selection.getNode().nodeName, 'DD');527});528test('Enter at end of last empty DT inside DL', function() {529	editor.getBody().innerHTML = '<dl><dt>a</dt><dt></dt></dl>';530	Utils.setSelection('dt:nth-child(2)', 0);531	Utils.pressEnter();532	equal(editor.getContent(),'<dl><dt>a</dt></dl><p>\u00a0</p>');533	equal(editor.selection.getNode().nodeName, 'P');534});535test('Enter at end of last empty DD inside DL', function() {536	editor.getBody().innerHTML = '<dl><dd>a</dd><dd></dd></dl>';537	Utils.setSelection('dd:nth-child(2)', 0);538	Utils.pressEnter();539	equal(editor.getContent(),'<dl><dd>a</dd></dl><p>\u00a0</p>');540	equal(editor.selection.getNode().nodeName, 'P');541});542test('Enter at beginning of P inside LI', function() {543	editor.getBody().innerHTML = '<ol><li><p>abcd</p></li></ol>';544	Utils.setSelection('p', 0);545	Utils.pressEnter();546	equal(editor.getContent(),'<ol><li></li><li><p>abcd</p></li></ol>');547	equal(editor.selection.getNode().nodeName, 'P');548});549test('Enter inside middle of P inside LI', function() {550	editor.getBody().innerHTML = '<ol><li><p>abcd</p></li></ol>';551	Utils.setSelection('p', 2);552	Utils.pressEnter();553	equal(editor.getContent(),'<ol><li><p>ab</p></li><li><p>cd</p></li></ol>');554	// Ignore on IE 7, 8 this is a known bug not worth fixing555	if (!tinymce.Env.ie || tinymce.Env.ie > 8) {556		equal(editor.selection.getNode().nodeName, 'P');557	}558});559test('Enter at end of P inside LI', function() {560	editor.getBody().innerHTML = '<ol><li><p>abcd</p></li></ol>';561	Utils.setSelection('p', 4);562	Utils.pressEnter();563	equal(editor.getContent(),'<ol><li><p>abcd</p></li><li></li></ol>');564	equal(editor.selection.getNode().nodeName, 'LI');565});566test('Shift+Enter at beginning of P inside LI', function() {567	editor.getBody().innerHTML = '<ol><li><p>abcd</p></li></ol>';568	Utils.setSelection('p', 0);569	Utils.pressEnter({shiftKey: true});570	equal(editor.getContent(),'<ol><li><p><br />abcd</p></li></ol>');571	equal(editor.selection.getNode().nodeName, 'P');572});573test('Shift+Enter inside middle of P inside LI', function() {574	editor.getBody().innerHTML = '<ol><li><p>abcd</p></li></ol>';575	Utils.setSelection('p', 2);576	Utils.pressEnter({shiftKey: true});577	equal(editor.getContent(),'<ol><li><p>ab<br />cd</p></li></ol>');578	equal(editor.selection.getNode().nodeName, 'P');579});580test('Shift+Enter at end of P inside LI', function() {581	editor.getBody().innerHTML = '<ol><li><p>abcd</p></li></ol>';582	Utils.setSelection('p', 4);583	Utils.pressEnter({shiftKey: true});584	equal(editor.getContent(),(tinymce.isIE && tinymce.Env.ie < 11) ? '<ol><li><p>abcd</p></li></ol>': '<ol><li><p>abcd<br /><br /></p></li></ol>');585	equal(editor.selection.getNode().nodeName, 'P');586});587test('Ctrl+Enter at beginning of P inside LI', function() {588	editor.getBody().innerHTML = '<ol><li><p>abcd</p></li></ol>';589	Utils.setSelection('p', 0);590	Utils.pressEnter({ctrlKey: true});591	equal(editor.getContent(),'<ol><li><p>\u00a0</p><p>abcd</p></li></ol>');592	equal(editor.selection.getNode().nodeName, 'P');593});594test('Ctrl+Enter inside middle of P inside LI', function() {595	editor.getBody().innerHTML = '<ol><li><p>abcd</p></li></ol>';596	Utils.setSelection('p', 2);597	Utils.pressEnter({ctrlKey: true});598	equal(editor.getContent(),'<ol><li><p>ab</p><p>cd</p></li></ol>');599	equal(editor.selection.getNode().nodeName, 'P');600});601test('Ctrl+Enter at end of P inside LI', function() {602	editor.getBody().innerHTML = '<ol><li><p>abcd</p></li></ol>';603	Utils.setSelection('p', 4);604	Utils.pressEnter({ctrlKey: true});605	equal(editor.getContent(),'<ol><li><p>abcd</p><p>\u00a0</p></li></ol>');606	equal(editor.selection.getNode().nodeName, 'P');607});608test('Enter in the middle of text in P with forced_root_block set to false', function() {609	editor.settings.forced_root_block = false;610	editor.getBody().innerHTML = '<p>abc</p>';611	Utils.setSelection('p', 2);612	Utils.pressEnter();613	equal(editor.getContent(),'<p>ab<br />c</p>');614});615test('Enter at the end of text in P with forced_root_block set to false', function() {616	editor.settings.forced_root_block = false;617	editor.getBody().innerHTML = '<p>abc</p>';618	Utils.setSelection('p', 3);619	Utils.pressEnter();620	equal(Utils.cleanHtml(editor.getBody().innerHTML), (tinymce.isIE && tinymce.Env.ie < 11) ? '<p>abc<br></p>': '<p>abc<br><br></p>');621});622test('Enter at the middle of text in BODY with forced_root_block set to false', function() {623	editor.settings.forced_root_block = false;624	editor.getBody().innerHTML = 'abcd';625	Utils.setSelection('body', 2);626	editor.focus();627	Utils.pressEnter();628	equal(Utils.cleanHtml(editor.getBody().innerHTML), 'ab<br>cd');629});630test('Enter at the beginning of text in BODY with forced_root_block set to false', function() {631	editor.settings.forced_root_block = false;632	editor.getBody().innerHTML = 'abcd';633	Utils.setSelection('body', 0);634	editor.focus();635	Utils.pressEnter();636	equal(Utils.cleanHtml(editor.getBody().innerHTML), '<br>abcd');637});638test('Enter at the end of text in BODY with forced_root_block set to false', function() {639	editor.settings.forced_root_block = false;640	editor.getBody().innerHTML = 'abcd';641	Utils.setSelection('body', 4);642	editor.focus();643	Utils.pressEnter();644	equal(Utils.cleanHtml(editor.getBody().innerHTML), (tinymce.isIE && tinymce.Env.ie < 11) ? 'abcd<br>': 'abcd<br><br>');645});646test('Enter in empty P at the end of a blockquote and end_container_on_empty_block: true', function() {647	editor.settings.end_container_on_empty_block = true;648	editor.getBody().innerHTML = (tinymce.isIE && tinymce.Env.ie < 11) ? '<blockquote><p>abc</p><p></p></blockquote>': '<blockquote><p>abc</p><p><br></p></blockquote>';649	Utils.setSelection('p:last', 0);650	Utils.pressEnter();651	equal(editor.getContent(),'<blockquote><p>abc</p></blockquote><p>\u00a0</p>');652});653test('Enter in empty P at the beginning of a blockquote and end_container_on_empty_block: true', function() {654	editor.settings.end_container_on_empty_block = true;655	editor.getBody().innerHTML = (tinymce.isIE && tinymce.Env.ie < 11) ? '<blockquote><p></p><p>abc</p></blockquote>': '<blockquote><p><br></p><p>abc</p></blockquote>';656	Utils.setSelection('p', 0);657	Utils.pressEnter();658	equal(editor.getContent(),'<p>\u00a0</p><blockquote><p>abc</p></blockquote>');659});660test('Enter in empty P at in the middle of a blockquote and end_container_on_empty_block: true', function() {661	editor.settings.end_container_on_empty_block = true;662	editor.getBody().innerHTML = (tinymce.isIE && tinymce.Env.ie < 11) ? '<blockquote><p>abc</p><p></p><p>123</p></blockquote>': '<blockquote><p>abc</p><p><br></p><p>123</p></blockquote>';663	Utils.setSelection('p:nth-child(2)', 0);664	Utils.pressEnter();665	equal(editor.getContent(),'<blockquote><p>abc</p></blockquote><p>\u00a0</p><blockquote><p>123</p></blockquote>');666});667test('Enter inside empty P with empty P siblings', function() {668	// Tests that a workaround for an IE bug is working correctly669	editor.getBody().innerHTML = '<p></p><p></p><p>X</p>';670	Utils.setSelection('p', 0);671	Utils.pressEnter();672	equal(editor.getContent(),'<p>\u00a0</p><p>\u00a0</p><p>\u00a0</p><p>X</p>');673});674test('Enter at end of H1 with forced_root_block_attrs', function() {675	editor.settings.forced_root_block_attrs = {"class": "class1"};676	editor.getBody().innerHTML = '<h1>a</h1>';677	Utils.setSelection('h1', 1);678	Utils.pressEnter();679	equal(editor.getContent(),'<h1>a</h1><p class="class1">\u00a0</p>');680});681test('Shift+Enter at beginning of P', function() {682	editor.getBody().innerHTML = '<p>abc</p>';683	Utils.setSelection('p', 0);684	Utils.pressEnter({shiftKey: true});685	equal(editor.getContent(),'<p><br />abc</p>');686});687test('Shift+Enter in the middle of P', function() {688	editor.getBody().innerHTML = '<p>abcd</p>';689	Utils.setSelection('p', 2);690	Utils.pressEnter({shiftKey: true});691	equal(editor.getContent(),'<p>ab<br />cd</p>');692});693test('Shift+Enter at the end of P', function() {694	editor.getBody().innerHTML = '<p>abcd</p>';695	Utils.setSelection('p', 4);696	Utils.pressEnter({shiftKey: true});697	equal(editor.getContent(),(tinymce.isIE && tinymce.Env.ie < 11) ? '<p>abcd</p>': '<p>abcd<br /><br /></p>');698});699test('Shift+Enter in the middle of B with a BR after it', function() {700	editor.getBody().innerHTML = '<p><b>abcd</b><br></p>';701	Utils.setSelection('b', 2);702	Utils.pressEnter({shiftKey: true});703	equal(editor.getContent(),'<p><b>ab<br />cd</b></p>');704});705test('Shift+Enter at the end of B with a BR after it', function() {706	editor.getBody().innerHTML = '<p><b>abcd</b><br></p>';707	Utils.setSelection('b', 4);708	Utils.pressEnter({shiftKey: true});709	equal(editor.getContent(),'<p><b>abcd<br /></b></p>');710});711test('Enter in beginning of PRE', function() {712	editor.getBody().innerHTML = '<pre>abc</pre>';713	Utils.setSelection('pre', 0);714	Utils.pressEnter();715	equal(editor.getContent(),'<pre><br />abc</pre>');716});717test('Enter in the middle of PRE', function() {718	editor.getBody().innerHTML = '<pre>abcd</pre>';719	Utils.setSelection('pre', 2);720	Utils.pressEnter();721	equal(editor.getContent(),'<pre>ab<br />cd</pre>');722});723test('Enter at the end of PRE', function() {724	editor.getBody().innerHTML = '<pre>abcd</pre>';725	Utils.setSelection('pre', 4);726	Utils.pressEnter();727	equal(editor.getContent(),(tinymce.isIE && tinymce.Env.ie < 11) ? '<pre>abcd</pre>': '<pre>abcd<br /><br /></pre>');728});729test('Enter in beginning of PRE and br_in_pre: false', function() {730	editor.settings.br_in_pre = false;731	editor.getBody().innerHTML = '<pre>abc</pre>';732	Utils.setSelection('pre', 0);733	Utils.pressEnter();734	equal(editor.getContent(),'<pre>\u00a0</pre><pre>abc</pre>');735});736test('Enter in the middle of PRE and br_in_pre: false', function() {737	editor.settings.br_in_pre = false;738	editor.getBody().innerHTML = '<pre>abcd</pre>';739	Utils.setSelection('pre', 2);740	Utils.pressEnter();741	equal(editor.getContent(),'<pre>ab</pre><pre>cd</pre>');742});743test('Enter at the end of PRE and br_in_pre: false', function() {744	editor.settings.br_in_pre = false;745	editor.getBody().innerHTML = '<pre>abcd</pre>';746	Utils.setSelection('pre', 4);747	Utils.pressEnter();748	equal(editor.getContent(),'<pre>abcd</pre><p>\u00a0</p>');749});750test('Shift+Enter in beginning of PRE', function() {751	editor.getBody().innerHTML = '<pre>abc</pre>';752	Utils.setSelection('pre', 0);753	Utils.pressEnter({shiftKey: true});754	equal(editor.getContent(),'<pre>\u00a0</pre><pre>abc</pre>');755});756test('Shift+Enter in the middle of PRE', function() {757	editor.getBody().innerHTML = '<pre>abcd</pre>';758	Utils.setSelection('pre', 2);759	Utils.pressEnter({shiftKey: true});760	equal(editor.getContent(),'<pre>ab</pre><pre>cd</pre>');761});762test('Shift+Enter at the end of PRE', function() {763	editor.getBody().innerHTML = '<pre>abcd</pre>';764	Utils.setSelection('pre', 4);765	Utils.pressEnter({shiftKey: true});766	equal(editor.getContent(),'<pre>abcd</pre><p>\u00a0</p>');767});768test('Shift+Enter in beginning of P with forced_root_block set to false', function() {769	editor.settings.forced_root_block = false;770	editor.getBody().innerHTML = '<p>abc</p>';771	Utils.setSelection('p', 0);772	Utils.pressEnter({shiftKey: true});773	equal(editor.getContent(),'<p>\u00a0</p><p>abc</p>');774});775test('Shift+Enter in middle of P with forced_root_block set to false', function() {776	editor.settings.forced_root_block = false;777	editor.getBody().innerHTML = '<p>abcd</p>';778	Utils.setSelection('p', 2);779	Utils.pressEnter({shiftKey: true});780	equal(editor.getContent(),'<p>ab</p><p>cd</p>');781});782test('Shift+Enter at the end of P with forced_root_block set to false', function() {783	editor.settings.forced_root_block = false;784	editor.getBody().innerHTML = '<p>abc</p>';785	Utils.setSelection('p', 3);786	Utils.pressEnter({shiftKey: true});787	equal(editor.getContent(),'<p>abc</p><p>\u00a0</p>');788});789test('Shift+Enter in body with forced_root_block set to false', function() {790	editor.settings.forced_root_block = false;791	editor.getBody().innerHTML = 'abcd';792	var rng = editor.dom.createRng();793	rng.setStart(editor.getBody().firstChild, 2);794	rng.setEnd(editor.getBody().firstChild, 2);795	editor.selection.setRng(rng);796	Utils.pressEnter({shiftKey: true});797	equal(editor.getContent(),'<p>ab</p><p>cd</p>');798});799test('Enter at the end of DIV layer', function() {800	editor.settings.br_in_pre = false;801	editor.setContent('<div style="position: absolute; top: 1px; left: 2px;">abcd</div>');802	Utils.setSelection('div', 4);803	Utils.pressEnter();804	equal(editor.getContent(),'<div style="position: absolute; top: 1px; left: 2px;"><p>abcd</p><p>\u00a0</p></div>');805});806test('Enter in div inside contentEditable:false div', function() {807	editor.getBody().innerHTML = '<div data-mce-contenteditable="false"><div>abcd</div></div>';808	Utils.setSelection('div div', 2);809	Utils.pressEnter();810	equal(Utils.cleanHtml(editor.getBody().innerHTML), '<div data-mce-contenteditable="false"><div>abcd</div></div>');811});812test('Enter in div with contentEditable:true inside contentEditable:false div', function() {813	editor.getBody().innerHTML = '<div data-mce-contenteditable="false"><div data-mce-contenteditable="true">abcd</div></div>';814	Utils.setSelection('div div', 2);815	Utils.pressEnter();816	equal(Utils.cleanHtml(editor.getBody().innerHTML), '<div data-mce-contenteditable="false"><div data-mce-contenteditable="true"><p>ab</p><p>cd</p></div></div>');817});818test('Enter in span with contentEditable:true inside contentEditable:false div', function() {819	editor.getBody().innerHTML = '<div data-mce-contenteditable="false"><span data-mce-contenteditable="true">abcd</span></div>';820	Utils.setSelection('span', 2);821	Utils.pressEnter();822	equal(Utils.cleanHtml(editor.getBody().innerHTML), '<div data-mce-contenteditable="false"><span data-mce-contenteditable="true">abcd</span></div>');823});824test('Shift+Enter in span with contentEditable:true inside contentEditable:false div', function() {825	editor.getBody().innerHTML = '<div data-mce-contenteditable="false"><span data-mce-contenteditable="true">abcd</span></div>';826	Utils.setSelection('span', 2);827	Utils.pressEnter({shiftKey: true});828	equal(Utils.cleanHtml(editor.getBody().innerHTML), '<div data-mce-contenteditable="false"><span data-mce-contenteditable="true">ab<br>cd</span></div>');829});830test('Enter in span with contentEditable:true inside contentEditable:false div and forced_root_block: false', function() {831	editor.settings.forced_root_block = false;832	editor.getBody().innerHTML = '<div data-mce-contenteditable="false"><span data-mce-contenteditable="true">abcd</span></div>';833	Utils.setSelection('span', 2);834	Utils.pressEnter();835	equal(Utils.cleanHtml(editor.getBody().innerHTML), '<div data-mce-contenteditable="false"><span data-mce-contenteditable="true">ab<br>cd</span></div>');836});837test('Enter in em within contentEditable:true div inside contentEditable:false div', function() {838	editor.getBody().innerHTML = '<div data-mce-contenteditable="false"><div data-mce-contenteditable="true"><em>abcd</em></div></div>';839	Utils.setSelection('em', 2);840	Utils.pressEnter();841	equal(Utils.cleanHtml(editor.getBody().innerHTML), '<div data-mce-contenteditable="false"><div data-mce-contenteditable="true"><p><em>ab</em></p><p><em>cd</em></p></div></div>');842});843test('Enter at end of text in a span inside a P and keep_styles: false', function() {844	editor.settings.keep_styles = false;845	editor.getBody().innerHTML = '<p><em><span style="font-size: 13px;">X</span></em></p>';846	Utils.setSelection('span', 1);847	Utils.pressEnter();848	equal(editor.getContent(),'<p><em><span style="font-size: 13px;">X</span></em></p><p>\u00a0</p>');849});850test('Shift+enter in LI when forced_root_block: false', function() {851	editor.settings.forced_root_block = false;852	editor.getBody().innerHTML = '<ul><li>text</li></ul>';853	Utils.setSelection('li', 2);854	Utils.pressEnter({shiftKey: true});855	equal(editor.getContent(),'<ul><li>te<br />xt</li></ul>');856});857test('Enter when forced_root_block: false and force_p_newlines: true', function() {858	editor.settings.forced_root_block = false;859	editor.settings.force_p_newlines = true;860	editor.getBody().innerHTML = 'text';861	Utils.setSelection('body', 2);862	Utils.pressEnter();863	equal(editor.getContent(),'<p>te</p><p>xt</p>');864});865test('Enter at end of br line', function() {866	editor.settings.forced_root_block = false;867	editor.settings.force_p_newlines = true;868	editor.getBody().innerHTML = '<p>a<br>b</p>';869	Utils.setSelection('p', 1);870	Utils.pressEnter();871	equal(editor.getContent(), '<p>a</p><p><br />b</p>');872	var rng = editor.selection.getRng(true);873	equal(rng.startContainer.nodeName, 'P');874	equal(rng.startContainer.childNodes[rng.startOffset].nodeName, 'BR');875});876// Ignore on IE 7, 8 this is a known bug not worth fixing877if (!tinymce.Env.ie || tinymce.Env.ie > 8) {878	test('Enter before BR between DIVs', function() {879		editor.getBody().innerHTML = '<div>a<span>b</span>c</div><br /><div>d</div>';880		var rng = editor.dom.createRng();881		rng.setStartBefore(editor.dom.select('br')[0]);882		rng.setEndBefore(editor.dom.select('br')[0]);883		editor.selection.setRng(rng);...setSelection.js
Source:setSelection.js  
1/**2 * Created by romain & hen (hendrik.strobelt.com)3 */4function plotSetOverview() {5    var initialize = false;6    var animate = false;7    if (arguments[0]) {8        console.log(arguments[0]);9        initialize = arguments[0].initialize || false;10        if (initialize) {11            ctx.setSelection.mode = "none"12            ctx.setSelection.modeChange = false;13            ctx.setSelection.multiSelIn = d3.set();14            ctx.setSelection.multiSelOut = d3.set();15        }16//        animate = arguments[0].animate || false;17//        mode = arguments[0].mode || "none";18    }19    console.log("plotSetOverview");20    var majorPadding = 5;21    var minorPadding = 2;22    var cellDistance = 20;23    var cellSize = cellDistance;// - minorPadding;24    var setCellDistance = 12;25    var setCellSize = 10;26    var differenceForMultiSel = 7;27    var textHeight = 62 - differenceForMultiSel;28    var truncateAfter = 7;29    var distanceUsedMenu = 15;30    var paddingForPaginationRight = 115;31    var paddingForPaginationRightExtra = (ctx.setSelection.mode === "none") ? 0 : 100;32    const paginationLinespace = 14;33    var headerSVG = d3.select('#headerVis').select('svg');34    // calculate widths35    var svgWidth = headerSVG.attr("width");36    var menuOffset = usedSets.length * cellSize + distanceUsedMenu;37    var maxWidthUnused = svgWidth - menuOffset - paddingForPaginationRight - paddingForPaginationRightExtra - distanceUsedMenu - cellDistance;38    var unusedSets = sets.filter(function (n) {39        return usedSets.indexOf(n) == -140    });41    // --- INIT the SVG structure (d3 version)42    var setSelectionGroup = headerSVG.selectAll(".setSelection").data([1]);43    setSelectionGroup.enter().append("g").attr({44        class: "setSelection",45        "transform": "translate(" + 0 + "," + 0 + ")"46    })47    // scale for the size of the subSets, also used for the sets48    var setSizeScale = d3.scale.linear().domain([0, d3.max(sets, function (d) {49        return d.setSize;50    })]).nice().range([0, textHeight]);51    function updateUsedSets() {52        // ----------------------------53        ///-- Render the used Sets54        // ----------------------------55        var usedSetsVis = setSelectionGroup.selectAll(".usedSets").data([1]);56        usedSetsVis.enter().append("g").attr("class", "usedSets");57        usedSetsVis.attr({58            "transform": "translate(" + 0 + "," + differenceForMultiSel + ")"59        })60        var usedSetsLabels = usedSetsVis61            .selectAll('.setLabel')62            .data(usedSets, function (d) {63                return d.elementName;64            })65        usedSetsLabels.exit().remove();66        var usedSetsLabelsEnter = usedSetsLabels.enter().append("g").attr("class", "setLabel").attr({67            transform: function (d, i) {68                return 'translate(' + (cellDistance * (i)) + ', 0)'69            },70            opacity: .171        });72        usedSetsLabelsEnter73            .append('rect')74            .attr({75                class: 'setSizeBackground',76                height: (textHeight + 1),77                width: cellSize,//setRowScale.rangeBand()78                title: function (d) {79                    return d.setSize80                }81            })82            .on('click', setClicked)83            .on('mouseover', function (d, i) {84                mouseoverColumn(d, i);85            })86            .on('mouseout', function (d, i) {87                mouseoutColumn(d, i);88            })89            .append("svg:title")90                .text(function (d) {91                    return d.elementName + " (" + d.setSize + ")";92                });93        // background bar94        usedSetsLabelsEnter95            .append('rect')96            .attr({97                class: 'setSizeRect setSize',98                x: 1,99                width: cellSize - 2//setRowScale.rangeBand()100            })101            //  .attr("transform", "skewX(45)")102            .on('mouseover', mouseoverColumn)103            .on('mouseout', mouseoutColumn)104            .on('click', setClicked)105            .append("svg:title")106                .text(function (d) {107                    return d.elementName + " (" + d.setSize + ")";108                });109        // *** update sizes (might happen when changing datasets)110        d3.selectAll(".usedSets .setSize").transition().duration(1000).attr({111            y: function (d) {112                return (textHeight - (setSizeScale(d.setSize)));113            },114            height: function (d) {115                return setSizeScale(d.setSize);116            }117        });118        usedSetsLabelsEnter.transition().duration(400).delay(400).attr({119            opacity: 1120        })121        // *** update group position122//        usedSetsLabels123//            .attr({124//                transform: function (d, i) {125//                        return 'translate(' + (cellDistance * i) + ', 0)'126//                }127//            })128        usedSetsLabels.attr({129            transform: function (d, i) {130                if (ctx.setSelection.mode === "multiSel") {131                    if (ctx.setSelection.multiSelOut.has(d.elementName)) {132                        return 'translate(' + (cellDistance * i) + ', -' + differenceForMultiSel + ')'133                    } else {134                        return 'translate(' + (cellDistance * i) + ', 0)'135                    }136                } else {137                    return 'translate(' + (cellDistance * i) + ', 0)'138                }139            }140        })141        usedSetsLabels.selectAll(".setSizeRect")142            .attr({143                "class": function (d) {144                    if (ctx.setSelection.multiSelOut.has(d.elementName)) {145                        return 'setSizeRect unusedSetSize'146                    } else {147                        return 'setSizeRect setSize'148                    }149                }150            })151    }152    updateUsedSets();153    function updateUnusedSets() {154        // ----------------------------155        ///-- Render the unused Sets156        // ----------------------------157        var sortSize = function (a, b) {158            return b.setSize - a.setSize;159        };160        var sortName = function (a, b) {161            return d3.ascending(a.elementName, b.elementName);162        };163        var sortFn;164        if (ctx.setSelection.setOrder === "name") {165            sortFn = sortName;166        } else {167            sortFn = sortSize;168        }169        var unuseedSetsOffset = menuOffset + paddingForPaginationRight + paddingForPaginationRightExtra + distanceUsedMenu;170        unusedSets.sort(sortFn);171        var unusedSetsGroup = setSelectionGroup.selectAll(".unusedSets").data([1])172        unusedSetsGroup.enter().append("g").attr("class", "unusedSets")173        unusedSetsGroup.attr({174            "transform": function (d) {175                if (ctx.setSelection.mode === "multiSel") {176                    return 'translate(' + unuseedSetsOffset + ', 0)'177                } else {178                    return 'translate(' + unuseedSetsOffset + ', ' + differenceForMultiSel + ')'179                }180            }181        })182        if (maxWidthUnused < cellDistance) {183            unusedSetsGroup.selectAll('.unusedSetLabel').remove();184        } else {185            /*186             * add only if there is enough space !!!187             * */188            console.log(maxWidthUnused, cellDistance);189            var paginationDistance = Math.floor(maxWidthUnused / cellDistance);190            console.log(maxWidthUnused, cellDistance, paginationDistance);191            if (initialize) {192                ctx.setSelection.paginationStart = +0;193            }194            ctx.setSelection.paginationEnd = +ctx.setSelection.paginationStart + paginationDistance;195            var unusedSetsFiltered = unusedSets.filter(196                function (d, i) {197                    return ((ctx.setSelection.paginationStart <= i) && (i <= ctx.setSelection.paginationEnd));198                }199            )200            /*201             * create buttons for pagination202             * */203            updatePaginationDecoration();204            var unusedSetsLabels = unusedSetsGroup205                .selectAll('.unusedSetLabel')206                .data(unusedSetsFiltered, function (d) {207                    return d.elementName;208                })209            unusedSetsLabels.exit().remove();210            var unusedSetsLabelsEnter = unusedSetsLabels.enter().append("g").attr("class", "unusedSetLabel").attr({211                transform: function (d, i) {212                    return 'translate(' + (cellDistance * (i)) + ', -10)'213                },214                opacity: .1215            });216            unusedSetsLabelsEnter217                .append('rect')218                .attr({219                    class: 'unusedSetSizeBackground',220//                transform: function (d, i) {221//                    return 'translate(' + (cellDistance * (i )) + ', 20)'222//                },223                    height: textHeight - 2,224                    width: cellSize225                })226                .on('click', setClicked)227            unusedSetsLabelsEnter228                .append('rect')229                .attr({230                    class: 'setSizeRect unusedSetSize',231                    transform: function (d, i) {232                        return 'translate(1, ' + (textHeight - setSizeScale(d.setSize)) + ')'233                    }, // ' + (textHeight - 5) + ')'234                    height: function (d) {235                        return setSizeScale(d.setSize);236                    },237                    width: cellSize - 2,238                })239                .on('click', setClicked)240               // .append('title').text(function (d) {return d});241              //     .append('title').text("what");242//        .append("svg:title")243//        .text(function(d, i) { return d.elementName + " (" +d.setSize+ ")"; });;244            unusedSetsLabelsEnter245                .append('text').text(function (d) {246                if (d.elementName.length > (truncateAfter + 3)) {247                    var str = d.elementName.substring(0, truncateAfter)248                    if (str.length < d.elementName.length)249                        str = str.trim() + "...";250                } else {251                    str = d.elementName.trim();252                }253                return str;254            })255                .attr({256                    class: 'setLabel',257                    transform: function (d, i) {258                        return 'translate(' + (cellDistance + 5) + ', 0) rotate(90)'259                    },260                    y: cellSize - 3,261                    x: 3,262                    height: textHeight - 4,263                    'text-anchor': 'start'264                })265                .on('click', setClicked)266                .append("svg:title")267                .text(function (d, i) {268                    return d.elementName + " (" + d.setSize + ")";269                });270//            console.log("animate:", animate);271//            var updateUnusedPos =unusedSetsLabelsEnter;272//            if (animate){273//                updateUnusedPos= unusedSetsLabelsEnter274//                    .transition().duration(400).delay(400)275//            }276//            updateUnusedPos.attr({277//                opacity:1,278//                transform: function (d, i) {279//                    return 'translate(' + (cellDistance * (i ) + unusedLabelOffset) + ', 0)'280//                }281//            })282            unusedSetsLabels.attr({283                transform: function (d, i) {284                    if (ctx.setSelection.mode === "multiSel") {285                        if (ctx.setSelection.multiSelIn.has(d.elementName)) {286                            return 'translate(' + (cellDistance * (i)) + ', ' + differenceForMultiSel + ')'287                        } else {288                            return 'translate(' + (cellDistance * (i)) + ', 0)'289                        }290                    } else {291                        return 'translate(' + (cellDistance * (i)) + ', 0)'292                    }293                },294                opacity: 1295            })296            unusedSetsLabels.selectAll(".setSizeRect")297                .attr({298                    "class": function (d) {299                        if (ctx.setSelection.multiSelIn.has(d.elementName)) {300                            return 'setSizeRect setSize'301                        } else {302                            return 'setSizeRect unusedSetSize'303                        }304                    }305                })306        }307    }308    updateUnusedSets();309    function updatePaginationDecoration() {310        var internalLeftPadding = 0 // only local311        var setsRight = unusedSets.length - ctx.setSelection.paginationEnd;312        var setsLeft = ctx.setSelection.paginationStart;313        var middlePos = ((paddingForPaginationRight - internalLeftPadding) / 2 + internalLeftPadding);314        var paginationDistance = Math.floor(maxWidthUnused / cellDistance);315        var pagi = headerSVG.selectAll(".pagination")316            .data([{countRight: setsRight, countLeft: setsLeft, distance: paginationDistance}])317        var pagiGroup = pagi.enter().append("g").attr({318            "class": "pagination"319        })320//        var finalPos = svgWidth-paddingForPaginationRight;321        var finalPos = menuOffset;322//        console.log("finalpos", finalPos);323        if (ctx.setSelection.mode !== "none") {324            finalPos += paddingForPaginationRightExtra;325        }326        if (ctx.setSelection.modeChange) {327            pagi.transition().attr({328                "transform": "translate(" + (finalPos) + ",0)"329            })330        } else {331            pagi.attr({332                "transform": "translate(" + (finalPos) + ",0)"333            })334        }335        pagiGroup.append("text")336            .style({337                "text-anchor": "middle",338                "cursor": "default",339                "font-weight": "bold"340            }).attr({341            "transform": function () {342                return "translate(" + (middlePos) + "," + (.8 * paginationLinespace) + ")";343            }344        }).text("Set Selection")345        pagiGroup.append("rect")346            .attr({347                "class": "selectionRect setSelectionArea",348                x: -5,349                width: paddingForPaginationRight - internalLeftPadding + 5,350                height: paginationLinespace * .9,351                opacity: 0352            })353        pagiGroup.append("text").attr({354            "class": "right setSelectionLabelAwesome"355        }).style({356            "text-anchor": "end"357        }).attr({358            "transform": function () {359                return "translate(" + (paddingForPaginationRight - 2) + "," + (2 * paginationLinespace) + ")";360            }361        })362        pagiGroup.append("text").attr({363            "class": "left setSelectionLabelAwesome"364        }).style({365            "text-anchor": "start"366        }).attr({367            "transform": function () {368                return "translate(" + (internalLeftPadding + 2) + "," + (2 * paginationLinespace) + ")";369            }370        })371        pagiGroup.append("text").attr({372            "class": "info_distance"373        }).style({374            "text-anchor": "middle",375            "cursor": "default"376        }).attr({377            "transform": function (d) {378                return "translate(" + (middlePos) + ","379                    + (2 * paginationLinespace) + ")";380            }381        })382        pagiGroup.append("rect").attr({383            "class": "multiSelect setSelectionButton"384        }).attr({385            "transform": "translate(" + (internalLeftPadding + 2) + "," + (2.3 * paginationLinespace) + ")",386            width: paddingForPaginationRight - internalLeftPadding - 4,387            height: .9 * paginationLinespace,388            rx: 5,389            ry: 5390        })391            .on({392                "click": function () {393                    if (ctx.setSelection.mode == "none") {394                        ctx.setSelection.mode = "multiSel";395                        ctx.setSelection.modeChange = true;396                        plotSetOverview();397                    } else if (ctx.setSelection.mode === "multiSel") {398                        ctx.setSelection.multiSelIn = d3.set();399                        ctx.setSelection.multiSelOut = d3.set();400                        ctx.setSelection.mode = "none";401                        ctx.setSelection.modeChange = true;402                        plotSetOverview();403                    }404                }405            })406        pagiGroup.append("text").attr({407            "class": "multiSelect setSelectionButtonText"408        }).style({409            "text-anchor": "middle",410            "cursor": "pointer",411            "pointer-events": "none"412        }).attr({413            "transform": "translate(" + (middlePos) + "," + (3.0 * paginationLinespace) + ")"414        }).text("Batch Add Sets")415        pagiGroup.append("rect").attr({416            "class": "sortFilter setSelectionButton"417        }).attr({418            "transform": "translate(" + (internalLeftPadding + 2) + "," + (3.3 * paginationLinespace) + ")",419            width: paddingForPaginationRight - internalLeftPadding - 4,420            height: .9 * paginationLinespace,421            rx: 5,422            ry: 5423        })424            .on({425                "click": function () {426                    if (ctx.setSelection.mode == "none") {427                        ctx.setSelection.mode = "sortFilter";428                        ctx.setSelection.modeChange = true;429                        plotSetOverview();430                    } else if (ctx.setSelection.mode === "sortFilter") {431                        ctx.setSelection.mode = "none";432                        ctx.setSelection.modeChange = true;433                        plotSetOverview();434                    }435                }436            })437        pagiGroup.append("text").attr({438            "class": "sortFilter setSelectionButtonText"439        }).style({440            "text-anchor": "middle",441            "cursor": "pointer",442            "pointer-events": "none"443        }).attr({444            "transform": "translate(" + (middlePos) + "," + (4 * paginationLinespace) + ")"445        }).text("Sort Sets")446        // --- UPDATES447        pagi.select(".right").text(function (d) {448//            if (d.countRight < 1) return '-|'449//            else return '>>';450            if (d.countRight < 1) return ''451            else return '\uf0a9';452        }).on({453            "click": function (d) {454                if (d.countRight > 0) {455                    ctx.setSelection.paginationStart = ctx.setSelection.paginationStart + d.distance;456                    plotSetOverview({animate: false});457                } else {458                    return;459                }460            }461        })462        pagi.select(".left")463            .text(function (d) {464//                if (d.countLeft < 1) return '|-'465//                else return '<<'; })466                if (d.countLeft < 1) return ''467                else return '\uf0a8';468            })469            //&#f053470            .on({471                "click": function (d) {472                    if (d.countLeft > 0) {473                        ctx.setSelection.paginationStart = Math.max(ctx.setSelection.paginationStart - d.distance, 0);474                        plotSetOverview({animate: false});475                    } else {476                        return;477                    }478                }479            })480        pagi.select(".info_distance").text(function (d) {481            return ctx.setSelection.paginationStart + " - " +482                Math.min(ctx.setSelection.paginationEnd, unusedSets.length)483        })484//        pagi.select(".multiSelect").style({485//            "font-weight": function () {486////                if (ctx.setSelection.mode === "multiSel"){487////                    return "bold"488////                }else{489//                    return "normal"490////                }491//            }492//        })493        var selRectPos = 0;494        var selRectOpa = 0;495        if (ctx.setSelection.mode === "multiSel") {496            selRectPos = 2.3 * paginationLinespace;497            selRectOpa = 1;498        } else if (ctx.setSelection.mode === "sortFilter") {499            selRectPos = 3.3 * paginationLinespace;500            selRectOpa = 1;501        }502        if (ctx.setSelection.modeChange) {503            pagi.select(".selectionRect").transition().duration(200)504                .attr({505                    y: selRectPos,506                    opacity: selRectOpa507                })508        } else {509            pagi.select(".selectionRect").attr({510                y: selRectPos,511                opacity: selRectOpa512            })513        }514        updateSecondMenu();515        // only one pass of mode change rendering516        ctx.setSelection.modeChange = false;517    }518    function updateSecondMenu() {519        var menuContent = []520        if (ctx.setSelection.mode === "multiSel") {521            menuContent =522                [[523                    {524                        name: "Add All Sets", func: function () {525                            unusedSets.forEach(function (d) {526                                ctx.setSelection.multiSelIn.add(d.elementName);527                            });528                            ctx.setSelection.multiSelOut = d3.set();529                            plotSetOverview();530                        }531                    },532                    {533                        name: "Clear All Sets", func: function () {534                            ctx.setSelection.multiSelIn = d3.set();535                            usedSets.forEach(function (d) {536                                ctx.setSelection.multiSelOut.add(d.elementName);537                            });538                            plotSetOverview()539                        }540                    },541                    {542                        name: "Cancel", func: function () {543                            ctx.setSelection.multiSelIn = d3.set();544                            ctx.setSelection.multiSelOut = d3.set();545                            //close multiselect panel546                            ctx.setSelection.mode = "none"547                            ctx.setSelection.modeChange = true548                            plotSetOverview();549                        }, fontawe: "\uf00d"550                    },551                    {name: "Confirm", func: bulkChange, fontawe: "\uf00c"}552                ]]553        } else if (ctx.setSelection.mode === "sortFilter") {554            menuContent =555                [[556                    {557                        name: "by Size", func: function () {558                            ctx.setSelection.setOrder = "size"559                            ctx.setSelection.mode = "none"560                            ctx.setSelection.modeChange = true561                            plotSetOverview();562                        }563                    },564                    {565                        name: "by Name", func: function () {566                            ctx.setSelection.setOrder = "name"567                            ctx.setSelection.mode = "none"568                            ctx.setSelection.modeChange = true569                            plotSetOverview()570                        }571                    }572                ]]573        }574        var menuExtra = headerSVG.selectAll(".setMenuExtra").data(menuContent);575        menuExtra.exit().remove();576        var menuExtraGroup = menuExtra.enter().append("g").attr("class", "setMenuExtra").attr({577            opacity: .1578        })579        menuExtraGroup.append("rect").attr({580            "class": "setSelectionArea",581            x: 5,582            width: paddingForPaginationRightExtra - 10,583            height: textHeight + 5584        })585        if (ctx.setSelection.modeChange) {586            menuExtra.transition().duration(500)587                .attr({588                    opacity: 1589                });590        }591        menuExtra592            .attr({593                "transform": "translate(" + (menuOffset) + "," + 0 + ")"594            });595        var menuExtraGroupEntries = menuExtraGroup.selectAll(".menuExtraEntry").data(function (d) {596            return d;597        })598        menuExtraGroupEntries.enter().append("text")599            .attr({600                "class": function (d) {601                    if ('fontawe' in d) {602                        return "menuExtraEntry setMenuExtraAwesome"603                    } else {604                        return "menuExtraEntry"605                    }606                },607                "transform": function (d, i) {608                    return "translate(" + (paddingForPaginationRightExtra / 2) + "," + ((1 + (i * 1.0)) * paginationLinespace) + ")";609                }610            })611            .style({612                "cursor": "pointer",613                "text-anchor": "middle"614            })615            .text(function (d) {616                if ('fontawe' in d) {617                    return d.fontawe + " " + d.name;618                } else {619                    return d.name;620                }621            })622            .on("click", function (d) {623                d.func();624            })625    }626//    // -- update position !!!627//    var unusedSetsLabels =  overview.append("foreignObject")628//        .attr("width", 710)629//        .attr("height", textHeight+20)630//        .attr("x", usedSets.length*cellSize)631//        .attr("y", 40)632//      .append("xhtml:div")633//        .style("overflow-x", "auto")634//        .append("svg")635//        .attr({636//            height: textHeight+20,637//            width: unusedSets.length*cellSize638//        })639//        .append("g")640//        //.attr("transform", "translate(-50)")641//        .attr("class", "unusedSets")642//        .selectAll('.unusedSetsLabels')643//        .data(unusedSets)644//        .enter();645//646//    unusedSetsLabels647//            .append('rect')648//            .sort(sortFn)649//            .attr({650//                class: 'unusedSetSizeBackground',651//                transform: function (d, i) {652//                    return 'translate(' + (cellDistance * (i )) + ', 20)'653//                },654//                height: textHeight-2,655//                width: cellSize656//            })657//            .on('click', setClicked)658//659//660//    // background bar661//    unusedSetsLabels662//        .append('rect')663//        .sort(sortFn)664//        .attr({665//            class: 'unusedSetSize',666//            transform: function (d, i) {667//                return 'translate(' + (cellDistance * i) + ', ' + ( textHeight - minorPadding - setSizeScale(d.setSize) + 21) + ')'668//            }, // ' + (textHeight - 5) + ')'669//            height: function (d) {670//                return setSizeScale(d.setSize);671//            },672//            width: cellSize673//        })674//       // .on('mouseover', mouseoverColumn)675//       // .on('mouseout', mouseoutColumn)676//        .on('click', setClicked)677//678//    unusedSetsLabels679//        .append('text').text(function (d) {680//681//          //var tmpText = d3.select("svg").append("text").attr("id", "tmpText").text(d.elementName.substring(0, truncateAfter))682//          //var str = Utilities.truncate(tmpText, 70)683//          //tmpText.remove();684//          var str = d.elementName.substring(0, truncateAfter)685//          if(str.length<d.elementName.length)686//            str = str.trim() + "...";687//688//            return str;689//          })690//        .sort(sortFn)691//        .attr({692//            class: 'setLabel',693//         // Not sure we need this..694//         //   id: function (d) {695//         //       return d.elementName.substring(0, truncateAfter);696//         //   },697//                transform: function (d, i) {698//                    return 'translate(' + (cellDistance * (i + 1) + 5) + ', 20) rotate(90)'699//                },700//            y: cellSize - 3,701//            x: 3,702//            height: textHeight-4,703//            'text-anchor': 'start'704//705////            transform: function (d, i) {706////                return 'translate(' + (cellDistance * (i ) + cellDistance / 2) + ',' + (setMatrixHeight + textHeight - textSpacing) + ')rotate(270)';707////            }708//      })709//      .on('click', setClicked)710//      .append("svg:title")711//      .text(function(d, i) { return d.elementName + " (" +d.setSize+ ")"; });712    function setClicked(d, i) {713        if (ctx.setSelection.mode === "multiSel") {714            if (d.isSelected) {715                // for usedSets:716                if (ctx.setSelection.multiSelOut.has(d.elementName)) {717                    ctx.setSelection.multiSelOut.remove(d.elementName);718                } else {719                    ctx.setSelection.multiSelOut.add(d.elementName);720                }721            } else {722                // for UNusedSets:723                if (ctx.setSelection.multiSelIn.has(d.elementName)) {724                    ctx.setSelection.multiSelIn.remove(d.elementName);725                } else {726                    ctx.setSelection.multiSelIn.add(d.elementName);727                }728            }729            plotSetOverview();730        } else {731            updateSetContainment(d, true);732        }733//               d3.selectAll(".bulkCheck").transition().remove();734    }735    function bulkChange() {736        var list_update =737            sets.filter(function (d) {738                return ctx.setSelection.multiSelIn.has(d.elementName) ||739                    ctx.setSelection.multiSelOut.has(d.elementName)740            })741        ctx.setSelection.multiSelIn = d3.set();742        ctx.setSelection.multiSelOut = d3.set();743        //close multiselect panel744        ctx.setSelection.mode = "none"745        ctx.setSelection.modeChange = true746        if (list_update.length > 0) {747            // updateSetCon will call plot again748            list_update.map(function (d, i) {749                updateSetContainment(d, i == list_update.length - 1);750            });751        } else {752            plotSetOverview()753        }754    }755}756//    overview.on('mouseover', function(d, i) {757//758//      // Remove current transitions759//      d3.selectAll(".bulkCheck").transition();760//761//        var sortFn;762//763//        if (ctx.setOrder === "name") {764//          sortFn = sortName;765//        }  else {766//          sortFn = sortSize;767//        }768//769//      if(d3.selectAll(".bulkCheck")[0].length>5)770//        return;771//772//        usedSets.filter(function(d, ii) {773//774//          d3.select(".usedSets")775//            .append("foreignObject")776//            .datum([d])777//            .attr("width", 100)778//            .attr("height", 100)779//            .attr("class", "bulkCheck")780//            .attr("y", 40)781//            .attr("x", function(d, i) {782//              return cellDistance * (ii);783//            })784//            .html("<form><input type=checkbox value=setcheck id=setcheck_"+ii+" checked/></form>")785//786//        })787//788//        var unusedSetsCheck = unusedSets.sort(sortFn).filter(function(d, ii) {789//790//          d3.select(".unusedSets")791//            .append("foreignObject")792//            .datum([d])793//            .attr("width", 100)794//            .attr("height", 100)795//            .attr("class", "bulkCheck unusedSets")796//            .attr("y", 0)797//            .attr("x", function(d, i) {798//              return cellDistance * (ii);799//            })800//            .html("<form><input type=checkbox value=setcheck id="+ii+" /></form>")801//802//        })803//804//         d3.select("#headerVis").select("svg")805//            .append("foreignObject")806//            .attr("width", 100)807//            .attr("height", 100)808//            .attr("class", "bulkCheck")809//            .attr("y", 20)810//            .attr("x", function(d, i) {811//              return 0;//ctx.w- usedSets.length*cellDistance-100;812//            })813//            .html("<form><input type=button value=update /></form>")814//            .on("click", setClickedByBulk);815//816//         d3.select("#headerVis").select("svg")817//            .append("foreignObject")818//            .attr("width", 100)819//            .attr("height", 100)820//            .attr("class", "bulkCheck")821//            .attr("y", 20)822//            .attr("x", function(d, i) {823//              return 60;//ctx.w- usedSets.length*cellDistance-100;824//            })825//            .html("<form><input type=button value='all' /></form>")826//            .on("click", function() {827//              d3.selectAll("input[value=setcheck]").property("checked", true);828//            });829//830//         d3.select("#headerVis").select("svg")831//            .append("foreignObject")832//            .attr("width", 100)833//            .attr("height", 100)834//            .attr("class", "bulkCheck")835//            .attr("y", 20)836//            .attr("x", function(d, i) {837//              return 95;//ctx.w- usedSets.length*cellDistance-100;838//            })839//            .html("<form><input type=button value='none' /></form>")840//            .on("click", function() {841//              d3.selectAll("input[value=setcheck]").property("checked", false);842//            });843//844//         d3.select("#headerVis").select("svg")845//            .append("foreignObject")846//            .attr("width", 200)847//            .attr("height", 100)848//            .attr("class", "bulkCheck")849//            .attr("y", 20)850//            .attr("x", function(d, i) {851//              return 145;//ctx.w- usedSets.length*cellDistance-100;852//            })853//            .html("<form style='font-size:12px'>Order by: <input type=radio name='order' value='size' "+ (ctx.setOrder == 'size' ? 'checked' : '') +"/> Size <input type=radio name='order' value='name' "+ (ctx.setOrder == 'name' ? 'checked' : '') +"/> Name</form>")854//            .on("click", function() {855//              d3.select(this).selectAll("input").each(orderChange);856//            });857//858//           d3.selectAll(".bulkCheck").on("mouseenter", function() {859//            // Remove current transitions860//            d3.selectAll(".bulkCheck").transition();861//          })862//863//        })864//        .on('mouseout', function(d, i) {865//            mouseoutColumn(d, i);866//            d3.selectAll(".bulkCheck").transition().duration(1500).remove();867//        })868//function orderChange() {869//    if(!this.checked)870//        return;871//872//    var sortFn;873//874//    if (this.value === "name") {875//        sortFn = sortName;876//        ctx.setOrder = "name";877//    }  else {878//        sortFn = sortSize;879//        ctx.setOrder = "size";880//    }881//882//    d3.selectAll(".unusedSets .unusedSetSizeBackground")883//        .sort(sortFn)884//        .transition().duration(500).delay(function(d, i) {885//            return i * 500 / unusedSets.length;886//        })887//        .attr("transform", function (d, i) {888//            return 'translate(' + (cellDistance * (i )) + ', 20)'889//        })890//    d3.selectAll(".unusedSets .unusedSetSize")891//        .sort(sortFn)892//        .transition().duration(500).delay(function(d, i) {893//            return i * 500 / unusedSets.length;894//        })895//        .attr("transform", function (d, i) {896//            return 'translate(' + (cellDistance * i) + ', ' + ( textHeight - minorPadding - setSizeScale(d.setSize) + 20) + ')'897//        })898//899//    d3.selectAll(".unusedSets .setLabel")900//        .sort(sortFn)901//        .transition().duration(500).delay(function(d, i) {902//            return i * 500 / unusedSets.length;903//        })904//        .attr("transform", function (d, i) {905//            return 'translate(' + (cellDistance * (i + 1) + 5) + ', 20) rotate(90)'906//        })907//908//    d3.selectAll(".unusedSets .bulkCheck").remove();909//910//    unusedSets.sort(sortFn).filter(function(d, ii) {911//912//        d3.select(".unusedSets")913//            .append("foreignObject")914//            .datum([d])915//            .attr("width", 100)916//            .attr("height", 100)917//            .attr("class", "bulkCheck")918//            .attr("y", 0)919//            .attr("x", function(d, i) {920//                return cellDistance * (ii);921//            })922//            .html("<form><input type=checkbox value=setcheck id="+ii+" /></form>")923//924//    })925//...restrictededitingmodeediting-commands.js
Source:restrictededitingmodeediting-commands.js  
...39					editor.commands.add( 'undo', buildFakeCommand( editor ) );40				} );41				it( 'should be enabled outside exception marker', () => {42					model.change( writer => {43						writer.setSelection( firstParagraph, 1 );44					} );45					expect( editor.commands.get( 'undo' ).isEnabled ).to.be.true;46				} );47				it( 'should be enabled inside exception marker', () => {48					model.change( writer => {49						writer.setSelection( firstParagraph, 5 );50					} );51					expect( editor.commands.get( 'undo' ).isEnabled ).to.be.true;52				} );53			} );54			describe( 'redo', () => {55				beforeEach( () => {56					editor.commands.add( 'redo', buildFakeCommand( editor ) );57				} );58				it( 'should be enabled outside exception marker', () => {59					model.change( writer => {60						writer.setSelection( firstParagraph, 1 );61					} );62					expect( editor.commands.get( 'redo' ).isEnabled ).to.be.true;63				} );64				it( 'should be enabled inside exception marker', () => {65					model.change( writer => {66						writer.setSelection( firstParagraph, 5 );67					} );68					expect( editor.commands.get( 'redo' ).isEnabled ).to.be.true;69				} );70			} );71		} );72		describe( 'commands enabled in exception marker', () => {73			describe( 'input', () => {74				beforeEach( () => {75					editor.commands.add( 'input', buildFakeCommand( editor ) );76					model.change( writer => {77						writer.setSelection( firstParagraph, 'end' );78					} );79				} );80				it( 'should be disabled when caret is outside exception marker', () => {81					model.change( writer => {82						writer.setSelection( firstParagraph, 1 );83					} );84					expect( editor.commands.get( 'input' ).isEnabled ).to.be.false;85				} );86				it( 'should be enabled when caret is inside exception marker (not touching boundaries)', () => {87					model.change( writer => {88						writer.setSelection( firstParagraph, 5 );89					} );90					expect( editor.commands.get( 'input' ).isEnabled ).to.be.true;91				} );92				it( 'should be disabled when caret is inside other marker', () => {93					model.change( writer => {94						writer.addMarker( 'foo-bar:1', {95							range: writer.createRange(96								writer.createPositionAt( firstParagraph, 0 ),97								writer.createPositionAt( firstParagraph, 3 ) ),98							usingOperation: true,99							affectsData: true100						} );101						writer.setSelection( firstParagraph, 1 );102					} );103					expect( editor.commands.get( 'input' ).isEnabled ).to.be.false;104				} );105				it( 'should be enabled when caret is inside exception marker (start boundary)', () => {106					model.change( writer => {107						writer.setSelection( firstParagraph, 4 );108					} );109					expect( editor.commands.get( 'input' ).isEnabled ).to.be.true;110				} );111				it( 'should be enabled when caret is inside exception marker (end boundary)', () => {112					model.change( writer => {113						writer.setSelection( firstParagraph, 7 );114					} );115					expect( editor.commands.get( 'input' ).isEnabled ).to.be.true;116				} );117				it( 'should be disabled for multi-range selection (collapsed ranges)', () => {118					model.change( writer => {119						writer.setSelection( [120							writer.createRange(121								writer.createPositionAt( firstParagraph, 5 )122							),123							writer.createRange(124								writer.createPositionAt( firstParagraph, 9 )125							)126						] );127					} );128					expect( editor.commands.get( 'input' ).isEnabled ).to.be.false;129				} );130				it( 'should be disabled for non-collapsed selection that expands over exception marker', () => {131					model.change( writer => {132						writer.setSelection( writer.createRange(133							writer.createPositionAt( firstParagraph, 0 ),134							writer.createPositionAt( firstParagraph, 5 )135						) );136					} );137					expect( editor.commands.get( 'input' ).isEnabled ).to.be.false;138				} );139				it( 'should be enabled for non-collapsed selection that is fully contained inside exception marker', () => {140					model.change( writer => {141						writer.setSelection( writer.createRange(142							writer.createPositionAt( firstParagraph, 5 ),143							writer.createPositionAt( firstParagraph, 6 )144						) );145					} );146					expect( editor.commands.get( 'input' ).isEnabled ).to.be.true;147				} );148				it( 'should be enabled for non-collapsed selection inside exception marker (start position on marker boundary)', () => {149					model.change( writer => {150						writer.setSelection( writer.createRange(151							writer.createPositionAt( firstParagraph, 4 ),152							writer.createPositionAt( firstParagraph, 6 )153						) );154					} );155					expect( editor.commands.get( 'input' ).isEnabled ).to.be.true;156				} );157				it( 'should be enabled for non-collapsed selection inside exception marker (end position on marker boundary)', () => {158					model.change( writer => {159						writer.setSelection( writer.createRange(160							writer.createPositionAt( firstParagraph, 5 ),161							writer.createPositionAt( firstParagraph, 7 )162						) );163					} );164					expect( editor.commands.get( 'input' ).isEnabled ).to.be.true;165				} );166				it( 'should be enabled for non-collapsed selection is equal to exception marker', () => {167					model.change( writer => {168						writer.setSelection( writer.createRange(169							writer.createPositionAt( firstParagraph, 4 ),170							writer.createPositionAt( firstParagraph, 7 )171						) );172					} );173					expect( editor.commands.get( 'input' ).isEnabled ).to.be.true;174				} );175				it( 'should be disabled for non-collapsed selection with more then one range', () => {176					model.change( writer => {177						writer.setSelection( [178							writer.createRange(179								writer.createPositionAt( firstParagraph, 5 ),180								writer.createPositionAt( firstParagraph, 6 )181							),182							writer.createRange(183								writer.createPositionAt( firstParagraph, 8 ),184								writer.createPositionAt( firstParagraph, 9 )185							)186						] );187					} );188					expect( editor.commands.get( 'input' ).isEnabled ).to.be.false;189				} );190			} );191			describe( 'delete', () => {192				beforeEach( () => {193					editor.commands.add( 'delete', buildFakeCommand( editor ) );194					model.change( writer => {195						writer.setSelection( firstParagraph, 'end' );196					} );197				} );198				it( 'should be disabled when caret is outside exception marker', () => {199					model.change( writer => {200						writer.setSelection( firstParagraph, 1 );201					} );202					expect( editor.commands.get( 'delete' ).isEnabled ).to.be.false;203				} );204				it( 'should be enabled when caret is inside exception marker (not touching boundaries)', () => {205					model.change( writer => {206						writer.setSelection( firstParagraph, 5 );207					} );208					expect( editor.commands.get( 'delete' ).isEnabled ).to.be.true;209				} );210				it( 'should be disabled when caret is inside exception marker (start boundary)', () => {211					model.change( writer => {212						writer.setSelection( firstParagraph, 4 );213					} );214					expect( editor.commands.get( 'delete' ).isEnabled ).to.be.false;215				} );216				it( 'should be disabled when caret moves to start boundary and it was enabled previously', () => {217					model.change( writer => {218						writer.setSelection( firstParagraph, 5 );219					} );220					expect( editor.commands.get( 'delete' ).isEnabled ).to.be.true;221					model.change( writer => {222						writer.setSelection( firstParagraph, 4 );223					} );224					expect( editor.commands.get( 'delete' ).isEnabled ).to.be.false;225				} );226				it( 'should be enabled when caret is inside exception marker (end boundary)', () => {227					model.change( writer => {228						writer.setSelection( firstParagraph, 7 );229					} );230					expect( editor.commands.get( 'delete' ).isEnabled ).to.be.true;231				} );232				it( 'should be disabled for non-collapsed selection that expands over exception marker', () => {233					model.change( writer => {234						writer.setSelection( writer.createRange(235							writer.createPositionAt( firstParagraph, 0 ),236							writer.createPositionAt( firstParagraph, 5 )237						) );238					} );239					expect( editor.commands.get( 'delete' ).isEnabled ).to.be.false;240				} );241				it( 'should be enabled for non-collapsed selection that is fully contained inside exception marker', () => {242					model.change( writer => {243						writer.setSelection( writer.createRange(244							writer.createPositionAt( firstParagraph, 5 ),245							writer.createPositionAt( firstParagraph, 6 )246						) );247					} );248					expect( editor.commands.get( 'delete' ).isEnabled ).to.be.true;249				} );250				it( 'should be enabled for non-collapsed selection inside exception marker (start position on marker boundary)', () => {251					model.change( writer => {252						writer.setSelection( writer.createRange(253							writer.createPositionAt( firstParagraph, 4 ),254							writer.createPositionAt( firstParagraph, 6 )255						) );256					} );257					expect( editor.commands.get( 'delete' ).isEnabled ).to.be.true;258				} );259				it( 'should be enabled for non-collapsed selection inside exception marker (end position on marker boundary)', () => {260					model.change( writer => {261						writer.setSelection( writer.createRange(262							writer.createPositionAt( firstParagraph, 5 ),263							writer.createPositionAt( firstParagraph, 7 )264						) );265					} );266					expect( editor.commands.get( 'delete' ).isEnabled ).to.be.true;267				} );268				it( 'should be enabled for non-collapsed selection is equal to exception marker', () => {269					model.change( writer => {270						writer.setSelection( writer.createRange(271							writer.createPositionAt( firstParagraph, 4 ),272							writer.createPositionAt( firstParagraph, 7 )273						) );274					} );275					expect( editor.commands.get( 'delete' ).isEnabled ).to.be.true;276				} );277			} );278			describe( 'forwardDelete', () => {279				beforeEach( () => {280					editor.commands.add( 'forwardDelete', buildFakeCommand( editor ) );281					model.change( writer => {282						writer.setSelection( firstParagraph, 'end' );283					} );284				} );285				it( 'should be disabled when caret is outside exception marker', () => {286					model.change( writer => {287						writer.setSelection( firstParagraph, 1 );288					} );289					expect( editor.commands.get( 'forwardDelete' ).isEnabled ).to.be.false;290				} );291				it( 'should be enabled when caret is inside exception marker (not touching boundaries)', () => {292					model.change( writer => {293						writer.setSelection( firstParagraph, 5 );294					} );295					expect( editor.commands.get( 'forwardDelete' ).isEnabled ).to.be.true;296				} );297				it( 'should be enabled when caret is inside exception marker (start boundary)', () => {298					model.change( writer => {299						writer.setSelection( firstParagraph, 4 );300					} );301					expect( editor.commands.get( 'forwardDelete' ).isEnabled ).to.be.true;302				} );303				it( 'should be disabled when caret is inside exception marker (end boundary)', () => {304					model.change( writer => {305						writer.setSelection( firstParagraph, 7 );306					} );307					expect( editor.commands.get( 'forwardDelete' ).isEnabled ).to.be.false;308				} );309				it( 'should be disabled when caret moves to end boundary and it was enabled previously', () => {310					model.change( writer => {311						writer.setSelection( firstParagraph, 5 );312					} );313					expect( editor.commands.get( 'forwardDelete' ).isEnabled ).to.be.true;314					model.change( writer => {315						writer.setSelection( firstParagraph, 7 );316					} );317					expect( editor.commands.get( 'forwardDelete' ).isEnabled ).to.be.false;318				} );319				it( 'should be disabled for non-collapsed selection that expands over exception marker', () => {320					model.change( writer => {321						writer.setSelection( writer.createRange(322							writer.createPositionAt( firstParagraph, 0 ),323							writer.createPositionAt( firstParagraph, 5 )324						) );325					} );326					expect( editor.commands.get( 'forwardDelete' ).isEnabled ).to.be.false;327				} );328				it( 'should be enabled for non-collapsed selection that is fully contained inside exception marker', () => {329					model.change( writer => {330						writer.setSelection( writer.createRange(331							writer.createPositionAt( firstParagraph, 5 ),332							writer.createPositionAt( firstParagraph, 6 )333						) );334					} );335					expect( editor.commands.get( 'forwardDelete' ).isEnabled ).to.be.true;336				} );337				it( 'should be enabled for non-collapsed selection inside exception marker (start position on marker boundary)', () => {338					model.change( writer => {339						writer.setSelection( writer.createRange(340							writer.createPositionAt( firstParagraph, 4 ),341							writer.createPositionAt( firstParagraph, 6 )342						) );343					} );344					expect( editor.commands.get( 'forwardDelete' ).isEnabled ).to.be.true;345				} );346				it( 'should be enabled for non-collapsed selection inside exception marker (end position on marker boundary)', () => {347					model.change( writer => {348						writer.setSelection( writer.createRange(349							writer.createPositionAt( firstParagraph, 5 ),350							writer.createPositionAt( firstParagraph, 7 )351						) );352					} );353					expect( editor.commands.get( 'forwardDelete' ).isEnabled ).to.be.true;354				} );355				it( 'should be enabled for non-collapsed selection is equal to exception marker', () => {356					model.change( writer => {357						writer.setSelection( writer.createRange(358							writer.createPositionAt( firstParagraph, 4 ),359							writer.createPositionAt( firstParagraph, 7 )360						) );361					} );362					expect( editor.commands.get( 'forwardDelete' ).isEnabled ).to.be.true;363				} );364			} );365		} );366		describe( 'non-enabled commands', () => {367			beforeEach( () => {368				editor.commands.add( 'other', buildFakeCommand( editor ) );369				model.change( writer => {370					writer.setSelection( firstParagraph, 'end' );371				} );372			} );373			it( 'should be disabled outside exception marker', () => {374				model.change( writer => {375					writer.setSelection( firstParagraph, 1 );376				} );377				expect( editor.commands.get( 'other' ).isEnabled ).to.be.false;378			} );379			it( 'should be disabled inside exception marker', () => {380				model.change( writer => {381					writer.setSelection( firstParagraph, 1 );382				} );383				model.change( writer => {384					writer.setSelection( firstParagraph, 5 );385				} );386				expect( editor.commands.get( 'other' ).isEnabled ).to.be.false;387			} );388			it( 'should be disabled when caret is inside exception marker (not touching boundaries)', () => {389				model.change( writer => {390					writer.setSelection( firstParagraph, 5 );391				} );392				expect( editor.commands.get( 'other' ).isEnabled ).to.be.false;393			} );394			it( 'should be disabled when caret is inside exception marker (start boundary)', () => {395				model.change( writer => {396					writer.setSelection( firstParagraph, 4 );397				} );398				expect( editor.commands.get( 'other' ).isEnabled ).to.be.false;399			} );400			it( 'should be disabled when caret is inside exception marker (end boundary)', () => {401				model.change( writer => {402					writer.setSelection( firstParagraph, 7 );403				} );404				expect( editor.commands.get( 'other' ).isEnabled ).to.be.false;405			} );406			it( 'should be disabled for non-collapsed selection that expands over exception marker', () => {407				model.change( writer => {408					writer.setSelection( writer.createRange(409						writer.createPositionAt( firstParagraph, 0 ),410						writer.createPositionAt( firstParagraph, 5 )411					) );412				} );413				expect( editor.commands.get( 'other' ).isEnabled ).to.be.false;414			} );415			it( 'should be disabled for non-collapsed selection that is fully contained inside exception marker', () => {416				model.change( writer => {417					writer.setSelection( writer.createRange(418						writer.createPositionAt( firstParagraph, 5 ),419						writer.createPositionAt( firstParagraph, 6 )420					) );421				} );422				expect( editor.commands.get( 'other' ).isEnabled ).to.be.false;423			} );424			it( 'should be disabled for non-collapsed selection inside exception marker (start position on marker boundary)', () => {425				model.change( writer => {426					writer.setSelection( writer.createRange(427						writer.createPositionAt( firstParagraph, 4 ),428						writer.createPositionAt( firstParagraph, 6 )429					) );430				} );431				expect( editor.commands.get( 'other' ).isEnabled ).to.be.false;432			} );433			it( 'should be disabled for non-collapsed selection inside exception marker (end position on marker boundary)', () => {434				model.change( writer => {435					writer.setSelection( writer.createRange(436						writer.createPositionAt( firstParagraph, 5 ),437						writer.createPositionAt( firstParagraph, 7 )438					) );439				} );440				expect( editor.commands.get( 'other' ).isEnabled ).to.be.false;441			} );442			it( 'should be disabled for non-collapsed selection is equal to exception marker', () => {443				model.change( writer => {444					writer.setSelection( writer.createRange(445						writer.createPositionAt( firstParagraph, 4 ),446						writer.createPositionAt( firstParagraph, 7 )447					) );448				} );449				expect( editor.commands.get( 'other' ).isEnabled ).to.be.false;450			} );451		} );452	} );453	describe( 'commands enabled in exception marker by configuration', () => {454		let model, firstParagraph;455		beforeEach( async () => {456			editor = await VirtualTestEditor.create( {457				plugins: [ Paragraph, Typing, RestrictedEditingModeEditing ],458				restrictedEditing: {459					allowedCommands: [ 'allowed' ]460				}461			} );462			model = editor.model;463			editor.commands.add( 'allowed', buildFakeCommand( editor ) );464			setModelData( model, '<paragraph>[]foo bar baz</paragraph>' );465			firstParagraph = model.document.getRoot().getChild( 0 );466			model.change( writer => {467				writer.addMarker( 'restrictedEditingException:1', {468					range: writer.createRange(469						writer.createPositionAt( firstParagraph, 4 ),470						writer.createPositionAt( firstParagraph, 7 ) ),471					usingOperation: true,472					affectsData: true473				} );474				writer.setSelection( firstParagraph, 'end' );475			} );476		} );477		afterEach( async () => {478			await editor.destroy();479		} );480		it( 'should be disabled when caret is outside exception marker', () => {481			model.change( writer => {482				writer.setSelection( firstParagraph, 1 );483			} );484			expect( editor.commands.get( 'allowed' ).isEnabled ).to.be.false;485		} );486		it( 'should be enabled when caret is inside exception marker (not touching boundaries)', () => {487			model.change( writer => {488				writer.setSelection( firstParagraph, 5 );489			} );490			expect( editor.commands.get( 'allowed' ).isEnabled ).to.be.true;491		} );492		it( 'should be disabled when caret is inside other marker', () => {493			model.change( writer => {494				writer.addMarker( 'foo-bar:1', {495					range: writer.createRange(496						writer.createPositionAt( firstParagraph, 0 ),497						writer.createPositionAt( firstParagraph, 3 ) ),498					usingOperation: true,499					affectsData: true500				} );501				writer.setSelection( firstParagraph, 1 );502			} );503			expect( editor.commands.get( 'allowed' ).isEnabled ).to.be.false;504		} );505		it( 'should be enabled when caret is inside exception marker (start boundary)', () => {506			model.change( writer => {507				writer.setSelection( firstParagraph, 4 );508			} );509			expect( editor.commands.get( 'allowed' ).isEnabled ).to.be.true;510		} );511		it( 'should be enabled when caret is inside exception marker (end boundary)', () => {512			model.change( writer => {513				writer.setSelection( firstParagraph, 7 );514			} );515			expect( editor.commands.get( 'allowed' ).isEnabled ).to.be.true;516		} );517		it( 'should be disabled for multi-range selection (collapsed ranges)', () => {518			model.change( writer => {519				writer.setSelection( [520					writer.createRange(521						writer.createPositionAt( firstParagraph, 5 )522					),523					writer.createRange(524						writer.createPositionAt( firstParagraph, 9 )525					)526				] );527			} );528			expect( editor.commands.get( 'allowed' ).isEnabled ).to.be.false;529		} );530		it( 'should be disabled for non-collapsed selection that expands over exception marker', () => {531			model.change( writer => {532				writer.setSelection( writer.createRange(533					writer.createPositionAt( firstParagraph, 0 ),534					writer.createPositionAt( firstParagraph, 5 )535				) );536			} );537			expect( editor.commands.get( 'allowed' ).isEnabled ).to.be.false;538		} );539		it( 'should be enabled for non-collapsed selection that is fully contained inside exception marker', () => {540			model.change( writer => {541				writer.setSelection( writer.createRange(542					writer.createPositionAt( firstParagraph, 5 ),543					writer.createPositionAt( firstParagraph, 6 )544				) );545			} );546			expect( editor.commands.get( 'allowed' ).isEnabled ).to.be.true;547		} );548		it( 'should be enabled for non-collapsed selection inside exception marker (start position on marker boundary)', () => {549			model.change( writer => {550				writer.setSelection( writer.createRange(551					writer.createPositionAt( firstParagraph, 4 ),552					writer.createPositionAt( firstParagraph, 6 )553				) );554			} );555			expect( editor.commands.get( 'allowed' ).isEnabled ).to.be.true;556		} );557		it( 'should be enabled for non-collapsed selection inside exception marker (end position on marker boundary)', () => {558			model.change( writer => {559				writer.setSelection( writer.createRange(560					writer.createPositionAt( firstParagraph, 5 ),561					writer.createPositionAt( firstParagraph, 7 )562				) );563			} );564			expect( editor.commands.get( 'allowed' ).isEnabled ).to.be.true;565		} );566		it( 'should be enabled for non-collapsed selection is equal to exception marker', () => {567			model.change( writer => {568				writer.setSelection( writer.createRange(569					writer.createPositionAt( firstParagraph, 4 ),570					writer.createPositionAt( firstParagraph, 7 )571				) );572			} );573			expect( editor.commands.get( 'allowed' ).isEnabled ).to.be.true;574		} );575		it( 'should be disabled for non-collapsed selection with more then one range', () => {576			model.change( writer => {577				writer.setSelection( [578					writer.createRange(579						writer.createPositionAt( firstParagraph, 5 ),580						writer.createPositionAt( firstParagraph, 6 )581					),582					writer.createRange(583						writer.createPositionAt( firstParagraph, 8 ),584						writer.createPositionAt( firstParagraph, 9 )585					)586				] );587			} );588			expect( editor.commands.get( 'allowed' ).isEnabled ).to.be.false;589		} );590	} );591	describe( 'integration', () => {592		let model, firstParagraph;593		beforeEach( async () => {594			editor = await VirtualTestEditor.create( { plugins: [ Paragraph, Typing, UndoEditing, RestrictedEditingModeEditing ] } );595			model = editor.model;596			setModelData( model, '<paragraph>[]foo bar baz</paragraph>' );597			firstParagraph = model.document.getRoot().getChild( 0 );598			model.change( writer => {599				writer.addMarker( 'restrictedEditingException:1', {600					range: writer.createRange(601						writer.createPositionAt( firstParagraph, 4 ),602						writer.createPositionAt( firstParagraph, 7 ) ),603					usingOperation: true,604					affectsData: true605				} );606			} );607		} );608		afterEach( async () => {609			await editor.destroy();610		} );611		describe( 'delete + undo', () => {612			it( 'should be enabled after data change (no selection change event on undo)', () => {613				model.change( writer => {614					writer.setSelection( firstParagraph, 7 );615				} );616				editor.execute( 'delete' );617				editor.execute( 'undo' );618				expect( editor.commands.get( 'delete' ).isEnabled ).to.be.true;619			} );620		} );621	} );622	class FakeCommand extends Command {623		refresh() {624			this.isEnabled = true;625		}626	}627	function buildFakeCommand( editor ) {628		return new FakeCommand( editor );...undo.js
Source:undo.js  
...17	} );18	it( 'split, remove', () => {19		john.setData( '<paragraph>Foo[]Bar</paragraph>' );20		john.split();21		john.setSelection( [ 1 ], [ 2 ] );22		john.remove();23		john.undo();24		john.undo();25		expectClients( '<paragraph>FooBar</paragraph>' );26	} );27	it( 'move, merge', () => {28		john.setData( '[<paragraph>Foo</paragraph>]<paragraph>Bar</paragraph>' );29		john.move( [ 2 ] );30		john.setSelection( [ 1 ] );31		john.merge();32		john.undo();33		john.undo();34		expectClients( '<paragraph>Foo</paragraph><paragraph>Bar</paragraph>' );35	} );36	it.skip( 'move multiple, merge', () => {37		john.setData( '[<paragraph>Foo</paragraph><paragraph>Bar</paragraph>]<paragraph>Xyz</paragraph>' );38		john.move( [ 3 ] );39		expectClients( '<paragraph>Xyz</paragraph><paragraph>Foo</paragraph><paragraph>Bar</paragraph>' );40		john.setSelection( [ 1 ] );41		john.merge();42		expectClients( '<paragraph>XyzFoo</paragraph><paragraph>Bar</paragraph>' );43		john.undo();44		expectClients( '<paragraph>Xyz</paragraph><paragraph>Foo</paragraph><paragraph>Bar</paragraph>' );45		john.undo();46		// Wrong move is done.47		expectClients( '<paragraph>Foo</paragraph><paragraph>Bar</paragraph><paragraph>Xyz</paragraph>' );48	} );49	it( 'move inside unwrapped content', () => {50		john.setData( '<blockQuote>[<paragraph>Foo</paragraph>]<paragraph>Bar</paragraph></blockQuote>' );51		john.move( [ 0, 2 ] );52		john.setSelection( [ 0, 0 ] );53		john.unwrap();54		john.undo();55		john.undo();56		expectClients(57			'<blockQuote>' +58				'<paragraph>Foo</paragraph>' +59				'<paragraph>Bar</paragraph>' +60			'</blockQuote>'61		);62	} );63	it( 'remove node, merge', () => {64		john.setData( '<paragraph>Foo</paragraph><paragraph>[Bar]</paragraph>' );65		john.remove();66		john.setSelection( [ 1 ] );67		john.merge();68		john.undo();69		john.undo();70		expectClients( '<paragraph>Foo</paragraph><paragraph>Bar</paragraph>' );71	} );72	it( 'merge, merge #1', () => {73		john.setData(74			'<blockQuote>' +75				'<paragraph>Foo</paragraph>' +76				'<paragraph>Bar</paragraph>' +77			'</blockQuote>' +78			'[]' +79			'<blockQuote>' +80				'<paragraph>Xyz</paragraph>' +81			'</blockQuote>'82		);83		john.merge();84		john.setSelection( [ 0, 2 ] );85		john.merge();86		expectClients(87			'<blockQuote>' +88				'<paragraph>Foo</paragraph>' +89				'<paragraph>BarXyz</paragraph>' +90			'</blockQuote>'91		);92		john.undo();93		john.undo();94		expectClients(95			'<blockQuote>' +96				'<paragraph>Foo</paragraph>' +97				'<paragraph>Bar</paragraph>' +98			'</blockQuote>' +99			'<blockQuote>' +100				'<paragraph>Xyz</paragraph>' +101			'</blockQuote>'102		);103	} );104	it( 'merge, merge #2', () => {105		john.setData(106			'<blockQuote>' +107				'<paragraph>Foo</paragraph>' +108			'</blockQuote>' +109			'[]' +110			'<blockQuote>' +111				'<paragraph>Bar</paragraph>' +112				'<paragraph>Xyz</paragraph>' +113			'</blockQuote>'114		);115		john.merge();116		john.setSelection( [ 0, 1 ] );117		john.merge();118		expectClients(119			'<blockQuote>' +120				'<paragraph>FooBar</paragraph>' +121				'<paragraph>Xyz</paragraph>' +122			'</blockQuote>'123		);124		john.undo();125		john.undo();126		expectClients(127			'<blockQuote>' +128				'<paragraph>Foo</paragraph>' +129			'</blockQuote>' +130			'<blockQuote>' +131				'<paragraph>Bar</paragraph>' +132				'<paragraph>Xyz</paragraph>' +133			'</blockQuote>'134		);135	} );136	it( 'merge, unwrap', () => {137		john.setData( '<paragraph></paragraph>[]<paragraph>Foo</paragraph>' );138		john.merge();139		john.setSelection( [ 0, 0 ] );140		john.unwrap();141		john.undo();142		john.undo();143		expectClients( '<paragraph></paragraph><paragraph>Foo</paragraph>' );144	} );145	it( 'remove node at the split position #1', () => {146		john.setData( '<paragraph>Ab</paragraph>[]<paragraph>Xy</paragraph>' );147		john.merge();148		john.setSelection( [ 0, 1 ], [ 0, 2 ] );149		john.remove();150		john.undo();151		john.undo();152		expectClients( '<paragraph>Ab</paragraph><paragraph>Xy</paragraph>' );153	} );154	it( 'remove node at the split position #2', () => {155		john.setData( '<paragraph>Ab</paragraph>[]<paragraph>Xy</paragraph>' );156		john.merge();157		john.setSelection( [ 0, 2 ], [ 0, 3 ] );158		john.remove();159		john.undo();160		john.undo();161		expectClients( '<paragraph>Ab</paragraph><paragraph>Xy</paragraph>' );162	} );163	it( 'undoing split after the element created by split has been removed', () => {164		// This example is ported here from ckeditor5-undo to keep 100% CC in ckeditor5-engine alone.165		john.setData( '<paragraph>Foo[]bar</paragraph>' );166		john.split();167		john.setSelection( [ 0, 3 ], [ 1, 3 ] );168		john.delete();169		expectClients( '<paragraph>Foo</paragraph>' );170		john.undo();171		expectClients( '<paragraph>Foo</paragraph><paragraph>bar</paragraph>' );172		john.undo();173		expectClients( '<paragraph>Foobar</paragraph>' );174	} );175	it( 'remove text from paragraph and merge it', () => {176		john.setData( '<paragraph>Foo</paragraph><paragraph>[Bar]</paragraph>' );177		john.remove();178		john.setSelection( [ 1 ] );179		john.merge();180		expectClients( '<paragraph>Foo</paragraph>' );181		john.undo();182		expectClients( '<paragraph>Foo</paragraph><paragraph></paragraph>' );183		john.undo();184		expectClients( '<paragraph>Foo</paragraph><paragraph>Bar</paragraph>' );185	} );186	it( 'delete split paragraphs', () => {187		john.setData( '<paragraph>Foo</paragraph><paragraph>B[]ar</paragraph>' );188		john.split();189		john.setSelection( [ 2, 1 ] );190		john.split();191		john.setSelection( [ 1, 0 ], [ 3, 1 ] );192		john.delete();193		john.setSelection( [ 1 ] );194		john.merge();195		expectClients( '<paragraph>Foo</paragraph>' );196		john.undo();197		expectClients( '<paragraph>Foo</paragraph><paragraph></paragraph>' );198		john.undo();199		expectClients( '<paragraph>Foo</paragraph><paragraph>B</paragraph><paragraph>a</paragraph><paragraph>r</paragraph>' );200		john.undo();201		expectClients( '<paragraph>Foo</paragraph><paragraph>B</paragraph><paragraph>ar</paragraph>' );202		john.undo();203		expectClients( '<paragraph>Foo</paragraph><paragraph>Bar</paragraph>' );204		john.redo();205		expectClients( '<paragraph>Foo</paragraph><paragraph>B</paragraph><paragraph>ar</paragraph>' );206		john.redo();207		expectClients( '<paragraph>Foo</paragraph><paragraph>B</paragraph><paragraph>a</paragraph><paragraph>r</paragraph>' );208		john.redo();209		expectClients( '<paragraph>Foo</paragraph><paragraph></paragraph>' );210		john.redo();211		expectClients( '<paragraph>Foo</paragraph>' );212	} );213	it( 'pasting on collapsed selection undo and redo', () => {214		john.setData( '<paragraph>Foo[]Bar</paragraph>' );215		// Below simulates pasting.216		john.editor.model.change( () => {217			john.split();218			john.setSelection( [ 1 ] );219			john.insert( '<paragraph>1</paragraph>' );220			john.setSelection( [ 1 ] );221			john.merge();222			john.setSelection( [ 1 ] );223			john.insert( '<paragraph>2</paragraph>' );224			john.setSelection( [ 2 ] );225			john.merge();226		} );227		expectClients( '<paragraph>Foo1</paragraph><paragraph>2Bar</paragraph>' );228		john.undo();229		expectClients( '<paragraph>FooBar</paragraph>' );230		john.redo();231		expectClients( '<paragraph>Foo1</paragraph><paragraph>2Bar</paragraph>' );232		john.undo();233		expectClients( '<paragraph>FooBar</paragraph>' );234		john.redo();235		expectClients( '<paragraph>Foo1</paragraph><paragraph>2Bar</paragraph>' );236	} );237	it( 'selection attribute setting: split, bold, merge, undo, undo, undo', () => {238		// This test is ported from undo to keep 100% CC in engine.239		john.setData( '<paragraph>Foo[]</paragraph><paragraph>Bar</paragraph>' );240		john.split();241		john.setSelection( [ 1, 0 ] );242		john._processExecute( 'bold' );243		john._processExecute( 'forwardDelete' );244		expectClients( '<paragraph>Foo</paragraph><paragraph>Bar</paragraph>' );245		john.undo();246		expectClients( '<paragraph>Foo</paragraph><paragraph selection:bold="true"></paragraph><paragraph>Bar</paragraph>' );247		john.undo();248		expectClients( '<paragraph>Foo</paragraph><paragraph></paragraph><paragraph>Bar</paragraph>' );249		john.undo();250		expectClients( '<paragraph>Foo</paragraph><paragraph>Bar</paragraph>' );251	} );252	// https://github.com/ckeditor/ckeditor5/issues/1288253	it( 'remove two groups of blocks then undo, undo', () => {254		john.setData(255			'<paragraph>X</paragraph><paragraph>A</paragraph><paragraph>B[</paragraph><paragraph>C</paragraph><paragraph>D]</paragraph>'256		);257		john.delete();258		john.setSelection( [ 0, 1 ], [ 2, 1 ] );259		john.delete();260		expectClients( '<paragraph>X</paragraph>' );261		john.undo();262		expectClients( '<paragraph>X</paragraph><paragraph>A</paragraph><paragraph>B</paragraph>' );263		john.undo();264		expectClients(265			'<paragraph>X</paragraph><paragraph>A</paragraph><paragraph>B</paragraph><paragraph>C</paragraph><paragraph>D</paragraph>'266		);267	} );268	// https://github.com/ckeditor/ckeditor5/issues/1287 TC1269	it( 'pasting on non-collapsed selection undo and redo', () => {270		john.setData( '<paragraph>Fo[o</paragraph><paragraph>B]ar</paragraph>' );271		// Below simulates pasting.272		john.editor.model.change( () => {273			john.editor.model.deleteContent( john.document.selection );274			john.setSelection( [ 0, 2 ] );275			john.split();276			john.setSelection( [ 1 ] );277			john.insert( '<paragraph>1</paragraph>' );278			john.setSelection( [ 1 ] );279			john.merge();280			john.setSelection( [ 1 ] );281			john.insert( '<paragraph>2</paragraph>' );282			john.setSelection( [ 2 ] );283			john.merge();284		} );285		expectClients( '<paragraph>Fo1</paragraph><paragraph>2ar</paragraph>' );286		john.undo();287		expectClients( '<paragraph>Foo</paragraph><paragraph>Bar</paragraph>' );288		john.redo();289		expectClients( '<paragraph>Fo1</paragraph><paragraph>2ar</paragraph>' );290		john.undo();291		expectClients( '<paragraph>Foo</paragraph><paragraph>Bar</paragraph>' );292	} );293	it( 'collapsed marker at the beginning of merged element then undo', () => {294		john.setData( '<paragraph>Foo</paragraph><paragraph>[]Bar</paragraph>' );295		john.setMarker( 'm1' );296		john.setSelection( [ 1 ] );297		john.merge();298		expectClients( '<paragraph>Foo<m1:start></m1:start>Bar</paragraph>' );299		john.undo();300		expectClients( '<paragraph>Foo</paragraph><paragraph><m1:start></m1:start>Bar</paragraph>' );301	} );302	it( 'collapsed marker at the end of merge-target element then undo', () => {303		john.setData( '<paragraph>Foo[]</paragraph><paragraph>Bar</paragraph>' );304		john.setMarker( 'm1' );305		john.setSelection( [ 1 ] );306		john.merge();307		expectClients( '<paragraph>Foo<m1:start></m1:start>Bar</paragraph>' );308		john.undo();309		expectClients( '<paragraph>Foo<m1:start></m1:start></paragraph><paragraph>Bar</paragraph>' );310	} );311	it( 'empty marker between merged elements then undo', () => {312		john.setData( '<paragraph>Foo[</paragraph><paragraph>]Bar</paragraph>' );313		john.setMarker( 'm1' );314		john.setSelection( [ 1 ] );315		john.merge();316		expectClients( '<paragraph>Foo<m1:start></m1:start>Bar</paragraph>' );317		john.undo();318		expectClients( '<paragraph>Foo<m1:start></m1:start></paragraph><paragraph><m1:end></m1:end>Bar</paragraph>' );319	} );320	it( 'left side of marker moved then undo', () => {321		john.setData( '<paragraph>Foo[bar]</paragraph><paragraph></paragraph>' );322		john.setMarker( 'm1' );323		john.setSelection( [ 0, 2 ], [ 0, 4 ] );324		john.move( [ 1, 0 ] );325		expectClients( '<paragraph>Fo<m1:start></m1:start>ar<m1:end></m1:end></paragraph><paragraph>ob</paragraph>' );326		john.undo();327		expectClients( '<paragraph>Foo<m1:start></m1:start>bar<m1:end></m1:end></paragraph><paragraph></paragraph>' );328	} );329	it( 'right side of marker moved then undo', () => {330		john.setData( '<paragraph>[Foo]bar</paragraph><paragraph></paragraph>' );331		john.setMarker( 'm1' );332		john.setSelection( [ 0, 2 ], [ 0, 4 ] );333		john.move( [ 1, 0 ] );334		expectClients( '<paragraph><m1:start></m1:start>Fo<m1:end></m1:end>ar</paragraph><paragraph>ob</paragraph>' );335		john.undo();336		expectClients( '<paragraph><m1:start></m1:start>Foo<m1:end></m1:end>bar</paragraph><paragraph></paragraph>' );337	} );338	it( 'marker on closing and opening tag - remove multiple elements #1', () => {339		john.setData(340			'<paragraph>Abc</paragraph>' +341			'<paragraph>Foo[</paragraph>' +342			'<paragraph>]Bar</paragraph>'343		);344		john.setMarker( 'm1' );345		john.setSelection( [ 0, 1 ], [ 2, 2 ] );346		john._processExecute( 'delete' );347		expectClients( '<paragraph>A<m1:start></m1:start>r</paragraph>' );348		john.undo();349		expectClients(350			'<paragraph>Abc</paragraph>' +351			'<paragraph>Foo<m1:start></m1:start></paragraph>' +352			'<paragraph><m1:end></m1:end>Bar</paragraph>'353		);354	} );355	it( 'marker on closing and opening tag - remove multiple elements #2', () => {356		john.setData(357			'<paragraph>Foo[</paragraph>' +358			'<paragraph>]Bar</paragraph>' +359			'<paragraph>Xyz</paragraph>'360		);361		john.setMarker( 'm1' );362		john.setSelection( [ 0, 1 ], [ 2, 2 ] );363		john._processExecute( 'delete' );364		expectClients( '<paragraph>F<m1:start></m1:start>z</paragraph>' );365		john.undo();366		expectClients(367			'<paragraph>Foo<m1:start></m1:start></paragraph>' +368			'<paragraph><m1:end></m1:end>Bar</paragraph>' +369			'<paragraph>Xyz</paragraph>'370		);371	} );372	it( 'marker on closing and opening tag + some text - merge elements + remove text', () => {373		john.setData(374			'<paragraph>Foo[</paragraph>' +375			'<paragraph>B]ar</paragraph>'376		);377		john.setMarker( 'm1' );378		john.setSelection( [ 0, 1 ], [ 1, 2 ] );379		john._processExecute( 'delete' );380		expectClients( '<paragraph>F<m1:start></m1:start>r</paragraph>' );381		john.undo();382		expectClients(383			'<paragraph>Foo<m1:start></m1:start></paragraph>' +384			'<paragraph>B<m1:end></m1:end>ar</paragraph>'385		);386	} );387	// https://github.com/ckeditor/ckeditor5-engine/issues/1668388	it( 'marker and moves with undo-redo-undo', () => {389		john.setData( '<paragraph>X[]Y</paragraph>' );390		const inputBufferBatch = john.editor.commands.get( 'input' ).buffer.batch;391		john.editor.model.enqueueChange( inputBufferBatch, () => {392			john.type( 'a' );393			john.type( 'b' );394			john.type( 'c' );395			john.setSelection( [ 0, 1 ], [ 0, 4 ] );396			john.setMarker( 'm1' );397		} );398		expectClients( '<paragraph>X<m1:start></m1:start>abc<m1:end></m1:end>Y</paragraph>' );399		john.setSelection( [ 0, 0 ], [ 0, 5 ] );400		john._processExecute( 'delete' );401		expectClients( '<paragraph></paragraph>' );402		john.undo();403		expectClients( '<paragraph>X<m1:start></m1:start>abc<m1:end></m1:end>Y</paragraph>' );404		john.undo();405		expectClients( '<paragraph>XY</paragraph>' );406		john.redo();407		expectClients( '<paragraph>X<m1:start></m1:start>abc<m1:end></m1:end>Y</paragraph>' );408		john.redo();409		expectClients( '<paragraph></paragraph>' );410		john.undo();411		expectClients( '<paragraph>X<m1:start></m1:start>abc<m1:end></m1:end>Y</paragraph>' );412		john.undo();413		expectClients( '<paragraph>XY</paragraph>' );414	} );415	// https://github.com/ckeditor/ckeditor5/issues/1385416	it( 'paste inside paste + undo, undo + redo, redo', () => {417		const model = john.editor.model;418		john.setData( '<paragraph>[]</paragraph>' );419		model.insertContent( getPastedContent() );420		john.setSelection( [ 0, 3 ] );421		model.insertContent( getPastedContent() );422		expectClients( '<heading1>FooFoobarbar</heading1>' );423		john.undo();424		expectClients( '<heading1>Foobar</heading1>' );425		john.undo();426		expectClients( '<paragraph></paragraph>' );427		john.redo();428		expectClients( '<heading1>Foobar</heading1>' );429		john.redo();430		expectClients( '<heading1>FooFoobarbar</heading1>' );431		function getPastedContent() {432			return new Element( 'heading1', null, new Text( 'Foobar' ) );433		}434	} );435	// https://github.com/ckeditor/ckeditor5/issues/1540436	it( 'paste, select all, paste, undo, undo, redo, redo, redo', () => {437		john.setData( '<paragraph>[]</paragraph>' );438		pasteContent();439		john.setSelection( [ 0, 0 ], [ 1, 3 ] );440		pasteContent();441		expectClients( '<heading1>Foo</heading1><paragraph>Bar</paragraph>' );442		john.undo();443		expectClients( '<heading1>Foo</heading1><paragraph>Bar</paragraph>' );444		john.undo();445		expectClients( '<paragraph></paragraph>' );446		john.redo();447		expectClients( '<heading1>Foo</heading1><paragraph>Bar</paragraph>' );448		john.redo();449		expectClients( '<heading1>Foo</heading1><paragraph>Bar</paragraph>' );450		function pasteContent() {451			john.editor.model.insertContent(452				new DocumentFragment( [453					new Element( 'heading1', null, new Text( 'Foo' ) ),454					new Element( 'paragraph', null, new Text( 'Bar' ) )455				] )456			);457		}458	} );459	// Happens in track changes. Emulated here.460	// https://github.com/ckeditor/ckeditor5-engine/issues/1701461	it( 'paste, remove, undo, undo, redo, redo', () => {462		john.setData( '<paragraph>Ab[]cd</paragraph><paragraph>Wxyz</paragraph>' );463		john.editor.model.insertContent(464			new DocumentFragment( [465				new Element( 'paragraph', null, new Text( 'Foo' ) ),466				new Element( 'paragraph', null, new Text( 'Bar' ) )467			] )468		);469		john.setSelection( [ 1, 3 ], [ 2, 2 ] );470		john._processExecute( 'delete' );471		expectClients( '<paragraph>AbFoo</paragraph><paragraph>Baryz</paragraph>' );472		john.undo();473		expectClients( '<paragraph>AbFoo</paragraph><paragraph>Barcd</paragraph><paragraph>Wxyz</paragraph>' );474		john.undo();475		expectClients( '<paragraph>Abcd</paragraph><paragraph>Wxyz</paragraph>' );476		john.redo();477		expectClients( '<paragraph>AbFoo</paragraph><paragraph>Barcd</paragraph><paragraph>Wxyz</paragraph>' );478		john.redo();479		expectClients( '<paragraph>AbFoo</paragraph><paragraph>Baryz</paragraph>' );480	} );...Settings.js
Source:Settings.js  
...21    <div className="account-tour">22      <Row>23        <Col>24          <Navbar color="light" light expand="md" className="settings-nav-tour">25            <NavbarBrand onClick={() => setSelection('index')}>Settings</NavbarBrand>26            <NavbarToggler onClick={toggle} />27            <Collapse isOpen={isOpen} navbar>28              <Nav className="mr-auto" navbar>29                <UncontrolledDropdown nav inNavbar>30                  <DropdownToggle nav caret>31                    Doors32                  </DropdownToggle>33                  <DropdownMenu right >34                    <DropdownItem onClick={() => setSelection('cope_door')} >35                      Cope and Stick36                    </DropdownItem>37                    <DropdownItem onClick={() => setSelection('mt_door')}>38                      MT Door39                    </DropdownItem>40                    <DropdownItem onClick={() => setSelection('miter_door')}>41                      Miter Door42                    </DropdownItem>43                    {/* <DropdownItem onClick={() => setSelection('one_piece_door')}>44                      One Piece Door45                    </DropdownItem> */}46                47                  </DropdownMenu>48                </UncontrolledDropdown>49                <UncontrolledDropdown nav inNavbar>50                  <DropdownToggle nav caret>51                    Drawer Fronts52                  </DropdownToggle>53                  <DropdownMenu right>54                    <DropdownItem onClick={() => setSelection('cope_df')}>55                      Cope and Stick56                    </DropdownItem>57                    <DropdownItem onClick={() => setSelection('mt_df')}>58                      MT Design59                    </DropdownItem>60                    <DropdownItem onClick={() => setSelection('miter_df')}>61                      Miter Design62                    </DropdownItem>63                    <DropdownItem onClick={() => setSelection('slab_type_door')}>64                      Slab Type DF65                    </DropdownItem>66                  </DropdownMenu>67                </UncontrolledDropdown>68                <UncontrolledDropdown nav inNavbar>69                  <DropdownToggle nav caret>70                    Drawer Boxes71                  </DropdownToggle>72                  <DropdownMenu right>73                    <DropdownItem onClick={() => setSelection('drawer_box')}>74                      Dovetail Drawer Box75                    </DropdownItem>76                  </DropdownMenu>77                </UncontrolledDropdown>78                <UncontrolledDropdown nav inNavbar>79                  <DropdownToggle nav caret>80                    Face Frames81                  </DropdownToggle>82                  <DropdownMenu right>83                    <DropdownItem onClick={() => setSelection('face_frames')}>84                      Face Frames85                    </DropdownItem>86                  </DropdownMenu>87                </UncontrolledDropdown>88                <UncontrolledDropdown nav inNavbar>89                  <DropdownToggle nav caret>90                    Mouldings91                  </DropdownToggle>92                  <DropdownMenu right>93                    <DropdownItem onClick={() => setSelection('base_cap')}>94                      Base Caps95                    </DropdownItem>96                    <DropdownItem onClick={() => setSelection('baseboards')}>97                      Baseboards98                    </DropdownItem>99                    <DropdownItem onClick={() => setSelection('casings')}>100                      Casings101                    </DropdownItem>102                    <DropdownItem onClick={() => setSelection('chair_rails')}>103                      Chair Rails104                    </DropdownItem>105                    <DropdownItem onClick={() => setSelection('crown_mouldings')}>106                      Crown Mouldings107                    </DropdownItem>108                    <DropdownItem onClick={() => setSelection('solid_crowns')}>109                      Solid Crowns110                    </DropdownItem>111                    <DropdownItem onClick={() => setSelection('wainscot')}>112                      Wainscot113                    </DropdownItem>114                    <DropdownItem onClick={() => setSelection('plynths')}>115                      Plynths and Others116                    </DropdownItem>117                    <DropdownItem onClick={() => setSelection('flat_stock')}>118                      Flat Stock119                    </DropdownItem>120                  </DropdownMenu>121                </UncontrolledDropdown>122                <UncontrolledDropdown nav inNavbar>123                  <DropdownToggle nav caret>124                    Misc. Items125                  </DropdownToggle>126                  <DropdownMenu right>127                    <DropdownItem onClick={() => setSelection('misc_items')}>128                      Misc Items.129                    </DropdownItem>130                  </DropdownMenu>131                </UncontrolledDropdown>132                <UncontrolledDropdown nav inNavbar>133                  <DropdownToggle nav caret>134                    Pricing135                  </DropdownToggle>136                  <DropdownMenu right>137                    <DropdownItem onClick={() => setSelection('door_pricing')}>138                      Doors139                    </DropdownItem>140                    <DropdownItem onClick={() => setSelection('drawer_pricing')} >141                      Drawer Boxes142                    </DropdownItem>143                  </DropdownMenu>144                </UncontrolledDropdown>145              </Nav>146            147            </Collapse>148          </Navbar>149        </Col>150      </Row>151      <Row>152        <Col>153          <Selection selection={selection} />154        </Col>...LegacyOutputPluginTest.js
Source:LegacyOutputPluginTest.js  
...14    Plugin();15    Theme();16    suite.test("Font color", function (editor) {17      editor.setContent('<p>text</p>');18      LegacyUnit.setSelection(editor, 'p', 0, 'p', 4);19      editor.execCommand('forecolor', false, '#FF0000');20      LegacyUnit.equal(editor.getContent().toLowerCase(), '<p><font color="#ff0000">text</font></p>');21    });22    suite.test("Font size", function (editor) {23      editor.setContent('<p>text</p>');24      LegacyUnit.setSelection(editor, 'p', 0, 'p', 4);25      editor.execCommand('fontsize', false, 7);26      LegacyUnit.equal(editor.getContent(), '<p><font size="7">text</font></p>');27    });28    suite.test("Font face", function (editor) {29      editor.setContent('<p>text</p>');30      LegacyUnit.setSelection(editor, 'p', 0, 'p', 4);31      editor.execCommand('fontname', false, "times");32      LegacyUnit.equal(editor.getContent(), '<p><font face="times">text</font></p>');33    });34    suite.test("Bold", function (editor) {35      editor.setContent('<p>text</p>');36      LegacyUnit.setSelection(editor, 'p', 0, 'p', 4);37      editor.execCommand('bold');38      LegacyUnit.equal(editor.getContent(), '<p><b>text</b></p>');39    });40    suite.test("Italic", function (editor) {41      editor.setContent('<p>text</p>');42      LegacyUnit.setSelection(editor, 'p', 0, 'p', 4);43      editor.execCommand('italic');44      LegacyUnit.equal(editor.getContent(), '<p><i>text</i></p>');45    });46    suite.test("Underline", function (editor) {47      editor.setContent('<p>text</p>');48      LegacyUnit.setSelection(editor, 'p', 0, 'p', 4);49      editor.execCommand('underline');50      LegacyUnit.equal(editor.getContent(), '<p><u>text</u></p>');51    });52    suite.test("Strikethrough", function (editor) {53      editor.setContent('<p>text</p>');54      LegacyUnit.setSelection(editor, 'p', 0, 'p', 4);55      editor.execCommand('strikethrough');56      LegacyUnit.equal(editor.getContent(), '<p><strike>text</strike></p>');57    });58    suite.test("Justifyleft", function (editor) {59      editor.setContent('<p>text</p>');60      LegacyUnit.setSelection(editor, 'p', 0, 'p', 4);61      editor.execCommand('justifyleft');62      LegacyUnit.equal(editor.getContent(), '<p align="left">text</p>');63    });64    suite.test("Justifycenter", function (editor) {65      editor.setContent('<p>text</p>');66      LegacyUnit.setSelection(editor, 'p', 0, 'p', 4);67      editor.execCommand('justifycenter');68      LegacyUnit.equal(editor.getContent(), '<p align="center">text</p>');69    });70    suite.test("Justifyright", function (editor) {71      editor.setContent('<p>text</p>');72      LegacyUnit.setSelection(editor, 'p', 0, 'p', 4);73      editor.execCommand('justifyright');74      LegacyUnit.equal(editor.getContent(), '<p align="right">text</p>');75    });76    suite.test("Justifyfull", function (editor) {77      editor.setContent('<p>text</p>');78      LegacyUnit.setSelection(editor, 'p', 0, 'p', 4);79      editor.execCommand('justifyfull');80      LegacyUnit.equal(editor.getContent(), '<p align="justify">text</p>');81    });82    TinyLoader.setup(function (editor, onSuccess, onFailure) {83      Pipeline.async({}, suite.toSteps(editor), onSuccess, onFailure);84    }, {85      plugins: 'legacyoutput',86      indent: false,87      skin_url: '/project/src/skins/lightgray/dist/lightgray'88    }, success, failure);89  }...legacyoutput.js
Source:legacyoutput.js  
...14	}15});16test("Font color", function() {17	editor.setContent('<p>text</p>');18	Utils.setSelection('p', 0, 'p', 4);19	editor.execCommand('forecolor', false, '#FF0000');20	equal(editor.getContent().toLowerCase(), '<p><font color="#ff0000">text</font></p>');21});22test("Font size", function() {23	editor.setContent('<p>text</p>');24	Utils.setSelection('p', 0, 'p', 4);25	editor.execCommand('fontsize', false, 7);26	equal(editor.getContent(), '<p><font size="7">text</font></p>');27});28test("Font face", function() {29	editor.setContent('<p>text</p>');30	Utils.setSelection('p', 0, 'p', 4);31	editor.execCommand('fontname', false, "times");32	equal(editor.getContent(), '<p><font face="times">text</font></p>');33});34test("Bold", function() {35	editor.setContent('<p>text</p>');36	Utils.setSelection('p', 0, 'p', 4);37	editor.execCommand('bold');38	equal(editor.getContent(), '<p><b>text</b></p>');39});40test("Italic", function() {41	editor.setContent('<p>text</p>');42	Utils.setSelection('p', 0, 'p', 4);43	editor.execCommand('italic');44	equal(editor.getContent(), '<p><i>text</i></p>');45});46test("Underline", function() {47	editor.setContent('<p>text</p>');48	Utils.setSelection('p', 0, 'p', 4);49	editor.execCommand('underline');50	equal(editor.getContent(), '<p><u>text</u></p>');51});52test("Strikethrough", function() {53	editor.setContent('<p>text</p>');54	Utils.setSelection('p', 0, 'p', 4);55	editor.execCommand('strikethrough');56	equal(editor.getContent(), '<p><strike>text</strike></p>');57});58test("Justifyleft", function() {59	editor.setContent('<p>text</p>');60	Utils.setSelection('p', 0, 'p', 4);61	editor.execCommand('justifyleft');62	equal(editor.getContent(), '<p align="left">text</p>');63});64test("Justifycenter", function() {65	editor.setContent('<p>text</p>');66	Utils.setSelection('p', 0, 'p', 4);67	editor.execCommand('justifycenter');68	equal(editor.getContent(), '<p align="center">text</p>');69});70test("Justifyright", function() {71	editor.setContent('<p>text</p>');72	Utils.setSelection('p', 0, 'p', 4);73	editor.execCommand('justifyright');74	equal(editor.getContent(), '<p align="right">text</p>');75});76test("Justifyfull", function() {77	editor.setContent('<p>text</p>');78	Utils.setSelection('p', 0, 'p', 4);79	editor.execCommand('justifyfull');80	equal(editor.getContent(), '<p align="justify">text</p>');...Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3  const browser = await chromium.launch();4  const context = await browser.newContext();5  const page = await context.newPage();6  const internalApi = page._delegate;7  await internalApi.setSelection('text=Playwright is a Node library to automate Chromium, Firefox and WebKit with a single API');8  await new Promise((resolve) => setTimeout(resolve, 5000));9  await browser.close();10})();11const { chromium } = require('playwright');12(async () => {13  const browser = await chromium.launch();14  const context = await browser.newContext();15  const page = await context.newPage();16  const internalApi = page._delegate;17  await internalApi.setSelection('text=Playwright is a Node library to automate Chromium, Firefox and WebKit with a single API');18  await new Promise((resolve) => setTimeout(resolve, 5000));19  await browser.close();20})();21const { chromium } = require('playwright');22(async () => {23  const browser = await chromium.launch();24  const context = await browser.newContext();25  const page = await context.newPage();26  const internalApi = page._delegate;27  await internalApi.setSelection('text=Playwright is a Node library to automate Chromium, Firefox and WebKit with a single API');28  await new Promise((resolve) => setTimeout(resolve, 5000));29  await browser.close();30})();31const { chromium } = require('playwright');32(async () => {33  const browser = await chromium.launch();Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3  const browser = await chromium.launch();4  const context = await browser.newContext();5  const page = await context.newPage();6  await page.click('text=Docs');7  await page.click('text=API');8  await page.click('text=Selectors');9  await page.click('text=Playwright');10  await page.click('text=Internal API');11  await page.click('text=Page');12  await page.click('text=setSelection');13  await page.click('text=Syntax');14  await page.click('text=setSelection');15  await page.click('text=Parameters');16  await page.click('text=setSelection');17  await page.click('text=Options');18  await page.click('text=setSelection');19  await page.click('text=Examples');20  await page.click('text=setSelection');21  await page.click('text=See also');22  await page.click('text=setSelection');23  await page.click('text=Related Projects');Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3  const browser = await chromium.launch();4  const page = await browser.newPage();5  await page.evaluate(async () => {6    await window.playwright._setSelection(document.body, 0, document.body, 1);7  });8  await browser.close();9})();10const { chromium } = require('playwright');11(async () => {12  const browser = await chromium.launch();13  const page = await browser.newPage();14  await page.evaluate(async () => {15    await window.playwright._setSelection(document.querySelector('input'), 0, document.querySelector('input'), 1);16  });17  await browser.close();18})();19const { chromium } = require('playwright');20(async () => {21  const browser = await chromium.launch();22  const page = await browser.newPage();23  await page.evaluate(async () => {24    await window.playwright._setSelection(document.querySelector('textarea'), 0, document.querySelector('textarea'), 1);25  });26  await browser.close();27})();28const { chromium } = require('playwright');29(async () => {30  const browser = await chromium.launch();31  const page = await browser.newPage();32  await page.evaluate(async () => {33    await window.playwright._setSelection(document.querySelector('.navbar__inner'), 0, document.querySelector('.navbar__inner'), 1);34  });35  await browser.close();36})();Using AI Code Generation
1const { setSelection } = require('playwright/lib/server/frames');2const { chromium } = require('playwright');3(async () => {4  const browser = await chromium.launch();5  const context = await browser.newContext();6  const page = await context.newPage();7  await page.click('text=Get started');8  await page.click('text=Docs');9  await page.click('text=API');10  await page.click('text=class: Page');11  await page.click('text=click');12  await page.click('text=frame');13  await page.click('text=selector');14  await page.click('text=force');15  await page.click('text=timeout');16  await page.click('text=strict');Using AI Code Generation
1const { chromium } = require('playwright');2const { setSelection } = require('playwright/lib/server/dom.js');3(async () => {4  const browser = await chromium.launch({ headless: false });5  const context = await browser.newContext();6  const page = await context.newPage();7  await page.click('input[title="Search"]');8  await page.fill('input[title="Search"]', 'Playwright');9  await page.click('text=Playwright');10  await page.click('text=Playwright');11  const element = await page.$('text=Playwright');12  await setSelection(page, element, 0, 5);13  await page.keyboard.press('Backspace');Using AI Code Generation
1await page.evaluate(() => {2  const range = new Range();3  range.setStart(document.querySelector('p').firstChild, 1);4  range.setEnd(document.querySelector('p').firstChild, 3);5  const selection = window.getSelection();6  selection.removeAllRanges();7  selection.addRange(range);8});9const selection = await page.evaluate(() => {10  return window.getSelection().toString();11});12console.log(selection);13await page.evaluate(() => {14  const range = new Range();15  range.setStart(document.querySelector('p').firstChild, 1);16  range.setEnd(document.querySelector('p').firstChild, 3);17  const selection = window.getSelection();18  selection.removeAllRanges();19  selection.addRange(range);20});21const selection = await page.evaluate(() => {22  return window.getSelection().toString();23});24console.log(selection);25await page.evaluate(() => {26  const range = new Range();27  range.setStart(document.querySelector('p').firstChild, 1);28  range.setEnd(document.querySelector('p').firstChild, 3);29  const selection = window.getSelection();30  selection.removeAllRanges();31  selection.addRange(range);32});33const selection = await page.evaluate(() => {34  return window.getSelection().toString();35});36console.log(selection);37await page.evaluate(() => {38  const range = new Range();39  range.setStart(document.querySelector('p').firstChild, 1);40  range.setEnd(document.querySelector('p').firstChild, 3);41  const selection = window.getSelection();42  selection.removeAllRanges();43  selection.addRange(range);44});45const selection = await page.evaluate(() => {46  return window.getSelection().toString();47});48console.log(selection);49await page.evaluate(() => {50  const range = new Range();51  range.setStart(document.querySelector('p').firstChild, 1);52  range.setEnd(document.querySelector('p').firstChild, 3);53  const selection = window.getSelection();54  selection.removeAllRanges();55  selection.addRange(range);Using AI Code Generation
1await page.evaluate(() => {2  const range = new Range();3  range.setStart(document.querySelector('p').firstChild, 1);4  range.setEnd(document.querySelector('p').firstChild, 3);5  const selection = window.getSelection();6  selection.removeAllRanges();7  selection.addRange(range);8});9const selection = await page.evaluate(() => {10  return window.getSelection().toString();11});12console.log(selection);13await page.evaluate(() => {14  const range = new Range();15  range.setStart(document.querySelector('p').firstChild, 1);16  range.setEnd(document.querySelector('p').firstChild, 3);17  const selection = window.getSelection();18  selection.removeAllRanges();19  selection.addRange(range);20});21const selection = await page.evaluate(() => {22  return window.getSelection().toString();23});24console.log(selection);25await page.evaluate(() => {26  const range = new Range();27  range.setStart(document.querySelector('p').firstChild, 1);28  range.setEnd(document.querySelector('p').firstChild, 3);29  const selection = window.getSelection();30  selection.removeAllRanges();31  selection.addRange(range);32});33const selection = await page.evaluate(() => {34  return window.getSelection().toString();35});36console.log(selection);37await page.evaluate(() => {38  const range = new Range();39  range.setStart(document.querySelector('p').firstChild, 1);40  range.setEnd(document.querySelector('p').firstChild, 3);41  const selection = window.getSelection();42  selection.removeAllRanges();43  selection.addRange(range);44});45const selection = await page.evaluate(() => {46  return window.getSelection().toString();47});48console.log(selection);49await page.evaluate(() => {50  const range = new Range();51  range.setStart(document.querySelector('p').firstChild, 1);52  range.setEnd(document.querySelector('p').firstChild, 3);53  const selection = window.getSelection();54  selection.removeAllRanges();55  selection.addRange(range);Using AI Code Generation
1const { setSelection } = require('@playwright/test/lib/internal/selectorEngine');2const { test, expect } = require('@playwright/test');3test('test', async ({ page }) => {4  const input = await page.$('input[name=q]');5  await setSelection(page, input, 1, 3);6  expect(await input.evaluate((e) => e.value)).toBe('oo');7});8{9  "compilerOptions": {10    "paths": {11    }12  },13}14{15  "scripts": {16  },17  "dependencies": {18  }19}Using AI Code Generation
1const { test, expect } = require('@playwright/test');2test('test', async ({ page }) => {3  await page.evaluate(() => {4    const range = document.createRange();5    const selection = window.getSelection();6    range.setStart(document.body, 0);7    range.setEnd(document.body, 0);8    selection.removeAllRanges();9    selection.addRange(range);10  });11  await page.keyboard.type('test');12  expect(await page.evaluate(() => document.body.textContent)).toBe('test');13});Using AI Code Generation
1const { setSelection } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');2await setSelection(page, 'input', 'test');3const { setSelection } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');4await setSelection(page, 'input', 'test');5const { setSelection } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');6await setSelection(page, 'input', 'test');7const { setSelection } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');8await setSelection(page, 'input', 'test');9const { setSelection } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');10await setSelection(page, 'input', 'test');11const { setSelection } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');12await setSelection(page, 'input', 'test');13const { setSelection } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');14await setSelection(page, 'input', 'test');15const { setSelection } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');16await setSelection(page, 'input', 'test');17const { setSelection } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');18await setSelection(page, 'input', 'test');19const { setSelection } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');20await setSelection(page, 'input', 'test');21const { setSelection } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');22await setSelection(pageUsing AI Code Generation
1const { test, expect } = require('@playwright/test');2test('test', async ({ page }) => {3  await page.evaluate(() => {4    const range = document.createRange();5    const selection = window.getSelection();6    range.setStart(document.body, 0);7    range.setEnd(document.body, 0);8    selection.removeAllRanges();9    selection.addRange(range);10  });11  await page.keyboard.type('test');12  expect(await page.evaluate(() => document.body.textContent)).toBe('test');13});Using AI Code Generation
1const { setSelection } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');2await setSelection(page, 'input', 'test');3const { setSelection } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');4await setSelection(page, 'input', 'test');5const { setSelection } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');6await setSelection(page, 'input', 'test');7const { setSelection } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');8await setSelection(page, 'input', 'test');9const { setSelection } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');10await setSelection(page, 'input', 'test');11const { setSelection } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');12await setSelection(page, 'input', 'test');13const { setSelection } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');14await setSelection(page, 'input', 'test');15const { setSelection } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');16await setSelection(page, 'input', 'test');17const { setSelection } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');18await setSelection(page, 'input', 'test');19const { setSelection } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');20await setSelection(page, 'input', 'test');21const { setSelection } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');22await setSelection(pageLambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!
