Make WordPress Core

Changeset 40399 for trunk


Ignore:
Timestamp:
04/09/2017 11:10:15 PM (9 years ago)
Author:
azaozz
Message:

TinyMCE: update the tests for version 4.5.6. Remove default plugins tests, it is quite pointless to keep repeating them at this point.

See #40305.

Location:
trunk/tests/qunit/editor
Files:
15 added
1 deleted
27 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/qunit/editor/index.html

    r38773 r40399  
    4141        <script src="tinymce/caret/LineWalker.js"></script>
    4242
     43        <!-- tinymce.content.* -->
     44        <script src="tinymce/content/LinkTargets.js"></script>
     45
    4346        <!-- tinymce.geom.* -->
    4447        <script src="tinymce/geom/Rect.js"></script>
     
    5255        <!-- tinymce.fmt.* -->
    5356        <script src="tinymce/fmt/Hooks.js"></script>
     57        <script src="tinymce/fmt/Preview.js"></script>
     58        <script src="tinymce/fmt/FontInfo.js"></script>
    5459
    5560        <!-- tinymce.text.* -->
     
    8792        <script src="tinymce/ui/ColorButton.js"></script>
    8893        <script src="tinymce/ui/Control.js"></script>
     94<!--<script src="tinymce/ui/FilePicker.js"></script>-->
    8995        <script src="tinymce/ui/FitLayout.js"></script>
    9096        <script src="tinymce/ui/FlexLayout.js"></script>
     
    97103        <script src="tinymce/ui/TextBox.js"></script>
    98104        <script src="tinymce/ui/Window.js"></script>
     105
     106        <!-- tinymce.undo.* -->
     107        <script src="tinymce/undo/Diff.js"></script>
     108        <script src="tinymce/undo/Fragments.js"></script>
     109        <script src="tinymce/undo/Levels.js"></script>
     110        <script src="tinymce/undo/ForcedRootBlock.js"></script>
    99111
    100112        <!-- tinymce.util.* -->
     
    116128        <!-- tinymce.* -->
    117129        <script src="tinymce/AddOnManager.js"></script>
     130        <script src="tinymce/options.js"></script>
    118131        <script src="tinymce/Editor.js"></script>
    119132        <script src="tinymce/Editor_rtl.js"></script>
     133        <script src="tinymce/EditorCustomTheme.js"></script>
    120134        <script src="tinymce/EditorUpload.js"></script>
    121135        <script src="tinymce/EditorCommands.js"></script>
    122136        <script src="tinymce/EditorManager.js"></script>
    123137        <script src="tinymce/EnterKey.js"></script>
     138        <script src="tinymce/FocusManager.js"></script>
    124139        <script src="tinymce/ForceBlocks.js"></script>
    125140        <script src="tinymce/Formatter_apply.js"></script>
     
    131146        <script src="tinymce/WindowManager.js"></script>
    132147        <script src="tinymce/InsertContent.js"></script>
     148        <script src="tinymce/InsertContentForcedRootFalse.js"></script>
    133149        <script src="tinymce/InsertList.js"></script>
     150        <script src="tinymce/NotificationManager.js"></script>
    134151
    135152        <!-- tinymce.plugins.* -->
    136 <!--<script src="plugins/autolink.js"></script>-->
    137         <script src="plugins/charmap.js"></script>
    138 <!--<script src="plugins/autosave.js"></script>-->
    139 <!--<script src="plugins/fullpage.js"></script>-->
    140         <script src="plugins/image.js"></script>
    141 <!--<script src="plugins/importcss.js"></script>-->
    142 <!--<script src="plugins/jquery_plugin.js"></script>-->
    143 <!--<script src="plugins/jquery_initialization.js"></script>-->
    144 <!--<script src="plugins/legacyoutput.js"></script>-->
    145 <!--<script src="plugins/link.js"></script>-->
    146         <script src="plugins/lists.js"></script>
    147         <script src="plugins/media.js"></script>
    148 <!--<script src="plugins/noneditable.js"></script> -->
    149         <script src="plugins/paste.js"></script>
    150         <script src="plugins/paste_images.js"></script>
    151         <script src="plugins/paste_smart.js"></script>
    152 <!--<script src="plugins/searchreplace.js"></script>-->
    153 <!--<script src="plugins/spellchecker.js"></script>-->
    154 <!--<script src="plugins/table.js"></script>-->
    155 <!--<script src="plugins/textpattern.js"></script>-->
    156 <!--<script src="plugins/wordcount.js"></script>-->
     153
    157154</body>
    158155</html>
  • trunk/tests/qunit/editor/js/init.js

    r29203 r40399  
    55        QUnit.config.hidepassed = true;
    66
    7         window.editor = window.inlineEditor = null; 
     7        window.editor = window.inlineEditor = null;
    88
    99        var oldModule = module;
     
    2424        // Sauce labs
    2525        QUnit.testStart(function(testDetails) {
    26                 QUnit.log = function(details) {
     26                QUnit.log(function(details) {
    2727                        if (!details.result) {
    2828                                details.name = currentModule + ':' + testDetails.name;
    2929                                log.push(details);
    3030                        }
    31                 };
     31                });
    3232        });
    3333
  • trunk/tests/qunit/editor/js/qunit/qunit.js

    r27679 r40399  
    570570if ( !defined.document || document.readyState === "complete" ) {
    571571        config.autorun = true;
     572}
     573
     574if (document.location.search.indexOf('bedrock') !== -1) {
     575        config.autorun = false;
     576        config.autostart = false;
    572577}
    573578
  • trunk/tests/qunit/editor/js/tinymce_loader.js

    r36352 r40399  
    55                        'fullscreen wordpress wpautoresize wpeditimage wpgallery wplink wpdialogs wpview';
    66
     7var $ = window.jQuery;
     8
    79getUserSetting = setUserSetting = function() {}
  • trunk/tests/qunit/editor/tinymce/Editor.js

    r38773 r40399  
    493493});
    494494
     495test('Treat some paragraphs as empty contents', function() {
     496        editor.setContent('<p><br /></p>');
     497        equal(editor.getContent(), '');
     498
     499        editor.setContent('<p>\u00a0</p>');
     500        equal(editor.getContent(), '');
     501});
     502
    495503test('kamer word bounderies', function() {
    496504        editor.setContent('<p>!\u200b!\u200b!</p>');
    497505        equal(editor.getContent(), '<p>!\u200b!\u200b!</p>');
    498506});
     507
     508test('Padd empty elements with br', function() {
     509        editor.settings.padd_empty_with_br = true;
     510        editor.setContent('<p>a</p><p></p>');
     511        equal(editor.getContent(), '<p>a</p><p><br /></p>');
     512        delete editor.settings.padd_empty_with_br;
     513});
     514
     515test('Padd empty elements with br on insert at caret', function() {
     516        editor.settings.padd_empty_with_br = true;
     517        editor.setContent('<p>a</p>');
     518        Utils.setSelection('p', 1);
     519        editor.insertContent('<p>b</p><p></p>');
     520        equal(editor.getContent(), '<p>a</p><p>b</p><p><br /></p>');
     521        delete editor.settings.padd_empty_with_br;
     522});
     523
     524test('Preserve whitespace pre elements', function() {
     525        editor.setContent('<pre> </pre>');
     526        equal(editor.getContent(), '<pre> </pre>');
     527});
  • trunk/tests/qunit/editor/tinymce/EditorCommands.js

    r38034 r40399  
    751751});
    752752
     753test('unlink - unselected a[href] with childNodes', function() {
     754        editor.setContent('<p><a href="test"><strong><em>test</em></strong></a></p>');
     755        Utils.setSelection('em', 0);
     756        editor.execCommand('unlink');
     757        equal(editor.getContent(), '<p><strong><em>test</em></strong></p>');
     758});
     759
    753760test('subscript/superscript', function() {
    754761        expect(4);
     
    802809        editor.execCommand('Outdent');
    803810        equal(editor.getContent(), '<p>test 123</p>');
     811});
     812
     813test('indent/outdent table always uses margin', function () {
     814        expect(4);
     815
     816        editor.setContent('<table><tbody><tr><td>test</td></tr></tbody></table>');
     817        editor.execCommand('SelectAll');
     818        editor.execCommand('Indent');
     819        equal(editor.getContent(), '<table style="margin-left: 30px;"><tbody><tr><td>test</td></tr></tbody></table>');
     820
     821        editor.setContent('<table><tbody><tr><td>test</td></tr></tbody></table>');
     822        editor.execCommand('SelectAll');
     823        editor.execCommand('Indent');
     824        editor.execCommand('Indent');
     825        equal(editor.getContent(), '<table style="margin-left: 60px;"><tbody><tr><td>test</td></tr></tbody></table>');
     826
     827        editor.setContent('<table><tbody><tr><td>test</td></tr></tbody></table>');
     828        editor.execCommand('SelectAll');
     829        editor.execCommand('Indent');
     830        editor.execCommand('Indent');
     831        editor.execCommand('Outdent');
     832        equal(editor.getContent(), '<table style="margin-left: 30px;"><tbody><tr><td>test</td></tr></tbody></table>');
     833
     834        editor.setContent('<table><tbody><tr><td>test</td></tr></tbody></table>');
     835        editor.execCommand('SelectAll');
     836        editor.execCommand('Outdent');
     837        equal(editor.getContent(), '<table><tbody><tr><td>test</td></tr></tbody></table>');
    804838});
    805839
     
    827861        equal(editor.getContent(), '<p>dfn tag code tag samp tag kbd tag var tag cite tag mark tag q tag</p>');
    828862});
     863
     864if (tinymce.Env.ceFalse) {
     865        test('SelectAll', function() {
     866                editor.setContent('<p>a</p><div contenteditable="false"><div contenteditable="true">b</div><p>c</p>');
     867                Utils.setSelection('div div', 0);
     868                editor.execCommand('SelectAll');
     869                equal(editor.selection.getStart().nodeName, 'DIV');
     870                equal(editor.selection.getEnd().nodeName, 'DIV');
     871                equal(editor.selection.isCollapsed(), false);
     872        });
     873}
    829874
    830875test('InsertLineBreak', function() {
  • trunk/tests/qunit/editor/tinymce/EditorManager.js

    r38034 r40399  
    9999
    100100asyncTest('Init editor async with proper editors state', function() {
    101         var unloadTheme = function(name) {
    102                 var url = tinymce.baseURI.toAbsolute('themes/' + name + '/theme.js');
     101        var unloadUrl = function (url) {
    103102                tinymce.dom.ScriptLoader.ScriptLoader.remove(url);
    104103                tinymce.ThemeManager.remove(name);
     104        };
     105
     106        var unloadTheme = function(name) {
     107                unloadUrl(tinymce.baseURI.toAbsolute('themes/' + name + '/theme.min.js'));
     108                unloadUrl(tinymce.baseURI.toAbsolute('themes/' + name + '/theme.js'));
    105109        };
    106110
     
    142146                        "plugina": "//domain/plugina.js",
    143147                        "pluginb": "//domain/pluginb.js"
     148                },
     149                plugin_base_urls: {
     150                        testplugin: 'http://custom.ephox.com/dir/testplugin'
    144151                }
    145152        });
     
    149156        strictEqual(tinymce.suffix, "x");
    150157        strictEqual(new tinymce.Editor('ed1', {}, tinymce).settings.test, 42);
     158        strictEqual(tinymce.PluginManager.urls.testplugin, 'http://custom.ephox.com/dir/testplugin');
    151159
    152160        deepEqual(new tinymce.Editor('ed2', {
     
    154162                        "plugina": "//domain/plugina2.js",
    155163                        "pluginc": "//domain/pluginc.js"
     164                },
     165                plugin_base_urls: {
     166                        testplugin: 'http://custom.ephox.com/dir/testplugin'
    156167                }
    157168        }, tinymce).settings.external_plugins, {
  • trunk/tests/qunit/editor/tinymce/EditorUpload.js

    r38034 r40399  
    236236                        if (callCount == 2) {
    237237                                QUnit.start();
    238                                 equal(uploadCount, 1, 'Should only be one upload.');
     238                                // This is in exact since the status of the image can be pending or failed meaing it should try again
     239                                ok(uploadCount >= 1, 'Should at least be one.');
    239240                        }
    240241
  • trunk/tests/qunit/editor/tinymce/EnterKey.js

    r37000 r40399  
    10991099        });
    11001100}
     1101
     1102if (tinymce.Env.ceFalse) {
     1103        test('Enter before cE=false div', function() {
     1104                editor.getBody().innerHTML = '<div contenteditable="false">x</div>';
     1105                editor.selection.select(editor.dom.select('div')[0]);
     1106                editor.selection.collapse(true);
     1107                Utils.pressEnter();
     1108                equal(Utils.cleanHtml(editor.getBody().innerHTML), '<p><br data-mce-bogus="1"></p><div contenteditable="false">x</div>');
     1109                equal(editor.selection.getNode().nodeName, 'P');
     1110        });
     1111
     1112        test('Enter after cE=false div', function() {
     1113                editor.getBody().innerHTML = '<div contenteditable="false">x</div>';
     1114                editor.selection.select(editor.dom.select('div')[0]);
     1115                editor.selection.collapse(false);
     1116                Utils.pressEnter();
     1117                equal(Utils.cleanHtml(editor.getBody().innerHTML), '<div contenteditable="false">x</div><p><br data-mce-bogus="1"></p>');
     1118                equal(editor.selection.getNode().nodeName, 'P');
     1119        });
     1120}
     1121
  • trunk/tests/qunit/editor/tinymce/Formatter_apply.js

    r38773 r40399  
    11module("tinymce.Formatter - Apply", {
    22        setupModule: function() {
    3                 document.getElementById('view').innerHTML = '<textarea id="elm1"></textarea><div id="elm2"></div>';
     3                document.getElementById('view').innerHTML = '<textarea id="elm1"></textarea><div id="elm2"></div><textarea id="elm3"></textarea>';
    44                QUnit.stop();
    55
     
    1919                        },
    2020                        init_instance_callback: function(ed) {
     21                                QUnit.start();
    2122                                window.editor = ed;
    22 
    23                                 if (inlineEditor) {
    24                                         QUnit.start();
    25                                 }
    26                         }
    27                 });
    28 
    29                 tinymce.init({
    30                         selector: "#elm2",
    31                         inline: true,
    32                         add_unload_trigger: false,
    33                         skin: false,
    34                         indent: false,
    35                         convert_fonts_to_spans: false,
    36                         disable_nodechange: true,
    37                         entities: 'raw',
    38                         valid_styles: {
    39                                 '*': 'color,font-size,font-family,background-color,font-weight,font-style,text-decoration,float,margin,margin-top,margin-right,margin-bottom,margin-left,display,text-align'
    40                         },
    41                         init_instance_callback: function(ed) {
    42                                 window.inlineEditor = ed;
    43 
    44                                 if (editor) {
    45                                         QUnit.start();
    46                                 }
    4723                        }
    4824                });
     
    12901266        editor.formatter.apply('format');
    12911267        equal(editor.getContent(), '<p><b>abc</b></p>');
     1268});
     1269
     1270test('Caret format inside non-ascii single block word', function() {
     1271        editor.setContent('<p>noël</p>');
     1272        editor.formatter.register('format', {
     1273                inline: 'b'
     1274        });
     1275        Utils.setSelection('p', 2, 'p', 2);
     1276        editor.formatter.apply('format');
     1277        equal(editor.getContent(), '<p><b>noël</b></p>');
    12921278});
    12931279
     
    16801666});
    16811667
    1682 test('Bug #6518 - Apply div blocks to inline editor paragraph', function() {
    1683         inlineEditor.setContent('<p>a</p><p>b</p>');
    1684         inlineEditor.selection.select(inlineEditor.getBody().firstChild, true);
    1685         inlineEditor.selection.collapse(true);
    1686         inlineEditor.formatter.register('format', {
    1687                 block: 'div'
    1688         });
    1689         inlineEditor.formatter.apply('format');
    1690         equal(inlineEditor.getContent(), '<div>a</div><p>b</p>');
     1668asyncTest('Bug #6518 - Apply div blocks to inline editor paragraph', function() {
     1669        tinymce.init({
     1670                selector: "#elm2",
     1671                inline: true,
     1672                add_unload_trigger: false,
     1673                skin: false,
     1674                indent: false,
     1675                convert_fonts_to_spans: false,
     1676                disable_nodechange: true,
     1677                entities: 'raw',
     1678                valid_styles: {
     1679                        '*': 'color,font-size,font-family,background-color,font-weight,font-style,text-decoration,float,margin,margin-top,margin-right,margin-bottom,margin-left,display,text-align'
     1680                },
     1681                init_instance_callback: function(ed) {
     1682            QUnit.start();
     1683
     1684                        ed.setContent('<p>a</p><p>b</p>');
     1685                        ed.selection.select(ed.getBody().firstChild, true);
     1686                        ed.selection.collapse(true);
     1687                        ed.formatter.register('format', {
     1688                                block: 'div'
     1689                        });
     1690                        ed.formatter.apply('format');
     1691                        equal(ed.getContent(), '<div>a</div><p>b</p>');
     1692                }
     1693        });
    16911694});
    16921695
    16931696asyncTest('Bug #7412 - valid_styles affects the Bold and Italic buttons, although it shouldn\'t', function() {
    1694     tinymce.remove();
    1695 
    1696     document.getElementById('view').innerHTML = '<textarea id="elm1"></textarea>';
    1697 
    16981697    tinymce.init({
    1699         selector: "#elm1",
     1698        selector: "#elm3",
    17001699        add_unload_trigger: false,
    17011700        valid_styles: {
     
    17031702        },
    17041703        init_instance_callback: function(ed) {
    1705             window.editor = ed;
    17061704            QUnit.start();
    17071705
    1708             editor.getBody().innerHTML = '<p>1 <span style="text-decoration: underline;">1234</span> 1</p>';
    1709             var rng = editor.dom.createRng();
    1710             rng.setStart(editor.dom.select('span')[0], 0);
    1711             rng.setEnd(editor.dom.select('span')[0], 1);
    1712             editor.selection.setRng(rng);
    1713             editor.formatter.toggle('bold');
    1714             equal(getContent(), '<p>1 <strong><span style="text-decoration: underline;">1234</span></strong> 1</p>');
     1706            ed.getBody().innerHTML = '<p>1 <span style="text-decoration: underline;">1234</span> 1</p>';
     1707            var rng = ed.dom.createRng();
     1708            rng.setStart(ed.dom.select('span')[0], 0);
     1709            rng.setEnd(ed.dom.select('span')[0], 1);
     1710            ed.selection.setRng(rng);
     1711            ed.formatter.toggle('bold');
     1712            equal(ed.getContent(), '<p>1 <strong><span style="text-decoration: underline;">1234</span></strong> 1</p>');
    17151713        }
    17161714    });
     
    17221720        Utils.setSelection('#a', 0, '#b', 0);
    17231721        editor.execCommand('formatBlock', false, 'h1');
    1724         equal(getContent(), '<h1 id="a">one</h1>\n<div id="b">two</div>');
     1722        equal(getContent(), '<h1 id="a">one</h1><div id="b">two</div>');
    17251723});
    17261724
    17271725test('Format selection over fragments', function(){
    1728         editor.setContent("<strong>a</strong>bc<em>d</em>");
     1726        editor.setContent("<p><strong>a</strong>bc<em>d</em></p>");
    17291727        Utils.setSelection('strong', 1, 'em', 0);
    17301728        editor.formatter.apply('underline');
    17311729        equal(getContent(), '<p><strong>a</strong><span style="text-decoration: underline;">bc</span><em>d</em></p>');
    17321730});
     1731
     1732test("Wrapper with fontSize should retain priority within a branch of nested inline format wrappers", function() {
     1733        editor.setContent("<p>abc</p>");
     1734        Utils.setSelection('p', 0, 'p', 3);
     1735
     1736        editor.formatter.apply('fontsize', {value: '18px'});
     1737        editor.formatter.apply('bold');
     1738        editor.formatter.apply('underline');
     1739        editor.formatter.apply('forecolor', {value: '#ff0000'});
     1740
     1741    equal(getContent(), '<p><span style="color: #ff0000; font-size: 18px; text-decoration: underline;"><strong>abc</strong></span></p>');
     1742});
     1743
     1744test("Child wrapper having the same format as the immediate parent, shouldn't be removed if it also has other formats merged", function() {
     1745        editor.getBody().innerHTML = '<p><span style="font-family: verdana;">a <span style="color: #ff0000;">b</span>c</span></p>';
     1746        Utils.setSelection('span span', 0, 'span span', 1);
     1747        editor.formatter.apply('fontname', {value: "verdana"});
     1748        equal(getContent(), '<p><span style="font-family: verdana;">a <span style="color: #ff0000;">b</span>c</span></p>');
     1749});
     1750
     1751test("When format with backgroundColor is applied, all the nested childNodes having fontSize should receive backgroundColor as well", function() {
     1752        editor.getBody().innerHTML = '<p>a <span style="font-size: 36pt;">b</span> c</p>';
     1753        editor.selection.select(editor.dom.select('p')[0]);
     1754
     1755        editor.formatter.apply('hilitecolor', {value: "#ff0000"});
     1756        equal(getContent(), '<p><span style="background-color: #ff0000;">a <span style="font-size: 36pt; background-color: #ff0000;">b</span> c</span></p>');
     1757
     1758        editor.formatter.remove('hilitecolor', {value: "#ff0000"});
     1759        equal(getContent(), '<p>a <span style="font-size: 36pt;">b</span> c</p>');
     1760});
     1761
     1762test("TINY-782: Can't apply sub/sup to word on own line with large font", function() {
     1763        editor.getBody().innerHTML = '<p><span style="font-size: 18px;">abc</p>';
     1764        Utils.setSelection('span', 0, 'span', 3);
     1765        editor.formatter.apply('superscript');
     1766        equal(getContent(), '<p><span style="font-size: 18px;"><sup>abc</sup></span></p>');
     1767});
     1768
     1769test("TINY-671: Background color on nested font size bug", function() {
     1770        editor.getBody().innerHTML = '<p><strong><span style="font-size: 18px;">abc</span></strong></p>';
     1771        Utils.setSelection('span', 0, 'span', 3);
     1772        editor.formatter.apply('hilitecolor', {value: '#ff0000'});
     1773        equal(getContent(), '<p><span style="font-size: 18px; background-color: #ff0000;"><strong>abc</strong></span></p>');
     1774});
     1775
     1776test("TINY-865: Font size removed when changing background color", function() {
     1777        editor.getBody().innerHTML = '<p><span style="background-color: #ffff00;"><span style="font-size: 8pt;">a</span> <span style="font-size: 36pt;">b</span> <span style="font-size: 8pt;">c</span></span></p>';
     1778        Utils.setSelection('span span:nth-child(2)', 0, 'span span:nth-child(2)', 1);
     1779        editor.formatter.apply('hilitecolor', {value: '#ff0000'});
     1780    equal(getContent(), '<p><span style="background-color: #ffff00;"><span style="font-size: 8pt;">a</span> <span style="font-size: 36pt; background-color: #ff0000;">b</span> <span style="font-size: 8pt;">c</span></span></p>');
     1781});
     1782
     1783test("TINY-935: Text color, then size, then change color wraps span doesn't change color", function() {
     1784    editor.getBody().innerHTML = '<p><span style="color: #00ff00; font-size: 14pt;">text</span></p>';
     1785    Utils.setSelection('span', 0, 'span', 4);
     1786    editor.formatter.apply('forecolor', {value: '#ff0000'});
     1787    equal(getContent(), '<p><span style="color: #ff0000; font-size: 14pt;">text</span></p>');
     1788});
     1789
     1790test("GH-3519: Font family selection does not work after changing font size", function() {
     1791    editor.getBody().innerHTML = '<p><span style="font-size: 14pt; font-family: \'comic sans ms\', sans-serif;">text</span></p>';
     1792    Utils.setSelection('span', 0, 'span', 4);
     1793    editor.formatter.apply('fontname', {value: "verdana"});
     1794    equal(getContent(), '<p><span style="font-size: 14pt; font-family: verdana;">text</span></p>');
     1795});
  • trunk/tests/qunit/editor/tinymce/Formatter_check.js

    r36352 r40399  
    229229        ok(!inlineEditor.formatter.match('div'), 'Formatter.match on div says true');
    230230});
    231 
    232 test('Get preview css text for formats', function() {
    233         ok(/font-weight\:(bold|700)/.test(editor.formatter.getCssText('bold')), 'Bold not found in preview style');
    234         ok(/font-weight\:(bold|700)/.test(editor.formatter.getCssText({inline: 'b'})), 'Bold not found in preview style');
    235 });
  • trunk/tests/qunit/editor/tinymce/SelectionOverrides.js

    r38773 r40399  
    4848        function assertCaretInCaretBlockContainer() {
    4949                var beforeRng = editor.selection.getRng();
    50                 equal(CaretContainer.isCaretContainerBlock(beforeRng.startContainer.parentNode), true, 'Not in caret block container.');
     50                equal(CaretContainer.isCaretContainerBlock(beforeRng.startContainer), true, 'Not in caret block container.');
    5151        }
    5252
     
    225225                equal(editor.getContent(), '<p contenteditable="false">1</p><p contenteditable="false">2</p>');
    226226                assertCaretInCaretBlockContainer();
    227                 equal(rng.startContainer.parentNode.previousSibling, editor.dom.select('p')[0]);
     227                equal(rng.startContainer.previousSibling, editor.dom.select('p')[0]);
    228228        });
    229229
     
    264264                equal(editor.getContent(), '<p contenteditable="false">1</p><p contenteditable="false">2</p>');
    265265                assertCaretInCaretBlockContainer();
    266                 equal(rng.startContainer.parentNode.nextSibling, editor.dom.select('p')[2]);
     266                equal(rng.startContainer.nextSibling, editor.dom.select('p')[2]);
    267267        });
    268268
     
    329329                equal(editor.selection.getNode().nodeName !== 'P', true);
    330330        });
     331
     332        test('offscreen copy of cE=false block remains offscreen', function() {
     333                if (tinymce.isIE || tinymce.isGecko || tinymce.isOpera) {
     334                        editor.setContent(
     335                                '<table contenteditable="false" style="width: 100%; table-layout: fixed">' +
     336                                '<tbody><tr><td>1</td><td>2</td></tr></tbody>' +
     337                                '</table>'
     338                        );
     339
     340                        editor.selection.select(editor.dom.select('table')[0]);
     341                        var offscreenSelection = editor.dom.select('.mce-offscreen-selection')[0];
     342
     343                        ok(offscreenSelection.offsetLeft !== undefined, 'The offscreen selection\'s left border is undefined');
     344                        ok(offscreenSelection.offsetLeft < 0, 'The offscreen selection\'s left border is onscreen');
     345                        ok(offscreenSelection.offsetWidth + offscreenSelection.offsetLeft < 0,
     346                                'The cE=false offscreen selection is visible on-screen. Right edge: ' +
     347                                offscreenSelection.offsetLeft + '+' + offscreenSelection.offsetWidth + '=' +
     348                                (offscreenSelection.offsetLeft + offscreenSelection.offsetWidth) + 'px'
     349                        );
     350                } else {
     351                        // Chrome and Safari behave correctly, and PhantomJS also declares itself as WebKit but does not
     352                        // put the off-screen selection off-screen, so fails the above tests. However, it has no visible UI,
     353                        // so everything is off-screen anyway :-)
     354                        ok(true, 'Not a tested browser - Chrome & Safari work, PhantomJS does not put the selection off screen');
     355                }
     356        });
    331357});
  • trunk/tests/qunit/editor/tinymce/UndoManager.js

    r38773 r40399  
    9797        ok(editor.undoManager.typing);
    9898
    99         editor.dom.fire(editor.getBody(), 'keyup', {keyCode: 13});
     99        editor.dom.fire(editor.getBody(), 'keydown', {keyCode: 13});
    100100        ok(!editor.undoManager.typing);
    101101
     
    452452        ok(editor.isDirty(), "Dirty state should be true");
    453453});
     454
     455test('ExecCommand while typing should produce undo level', function() {
     456        editor.undoManager.clear();
     457        editor.setDirty(false);
     458        editor.setContent('<p>a</p>');
     459        Utils.setSelection('p', 1);
     460
     461        equal(editor.undoManager.typing, false);
     462        Utils.type({keyCode: 66, charCode: 66});
     463        equal(editor.undoManager.typing, true);
     464        equal(editor.getContent(), '<p>aB</p>');
     465        editor.execCommand('mceInsertContent', false, 'C');
     466        equal(editor.undoManager.typing, false);
     467        equal(editor.undoManager.data.length, 3);
     468        equal(editor.undoManager.data[0].content, '<p>a</p>');
     469        equal(editor.undoManager.data[1].content, '<p>aB</p>');
     470        equal(editor.undoManager.data[2].content, '<p>aBC</p>');
     471});
     472
     473test('transact while typing should produce undo level', function() {
     474        editor.undoManager.clear();
     475        editor.setDirty(false);
     476        editor.setContent('<p>a</p>');
     477        Utils.setSelection('p', 1);
     478
     479        equal(editor.undoManager.typing, false);
     480        Utils.type({keyCode: 66, charCode: 66});
     481        equal(editor.undoManager.typing, true);
     482        equal(editor.getContent(), '<p>aB</p>');
     483        editor.undoManager.transact(function () {
     484                editor.getBody().firstChild.firstChild.data = 'aBC';
     485        });
     486        equal(editor.undoManager.typing, false);
     487        equal(editor.undoManager.data.length, 3);
     488        equal(editor.undoManager.data[0].content, '<p>a</p>');
     489        equal(editor.undoManager.data[1].content, '<p>aB</p>');
     490        equal(editor.undoManager.data[2].content, '<p>aBC</p>');
     491});
  • trunk/tests/qunit/editor/tinymce/caret/CaretContainer.js

    r38773 r40399  
    119119                equal(CaretContainer.endsWithCaretContainer(getRoot().firstChild), true);
    120120        });
     121
     122        test('hasContent', function() {
     123                setViewHtml('<span contentEditable="false">1</span>');
     124                var caretContainerBlock = CaretContainer.insertBlock('p', getRoot().firstChild, true);
     125                equal(CaretContainer.hasContent(caretContainerBlock), false);
     126                caretContainerBlock.insertBefore(document.createTextNode('a'), caretContainerBlock.firstChild);
     127                equal(CaretContainer.hasContent(caretContainerBlock), true);
     128        });
     129
     130        test('showCaretContainerBlock', function() {
     131                setViewHtml('<span contentEditable="false">1</span>');
     132                var caretContainerBlock = CaretContainer.insertBlock('p', getRoot().firstChild, true);
     133                caretContainerBlock.insertBefore(document.createTextNode('a'), caretContainerBlock.firstChild);
     134                CaretContainer.showCaretContainerBlock(caretContainerBlock);
     135                equal(caretContainerBlock.outerHTML, '<p>a</p>');
     136        });
    121137});
  • trunk/tests/qunit/editor/tinymce/caret/FakeCaret.js

    r36352 r40399  
    3535                equal($fakeCaretElm[0].nodeName, 'P');
    3636                equal($fakeCaretElm.attr('data-mce-caret'), 'before');
    37                 Utils.assertRange(rng, Utils.createRange($fakeCaretElm[0].firstChild, 0, $fakeCaretElm[0].firstChild, 1));
     37                Utils.assertRange(rng, Utils.createRange($fakeCaretElm[0], 0, $fakeCaretElm[0], 0));
    3838
    3939                fakeCaret.hide();
     
    5151                equal($fakeCaretElm[1].nodeName, 'P');
    5252                equal($fakeCaretElm.eq(1).attr('data-mce-caret'), 'after');
    53                 Utils.assertRange(rng, Utils.createRange($fakeCaretElm[1].firstChild, 0, $fakeCaretElm[1].firstChild, 1));
     53                Utils.assertRange(rng, Utils.createRange($fakeCaretElm[1], 0, $fakeCaretElm[1], 0));
    5454
    5555                fakeCaret.hide();
  • trunk/tests/qunit/editor/tinymce/dom/DOMUtils.js

    r29994 r40399  
    3636                        'border: 1pt none black;'
    3737                );
    38                
     38
    3939                equal(
    4040                        dom.serializeStyle(dom.parseStyle('border-width: 1pt 4pt 2pt 3pt; border-style: solid dashed dotted none; border-color: black red green blue;')),
     
    340340        });
    341341
     342        var eqNodeName = function(name) {
     343                return function (n) {
     344                        return n.nodeName === name;
     345                };
     346        };
     347
    342348        test('getParent', 6, function() {
    343349                DOM.add(document.body, 'div', {id : 'test'});
     
    345351                DOM.get('test').innerHTML = '<div><span>ab<a id="test2" href="">abc</a>c</span></div>';
    346352
    347                 equal(DOM.getParent('test2', function(n) {return n.nodeName == 'SPAN';}).nodeName, 'SPAN');
    348                 equal(DOM.getParent('test2', function(n) {return n.nodeName == 'BODY';}).nodeName, 'BODY');
    349                 equal(DOM.getParent('test2', function(n) {return n.nodeName == 'BODY';}, document.body), null);
    350                 equal(DOM.getParent('test2', function() {return false;}), null);
     353                equal(DOM.getParent('test2', eqNodeName('SPAN')).nodeName, 'SPAN');
     354                equal(DOM.getParent('test2', eqNodeName('BODY')).nodeName, 'BODY');
     355                equal(DOM.getParent('test2', eqNodeName('BODY'), document.body), null);
     356                equal(DOM.getParent('test2', eqNodeName('X')), null);
    351357                equal(DOM.getParent('test2', 'SPAN').nodeName, 'SPAN');
    352358                equal(DOM.getParent('test2', 'body', DOM.get('test')), null);
     
    361367                DOM.get('test').innerHTML = '<div><span class="test">ab<span><a id="test2" href="">abc</a>c</span></span></div>';
    362368
    363                 equal(DOM.getParents('test2', function(n) {return n.nodeName == 'SPAN';}).length, 2);
     369                equal(DOM.getParents('test2', eqNodeName('SPAN')).length, 2);
    364370                equal(DOM.getParents('test2', 'span').length, 2);
    365371                equal(DOM.getParents('test2', 'span.test').length, 1);
     
    434440                equal(DOM.getNext(DOM.get('test').firstChild, 'div'), null);
    435441                equal(DOM.getNext(null, 'div'), null);
    436                 equal(DOM.getNext(DOM.get('test').firstChild, function(n) {return n.nodeName == 'EM';}).nodeName, 'EM');
     442                equal(DOM.getNext(DOM.get('test').firstChild, eqNodeName('EM')).nodeName, 'EM');
    437443
    438444                DOM.remove('test');
     
    447453                equal(DOM.getPrev(DOM.get('test').lastChild, 'div'), null);
    448454                equal(DOM.getPrev(null, 'div'), null);
    449                 equal(DOM.getPrev(DOM.get('test').lastChild, function(n) {return n.nodeName == 'STRONG';}).nodeName, 'STRONG');
     455                equal(DOM.getPrev(DOM.get('test').lastChild, eqNodeName('STRONG')).nodeName, 'STRONG');
    450456
    451457                DOM.remove('test');
     
    582588        });
    583589
    584         test('isEmpty', 14, function() {
     590        test('isEmpty', function() {
    585591                DOM.schema = new tinymce.html.Schema(); // A schema will be added when used within a editor instance
    586592                DOM.add(document.body, 'div', {id : 'test'}, '');
     
    626632                DOM.setHTML('test', '<div><!-- comment --></div>');
    627633                ok(!DOM.isEmpty(DOM.get('test')), 'Element with comment.');
     634
     635                DOM.setHTML('test', '<span data-mce-bogus="1"></span>');
     636                ok(DOM.isEmpty(DOM.get('test')), 'Contains just a bogus element.');
     637
     638                DOM.setHTML('test', '<span data-mce-bogus="1">a</span>');
     639                ok(!DOM.isEmpty(DOM.get('test')), 'Contains a text node in a bogus element.');
     640
     641                DOM.setHTML('test', '<span data-mce-bogus="all">a</span>');
     642                ok(DOM.isEmpty(DOM.get('test')), 'Contains just a bogus all element.');
     643
     644                DOM.setHTML('test', '<span data-mce-bogus="all">a</span>b');
     645                ok(!DOM.isEmpty(DOM.get('test')), 'Contains a bogus all element but some text as well.');
     646
     647                DOM.setHTML('test', '<code> </code>');
     648                ok(!DOM.isEmpty(DOM.get('test')), 'Contains a code element should be treated as content.');
     649
     650                DOM.setHTML('test', '<pre> </pre>');
     651                ok(!DOM.isEmpty(DOM.get('test')), 'Contains a pre element should be treated as content.');
     652
     653                DOM.setHTML('test', '<code></code>');
     654                ok(!DOM.isEmpty(DOM.get('test')), 'Contains a code element should be treated as content.');
     655
     656                DOM.setHTML('test', '<pre></pre>');
     657                ok(!DOM.isEmpty(DOM.get('test')), 'Contains a pre element should be treated as content.');
    628658
    629659                DOM.remove('test');
     
    635665        });
    636666
     667        test('isEmpty on pre', function() {
     668                var elm = DOM.create('pre', null, '  ');
     669                equal(false, DOM.isEmpty(elm));
     670        });
     671
    637672        test('isEmpty with list of elements considered non-empty without schema', function() {
    638673                var domWithoutSchema = new tinymce.dom.DOMUtils(document, {keep_values: true});
     
    646681                ok(DOM.isEmpty(elm, 'No children'));
    647682        });
    648        
     683
    649684        test('isEmpty on P with two BR in EM', function() {
    650685                var elm = DOM.create('p', null, '<em><br><br></em>');
     
    655690                var count = 0;
    656691
    657                 DOM.bind(document, 'click', function() {count++;});
     692                DOM.bind(document, 'click', function() {
     693                        count++;
     694                });
    658695                DOM.fire(document, 'click');
    659696                DOM.unbind(document, 'click');
     
    661698
    662699                count = 0;
    663                 DOM.bind([document, window], 'click', function(e) {e.stopPropagation(); count++;});
     700                DOM.bind([document, window], 'click', function(e) {
     701                        e.stopPropagation();
     702                        count++;
     703                });
    664704                DOM.fire(document, 'click');
    665705                DOM.fire(window, 'click');
  • trunk/tests/qunit/editor/tinymce/dom/Selection.js

    r38034 r40399  
    11ModuleLoader.require([
    22        "tinymce/caret/CaretContainer",
     3        "tinymce/text/Zwsp",
    34        "tinymce/Env"
    4 ], function(CaretContainer, Env) {
     5], function(CaretContainer, Zwsp, Env) {
    56        module("tinymce.dom.Selection", {
    67                setupModule: function() {
     
    504505                CaretContainer.insertBlock('p', editor.$('p')[0], true);
    505506                rng = editor.dom.createRng();
    506                 rng.setStart(editor.$('p')[0].firstChild, 0);
    507                 rng.setEnd(editor.$('p')[0].firstChild, 1);
     507                rng.setStart(editor.$('p')[0], 0);
     508                rng.setEnd(editor.$('p')[0], 0);
    508509                editor.selection.setRng(rng);
    509510                bookmark = editor.selection.getBookmark(2);
     
    847848                });
    848849
     850                test('normalize lean left from br into formatter caret container', function() {
     851                        var rng;
     852
     853                        editor.getBody().innerHTML = '<p><span id="_mce_caret">' + Zwsp.ZWSP + '</span><br /></p>';
     854                        rng = editor.dom.createRng();
     855                        rng.setStartBefore(editor.getBody().firstChild.lastChild);
     856                        rng.setEndBefore(editor.getBody().firstChild.lastChild);
     857                        editor.selection.setRng(rng);
     858                        editor.selection.normalize();
     859
     860                        rng = editor.selection.getRng(true);
     861                        equal(rng.startContainer.nodeType, 3);
     862                        equal(rng.startOffset, 1);
     863                });
     864
    849865                test('normalize don\'t lean left into empty inline elements if there is a br element after caret', function() {
    850866                        var rng;
     
    10561072                equal(rng.endOffset, 1);
    10571073        });
     1074
     1075        test('getRng should return null if win.document is not defined or null', function() {
     1076                var win = editor.selection.win,
     1077                        rng = editor.dom.createRng();
     1078
     1079                editor.setContent('<p>x</p>');
     1080
     1081                rng.setStart(editor.$('p')[0].firstChild, 0);
     1082                rng.setEnd(editor.$('p')[0].firstChild, 1);
     1083
     1084                editor.selection.setRng(rng);
     1085                editor.selection.setRng(null);
     1086
     1087                editor.selection.win = {};
     1088                rng = editor.selection.getRng(true);
     1089                equal(rng, null);
     1090
     1091                editor.selection.win = {document:null};
     1092                rng = editor.selection.getRng(true);
     1093                equal(rng, null);
     1094
     1095                editor.selection.win = win;
     1096        });
     1097
     1098        test('image selection webkit bug', function() {
     1099                var testImageSelection = function (inputHtml, expectedContainerName, expectedOffset) {
     1100                        editor.setContent(inputHtml);
     1101                        editor.selection.select(editor.dom.select('img')[0]);
     1102
     1103                        var rng = editor.selection.getRng(true);
     1104                        equal(rng.startContainer.nodeName, 'P');
     1105                        equal(rng.startOffset, expectedOffset);
     1106                        equal(rng.startContainer.nodeName, 'P');
     1107                        equal(rng.endOffset, expectedOffset + 1);
     1108                        equal(editor.selection.getNode().nodeName, 'IMG');
     1109                        equal(editor.selection.getStart().nodeName, 'IMG');
     1110                        equal(editor.selection.getEnd().nodeName, 'IMG');
     1111
     1112                        var nativeRng = editor.selection.getSel().getRangeAt(0);
     1113                        equal(nativeRng.startContainer.nodeName, 'P');
     1114                        equal(nativeRng.startOffset, expectedOffset);
     1115                        equal(nativeRng.startContainer.nodeName, 'P');
     1116                        equal(nativeRng.endOffset, expectedOffset + 1);
     1117                };
     1118
     1119                testImageSelection('<p><img src="#"></p>', 'P', 0);
     1120                testImageSelection('<p><img src="#">abc</p>', 'P', 0);
     1121                testImageSelection('<p>abc<img src="#"></p>', 'P', 1);
     1122                testImageSelection('<p>abc<img src="#">def</p>', 'P', 1);
     1123                testImageSelection('<p><img style="float: right;" src="#"></p>', 'P', 0);
     1124                testImageSelection('<p><img style="float: right;" src="#">abc</p>', 'P', 0);
     1125                testImageSelection('<p>abc<img style="float: right;" src="#"></p>', 'P', 1);
     1126                testImageSelection('<p>abc<img style="float: right;" src="#">def</p>', 'P', 1);
     1127                testImageSelection('<p><img style="float: left;" src="#"></p>', 'P', 0);
     1128                testImageSelection('<p><img style="float: left;" src="#">abc</p>', 'P', 0);
     1129                testImageSelection('<p>abc<img style="float: left;" src="#"></p>', 'P', 1);
     1130                testImageSelection('<p>abc<img style="float: left;" src="#">def</p>', 'P', 1);
     1131                testImageSelection('<p dir="rtl"><img style="float: right;" src="#"></p>', 'P', 0);
     1132                testImageSelection('<p dir="rtl"><img style="float: right;" src="#">abc</p>', 'P', 0);
     1133                testImageSelection('<p dir="rtl">abc<img style="float: right;" src="#"></p>', 'P', 1);
     1134                testImageSelection('<p dir="rtl">abc<img style="float: right;" src="#">def</p>', 'P', 1);
     1135                testImageSelection('<p dir="rtl"><img style="float: left;" src="#"></p>', 'P', 0);
     1136                testImageSelection('<p dir="rtl"><img style="float: left;" src="#">abc</p>', 'P', 0);
     1137                testImageSelection('<p dir="rtl">abc<img style="float: left;" src="#"></p>', 'P', 1);
     1138                testImageSelection('<p dir="rtl">abc<img style="float: left;" src="#">def</p>', 'P', 1);
     1139        });
    10581140});
    10591141
  • trunk/tests/qunit/editor/tinymce/dom/Serializer.js

    r37000 r40399  
    2626        ser.setRules('a[href|target<_blank?_top|title:forced value]');
    2727        DOM.setHTML('test', '<a href="file.htm" data-mce-href="file.htm" target="_blank" title="title">link</a><a href="#" data-mce-href="#" target="test">test2</a>');
    28         equal(ser.serialize(DOM.get('test')), '<a href="file.htm" target="_blank" title="forced value">link</a><a href="#" title="forced value">test2</a>');
     28        equal(ser.serialize(DOM.get('test')), '<a href="file.htm" target="_blank" title="forced value" rel="noopener noreferrer">link</a><a href="#" title="forced value">test2</a>');
    2929
    3030        ser.setRules('img[src|border=0|alt=]');
     
    235235});
    236236
     237test('Padd empty elements with BR', function() {
     238        var ser = new tinymce.dom.Serializer({padd_empty_with_br: true});
     239
     240        ser.setRules('#p,table,tr,#td,br');
     241
     242        DOM.setHTML('test', '<p>a</p><p></p>');
     243        equal(ser.serialize(DOM.get('test')), '<p>a</p><p><br /></p>');
     244        DOM.setHTML('test', '<p>a</p><table><tr><td><br></td></tr></table>');
     245        equal(ser.serialize(DOM.get('test')), '<p>a</p><table><tr><td><br /></td></tr></table>');
     246});
     247
    237248test('Remove empty elements', function() {
    238249        var ser = new tinymce.dom.Serializer({fix_list_elements : true});
     
    345356        DOM.setHTML('test', '<script>\n\n<![CDATA[\n\n1 < 2;\n\n]]>\n\n</s' + 'cript>');
    346357        equal(ser.serialize(DOM.get('test')).replace(/\r/g, ''), '<s' + 'cript>// <![CDATA[\n1 < 2;\n// ]]></s' + 'cript>');
     358});
     359
     360test('Whitespace preserve in pre', function() {
     361        var ser = new tinymce.dom.Serializer({fix_list_elements : true});
     362        ser.setRules('pre');
     363
     364        DOM.setHTML('test', '<pre>  </pre>');
     365        equal(ser.serialize(DOM.get('test')), '<pre>  </pre>');
    347366});
    348367
     
    525544        equal(ser.trimHtml('<p data-x="1" data-y="2" data-z="3">a</p>'), '<p data-z="3">a</p>');
    526545});
     546
     547test('addTempAttr same attr twice', function() {
     548        var ser1 = new tinymce.dom.Serializer({});
     549        var ser2 = new tinymce.dom.Serializer({});
     550
     551        ser1.addTempAttr('data-x');
     552        ser2.addTempAttr('data-x');
     553
     554        DOM.setHTML('test', '<p data-x="1" data-z="3">a</p>');
     555        equal(ser1.serialize(DOM.get('test'), {getInner: 1}), '<p data-z="3">a</p>');
     556        equal(ser1.trimHtml('<p data-x="1" data-z="3">a</p>'), '<p data-z="3">a</p>');
     557        equal(ser2.serialize(DOM.get('test'), {getInner: 1}), '<p data-z="3">a</p>');
     558        equal(ser2.trimHtml('<p data-x="1" data-z="3">a</p>'), '<p data-z="3">a</p>');
     559});
  • trunk/tests/qunit/editor/tinymce/file/ImageScanner.js

    r38034 r40399  
    33        "tinymce/file/UploadStatus",
    44        "tinymce/file/BlobCache",
     5        "tinymce/file/Conversions",
    56        "tinymce/Env"
    6 ], function(ImageScanner, UploadStatus, BlobCache, Env) {
     7], function(ImageScanner, UploadStatus, BlobCache, Conversions, Env) {
    78        if (!tinymce.Env.fileApi) {
    89                return;
    910        }
    1011
     12        QUnit.config.autostart = false;
     13
    1114        module("tinymce.file.ImageScanner");
    1215
    1316        var base64Src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==';
     17        var blobUriSrc;
     18
     19        Conversions.uriToBlob(base64Src).then(function(blob) {
     20                blobUriSrc = URL.createObjectURL(blob);
     21                QUnit.start();
     22        });
    1423
    1524        QUnit.asyncTest("findAll", function() {
     
    1827                document.getElementById('view').innerHTML = (
    1928                        '<img src="' + base64Src + '">' +
     29                        '<img src="' + blobUriSrc + '">' +
    2030                        '<img src="' + Env.transparentSrc + '">' +
    2131                        '<img src="' + base64Src + '" data-mce-bogus="1">' +
     
    2535                imageScanner.findAll(document.getElementById('view')).then(function(result) {
    2636                        QUnit.start();
    27                         equal(result.length, 1);
    28                         equal('data:image/gif;base64,' + result[0].blobInfo.base64(), base64Src);
     37                        var blobInfo = result[0].blobInfo;
     38                        equal(result.length, 2);
     39                        equal('data:image/gif;base64,' + blobInfo.base64(), base64Src);
    2940                        strictEqual(result[0].image, document.getElementById('view').firstChild);
    3041                });
  • trunk/tests/qunit/editor/tinymce/html/DomParser.js

    r37000 r40399  
    100100        });
    101101
     102        test('Whitespace preserved in PRE', function() {
     103                parser = new tinymce.html.DomParser({}, schema);
     104                root = parser.parse('<PRE>  </PRE>');
     105                equal(serializer.serialize(root), '<pre>  </pre>', 'Whitespace around and inside PRE');
     106                deepEqual(countNodes(root), {body:1, pre:1, '#text':1}, 'Whitespace around and inside PRE (count)');
     107        });
     108
    102109        test('Whitespace preserved in SPAN inside PRE', function() {
    103110                parser = new tinymce.html.DomParser({}, schema);
     
    105112                equal(serializer.serialize(root), '<pre>  \t\r\n  <span>    test    </span> \t\r\n   </pre>', 'Whitespace around and inside PRE');
    106113                deepEqual(countNodes(root), {body:1, pre:1, span:1, '#text':3}, 'Whitespace around and inside PRE (count)');
     114        });
     115
     116        test('Whitespace preserved in code', function() {
     117                parser = new tinymce.html.DomParser({}, schema);
     118                root = parser.parse('<code>  a  </code>');
     119                equal(serializer.serialize(root), '<code>  a  </code>', 'Whitespace inside code');
     120                deepEqual(countNodes(root), {body:1, code:1, '#text':1}, 'Whitespace inside code (count)');
     121        });
     122
     123        test('Whitespace preserved in code', function() {
     124                parser = new tinymce.html.DomParser({}, schema);
     125                root = parser.parse('<code>  </code>');
     126                equal(serializer.serialize(root), '<code>  </code>', 'Whitespace inside code');
     127                deepEqual(countNodes(root), {body:1, code:1, '#text':1}, 'Whitespace inside code (count)');
    107128        });
    108129
     
    423444        });
    424445
     446        test('Parse html4 lists into html5 lists', function() {
     447                var parser, root, schema = new tinymce.html.Schema();
     448
     449                parser = new tinymce.html.DomParser({fix_list_elements: true}, schema);
     450                root = parser.parse('<ul><ul><li>a</li></ul></ul><ul><li>a</li><ul><li>b</li></ul></ul>');
     451                equal(serializer.serialize(root), '<ul><li style="list-style-type: none"><ul><li>a</li></ul></li></ul><ul><li>a<ul><li>b</li></ul></li></ul>');
     452        });
     453
    425454        test('Parse contents with html4 anchors and allow_html_in_named_anchor: false', function() {
    426455                var parser, root, schema = new tinymce.html.Schema();
     
    509538                root = parser.parse('<ul><li></li></ul><ul><li> </li></ul>');
    510539                equal(serializer.serialize(root), '');
     540        });
     541
     542        test('Padd empty with br', function() {
     543                var schema = new tinymce.html.Schema();
     544                var parser = new tinymce.html.DomParser({padd_empty_with_br: true}, schema);
     545                var serializer = new tinymce.html.Serializer({padd_empty_with_br: true}, schema);
     546                var root = parser.parse('<p>a</p><p></p>');
     547                equal(serializer.serialize(root), '<p>a</p><p><br /></p>');
    511548        });
    512549
  • trunk/tests/qunit/editor/tinymce/html/Node.js

    r27679 r40399  
    140140        ok(node.next === node3, 'node.next');
    141141        equal(node.prev, undefined, 'node.prev');
    142         ok(node3.prev, node, 'node3.prev');
     142        equal(node3.prev, node, 'node3.prev');
    143143        equal(node3.next, undefined, 'node3.next');
    144144});
  • trunk/tests/qunit/editor/tinymce/html/SaxParser.js

    r33013 r40399  
    605605                parser.parse('<!--[if !IE]>alert(1)<![endif]-->');
    606606                equal(writer.getContent(), '<!-- [if !IE]>alert(1)<![endif]-->');
     607
     608                writer.reset();
     609                parser.parse('<!--[iF !IE]>alert(1)<![endif]-->');
     610                equal(writer.getContent(), '<!-- [iF !IE]>alert(1)<![endif]-->');
    607611        });
    608612
  • trunk/tests/qunit/editor/tinymce/html/Schema.js

    r36352 r40399  
    1414
    1515        schema = new tinymce.html.Schema({valid_elements: '*[id|class]'});
    16         deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {} });
     16        deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {}});
    1717        deepEqual(schema.getElementRule('b').attributesOrder, ["id", "class"]);
    1818
    1919        schema = new tinymce.html.Schema({valid_elements: 'b*[id|class]'});
    20         deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {} });
     20        deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {}});
    2121        deepEqual(schema.getElementRule('b').attributesOrder, ["id", "class"]);
    22         deepEqual(schema.getElementRule('body').attributes, {"id": {}, "class": {} });
     22        deepEqual(schema.getElementRule('body').attributes, {"id": {}, "class": {}});
    2323        deepEqual(schema.getElementRule('body').attributesOrder, ["id", "class"]);
    2424        equal(schema.getElementRule('img'), undefined);
    2525
    2626        schema = new tinymce.html.Schema({valid_elements: 'b?[id|class]'});
    27         deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {} });
     27        deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {}});
    2828        deepEqual(schema.getElementRule('b').attributesOrder, ["id", "class"]);
    29         deepEqual(schema.getElementRule('bx').attributes, {"id": {}, "class": {} });
     29        deepEqual(schema.getElementRule('bx').attributes, {"id": {}, "class": {}});
    3030        deepEqual(schema.getElementRule('bx').attributesOrder, ["id", "class"]);
    3131        equal(schema.getElementRule('body'), undefined);
    3232
    3333        schema = new tinymce.html.Schema({valid_elements: 'b+[id|class]'});
    34         deepEqual(schema.getElementRule('body').attributes, {"id": {}, "class": {} });
     34        deepEqual(schema.getElementRule('body').attributes, {"id": {}, "class": {}});
    3535        deepEqual(schema.getElementRule('body').attributesOrder, ["id", "class"]);
    36         deepEqual(schema.getElementRule('bx').attributes, {"id": {}, "class": {} });
     36        deepEqual(schema.getElementRule('bx').attributes, {"id": {}, "class": {}});
    3737        deepEqual(schema.getElementRule('bx').attributesOrder, ["id", "class"]);
    3838        equal(schema.getElementRule('b'), undefined);
     
    4545
    4646        schema = new tinymce.html.Schema({valid_elements: 'b[id|class|*]'});
    47         deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {} });
     47        deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {}});
    4848        deepEqual(schema.getElementRule('b').attributesOrder, ["id", "class"]);
    4949        ok(schema.getElementRule('b').attributePatterns[0].pattern.test('x'));
    5050
    5151        schema = new tinymce.html.Schema({valid_elements: 'b[id|class|x?]'});
    52         deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {} });
     52        deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {}});
    5353        deepEqual(schema.getElementRule('b').attributesOrder, ["id", "class"]);
    5454        ok(schema.getElementRule('b').attributePatterns[0].pattern.test('xy'));
     
    5757
    5858        schema = new tinymce.html.Schema({valid_elements: 'b[id|class|x+]'});
    59         deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {} });
     59        deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {}});
    6060        deepEqual(schema.getElementRule('b').attributesOrder, ["id", "class"]);
    6161        ok(!schema.getElementRule('b').attributePatterns[0].pattern.test('x'));
     
    118118        schema = new tinymce.html.Schema({valid_elements: 'span[dir<ltr?rtl]'});
    119119        deepEqual(schema.getElementRule('span'), {"attributes": {"dir": {"validValues": {"rtl": {}, "ltr": {}}}}, "attributesOrder": ["dir"]});
     120});
     121
     122test('Required parents', function() {
     123        var schema;
     124
     125        schema = new tinymce.html.Schema();
     126        deepEqual(schema.getElementRule('tr').parentsRequired, ['tbody', 'thead', 'tfoot']);
     127        deepEqual(schema.getElementRule('li').parentsRequired, ['ul', 'ol']);
     128        deepEqual(schema.getElementRule('div').parentsRequired, undefined);
    120129});
    121130
     
    221230                "INPUT": {}, "IMG": {}, "HR": {}, "FRAME": {}, "COL": {}, "BR": {},
    222231                "BASEFONT": {}, "BASE": {}, "AREA": {}, "SOURCE" : {},
    223                 "TD": {}, "TH": {}, "IFRAME": {}, "VIDEO": {}, "AUDIO": {}, "OBJECT": {}, "WBR": {}, "TRACK" : {}, "SCRIPT" : {},
     232                "TD": {}, "TH": {}, "IFRAME": {}, "VIDEO": {}, "AUDIO": {}, "OBJECT": {}, "WBR": {}, "TRACK" : {}, "SCRIPT" : {}, "PRE": {}, "CODE": {},
    224233                "embed": {}, "param": {}, "meta": {}, "link": {}, "isindex": {},
    225234                "input": {}, "img": {}, "hr": {}, "frame": {}, "col": {}, "br": {},
    226235                "basefont": {}, "base": {}, "area": {}, "source" : {},
    227                 "td": {}, "th": {}, "iframe": {}, "video": {}, "audio": {}, "object": {}, "wbr" : {}, "track" : {},  "script" : {}
     236                "td": {}, "th": {}, "iframe": {}, "video": {}, "audio": {}, "object": {}, "wbr" : {}, "track" : {}, "script" : {}, "pre": {}, "code": {}
    228237        });
    229238});
     
    236245        schema = new tinymce.html.Schema();
    237246        deepEqual(schema.getWhiteSpaceElements(), {
    238                 "IFRAME": {}, "NOSCRIPT": {}, "OBJECT": {}, "PRE": {},
     247                "IFRAME": {}, "NOSCRIPT": {}, "OBJECT": {}, "PRE": {}, "CODE": {},
    239248                "SCRIPT": {}, "STYLE": {}, "TEXTAREA": {}, "VIDEO": {}, "AUDIO": {},
    240                 "iframe": {}, "noscript": {}, "object": {}, "pre": {},
     249                "iframe": {}, "noscript": {}, "object": {}, "pre": {}, "code": {},
    241250                "script": {}, "style": {}, "textarea": {}, "video": {}, "audio": {}
    242251        });
  • trunk/tests/qunit/editor/tinymce/html/Styles.js

    r28768 r40399  
    44        var styles = new tinymce.html.Styles();
    55
    6         expect(11);
     6        expect(12);
    77
    88        equal(styles.serialize(styles.parse('FONT-SIZE:10px')), "font-size: 10px;");
     
    1717        equal(styles.serialize(styles.parse('value: "&"')), "value: '&';");
    1818        equal(styles.serialize(styles.parse('value: ')), "");
     19        equal(styles.serialize(styles.parse("background: url('http://www.site.com/(foo)');")), "background: url('http://www.site.com/(foo)');");
    1920});
    2021
     
    6263                'border: 1pt none black;'
    6364        );
    64        
     65
    6566        equal(
    6667                styles.serialize(styles.parse('border-width: 1pt 4pt 2pt 3pt; border-style: solid dashed dotted none; border-color: black red green blue;')),
     
    138139});
    139140
     141test('Suspicious (XSS) property names', function() {
     142        var styles = new tinymce.html.Styles();
     143
     144        equal(styles.serialize(styles.parse('font-fa"on-load\\3dxss\\28\\29\\20mily:\'arial\'')), "");
     145        equal(styles.serialize(styles.parse('font-fa\\"on-load\\3dxss\\28\\29\\20mily:\'arial\'')), "");
     146        equal(styles.serialize(styles.parse('font-fa\\22on-load\\3dxss\\28\\29\\20mily:\'arial\'')), "");
     147});
     148
    140149test('Script urls denied', function() {
    141150        var styles = new tinymce.html.Styles();
    142151
    143152        equal(styles.serialize(styles.parse('behavior:url(test.htc)')), "");
     153        equal(styles.serialize(styles.parse('b\\65havior:url(test.htc)')), "");
    144154        equal(styles.serialize(styles.parse('color:expression(alert(1))')), "");
    145155        equal(styles.serialize(styles.parse('color:\\65xpression(alert(1))')), "");
     
    149159        equal(styles.serialize(styles.parse('background:url(jAvaScript:alert(1)')), "");
    150160        equal(styles.serialize(styles.parse('background:url(javascript:alert(1)')), "");
     161        equal(styles.serialize(styles.parse('background:url(j\\61vascript:alert(1)')), "");
     162        equal(styles.serialize(styles.parse('background:url(\\6a\\61vascript:alert(1)')), "");
     163        equal(styles.serialize(styles.parse('background:url(\\6A\\61vascript:alert(1)')), "");
     164        equal(styles.serialize(styles.parse('background:url\\28\\6A\\61vascript:alert(1)')), "");
     165        equal(styles.serialize(styles.parse('background:\\75rl(j\\61vascript:alert(1)')), "");
     166        equal(styles.serialize(styles.parse('b\\61ckground:\\75rl(j\\61vascript:alert(1)')), "");
    151167        equal(styles.serialize(styles.parse('background:url(vbscript:alert(1)')), "");
    152168        equal(styles.serialize(styles.parse('background:url(j\navas\u0000cr\tipt:alert(1)')), "");
    153169        equal(styles.serialize(styles.parse('background:url(data:image/svg+xml,%3Csvg/%3E)')), "");
     170        equal(styles.serialize(styles.parse('background:url( data:image/svg+xml,%3Csvg/%3E)')), "");
     171        equal(styles.serialize(styles.parse('background:url\\28 data:image/svg+xml,%3Csvg/%3E)')), "");
     172        equal(styles.serialize(styles.parse('background:url("data: image/svg+xml,%3Csvg/%3E")')), "");
     173        equal(styles.serialize(styles.parse('background:url("data: ima ge/svg+xml,%3Csvg/%3E")')), "");
     174        equal(styles.serialize(styles.parse('background:url("data: image /svg+xml,%3Csvg/%3E")')), "");
    154175});
    155176
  • trunk/tests/qunit/editor/tinymce/ui/Window.js

    r27679 r40399  
    3737
    3838        test("title, no buttonbar, autoResize, title is widest", function() {
    39                 var win = createWindow({
     39                var win1 = createWindow({
     40                        x: 100,
     41                        y: 120,
     42                        title: "XXXXXXXXXXXXXXXXXXX",
     43                        items: [
     44                                {type: 'spacer', classes: 'red', flex: 1}
     45                        ]
     46                });
     47
     48                var win2 = createWindow({
    4049                        x: 100,
    4150                        y: 120,
     
    4655                });
    4756
    48                 Utils.nearlyEqualRects(Utils.size(win), [326, 61], 60);
    49                 Utils.nearlyEqualRects(Utils.size(win.find("spacer")[0]), [324, 20], 60);
     57                equal(Utils.size(win2)[0] > Utils.size(win1)[0], true, 'Window 2 should be wider since the title spaces out the window');
     58                equal(Utils.size(win2.find("spacer")[0]) > Utils.size(win1.find("spacer")[0]), true, 'Window 2 spacer should be widger than window 1');
    5059        });
    5160
  • trunk/tests/qunit/editor/tinymce/util/I18n.js

    r31700 r40399  
    66
    77test("Translate strings", function() {
     8        var undef;
     9        var translate = tinymce.util.I18n.translate;
     10
    811        tinymce.util.I18n.add("code", {
    912                "text": "text translation",
    1013                "value:{0}{1}": "value translation:{0}{1}",
    1114                "text{context:something}": "text translation with context",
    12                 "value:{0}{1}{context:something}": "value translation:{0}{1} with context"
     15                "value:{0}{1}{context:something}": "value translation:{0}{1} with context",
     16                "empty string": ""
    1317        });
    1418
    15         equal(tinymce.util.I18n.translate("text"), "text translation");
    16         equal(tinymce.util.I18n.translate("untranslated text"), "untranslated text");
    17         equal(tinymce.util.I18n.translate(["untranslated value:{0}{1}", "a", "b"]), "untranslated value:ab");
    18         equal(tinymce.util.I18n.translate(["value:{0}{1}", "a", "b"]), "value translation:ab");
    19         equal(tinymce.util.I18n.translate("untranslated text{context:context}"), "untranslated text");
    20         equal(tinymce.util.I18n.translate(["untranslated value:{0}{1}{context:something}", "a", "b"]), "untranslated value:ab");
    21         equal(tinymce.util.I18n.translate(["value:{0}{1}{context:something}", "a", "b"]), "value translation:ab with context");
     19        equal(translate("text"), "text translation");
     20        equal(translate("untranslated text"), "untranslated text");
     21        equal(translate(["untranslated value:{0}{1}", "a", "b"]), "untranslated value:ab");
     22        equal(translate(["value:{0}{1}", "a", "b"]), "value translation:ab");
     23        equal(translate("untranslated text{context:context}"), "untranslated text");
     24        equal(translate(["untranslated value:{0}{1}{context:something}", "a", "b"]), "untranslated value:ab");
     25        equal(translate(["value:{0}{1}{context:something}", "a", "b"]), "value translation:ab with context");
     26
     27        // check if translate survives some awkward cases
     28        deepEqual(translate("empty string"), "");
     29        equal(translate(["untranslated value:{0}{1}", "a"]), "untranslated value:a{1}",
     30                "Do not strip tokens that weren't replaced.");
     31
     32        equal(translate([{}]), "[object Object]");
     33        equal(translate(function(){}), "[object Function]");
     34
     35        equal(translate(null), "");
     36        equal(translate(0), 0, "0");
     37        equal(translate(true), "true", "true");
     38        equal(translate(false), "false", "false");
     39
     40        equal(translate({}), "[object Object]", "[object Object]");
     41        equal(translate({raw:""}), "", "empty string");
     42        equal(translate({raw:false}), "false", "false");
     43        equal(translate({raw:undef}), "");
     44        equal(translate({raw:null}), "");
     45
     46        // https://github.com/tinymce/tinymce/issues/3029
     47        equal(translate("hasOwnProperty"), "hasOwnProperty");
     48        tinymce.util.I18n.add("code", {
     49                "hasOwnProperty": "good"
     50        });
     51        equal(translate("hasOwnProperty"), "good");
     52
    2253});
    2354
  • trunk/tests/qunit/editor/tinymce/util/Quirks_webkit.js

    r38034 r40399  
    126126        });
    127127
     128        test('Delete from after image to paragraph', function() {
     129                editor.getBody().innerHTML = '<p>a</p><p><img src="about:blank"></p>';
     130                var rng = editor.dom.createRng();
     131                rng.setStartAfter(editor.dom.select('img')[0]);
     132                rng.setEndAfter(editor.dom.select('img')[0]);
     133                editor.selection.setRng(rng);
     134                editor.execCommand('Delete');
     135                equal(Utils.normalizeHtml(Utils.cleanHtml(editor.getBody().innerHTML)), '<p>a</p>');
     136                equal(editor.selection.getStart().nodeName, 'P');
     137        });
     138
    128139        test('ForwardDelete from end of H1 to P with style span', function() {
    129140                editor.getBody().innerHTML = '<h1>a</h1><p><span style="color:red">b</span></p>';
     
    335346                equal(editor.selection.getStart(true).nodeName, 'P');
    336347        });
     348
     349        test('Delete with similar sibling nodes', function() {
     350                editor.getBody().innerHTML = '<p>Test test</p><p>a</p><p>a</p><p id="t1">a</p><p>test1</p><p id="t2">test2</p>';
     351                Utils.setSelection('p#t1', 1, 'p#t2', 5);
     352                editor.fire('keydown', {keyCode: 8});
     353                equal(Utils.cleanHtml(editor.getBody().innerHTML), '<p>test test</p><p>a</p><p>a</p><p id="t1">a</p>');
     354                equal(editor.selection.getStart(true).nodeName, 'P');
     355        });
    337356} else {
    338357        test("Skipped since the browser isn't WebKit", function() {
Note: See TracChangeset for help on using the changeset viewer.