<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[28138] trunk/tests/qunit/editor: Update the TinyMCE tests to 4.0.21.1, see #27744</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://core.trac.wordpress.org/changeset/28138">28138</a></dd>
<dt>Author</dt> <dd>azaozz</dd>
<dt>Date</dt> <dd>2014-04-15 22:06:11 +0000 (Tue, 15 Apr 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Update the TinyMCE tests to 4.0.21.1, see <a href="http://core.trac.wordpress.org/ticket/27744">#27744</a></pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunktestsquniteditorindexhtml">trunk/tests/qunit/editor/index.html</a></li>
<li><a href="#trunktestsquniteditorjsinitjs">trunk/tests/qunit/editor/js/init.js</a></li>
<li><a href="#trunktestsquniteditorjsutilsjs">trunk/tests/qunit/editor/js/utils.js</a></li>
<li><a href="#trunktestsquniteditorpluginslistsjs">trunk/tests/qunit/editor/plugins/lists.js</a></li>
<li><a href="#trunktestsquniteditorpluginsnoneditablejs">trunk/tests/qunit/editor/plugins/noneditable.js</a></li>
<li><a href="#trunktestsquniteditorpluginspastejs">trunk/tests/qunit/editor/plugins/paste.js</a></li>
<li><a href="#trunktestsquniteditortinymceEditorjs">trunk/tests/qunit/editor/tinymce/Editor.js</a></li>
<li><a href="#trunktestsquniteditortinymceEnterKeyjs">trunk/tests/qunit/editor/tinymce/EnterKey.js</a></li>
<li><a href="#trunktestsquniteditortinymceFormatter_applyjs">trunk/tests/qunit/editor/tinymce/Formatter_apply.js</a></li>
<li><a href="#trunktestsquniteditortinymceFormatter_checkjs">trunk/tests/qunit/editor/tinymce/Formatter_check.js</a></li>
<li><a href="#trunktestsquniteditortinymceUndoManagerjs">trunk/tests/qunit/editor/tinymce/UndoManager.js</a></li>
<li><a href="#trunktestsquniteditortinymcedomEventUtilsjs">trunk/tests/qunit/editor/tinymce/dom/EventUtils.js</a></li>
<li><a href="#trunktestsquniteditortinymcedomSerializerjs">trunk/tests/qunit/editor/tinymce/dom/Serializer.js</a></li>
<li><a href="#trunktestsquniteditortinymceuiControljs">trunk/tests/qunit/editor/tinymce/ui/Control.js</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunktestsquniteditortinymceAddOnManagerjs">trunk/tests/qunit/editor/tinymce/AddOnManager.js</a></li>
<li><a href="#trunktestsquniteditortinymceEditorManagerjs">trunk/tests/qunit/editor/tinymce/EditorManager.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunktestsquniteditorindexhtml"></a>
<div class="modfile"><h4>Modified: trunk/tests/qunit/editor/index.html (28137 => 28138)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/tests/qunit/editor/index.html      2014-04-15 10:56:56 UTC (rev 28137)
+++ trunk/tests/qunit/editor/index.html 2014-04-15 22:06:11 UTC (rev 28138)
</span><span class="lines">@@ -5,7 +5,6 @@
</span><span class="cx">  <title>TinyMCE QUnit tests</title>
</span><span class="cx">  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
</span><span class="cx">  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0" />
</span><del>-       <title>QUnit tests</title>
</del><span class="cx">   <link rel="stylesheet" href="js/qunit/qunit.css" type="text/css" />
</span><span class="cx">  <link rel="stylesheet" href="../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" type="text/css" />
</span><span class="cx">  <link rel="stylesheet" href="tinymce/ui/css/ui-overrides.css" type="text/css" />
</span><span class="lines">@@ -70,8 +69,10 @@
</span><span class="cx">  <script src="tinymce/util/XHR.js"></script>
</span><span class="cx"> 
</span><span class="cx">  <!-- tinymce.* -->
</span><ins>+       <script src="tinymce/AddOnManager.js"></script>
</ins><span class="cx">   <script src="tinymce/Editor.js"></script>
</span><span class="cx">  <script src="tinymce/EditorCommands.js"></script>
</span><ins>+       <script src="tinymce/EditorManager.js"></script>
</ins><span class="cx">   <script src="tinymce/EnterKey.js"></script>
</span><span class="cx">  <script src="tinymce/ForceBlocks.js"></script>
</span><span class="cx">  <script src="tinymce/Formatter_apply.js"></script>
</span></span></pre></div>
<a id="trunktestsquniteditorjsinitjs"></a>
<div class="modfile"><h4>Modified: trunk/tests/qunit/editor/js/init.js (28137 => 28138)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/tests/qunit/editor/js/init.js      2014-04-15 10:56:56 UTC (rev 28137)
+++ trunk/tests/qunit/editor/js/init.js 2014-04-15 22:06:11 UTC (rev 28138)
</span><span class="lines">@@ -1,11 +1,13 @@
</span><span class="cx"> (function() {
</span><del>-       var coverObjects = [], modulesExecuted = {};
</del><ins>+        var coverObjects = [], modulesExecuted = {}, log = [], currentModule;
</ins><span class="cx"> 
</span><span class="cx">  QUnit.config.reorder = false;
</span><ins>+       QUnit.config.hidepassed = true;
</ins><span class="cx"> 
</span><span class="cx">  var oldModule = module;
</span><span class="cx"> 
</span><span class="cx">  QUnit.moduleStart(function(details) {
</span><ins>+               currentModule = details.name;
</ins><span class="cx">           modulesExecuted[details.name] = true;
</span><span class="cx"> 
</span><span class="cx">          tinymce.remove();
</span><span class="lines">@@ -17,7 +19,17 @@
</span><span class="cx">          window.editor = window.inlineEditor = null;
</span><span class="cx">  });
</span><span class="cx"> 
</span><del>-       QUnit.done(function() {
</del><ins>+        // Sauce labs
+       QUnit.testStart(function(testDetails) {
+               QUnit.log = function(details) {
+                       if (!details.result) {
+                               details.name = currentModule + ':' + testDetails.name;
+                               log.push(details);
+                       }
+               };
+       });
+
+       QUnit.done(function(results) {
</ins><span class="cx">           document.getElementById("view").style.display = 'none';
</span><span class="cx"> 
</span><span class="cx">          if (window.__$coverObject) {
</span><span class="lines">@@ -27,6 +39,21 @@
</span><span class="cx">                          window.open('coverage/index.html', 'coverage');
</span><span class="cx">                  }).appendTo(document.body);
</span><span class="cx">          }
</span><ins>+
+               // Sauce labs
+               var tests = [];
+               for (var i = 0; i < log.length; i++) {
+                       tests.push({
+                               name: log[i].name,
+                               result: log[i].result,
+                               expected: log[i].expected,
+                               actual: log[i].actual,
+                               source: log[i].source
+                       });
+               }
+
+               results.tests = tests;
+               window.global_test_results = results;
</ins><span class="cx">   });
</span><span class="cx"> 
</span><span class="cx">  window.module = function(name, settings) {
</span></span></pre></div>
<a id="trunktestsquniteditorjsutilsjs"></a>
<div class="modfile"><h4>Modified: trunk/tests/qunit/editor/js/utils.js (28137 => 28138)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/tests/qunit/editor/js/utils.js     2014-04-15 10:56:56 UTC (rev 28137)
+++ trunk/tests/qunit/editor/js/utils.js        2014-04-15 22:06:11 UTC (rev 28138)
</span><span class="lines">@@ -98,8 +98,9 @@
</span><span class="cx">          } else {
</span><span class="cx">                  ev = document.createEvent('UIEvents');
</span><span class="cx"> 
</span><del>-                       if (ev.initUIEvent)
</del><ins>+                        if (ev.initUIEvent) {
</ins><span class="cx">                           ev.initUIEvent(na, true, true, window, 1);
</span><ins>+                       }
</ins><span class="cx"> 
</span><span class="cx">                  ev.keyCode = o.keyCode;
</span><span class="cx">                  ev.charCode = o.charCode;
</span><span class="lines">@@ -110,17 +111,19 @@
</span><span class="cx"> 
</span><span class="cx">  function normalizeRng(rng) {
</span><span class="cx">          if (rng.startContainer.nodeType == 3) {
</span><del>-                       if (rng.startOffset == 0)
</del><ins>+                        if (rng.startOffset === 0) {
</ins><span class="cx">                           rng.setStartBefore(rng.startContainer);
</span><del>-                       else if (rng.startOffset >= rng.startContainer.nodeValue.length - 1)
</del><ins>+                        } else if (rng.startOffset >= rng.startContainer.nodeValue.length - 1) {
</ins><span class="cx">                           rng.setStartAfter(rng.startContainer);
</span><ins>+                       }
</ins><span class="cx">           }
</span><span class="cx"> 
</span><span class="cx">          if (rng.endContainer.nodeType == 3) {
</span><del>-                       if (rng.endOffset == 0)
</del><ins>+                        if (rng.endOffset === 0) {
</ins><span class="cx">                           rng.setEndBefore(rng.endContainer);
</span><del>-                       else if (rng.endOffset >= rng.endContainer.nodeValue.length - 1)
</del><ins>+                        } else if (rng.endOffset >= rng.endContainer.nodeValue.length - 1) {
</ins><span class="cx">                           rng.setEndAfter(rng.endContainer);
</span><ins>+                       }
</ins><span class="cx">           }
</span><span class="cx"> 
</span><span class="cx">          return rng;
</span><span class="lines">@@ -128,7 +131,7 @@
</span><span class="cx"> 
</span><span class="cx">  // TODO: Replace this with the new event logic in 3.5
</span><span class="cx">  function type(chr) {
</span><del>-               var editor = tinymce.activeEditor, keyCode, charCode, event = tinymce.dom.Event, evt, startElm, rng;
</del><ins>+                var editor = tinymce.activeEditor, keyCode, charCode, evt, startElm, rng;
</ins><span class="cx"> 
</span><span class="cx">          function fakeEvent(target, type, evt) {
</span><span class="cx">                  editor.dom.fire(target, type, evt);
</span><span class="lines">@@ -317,6 +320,46 @@
</span><span class="cx">          return html.replace(/<br[^>]*>/gi, '');
</span><span class="cx">  }
</span><span class="cx"> 
</span><ins>+       function patch(proto, name, patchFunc) {
+               var originalFunc = proto[name];
+               var originalFuncs = proto.__originalFuncs;
+
+               if (!originalFuncs) {
+                       proto.__originalFuncs = originalFuncs = {};
+               }
+
+               if (!originalFuncs[name]) {
+                       originalFuncs[name] = originalFunc;
+               } else {
+                       originalFunc = originalFuncs[name];
+               }
+
+               proto[name] = function() {
+                       var args = Array.prototype.slice.call(arguments);
+                       args.unshift(originalFunc);
+                       return patchFunc.apply(this, args);
+               };
+       }
+
+       function unpatch(proto, name) {
+               var originalFuncs = proto.__originalFuncs;
+
+               if (!originalFuncs) {
+                       return;
+               }
+
+               if (name) {
+                       proto[name] = originalFuncs[name];
+                       delete originalFuncs[name];
+               } else {
+                       for (var key in originalFuncs) {
+                               proto[key] = originalFuncs[key];
+                       }
+
+                       delete proto.__originalFuncs;
+               }
+       }
+
</ins><span class="cx">   window.Utils = {
</span><span class="cx">          fontFace: fontFace,
</span><span class="cx">          findContainer: findContainer,
</span><span class="lines">@@ -334,6 +377,8 @@
</span><span class="cx">          getFontmostWindow: getFontmostWindow,
</span><span class="cx">          pressArrowKey: pressArrowKey,
</span><span class="cx">          pressEnter: pressEnter,
</span><del>-               trimBrsOnIE: trimBrsOnIE
</del><ins>+                trimBrsOnIE: trimBrsOnIE,
+               patch: patch,
+               unpatch: unpatch
</ins><span class="cx">   };
</span><span class="cx"> })();
</span></span></pre></div>
<a id="trunktestsquniteditorpluginslistsjs"></a>
<div class="modfile"><h4>Modified: trunk/tests/qunit/editor/plugins/lists.js (28137 => 28138)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/tests/qunit/editor/plugins/lists.js        2014-04-15 10:56:56 UTC (rev 28137)
+++ trunk/tests/qunit/editor/plugins/lists.js   2014-04-15 22:06:11 UTC (rev 28138)
</span><span class="lines">@@ -4,7 +4,7 @@
</span><span class="cx">          QUnit.stop();
</span><span class="cx"> 
</span><span class="cx">          function wait() {
</span><del>-                       if (editor && inlineEditor) {
</del><ins>+                        if (window.editor && window.inlineEditor) {
</ins><span class="cx">                           if (!QUnit.started) {
</span><span class="cx">                                  QUnit.start();
</span><span class="cx">                                  QUnit.started = true;
</span><span class="lines">@@ -449,30 +449,33 @@
</span><span class="cx">  equal(editor.selection.getEnd().nodeName, tinymce.Env.ie && tinymce.Env.ie < 9 ? 'LI' : 'EM'); // Old IE will return the end LI not a big deal
</span><span class="cx"> });
</span><span class="cx"> 
</span><del>-test('Apply UL list to br line and text block line', function() {
-       editor.settings.forced_root_block = false;
</del><ins>+// Ignore on IE 7, 8 this is a known bug not worth fixing
+if (!tinymce.Env.ie || tinymce.Env.ie > 8) {
+       test('Apply UL list to br line and text block line', function() {
+               editor.settings.forced_root_block = false;
</ins><span class="cx"> 
</span><del>-       editor.setContent(
-               'a' +
-               '<p>b</p>'
-       );
</del><ins>+                editor.setContent(
+                       'a' +
+                       '<p>b</p>'
+               );
</ins><span class="cx"> 
</span><del>-       var rng = editor.dom.createRng();
-       rng.setStart(editor.getBody().firstChild, 0);
-       rng.setEnd(editor.getBody().lastChild.firstChild, 1);
-       editor.selection.setRng(rng);
-       execCommand('InsertUnorderedList');
</del><ins>+                var rng = editor.dom.createRng();
+               rng.setStart(editor.getBody().firstChild, 0);
+               rng.setEnd(editor.getBody().lastChild.firstChild, 1);
+               editor.selection.setRng(rng);
+               execCommand('InsertUnorderedList');
</ins><span class="cx"> 
</span><del>-       equal(editor.getContent(),
-               '<ul>' +
-                       '<li>a</li>' +
-                       '<li>b</li>' +
-               '</ul>'
-       );
</del><ins>+                equal(editor.getContent(),
+                       '<ul>' +
+                               '<li>a</li>' +
+                               '<li>b</li>' +
+                       '</ul>'
+               );
</ins><span class="cx"> 
</span><del>-       equal(editor.selection.getStart().nodeName, 'LI');
-       equal(editor.selection.getEnd().nodeName, 'LI');
-});
</del><ins>+                equal(editor.selection.getStart().nodeName, 'LI');
+               equal(editor.selection.getEnd().nodeName, 'LI');
+       });
+}
</ins><span class="cx"> 
</span><span class="cx"> test('Apply UL list to text block line and br line', function() {
</span><span class="cx">  editor.settings.forced_root_block = false;
</span><span class="lines">@@ -838,28 +841,31 @@
</span><span class="cx">  equal(editor.selection.getNode().nodeName, 'P');
</span><span class="cx"> });
</span><span class="cx"> 
</span><del>-test('Remove empty UL between two textblocks in BR mode', function() {
-       editor.settings.forced_root_block = false;
</del><ins>+// Ignore on IE 7, 8 this is a known bug not worth fixing
+if (!tinymce.Env.ie || tinymce.Env.ie > 8) {
+       test('Remove empty UL between two textblocks in BR mode', function() {
+               editor.settings.forced_root_block = false;
</ins><span class="cx"> 
</span><del>-       editor.getBody().innerHTML = trimBrs(
-               '<div>a</div>' +
-               '<ul>' +
-                       '<li></li>' +
-               '</ul>' +
-               '<div>b</div>'
-       );
</del><ins>+                editor.getBody().innerHTML = trimBrs(
+                       '<div>a</div>' +
+                       '<ul>' +
+                               '<li></li>' +
+                       '</ul>' +
+                       '<div>b</div>'
+               );
</ins><span class="cx"> 
</span><del>-       editor.focus();
-       Utils.setSelection('li:first', 0);
-       execCommand('InsertUnorderedList');
</del><ins>+                editor.focus();
+               Utils.setSelection('li:first', 0);
+               execCommand('InsertUnorderedList');
</ins><span class="cx"> 
</span><del>-       equal(editor.getContent(),
-               '<div>a</div>' +
-               '<br />' +
-               '<div>b</div>'
-       );
-       equal(editor.selection.getStart().nodeName, 'BR');
-});
</del><ins>+                equal(editor.getContent(),
+                       '<div>a</div>' +
+                       '<br />' +
+                       '<div>b</div>'
+               );
+               equal(editor.selection.getStart().nodeName, 'BR');
+       });
+}
</ins><span class="cx"> 
</span><span class="cx"> // Outdent
</span><span class="cx"> 
</span><span class="lines">@@ -1730,7 +1736,7 @@
</span><span class="cx"> 
</span><span class="cx"> test('Remove UL in inline body element contained in LI', function() {
</span><span class="cx">  inlineEditor.setContent('<ul><li>a</li></ul>');
</span><del>-       inlineEditor.focus();
</del><ins>+        inlineEditor.selection.setCursorLocation();
</ins><span class="cx">   inlineEditor.execCommand('InsertUnorderedList');
</span><span class="cx">  equal(inlineEditor.getContent(), '<p>a</p>');
</span><span class="cx"> });
</span></span></pre></div>
<a id="trunktestsquniteditorpluginsnoneditablejs"></a>
<div class="modfile"><h4>Modified: trunk/tests/qunit/editor/plugins/noneditable.js (28137 => 28138)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/tests/qunit/editor/plugins/noneditable.js  2014-04-15 10:56:56 UTC (rev 28137)
+++ trunk/tests/qunit/editor/plugins/noneditable.js     2014-04-15 22:06:11 UTC (rev 28138)
</span><span class="lines">@@ -23,76 +23,79 @@
</span><span class="cx">  }
</span><span class="cx"> });
</span><span class="cx"> 
</span><del>-test('expand to noneditable (start)', function() {
-       editor.setContent('<p><span class="mceNonEditable">no</span>yes</p>');
</del><ins>+// Ignore on IE 7, 8 this is a known bug not worth fixing
+if (!tinymce.Env.ie || tinymce.Env.ie > 8) {
+       test('expand to noneditable (start)', function() {
+               editor.setContent('<p><span class="mceNonEditable">no</span>yes</p>');
</ins><span class="cx"> 
</span><del>-       var rng = editor.dom.createRng();
-       rng.setStart(editor.getBody().firstChild.firstChild.firstChild, 1);
-       rng.setEnd(editor.getBody().firstChild.lastChild, 1);
-       editor.selection.setRng(rng);
</del><ins>+                var rng = editor.dom.createRng();
+               rng.setStart(editor.getBody().firstChild.firstChild.firstChild, 1);
+               rng.setEnd(editor.getBody().firstChild.lastChild, 1);
+               editor.selection.setRng(rng);
</ins><span class="cx"> 
</span><del>-       editor.dom.fire(editor.getBody(), 'mouseup');
-       rng = Utils.normalizeRng(editor.selection.getRng(true));
</del><ins>+                editor.dom.fire(editor.getBody(), 'mouseup');
+               rng = Utils.normalizeRng(editor.selection.getRng(true));
</ins><span class="cx"> 
</span><del>-       equal(rng.startContainer.nodeName, 'P');
-       equal(rng.startOffset, 0);
-       equal(rng.endContainer.nodeName, '#text');
-       equal(rng.endOffset, 1);
-});
</del><ins>+                equal(rng.startContainer.nodeName, 'P');
+               equal(rng.startOffset, 0);
+               equal(rng.endContainer.nodeName, '#text');
+               equal(rng.endOffset, 1);
+       });
</ins><span class="cx"> 
</span><del>-test('expand to noneditable (end)', function() {
-       editor.setContent('<p>yes<span class="mceNonEditable">no</span></p>');
</del><ins>+        test('expand to noneditable (end)', function() {
+               editor.setContent('<p>yes<span class="mceNonEditable">no</span></p>');
</ins><span class="cx"> 
</span><del>-       var rng = editor.dom.createRng();
-       rng.setStart(editor.getBody().firstChild.firstChild, 1);
-       rng.setEnd(editor.getBody().firstChild.lastChild.firstChild, 1);
-       editor.selection.setRng(rng);
</del><ins>+                var rng = editor.dom.createRng();
+               rng.setStart(editor.getBody().firstChild.firstChild, 1);
+               rng.setEnd(editor.getBody().firstChild.lastChild.firstChild, 1);
+               editor.selection.setRng(rng);
</ins><span class="cx"> 
</span><del>-       editor.dom.fire(editor.getBody(), 'mouseup');
-       rng = Utils.normalizeRng(editor.selection.getRng(true));
</del><ins>+                editor.dom.fire(editor.getBody(), 'mouseup');
+               rng = Utils.normalizeRng(editor.selection.getRng(true));
</ins><span class="cx"> 
</span><del>-       equal(rng.startContainer.nodeName, '#text');
-       equal(rng.startOffset, 1);
-       equal(rng.endContainer.nodeName, 'P');
-       equal(rng.endOffset, 2);
-});
</del><ins>+                equal(rng.startContainer.nodeName, '#text');
+               equal(rng.startOffset, 1);
+               equal(rng.endContainer.nodeName, 'P');
+               equal(rng.endOffset, 2);
+       });
</ins><span class="cx"> 
</span><del>-test('expand to noneditable (start/end)', function() {
-       editor.setContent('<p>yes<span class="mceNonEditable">noedit</span>yes</p>');
</del><ins>+        test('expand to noneditable (start/end)', function() {
+               editor.setContent('<p>yes<span class="mceNonEditable">noedit</span>yes</p>');
</ins><span class="cx"> 
</span><del>-       var rng = editor.dom.createRng();
-       rng.setStart(editor.dom.select('span')[0].firstChild, 1);
-       rng.setEnd(editor.dom.select('span')[0].firstChild, 2);
-       editor.selection.setRng(rng);
</del><ins>+                var rng = editor.dom.createRng();
+               rng.setStart(editor.dom.select('span')[0].firstChild, 1);
+               rng.setEnd(editor.dom.select('span')[0].firstChild, 2);
+               editor.selection.setRng(rng);
</ins><span class="cx"> 
</span><del>-       editor.dom.fire(editor.getBody(), 'mouseup');
-       rng = Utils.normalizeRng(editor.selection.getRng(true));
</del><ins>+                editor.dom.fire(editor.getBody(), 'mouseup');
+               rng = Utils.normalizeRng(editor.selection.getRng(true));
</ins><span class="cx"> 
</span><del>-       equal(rng.startContainer.nodeName, 'P');
-       equal(rng.startOffset, 1);
-       equal(rng.endContainer.nodeName, 'P');
-       equal(rng.endOffset, 2);
-});
</del><ins>+                equal(rng.startContainer.nodeName, 'P');
+               equal(rng.startOffset, 1);
+               equal(rng.endContainer.nodeName, 'P');
+               equal(rng.endOffset, 2);
+       });
</ins><span class="cx"> 
</span><del>-test('type after non editable', function() {
-       editor.setContent('<p><span class="mceNonEditable">no</span>yes</p>');
</del><ins>+        test('type after non editable', function() {
+               editor.setContent('<p><span class="mceNonEditable">no</span>yes</p>');
</ins><span class="cx"> 
</span><del>-       var rng = editor.dom.createRng();
-       rng.setStart(editor.dom.select('span')[0].firstChild, 2);
-       rng.setEnd(editor.dom.select('span')[0].firstChild, 2);
-       editor.selection.setRng(rng);
</del><ins>+                var rng = editor.dom.createRng();
+               rng.setStart(editor.dom.select('span')[0].firstChild, 2);
+               rng.setEnd(editor.dom.select('span')[0].firstChild, 2);
+               editor.selection.setRng(rng);
</ins><span class="cx"> 
</span><del>-       editor.dom.fire(editor.getBody(), 'mouseup');
-       Utils.type('X');
-       rng = Utils.normalizeRng(editor.selection.getRng(true));
</del><ins>+                editor.dom.fire(editor.getBody(), 'mouseup');
+               Utils.type('X');
+               rng = Utils.normalizeRng(editor.selection.getRng(true));
</ins><span class="cx"> 
</span><del>-       equal(rng.startContainer.getAttribute('data-mce-bogus'), 'true');
-       equal(rng.startContainer.nodeName, 'SPAN');
-       equal(rng.startOffset, 1);
-       equal(rng.endContainer.nodeName, 'SPAN');
-       equal(rng.endOffset, 1);
-       equal(editor.getContent(), '<p><span class="mceNonEditable">no</span>Xyes</p>');
-});
</del><ins>+                equal(rng.startContainer.getAttribute('data-mce-bogus'), 'true');
+               equal(rng.startContainer.nodeName, 'SPAN');
+               equal(rng.startOffset, 1);
+               equal(rng.endContainer.nodeName, 'SPAN');
+               equal(rng.endOffset, 1);
+               equal(editor.getContent(), '<p><span class="mceNonEditable">no</span>Xyes</p>');
+       });
+}
</ins><span class="cx"> 
</span><span class="cx"> test('type between non editable', function() {
</span><span class="cx">  editor.setContent('<p><span class="mceNonEditable">no</span><span class="mceNonEditable">no</span></p>');
</span><span class="lines">@@ -134,21 +137,24 @@
</span><span class="cx">  equal(editor.getContent(), '<p><span class="mceNonEditable">no</span>X</p>');
</span><span class="cx"> });
</span><span class="cx"> 
</span><del>-test('escape noneditable inline element (left)', function() {
-       editor.setContent('<p>no <span class="mceNonEditable">yes</span> no</p><p class="mceNonEditable">no</p>');
</del><ins>+// Ignore on IE 7, 8 this is a known bug not worth fixing
+if (!tinymce.Env.ie || tinymce.Env.ie > 8) {
+       test('escape noneditable inline element (left)', function() {
+               editor.setContent('<p>no <span class="mceNonEditable">yes</span> no</p><p class="mceNonEditable">no</p>');
</ins><span class="cx"> 
</span><del>-       var rng = editor.dom.createRng();
-       rng.selectNode(editor.dom.select('span')[0]);
-       editor.selection.setRng(rng);
</del><ins>+                var rng = editor.dom.createRng();
+               rng.selectNode(editor.dom.select('span')[0]);
+               editor.selection.setRng(rng);
</ins><span class="cx"> 
</span><del>-       Utils.type({keyCode: 37});
-       rng = Utils.normalizeRng(editor.selection.getRng(true));
</del><ins>+                Utils.type({keyCode: 37});
+               rng = Utils.normalizeRng(editor.selection.getRng(true));
</ins><span class="cx"> 
</span><del>-       equal(rng.startContainer.nodeName, 'SPAN');
-       equal(rng.startContainer.parentNode.nodeName, 'P');
-       equal(editor.dom.nodeIndex(rng.startContainer), 1);
-       equal(rng.collapsed, true);
-});
</del><ins>+                equal(rng.startContainer.nodeName, 'SPAN');
+               equal(rng.startContainer.parentNode.nodeName, 'P');
+               equal(editor.dom.nodeIndex(rng.startContainer), 1);
+               equal(rng.collapsed, true);
+       });
+}
</ins><span class="cx"> 
</span><span class="cx"> test('escape noneditable inline element (right)', function() {
</span><span class="cx">  editor.setContent('<p>no <span class="mceNonEditable">yes</span> no</p><p class="mceNonEditable">no</p>');
</span></span></pre></div>
<a id="trunktestsquniteditorpluginspastejs"></a>
<div class="modfile"><h4>Modified: trunk/tests/qunit/editor/plugins/paste.js (28137 => 28138)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/tests/qunit/editor/plugins/paste.js        2014-04-15 10:56:56 UTC (rev 28137)
+++ trunk/tests/qunit/editor/plugins/paste.js   2014-04-15 22:06:11 UTC (rev 28138)
</span><span class="lines">@@ -15,6 +15,13 @@
</span><span class="cx">                          QUnit.start();
</span><span class="cx">                  }
</span><span class="cx">          });
</span><ins>+       },
+
+       teardown: function() {
+               delete editor.settings.paste_remove_styles_if_webkit;
+               delete editor.settings.paste_retain_style_properties;
+               delete editor.settings.paste_enable_default_filters;
+               delete editor.settings.paste_data_images;
</ins><span class="cx">   }
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="lines">@@ -96,7 +103,6 @@
</span><span class="cx">  editor.selection.setRng(rng);
</span><span class="cx">  editor.execCommand('mceInsertClipboardContent', false, {content: '<p class="ListStyle" style="margin-left:36.0pt;mso-add-space:auto;text-indent:-18.0pt;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt"><span lang="EN-US" style="color:black;mso-ansi-language:EN-US"><span style="mso-list:Ignore">1.<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span lang="EN-US" style="font-family:Arial;mso-fareast-font-family:Arial;mso-bidi-font-family:Arial;color:black;mso-ansi-language:EN-US">Version 7.0</span><span lang="EN-US" style="font-family:Arial;mso-fareast-font-family:Arial;mso-bidi-font-family:Arial;color:black;mso-ansi-language:EN-US">:<o:p></o:p></span></p>'});
</span><span class="cx">  equal(editor.getContent().replace(/[\r\n]+/g, ''), '<ol><li>Version 7.0:</li></ol>');
</span><del>-       editor.settings.paste_retain_style_properties = '';
</del><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> test("Paste Word fake list before BR", function() {
</span><span class="lines">@@ -141,6 +147,30 @@
</span><span class="cx">  equal(editor.getContent().replace(/[\r\n]+/g, ''), '<table><tbody><tr><td width="307"><p>Cell 1</p></td><td width="307"><p>Cell 2</p></td></tr><tr><td width="307"><p>Cell 3</p></td><td width="307"><p>Cell 4</p></td></tr></tbody></table><p>&nbsp;</p>');
</span><span class="cx"> });
</span><span class="cx"> 
</span><ins>+test("Paste Office 365", function() {
+       var rng = editor.dom.createRng();
+
+       editor.setContent('<p>1234</p>');
+       rng.setStart(editor.getBody().firstChild.firstChild, 0);
+       rng.setEnd(editor.getBody().firstChild.firstChild, 4);
+       editor.selection.setRng(rng);
+
+       editor.execCommand('mceInsertClipboardContent', false, {content: '<div class="OutlineElement Ltr SCX195156559">Test</div>'});
+       equal(editor.getContent().replace(/[\r\n]+/g, ''), '<p>Test</p>');
+});
+
+test("Paste Google Docs", function() {
+       var rng = editor.dom.createRng();
+
+       editor.setContent('<p>1234</p>');
+       rng.setStart(editor.getBody().firstChild.firstChild, 0);
+       rng.setEnd(editor.getBody().firstChild.firstChild, 4);
+       editor.selection.setRng(rng);
+
+       editor.execCommand('mceInsertClipboardContent', false, {content: '<span id="docs-internal-guid-94e46f1a-1c88-b42b-d502-1d19da30dde7"></span><p dir="ltr>Test</p>'});
+       equal(editor.getContent().replace(/[\r\n]+/g, ''), '<p>Test</p>');
+});
+
</ins><span class="cx"> test("Paste Word without mso markings", function() {
</span><span class="cx">  editor.setContent('');
</span><span class="cx">  editor.execCommand('mceInsertClipboardContent', false, {
</span><span class="lines">@@ -197,8 +227,25 @@
</span><span class="cx">  editor.execCommand('SelectAll');
</span><span class="cx">  editor.execCommand('mceInsertClipboardContent', false, {content: '<p class="MsoNormal" style="background-color: #ff0000">Test</p>'});
</span><span class="cx">  equal(Utils.trimContent(editor.getContent().replace(/[\r\n]+/g, '')), '<p style=\"background-color: #ff0000;\">Test</p>');
</span><ins>+});
</ins><span class="cx"> 
</span><del>-       editor.settings.paste_retain_style_properties = '';
</del><ins>+test("Paste Word retain bold/italic styles to elements", function() {
+       editor.settings.paste_retain_style_properties = 'color';
+
+       editor.setContent('');
+
+       editor.execCommand('mceInsertClipboardContent', false, {
+               content: (
+                       '<p class="MsoNormal">' +
+                               '<span style="font-weight: bold">bold</span>' +
+                               '<span style="font-style: italic">italic</span>' +
+                               '<span style="font-weight: bold; font-style: italic">bold + italic</span>' +
+                               '<span style="font-weight: bold; color: red">bold + color</span>' +
+                       '</p>'
+               )
+       });
+
+       equal(editor.getContent(), '<p><strong>bold</strong><em>italic</em><strong><em>bold + italic</em></strong><strong><span style="color: red;">bold + color</span></strong></p>');
</ins><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> test("Paste part of list from IE", function() {
</span><span class="lines">@@ -217,8 +264,6 @@
</span><span class="cx">  
</span><span class="cx">  editor.execCommand('mceInsertClipboardContent', false, {content: '<p class="MsoNormal" style="color: #ff0000;">Test</p>'});
</span><span class="cx">  equal(Utils.trimContent(editor.getContent().replace(/[\r\n]+/g, '')), '<p class="MsoNormal" style="color: #ff0000;">Test</p>');
</span><del>-
-       editor.settings.paste_enable_default_filters = true;
</del><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> test('paste invalid content with spans on page', function() {
</span><span class="lines">@@ -401,3 +446,95 @@
</span><span class="cx">  editor.getBody().innerHTML = '<pre> a </pre>';
</span><span class="cx">  equal(tinymce.pasteplugin.Utils.innerText(editor.getBody().firstChild.innerHTML), ' a ');
</span><span class="cx"> });
</span><ins>+
+if (tinymce.Env.webkit) {
+       test('paste webkit remove runtime styles (color)', function() {
+               editor.setContent('');
+               editor.execCommand('mceInsertClipboardContent', false, {content: '<span style="color:red; text-indent: 10px">Test</span>'});
+               equal(editor.getContent(), '<p><span style="color: red;">Test</span></p>');
+       });
+
+       test('paste webkit remove runtime styles (background-color)', function() {
+               editor.setContent('');
+               editor.execCommand('mceInsertClipboardContent', false, {content: '<span style="background-color:red; text-indent: 10px">Test</span>'});
+               equal(editor.getContent(), '<p><span style="background-color: red;">Test</span></p>');
+       });
+
+       test('paste webkit remove runtime styles (font-size)', function() {
+               editor.setContent('');
+               editor.execCommand('mceInsertClipboardContent', false, {content: '<span style="font-size:42px; text-indent: 10px">Test</span>'});
+               equal(editor.getContent(), '<p><span style="font-size: 42px;">Test</span></p>');
+       });
+/*
+       test('paste webkit remove runtime styles (font-family)', function() {
+               editor.setContent('');
+               editor.execCommand('mceInsertClipboardContent', false, {content: '<span style="font-family:Arial; text-indent: 10px">Test</span>'});
+               equal(editor.getContent(), '<p><span style="font-family: Arial;">Test</span></p>');
+       });
+*/
+       test('paste webkit remove runtime styles (custom styles)', function() {
+               editor.settings.paste_webkit_styles = 'color font-style';
+               editor.setContent('');
+               editor.execCommand('mceInsertClipboardContent', false, {content: '<span style="color: red; font-style: italic; text-indent: 10px">Test</span>'});
+               equal(editor.getContent(), '<p><span style="color: red; font-style: italic;">Test</span></p>');
+       });
+
+       test('paste webkit remove runtime styles (all)', function() {
+               editor.settings.paste_webkit_styles = 'all';
+               editor.setContent('');
+               editor.execCommand('mceInsertClipboardContent', false, {content: '<span style="color: red; font-style: italic; text-indent: 10px">Test</span>'});
+               equal(editor.getContent(), '<p><span style=\"color: red; font-style: italic; text-indent: 10px;\">Test</span></p>');
+       });
+
+       test('paste webkit remove runtime styles (none)', function() {
+               editor.settings.paste_webkit_styles = 'none';
+               editor.setContent('');
+               editor.execCommand('mceInsertClipboardContent', false, {content: '<span style="color: red; font-style: italic; text-indent: 10px">Test</span>'});
+               equal(editor.getContent(), '<p>Test</p>');
+       });
+
+       test('paste webkit remove runtime styles (color) in the same (color) (named)', function() {
+               editor.setContent('<p style="color:red">Test</span>');
+               Utils.setSelection('p', 0, 'p', 4);
+
+               editor.execCommand('mceInsertClipboardContent', false, {
+                       content: (
+                               '<span style="color:red; text-indent: 10px">a</span>' +
+                               '<span style="color:#ff0000; text-indent: 10px">b</span>' +
+                               '<span style="color:rgb(255, 0, 0); text-indent: 10px">c</span>'
+                       )
+               });
+
+               equal(editor.getContent(), '<p style="color: red;">abc</p>');
+       });
+
+       test('paste webkit remove runtime styles (color) in the same (color) (hex)', function() {
+               editor.setContent('<p style="color:#ff0000">Test</span>');
+               Utils.setSelection('p', 0, 'p', 4);
+
+               editor.execCommand('mceInsertClipboardContent', false, {
+                       content: (
+                               '<span style="color:red; text-indent: 10px">a</span>' +
+                               '<span style="color:#ff0000; text-indent: 10px">b</span>' +
+                               '<span style="color:rgb(255, 0, 0); text-indent: 10px">c</span>'
+                       )
+               });
+
+               equal(editor.getContent(), '<p style="color: #ff0000;">abc</p>');
+       });
+
+       test('paste webkit remove runtime styles (color) in the same (color) (rgb)', function() {
+               editor.setContent('<p style="color:rgb(255, 0, 0)">Test</span>');
+               Utils.setSelection('p', 0, 'p', 4);
+
+               editor.execCommand('mceInsertClipboardContent', false, {
+                       content: (
+                               '<span style="color:red; text-indent: 10px">a</span>' +
+                               '<span style="color:#ff0000; text-indent: 10px">b</span>' +
+                               '<span style="color:rgb(255, 0, 0); text-indent: 10px">c</span>'
+                       )
+               });
+
+               equal(editor.getContent(), '<p style="color: #ff0000;">abc</p>');
+       });
+}
</ins></span></pre></div>
<a id="trunktestsquniteditortinymceAddOnManagerjs"></a>
<div class="addfile"><h4>Added: trunk/tests/qunit/editor/tinymce/AddOnManager.js (0 => 28138)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/tests/qunit/editor/tinymce/AddOnManager.js                         (rev 0)
+++ trunk/tests/qunit/editor/tinymce/AddOnManager.js    2014-04-15 22:06:11 UTC (rev 28138)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+module("tinymce.AddOnManager", {
+       teardown: function() {
+               Utils.unpatch(tinymce.dom.ScriptLoader.ScriptLoader);
+               tinymce.AddOnManager.languageLoad = true;
+               tinymce.AddOnManager.language = 'en';
+       }
+});
+
+test('requireLangPack', function() {
+       var languagePackUrl;
+
+       Utils.patch(tinymce.dom.ScriptLoader.ScriptLoader, 'add', function(origFunc, url) {
+               languagePackUrl = url;
+       });
+
+       function getLanguagePackUrl(language, languages) {
+               languagePackUrl = null;
+               tinymce.AddOnManager.language = language;
+               tinymce.AddOnManager.PluginManager.requireLangPack('plugin', languages);
+               return languagePackUrl;
+       }
+
+       tinymce.AddOnManager.PluginManager.urls.plugin = '/root';
+
+       equal(getLanguagePackUrl('sv_SE'), '/root/langs/sv_SE.js');
+       equal(getLanguagePackUrl('sv_SE', 'sv,en,us'), '/root/langs/sv.js');
+       equal(getLanguagePackUrl('sv_SE', 'sv_SE,en_US'), '/root/langs/sv_SE.js');
+       equal(getLanguagePackUrl('sv'), '/root/langs/sv.js');
+       equal(getLanguagePackUrl('sv', 'sv'), '/root/langs/sv.js');
+       equal(getLanguagePackUrl('sv', 'sv,en,us'), '/root/langs/sv.js');
+       equal(getLanguagePackUrl('sv', 'en,sv,us'), '/root/langs/sv.js');
+       equal(getLanguagePackUrl('sv', 'en,us,sv'), '/root/langs/sv.js');
+       strictEqual(getLanguagePackUrl('sv', 'en,us'), null);
+       strictEqual(getLanguagePackUrl(null, 'en,us'), null);
+       strictEqual(getLanguagePackUrl(null), null);
+
+       tinymce.AddOnManager.languageLoad = false;
+       strictEqual(getLanguagePackUrl('sv', 'sv'), null);
+});
</ins><span class="cx">Property changes on: trunk/tests/qunit/editor/tinymce/AddOnManager.js
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<ins>+native
</ins><span class="cx">\ No newline at end of property
</span><a id="trunktestsquniteditortinymceEditorjs"></a>
<div class="modfile"><h4>Modified: trunk/tests/qunit/editor/tinymce/Editor.js (28137 => 28138)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/tests/qunit/editor/tinymce/Editor.js       2014-04-15 10:56:56 UTC (rev 28137)
+++ trunk/tests/qunit/editor/tinymce/Editor.js  2014-04-15 22:06:11 UTC (rev 28138)
</span><span class="lines">@@ -8,6 +8,7 @@
</span><span class="cx">                  disable_nodechange: true,
</span><span class="cx">                  skin: false,
</span><span class="cx">                  entities: 'raw',
</span><ins>+                       indent: false,
</ins><span class="cx">                   valid_styles: {
</span><span class="cx">                          '*': 'color,font-size,font-family,background-color,font-weight,font-style,text-decoration,float,margin,margin-top,margin-right,margin-bottom,margin-left,display'
</span><span class="cx">                  },
</span><span class="lines">@@ -137,7 +138,7 @@
</span><span class="cx">          var p = editor.dom.create('p', {}, '123<table><tbody><tr><td>X</td></tr></tbody></table>456');
</span><span class="cx">          editor.dom.replace(p, editor.getBody().firstChild);
</span><span class="cx"> 
</span><del>-               equal(editor.getContent(), '<p>123</p>\n<table>\n<tbody>\n<tr>\n<td>X</td>\n</tr>\n</tbody>\n</table>\n<p>456</p>');
</del><ins>+                equal(editor.getContent(), '<p>123</p><table><tbody><tr><td>X</td></tr></tbody></table><p>456</p>');
</ins><span class="cx">   }
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="lines">@@ -187,9 +188,12 @@
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> test('custom elements', function() {
</span><del>-       expect(1);
-
</del><span class="cx">   editor.setContent('<custom1>c1</custom1><custom2>c1</custom2>');
</span><del>-       equal(editor.getContent().replace(/[\r\n]/g, ''), '<custom1>c1</custom1><p><custom2>c1</custom2></p>');
</del><ins>+        equal(editor.getContent(), '<custom1>c1</custom1><p><custom2>c1</custom2></p>');
</ins><span class="cx"> });
</span><span class="cx"> 
</span><ins>+test('Store/restore tabindex', function() {
+       editor.setContent('<span tabindex="42">abc</span>');
+       equal(editor.getContent({format:'raw'}).toLowerCase(), '<p><span data-mce-tabindex="42">abc</span></p>');
+       equal(editor.getContent(), '<p><span tabindex="42">abc</span></p>');
+});
</ins></span></pre></div>
<a id="trunktestsquniteditortinymceEditorManagerjs"></a>
<div class="addfile"><h4>Added: trunk/tests/qunit/editor/tinymce/EditorManager.js (0 => 28138)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/tests/qunit/editor/tinymce/EditorManager.js                                (rev 0)
+++ trunk/tests/qunit/editor/tinymce/EditorManager.js   2014-04-15 22:06:11 UTC (rev 28138)
</span><span class="lines">@@ -0,0 +1,72 @@
</span><ins>+module("tinymce.EditorManager", {
+       setupModule: function() {
+               QUnit.stop();
+
+               tinymce.init({
+                       selector: "textarea",
+                       add_unload_trigger: false,
+                       disable_nodechange: true,
+                       skin: false,
+                       init_instance_callback: function(ed) {
+                               window.editor = ed;
+                               QUnit.start();
+                       }
+               });
+       }
+});
+
+test('get', function() {
+       strictEqual(tinymce.get().length, 1);
+       strictEqual(tinymce.get(0), tinymce.activeEditor);
+       strictEqual(tinymce.get(1), null);
+       strictEqual(tinymce.get("noid"), null);
+       strictEqual(tinymce.get(undefined), null);
+       strictEqual(tinymce.get()[0], tinymce.activeEditor);
+       strictEqual(tinymce.get(tinymce.activeEditor.id), tinymce.activeEditor);
+});
+
+test('addI18n/translate', function() {
+       tinymce.addI18n('en', {
+               'from': 'to'
+       });
+
+       equal(tinymce.translate('from'), 'to');
+});
+
+test('triggerSave', function() {
+       var saveCount = 0;
+
+       window.editor.on('SaveContent', function() {
+               saveCount++;
+       });
+
+       tinymce.triggerSave();
+       equal(saveCount, 1);
+});
+
+test('Re-init on same id', function() {
+       tinymce.init({selector: "#" + tinymce.activeEditor.id});
+       strictEqual(tinymce.get().length, 1);
+});
+
+asyncTest('Init/remove on same id', function() {
+       var textArea = document.createElement('textarea');
+       document.getElementById('view').appendChild(textArea);
+
+       tinymce.init({
+               selector: "#view textarea",
+               init_instance_callback: function() {
+                       window.setTimeout(function() {
+                               QUnit.start();
+
+                               strictEqual(tinymce.get().length, 2);
+                               strictEqual(tinymce.get(1), tinymce.activeEditor);
+                               tinymce.remove('#' + tinymce.get(1).id);
+                               strictEqual(tinymce.get().length, 1);
+                               strictEqual(tinymce.get(0), tinymce.activeEditor);
+                       }, 0);
+               }
+       });
+
+       strictEqual(tinymce.get().length, 2);
+});
</ins><span class="cx">Property changes on: trunk/tests/qunit/editor/tinymce/EditorManager.js
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<ins>+native
</ins><span class="cx">\ No newline at end of property
</span><a id="trunktestsquniteditortinymceEnterKeyjs"></a>
<div class="modfile"><h4>Modified: trunk/tests/qunit/editor/tinymce/EnterKey.js (28137 => 28138)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/tests/qunit/editor/tinymce/EnterKey.js     2014-04-15 10:56:56 UTC (rev 28137)
+++ trunk/tests/qunit/editor/tinymce/EnterKey.js        2014-04-15 22:06:11 UTC (rev 28138)
</span><span class="lines">@@ -392,7 +392,10 @@
</span><span class="cx">          '</ol>'
</span><span class="cx">  );
</span><span class="cx"> 
</span><del>-       equal(editor.selection.getNode().nodeName, 'LI');
</del><ins>+        // Ignore on IE 7, 8 this is a known bug not worth fixing
+       if (!tinymce.Env.ie || tinymce.Env.ie > 8) {
+               equal(editor.selection.getNode().nodeName, 'LI');
+       }
</ins><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> test('Enter inside empty LI in end of OL in LI', function() {
</span><span class="lines">@@ -427,36 +430,39 @@
</span><span class="cx"> 
</span><span class="cx"> // Nested lists in OL elements
</span><span class="cx"> 
</span><del>-test('Enter before nested list', function() {
-       editor.getBody().innerHTML = Utils.trimBrsOnIE(
-               '<ol>' +
-                       '<li>a' +
-                               '<ul>' +
-                                       '<li>b</li>' +
-                                       '<li>c</li>' +
-                               '</ul>' +
-                       '</li>' +
-               '</ol>'
-       );
</del><ins>+// Ignore on IE 7, 8 this is a known bug not worth fixing
+if (!tinymce.Env.ie || tinymce.Env.ie > 8) {
+       test('Enter before nested list', function() {
+               editor.getBody().innerHTML = Utils.trimBrsOnIE(
+                       '<ol>' +
+                               '<li>a' +
+                                       '<ul>' +
+                                               '<li>b</li>' +
+                                               '<li>c</li>' +
+                                       '</ul>' +
+                               '</li>' +
+                       '</ol>'
+               );
</ins><span class="cx"> 
</span><del>-       Utils.setSelection('ol > li', 1);
-       editor.focus();
-       Utils.pressEnter();
</del><ins>+                Utils.setSelection('ol > li', 1);
+               editor.focus();
+               Utils.pressEnter();
</ins><span class="cx"> 
</span><del>-       equal(editor.getContent(),
-               '<ol>' +
-                       '<li>a</li>' +
-                       '<li>\u00a0' +
-                               '<ul>' +
-                                       '<li>b</li>' +
-                                       '<li>c</li>' +
-                               '</ul>' +
-                       '</li>' +
-               '</ol>'
-       );
</del><ins>+                equal(editor.getContent(),
+                       '<ol>' +
+                               '<li>a</li>' +
+                               '<li>\u00a0' +
+                                       '<ul>' +
+                                               '<li>b</li>' +
+                                               '<li>c</li>' +
+                                       '</ul>' +
+                               '</li>' +
+                       '</ol>'
+               );
</ins><span class="cx"> 
</span><del>-       equal(editor.selection.getNode().nodeName, 'LI');
-});
</del><ins>+                equal(editor.selection.getNode().nodeName, 'LI');
+       });
+}
</ins><span class="cx"> 
</span><span class="cx"> test('Enter inside empty LI in beginning of OL in OL', function() {
</span><span class="cx">  editor.getBody().innerHTML = Utils.trimBrsOnIE(
</span><span class="lines">@@ -561,7 +567,11 @@
</span><span class="cx">  Utils.setSelection('p', 2);
</span><span class="cx">  Utils.pressEnter();
</span><span class="cx">  equal(editor.getContent(),'<ol><li><p>ab</p></li><li><p>cd</p></li></ol>');
</span><del>-       equal(editor.selection.getNode().nodeName, 'P');
</del><ins>+
+       // Ignore on IE 7, 8 this is a known bug not worth fixing
+       if (!tinymce.Env.ie || tinymce.Env.ie > 8) {
+               equal(editor.selection.getNode().nodeName, 'P');
+       }
</ins><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> test('Enter at end of P inside LI', function() {
</span><span class="lines">@@ -918,15 +928,18 @@
</span><span class="cx">  equal(editor.getContent(),'<p>te</p><p>xt</p>');
</span><span class="cx"> });
</span><span class="cx"> 
</span><del>-test('Enter before BR between DIVs', function() {
-       editor.getBody().innerHTML = '<div>a<span>b</span>c</div><br /><div>d</div>';
-       var rng = editor.dom.createRng();
-       rng.setStartBefore(editor.dom.select('br')[0]);
-       rng.setEndBefore(editor.dom.select('br')[0]);
-       editor.selection.setRng(rng);
-       Utils.pressEnter();
-       equal(editor.getContent(),'<div>a<span>b</span>c</div><p>\u00a0</p><p>\u00a0</p><div>d</div>');
-});
</del><ins>+// Ignore on IE 7, 8 this is a known bug not worth fixing
+if (!tinymce.Env.ie || tinymce.Env.ie > 8) {
+       test('Enter before BR between DIVs', function() {
+               editor.getBody().innerHTML = '<div>a<span>b</span>c</div><br /><div>d</div>';
+               var rng = editor.dom.createRng();
+               rng.setStartBefore(editor.dom.select('br')[0]);
+               rng.setEndBefore(editor.dom.select('br')[0]);
+               editor.selection.setRng(rng);
+               Utils.pressEnter();
+               equal(editor.getContent(),'<div>a<span>b</span>c</div><p>\u00a0</p><p>\u00a0</p><div>d</div>');
+       });
+}
</ins><span class="cx"> 
</span><span class="cx"> // Only test these on modern browsers
</span><span class="cx"> if (window.getSelection) {
</span></span></pre></div>
<a id="trunktestsquniteditortinymceFormatter_applyjs"></a>
<div class="modfile"><h4>Modified: trunk/tests/qunit/editor/tinymce/Formatter_apply.js (28137 => 28138)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/tests/qunit/editor/tinymce/Formatter_apply.js      2014-04-15 10:56:56 UTC (rev 28137)
+++ trunk/tests/qunit/editor/tinymce/Formatter_apply.js 2014-04-15 22:06:11 UTC (rev 28138)
</span><span class="lines">@@ -1597,4 +1597,4 @@
</span><span class="cx">  });
</span><span class="cx">  inlineEditor.formatter.apply('format');
</span><span class="cx">  equal(inlineEditor.getContent(), '<div>a</div><p>b</p>');
</span><del>-});
</del><ins>+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunktestsquniteditortinymceFormatter_checkjs"></a>
<div class="modfile"><h4>Modified: trunk/tests/qunit/editor/tinymce/Formatter_check.js (28137 => 28138)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/tests/qunit/editor/tinymce/Formatter_check.js      2014-04-15 10:56:56 UTC (rev 28137)
+++ trunk/tests/qunit/editor/tinymce/Formatter_check.js 2014-04-15 22:06:11 UTC (rev 28138)
</span><span class="lines">@@ -228,3 +228,8 @@
</span><span class="cx">  inlineEditor.execCommand('SelectAll');
</span><span class="cx">  ok(!inlineEditor.formatter.match('div'), 'Formatter.match on div says true');
</span><span class="cx"> });
</span><ins>+
+test('Get preview css text for formats', function() {
+       ok(/font-weight\:(bold|700)/.test(editor.formatter.getCssText('bold')), 'Bold not found in preview style');
+       ok(/font-weight\:(bold|700)/.test(editor.formatter.getCssText({inline: 'b'})), 'Bold not found in preview style');
+});
</ins></span></pre></div>
<a id="trunktestsquniteditortinymceUndoManagerjs"></a>
<div class="modfile"><h4>Modified: trunk/tests/qunit/editor/tinymce/UndoManager.js (28137 => 28138)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/tests/qunit/editor/tinymce/UndoManager.js  2014-04-15 10:56:56 UTC (rev 28137)
+++ trunk/tests/qunit/editor/tinymce/UndoManager.js     2014-04-15 22:06:11 UTC (rev 28138)
</span><span class="lines">@@ -149,26 +149,167 @@
</span><span class="cx">  ok(redo.bookmark);
</span><span class="cx"> });
</span><span class="cx"> 
</span><del>-asyncTest('Undo added when typing and losing focus', function() {
-       window.focus();
</del><ins>+test('Transact', function() {
+       var count = 0;
</ins><span class="cx"> 
</span><del>-       window.setTimeout(function() {
-               start();
</del><ins>+        editor.undoManager.clear();
</ins><span class="cx"> 
</span><del>-               editor.focus();
-               editor.undoManager.clear();
-               editor.setContent("<p>some text</p>");
-               Utils.setSelection('p', 4, 'p', 9);
-               Utils.type('\b');
</del><ins>+        editor.on('BeforeAddUndo', function() {
+               count++;
+       });
</ins><span class="cx"> 
</span><del>-               // Move focus to an input element
-               var input = document.createElement('input');
-               document.getElementById('view').appendChild(input);
-               input.focus();
-               input.parentNode.removeChild(input);
</del><ins>+        editor.undoManager.transact(function() {
+               editor.undoManager.add();
+               editor.undoManager.add();
+       });
</ins><span class="cx"> 
</span><del>-               editor.execCommand('FormatBlock', false, 'h1');
-               editor.undoManager.undo();
-               equal(editor.getContent(), "<p>some</p>");
-       }, 0);
</del><ins>+        equal(count, 1);
</ins><span class="cx"> });
</span><ins>+
+test('Transact nested', function() {
+       var count = 0;
+
+       editor.undoManager.clear();
+
+       editor.on('BeforeAddUndo', function() {
+               count++;
+       });
+
+       editor.undoManager.transact(function() {
+               editor.undoManager.add();
+
+               editor.undoManager.transact(function() {
+                       editor.undoManager.add();
+               });
+       });
+
+       equal(count, 1);
+});
+
+test('Transact exception', function() {
+       var count = 0;
+
+       editor.undoManager.clear();
+
+       editor.on('BeforeAddUndo', function() {
+               count++;
+       });
+
+       throws(
+               function() {
+                       editor.undoManager.transact(function() {
+                               throw new Error("Test");
+                       });
+               },
+
+               "Test"
+       );
+
+       editor.undoManager.add();
+
+       equal(count, 1);
+});
+
+test('Exclude internal elements', function() {
+       var count = 0, lastLevel;
+
+       editor.undoManager.clear();
+       equal(count, 0);
+
+       editor.on('AddUndo', function() {
+               count++;
+       });
+
+       editor.on('BeforeAddUndo', function(e) {
+               lastLevel = e.level;
+       });
+
+       editor.getBody().innerHTML = (
+               'test' +
+               '<img src="about:blank" data-mce-selected="1" />' +
+               '<table data-mce-selected="1"><tr><td>x</td></tr></table>'
+       );
+
+       editor.undoManager.add();
+       equal(count, 1);
+       equal(Utils.cleanHtml(lastLevel.content),
+               'test' +
+               '<img src="about:blank">' +
+               '<table><tbody><tr><td>x</td></tr></tbody></table>'
+       );
+
+       editor.getBody().innerHTML = (
+               '<span data-mce-bogus="1">\u200B</span>' +
+               '<span data-mce-bogus="1">\uFEFF</span>' +
+               '<div data-mce-bogus="1"></div>' +
+               'test' +
+               '<img src="about:blank" />' +
+               '<table><tr><td>x</td></tr></table>'
+       );
+
+       editor.undoManager.add();
+       equal(count, 1);
+       equal(Utils.cleanHtml(lastLevel.content),
+               'test' +
+               '<img src="about:blank">' +
+               '<table><tbody><tr><td>x</td></tr></tbody></table>'
+       );
+});
+
+test('Undo added when typing and losing focus', function() {
+       var lastLevel;
+
+       editor.on('BeforeAddUndo', function(e) {
+               lastLevel = e.level;
+       });
+
+       editor.undoManager.clear();
+       editor.setContent("<p>some text</p>");
+       Utils.setSelection('p', 4, 'p', 9);
+       Utils.type('\b');
+
+       equal(Utils.cleanHtml(lastLevel.content), "<p>some text</p>");
+       editor.fire('blur');
+       equal(Utils.cleanHtml(lastLevel.content), "<p>some</p>");
+
+       editor.execCommand('FormatBlock', false, 'h1');
+       editor.undoManager.undo();
+       equal(editor.getContent(), "<p>some</p>");
+});
+
+test('BeforeAddUndo event', function() {
+       var lastEvt, addUndoEvt;
+
+       editor.on('BeforeAddUndo', function(e) {
+               lastEvt = e;
+       });
+
+       editor.undoManager.clear();
+       editor.setContent("<p>a</p>");
+       editor.undoManager.add();
+
+       equal(lastEvt.lastLevel, null);
+       equal(Utils.cleanHtml(lastEvt.level.content), "<p>a</p>");
+
+       editor.setContent("<p>b</p>");
+       editor.undoManager.add();
+
+       equal(Utils.cleanHtml(lastEvt.lastLevel.content), "<p>a</p>");
+       equal(Utils.cleanHtml(lastEvt.level.content), "<p>b</p>");
+
+       editor.on('BeforeAddUndo', function(e) {
+               e.preventDefault();
+       });
+
+       editor.on('AddUndo', function(e) {
+               addUndoEvt = e;
+       });
+
+       editor.setContent("<p>c</p>");
+       editor.undoManager.add(null, {data: 1});
+
+       equal(Utils.cleanHtml(lastEvt.lastLevel.content), "<p>b</p>");
+       equal(Utils.cleanHtml(lastEvt.level.content), "<p>c</p>");
+       equal(lastEvt.originalEvent.data, 1);
+       ok(!addUndoEvt, "Event level produced when it should be blocked");
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunktestsquniteditortinymcedomEventUtilsjs"></a>
<div class="modfile"><h4>Modified: trunk/tests/qunit/editor/tinymce/dom/EventUtils.js (28137 => 28138)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/tests/qunit/editor/tinymce/dom/EventUtils.js       2014-04-15 10:56:56 UTC (rev 28137)
+++ trunk/tests/qunit/editor/tinymce/dom/EventUtils.js  2014-04-15 22:06:11 UTC (rev 28138)
</span><span class="lines">@@ -328,6 +328,7 @@
</span><span class="cx">  deepEqual(result, {});
</span><span class="cx"> });
</span><span class="cx"> 
</span><ins>+/*
</ins><span class="cx"> asyncTest("focusin/focusout bind/unbind", function() {
</span><span class="cx">  var result = {};
</span><span class="cx"> 
</span><span class="lines">@@ -348,6 +349,7 @@
</span><span class="cx">          deepEqual(result, {focusin: 2, focusout: 1});
</span><span class="cx">  }, 0);
</span><span class="cx"> });
</span><ins>+*/
</ins><span class="cx"> 
</span><span class="cx"> test("bind unbind fire clean on null", function() {
</span><span class="cx">  eventUtils.bind(null, 'click', function() {});
</span></span></pre></div>
<a id="trunktestsquniteditortinymcedomSerializerjs"></a>
<div class="modfile"><h4>Modified: trunk/tests/qunit/editor/tinymce/dom/Serializer.js (28137 => 28138)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/tests/qunit/editor/tinymce/dom/Serializer.js       2014-04-15 10:56:56 UTC (rev 28137)
+++ trunk/tests/qunit/editor/tinymce/dom/Serializer.js  2014-04-15 22:06:11 UTC (rev 28138)
</span><span class="lines">@@ -490,3 +490,12 @@
</span><span class="cx">  DOM.setHTML('test', '<span class="b mce-item-X"></span>');
</span><span class="cx">  equal(ser.serialize(DOM.get('test')), '<span class="b"></span>');
</span><span class="cx"> });
</span><ins>+
+test('Restore tabindex', function() {
+       var ser = new tinymce.dom.Serializer({
+               valid_elements: 'span[tabindex]'
+       });
+
+       DOM.setHTML('test', '<span data-mce-tabindex="42"></span>');
+       equal(ser.serialize(DOM.get('test')), '<span tabindex="42"></span>');
+});
</ins></span></pre></div>
<a id="trunktestsquniteditortinymceuiControljs"></a>
<div class="modfile"><h4>Modified: trunk/tests/qunit/editor/tinymce/ui/Control.js (28137 => 28138)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/tests/qunit/editor/tinymce/ui/Control.js   2014-04-15 10:56:56 UTC (rev 28137)
+++ trunk/tests/qunit/editor/tinymce/ui/Control.js      2014-04-15 22:06:11 UTC (rev 28138)
</span><span class="lines">@@ -53,7 +53,6 @@
</span><span class="cx">          });
</span><span class="cx">  });
</span><span class="cx"> 
</span><del>-       /*
</del><span class="cx">   test("Properties", function() {
</span><span class="cx">          var ctrl, cont;
</span><span class="cx"> 
</span><span class="lines">@@ -89,11 +88,9 @@
</span><span class="cx"> 
</span><span class="cx">          // Set all states
</span><span class="cx">          ctrl = ctrl.
</span><del>-                       refresh().
-                       bind('click', function() {}).
-                       unbind().
-                       renderTo(document.getElementById('viewport')).
-                       fire("nothing").
</del><ins>+                        on('click', function() {}).
+                       off().
+                       renderTo(document.getElementById('view')).
</ins><span class="cx">                   remove();
</span><span class="cx"> 
</span><span class="cx">          // Check so that the chain worked
</span><span class="lines">@@ -102,29 +99,32 @@
</span><span class="cx"> 
</span><span class="cx">  test("Events", function() {
</span><span class="cx">          var ctrl = new tinymce.ui.Control({
</span><del>-                       handlers: {
</del><ins>+                        onMyEvent: function() {
+                               count++;
+                       },
+                       callbacks: {
</ins><span class="cx">                           handler1: function() {
</span><span class="cx">                                  count++;
</span><span class="cx">                          }
</span><span class="cx">                  }
</span><span class="cx">          }), count;
</span><span class="cx"> 
</span><del>-               ctrl.bind('MyEvent', function(target, args) {
-                       ok(target === ctrl);
-                       ok(ctrl === this);
-                       deepEqual(args, {myKey: 'myVal'});
</del><ins>+                ctrl.on('MyEvent', function(args) {
+                       equal(ctrl, args.control);
+                       equal(ctrl, this);
+                       equal(args.myKey, 'myVal');
</ins><span class="cx">           });
</span><span class="cx"> 
</span><span class="cx">          ctrl.fire('MyEvent', {myKey: 'myVal'});
</span><span class="cx"> 
</span><del>-               function countAndBreak(target, args) {
</del><ins>+                function countAndBreak() {
</ins><span class="cx">                   count++;
</span><span class="cx">                  return false;
</span><span class="cx">          }
</span><span class="cx"> 
</span><span class="cx">          // Bind two events
</span><del>-               ctrl.bind('MyEvent2', countAndBreak);
-               ctrl.bind('MyEvent2', countAndBreak);
</del><ins>+                ctrl.on('MyEvent2', countAndBreak);
+               ctrl.on('MyEvent2', countAndBreak);
</ins><span class="cx"> 
</span><span class="cx">          // Check if only one of them was called
</span><span class="cx">          count = 0;
</span><span class="lines">@@ -135,31 +135,31 @@
</span><span class="cx">          ctrl.fire('MyEvent3', {myKey: 'myVal'});
</span><span class="cx"> 
</span><span class="cx">          // Unbind all
</span><del>-               ctrl.unbind();
</del><ins>+                ctrl.off();
</ins><span class="cx">           count = 0;
</span><span class="cx">          ctrl.fire('MyEvent2', {myKey: 'myVal'});
</span><span class="cx">          equal(count, 0, 'Unbind all');
</span><span class="cx"> 
</span><span class="cx">          // Unbind by name
</span><del>-               ctrl.bind('MyEvent1', countAndBreak);
-               ctrl.bind('MyEvent2', countAndBreak);
-               ctrl.unbind('MyEvent2');
</del><ins>+                ctrl.on('MyEvent1', countAndBreak);
+               ctrl.on('MyEvent2', countAndBreak);
+               ctrl.off('MyEvent2');
</ins><span class="cx">           count = 0;
</span><span class="cx">          ctrl.fire('MyEvent1', {myKey: 'myVal'});
</span><span class="cx">          ctrl.fire('MyEvent2', {myKey: 'myVal'});
</span><span class="cx">          equal(count, 1);
</span><span class="cx"> 
</span><span class="cx">          // Unbind by name callback
</span><del>-               ctrl.bind('MyEvent1', countAndBreak);
-               ctrl.bind('MyEvent1', function() {count++;});
-               ctrl.unbind('MyEvent1', countAndBreak);
</del><ins>+                ctrl.on('MyEvent1', countAndBreak);
+               ctrl.on('MyEvent1', function() {count++;});
+               ctrl.off('MyEvent1', countAndBreak);
</ins><span class="cx">           count = 0;
</span><span class="cx">          ctrl.fire('MyEvent1', {myKey: 'myVal'});
</span><span class="cx">          equal(count, 1);
</span><span class="cx"> 
</span><span class="cx">          // Bind by named handler
</span><del>-               ctrl.unbind();
-               ctrl.bind('MyEvent', 'handler1');
</del><ins>+                ctrl.off();
+               ctrl.on('MyEvent', 'handler1');
</ins><span class="cx">           count = 0;
</span><span class="cx">          ctrl.fire('MyEvent', {myKey: 'myVal'});
</span><span class="cx">          equal(count, 1);
</span><span class="lines">@@ -168,28 +168,28 @@
</span><span class="cx">  test("hasClass,addClass,removeClass", function() {
</span><span class="cx">          var ctrl = new tinymce.ui.Control({classes: 'class1 class2 class3'});
</span><span class="cx"> 
</span><del>-               equal(ctrl.classes(), 'class1 class2 class3');
</del><ins>+                equal(ctrl.classes(), 'mce-class1 mce-class2 mce-class3');
</ins><span class="cx">           ok(ctrl.hasClass('class1'));
</span><span class="cx">          ok(ctrl.hasClass('class2'));
</span><span class="cx">          ok(ctrl.hasClass('class3'));
</span><span class="cx">          ok(!ctrl.hasClass('class4'));
</span><span class="cx"> 
</span><span class="cx">          ctrl.addClass('class4');
</span><del>-               equal(ctrl.classes(), 'class1 class2 class3 class4');
</del><ins>+                equal(ctrl.classes(), 'mce-class1 mce-class2 mce-class3 mce-class4');
</ins><span class="cx">           ok(ctrl.hasClass('class1'));
</span><span class="cx">          ok(ctrl.hasClass('class2'));
</span><span class="cx">          ok(ctrl.hasClass('class3'));
</span><span class="cx">          ok(ctrl.hasClass('class4'));
</span><span class="cx"> 
</span><span class="cx">          ctrl.removeClass('class4');
</span><del>-               equal(ctrl.classes(), 'class1 class2 class3');
</del><ins>+                equal(ctrl.classes(), 'mce-class1 mce-class2 mce-class3');
</ins><span class="cx">           ok(ctrl.hasClass('class1'));
</span><span class="cx">          ok(ctrl.hasClass('class2'));
</span><span class="cx">          ok(ctrl.hasClass('class3'));
</span><span class="cx">          ok(!ctrl.hasClass('class4'));
</span><span class="cx"> 
</span><span class="cx">          ctrl.removeClass('class3').removeClass('class2');
</span><del>-               equal(ctrl.classes(), 'class1');
</del><ins>+                equal(ctrl.classes(), 'mce-class1');
</ins><span class="cx">           ok(ctrl.hasClass('class1'));
</span><span class="cx">          ok(!ctrl.hasClass('class2'));
</span><span class="cx">          ok(!ctrl.hasClass('class3'));
</span><span class="lines">@@ -200,5 +200,17 @@
</span><span class="cx">          ok(!ctrl.hasClass('class2'));
</span><span class="cx">          ok(!ctrl.hasClass('class3'));
</span><span class="cx">  });
</span><del>-       */
</del><ins>+
+       test("encode", function() {
+               tinymce.i18n.add('en', {'old': '"new"'});
+               equal(new tinymce.ui.Control({}).encode('<>"&'), '&#60;&#62;&#34;&#38;');
+               equal(new tinymce.ui.Control({}).encode('old'), '&#34;new&#34;');
+               equal(new tinymce.ui.Control({}).encode('old', false), 'old');
+       });
+
+       test("translate", function() {
+               tinymce.i18n.add('en', {'old': 'new'});
+               equal(new tinymce.ui.Control({}).translate('old'), 'new');
+               equal(new tinymce.ui.Control({}).translate('old2'), 'old2');
+       });
</ins><span class="cx"> })();
</span></span></pre>
</div>
</div>

</body>
</html>