diff --git a/addons/mass_mailing/static/tests/mass_mailing_html_tests.js b/addons/mass_mailing/static/tests/mass_mailing_html_tests.js index ee5b45c1b0d..e039fa14c86 100644 --- a/addons/mass_mailing/static/tests/mass_mailing_html_tests.js +++ b/addons/mass_mailing/static/tests/mass_mailing_html_tests.js @@ -64,7 +64,7 @@ QUnit.module('field html', { }, function () { QUnit.test('save arch and html', async function (assert) { - assert.expect(6); + assert.expect(4); var form = await testUtils.createView({ View: FormView, @@ -85,19 +85,6 @@ QUnit.test('save arch and html', async function (assert) { ' />'+ '', res_id: 1, - mockRPC: function (route, args) { - if (args.method === "write") { - var values = args.args[1]; - assert.strictEqual(values.body_html, - '

code to edit

', - "should save the content"); - assert.strictEqual(values.body_arch, - '

code to edit

', - "should save the content"); - - } - return this._super.apply(this, arguments); - }, }); var $fieldReadonly = form.$('.oe_form_field[name="body_html"]'); var $fieldEdit = form.$('.oe_form_field[name="body_arch"]'); @@ -113,79 +100,6 @@ QUnit.test('save arch and html', async function (assert) { assert.strictEqual($fieldReadonly.css('display'), 'none', "should hide the readonly mode"); assert.strictEqual($fieldEdit.css('display'), 'block', "should display the edit mode"); - var $iframe = $fieldEdit.find('iframe'); - await testUtils.nextTick(); - await $iframe.data('loadDef'); - await testUtils.nextTick(); - var doc = $iframe.contents()[0]; - var $content = $('#iframe_target', doc); - - // select the text - var pText = $content.find('.note-editable p').first().contents()[0]; - Wysiwyg.setRange(pText, 1, pText, 3); - // text is selected - await testUtils.nextTick(); - - await testUtils.dom.triggerEvents($content.find('.note-toolbar .note-font .note-btn-bold'),['mousedown','click']); - - await testUtils.dom.click(form.$buttons.find('.o_form_button_save')); - - form.destroy(); -}); - -QUnit.test('save and edit arch wysiwyg', async function (assert) { - assert.expect(4); - - testUtils.mock.patch(FieldHtml, { - commitChanges: function () { - assert.step("FieldHtml"); - return this._super.apply(this, arguments); - }, - }); - - testUtils.mock.patch(MassMailingFieldHtml, { - commitChanges: function () { - assert.step("MassMailingFieldHtml"); - return this._super.apply(this, arguments); - }, - }); - - var form = await testUtils.createView({ - View: FormView, - model: 'mailing.mailing', - data: this.data, - arch: '
' + - '
' + - '
' + - ' ' + - '', - res_id: 1, - intercepts: { - execute_action: function (event) { - event.data.on_success(); - }, - }, - }); - - await testUtils.dom.click($('[name=action_put_in_queue]')); - await testUtils.form.clickEdit(form); - var $fieldEdit = form.$('.oe_form_field[name="body_arch"]'); - var $iframe = $fieldEdit.find('iframe'); - - await $iframe.data('loadDef'); - await testUtils.nextTick(); - await testUtils.dom.click($('[name=action_put_in_queue]')); - assert.verifySteps(["MassMailingFieldHtml", "FieldHtml", "MassMailingFieldHtml"]); - - testUtils.mock.unpatch(FieldHtml); - testUtils.mock.unpatch(MassMailingFieldHtml); form.destroy(); }); diff --git a/addons/web_editor/static/tests/field_html_tests.js b/addons/web_editor/static/tests/field_html_tests.js index f9e08872bd3..b092604bd64 100644 --- a/addons/web_editor/static/tests/field_html_tests.js +++ b/addons/web_editor/static/tests/field_html_tests.js @@ -137,14 +137,14 @@ QUnit.module('web_editor', {}, function () { assert.strictEqual(range.sc, pText, "should select the text"); - $field.find('.note-toolbar .note-bg-color button:first').mousedown().click(); + await testUtils.dom.click($field.find('.note-toolbar .note-back-color-preview button:first')); - assert.ok($field.find('.note-bg-color').hasClass('show') && $field.find('.note-bg-color .dropdown-menu').hasClass('show'), + assert.ok($field.find('.note-back-color-preview').hasClass('show'), "should display the color picker"); - $field.find('.note-toolbar .note-bg-color button[data-value="#00FFFF"]').mousedown().click(); + await testUtils.dom.click($field.find('.note-toolbar .note-back-color-preview button[data-value="#00FFFF"]')); - assert.ok(!$field.find('.note-bg-color').hasClass('show') && !$field.find('.note-bg-color .dropdown-menu').hasClass('show'), + assert.ok(!$field.find('.note-back-color-preview').hasClass('show'), "should close the color picker"); assert.strictEqual($field.find('.note-editable').html(), @@ -167,11 +167,11 @@ QUnit.module('web_editor', {}, function () { Wysiwyg.setRange(fontContent, 5, pText, 2); // text is selected - $field.find('.note-toolbar .note-bg-color button:first').mousedown().click(); - $field.find('.note-toolbar .note-bg-color button[data-value="bg-gamma"]').mousedown().click(); + await testUtils.dom.click($field.find('.note-toolbar .note-back-color-preview button:first')); + await testUtils.dom.click($field.find('.note-toolbar .note-back-color-preview button[data-value="bg-gamma"]')); assert.strictEqual($field.find('.note-editable').html(), - '

toto toto toto

tata

', + '

toto toto toto

tata

', "should have rendered the field correctly in edit"); form.destroy(); @@ -215,7 +215,7 @@ QUnit.module('web_editor', {}, function () { var pText = $field.find('.note-editable p').first().contents()[0]; Wysiwyg.setRange(pText, 1); - $field.find('.note-toolbar .note-insert button:has(.fa-file-image-o)').mousedown().click(); + await testUtils.dom.click($field.find('.note-toolbar .note-insert button:has(.fa-file-image-o)')); // load static xml file (dialog, media dialog, unsplash image widget) await defMediaDialog; @@ -266,7 +266,7 @@ QUnit.module('web_editor', {}, function () { var pText = $field.find('.note-editable p').first().contents()[0]; Wysiwyg.setRange(pText, 1); - $field.find('.note-toolbar .note-insert button:has(.fa-file-image-o)').mousedown().click(); + await testUtils.dom.click($field.find('.note-toolbar .note-insert button:has(.fa-file-image-o)')); // load static xml file (dialog, media dialog, unsplash image widget) await defMediaDialog; @@ -315,82 +315,8 @@ QUnit.module('web_editor', {}, function () { Wysiwyg.setRange(pText, 1, pText, 10); // text is selected - await testUtils.dom.click($field.find('.note-toolbar .note-bg-color button:first').mousedown()); - await testUtils.dom.click($field.find('.note-toolbar .note-bg-color button[data-value="bg-gamma"]').mousedown()); - - await testUtils.form.clickSave(form); - - form.destroy(); - }); - - QUnit.module('inline-style'); - - QUnit.test('convert style to class on edit', async function (assert) { - assert.expect(5); - - this.data['note.note'].records[0].body = '

toto ' + - '' + - 'toto toto

tata

'; - - var form = await testUtils.createView({ - View: FormView, - model: 'note.note', - data: this.data, - arch: '
' + - '' + - '', - res_id: 1, - mockRPC: function (route, args) { - if (args.method === "write") { - assert.strictEqual(args.args[1].body, - '

' + - 'toto ' + - '' + - 'toto toto' + - '

' + - '

' + - 'tata' + - '

', - "should save the content"); - } - if (route.indexOf("/web_editor/font_to_img/61445/rgb(") !== -1) { - assert.strictEqual(route, - '/web_editor/font_to_img/61445/rgb(255,0,0)/13', - "should use the image in function of the font and the color"); - return Promise.resolve('#'); - } - return this._super.apply(this, arguments); - }, - }); - var $field = form.$('.oe_form_field[name="body"]'); - - assert.strictEqual($field.children('.o_readonly').html(), - '

' + - 'toto ' + - '' + - 'toto toto' + - '

' + - '

tata

', - "should have rendered a div with correct content in readonly"); - - await testUtils.form.clickEdit(form); - - $field = form.$('.oe_form_field[name="body"]'); - assert.strictEqual($field.find('.note-editable').html(), - '

' + - 'toto ' + - '' + - 'toto toto' + - '

' + - '

tata

', - "should have rendered the field correctly in edit (remove inline style that used class)"); + await testUtils.dom.click($field.find('.note-toolbar .note-back-color-preview button:first')); + await testUtils.dom.click($field.find('.note-toolbar .note-back-color-preview button[data-value="bg-gamma"]')); await testUtils.form.clickSave(form); @@ -433,96 +359,10 @@ QUnit.module('web_editor', {}, function () { form.destroy(); }); - QUnit.module('cssEdit'); - - QUnit.test('rendering with iframe for edit mode', async function (assert) { - assert.expect(4); - - var form = await testUtils.createView({ - View: FormView, - model: 'note.note', - data: this.data, - arch: '
' + - '' + - '', - res_id: 1, - }); - var $field = form.$('.oe_form_field[name="body"]'); - assert.strictEqual($field.children('.o_readonly').html(), - '

toto toto toto

tata

', - "should have rendered a div with correct content in readonly"); - - await testUtils.form.clickEdit(form); - - $field = form.$('.oe_form_field[name="body"]'); - var $iframe = $field.find('iframe'); - await $iframe.data('loadDef'); - var doc = $iframe.contents()[0]; - var $content = $('#iframe_target', doc); - - await testUtils.nextTick(); - - assert.strictEqual($content.find('.note-editable').html(), - '

toto toto toto

tata

', - "should have rendered a div with correct content in edit mode"); - - assert.strictEqual(doc.defaultView.getComputedStyle(doc.body).backgroundColor, - 'rgb(255, 0, 0)', - "should load the asset css"); - - $content.find('.note-toolbar .note-bg-color button:first').mousedown().click(); - await testUtils.nextTick(); - - assert.ok($content.find('.note-bg-color').hasClass('show') && $content.find('.note-bg-color .dropdown-menu').hasClass('show'), - "should display toolbar dropdown menu in iframe"); - - form.destroy(); - }); - -QUnit.test('save immediately before iframe is rendered in edit mode', async function (assert) { - assert.expect(1); - - var form = await testUtils.createAsyncView({ - View: FormView, - model: 'note.note', - data: this.data, - arch: '
' + - '' + - '', - res_id: 1, - }); - testUtils.form.clickEdit(form); - await testUtils.nextTick(); - testUtils.form.clickSave(form); - await testUtils.nextTick(); - assert.ok(true, "No traceback encountered. The wysiwyg was cut while not loaded."); - form.destroy(); -}); - - QUnit.test('save immediately before iframe is rendered in edit mode with style-inline', async function (assert) { + QUnit.test('save immediately before iframe is rendered in edit mode', async function (assert) { assert.expect(1); var form = await testUtils.createAsyncView({ - View: FormView, - model: 'note.note', - data: this.data, - arch: '
' + - '' + - '', - res_id: 1, - }); - testUtils.form.clickEdit(form); - await testUtils.nextTick(); - testUtils.form.clickSave(form); - await testUtils.nextTick(); - assert.ok(true, "No traceback encountered. The wysiwyg was cut while not loaded."); - form.destroy(); - }); - - QUnit.test('use colorpicker and save', async function (assert) { - assert.expect(1); - - var form = await testUtils.createView({ View: FormView, model: 'note.note', data: this.data, @@ -530,268 +370,15 @@ QUnit.test('save immediately before iframe is rendered in edit mode', async func '' + '', res_id: 1, - mockRPC: function (route, args) { - if (args.method === "write") { - assert.strictEqual(args.args[1].body, - '

toto toto toto

tata

', - "should save the content"); - } - return this._super.apply(this, arguments); - }, }); await testUtils.form.clickEdit(form); - var $field = form.$('.oe_form_field[name="body"]'); - var $iframe = $field.find('iframe'); - - await $iframe.data('loadDef'); await testUtils.nextTick(); - - var doc = $iframe.contents()[0]; - var $content = $('#iframe_target', doc); - var $editable = $content.find('.note-editable'); - - // select the text - var pText = $editable.find('p').first().contents()[0]; - Wysiwyg.setRange(pText, 1, pText, 10); - // text is selected - - await testUtils.dom.click($content.find('.note-toolbar .note-bg-color button:first').mousedown()); - await testUtils.dom.click($content.find('.note-toolbar .note-bg-color button[data-value="bg-gamma"]').mousedown()); - await testUtils.form.clickSave(form); + await testUtils.nextTick(); + assert.ok(true, "No traceback encountered. The wysiwyg was cut while not loaded."); form.destroy(); }); - QUnit.module('wrapper'); - - // todo add test wrapper - - QUnit.module('snippet (without iframe)'); - - QUnit.test('rendering with snippet panel', async function (assert) { - var done = assert.async(); - assert.expect(1); - - var form = await testUtils.createView({ - View: FormView, - model: 'note.note', - data: this.data, - arch: '
' + - '' + - '', - res_id: 1, - }); - testUtils.mock.intercept(form, "snippets_loaded", function () { - assert.strictEqual(form.$('.oe_form_field #oe_snippets').length, 1, - "should display the snippet panel"); - form.destroy(); - done(); - }); - await testUtils.form.clickEdit(form); - }); - - QUnit.test('drag&drop snippet', async function (assert) { - assert.expect(1); - - var form = await testUtils.createView({ - View: FormView, - model: 'note.note', - data: this.data, - arch: '
' + - '' + - '', - res_id: 1, - }); - var defSnippets = testUtils.makeTestPromise(); - testUtils.mock.intercept(form, "snippets_loaded", function () { - defSnippets.resolve(); - }); - - await testUtils.form.clickEdit(form); - var $field = form.$('.oe_form_field[name="body"]'); - var $editable = $field.find('.note-editable'); - - await defSnippets; - var $hr = $field.find('.oe_snippet_thumbnail:first'); - testUtils.dom.dragAndDrop($hr, $editable.find('p')); - - assert.strictEqual($editable.data('wysiwyg').getValue().replace(/\s+/g, ' '), - '

toto toto toto

tata

', - "should drop the snippet"); - - form.destroy(); - }); - - // todo add test snippet + customize snippet - - QUnit.module('snippet & cssEdit'); - - QUnit.test('rendering with snippet panel', async function (assert) { - var done = assert.async(); - assert.expect(1); - - var form = await testUtils.createView({ - View: FormView, - model: 'note.note', - data: this.data, - arch: '
' + - '' + - '', - res_id: 1, - }); - testUtils.mock.intercept(form, "snippets_loaded", function () { - var doc = form.$('iframe').contents()[0]; - var $content = $('#iframe_target', doc); - assert.strictEqual($content.find('#oe_snippets').length, 1, - "should display the snippet panel"); - form.destroy(); - done(); - }); - await testUtils.form.clickEdit(form); - }); - - QUnit.test('drag&drop snippet', async function (assert) { - assert.expect(1); - - var form = await testUtils.createView({ - View: FormView, - model: 'note.note', - data: this.data, - arch: '
' + - '' + - '', - res_id: 1, - }); - var defSnippets = testUtils.makeTestPromise(); - testUtils.mock.intercept(form, "snippets_loaded", function () { - defSnippets.resolve(); - }); - await testUtils.form.clickEdit(form); - - await defSnippets; - var doc = form.$('iframe').contents()[0]; - var $content = $('#iframe_target', doc); - var $editable = $content.find('.note-editable'); - - var $hr = $content.find('.oe_snippet_thumbnail:first'); - var from = $hr.offset(); - var to = $editable.find('p').offset(); - - $hr.trigger($.Event("mousedown", { - which: 1, - pageX: from.left + 1, - pageY: from.top + 1 - })); - $hr.trigger($.Event("mousemove", { - which: 1, - pageX: to.left, - pageY: to.top - })); - $hr.trigger($.Event("mouseup", { - which: 1, - pageX: to.left, - pageY: to.top - })); - - assert.strictEqual($editable.data('wysiwyg').getValue().replace(/\s+/g, ' '), - '

toto toto toto

tata

', - "should drop the snippet"); - - form.destroy(); - }); - - QUnit.test('drag&drop snippet options', async function (assert) { - var done = assert.async(); - assert.expect(6); - - var form = await testUtils.createView({ - View: FormView, - model: 'note.note', - data: this.data, - arch: '
' + - '' + - '', - res_id: 1, - }); - var defSnippets = testUtils.makeTestPromise(); - testUtils.mock.intercept(form, "snippets_loaded", function () { - defSnippets.resolve(); - }); - - var defActivateSnippet; - testUtils.mock.intercept(form, "snippet_focused", function (e) { - defActivateSnippet.resolve(e.target); - }); - - await testUtils.form.clickEdit(form); - - defSnippets.then(function () { - var doc = form.$('iframe').contents()[0]; - var $content = $('#iframe_target', doc); - var $editable = $content.find('.note-editable'); - - function dropSnippet() { - defActivateSnippet = testUtils.makeTestPromise(); - - var $hr = $content.find('.oe_snippet_thumbnail:first'); - var from = $hr.offset(); - var to = $editable.find('p').offset(); - - $hr.trigger($.Event("mousedown", { - which: 1, - pageX: from.left + 1, - pageY: from.top + 1 - })); - $hr.trigger($.Event("mousemove", { - which: 1, - pageX: to.left, - pageY: to.top - })); - $hr.trigger($.Event("mouseup", { - which: 1, - pageX: to.left, - pageY: to.top - })); - } - - dropSnippet(); - defActivateSnippet.then(function (snippet) { - assert.strictEqual($editable.data('wysiwyg').getValue().replace(/\s+/g, ' '), - '

toto toto toto

tata

', - "should drop the snippet"); - - assert.strictEqual(snippet.$target.index(), 0, - 'should show the snippet editor for the first dropped block'); - - dropSnippet(); - defActivateSnippet.then(function (snippet) { - assert.strictEqual($editable.data('wysiwyg').getValue().replace(/\s+/g, ' '), - '

' + - '

' + - '

toto toto toto

tata

', - "should drop the snippet"); - - assert.strictEqual(snippet.$target.index(), 1, - 'should show the snippet editor for the second dropped block'); - - assert.strictEqual($('.oe_active .oe_overlay_options .btn:visible', doc).length, 4, - 'should show the snippet editor buttons'); - - defActivateSnippet = testUtils.makeTestPromise(); - $editable.find('hr:first').trigger('click'); - defActivateSnippet.then(function (snippet) { - - assert.strictEqual(snippet.$target.index(), 0, - 'should show the snippet editor for the first dropped block'); - - form.destroy(); - done(); - }); - }); - }); - }); - }); - QUnit.module('translation'); QUnit.test('field html translatable', async function (assert) { @@ -824,47 +411,6 @@ QUnit.test('save immediately before iframe is rendered in edit mode', async func await testUtils.form.clickEdit(form); var $button = form.$('.oe_form_field_html .o_field_translate'); assert.strictEqual($button.length, 1, "should have a translate button"); - $button.click(); - - form.destroy(); - _t.database.multi_lang = multiLang; - }); - - QUnit.test('field html translatable in iframe', async function (assert) { - assert.expect(2); - - var multiLang = _t.database.multi_lang; - _t.database.multi_lang = true; - - this.data['note.note'].fields.body.translate = true; - - var form = await testUtils.createView({ - View: FormView, - model: 'note.note', - data: this.data, - arch: '
' + - '' + - '', - res_id: 1, - mockRPC: function (route, args) { - if (route === '/web/dataset/call_button' && args.method === 'translate_fields') { - assert.deepEqual(args.args, ['note.note', 1, 'body'], "should call 'call_button' route"); - return Promise.resolve(); - } - return this._super.apply(this, arguments); - }, - }); - await testUtils.form.clickEdit(form); - var $field = form.$('.oe_form_field[name="body"]'); - var $iframe = $field.find('iframe'); - - await $iframe.data('loadDef'); - await testUtils.nextTick(); - var doc = $iframe.contents()[0]; - var $content = $('#iframe_target', doc); - - var $button = $content.find('.o_field_translate'); - assert.strictEqual($button.length, 1, "should have a translate button"); await testUtils.dom.click($button); form.destroy(); diff --git a/addons/web_editor/static/tests/wysiwyg_keyboard_tests.js b/addons/web_editor/static/tests/wysiwyg_keyboard_tests.js deleted file mode 100644 index cba62aef1c6..00000000000 --- a/addons/web_editor/static/tests/wysiwyg_keyboard_tests.js +++ /dev/null @@ -1,4423 +0,0 @@ -odoo.define('web_editor.wysiwyg.keyboard_tests', function (require) { -"use strict"; - -var weTestUtils = require('web_editor.test_utils'); - -//-------------------------------------------------------------------------- -// tests -//-------------------------------------------------------------------------- - -QUnit.module('web_editor', {}, function () { -QUnit.module('wysiwyg', {}, function () { - -//-------------------------------------------------------------------------- -// Unbreakable tests -//-------------------------------------------------------------------------- -QUnit.module('Unbreakable'); - -var unbreakableTestDom = [ - ' ', - ' content_a_0', - ' content_b_0', - ' ', - ' content_c_0', - ' content_d_0', - ' ', - ' content_e_0', - ' content_f_0', - ' content_e_1', - ' ', - ' content_c_4', - ' ', - ' content_g_0', - ' ', - ' content_h_0', - ' content_i_0', - ' content_h_2', - ' ', - ' ', - ' content_j_0', - ' content_k_0', - ' content_l_0', - ' content_j_4', - ' ', - ' ', - ' content_m_0', - ' content_n_0', - '' -].join('\n'); -var UnbreakableTests = [{ - name: "nothing to do", - content: unbreakableTestDom, - steps: [{ - start: "#c:contents()[0]->13", - end: "#c:contents()[0]->15", - }], - test: { - content: unbreakableTestDom, - start: "#c:contents()[0]->13", - end: "#c:contents()[0]->15", - }, - }, - { - name: "nothing to do 2", - content: unbreakableTestDom, - steps: [{ - start: "#j:contents()[0]->13", - end: "#l:contents()[0]->5", - }], - test: { - content: unbreakableTestDom, - start: "#j:contents()[0]->13", - end: "#l:contents()[0]->5", - }, - }, - { - name: "nothing to do 3", - content: unbreakableTestDom, - steps: [{ - start: "#k:contents()[0]->3", - end: "#l:contents()[0]->5", - }], - test: { - content: unbreakableTestDom, - start: "#k:contents()[0]->3", - end: "#l:contents()[0]->5", - }, - }, - { - name: "find the first allowed node", - content: unbreakableTestDom, - steps: [{ - start: "#a:contents()[0]->13", - }], - test: { - content: unbreakableTestDom, - start: "#c:contents()[0]->0", - end: "#c:contents()[0]->0", - }, - }, - { - name: "find the first allowed node and collapse the selection", - content: unbreakableTestDom, - steps: [{ - start: "#a:contents()[0]->10", - end: "#b:contents()[0]->3", - }], - test: { - content: unbreakableTestDom, - start: "#c:contents()[0]->0", - end: "#c:contents()[0]->0", - }, - }, - { - name: "resize the range to the allowed end", - content: unbreakableTestDom, - steps: [{ - start: "#a:contents()[0]->10", - end: "#c:contents()[0]->14", - }], - test: { - content: unbreakableTestDom, - start: "#c:contents()[0]->0", - end: "#c:contents()[0]->14", - }, - }, - { - name: "resize the range to the allowed start", - content: unbreakableTestDom, - steps: [{ - start: "#c:contents()[0]->15", - end: "#d:contents()[0]->4", - }], - test: { - content: unbreakableTestDom, - start: "#c:contents()[0]->15", - end: "#c:contents()[0]->37", - }, - }, - { - name: "resize the range to the allowed node that contains unbreakable node", - content: unbreakableTestDom, - steps: [{ - start: "#g:contents()[0]->5", - end: "#h:contents()[2]->15", - }], - test: { - content: unbreakableTestDom, - start: "#h:contents()[0]->0", - end: "#h:contents()[2]->15", - }, - }, - { - name: "resize the range to the allowed node between the start and the end", - content: unbreakableTestDom, - steps: [{ - start: "#e:contents()[0]->15", - end: "#c:contents()[4]->15", - }], - test: { - content: unbreakableTestDom, - start: "#f:contents()[0]->0", - end: "#f:contents()[0]->11", - }, - }, - { - name: "resize the range to the allowed start with the entirety of the unbreakable node", - content: unbreakableTestDom, - steps: [{ - start: "#c:contents()[0]->15", - end: "#e:contents()[0]->15", - }], - test: { - content: unbreakableTestDom, - start: "#c:contents()[0]->15", - end: "#d->1", - }, - }, - { - name: "resize the range to the allowed start and delete content", - content: unbreakableTestDom, - steps: [{ - start: "#c:contents()[0]->15", - end: "#e:contents()[0]->15", - key: "DELETE", - }], - test: { - content: unbreakableTestDom - // when we remove, we clean the invisible space before and after the deleted area - .replace(/>[\s]+content_c_0[\s\S]+content_d_0<\/noteditable>\s+/, '>co') - .replace(/^\s+/, ''), // corner effect of the clean and normalize - start: "#c:contents()[0]->2", - end: "#c:contents()[0]->2", - }, - }, - { - name: "delete unbreakable nodes in a breakable", - content: unbreakableTestDom, - steps: [{ - start: "#c:contents()[0]->15", - end: "#c:contents()[4]->19", - key: "DELETE", - }], - test: { - content: unbreakableTestDom - // when we remove, we clean the invisible space before and after the deleted area - .replace(/>[\s]+content_c_0[\s\S]*content_c_4\s*/, '>cot_c_4') - .replace(/^\s+/, ''), // corner effect of the clean and normalize - start: "#c:contents()[0]->2", - end: "#c:contents()[0]->2", - }, - }, - { - name: "select range with 2 nodes on the root", - content: unbreakableTestDom, - steps: [{ - start: "#m:contents()[0]->5", - end: "#n:contents()[0]->5", - }], - test: { - content: unbreakableTestDom, - start: "#m:contents()[0]->5", - end: "#n:contents()[0]->5", - }, - }, - { - name: "ENTER in an unbreakable p", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->1", - end: "p:contents()[0]->1", - key: 'ENTER', - }], - test: { - content: '

d
om to edit

', - start: "p:contents()[2]->0", - }, - }, -]; - -QUnit.test('Unbreakable selection and edition', function (assert) { - var done = assert.async(); - weTestUtils.createWysiwyg({ - data: this.data, - useOnlyTestUnbreakable: true, - wysiwygOptions: { - tooltip: false, - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.$('.note-editable'); - weTestUtils.testKeyboard($editable, assert, UnbreakableTests).then(function () { - wysiwyg.destroy(); - done(); - }); - }); -}); - -//-------------------------------------------------------------------------- -// Keyboard integration -//-------------------------------------------------------------------------- - -QUnit.module('Keyboard'); - -var keyboardTestsChar = [{ - name: "visible char in a p tag", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->3", - keyCode: 66, - }], - test: { - content: "

domB to edit

", - start: "p:contents()[0]->4", - end: null, - check: function ($editable, assert) { - assert.ok(true); - }, - }, - }, - { - name: "visible char in a link tag entirely selected", - content: '', - steps: [{ - start: "a:contents()[0]->0", - end: "a:contents()[0]->11", - key: 'a', - }], - test: { - content: '', - start: "a:contents()[0]->2", - }, - }, - { - name: "'a' on a selection of all the contents of a complex dom", - content: "

dom

to
completely
remove

", - steps: [{ - start: "p:contents()[0]->0", - end: "i:contents()[0]->1", - key: 'a', - }], - test: { - content: "

a

", - start: "b:contents()[0]->1", - }, - }, - { - name: "'a' on a selection of all the contents of a complex dom (2)", - content: "

dom toedit

", - steps: [{ - start: "font:contents()[0]->0", - end: "font:contents()[1]->4", - key: 'a', - }], - test: { - content: "

a

", - start: "b:contents()[0]->1", - }, - }, - { - name: "'a' before an image", - content: '

xxx yyy

', - steps: [{ - start: "p:contents()[0]->4", - key: 'a', - }], - test: { - content: '

xxx a yyy

', - start: "p:contents()[0]->5", - }, - }, - { - name: "'a' before an image (2)", - content: '

xxx yyy

', - steps: [{ - start: "img->0", - key: 'a', - }], - test: { - content: '

xxx a yyy

', - start: "p:contents()[0]->5", - }, - }, - { - name: "'a' before an image in table", - content: '

xxx

yyy

', - steps: [{ - start: "img->0", - key: 'a', - }], - test: { - content: '

xxx

a

yyy

', - start: "p:eq(1):contents()[0]->1", - }, - }, - { - name: "'a' on invisible text before an image in table", - content: '

xxx

yyy

', - steps: [{ - start: "p:eq(1)->0", - key: 'a', - }], - test: { - content: '

xxx

a

yyy

', - start: "p:eq(1):contents()[0]->1", - }, - }, - { - name: "'a' before an image in table without spaces", - content: '

xxx

yyy

', - steps: [{ - start: "img->0", - key: 'a', - }], - test: { - content: '

xxx

a

yyy

', - start: "p:eq(1):contents()[0]->1", - }, - }, - { - name: "'a' before an image in table without spaces (2)", - content: '

xxx

yyy

', - steps: [{ - start: "td:eq(1)->0", - key: 'a', - }], - test: { - content: '

xxx

a

yyy

', - start: "p:eq(1):contents()[0]->1", - }, - }, - { - name: "'a' before an image in table with spaces", - content: - '\n' + - ' \n' + - ' \n' + - ' \n' + - ' \n' + - ' \n' + - '
\n' + - '

xxx

\n' + - '
\n' + - '

\n' + - '
\n' + - '

yyy

\n' + - '
', - steps: [{ - start: "img->0", - key: 'a', - }], - test: { - content: - '\n' + - ' \n' + - ' \n' + - ' \n' + - ' \n' + - ' \n' + - '
\n' + - '

xxx

\n' + - '
\n' + - '

a

\n' + - '
\n' + - '

yyy

\n' + - '
', - start: "p:eq(1):contents()[0]->1", - }, - }, - { - name: "'a' before an image in table with spaces (2)", - content: - '\n' + - ' \n' + - ' \n' + - ' \n' + - ' \n' + - ' \n' + - '
\n' + - '

xxx

\n' + - '
\n' + - '

\n' + - '
\n' + - '

yyy

\n' + - '
', - steps: [{ - start: "td:eq(1)->1", - key: 'a', - }], - test: { - content: - '\n' + - ' \n' + - ' \n' + - ' \n' + - ' \n' + - ' \n' + - '
\n' + - '

xxx

\n' + - '
\n' + - '

a

\n' + - '
\n' + - '

yyy

\n' + - '
', - start: "p:eq(1):contents()[0]->1", - }, - }, - { - name: "'a' before an image in table with spaces (3)", - content: - '\n' + - ' \n' + - ' \n' + - ' \n' + - ' \n' + - ' \n' + - '
\n' + - '

xxx

\n' + - '
\n' + - '

\n' + - '
\n' + - '

yyy

\n' + - '
', - steps: [{ - start: "td:eq(1):contents()[0]->12", - key: 'a', - }], - test: { - content: - '\n' + - ' \n' + - ' \n' + - ' \n' + - ' \n' + - ' \n' + - '
\n' + - '

xxx

\n' + - '
\n' + - '

a

\n' + - '
\n' + - '

yyy

\n' + - '
', - start: "p:eq(1):contents()[0]->1", - }, - }, - { - name: "'a' on begin of a span with fake_editable", - content: - '
\n' + - '
\n' + - ' \n' + - '
\n' + - '
', - steps: [{ - start: "span:contents(0)->10", - key: 'a', - }], - test: { - content: - '
\n' + - '
\n' + - ' \n' + - '
\n' + - '
', - start: "span:contents(0)->11", - }, - }, - { - name: "'a' on all contents of p starting with an icon", - content: '

bbb

', - steps: [{ - start: "span->0", - end: 'p:contents(1)->3', - key: 'a', - }], - test: { - content: '

a

', - start: "p:contents()[0]->1", - }, - }, - { - name: "' ' at start of p", - content: '

dom to edit

', - steps: [{ - start: "p:contents()[0]->0", - key: ' ', - }], - test: { - content: '

 dom to edit

', - start: "p:contents()[0]->1", - }, - }, - { - name: "' ' at end of p", - content: '

dom to edit

', - steps: [{ - start: "p:contents()[0]->11", - key: ' ', - }], - test: { - content: '

dom to edit 

', - start: "p:contents()[0]->12", - }, - }, - { - name: "' ' within p", - content: '

dom to edit

', - steps: [{ - start: "p:contents()[0]->2", - key: ' ', - }], - test: { - content: '

do m to edit

', - start: "p:contents()[0]->3", - }, - }, - { - name: "' ' before space within p", - content: '

dom to edit

', - steps: [{ - start: "p:contents()[0]->3", - key: ' ', - }], - test: { - content: '

dom  to edit

', - start: "p:contents()[0]->4", - }, - }, - { - name: "' ' after space within p", - content: '

dom to edit

', - steps: [{ - start: "p:contents()[0]->4", - key: ' ', - }], - test: { - content: '

dom  to edit

', - start: "p:contents()[0]->5", - }, - }, - { - name: "3x ' ' at start of p", - content: '

dom to edit

', - steps: [{ - start: "p:contents()[0]->0", - key: ' ', - }, { - key: ' ', - }, { - key: ' ', - }], - test: { - content: '

   dom to edit

', - start: "p:contents()[0]->3", - }, - }, - { - name: "3x ' ' at end of p", - content: '

dom to edit

', - steps: [{ - start: "p:contents()[0]->11", - key: ' ', - }, { - key: ' ', - }, { - key: ' ', - }], - test: { - content: '

dom to edit   

', - start: "p:contents()[0]->14", - }, - }, - { - name: "3x ' ' within p", - content: '

dom to edit

', - steps: [{ - start: "p:contents()[0]->2", - key: ' ', - }, { - key: ' ', - }, { - key: ' ', - }], - test: { - content: '

do   m to edit

', - start: "p:contents()[0]->5", - }, - }, - { - name: "3x ' ' before space in p", - content: '

dom to edit

', - steps: [{ - start: "p:contents()[0]->3", - key: ' ', - }, { - key: ' ', - }, { - key: ' ', - }], - test: { - content: '

dom    to edit

', - start: "p:contents()[0]->6", - }, - }, - { - name: "3x ' ' after space in p", - content: '

dom to edit

', - steps: [{ - start: "p:contents()[0]->4", - key: ' ', - }, { - key: ' ', - }, { - key: ' ', - }], - test: { - content: '

dom    to edit

', - start: "p:contents()[0]->7", - }, - }, - { - name: "'a' in unbreakable with font", - content: '
dom to edit
', - steps: [{ - start: "div:contents(2)->2", - key: 'a', - }], - test: { - content: '
dom toa edit
', - start: "div:contents(2)->3", - }, - }, - { - name: "'a' on begin of unbreakable inline node", - content: 'dom to edit', - steps: [{ - start: "strong:contents(0)->0", - key: 'a', - }], - test: { - content: 'dom ato edit', - start: "strong:contents(0)->1", - }, - }, - { - name: "'a' on end of unbreakable inline node", - content: '
dom to edit
', - steps: [{ - start: "strong:contents(0)->2", - key: 'a', - }], - test: { - content: '
dom toa edit
', - start: "strong:contents(0)->3", - }, - }, - { - name: "'1' on begin of value of a field currency", - content: - '\n' + - '$ 750.00\n' + - '', - steps: [{ - start: "span:contents(0)->0", - key: '1', - }], - test: { - content: - '\n' + - '$ 1750.00\n' + - '', - start: "span:contents(0)->1", - }, - }, - { - name: "'1' on end of value of a field currency", - content: - '\n' + - '$ 750.00\n' + - '', - steps: [{ - start: "span:contents(0)->6", - key: '1', - }], - test: { - content: - '\n' + - '$ 750.001\n' + - '', - start: "span:contents(0)->7", - }, - }, - { - name: "'1' on begin of editable in noteditable", - content: - '\n' + - '$ 750.00\n' + - '', - steps: [{ - start: "span:contents(0)->0", - key: '1', - }], - test: { - content: - '\n' + - '$ 1750.00\n' + - '', - start: "span:contents(0)->1", - }, - }, - { - name: "'1' on end of editable in noteditable", - content: - '\n' + - '$ 750.00\n' + - '', - steps: [{ - start: "span:contents(0)->6", - key: '1', - }], - test: { - content: - '\n' + - '$ 750.001\n' + - '', - start: "span:contents(0)->7", - }, - }, - { - name: "'a' on editable with before&after in noteditable", - content: - '\n' + - '\n' + - '\n' + - '', - steps: [{ - start: "b->0", - key: 'a', - }], - test: { - content: - '\n' + - '\n' + - 'a\n' + - '', - start: "b:contents(0)->1", - }, - }, - { - name: "'a' in empty li", - content: '

', - steps: [{ - start: "p->1", - key: 'a', - }], - test: { - content: '
  • a

', - start: "p:contents(0)->1", - }, - }, -]; - -QUnit.test('Char', function (assert) { - var done = assert.async(); - weTestUtils.createWysiwyg({ - data: this.data, - wysiwygOptions: { - tooltip: false, - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.$('.note-editable'); - weTestUtils.testKeyboard($editable, assert, keyboardTestsChar).then(function () { - wysiwyg.destroy(); - done(); - }); - }); -}); - -var keyboardTestsEnter = [{ - name: "in p: ENTER", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->1", - key: 'ENTER', - }], - test: { - content: "

d

om to edit

", - start: "p:contents()[1]->0", - }, - }, - { - name: "in p: 2x ENTER", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->1", - key: 'ENTER', - }, { - key: 'ENTER', - }], - test: { - content: "

d


om to edit

", - start: "p:contents()[2]->0", - }, - }, - { - name: "in p: SHIFT+ENTER", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->1", - key: 'ENTER', - shiftKey: true, - }], - test: { - content: "

d
om to edit

", - start: "p:contents()[2]->0", - }, - }, - { - name: "in empty-p: SHIFT+ENTER", - content: "


", - steps: [{ - start: "p->1", - key: 'ENTER', - shiftKey: true, - }], - test: { - content: "



", - start: "br:eq(1)->0", - }, - }, - { - name: "in p: 2x SHIFT+ENTER", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->1", - key: 'ENTER', - shiftKey: true, - }, { - key: 'ENTER', - shiftKey: true, - }], - test: { - content: "

d

om to edit

", - start: "p:contents()[3]->0", - }, - }, - { - name: "in empty-p: 2x SHIFT+ENTER", - content: "


", - steps: [{ - start: "p->1", - key: 'ENTER', - shiftKey: true, - }, { - key: 'ENTER', - shiftKey: true, - }], - test: { - content: "




", - start: "br:eq(2)->0", - }, - }, - { - name: "in p: ENTER -> SHIFT+ENTER", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->1", - key: 'ENTER', - }, { - key: 'ENTER', - shiftKey: true, - }], - test: { - content: "

d


om to edit

", - start: "p:eq(1):contents()[1]->0", - }, - }, - { - name: "in p: ENTER on selection", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->1", - end: "p:contents()[0]->7", - key: 'ENTER', - }], - test: { - content: "

d

edit

", - start: "p:contents()[1]->0", - end: "p:contents()[1]->0", - }, - }, - { - name: "in p: SHIFT+ENTER on selection", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->1", - end: "p:contents()[0]->7", - key: 'ENTER', - shiftKey: true, - }], - test: { - content: "

d
edit

", - start: "p:contents()[2]->0", - }, - }, - - // list UL / OL - - { - name: "in li: SHIFT+ENTER at start", - content: "
  • dom to edit
", - steps: [{ - start: "li:contents()[0]->0", - key: 'ENTER', - shiftKey: true, - }], - test: { - content: "

  • dom to edit
", - start: "li:contents()[1]->0", - }, - }, - { - name: "in li: SHIFT+ENTER within contents", - content: "
  • dom to edit
", - steps: [{ - start: "li:contents()[0]->5", - key: 'ENTER', - shiftKey: true, - }], - test: { - content: "
  • dom t
    o edit
", - start: "li:contents()[2]->0", - }, - }, - { - name: "in empty-li: SHIFT+ENTER", - content: "

", - steps: [{ - start: "li:contents()[0]->0", - key: 'ENTER', - shiftKey: true, - }], - test: { - content: "


", - start: "br:eq(1)->0", - }, - }, - { - name: "in li: SHIFT+ENTER on selection", - content: "
  • dom to edit
", - steps: [{ - start: "li:contents()[0]->1", - end: "li:contents()[0]->7", - key: 'ENTER', - shiftKey: true, - }], - test: { - content: "
  • d
    edit
", - start: "li:contents()[2]->0", - }, - }, - { - name: "in li: ENTER at start", - content: "
  • dom to edit
", - steps: [{ - start: "li:contents()[0]->0", - key: 'ENTER', - }], - test: { - content: "

  • dom to edit
", - start: "li:contents()[1]->0", - }, - }, - { - name: "in li: ENTER within contents", - content: "
  • dom to edit
", - steps: [{ - start: "li:contents()[0]->5", - key: 'ENTER', - }], - test: { - content: "
  • dom t
  • o edit
", - start: "li:eq(1):contents()[0]->0", - }, - }, - { - name: "in li: ENTER on selection", - content: "
  • dom to edit
", - steps: [{ - start: "li:contents()[0]->1", - end: "li:contents()[0]->7", - key: 'ENTER', - }], - test: { - content: "
  • d
  • edit
", - start: "li:eq(1):contents()[0]->0", - }, - }, - { - name: "in li: ENTER on selection of all contents", - content: "
  • dom to edit
", - steps: [{ - start: "li:contents()[0]->0", - end: "li:contents()[0]->11", - key: 'ENTER', - }], - test: { - content: "


", - start: "br->0", - }, - }, - { - name: "in li: ENTER -> 'a' on selection of all contents", - content: "
  • dom to edit
", - steps: [{ - start: "li:contents()[0]->0", - end: "li:contents()[0]->11", - key: 'ENTER', - }, { - key: 'a', - }], - test: { - content: "

a

", - start: "p:contents()[0]->1", - }, - }, - { - name: "across 2 li: ENTER on partial selection", - content: "
  • dom to edit
  • dom to edit
", - steps: [{ - start: "li:contents()[0]->1", - end: "li:eq(1):contents()[0]->4", - key: 'ENTER', - }], - test: { - content: "
  • d
  • to edit
", - start: "li:eq(1):contents()[0]->0", // we are after the
, the carret is on the li with an offset equal to the node length - }, - }, - { - name: "in li: ENTER at end", - content: "
  • dom to edit

", - steps: [{ - start: "p:contents()[0]->11", - key: 'ENTER', - }], - test: { - content: "
  • dom to edit


", - start: "br->0", - }, - }, - { - name: "in li: 2x ENTER at end", - content: "
  • dom to edit

", - steps: [{ - start: "p:contents()[0]->11", - key: 'ENTER', - }, { - key: 'ENTER', - }], - test: { - content: "
  • dom to edit


", - start: "br->0", - }, - }, - { - name: "in ul.list-group > li: ENTER at end", - content: '
  • dom to edit

', - steps: [{ - start: "p:contents()[0]->11", - key: 'ENTER', - }, { - key: 'ENTER', - }], - test: { - content: '
  • dom to edit



', - start: "p:eq(2) br->0", - }, - }, - { - name: "in indented-li: 2x ENTER at end", - content: "
  • aaa

    • dom to edit

  • bbb

", - steps: [{ - start: "ul ul p:contents()[0]->11", - key: 'ENTER', - }, { - key: 'ENTER', - }], - test: { - content: "
  • aaa

    • dom to edit


  • bbb

", - start: "p:eq(2) br->0", - }, - }, - { - name: "in indented-li with font: 2x ENTER at end", - content: "
  • aaa

    • dom to edit

  • bbb

", - steps: [{ - start: "font:contents()[0]->11", - key: 'ENTER', - }, { - key: 'ENTER', - }], - test: { - content: "
  • aaa

    • dom to edit


  • bbb

", - start: "p:eq(2) br->0", - }, - }, - { - name: "in li > empty-p: ENTER", - content: "

", - steps: [{ - start: "p:contents()[0]->0", - key: 'ENTER', - }], - test: { - content: "


", - start: "br->0", - }, - }, - { - name: "in li > p > empty-b: ENTER", - content: "

", - steps: [{ - start: "b:contents()[0]->0", - key: 'ENTER', - }], - test: { - content: "


", - start: "br->0", - }, - }, - { - name: "in ul.o_checklist > li.o_checked > p: ENTER at end", - content: '
  • test

', - steps: [{ - start: "p:contents()[0]->4", - key: 'ENTER', - }], - test: { - content: '
  • test


', - start: "br->0", - }, - }, - { - name: "in ul.o_checklist > li.o_checked > p > b: ENTER within text", - content: '
  • test

', - steps: [{ - start: "b:contents()[0]->2", - key: 'ENTER', - }], - test: { - content: '
  • te

  • st

', - start: "b:eq(1):contents()[0]->0", - }, - }, - - // end list UL / OL - - { - name: "after p > b: SHIFT+ENTER", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[1]->0", - key: 'ENTER', - shiftKey: true, - }], - test: { - content: "

dom
 to edit

", - start: "p:contents()[2]->0", - }, - }, - { - name: "in p > b: ENTER -> 'a'", - content: "

dom to edit

", - steps: [{ - start: "b:contents()[0]->2", - key: 'ENTER', - }, { - key: 'a', - }], - test: { - content: "

do

am to edit

", - start: "b:eq(1):contents()[0]->1", - }, - }, - { - name: "after p > b: ENTER -> 'a'", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[1]->0", - key: 'ENTER', - }, { - key: 'a', - }], - test: { - content: "

dom

a to edit

", - start: "p:eq(1):contents()[0]->1", - }, - }, - { - name: "after p > b: SHIFT+ENTER -> 'a'", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[1]->0", - key: 'ENTER', - shiftKey: true, - }, { - key: 'a', - }], - test: { - content: "

dom
a to edit

", - start: "p:contents()[2]->1", - }, - }, - { - name: "in p (other-p > span.a before - p > span.b after): ENTER at beginning", - content: "

dom to

edit

", - steps: [{ - start: "p:eq(1):contents()[0]->0", - key: 'ENTER', - }], - test: { - content: "

dom to


edit

", - start: "span:eq(2):contents()[0]->0", - }, - }, - { - name: "in p (other-p > span.a before - p > span.b after): ENTER -> 'a' at beginning", - content: "

dom to

edit

", - steps: [{ - start: "p:eq(1):contents()[0]->0", - key: 'ENTER', - }, { - key: 'a', - }], - test: { - content: "

dom to


aedit

", - start: "span:eq(2):contents()[0]->1", - }, - }, - { - name: "in p (other-p > span.a before - p > span.b after): SHIFT+ENTER at beginning", - content: "

dom to

edit

", - steps: [{ - start: "p:eq(1):contents()[0]->0", - key: 'ENTER', - shiftKey: true, - }], - test: { - content: "

dom to


edit

", - start: "span:eq(1):contents()[1]->0", - }, - }, - { - name: "in p (other-p > span.a before - p > span.b after): SHIFT+ENTER -> 'a' at beginning", - content: "

dom to

edit

", - steps: [{ - start: "p:eq(1):contents()[0]->0", - key: 'ENTER', - shiftKey: true, - }, { - key: 'a', - }], - test: { - content: "

dom to


aedit

", - start: "span:eq(1):contents()[1]->1", - }, - }, - { - name: "in p: ENTER on selection of all contents", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->0", - end: "p:contents()[0]->11", - key: 'ENTER', - }], - test: { - content: "



", - start: "p:eq(1) br->0", - }, - }, - { - name: "in p: ENTER -> 'a' on selection of all contents", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->0", - end: "p:contents()[0]->11", - key: 'ENTER', - }, { - key: 'a', - }], - test: { - content: "


a

", - start: "p:eq(1):contents()[0]->1", - }, - }, - { - name: "in p: SHIFT+ENTER on selection of all contents", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->0", - end: "p:contents()[0]->11", - key: 'ENTER', - shiftKey: true, - }], - test: { - content: "



", - start: "br:eq(1)->0", - }, - }, - { - name: "in p: SHIFT+ENTER -> 'a' on selection of all contents", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->0", - end: "p:contents()[0]->11", - key: 'ENTER', - shiftKey: true, - }, { - key: 'a', - }], - test: { - content: "


a

", - start: "p:contents()[1]->1", - }, - }, - { - name: "in p: 2x ENTER -> 'a' on selection of all contents", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->3", - key: 'ENTER', - }, { - key: 'ENTER', - }, { - key: 'a', - }], - test: { - content: "

dom


a to edit

", - start: "p:eq(2):contents()[0]->1", - }, - }, - { - name: "in p > b: ENTER at start", - content: "

dom to edit

", - steps: [{ - start: "b:contents()[0]->0", - key: 'ENTER', - }], - test: { - content: "


dom to edit

", - start: "b:eq(1):contents()[0]->0", - }, - }, - { - name: "in p > b: ENTER", - content: "

dom to edit

", - steps: [{ - start: "b:contents()[0]->3", - key: 'ENTER', - }], - test: { - content: "

dom

 to edit

", - start: "b:eq(1):contents()[0]->0", - }, - }, - { - name: "in p > b: SHIFT+ENTER -> ENTER", - content: "

dom to edit

", - steps: [{ - start: "b:contents()[0]->3", - key: 'ENTER', - shiftKey: true, - }, { - key: 'ENTER', - }], - test: { - content: "

dom
​

 to edit

", - start: "b:eq(1):contents()[0]->0", - }, - }, - { - name: "in p > b: ENTER -> a'", - content: "

dom to edit

", - steps: [{ - start: "b:contents()[0]->3", - key: 'ENTER', - }, { - key: 'a', - }], - test: { - content: "

dom

a to edit

", - start: "b:eq(1):contents()[0]->1", - }, - }, - { - name: "in p > b: SHIFT+ENTER", - content: "

dom to edit

", - steps: [{ - start: "b:contents()[0]->3", - key: 'ENTER', - shiftKey: true, - }], - test: { - content: "

dom
 to edit

", - start: "b:contents()[2]->0", - }, - }, - { - name: "in p > b: SHIFT+ENTER -> 'a'", - content: "

dom to edit

", - steps: [{ - start: "b:contents()[0]->3", - key: 'ENTER', - shiftKey: true, - }, { - key: 'a', - }], - test: { - content: "

dom
a to edit

", - start: "b:contents()[2]->1", - }, - }, - { - name: "in p > b: SHIFT+ENTER -> ENTER -> 'a'", - content: "

dom to edit

", - steps: [{ - start: "b:contents()[0]->3", - key: 'ENTER', - shiftKey: true, - }, { - key: 'ENTER', - }, { - key: 'a', - }], - test: { - content: "

dom
​

a to edit

", - start: "b:eq(1):contents()[0]->1", - }, - }, - { - name: "in span > b: ENTER", - content: "dom to edit", - steps: [{ - start: "b:contents()[0]->3", - key: 'ENTER', - }], - test: { - content: "dom
​ to edit", - start: "b:eq(1):contents()[0]->1", - }, - }, - { - name: "in span > b: SHIFT+ENTER -> ENTER", - content: "dom to edit", - steps: [{ - start: "b:contents()[0]->3", - key: 'ENTER', - shiftKey: true, - }, { - key: 'ENTER', - }], - test: { - content: "dom

​ to edit", - start: "b:eq(1):contents()[0]->1", - }, - }, - { - name: "in span > b: ENTER -> a'", - content: "dom to edit", - steps: [{ - start: "b:contents()[0]->3", - key: 'ENTER', - }, { - key: 'a', - }], - test: { - content: "dom
a to edit", - start: "b:eq(1):contents()[0]->1", - }, - }, - { - name: "in span > b: SHIFT+ENTER", - content: "dom to edit", - steps: [{ - start: "b:contents()[0]->3", - key: 'ENTER', - shiftKey: true, - }], - test: { - content: "dom
 to edit
", - start: "b:contents()[2]->0", - }, - }, - { - name: "in span > b: SHIFT+ENTER -> 'a'", - content: "dom to edit", - steps: [{ - start: "b:contents()[0]->3", - key: 'ENTER', - shiftKey: true, - }, { - key: 'a', - }], - test: { - content: "dom
a to edit
", - start: "b:contents()[2]->1", - }, - }, - { - name: "in span > b: SHIFT+ENTER -> ENTER -> 'a'", - content: "dom to edit", - steps: [{ - start: "b:contents()[0]->3", - key: 'ENTER', - shiftKey: true, - }, { - key: 'ENTER', - }, { - key: 'a', - }], - test: { - content: "dom

a to edit", - start: "b:eq(1):contents()[0]->1", - }, - }, - { - name: "in p: 2x SHIFT+ENTER -> 'a'", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->3", - key: 'ENTER', - shiftKey: true, - }, { - key: 'ENTER', - shiftKey: true, - }, { - key: 'a', - }], - test: { - content: "

dom

a to edit

", - start: "p:contents()[3]->1", - }, - }, - { - name: "in p: ENTER -> SHIFT+ENTER -> 'a'", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->3", - key: 'ENTER', - }, { - key: 'ENTER', - shiftKey: true, - }, { - key: 'a', - }], - test: { - content: "

dom


a to edit

", - start: "p:eq(1):contents()[1]->1", - }, - }, - { - name: "in empty-p (p before and after): ENTER -> 'a'", - content: "

dom


to edit

", - steps: [{ - start: "p:eq(1):contents()[0]->0", - key: 'ENTER', - }, { - key: 'a', - }], - test: { - content: "

dom


a

to edit

", - start: "p:eq(2):contents()[0]->1", - }, - }, - { - name: "in p: SHIFT+ENTER at end", - content: "

dom

to edit

", - steps: [{ - start: "p:first:contents()[0]->4", - key: 'ENTER', - shiftKey: true, - }], - test: { - content: "

dom
​

to edit

", - start: "p:first:contents()[2]->0", - }, - }, - { - name: "in p: SHIFT+ENTER at end -> '寺'", - content: "

dom

to edit

", - steps: [{ - start: "p:first:contents()[0]->4", - key: 'ENTER', - shiftKey: true, - }, { - keyCode: 23546, /*temple in chinese*/ - }], - test: { - content: "

dom
寺

to edit

", - start: "p:first:contents()[2]->1", - }, - }, - { - name: "in empty-p (div > a after): 3x SHIFT+ENTER -> 'a'", - content: "


", - steps: [{ - start: "p->1", - key: 'ENTER', - shiftKey: true, - }, - { - key: 'ENTER', - shiftKey: true, - }, - { - key: 'ENTER', - shiftKey: true, - }, - { - key: 'a', - } - ], - test: { - content: "




a

", - start: "p:contents()[3]->1", - }, - }, - - // Buttons - - { - name: "in div > a.btn: ENTER -> 'a' at start (before invisible space)", - content: "", - steps: [{ - start: "a:contents()[0]->0", - key: 'ENTER', - }, { - key: 'a', - }], - test: { - content: "", - // split button has no text so the placeholder text is selected then replaced by 'a' - start: "a:eq(1):contents()[0]->2", - }, - }, - { - name: "in div > a.btn: ENTER -> 'a' at start (after invisible space)", - content: "", - steps: [{ - start: "a:contents()[0]->1", - key: 'ENTER', - }, { - key: 'a', - }], - test: { - content: "", - // split button has no text so the placeholder text is selected then replaced by 'a' - start: "a:eq(1):contents()[0]->2", - }, - }, - { - name: "in div > a.btn: ENTER -> 'a' within contents", - content: "", - steps: [{ - start: "a:contents()[0]->6", - key: 'ENTER', - }, { - key: 'a', - }], - test: { - content: "", - start: "a:eq(1):contents()[0]->2", - }, - }, - { - name: "in div > a.btn: ENTER -> 'a' at end (before invisible space)", - content: "", - steps: [{ - start: "a:contents()[0]->12", - key: 'ENTER', - }, { - key: 'a', - }], - test: { - content: "", - start: "a:eq(1):contents()[0]->2", - }, - }, - { - name: "in div > a.btn: ENTER -> 'a' at end (after invisible space)", - content: "", - steps: [{ - start: "a:contents()[0]->13", - key: 'ENTER', - }, { - key: 'a', - }], - test: { - content: "", - start: "a:eq(1):contents()[0]->2", - }, - }, - { - name: "in div > button.btn: ENTER -> 'a' at end (after invisible space)", - content: "
", - steps: [{ - start: "button:contents()[0]->13", - key: 'ENTER', - }, { - key: 'a', - }], - test: { - content: "
", - start: "button:eq(1):contents()[0]->2", - }, - }, - { - name: "in div > a.btn: ENTER -> 'a' on partial selection", - content: "", - steps: [{ - start: "a:contents()[0]->4", - end: "a:contents()[0]->8", - key: 'ENTER', - }, { - key: 'a', - }], - test: { - content: "", - start: "a:eq(1):contents()[0]->2", - }, - }, - { - name: "in div > a.btn: ENTER -> 'a' on selection of all visible text", - content: "", - steps: [{ - start: "a:contents()[0]->0", - end: "a:contents()[0]->11", - key: 'ENTER', - }, { - key: 'a', - }], - test: { - content: "", - // Removing all text in a link replaces that text with "Label" - start: "a:eq(1):contents()[0]->2", - }, - }, - { - name: "across 2 a.btn: ENTER on selection across two a.btn", - content: "", - steps: [{ - start: "a:contents()[0]->0", - end: "a:eq(1):contents()[0]->11", - key: 'ENTER', - }], - test: { - content: "", - start: "a:eq(1):contents()[0]->1", - }, - }, -]; - -QUnit.test('Enter', function (assert) { - var done = assert.async(); - weTestUtils.createWysiwyg({ - data: this.data, - wysiwygOptions: { - tooltip: false, - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.$('.note-editable'); - weTestUtils.testKeyboard($editable, assert, keyboardTestsEnter).then(function () { - wysiwyg.destroy(); - done(); - }); - }); -}); - -var keyboardTestsComplex = [{ - name: "in span > b: SHIFT+ENTER -> BACKSPACE -> 'a'", - content: "dom to edit", - steps: [{ - start: "b:contents()[0]->3", - key: 'ENTER', - shiftKey: true, - }, { - key: 'BACKSPACE', - }, { - key: 'a', - }], - test: { - content: "doma to edit", - start: "b:contents()[0]->4", - }, - }, - { - name: "in span > b: SHIFT+ENTER -> ENTER -> BACKSPACE", - content: "dom to edit", - steps: [{ - start: "b:contents()[0]->3", - key: 'ENTER', - shiftKey: true, - }, { - key: 'ENTER', - }, { - key: 'BACKSPACE', - }], - test: { - content: "dom
 to edit
", - start: "b:contents(2)->0", - }, - }, - { - name: "in span > b: SHIFT+ENTER -> ENTER -> BACKSPACE -> 'a'", - content: "dom to edit", - steps: [{ - start: "b:contents()[0]->3", - key: 'ENTER', - shiftKey: true, - }, { - key: 'ENTER', - }, { - key: 'BACKSPACE', - }, { - key: 'a', - }], - test: { - content: "dom
a to edit
", - start: "b:contents()[2]->1", - }, - }, - { - name: "in p > b: 2x SHIFT+ENTER -> BACKSPACE", - content: "

dom to edit

", - steps: [{ - start: "b:contents()[0]->3", - key: 'ENTER', - shiftKey: true, - }, { - key: 'ENTER', - shiftKey: true, - }, { - key: 'BACKSPACE', - }], - test: { - content: "

dom
 to edit

", - start: "b:contents()[2]->0", - }, - }, - { - name: "in p > b: 2x ENTER -> 2x BACKSPACE", - content: "

dom to edit

", - steps: [{ - start: "b:contents()[0]->3", - key: 'ENTER', - shiftKey: false - }, { - key: 'ENTER', - shiftKey: false - }, { - key: 'BACKSPACE', - }, { - key: 'BACKSPACE', - }], - test: { - content: "

dom to edit

", - start: "b:contents()[0]->3", - }, - }, - { - name: "in empty-p: 2x ENTER -> 2x BACKSPACE", - content: "


", - steps: [{ - start: "p->1", - key: 'ENTER', - shiftKey: false - }, { - key: 'ENTER', - shiftKey: false - }, { - key: 'BACKSPACE', - }, { - key: 'BACKSPACE', - }], - test: { - content: "


", - start: "p:contents()[0]->0", - }, - }, - { - name: "in empty-p (p before): ENTER -> 2x BACKSPACE", - content: "

dom not to edit


", - steps: [{ - start: "p:eq(1)->1", - key: 'ENTER', - shiftKey: false - }, { - key: 'BACKSPACE', - }, { - key: 'BACKSPACE', - }], - test: { - content: "

dom not to edit

", - start: "p:first:contents()[0]->15", - }, - }, - { - name: "in p > b: 2x SHIFT+ENTER -> BACKSPACE -> 'a'", - content: "

dom to edit

", - steps: [{ - start: "b:contents()[0]->3", - key: 'ENTER', - shiftKey: true, - }, { - key: 'ENTER', - shiftKey: true, - }, { - key: 'BACKSPACE', - }, { - key: 'a', - }], - test: { - content: "

dom
a to edit

", - start: "b:contents()[2]->1", - }, - }, - { - name: "in li -> ENTER before br -> 'a'", - content: "
  • dom
     to edit

", - steps: [{ - start: "p:contents()[0]->3", - key: 'ENTER', - }, { - key: 'a', - }], - test: { - content: "
  • dom

  • a
     to edit

", - start: "p:eq(1):contents()[0]->1", - }, - }, - { - name: "in li -> ENTER after br -> 'a'", - content: "
  • dom
     to edit

", - steps: [{ - start: "p:contents()[2]->0", - key: 'ENTER', - }, { - key: 'a', - }], - test: { - content: "
  • dom
    ​

  • a to edit

", - start: "p:eq(1):contents()[0]->1", - }, - }, - { - name: "within p (p before and after): 3x SHIFT+ENTER -> 3x BACKSPACE", - content: "

dom not to edit

dom to edit

dom not to edit

", - steps: [{ - start: "p:eq(1):contents()[0]->5", - key: 'ENTER', - shiftKey: true, - }, - { - key: 'ENTER', - shiftKey: true, - }, - { - key: 'ENTER', - shiftKey: true, - }, - { - key: 'BACKSPACE', - }, - { - key: 'BACKSPACE', - }, - { - key: 'BACKSPACE', - } - ], - test: { - content: "

dom not to edit

dom to edit

dom not to edit

", - start: "p:eq(1):contents()[0]->5", - }, - }, - { - name: "in h1.a > font: 'a' on selection of all contents", - content: "

dom to edit

", - steps: [{ - start: "h1->0", - end: "h1->1", - key: 'a', - }], - test: { - content: "

a

", - start: "font:contents()[0]->1", - }, - }, - { - name: "in complex-dom: BACKSPACE on partial selection (requires merging non-similar blocks)", - content: "

pif

paf

  • pouf

", - steps: [{ - start: 'p:contents()[0]->2', - end: 'i:contents()[0]->2', - key: 'BACKSPACE', - }], - test: { - content: '

pif

', - start: "p:contents()[0]->2", - }, - }, - { - name: "in complex-dom: DELETE on partial selection (requires merging non-similar blocks)", - content: "

pif

paf

  • pouf

", - steps: [{ - start: 'p:contents()[0]->2', - end: 'i:contents()[0]->2', - key: 'DELETE', - }], - test: { - content: '

pif

', - start: "p:contents()[0]->2", - }, - }, - - // paragraph outdent - - { - name: "in p (h1 before): TAB -> BACKSPACE at start (must indent then outdent)", - content: "

dom not to edit

dom to edit

", - steps: [{ - start: "p:contents()[0]->0", - key: 'TAB', - }, { - key: 'BACKSPACE', - }], - test: { - content: "

dom not to edit

dom to edit

", - start: "p:contents()[0]->0", - }, - }, - { - name: "in p (h1 before): TAB -> 2x BACKSPACE at start (must indent then outdent, then merge blocks)", - content: "

dom not to edit

dom to edit

", - steps: [{ - start: "p:contents()[0]->0", - key: 'TAB', - }, { - key: 'BACKSPACE', - }, { - key: 'BACKSPACE', - }], - test: { - content: "

dom not to editdom to edit

", - start: "h1:contents()[0]->15", - }, - }, - { - name: "in ul > li > ul > 1st li > empty p (other ul li ul before): BACKSPACE at start", - content: '
  • 1

    • 2


  • 3

', - steps: [{ - start: "p:eq(2)->0", - key: 'BACKSPACE', - }], - test: { - content: '
  • 1

    • 2

  • 3

', - start: "p:eq(1):contents()[0]->1", - }, - }, - { - name: "in ul > li > p > text (li > text before): BACKSPACE at start", - content: '
  • 1
  • 2

  • 3
', - steps: [{ - start: "p:contents()[0]->0", - key: 'BACKSPACE', - }], - test: { - content: '
  • 1
  • 2

  • 3
', - start: "p:contents()[0]->1", - }, - }, - { - name: "in ul > li > p > text (li > text before): 3x BACKSPACE after first character", - content: '
  • 1
  • 2
  • 34

  • 5
', - steps: [{ - start: "p:contents()[0]->1", - key: 'BACKSPACE', - }, { - key: 'BACKSPACE', - }, { - key: 'BACKSPACE', - }], - test: { - content: '
  • 1
  • 4

  • 5
', - start: "p:contents()[0]->0", - }, - }, - { - name: "in ul > li > text (li > p > text before): BACKSPACE at start", - content: '
  • 1
  • 2

  • 3
  • 4
', - steps: [{ - start: "li:eq(2):contents()[0]->0", - key: 'BACKSPACE', - }], - test: { - content: '
  • 1
  • 23

  • 4
', - start: "p:contents()[0]->1", - }, - }, - { - name: "in ul > li > text (li > p > text before): 3x BACKSPACE after first character", - content: '
  • 1
  • 2

  • 34
  • 5
', - steps: [{ - start: "li:eq(2):contents()[0]->1", - key: 'BACKSPACE', - }, { - key: 'BACKSPACE', - }, { - key: 'BACKSPACE', - }], - test: { - content: '
  • 1
  • 4

  • 5
', - start: "p:contents()[0]->0", - }, - }, - { - name: "in ul > li > p > text (li > text after): DELETE at end", - content: '
  • 1

  • 2
  • 3
', - steps: [{ - start: "p->0", - key: 'DELETE', - }], - test: { - content: '
  • 1
  • 2

  • 3
', - start: "p:contents()[0]->0", - }, - }, - { - name: "in ul > li > p > text (li > text after): 3x DELETE before last character", - content: '
  • 1
  • 23

  • 4
  • 5
', - steps: [{ - start: "p:contents()[0]->1", - key: 'DELETE', - }, { - key: 'DELETE', - }, { - key: 'DELETE', - }], - test: { - content: '
  • 1
  • 2

  • 5
', - start: "p:contents()[0]->1", - }, - }, - { - name: "in ul > li > text (li > p > text after): DELETE at end", - content: '
  • 1
  • 2
  • 3

  • 4
', - steps: [{ - start: "li:eq(1):contents()[0]->1", - key: 'DELETE', - }], - test: { - content: '
  • 1
  • 23

  • 4
', - start: "p:contents()[0]->1", - }, - }, - { - name: "in ul > li > text (li > p > text after): 3x DELETE before last character", - content: '
  • 1
  • 23
  • 4

  • 5
', - steps: [{ - start: "li:eq(1):contents()[0]->1", - key: 'DELETE', - }, { - key: 'DELETE', - }, { - key: 'DELETE', - }], - test: { - content: '
  • 1
  • 2

  • 5
', - start: "p:contents()[0]->1", - }, - }, - { - name: "in ul.list-group (div > p > text before): BACKSPACE at start", - content: '

1


', - steps: [{ - start: "p:eq(1)->0", - key: 'BACKSPACE', - }], - test: { - content: '

1


', - start: "p:eq(1)->0", - }, - }, - // List indent - { - name: "ENTER -> TAB -> a' at end of li > p (split -> indent -> write)", - content: '
  • a

', - steps: [{ - start: "p:contents()[0]->1", - key: 'ENTER', - }, - { - key: 'TAB', - }, - { - key: 'a', - }], - test: { - content: '
  • a

    • a

', - start: "p:eq(1):contents()[0]->1", - }, - }, -]; - -QUnit.test('Complex', function (assert) { - var done = assert.async(); - weTestUtils.createWysiwyg({ - data: this.data, - wysiwygOptions: { - tooltip: false, - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.$('.note-editable'); - weTestUtils.testKeyboard($editable, assert, keyboardTestsComplex).then(function () { - wysiwyg.destroy(); - done(); - }); - }); -}); - -var keyboardTestsTab = [{ - name: "in li: TAB at start", - content: "
  • dom to edit
", - steps: [{ - start: "li:contents()[0]->0", - key: 'TAB', - }], - test: { - content: "
    • dom to edit
", - start: "ul ul li:contents()[0]->0", - }, - }, - { - name: "in indented-li: SHIFT+TAB at start", - content: "
    • dom to edit
", - steps: [{ - start: "li:contents()[0]->0", - key: 'TAB', - shiftKey: true, - }], - test: { - content: "
  • dom to edit
", - start: "li:contents()[0]->0", - }, - }, - { - name: "in li: TAB within contents", - content: "
  • dom to edit
", - steps: [{ - start: "li:contents()[0]->5", - key: 'TAB', - }], - test: { - content: "
  • dom t    o edit
", - start: "li:contents()[0]->9", - }, - }, - { - name: "in li: SHIFT+TAB within contents (should do nothing)", - content: "
  • dom to edit
", - steps: [{ - start: "li:contents()[0]->5", - key: 'TAB', - shiftKey: true, - }], - test: { - content: "
  • dom to edit
", - start: "li:contents()[0]->5", - }, - }, - { - name: "in td > p: TAB within contents", - content: "

dom to edit

node

", - steps: [{ - start: "p:contents()[0]->5", - key: 'TAB', - }], - test: { - content: "

dom to edit

node

", - start: "td:eq(1) p:contents(0)->0", - }, - }, - { - name: "in p: TAB at start", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->0", - key: 'TAB', - }], - test: { - content: "

dom to edit

", - start: "p:contents()[0]->0", - }, - }, - { - name: "in indented-p: SHIFT+TAB at start", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->0", - key: 'TAB', - shiftKey: true, - }], - test: { - content: "

dom to edit

", - start: "p:contents()[0]->0", - }, - }, - { - name: "in p: TAB -> BACKSPACE at start", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->0", - key: 'TAB', - }, { - key: 'BACKSPACE', - }], - test: { - content: "

dom to edit

", - start: "p:contents()[0]->0", - }, - }, - { - name: "in p > b: TAB at start", - content: "

dom to edit

", - steps: [{ - start: "b:contents()[0]->0", - key: 'TAB', - }], - test: { - content: "

dom     to edit

", - start: "b:contents()[0]->4", - }, - }, - { - name: "in p > b: TAB -> BACKSPACE at start", - content: "

dom to edit

", - steps: [{ - start: "b:contents()[0]->0", - key: 'TAB', - }, { - key: 'BACKSPACE', - }], - test: { - content: "

dom    to edit

", - start: "b:contents()[0]->3", - }, - }, -]; - -QUnit.test('Tab', function (assert) { - var done = assert.async(); - weTestUtils.createWysiwyg({ - data: this.data, - wysiwygOptions: { - tooltip: false, - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.$('.note-editable'); - weTestUtils.testKeyboard($editable, assert, keyboardTestsTab).then(function () { - wysiwyg.destroy(); - done(); - }); - }); -}); - -var keyboardTestsBackspace = [{ - name: "in p: BACKSPACE after span.fa", - content: '

aaabbb

', - steps: [{ - start: "p:contents()[2]->0", - key: 'BACKSPACE', - }], - test: { - content: '

aaabbb

', - start: "p:contents()[0]->3", - }, - }, - { - name: "in empty-p (no br): BACKSPACE (must insert br)", - content: "

", - steps: [{ - start: "p->0", - key: 'BACKSPACE', - }], - test: { - content: "


", // The br is there to ensure the carret can enter the p tag - start: "br->0", - }, - }, - { - name: "in empty-p: BACKSPACE (must leave it unchanged)", - content: "


", - steps: [{ - start: "p->1", - key: 'BACKSPACE', - }], - test: { - content: "


", // The br is there to ensure the carret can enter the p tag - start: "br->0", - }, - }, - { - name: "in p (empty-p before): BACKSPACE", - content: "


dom to edit

", - steps: [{ - start: "p:eq(1):contents()[0]->0", - key: 'BACKSPACE', - }], - test: { - content: "

dom to edit

", - start: "p:contents()[0]->0", - }, - }, - { - name: "in p (empty-p.a before): BACKSPACE", - content: "


dom to edit

", - steps: [{ - start: "p:eq(1):contents()[0]->0", - key: 'BACKSPACE', - }], - test: { - content: "

dom to edit

", - start: "p:contents()[0]->0", - }, - }, - { - name: "in p: BACKSPACE within text", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->5", - key: 'BACKSPACE', - }], - test: { - content: "

dom o edit

", // The br is there to ensure the carret can enter the p tag - start: "p:contents()[0]->4", - }, - }, - { - name: "in p: 2x BACKSPACE within text", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->5", - key: 'BACKSPACE', - }, { - key: 'BACKSPACE', - }], - test: { - content: "

domo edit

", // The br is there to ensure the carret can enter the p tag - start: "p:contents()[0]->3", - }, - }, - { - name: "in p (p > span.a before - span.b after): BACKSPACE at beginning (must attach them)", - content: "

dom to

edit

", - steps: [{ - start: "p:eq(1):contents()[0]->0", - key: 'BACKSPACE', - }], - test: { - content: "

dom toedit

", - start: "span:eq(0):contents()[0]->6", - }, - }, - { - name: "in p (p > span.a before - span.a after): BACKSPACE (must merge them)", - content: "

dom to 

edit

", - steps: [{ - start: "p:eq(1):contents()[0]->0", - key: 'BACKSPACE', - }], - test: { - content: "

dom to edit

", - start: "span:contents()[0]->7", - }, - }, - { - name: "in p (b before): BACKSPACE", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[1]->0", - key: 'BACKSPACE', - }], - test: { - content: "

do to edit

", - start: "b:contents()[0]->2", - }, - }, - { - name: "in p (div > span.a before - span.a after): BACKSPACE at beginning (must do nothing)", - content: "
dom to 

edit

", - steps: [{ - start: "p:contents()[0]->0", - key: 'BACKSPACE', - }], - test: { - content: "
dom to 

edit

", - start: "span:eq(1):contents()[0]->0", - }, - }, - { - name: "in p: BACKSPACE on partial selection", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->1", - end: "p:contents()[0]->7", - key: 'BACKSPACE', - }], - test: { - content: "

dedit

", - start: "p:contents()[0]->1", - }, - }, - { - name: "across 2 p's: BACKSPACE on partial selection", - content: "

dom

to edit

", - steps: [{ - start: "p:contents()[0]->1", - end: "p:eq(1):contents()[0]->3", - key: 'BACKSPACE', - }], - test: { - content: "

dedit

", - start: "p:contents()[0]->1", - }, - }, - { - name: "in p: BACKSPACE within text, with space at beginning", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->10", - key: 'BACKSPACE', - }], - test: { - content: "

dom o edit

", - start: "p:contents()[0]->4", - }, - }, - { - name: "in p: BACKSPACE within text, with one space at beginning", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->6", - key: 'BACKSPACE', - }], - test: { - content: "

 dom o edit

", - start: "p:contents()[0]->5", - }, - }, - { - name: "in p: BACKSPACE within text, with space at end", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->5", - key: 'BACKSPACE', - }], - test: { - content: "

dom o edit

", - start: "p:contents()[0]->4", - }, - }, - { - name: "in p: BACKSPACE within text, with one space at end", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->5", - key: 'BACKSPACE', - }], - test: { - content: "

dom o edit 

", - start: "p:contents()[0]->4", - }, - }, - { - name: "in p: BACKSPACE within text, with space at beginning and end", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->10", - key: 'BACKSPACE', - }], - test: { - content: "

dom o edit

", - start: "p:contents()[0]->4", - }, - }, - { - name: "in p: BACKSPACE within text, with one space at beginning and one at end", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->6", - key: 'BACKSPACE', - }], - test: { - content: "

 dom o edit 

", - start: "p:contents()[0]->5", - }, - }, - { - name: "in p: BACKSPACE after \\w
\\w", - content: "

dom to edi
t

", - steps: [{ - start: "p:contents()[2]->1", - key: 'BACKSPACE', - }], - test: { - content: "

dom to edi
​

", - start: "p:contents()[2]->1", - }, - }, - { - name: "in p: BACKSPACE -> 'a' within text, after \\s\\w", - content: "

dom t

", - steps: [{ - start: "p:contents()[0]->5", - key: 'BACKSPACE', - }, { - key: 'a', - }], - test: { - content: "

dom a

", - start: "p:contents()[0]->5", - }, - }, - { - name: "in pre: BACKSPACE within text, with space at beginning", - content: "
     dom to edit
", - steps: [{ - start: "pre:contents()[0]->10", - key: 'BACKSPACE', - }], - test: { - content: "
     dom o edit
", - start: "pre:contents()[0]->9", - }, - }, - { - name: "in pre: BACKSPACE within text, with one space at beginning", - content: "
 dom to edit
", - steps: [{ - start: "pre:contents()[0]->6", - key: 'BACKSPACE', - }], - test: { - content: "
 dom o edit
", - start: "pre:contents()[0]->5", - }, - }, - { - name: "in pre: BACKSPACE within text, with space at end", - content: "
dom to edit     
", - steps: [{ - start: "pre:contents()[0]->5", - key: 'BACKSPACE', - }], - test: { - content: "
dom o edit     
", - start: "pre:contents()[0]->4", - }, - }, - { - name: "in pre: BACKSPACE within text, with one space at end", - content: "
dom to edit 
", - steps: [{ - start: "pre:contents()[0]->5", - key: 'BACKSPACE', - }], - test: { - content: "
dom o edit 
", - start: "pre:contents()[0]->4", - }, - }, - { - name: "in pre: BACKSPACE within text, with space at beginning and end", - content: "
     dom to edit     
", - steps: [{ - start: "pre:contents()[0]->10", - key: 'BACKSPACE', - }], - test: { - content: "
     dom o edit     
", - start: "pre:contents()[0]->9", - }, - }, - { - name: "in pre: BACKSPACE within text, with one space at beginning and one at end", - content: "
 dom to edit 
", - steps: [{ - start: "pre:contents()[0]->6", - key: 'BACKSPACE', - }], - test: { - content: "
 dom o edit 
", - start: "pre:contents()[0]->5", - }, - }, - - // list UL / OL - - { - name: "from p to ul > li: BACKSPACE on whole list", - content: "

dom not to edit

  • dom to edit

", - steps: [{ - start: "p:contents()[0]->15", - end: "p:eq(1):contents()[0)->11", - key: 'BACKSPACE', - }], - test: { - content: "

dom not to edit

", - start: "p:contents()[0]->15", - }, - }, - { - name: "in ul > second-li > p: BACKSPACE within text", - content: "
  • dom to

  • edit

", - steps: [{ - start: "p:eq(1):contents()[0]->4", - key: 'BACKSPACE', - }], - test: { - content: "
  • dom to

  • edi

", - start: "p:eq(1):contents()[0]->3", - }, - }, - { - name: "in ul > second-li > empty-p: BACKSPACE at beginning", - content: "


", - steps: [{ - start: "p:eq(1)->1", - key: 'BACKSPACE', - }], - test: { - content: "

", - start: "p:first:contents()[0]->0", - }, - }, - { - name: "in ul > indented-li (no other li - p before): BACKSPACE at beginning", - content: "

dom to

    • edit
", - steps: [{ - start: "li:contents()[0]->0", - key: 'BACKSPACE', - }], - test: { - content: "

dom to

  • edit
", - start: "li:contents()[0]->0", - }, - }, - { - name: "in ul > indented-li (no other li - p before): BACKSPACE -> 'a' at beginning", - content: "

dom to

    • edit
", - steps: [{ - start: "li:contents()[0]->0", - key: 'BACKSPACE', - }, { - key: 'a', - }], - test: { - content: "

dom to

  • aedit
", - start: "li:contents()[0]->1", - }, - }, - { - name: "in ul > indented-li (no other li - none before): BACKSPACE at beginning", - content: "
    • dom to edit
", - steps: [{ - start: "li:contents()[0]->0", - key: 'BACKSPACE', - }], - test: { - content: "
  • dom to edit
", - start: "li:contents()[0]->0", - }, - }, - { - name: "in li: BACKSPACE on partial selection", - content: "
  • dom to edit
", - steps: [{ - start: "li:contents()[0]->1", - end: "li:contents()[0]->7", - key: 'BACKSPACE', - }], - test: { - content: "
  • dedit
", - start: "li:contents()[0]->1", - }, - }, - { - name: "across 2 li: BACKSPACE on partial selection", - content: "
  • dom to edit
  • dom to edit
", - steps: [{ - start: "li:contents()[0]->1", - end: "li:eq(1):contents()[0]->7", - key: 'BACKSPACE', - }], - test: { - content: "
  • dedit
", - start: "li:contents()[0]->1", - }, - }, - { - name: "in li (no other li): BACKSPACE on selection of all contents", - content: "
  • dom to edit
", - steps: [{ - start: "li:contents()[0]->0", - end: "li:contents()[0]->11", - key: 'BACKSPACE', - }], - test: { - content: "

", - start: "li->0", - }, - }, - { - name: "in li (no other li): BACKSPACE -> 'a' on selection of all contents", - content: "
  • dom to edit
", - steps: [{ - start: "li:contents()[0]->0", - end: "li:contents()[0]->11", - key: 'BACKSPACE', - }, { - key: 'a', - }], - test: { - content: "
  • a

", - start: "p:contents()[0]->1", - }, - }, - { - name: "in empty-li: BACKSPACE (must remove list)", - content: "

", - steps: [{ - start: "li:contents()[0]->0", - key: 'BACKSPACE', - }], - test: { - content: "


", - start: "br->0", - }, - }, - { - name: "in empty-li (no other li - empty-p before): BACKSPACE -> 'a'", - content: "



", - steps: [{ - start: "li:contents()[0]->0", - key: 'BACKSPACE', - }, { - key: 'a', - }], - test: { - content: "


a

", - start: "p:eq(1):contents()[0]->1", - }, - }, - { - name: "in empty-li (no other li - p before): BACKSPACE", - content: "

toto


", - steps: [{ - start: "li:contents()[0]->0", - key: 'BACKSPACE', - }], - test: { - content: "

toto


", - start: "br->0", - }, - }, - { - name: "in li (no other li - p before): BACKSPACE at start", - content: "

toto

  •  
", - steps: [{ - start: "li:contents()[0]->0", - key: 'BACKSPACE', - }], - test: { - content: "

toto

 

", - start: "p:eq(1):contents()[0]->0", - }, - }, - { - name: "in empty-indented-li (other li - no other indented-li): BACKSPACE", - content: "
  • toto


  • tutu

", - steps: [{ - start: "ul ul li:contents()[0]->0", - key: 'BACKSPACE', - }], - test: { - content: "
  • toto


  • tutu

", - start: "li:eq(1) br->0", - }, - }, - { - name: "in empty-indented-li (other li - other indented-li): BACKSPACE", - content: "
  • toto



  • tutu

", - steps: [{ - start: "ul ul li:contents()[0]->0", - key: 'BACKSPACE', - }], - test: { - content: "
  • toto



  • tutu

", - start: "li:eq(1) br->0", - }, - }, - { - name: "in empty-indented-li (no other li, no other indented-li): BACKSPACE", - content: "

", - steps: [{ - start: "li:contents()[0]->0", - key: 'BACKSPACE', - }], - test: { - content: "

", - start: "br->0", - }, - }, - { - name: "in indented-li (other li, other indented-li): BACKSPACE at start", - content: "
  • toto

    • xxx

    • yyy

  • tutu

", - steps: [{ - start: "ul ul li:contents()[0]->0", - key: 'BACKSPACE', - }], - test: { - content: "
  • toto

  • xxx

    • yyy

  • tutu

", - start: "p:eq(1):contents()[0]->0", - }, - }, - { - name: "in li > second-p: BACKSPACE at start", - content: "
  • toto

  • xxx

    yyy

  • tutu

", - steps: [{ - start: "li:eq(1) p:eq(1):contents()[0]->0", - key: 'BACKSPACE', - }], - test: { - content: "
  • toto

  • xxxyyy

  • tutu

", - start: "li:eq(1) p:contents()[0]->3", - }, - }, - { - name: "in li (li after): BACKSPACE at start, with spaces", - content: "

dom to edit 

  •   dom to edit

  • dom not to edit

", - steps: [{ - start: "p:eq(1):contents()[0]->6", - key: 'BACKSPACE', - }, { - key: 'BACKSPACE', - }, { - key: 'BACKSPACE', - }, { - key: 'BACKSPACE', - }], - test: { - content: "

dom to edit dom to edit

  • dom not to edit

", - start: "p:contents()[0]->12", - }, - }, - { - name: "in li > p: BACKSPACE after single character", - content: "
  • a

", - steps: [{ - start: "p:contents()[0]->1", - key: 'BACKSPACE', - }], - test: { - content: "

", - start: "br->0", - }, - }, - { - name: "in li > p: BACKSPACE -> 'a' after single character", - content: "
  • a

", - steps: [{ - start: "p:contents()[0]->1", - key: 'BACKSPACE', - }, { - key: 'a', - }], - test: { - content: "
  • a

", - start: "p:contents()[0]->1", - }, - }, - - // end list UL / OL - - { - name: "in p: BACKSPACE on selection of all contents", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->0", - end: "p:contents()[0]->11", - key: 'BACKSPACE', - }], - test: { - content: "


", - start: "p->0", - }, - }, - { - name: "in p: BACKSPACE -> 'a' on selection of all contents", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->0", - end: "p:contents()[0]->11", - key: 'BACKSPACE', - }, { - key: 'a', - }], - test: { - content: "

a

", - start: "p:contents()[0]->1", - }, - }, - { - name: "in complex-dom: BACKSPACE on selection of most contents", - content: "

dom

to
partially
remove

", - steps: [{ - start: "b:contents()[0]->2", - end: "i:contents()[0]->1", - key: 'BACKSPACE', - }], - test: { - content: "

doove

", - start: "b:contents()[0]->2", - }, - }, - { - name: "in complex-dom: BACKSPACE on selection of all contents", - content: "

dom

to
completely
remove

", - steps: [{ - start: "p:contents()[0]->0", - end: "i:contents()[0]->1", - key: 'BACKSPACE', - }], - test: { - content: "


", - start: "br->0", - }, - }, - { - name: "in p: BACKSPACE after br", - content: "

dom
to edit

", - steps: [{ - start: "p:contents()[2]->0", - key: 'BACKSPACE', - }], - test: { - content: "

dom to edit

", - start: "p:contents()[0]->4", - }, - }, - { - name: "in complex-dom (span > b -> ENTER in contents)", - content: "dom

 to edit", - steps: [{ - start: "b:eq(1):contents()[0]->0", - key: 'BACKSPACE', - }], - test: { - content: "dom
 to edit
", - start: "b:contents(2)->0", - }, - }, - { - name: "in complex-dom (span > b -> ENTER in contents): 2 x BACKSPACE", - content: "dom

a to edit", - steps: [{ - start: "b:eq(1):contents()[0]->1", - key: 'BACKSPACE', - }, { - key: 'BACKSPACE', - }], - test: { - content: "dom
 to edit
", - start: "b:contents(2)->0", - }, - }, - { - name: "in p (hr before): BACKSPACE", - content: '

aaa


bbb

', - steps: [{ - start: "p:eq(1):contents()[0]->0", - key: 'BACKSPACE', - }], - test: { - content: '

aaabbb

', - start: "p:contents()[0]->3", - }, - }, - { - name: "in p with multi br[id] (p before and after) (1)", - content: '

dom not to edit





dom not to edit

', - steps: [{ - start: "p:eq(1)->2", - key: 'BACKSPACE', - }], - test: { - content: '

dom not to edit




dom not to edit

', - start: "p:eq(1)->1", - }, - }, - { - name: "in p with multi br[id] (p before and after) (2)", - content: '

dom not to edit





dom not to edit

', - steps: [{ - start: "br:eq(2)->0", - key: 'BACKSPACE', - }], - test: { - content: '

dom not to edit




dom not to edit

', - start: "p:eq(1)->1", - }, - }, - { - name: "in p with multi br[id] (p before and after): 2x BACKSPACE", - content: '

dom not to edit





dom not to edit

', - steps: [{ - start: "p:eq(1)->2", - key: 'BACKSPACE', - }, { - key: 'BACKSPACE', - }], - test: { - content: '

dom not to edit



dom not to edit

', - start: "p:eq(1)->0", - }, - }, - { - name: "in p with multi br (p before and after) (1)", - content: '

dom not to edit





dom not to edit

', - steps: [{ - start: "p:eq(1)->2", - key: 'BACKSPACE', - }], - test: { - content: '

dom not to edit




dom not to edit

', - start: "p:eq(1)->1", - }, - }, - { - name: "in p with multi br (p before and after) (2)", - content: '

dom not to edit





dom not to edit

', - steps: [{ - start: "br:eq(2)->0", - key: 'BACKSPACE', - }], - test: { - content: '

dom not to edit




dom not to edit

', - start: "p:eq(1)->1", - }, - }, - { - name: "in p with multi br (p before and after): 2x BACKSPACE", - content: '

dom not to edit





dom not to edit

', - steps: [{ - start: "p:eq(1)->2", - key: 'BACKSPACE', - }, { - key: 'BACKSPACE', - }], - test: { - content: '

dom not to edit



dom not to edit

', - start: "p:eq(1)->0", - }, - }, - { - name: "in p: BACKSPACE within text after \w+
", - content: '

dom to
edit

', - steps: [{ - start: "p:contents()[2]->3", - key: 'BACKSPACE', - }], - test: { - content: '

dom to
edt

', - start: "p:contents()[2]->2", - }, - }, - - // table - - { - name: "in empty-td (td before): BACKSPACE -> 'a' at start", - content: '



', - steps: [{ - start: "p:eq(1)->1", - key: 'BACKSPACE', - }, { - key: 'a', - }], - test: { - content: '


a

', - start: "p:eq(1):contents()[0]->1", - }, - }, - { - name: "in td (td before): 2x BACKSPACE -> 'a' after first character", - content: '

dom not to edit

dom to edit

', - steps: [{ - start: "p:eq(1):contents()[0]->1", - key: 'BACKSPACE', - }, { - key: 'BACKSPACE', - }, { - key: 'a', - }], - test: { - content: '

dom not to edit

aom to edit

', - start: "p:eq(1):contents()[0]->1", - }, - }, - { - name: "in td (no other td): BACKSPACE within text", - content: '

dom to edit

', - steps: [{ - start: "p:contents()[0]->5", - key: 'BACKSPACE', - }], - test: { - content: '

dom o edit

', - start: "p:contents()[0]->4", - }, - }, - { - name: "in complex-dom (empty-td (td before) -> 2x SHIFT-ENTER): 3x BACKSPACE -> 'a'", - content: '

dom not to edit




', - steps: [{ - start: 'p:eq(1)->3', - key: 'BACKSPACE', - }, { - key: 'BACKSPACE', - }, { - key: 'BACKSPACE', - }, { - key: 'a', - }], - test: { - content: '

dom not to edit

a

', - start: "p:eq(1):contents()[0]->1", - }, - }, - { - name: "in h1: BACKSPACE on full selection -> 'a'", - content: '

dom to delete

', - steps: [{ - start: 'h1:contents()[0]->0', - end: 'h1:contents()[0]->13', - key: 'BACKSPACE', - }, { - key: 'a', - }], - test: { - content: '

a

', - start: "h1:contents()[0]->1", - }, - }, - { - name: "in h1: BACKSPACE on full selection -> BACKSPACE -> 'a'", - content: '

dom to delete

', - steps: [{ - start: 'h1:contents()[0]->0', - end: 'h1:contents()[0]->13', - key: 'BACKSPACE', - }, { - key: 'BACKSPACE', - }, { - key: 'a', - }], - test: { - content: '

a

', - start: "p:contents()[0]->1", - }, - }, - { - name: "in h1: BACKSPACE on full selection -> DELETE -> 'a'", - content: '

dom to delete

', - steps: [{ - start: 'h1:contents()[0]->0', - end: 'h1:contents()[0]->13', - key: 'BACKSPACE', - }, { - key: 'DELETE', - }, { - key: 'a', - }], - test: { - content: '

a

', - start: "h1:contents()[0]->1", - }, - }, - - // merging non-similar blocks - - { - name: "in p (h1 before): BACKSPACE at start", - content: '

node to merge with

node to merge

', - steps: [{ - start: 'p:contents()[0]->0', - key: 'BACKSPACE', - }], - test: { - content: '

node to merge withnode to merge

', - start: "h1:contents()[0]->18", - }, - }, - { - name: "in empty-p (h1 before): BACKSPACE", - content: "

dom to edit


", - steps: [{ - start: "p->1", - key: 'BACKSPACE', - }], - test: { - content: "

dom to edit

", - start: "h1:contents()[0]->11", - }, - }, - { - name: "in empty-p (h1 before): 2x BACKSPACE", - content: "

dom to edit


", - steps: [{ - start: "p->1", - key: 'BACKSPACE', - }, { - key: 'BACKSPACE', - }], - test: { - content: "

dom to edi

", - start: "h1:contents()[0]->10", - }, - }, - { - name: "in p (ul before): BACKSPACE at start", - content: '
  • node to merge with

node to merge

', - steps: [{ - start: 'p:eq(1):contents()[0]->0', - key: 'BACKSPACE', - }], - test: { - content: '
  • node to merge withnode to merge

', - start: "p:contents()[0]->18", - }, - }, - { - name: "in p > b (ul before, i after): BACKSPACE at start", - content: '
  • node to merge with

node to merge

', - steps: [{ - start: 'b:contents()[0]->0', - key: 'BACKSPACE', - }], - test: { - content: '
  • node to merge withnode to merge

', - start: "p:contents()[0]->18", - }, - }, - { - name: "in p > b (ul > i before, i after): BACKSPACE at start", - content: '
  • node to merge with

node to merge

', - steps: [{ - start: 'b:contents()[0]->0', - key: 'BACKSPACE', - }], - test: { - content: '
  • node to merge withnode to merge

', - start: "i:contents()[0]->18", - }, - }, - { - name: "in p.c (p.a > span.b before - span.b after): BACKSPACE at beginning", - content: "

dom to 

edit

", - steps: [{ - start: "p:eq(1):contents()[0]->0", - key: 'BACKSPACE', - }], - test: { - content: "

dom to edit

", - start: "span:eq(0):contents()[0]->7", - }, - }, - { - name: "from h1 to p: BACKSPACE", - content: '

node to merge with

node to merge

', - steps: [{ - start: 'h1:contents()[0]->5', - end: 'p:contents()[0]->2', - key: 'BACKSPACE', - }], - test: { - content: '

node de to merge

', - start: "h1:contents()[0]->5", - }, - }, - { - name: "from h1 to p: BACKSPACE at start", - content: '

node to merge with

node to merge

', - steps: [{ - start: 'b:contents()[0]->0', - end: 'p:contents()[0]->2', - key: 'BACKSPACE', - }], - test: { - content: '

de to merge

', - start: "p:contents()[0]->0", - }, - }, -]; - -QUnit.test('Backspace', function (assert) { - var done = assert.async(); - weTestUtils.createWysiwyg({ - data: this.data, - wysiwygOptions: { - tooltip: false, - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.$('.note-editable'); - weTestUtils.testKeyboard($editable, assert, keyboardTestsBackspace).then(function () { - wysiwyg.destroy(); - done(); - }); - }); -}); - -var keyboardTestsDelete = [{ - name: "in empty-p (no br): DELETE (must insert br)", - content: "

", - steps: [{ - start: "p->0", - key: 'DELETE', - }], - test: { - content: "


", // The br is there to ensure the carret can enter the p tag - start: "br->0", - }, - }, - { - name: "in empty-p: DELETE (must leave it unchanged)", - content: "


", - steps: [{ - start: "p->0", - key: 'DELETE', - }], - test: { - content: "


", // The br is there to ensure the carret can enter the p tag - start: "p->0", - }, - }, - { - name: "in empty-p: DELETE (must leave it unchanged) (2)", - content: "

\n
\n

", - steps: [{ - start: "p->1", - key: 'DELETE', - }], - test: { - content: "

\n
\n

", // The br is there to ensure the carret can enter the p tag - start: "p:contents()[1]->0", - }, - }, - { - name: "in empty-p (p after): DELETE", - content: "


dom to edit

", - steps: [{ - start: "p->0", - key: 'DELETE', - }], - test: { - content: "

dom to edit

", - start: "p:contents()[0]->0", - }, - }, - { - name: "in empty-p (p after): DELETE (2)", - content: "

\n
\n

\n dom to edit

", - steps: [{ - start: "p:contents()[1]->0", - key: 'DELETE', - }], - test: { - content: "

dom to edit

", - start: "p:contents()[0]->0", - }, - }, - { - name: "in empty-p.a (p after): DELETE", - content: "


dom to edit

", - steps: [{ - start: "p->0", - key: 'DELETE', - }], - test: { - content: "

dom to edit

", - start: "p:contents()[0]->0", - }, - }, - { - name: "in empty-p.a (p after): DELETE (2)", - content: "


dom to edit

", - steps: [{ - start: "p->1", - key: 'DELETE', - }], - test: { - content: "

dom to edit

", - start: "p:contents()[0]->0", - }, - }, - { - name: "in p: DELETE at start", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->0", - key: 'DELETE', - }], - test: { - content: "

om to edit

", // The br is there to ensure the carret can enter the p tag - start: "p:contents()[0]->0", - }, - }, - { - name: "in p: 2x DELETE at start", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->0", - key: 'DELETE', - }, { - key: 'DELETE', - }], - test: { - content: "

m to edit

", // The br is there to ensure the carret can enter the p tag - start: "p:contents()[0]->0", - }, - }, - { - name: "in p: DELETE within text", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->5", - key: 'DELETE', - }], - test: { - content: "

dom t edit

", - start: "p:contents()[0]->5", - }, - }, - { - name: "in p: DELETE within text, with space at beginning", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->10", - key: 'DELETE', - }], - test: { - content: "

dom t edit

", - start: "p:contents()[0]->5", - }, - }, - { - name: "in p: DELETE within text, with one space at beginning", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->6", - key: 'DELETE', - }], - test: { - content: "

 dom t edit

", - start: "p:contents()[0]->6", - }, - }, - { - name: "in p: DELETE within text, with space at end", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->5", - key: 'DELETE', - }], - test: { - content: "

dom t edit

", - start: "p:contents()[0]->5", - }, - }, - { - name: "in p: DELETE within text, with one space at end", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->5", - key: 'DELETE', - }], - test: { - content: "

dom t edit 

", - start: "p:contents()[0]->5", - }, - }, - { - name: "in p: DELETE within text, with space at beginning and end", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->10", - key: 'DELETE', - }], - test: { - content: "

dom t edit

", - start: "p:contents()[0]->5", - }, - }, - { - name: "in p: DELETE within text, with one space at beginning and one at end", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->6", - key: 'DELETE', - }], - test: { - content: "

 dom t edit 

", - start: "p:contents()[0]->6", - }, - }, - { - name: "in p: DELETE -> 'a' within text, before \\w\\s", - content: "

dom t

", - steps: [{ - start: "p:contents()[0]->2", - key: 'DELETE', - }, { - key: 'a', - }], - test: { - content: "

doa t

", - start: "p:contents()[0]->3", - }, - }, - { - name: "in pre: DELETE within text, with space at beginning", - content: "
     dom to edit
", - steps: [{ - start: "pre:contents()[0]->10", - key: 'DELETE', - }], - test: { - content: "
     dom t edit
", - start: "pre:contents()[0]->10", - }, - }, - { - name: "in pre: DELETE within text, with one space at beginning", - content: "
 dom to edit
", - steps: [{ - start: "pre:contents()[0]->6", - key: 'DELETE', - }], - test: { - content: "
 dom t edit
", - start: "pre:contents()[0]->6", - }, - }, - { - name: "in pre: DELETE within text, with space at end", - content: "
dom to edit     
", - steps: [{ - start: "pre:contents()[0]->5", - key: 'DELETE', - }], - test: { - content: "
dom t edit     
", - start: "pre:contents()[0]->5", - }, - }, - { - name: "in pre: DELETE within text, with one space at end", - content: "
dom to edit 
", - steps: [{ - start: "pre:contents()[0]->5", - key: 'DELETE', - }], - test: { - content: "
dom t edit 
", - start: "pre:contents()[0]->5", - }, - }, - { - name: "in pre: DELETE within text, with space at beginning and end", - content: "
     dom to edit     
", - steps: [{ - start: "pre:contents()[0]->10", - key: 'DELETE', - }], - test: { - content: "
     dom t edit     
", - start: "pre:contents()[0]->10", - }, - }, - { - name: "in pre: DELETE within text, with one space at beginning and one at end", - content: "
 dom to edit 
", - steps: [{ - start: "pre:contents()[0]->6", - key: 'DELETE', - }], - test: { - content: "
 dom t edit 
", - start: "pre:contents()[0]->6", - }, - }, - - // list UL / OL - - { - name: "in empty-li (no other li): DELETE (must do nothing)", - content: "

", - steps: [{ - start: "li:contents()[0]->0", - key: 'DELETE', - }], - test: { - content: "

", - start: "li->0", - }, - }, - { - name: "from p to li > p: DELETE on whole list", - content: "

dom not to edit

  • dom to edit

", - steps: [{ - start: "p:contents()[0]->15", - end: "p:eq(1):contents()[0)->11", - key: 'DELETE', - }], - test: { - content: "

dom not to edit

", - start: "p:contents()[0]->15", - }, - }, - { - name: "in empty-li (no other li): DELETE -> 'a' (must write into it)", - content: "

", - steps: [{ - start: "li:contents()[0]->0", - key: 'DELETE', - }, { - key: 'a', - }], - test: { - content: "
  • a

", - start: "p:contents()[0]->1", - }, - }, - { - name: "in li (li after): DELETE at end (must move contents of second li to carret)", - content: "
  • dom to 
  • edit
", - steps: [{ - start: "li:contents()[0]->7", - key: 'DELETE', - }], - test: { - content: "
  • dom to edit
", - start: "li:contents()[0]->7", - }, - }, - { - name: "in li (li after): DELETE -> 'a' at end (must move contents of second li to carret, then write)", - content: "
  • dom to 
  • edit
", - steps: [{ - start: "li:contents()[0]->7", - key: 'DELETE', - }, { - key: 'a', - }], - test: { - content: "
  • dom to aedit
", - start: "li:contents()[0]->8", - }, - }, - { - name: "in li > p: DELETE before single character", - content: "
  • a

", - steps: [{ - start: "p:contents()[0]->0", - key: 'DELETE', - }], - test: { - content: "

", - start: "br->0", - }, - }, - { - name: "in li > p: DELETE -> 'a' before single character", - content: "
  • a

", - steps: [{ - start: "p:contents()[0]->0", - key: 'DELETE', - }, { - key: 'a', - }], - test: { - content: "
  • a

", - start: "p:contents()[0]->1", - }, - }, - { - name: "in li > p (p after): DELETE at end", - content: "
  • toto

  • xxx

    yyy

  • tutu

", - steps: [{ - start: "li:eq(1) p:eq(0):contents()[0]->3", - key: 'DELETE', - }], - test: { - content: "
  • toto

  • xxxyyy

  • tutu

", - start: "li:eq(1) p:eq(0):contents()[0]->3", - }, - }, - { - name: "in li > p (b before - p after): DELETE at end", - content: "
  • toto

  • xxx

    yyy

  • tutu

", - steps: [{ - start: "li:eq(1) p:eq(0):contents()[1]->2", - key: 'DELETE', - }], - test: { - content: "
  • toto

  • xxxyyy

  • tutu

", - start: "li:eq(1) p:eq(0):contents()[1]->2", - }, - }, - { - name: "in li > p (p.o_default_snippet_text after): DELETE at end", - content: '
  • toto

  • xxx

    yyy

  • tutu

', - steps: [{ - start: "li:eq(1) p:eq(0):contents()[0]->3", - key: 'DELETE', - }], - test: { - content: "
  • toto

  • xxxyyy

  • tutu

", - start: "li:eq(1) p:eq(0):contents()[0]->3", - }, - }, - { - name: "in indented-ul > li: DELETE at end (must do nothing)", - content: "
    • dom to edit
", - steps: [{ - start: "li:contents()[0]->11", - key: 'DELETE', - }], - test: { - content: "
    • dom to edit
", - start: "li:contents()[0]->11", - }, - }, - { - name: "in indented-ul > li: DELETE at end -> 'a' at end (must write)", - content: "
    • dom to edit
", - steps: [{ - start: "li:contents()[0]->11", - key: 'DELETE', - }, { - key: 'a', - }], - test: { - content: "
    • dom to edita
", - start: "li:contents()[0]->12", - }, - }, - { - name: "in indented-ul > li (non-indented-li after): DELETE at end", - content: "
    • dom to edit
  • dom to edit
", - steps: [{ - start: "li:contents()[0]->11", - key: 'DELETE', - }], - test: { - content: "
    • dom to editdom to edit
", - start: "li:contents()[0]->11", - }, - }, - { - name: "in ul > li (indented-li after): DELETE at end", - content: "
  • dom to edit
    • dom to edit
", - steps: [{ - start: "li:contents()[0]->11", - key: 'DELETE', - }], - test: { - content: "
  • dom to editdom to edit
", - start: "li:contents()[0]->11", - }, - }, - { - name: "in li: DELETE on partial selection", - content: "
  • dom to edit
", - steps: [{ - start: "li:contents()[0]->1", - end: "li:contents()[0]->7", - key: 'DELETE', - }], - test: { - content: "
  • dedit
", - start: "li:contents()[0]->1", - }, - }, - { - name: "across 2 li: DELETE on partial selection", - content: "
  • dom to edit
  • dom to edit
", - steps: [{ - start: "li:contents()[0]->1", - end: "li:eq(1):contents()[0]->7", - key: 'DELETE', - }], - test: { - content: "
  • dedit
", - start: "li:contents()[0]->1", - }, - }, - { - name: "in li: DELETE on selection of all contents", - content: "
  • dom to edit
", - steps: [{ - start: "li:contents()[0]->0", - end: "li:contents()[0]->11", - key: 'DELETE', - }], - test: { - content: "

", - start: "li->0", - }, - }, - { - name: "in li: DELETE -> 'a' on selection of all contents", - content: "
  • dom to edit
", - steps: [{ - start: "li:contents()[0]->0", - end: "li:contents()[0]->11", - key: 'DELETE', - }, { - key: 'a', - }], - test: { - content: "
  • a

", - start: "p:contents()[0]->1", - }, - }, - - // end list UL / OL - - { - name: "in p (b before): DELETE", - content: "

domto edit

", - steps: [{ - start: "b:contents()[0]->3", - key: 'DELETE', - }], - test: { - content: "

domo edit

", - start: "p:contents(1)->0", - }, - }, - { - name: "in p > span.a (div > span.a after): DELETE at end (must do nothing)", - content: "

dom to

edit
", - steps: [{ - start: "span:contents()[0]->6", - key: 'DELETE', - }], - test: { - content: "

dom to

edit
", - start: "span:contents()[0]->6", - }, - }, - { - name: "in p: DELETE on partial selection", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->1", - end: "p:contents()[0]->7", - key: 'DELETE', - }], - test: { - content: "

dedit

", - start: "p:contents()[0]->1", - }, - }, - { - name: "across 2 p: DELETE on partial selection", - content: "

dom

to edit

", - steps: [{ - start: "p:contents()[0]->1", - end: "p:eq(1):contents()[0]->3", - key: 'DELETE', - }], - test: { - content: "

dedit

", - start: "p:contents()[0]->1", - }, - }, - { - name: "in p: DELETE on selection of all contents", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->0", - end: "p:contents()[0]->11", - key: 'DELETE', - }], - test: { - content: "


", - start: "p->0", - }, - }, - { - name: "in p: DELETE -> 'a' on selection of all contents", - content: "

dom to edit

", - steps: [{ - start: "p:contents()[0]->0", - end: "p:contents()[0]->11", - key: 'DELETE', - }, { - key: 'a', - }], - test: { - content: "

a

", - start: "p:contents()[0]->1", - }, - }, - { - name: "in p: DELETE before br", - content: "

dom
to edit

", - steps: [{ - start: "p:contents()[0]->4", - key: 'DELETE', - }], - test: { - content: "

dom to edit

", - start: "p:contents()[0]->4", - }, - }, - { - name: "in complex-dom: DELETE on selection of most contents", - content: "

dom

to
partially
remove

", - steps: [{ - start: "b:contents()[0]->2", - end: "i:contents()[0]->1", - key: 'DELETE', - }], - test: { - content: "

doove

", - start: "b:contents()[0]->2", - }, - }, - { - name: "in complex-dom: DELETE on selection of all contents", - content: "

dom

to
completely
remove

", - steps: [{ - start: "p:contents()[0]->0", - end: "i:contents()[0]->1", - key: 'DELETE', - }], - test: { - content: "


", - start: "br->0", - }, - }, - { - name: "in complex-dom (span > b -> ENTER): DELETE", - content: "dom
to edit", - steps: [{ - start: "b:eq(0):contents()[0]->3", - key: 'DELETE', - }], - test: { - content: "dom to edit", - start: "b:contents()[0]->3", - }, - }, - { - name: "in p (span.fa after): DELETE", - content: '

aaabbb

', - steps: [{ - start: "p:contents()[0]->3", - key: 'DELETE', - }], - test: { - content: '

aaabbb

', - start: "p:contents()[0]->3", - }, - }, - { - name: "in p (hr after): DELETE", - content: '

aaa


bbb

', - steps: [{ - start: "p:eq(0):contents()[0]->3", - key: 'DELETE', - }], - test: { - content: '

aaabbb

', - start: "p:contents()[0]->3", - }, - }, - - // table - - { - name: "in empty-td (td after): DELETE -> 'a' at start", - content: '



', - steps: [{ - start: "p->1", - key: 'DELETE', - }, { - key: 'a', - }], - test: { - content: '

a


', - start: "p:contents()[0]->1", - }, - }, - { - name: "in td (td after): 2x DELETE -> 'a' after first character", - content: '

dom to edit

dom not to edit

', - steps: [{ - start: "p:contents()[0]->1", - key: 'DELETE', - }, { - key: 'DELETE', - }, { - key: 'a', - }], - test: { - content: '

da to edit

dom not to edit

', - start: "p:contents()[0]->2", - }, - }, - { - name: "in td: DELETE within text", - content: '

dom to edit

', - steps: [{ - start: "p:contents()[0]->4", - key: 'DELETE', - }], - test: { - content: '

dom o edit

', - start: "p:contents()[0]->4", - }, - }, - - // merging non-similar blocks - - { - name: "in p (ul after, with spaces): DELETE at end (must bring contents of first li to end of p)", - content: "

dom to edit 

  •   dom to edit

  • dom not to edit

", - steps: [{ - start: "p:contents()[0]->11", - key: 'DELETE', - }, { - key: 'DELETE', - }, { - key: 'DELETE', - }, { - key: 'DELETE', - }], - test: { - content: "

dom to editdom to edit

  • dom not to edit

", - start: "p:contents()[0]->11", - }, - }, - { - name: "in h1 (p after): DELETE at end", - content: '

node to merge with

node to merge

', - steps: [{ - start: 'h1:contents()[0]->18', - key: 'DELETE', - }], - test: { - content: '

node to merge withnode to merge

', - start: "h1:contents()[0]->18", - }, - }, - { - name: "in h1 (empty-p after): DELETE at end", - content: "

dom to edit


", - steps: [{ - start: "h1:contents()[0]->11", - key: 'DELETE', - }], - test: { - content: "

dom to edit

", - start: "h1:contents()[0]->11", - }, - }, - { - name: "in h1 (empty-p after): 2x DELETE at end", - content: "

dom to edit


", - steps: [{ - start: "h1:contents()[0]->11", - key: 'DELETE', - }, { - key: 'DELETE', - }], - test: { - content: "

dom to edit

", - start: "h1:contents()[0]->11", - }, - }, - { - name: "in li > p (p after): DELETE at end", - content: '
  • node to merge with

node to merge

', - steps: [{ - start: 'p:contents()[0]->18', - key: 'DELETE', - }], - test: { - content: '
  • node to merge withnode to merge

', - start: "p:contents()[0]->18", - }, - }, - { - name: "in li > p (i before - p > b after): DELETE at end", - content: '
  • node to merge with

node to merge

', - steps: [{ - start: 'p:contents()[1]->5', - key: 'DELETE', - }], - test: { - content: '
  • node to merge withnode to merge

', - start: "p:contents()[1]->5", - }, - }, - { - name: "in li > p > i (b before - p > b after): DELETE at end", - content: '
  • node to merge with

node to merge

', - steps: [{ - start: 'i:contents()[0]->10', - key: 'DELETE', - }], - test: { - content: '
  • node to merge withnode to merge

', - start: "i:contents()[0]->10", - }, - }, - { - name: "in p.a > span.b (p.c > span.b after): DELETE at end", - content: "

dom to 

edit

", - steps: [{ - start: "span:contents()[0]->7", - key: 'DELETE', - }], - test: { - content: "

dom to edit

", - start: "span:contents()[0]->7", - }, - }, -]; - -var keyboardTestsDeleteDOM = [ - '
', - '

', - ' Dear Ready Mat', - '

', - ' Here is', - ' the quotation SO003', - ' amounting in $ 1,127.50', - ' from YourCompany.', - '

', - ' Do not hesitate to contact us if you have any question.', - '

', - '

', - ' ', - ' ', - ' ', - ' ', - ' ', - '
', - ' Virtual Interior Design
On Site ', - '
', - ' 10 Hours', - '
', - '
', - ' ' -].join('\n'); -keyboardTestsDelete.push({ - name: "in complex-dom: DELETE text selection", - content: keyboardTestsDeleteDOM, - steps: [{ - start: "p:contents()[0]->20", - end: 'p:contents()[0]->23', - key: 'DELETE', - }, - { - start: "p:contents()[10]->55", - end: 'p:contents()[10]->63', - key: 'DELETE', - }, - ], - test: { - content: keyboardTestsDeleteDOM.replace('question', '').replace('Mat', ''), - start: "p:contents()[10]->55", - }, -}, { - name: "in complex-dom: DELETE br", - content: keyboardTestsDeleteDOM, - steps: [{ - start: "p->2", - key: 'DELETE', - }, ], - test: { - content: keyboardTestsDeleteDOM.replace('
', ''), - start: "p:contents()[2]->0", - }, -}, { - name: "in complex-dom: DELETE selection (all strong text content)", - content: keyboardTestsDeleteDOM, - steps: [{ - start: "strong:eq(0):contents()[0]->0", - end: 'strong:eq(0):contents()[0]->5', - key: 'DELETE', - }, ], - test: { - content: keyboardTestsDeleteDOM.replace(/SO003<\/strong>\s+/, ' '), - start: "p:contents()[3]->43", - }, -}, { - name: "in complex-dom: DELETE selection (in strong text content before br)", - content: keyboardTestsDeleteDOM, - steps: [{ - start: "strong:eq(2):contents()[0]->17", - end: 'strong:eq(2):contents()[0]->23', - key: 'DELETE', - }, ], - test: { - content: keyboardTestsDeleteDOM.replace(/Design/, ''), - start: "strong:eq(2):contents()[0]->17", - }, -}); - -QUnit.test('Delete', function (assert) { - var done = assert.async(); - weTestUtils.createWysiwyg({ - data: this.data, - wysiwygOptions: { - tooltip: false, - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.$('.note-editable'); - weTestUtils.testKeyboard($editable, assert, keyboardTestsDelete).then(function () { - wysiwyg.destroy(); - done(); - }); - }); -}); - -}); -}); -}); diff --git a/addons/web_editor/static/tests/wysiwyg_snippets_tests.js b/addons/web_editor/static/tests/wysiwyg_snippets_tests.js deleted file mode 100644 index f708b76b016..00000000000 --- a/addons/web_editor/static/tests/wysiwyg_snippets_tests.js +++ /dev/null @@ -1,413 +0,0 @@ -odoo.define('web_editor.wysiwyg_snippets_tests', function (require) { -"use strict"; - -var testUtils = require('web.test_utils'); -var weTestUtils = require('web_editor.test_utils'); -var MediaDialog = require('wysiwyg.widgets.MediaDialog'); - - -QUnit.module('web_editor', {}, function () { -QUnit.module('wysiwyg', {}, function () { -QUnit.module('Snippets', {}, function () { - -QUnit.test('drag&drop', function (assert) { - var done = assert.async(); - assert.expect(2); - - return weTestUtils.createWysiwyg({ - wysiwygOptions: { - snippets: true, - value: '

toto toto toto

tata

', - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.getEditable(); - - var $hr = wysiwyg.snippets.$('.oe_snippet_thumbnail:first'); - testUtils.dom.dragAndDrop($hr, $editable.find('p')); - - assert.strictEqual($editable.html().replace(/\s+/g, ' '), - '

toto toto toto


tata

', - "should drop the snippet"); - - testUtils.mock.intercept(wysiwyg, "snippet_focused", function () { - assert.strictEqual($editable.html().replace(/\s+/g, ' '), - '

toto toto toto


tata

', - "should build and focus the snippet"); - - wysiwyg.destroy(); - done(); - }); - }); -}); - -QUnit.test('begin drag&drop must hide popovers', function (assert) { - var done = assert.async(); - assert.expect(2); - - return weTestUtils.createWysiwyg({ - wysiwygOptions: { - snippets: true, - value: - '
' + - '
' + - ' ' + - '
' + - '

test

' + - '

test

', - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.getEditable(); - - $editable.find('.s_hr img').mousedown().click(); - assert.strictEqual($('.note-popover:visible').length, 1, "should display the image popover"); - - var $hr = wysiwyg.snippets.$('.oe_snippet_thumbnail:first'); - testUtils.dom.dragAndDrop($hr, $editable.find('h1'), { - disableDrop: true, - }); - assert.strictEqual($('.note-popover:visible').length, 0, "should hide the image popover"); - testUtils.dom.dragAndDrop($hr, $editable.find('h1'), { - continueMove: true, - }); - - wysiwyg.destroy(); - done(); - }); -}); - -QUnit.test('change size option must hide popovers', function (assert) { - var done = assert.async(); - assert.expect(4); - - return weTestUtils.createWysiwyg({ - wysiwygOptions: { - snippets: true, - value: - '
' + - '
' + - ' ' + - '
' + - '

test

' + - '

test

', - }, - }).then(async function (wysiwyg) { - var $editable = wysiwyg.getEditable(); - - await testUtils.dom.click($editable.find('.s_hr img').mousedown()); - assert.strictEqual($('.note-popover:visible').length, 1, "should display the image popover"); - - var $handle = $('#oe_manipulators .o_handle.s'); - testUtils.dom.dragAndDrop($handle, $editable.find('b'), { - disableDrop: true, - }); - assert.ok($handle.hasClass('o_active'), "should active the handle"); - assert.notOk($handle.hasClass('pb32'), "should change the padding bottom"); - assert.strictEqual($('.note-popover:visible').length, 0, "should hide the image popover"); - await testUtils.dom.dragAndDrop($handle, $editable.find('b'), { - continueMove: true, - }); - - wysiwyg.destroy(); - done(); - }); -}); - -QUnit.test('clean the dom before save, after drag&drop', function (assert) { - var done = assert.async(); - assert.expect(1); - - return weTestUtils.createWysiwyg({ - wysiwygOptions: { - snippets: true, - value: '

toto toto toto

tata

', - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.getEditable(); - - var $hr = wysiwyg.snippets.$('.oe_snippet_thumbnail:first'); - testUtils.dom.dragAndDrop($hr, $editable.find('p')); - - testUtils.mock.intercept(wysiwyg, "snippet_focused", function () { - wysiwyg.save().then(function (result) { - var isDirty = result.isDirty; - var html = result.html; - assert.strictEqual(html.replace(/\s+/g, ' '), - '

toto toto toto


tata

', - "should clean the snippet"); - - wysiwyg.destroy(); - done(); - }); - }); - }); -}); - -QUnit.test('clean the dom before save', function (assert) { - var done = assert.async(); - assert.expect(1); - - return weTestUtils.createWysiwyg({ - wysiwygOptions: { - snippets: true, - value: '

', - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.getEditable(); - - testUtils.mock.intercept(wysiwyg, "snippet_focused", function () { - // add dirty flag to remove warning because the cleaned dom is different of the initial value and no dirty flag - $editable.find('.s_hr').keydown(); - - // trigger change to avoid warning because the DOM change on clean without trigger onchange by snippet or edition - $editable.trigger('content_changed'); - - wysiwyg.save().then(function (result) { - assert.strictEqual(result.html.replace(/\s+/g, ' '), - '

', - "should clean the snippet"); - - wysiwyg.destroy(); - done(); - }); - }); - - $editable.find('.s_hr').mousedown().click(); - }); -}); - -QUnit.test('remove snippet', function (assert) { - var done = assert.async(); - assert.expect(2); - - return weTestUtils.createWysiwyg({ - wysiwygOptions: { - snippets: true, - value: '

', - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.getEditable(); - - testUtils.mock.intercept(wysiwyg, "snippet_focused", function () { - $('.note-btn-bold').removeClass('o_disabled'); - $('#oe_manipulators .oe_overlay_options .oe_snippet_remove').click(); - assert.ok($('.note-btn-bold').hasClass('o_disabled')); - - wysiwyg.save().then(function (result) { - assert.strictEqual(result.html.replace(/\s+/g, ' '), '', "should remove the snippet"); - - wysiwyg.destroy(); - done(); - }); - }); - - $editable.find('.s_hr').mousedown().click(); - }); -}); - -QUnit.test('move a snippet', function (assert) { - var done = assert.async(); - assert.expect(1); - - return weTestUtils.createWysiwyg({ - wysiwygOptions: { - snippets: true, - value: '

test

test

', - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.getEditable(); - - var first = true; - testUtils.mock.intercept(wysiwyg, "snippet_focused", function () { - if (first) { - first = false; - var $hr = $('#oe_manipulators .oe_overlay_options .oe_snippet_move'); - testUtils.dom.dragAndDrop($hr, $editable.find('b')); - } else { - wysiwyg.save().then(function (result) { - assert.strictEqual(result.html.replace(/\s+/g, ' '), - '

test


test

', - "should move the snippet on the bottom"); - - wysiwyg.destroy(); - done(); - }); - } - }); - - $editable.find('.s_hr').mousedown().click(); - }); -}); - -QUnit.test('clone a snippet', function (assert) { - var done = assert.async(); - assert.expect(2); - - return weTestUtils.createWysiwyg({ - wysiwygOptions: { - snippets: true, - value: '

test

test

', - }, - }).then(async function (wysiwyg) { - var $editable = wysiwyg.getEditable(); - - testUtils.mock.intercept(wysiwyg, "snippet_focused", async function () { - await testUtils.dom.click($('#oe_manipulators .oe_overlay_options .oe_snippet_clone')); - - assert.strictEqual($editable.html().replace(/\s+/g, ' '), - '


test

test

', - "should duplicate the snippet"); - - wysiwyg.save().then(function (result) { - assert.strictEqual(result.html.replace(/\s+/g, ' '), - '


test

test

', - "should duplicate the snippet"); - - wysiwyg.destroy(); - done(); - }); - }); - - await testUtils.dom.click($editable.find('.s_hr').mousedown()); - }); -}); - -QUnit.test('customize snippet', function (assert) { - var done = assert.async(); - assert.expect(2); - - return weTestUtils.createWysiwyg({ - wysiwygOptions: { - snippets: true, - value: '

test


test

', - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.getEditable(); - - testUtils.mock.intercept(wysiwyg, "snippet_focused", function () { - $('#oe_manipulators .oe_overlay_options .oe_options a:first').click(); - var $option = $('#oe_manipulators .oe_overlay_options a[data-select-class="align-items-center"]'); - - // assert.strictEqual($option.size(), 1, "should display the snippet option"); - - $option.click(); - - assert.strictEqual($editable.html().replace(/\s+/g, ' '), - '

test


test

', - "should customized the snippet"); - - $('#oe_manipulators .oe_overlay_options .oe_options a:first').click(); - $('#oe_manipulators .oe_overlay_options a[data-select-class="align-items-end"]').click(); - - assert.strictEqual($editable.html().replace(/\s+/g, ' '), - '

test


test

', - "should twice customized the snippet"); - - wysiwyg.destroy(); - done(); - }); - - $editable.find('.s_hr').mousedown().click(); - }); -}); - -QUnit.test('background-image', function (assert) { - var done = assert.async(); - assert.expect(2); - - return weTestUtils.createWysiwyg({ - wysiwygOptions: { - snippets: true, - value: - '

Big Title

' + - '
' + - '
' + - '
' + - '
' + - '

Title

' + - '

Content

' + - '
' + - '
' + - '
' + - '
', - }, - mockRPC: function (route, args) { - if (route.indexOf('/web_editor/static/src/img/') === 0) { - return Promise.resolve(); - } - return this._super(route, args); - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.getEditable(); - - var defMediaDialogInit = testUtils.makeTestPromise(); - var defMediaDialogSave = testUtils.makeTestPromise(); - testUtils.mock.patch(MediaDialog, { - init: function () { - this._super.apply(this, arguments); - this.opened(defMediaDialogInit.resolve.bind(defMediaDialogInit)); - }, - save: function () { - Promise.resolve(this._super.apply(this, arguments)).then(function () { - defMediaDialogSave.resolve(); - }); - }, - }); - - testUtils.mock.intercept(wysiwyg, "snippet_focused", function () { - $('#oe_manipulators .oe_overlay_options .oe_options a:first').click(); - $('#oe_manipulators .oe_overlay_options a.snippet-option-background[data-choose-image]').click(); - - defMediaDialogInit.then(function () { - $('.o_select_media_dialog .o_we_existing_attachments .o_existing_attachment_cell').click(); - $('.o_select_media_dialog .modal-footer .btn-primary').click(); - }); - - defMediaDialogSave.then(function () { - var $snippet = $editable.find('.test_option_all'); - assert.ok($snippet.hasClass('oe_custom_bg'), "should use custom background"); - var background = $snippet.css('background-image') || ''; - assert.strictEqual(background.replace(/[^(\("'\/]+\/\/[^\("'\/]+/, ''), - 'url("/web_editor/static/src/img/transparent.png")', - "should change the background image"); - - testUtils.mock.unpatch(MediaDialog); - wysiwyg.destroy(); - done(); - }); - }); - - $editable.find('h2').mousedown().click(); - }); -}); - -QUnit.test('update content', function (assert) { - var done = assert.async(); - assert.expect(1); - - return weTestUtils.createWysiwyg({ - wysiwygOptions: { - snippets: true, - value: '
' + - ' ' + - '
', - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.getEditable(); - - testUtils.mock.intercept(wysiwyg, "snippet_focused", function () { - var $snippetOption = $('#oe_manipulators .oe_overlay_options:visible'); - wysiwyg.$el.siblings('.note-image-popover').find('.note-media .note-icon-trash').mousedown().click(); - assert.ok($snippetOption.is(':hidden'), "should remove the snippet editor because the target are removed"); - - wysiwyg.destroy(); - done(); - }); - - $editable.find('img').mousedown().click(); - }); -}); - -}); -}); -}); -}); diff --git a/addons/web_editor/static/tests/wysiwyg_tests.js b/addons/web_editor/static/tests/wysiwyg_tests.js deleted file mode 100644 index 9a5fbb103cc..00000000000 --- a/addons/web_editor/static/tests/wysiwyg_tests.js +++ /dev/null @@ -1,4182 +0,0 @@ -odoo.define('web_editor.wysiwyg_tests', function (require) { -"use strict"; - -var testUtils = require('web.test_utils'); -var weTestUtils = require('web_editor.test_utils'); -var Wysiwyg = require('web_editor.wysiwyg'); -var AltDialog = require('wysiwyg.widgets.AltDialog'); -var CropDialog = require('wysiwyg.widgets.CropImageDialog'); - -var testName = ""; -var carretTestSuffix = " (carret position)"; - -QUnit.module('web_editor', { - afterEach: function () { - $('body').removeClass('modal-open'); - $('.note-popover, .modal, .modal-backdrop').remove(); - }, -}, function () { -QUnit.module('wysiwyg', {}, function () { -QUnit.module('toolbar', {}, function () { - -QUnit.test('Magic wand', async function (assert) { - assert.expect(8); - - var wysiwyg = await weTestUtils.createWysiwyg({ - debug: false, - wysiwygOptions: { - - }, - }); - var $editable = wysiwyg.$('.note-editable'); - - var $dropdownStyle = wysiwyg.$('.note-style .dropdown-toggle'); - var $btnsStyle = wysiwyg.$('.note-style .dropdown-menu .dropdown-item'); - - var wandTests = [{ - name: "Click H1: p -> h1", - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - do: async function () { - await testUtils.dom.triggerEvents($dropdownStyle, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnsStyle.find('h1'), ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'h1:contents()[0]->0', - end: 'h1:contents()[0]->11', - }, - }, - { - name: "Click CODE: h1 -> pre", - content: '

dom not to edit

dom to edit

', - start: 'h1:contents()[0]->1', - do: async function () { - await testUtils.dom.triggerEvents($dropdownStyle, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnsStyle.find('pre'), ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit
', - start: 'pre:contents()[0]->0', - end: 'pre:contents()[0]->11', - }, - }, - { - name: "Click NORMAL: pre -> p", - content: '

dom not to edit

dom to edit
', - start: 'pre:contents()[0]->1', - do: async function () { - await testUtils.dom.triggerEvents($dropdownStyle, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnsStyle.find('p'), ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->0', - end: 'p:eq(1):contents()[0]->11', - }, - }, - { - name: "Click H1 in empty p: empty p -> empty h1", - content: '


', - start: 'p->1', - do: async function () { - await testUtils.dom.triggerEvents($dropdownStyle, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnsStyle.find('h1'), ['mousedown', 'click']); - }, - test: { - content: '


', - start: 'h1:contents()[0]->0', - }, - }, - ]; - - var def = Promise.resolve(); - wandTests.forEach(function (test) { - def = def.then(async function() { - testName = test.name; - wysiwyg.setValue(test.content); - var range = weTestUtils.select(test.start, test.end, $editable); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - await testUtils.nextTick(); - await test.do(); - assert.deepEqual(wysiwyg.getValue(), test.test.content, testName); - assert.deepEqual(Wysiwyg.getRange($editable[0]), weTestUtils.select(test.test.start, test.test.end, $editable), testName + carretTestSuffix); - }); - }); - - return def.then(function() { - wysiwyg.destroy(); - }); -}); - -QUnit.test('Font style', function (assert) { - assert.expect(58); - - return weTestUtils.createWysiwyg({ - debug: false, - wysiwygOptions: { - generateOptions: function (options) { - options.toolbar[1][1] = ['bold', 'italic', 'underline', 'strikethrough', 'superscript', 'subscript', 'clear']; - }, - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.$('.note-editable'); - - var $btnBold = wysiwyg.$('.note-font .note-btn-bold'); - var $btnItalic = wysiwyg.$('.note-font .note-btn-italic'); - var $btnUnderline = wysiwyg.$('.note-font .note-btn-underline'); - var $strikethrough = wysiwyg.$('.note-font .note-icon-strikethrough'); - var $superscript = wysiwyg.$('.note-font .note-icon-superscript'); - var $subscript = wysiwyg.$('.note-font .note-icon-subscript'); - var $btnRemoveStyles = wysiwyg.$('.note-font .btn-sm .note-icon-eraser'); - - var styleTests = [ - /* BOLD */ - { - name: "Click BOLD: normal -> bold", - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'b:contents()[0]->0', - end: 'b:contents()[0]->4', - }, - }, - { - name: "Click BOLD then 'a': normal -> bold (empty p)", - content: '


', - start: 'p->1', - do: async function () { - await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']); - weTestUtils.keydown('a', $editable); - }, - test: { - content: '

a

', - start: 'b:contents()[0]->1', - }, - }, - { - name: "Click BOLD: normal -> bold (across paragraphs)", - content: '

dom to edit

dom to edit

', - start: 'p:contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']); - }, - test: { - content: '

dom to edit

dom to edit

', - start: 'b:contents()[0]->0', - end: 'b:eq(1):contents()[0]->5', - }, - }, - { - name: "Click BOLD then 'a': normal -> bold (no selection)", - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->4', - do: async function () { - await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']); - weTestUtils.keydown('a', $editable); - }, - test: { - content: '

dom not to edit

dom ato edit

', - start: 'b:contents()[0]->1', - }, - }, - { - name: "Click BOLD: bold -> normal", - content: '

dom not to edit

dom to edit

', - start: 'b:contents()[0]->0', - end: 'b:contents()[0]->11', - do: async function () { - await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->0', - end: 'p:eq(1):contents()[0]->11', - }, - }, - { - name: "Click BOLD: bold -> normal (partial selection)", - content: '

dom not to edit

dom to edit

', - start: 'b:contents()[0]->4', - end: 'b:contents()[0]->6', - do: async function () { - await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[1]->0', - end: 'p:eq(1):contents()[1]->2', - }, - }, - { - name: "Click BOLD: bold -> normal (no selection)", - content: '

dom not to edit

dom to edit

', - start: 'b:contents()[0]->4', - do: async function () { - await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom \u200Bto edit

', - start: 'p:eq(1):contents()[1]->1', - }, - }, - { - name: "Click BOLD: bold + normal -> normal", - content: '

dom to edit

', - start: 'b:contents()[0]->1', - end: 'p:contents()[1]->4', - do: async function () { - await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']); - }, - test: { - content: '

dom to edit

', - start: 'b:contents()[0]->1', - end: 'b:contents()[0]->8', - }, - }, - { - name: "Click BOLD: normal -> bold (with fontawesome)", - content: '

aaabbb

', - start: 'p:contents()[0]->1', - end: 'p:contents()[2]->2', - do: async function () { - await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']); - }, - test: { - content: '

aaabbb

', - start: 'b:contents()[0]->0', - end: 'b:contents()[2]->2', - }, - }, - { - name: "Click BOLD + click BOLD: normal -> bold -> normal (with fontawesome)", - content: '

aaabbb

', - start: 'p:contents()[0]->1', - end: 'p:contents()[2]->2', - do: async function () { - await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']); - }, - test: { - content: '

aaabbb

', - start: 'p:contents()[0]->1', - end: 'p:contents()[2]->2', - }, - }, - { - name: "Click BOLD: bold -> normal (with fontawesome)", - content: '

aaabbb

', - start: 'b:contents()[0]->1', - end: 'b:contents()[2]->2', - do: async function () { - await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']); - }, - test: { - content: '

aaabbb

', - start: 'p:contents()[1]->0', - end: 'p:contents()[3]->2', - }, - }, - { - name: "Click BOLD: bold -> normal (at start of dom)", - content: '

abc

', - start: 'b:contents()[0]->0', - do: function () { - $btnBold.mousedown().click(); - }, - test: { - content: '

\u200Babc

', - start: 'p:contents()[0]->1', - end: 'p:contents()[0]->1', - }, - }, - /* ITALIC */ - { - name: "Click ITALIC: bold -> bold + italic", - content: '

dom not to edit

dom to edit

', - start: 'b:contents()[0]->1', - end: 'b:contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($btnItalic, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'i:contents()[0]->0', - end: 'i:contents()[0]->4', - }, - }, - { - name: "Click ITALIC: bold & normal -> italic & bold + italic (across paragraphs)", - content: '

dom to edit

dom to edit

', - start: 'p:contents()[0]->1', - end: 'b:eq(1):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($btnItalic, ['mousedown', 'click']); - }, - test: { - content: '

dom to edit

dom to edit

', - start: 'i:contents()[0]->0', - end: 'i:eq(1):contents()[0]->5', - }, - }, - /* UNDERLINE */ - { - name: "Click UNDERLINE: bold -> bold + underlined", - content: '

dom not to edit

dom to edit

', - start: 'b:contents()[0]->1', - end: 'b:contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($btnUnderline, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'u:contents()[0]->0', - end: 'u:contents()[0]->4', - }, - }, - { - name: "Click UNDERLINE: bold & normal -> underlined & bold + underlined (across paragraphs)", - content: '

dom to edit

dom to edit

', - start: 'p:contents()[0]->1', - end: 'b:eq(1):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($btnUnderline, ['mousedown', 'click']); - }, - test: { - content: '

dom to edit

dom to edit

', - start: 'u:contents()[0]->0', - end: 'u:eq(1):contents()[0]->5', - }, - }, - /* strikethrough */ - { - name: "Click strikethrough: bold -> bold + strikethrough", - content: '

dom not to edit

dom to edit

', - start: 'b:contents()[0]->1', - end: 'b:contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($strikethrough, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 's:contents()[0]->0', - end: 's:contents()[0]->4', - }, - }, - { - name: "Click strikethrough: bold & normal -> strikethrough & bold + strikethrough (across paragraphs)", - content: '

dom to edit

dom to edit

', - start: 'p:contents()[0]->1', - end: 'b:eq(1):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($strikethrough, ['mousedown', 'click']); - }, - test: { - content: '

dom to edit

dom to edit

', - start: 's:contents()[0]->0', - end: 's:eq(1):contents()[0]->5', - }, - }, - /* superscript */ - { - name: "Click superscript: bold -> bold + superscript", - content: '

dom not to edit

dom to edit

', - start: 'b:contents()[0]->1', - end: 'b:contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($superscript, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'sup:contents()[0]->0', - end: 'sup:contents()[0]->4', - }, - }, - { - name: "Click superscript: bold & normal -> superscript & bold + superscript (across paragraphs)", - content: '

dom to edit

dom to edit

', - start: 'p:contents()[0]->1', - end: 'b:eq(1):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($superscript, ['mousedown', 'click']); - }, - test: { - content: '

dom to edit

dom to edit

', - start: 'sup:contents()[0]->0', - end: 'sup:eq(1):contents()[0]->5', - }, - }, - /* subscript */ - { - name: "Click subscript: bold -> bold + subscript", - content: '

dom not to edit

dom to edit

', - start: 'b:contents()[0]->1', - end: 'b:contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($subscript, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'sub:contents()[0]->0', - end: 'sub:contents()[0]->4', - }, - }, - { - name: "Click subscript: bold & normal -> subscript & bold + subscript (across paragraphs)", - content: '

dom to edit

dom to edit

', - start: 'p:contents()[0]->1', - end: 'b:eq(1):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($subscript, ['mousedown', 'click']); - }, - test: { - content: '

dom to edit

dom to edit

', - start: 'sub:contents()[0]->0', - end: 'sub:eq(1):contents()[0]->5', - }, - }, - /* REMOVE FONT STYLE */ - { - name: "Click REMOVE FONT STYLE: bold -> normal", - content: '

dom not to edit

dom to edit

', - start: 'b:contents()[0]->1', - end: 'b:contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($btnRemoveStyles, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[1]->0', - end: 'p:eq(1):contents()[1]->4', - }, - }, - { - name: "Click REMOVE FONT STYLE: bold, italic, underlined & normal -> normal (across paragraphs)", - content: '

dom to edit

dom to edit

', - start: 'p:contents()[0]->1', - end: 'u:eq(1):contents()[0]->3', - do: async function () { - await testUtils.dom.triggerEvents($btnRemoveStyles, ['mousedown', 'click']); - }, - test: { - content: '

dom to edit

dom to edit

', - start: 'p:contents()[0]->1', - end: 'p:eq(1):contents()[0]->3', - }, - }, - { - name: "Click REMOVE FONT STYLE: complex -> normal", - content: '

aaabbb

ccc

', - start: 'p:contents()[0]->1', - end: 'font:eq(1):contents()[0]->1', - do: async function () { - await testUtils.dom.triggerEvents($btnRemoveStyles, ['mousedown', 'click']); - }, - test: { - content: '

aaabbb

ccc

', - start: 'p:contents()[0]->1', - end: 'p:eq(1):contents()[0]->1', - }, - }, - { - name: "Click REMOVE FONT STYLE: complex -> normal (with icon)", - content: '

aaabbb

', - start: 'p:contents()[0]->0', - end: 'i:contents()[0]->1', - do: async function () { - await testUtils.dom.triggerEvents($btnRemoveStyles, ['mousedown', 'click']); - }, - test: { - content: '

aaabbb

', - start: 'p:contents()[0]->0', - end: 'p:contents()[2]->2', - }, - }, - /* COMPLEX */ - { - name: "COMPLEX Click BOLD: italic -> italic bold (partial selection)", - content: '

dom not to edit

dom to edit

', - start: 'i:contents()[0]->1', - end: 'i:contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'b:contents()[0]->0', - end: 'b:contents()[0]->4', - }, - }, - { - name: "COMPLEX Click BOLD then 'a': italic bold -> italic (across paragraphs)", - content: '

dom to edit

dom to edit

', - start: 'i:contents()[0]->1', - end: 'b:eq(1):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']); - weTestUtils.keydown('a', $editable, { - firstDeselect: true, - }); - }, - test: { - content: '

dom to edit

dom tao edit

', - }, - }, - { - name: "COMPLEX Click BOLD then 'a': bold italic -> italic (no selection)", - content: '

dom to edit

', - start: 'i:contents()[0]->4', - do: async function () { - await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']); - weTestUtils.keydown('a', $editable, { - firstDeselect: true, - }); - }, - test: { - content: '

dom ato edit

', - }, - }, - { - name: "COMPLEX Click BOLD then 'a': underlined italic -> underlined italic bold (across paragraphs)", - content: '

dom to edit

dom to edit

', - start: 'i:contents()[0]->1', - end: 'u:eq(1):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']); - weTestUtils.keydown('a', $editable, { - firstDeselect: true, - }); - }, - test: { - content: '

dom to edit

dom tao edit

', - }, - }, - { - name: "COMPLEX Click BOLD then 'a': underlined italic -> underlined italic bold (no selection)", - content: '

dom to edit

', - start: 'i:contents()[0]->1', - do: async function () { - await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']); - weTestUtils.keydown('a', $editable, { - firstDeselect: true, - }); - }, - test: { - content: '

daom to edit

', - }, - }, - ]; - - var def = Promise.resolve(); - _.each(styleTests, function (test) { - def = def.then(async function() { - testName = test.name; - wysiwyg.setValue(test.content); - test.end = test.end || test.start; - var range = weTestUtils.select(test.start, test.end, $editable); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - await test.do(); - assert.deepEqual(wysiwyg.getValue(), test.test.content, testName); - $editable[0].normalize(); - if (test.test.start) { - test.test.end = test.test.end || test.test.start; - assert.deepEqual(Wysiwyg.getRange($editable[0]), weTestUtils.select(test.test.start, test.test.end, $editable), testName + carretTestSuffix); - } - }); - }); - - return def.then(function() { - wysiwyg.destroy(); - }); - }); -}); - -QUnit.test('Font size', function (assert) { - assert.expect(10); - - return weTestUtils.createWysiwyg({ - debug: false, - wysiwygOptions: { - - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.$('.note-editable'); - - var $dropdownFontSize = wysiwyg.$('.note-fontsize .dropdown-toggle'); - var $linksFontSize = wysiwyg.$('.note-fontsize .dropdown-menu .dropdown-item'); - - var sizeTests = [{ - name: "Click 18: default -> 18px", - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($dropdownFontSize, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($linksFontSize.filter(':contains("18")'), ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'font:contents()[0]->0', - end: 'font:contents()[0]->4', - }, - }, - { - name: "Click DEFAULT: 18px -> default", - content: '

dom not to edit

dom to edit

', - start: 'font:contents()[0]->1', - end: 'font:contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($dropdownFontSize, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($linksFontSize.filter(':contains("Default")'), ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[1]->0', - end: 'p:eq(1):contents()[1]->4', - }, - }, - { - name: "Click 18: 26px -> 18px", - content: '

dom to edit

', - start: 'font:contents()[0]->1', - end: 'font:contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($dropdownFontSize, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($linksFontSize.filter(':contains("18")'), ['mousedown', 'click']); - }, - test: { - content: '

' + - 'd' + - 'om t' + - 'o edit

', - start: 'font:eq(1):contents()[0]->0', - end: 'font:eq(1):contents()[0]->4', - }, - }, - { - name: "Click 18 then 'a' (no selection): default -> 18px", - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - do: async function () { - await testUtils.dom.triggerEvents($dropdownFontSize, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($linksFontSize.filter(':contains("18")'), ['mousedown', 'click']); - weTestUtils.keydown('a', $editable, { - firstDeselect: true, - }); - }, - test: { - content: '

dom not to edit

daom to edit

', - start: 'font:contents()[0]->1', - }, - }, - { - name: "Click 18 then 'a' (no selection): 26px -> 18px", - content: '

dom to edit

', - start: 'font:contents()[0]->1', - do: async function () { - await testUtils.dom.triggerEvents($dropdownFontSize, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($linksFontSize.filter(':contains("18")'), ['mousedown', 'click']); - weTestUtils.keydown('a', $editable, { - firstDeselect: true, - }); - }, - test: { - content: '

' + - 'd' + - 'a' + - 'om to edit

', - start: 'font:eq(1):contents()[0]->1', - }, - }, - ]; - - var def = Promise.resolve(); - _.each(sizeTests, function (test) { - def = def.then(async function() { - testName = test.name; - wysiwyg.setValue(test.content); - var range = weTestUtils.select(test.start, test.end, $editable); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - await test.do(); - assert.deepEqual(wysiwyg.getValue(), test.test.content, testName); - assert.deepEqual(Wysiwyg.getRange($editable[0]), weTestUtils.select(test.test.start, test.test.end, $editable), testName + carretTestSuffix); - }); - }); - - return def.then(function() { - wysiwyg.destroy(); - }); - }); -}); - -QUnit.test('Text forecolor', function (assert) { - assert.expect(40); - - return weTestUtils.createWysiwyg({ - debug: false, - wysiwygOptions: { - - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.$('.note-editable'); - - var $dropdownForeColor = wysiwyg.$('.note-color .note-fore-color .dropdown-toggle'); - var $btnsForeColor = wysiwyg.$('.note-color .note-fore-color .dropdown-menu .note-palette .note-color-btn'); - var forecolorTests = [{ - name: "Click THEME COLORS - ALPHA: default -> alpha theme color", - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($dropdownForeColor, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnsForeColor.filter('.bg-alpha'), ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'font:contents()[0]->0', - end: 'font:contents()[0]->4', - }, - }, - { - name: "Click THEME COLORS - BLACK 25: alpha theme color & default -> black 25", - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'font:contents()[0]->3', - do: async function () { - await testUtils.dom.triggerEvents($dropdownForeColor, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnsForeColor.filter('.bg-black-25'), ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'font:contents()[0]->0', - end: 'font:contents()[0]->4', - }, - }, - { - name: "Click COMMON COLORS - BLUE #0000FF: black 25 & default -> blue #0000FF", - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'font:contents()[0]->3', - do: async function () { - await testUtils.dom.triggerEvents($dropdownForeColor, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnsForeColor.filter('[style="background-color:#0000FF"]'), ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'font:contents()[0]->0', - end: 'font:contents()[0]->4', - }, - }, - { - name: "Click RESET TO DEFAULT: black 25 & default -> default", - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'font:contents()[0]->3', - do: async function () { - await testUtils.dom.triggerEvents($dropdownForeColor, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnsForeColor.filter('.note-color-reset'), ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - }, - }, - { - name: "Click CUSTOM COLORS then CUSTOM COLOR: blue #0000FF & default -> #875A7B", - async: true, - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'font:contents()[0]->3', - do: async function () { - var self = this; - - await testUtils.dom.triggerEvents($dropdownForeColor, ['mousedown', 'click']); - await testUtils.dom.triggerEvents(wysiwyg.$('.note-color .note-fore-color .note-custom-color'), ['mousedown', 'click']); - - $('.modal-dialog .o_hex_input').val('#875A7B').change(); - await testUtils.dom.triggerEvents($('.o_technical_modal .modal-footer .btn-primary:contains("Choose")'), ['mousedown', 'click']); - await testUtils.dom.triggerEvents(wysiwyg.$('.note-color .note-fore-color .note-custom-color-btn:last'), ['mousedown', 'click']); - - assert.deepEqual(wysiwyg.getValue(), - '

dom not to edit

dom to edit

', - self.name); - var range = weTestUtils.select('font:contents()[0]->0', 'font:contents()[0]->4', $editable); - assert.deepEqual(Wysiwyg.getRange($editable[0]), range, self.name + carretTestSuffix); - }, - }, - { - name: "Click CUSTOM COLORS then CUSTOM COLOR: change blue input", - content: '

dom to edit

', - start: 'p:contents()[0]->1', - end: 'p:contents()[0]->6', - do: async function () { - var self = this; - - await testUtils.dom.triggerEvents($dropdownForeColor, ['mousedown', 'click']); - await testUtils.dom.triggerEvents(wysiwyg.$('.note-color .note-fore-color .note-custom-color'), ['mousedown', 'click']); - - $('.modal-dialog .o_blue_input').val('100').change(); - - assert.deepEqual($('.modal-dialog .o_hex_input').val(), '#ff0064', self.name + ' (hex)'); - assert.deepEqual($('.modal-dialog .o_hue_input').val(), '337', self.name + ' (hue)'); - - await testUtils.dom.triggerEvents($('.o_technical_modal .modal-footer .btn-primary:contains("Choose")'), ['mousedown', 'click']); - await testUtils.dom.triggerEvents(wysiwyg.$('.note-color .note-fore-color .note-custom-color-btn:last'), ['mousedown', 'click']); - }, - test: { - content: '

dom to edit

', - start: 'font:contents()[0]->0', - end: 'font:contents()[0]->5', - }, - }, - { - name: "CUSTOM COLOR: change hue, saturation and lightness inputs", - content: '

dom to edit

', - start: 'p:contents()[0]->1', - end: 'p:contents()[0]->6', - do: async function () { - var self = this; - - await testUtils.dom.triggerEvents($dropdownForeColor, ['mousedown', 'click']); - await testUtils.dom.triggerEvents(wysiwyg.$('.note-color .note-fore-color .note-custom-color'), ['mousedown', 'click']); - - $('.modal-dialog .o_hue_input').val('337').change(); - $('.modal-dialog .o_saturation_input').val('50').change(); - $('.modal-dialog .o_lightness_input').val('40').change(); - - assert.deepEqual($('.modal-dialog .o_hex_input').val(), '#99335a', self.name + ' (hex)'); - assert.deepEqual($('.modal-dialog .o_green_input').val(), '51', self.name + ' (green)'); - - await testUtils.dom.triggerEvents($('.o_technical_modal .modal-footer .btn-primary:contains("Choose")'), ['mousedown', 'click']); - await testUtils.dom.triggerEvents(wysiwyg.$('.note-color .note-fore-color .note-custom-color-btn:last'), ['mousedown', 'click']); - }, - test: { - content: '

dom to edit

', - start: 'font:contents()[0]->0', - end: 'font:contents()[0]->5', - }, - }, - { - name: "CUSTOM COLOR: mousedown on area", - content: '

dom to edit

', - start: 'p:contents()[0]->1', - end: 'p:contents()[0]->6', - do: async function () { - var self = this; - - await testUtils.dom.triggerEvents($dropdownForeColor, ['mousedown', 'click']); - await testUtils.dom.triggerEvents(wysiwyg.$('.note-color .note-fore-color .note-custom-color'), ['mousedown', 'click']); - - var $area = $('.modal-dialog .o_color_pick_area'); - var pos = $area.offset(); - $area.trigger($.Event("mousedown", { - which: 1, - pageX: pos.left + 50, - pageY: pos.top + 50 - })); - $area.trigger('mouseup'); - - assert.deepEqual($('.modal-dialog .o_hex_input').val(), '#cfafaf', self.name + ' (hex)'); - assert.deepEqual($('.modal-dialog .o_red_input').val(), '207', self.name + ' (red)'); - assert.deepEqual($('.modal-dialog .o_green_input').val(), '175', self.name + ' (green)'); - assert.deepEqual($('.modal-dialog .o_blue_input').val(), '175', self.name + ' (blue)'); - assert.deepEqual($('.modal-dialog .o_hue_input').val(), '0', self.name + ' (hue)'); - assert.deepEqual($('.modal-dialog .o_saturation_input').val(), '25', self.name + ' (saturation)'); - assert.deepEqual($('.modal-dialog .o_lightness_input').val(), '75', self.name + ' (lightness)'); - - await testUtils.dom.triggerEvents($('.o_technical_modal .modal-footer .btn-primary:contains("Choose")'), ['mousedown', 'click']); - await testUtils.dom.triggerEvents(wysiwyg.$('.note-color .note-fore-color .note-custom-color-btn:last'), ['mousedown', 'click']); - }, - test: { - content: '

dom to edit

', - start: 'font:contents()[0]->0', - end: 'font:contents()[0]->5', - }, - }, - { - name: "CUSTOM COLOR: mousedow on sliders", - content: '

dom to edit

', - start: 'p:contents()[0]->1', - end: 'p:contents()[0]->6', - do: async function () { - var self = this; - - await testUtils.dom.triggerEvents($dropdownForeColor, ['mousedown', 'click']); - await testUtils.dom.triggerEvents(wysiwyg.$('.note-color .note-fore-color .note-custom-color'), ['mousedown', 'click']); - - var $slider1 = $('.modal-dialog .o_slider_pointer'); - var pos1 = $slider1.offset(); - $slider1.trigger($.Event("mousedown", { - which: 1, - pageX: pos1.left, - pageY: pos1.top + 50 - })); - $slider1.trigger('mouseup'); - - assert.deepEqual($('.modal-dialog .o_hex_input').val(), '#83ff00', self.name + ' (hex)'); - - var $slider2 = $('.modal-dialog .o_opacity_slider'); - var pos2 = $slider2.offset(); - $slider2.trigger($.Event("mousedown", { - which: 1, - pageX: pos2.left, - pageY: pos2.top + 80 - })); - $slider2.trigger('mouseup'); - - assert.deepEqual($('.modal-dialog .o_hue_input').val(), '89', self.name + ' (hue)'); - assert.deepEqual($('.modal-dialog .o_opacity_input').val(), '60', self.name + ' (opacity)'); - - await testUtils.dom.triggerEvents($('.o_technical_modal .modal-footer .btn-primary:contains("Choose")'), ['mousedown', 'click']); - await testUtils.dom.triggerEvents(wysiwyg.$('.note-color .note-fore-color .note-custom-color-btn:last'), ['mousedown', 'click']); - }, - test: { - content: '

dom to edit

', - start: 'font:contents()[0]->0', - end: 'font:contents()[0]->5', - }, - }, - { - name: "Apply a color on a fontawesome", - content: '

dom not to edit

', - start: 'i->0', - do: async function () { - await testUtils.dom.triggerEvents($dropdownForeColor, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnsForeColor.filter('[style="background-color:#0000FF"]'), ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

', - start: 'p->2', - }, - }, - { - name: "Apply a color on a font with text", - content: '

dom not to edit

', - start: 'p:contents()[0]->1', - end: 'p:contents()[2]->6', - do: async function () { - await testUtils.dom.triggerEvents($dropdownForeColor, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnsForeColor.filter('[style="background-color:#0000FF"]'), ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

', - start: 'font:eq(0):contents()[0]->0', - end: 'font:eq(1):contents()[0]->6', - }, - }, - { - name: "Apply color, then 'a' (no selection)", - content: '

dom not to edit

', - start: 'p:contents()[0]->1', - do: async function () { - await testUtils.dom.triggerEvents($dropdownForeColor, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnsForeColor.filter('[style="background-color:#0000FF"]'), ['mousedown', 'click']); - weTestUtils.keydown('a', $editable, { - firstDeselect: true, - }); - }, - test: { - content: '

daom not to edit

', - start: 'font:contents()[0]->1', - }, - }, - { - name: "Apply color on two ranges with the same color", - content: '

do
m not to edit

', - start: 'p:contents()[0]->1', - end: 'p:contents()[3]->4', - do: async function ($editable) { - await testUtils.dom.triggerEvents($dropdownForeColor, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnsForeColor.filter('[style="background-color:#0000FF"]'), ['mousedown', 'click']); - - var range = weTestUtils.select('p:contents()[5]->3', 'p:contents()[5]->6', $editable); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - - await testUtils.dom.triggerEvents($dropdownForeColor, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnsForeColor.filter('[style="background-color:#0000FF"]'), ['mousedown', 'click']); - }, - test: { - content: '

do
m not to edit

', - start: 'font:eq(2):contents()[0]->0', - end: 'font:eq(2):contents()[0]->3', - }, - }, - ]; - - var def = Promise.resolve(); - _.each(forecolorTests, function (test) { - def = def.then(function () { - testName = test.name; - wysiwyg.setValue(test.content); - var range = weTestUtils.select(test.start, test.end, $editable); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - return Promise.resolve(test.do($editable)).then(function () { - if (!test.async) { - assert.deepEqual(wysiwyg.getValue(), test.test.content, testName); - assert.deepEqual(Wysiwyg.getRange($editable[0]), weTestUtils.select(test.test.start, test.test.end, $editable), testName + carretTestSuffix); - } - }); - }); - }); - return def.then(function () { - wysiwyg.destroy(); - }); - }); -}); - -QUnit.test('Text bgcolor', function (assert) { - assert.expect(10); - - return weTestUtils.createWysiwyg({ - debug: false, - wysiwygOptions: { - - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.$('.note-editable'); - var testName = ""; - var carretTestSuffix = " (carret position)"; - - var $dropdownBgColor = wysiwyg.$('.note-color .note-bg-color .dropdown-toggle'); - var $btnsBgColor = wysiwyg.$('.note-color .note-bg-color .dropdown-menu .note-palette .note-color-btn'); - - var bgcolorTests = [{ - name: "Click THEME COLORS - ALPHA: default -> alpha theme color", - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($dropdownBgColor, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnsBgColor.filter('.bg-alpha'), ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'font:contents()[0]->0', - end: 'font:contents()[0]->4', - }, - }, - { - name: "Click THEME COLORS - BLACK 25: alpha theme color & default -> black 25", - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'font:contents()[0]->3', - do: async function () { - await testUtils.dom.triggerEvents($dropdownBgColor, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnsBgColor.filter('.bg-black-25'), ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'font:contents()[0]->0', - end: 'font:contents()[0]->4', - }, - }, - { - name: "Click COMMON COLORS - BLUE #0000FF: black 25 & default -> blue #0000FF", - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'font:contents()[0]->3', - do: async function () { - await testUtils.dom.triggerEvents($dropdownBgColor, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnsBgColor.filter('[style="background-color:#0000FF"]'), ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'font:contents()[0]->0', - end: 'font:contents()[0]->4', - }, - }, - { - name: "Click RESET TO DEFAULT: black 25 & default -> default", - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'font:contents()[0]->3', - do: async function () { - await testUtils.dom.triggerEvents($dropdownBgColor, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnsBgColor.filter('.note-color-reset'), ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - }, - }, - { - name: "Click CUSTOM COLORS then CUSTOM COLOR: blue #0000FF & default -> #875A7B", - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'font:contents()[0]->3', - async: true, - do: async function () { - testName = "Click CUSTOM COLORS then CUSTOM COLOR: blue #0000FF & default -> #875A7B"; - - await testUtils.dom.triggerEvents($dropdownBgColor, ['mousedown', 'click']); - await testUtils.dom.triggerEvents(wysiwyg.$('.note-color .note-bg-color .note-custom-color'), ['mousedown', 'click']); - await testUtils.fields.editAndTrigger($('.modal-dialog .o_hex_input'), '#875A7B', 'change'); - await testUtils.dom.triggerEvents($('.o_technical_modal .modal-footer .btn-primary:contains("Choose")'), ['mousedown', 'click']); - await testUtils.dom.triggerEvents(wysiwyg.$('.note-color .note-bg-color .note-custom-color-btn:last'), ['mousedown', 'click']); - - assert.deepEqual(wysiwyg.getValue(), - '

dom not to edit

dom to edit

', - testName); - var range = weTestUtils.select('font:contents()[0]->0', - 'font:contents()[0]->4', - $editable); - assert.deepEqual(Wysiwyg.getRange($editable[0]), range, testName + carretTestSuffix); - }, - }, - ]; - - var def = Promise.resolve(); - _.each(bgcolorTests, function (test) { - def = def.then(async function () { - testName = test.name; - wysiwyg.setValue(test.content); - var range = weTestUtils.select(test.start, test.end, $editable); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - await test.do(); - if (!test.async) { - assert.deepEqual(wysiwyg.getValue(), test.test.content, testName); - assert.deepEqual(Wysiwyg.getRange($editable[0]), weTestUtils.select(test.test.start, test.test.end, $editable), testName + carretTestSuffix); - } - }); - }); - return def.then(function () { - wysiwyg.destroy(); - }); - }); -}); - -QUnit.test('Unordered list', function (assert) { - assert.expect(34); - - return weTestUtils.createWysiwyg({ - debug: false, - wysiwygOptions: { - - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.$('.note-editable'); - - var $btnUL = wysiwyg.$('.note-para .note-icon-unorderedlist'); - - var ulTests = [{ - name: "Click UL: p -> ul", - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($btnUL, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

  • dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - }, - }, - { - name: "Click UL: p -> ul (across paragraphs)", - content: '

dom not to edit

dom to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($btnUL, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

  • dom to edit

  • dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - }, - }, - { - name: "Click UL: ul -> p", - content: '

dom not to edit

  • dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($btnUL, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - }, - }, - { - name: "Click UL: p -> ul (across li's)", - content: '

dom not to edit

  • dom to edit

  • dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($btnUL, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - }, - }, - { - name: "Click UL: ul -> p (from second li)", - content: '

dom not to edit

  • xxx

  • dom to edit

', - start: 'li:eq(1) p:contents()[0]->1', - end: 'li:eq(1) p:contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($btnUL, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

  • xxx

dom to edit

', - start: 'p:eq(2):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - }, - }, - // Conversion from OL - { - name: "Click UL: ol -> ul", - content: '

dom not to edit

  1. dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - do: function () { - $btnUL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  • dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - }, - }, - { - name: "Click UL: ol -> ul (across li's)", - content: '

dom not to edit

  1. dom to edit

  2. dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - do: function () { - $btnUL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  • dom to edit

  • dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - }, - }, - { - name: "Click UL: ol -> ul (from second li)", - content: '

dom not to edit

  1. xxx

  2. dom to edit

', - start: 'li:eq(1) p:contents()[0]->1', - end: 'li:eq(1) p:contents()[0]->5', - do: function () { - $btnUL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  1. xxx

  • dom to edit

', - start: 'p:eq(2):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - }, - }, - { - name: "Click UL: ul ol -> ul ul (from indented li)", - content: '

dom not to edit

  • xxx

    1. dom to edit

', - start: 'li:eq(1) p:contents()[0]->1', - end: 'li:eq(1) p:contents()[0]->5', - do: function () { - $btnUL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  • xxx

    • dom to edit

', - start: 'p:eq(2):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - }, - }, - { - name: "Click UL: ul ol -> ul ul (across several indented li)", - content: '

dom not to edit

  • xxx

    1. dom to edit 1

    2. dom to edit 2

', - start: 'li:eq(1) p:contents()[0]->1', - end: 'li:eq(2) p:contents()[0]->5', - do: function () { - $btnUL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  • xxx

    • dom to edit 1

    • dom to edit 2

', - start: 'p:eq(2):contents()[0]->1', - end: 'p:eq(3):contents()[0]->5', - }, - }, - { - name: "Click UL: ul ol -> ul ul (from second indented li)", - content: '

dom not to edit

  • xxx

    1. dom not to edit

    2. dom to edit

    3. dom not to edit

', - start: 'li:eq(2) p:contents()[0]->1', - end: 'li:eq(2) p:contents()[0]->5', - do: function () { - $btnUL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  • xxx

    1. dom not to edit

    • dom to edit

    1. dom not to edit

', - start: 'p:eq(3):contents()[0]->1', - end: 'p:eq(3):contents()[0]->5', - }, - }, - // Conversion from Checklist - { - name: "Click UL: ul.o_checklist -> ul", - content: '

dom not to edit

  • dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - do: function () { - $btnUL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  • dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - }, - }, - { - name: "Click UL: ul.o_checklist -> ul (across li's)", - content: '

dom not to edit

  • dom to edit

  • dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - do: function () { - $btnUL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  • dom to edit

  • dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - }, - }, - { - name: "Click UL: ul.o_checklist -> ul (from second li)", - content: '

dom not to edit

  • xxx

  • dom to edit

', - start: 'li:eq(1) p:contents()[0]->1', - end: 'li:eq(1) p:contents()[0]->5', - do: function () { - $btnUL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  • xxx

  • dom to edit

', - start: 'p:eq(2):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - }, - }, - { - name: "Click UL: ul ul.o_checklist -> ul ul (from indented li)", - content: '

dom not to edit

  • xxx

    • dom to edit

', - start: 'li:eq(1) p:contents()[0]->1', - end: 'li:eq(1) p:contents()[0]->5', - do: function () { - $btnUL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  • xxx

    • dom to edit

', - start: 'p:eq(2):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - }, - }, - { - name: "Click UL: ul ul.o_checklist -> ul ul (across several indented li)", - content: '

dom not to edit

  • xxx

    • dom to edit 1

    • dom to edit 2

', - start: 'li:eq(1) p:contents()[0]->1', - end: 'li:eq(2) p:contents()[0]->5', - do: function () { - $btnUL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  • xxx

    • dom to edit 1

    • dom to edit 2

', - start: 'p:eq(2):contents()[0]->1', - end: 'p:eq(3):contents()[0]->5', - }, - }, - { - name: "Click UL: ul ul.o_checklist -> ul ul (from second indented li)", - content: '

dom not to edit

  • xxx

    • dom not to edit

    • dom to edit

    • dom not to edit

', - start: 'li:eq(2) p:contents()[0]->1', - end: 'li:eq(2) p:contents()[0]->5', - do: function () { - $btnUL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  • xxx

    • dom not to edit

    • dom to edit

    • dom not to edit

', - start: 'p:eq(3):contents()[0]->1', - end: 'p:eq(3):contents()[0]->5', - }, - }, - ]; - - var def = Promise.resolve(); - _.each(ulTests, function (test) { - def = def.then(async function() { - testName = test.name; - wysiwyg.setValue(test.content); - var range = weTestUtils.select(test.start, test.end, $editable); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - await test.do(); - assert.deepEqual(wysiwyg.getValue(), test.test.content, testName); - assert.deepEqual(Wysiwyg.getRange($editable[0]), weTestUtils.select(test.test.start, test.test.end, $editable), testName + carretTestSuffix); - }); - }); - return def.then(function() { - wysiwyg.destroy(); - }); - }); -}); - -QUnit.test('Ordered list', function (assert) { - assert.expect(56); - - return weTestUtils.createWysiwyg({ - debug: false, - wysiwygOptions: { - - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.$('.note-editable'); - - var $btnOL = wysiwyg.$('.note-para .note-icon-orderedlist'); - - var olTests = [{ - name: "Click OL: p -> ol", - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

  1. dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - }, - }, - { - name: "Click OL: p -> ol (across paragraphs)", - content: '

dom not to edit

dom to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

  1. dom to edit

  2. dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - }, - }, - { - name: "Click OL: ol -> p", - content: '

dom not to edit

  1. dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - }, - }, - { - name: "Click OL: p -> ol (across li's)", - content: '

dom not to edit

  1. dom to edit

  2. dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - }, - }, - { - name: "Click OL: ol -> p (from second li) (2)", - content: '

dom not to edit

  1. dom to edit

  2. dom to edit

', - start: 'li:eq(0) p:contents()[0]->1', - do: async function () { - await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

  1. dom to edit

', - start: 'p:eq(1):contents()[0]->1', - }, - }, - { - name: "Click OL: ol -> p (from second li)", - content: '

dom not to edit

  1. dom to edit

  2. dom to edit

', - start: 'li:eq(0) p:contents()[0]->1', - end: 'li:eq(0) p:contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

  1. dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - }, - }, - { - name: "Click OL + Click OL: ul ul -> ul ol -> ul", - content: '

a

' + - '
    ' + - '
  • b

  • ' + - '
      ' + - '
    • c

    • ' + - '
    • d

    • ' + - '
    ' + - '
  • e

  • ' + - '
', - start: 'ul ul li:first:contents()[0]->1', - do: async function () { - await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']); - }, - test: { - content: '

a

' + - '
    ' + - '
  • b

  • ' + - '
  • c

  • ' + - '
      ' + - '
    • d

    • ' + - '
    ' + - '
  • e

  • ' + - '
', - start: 'ul li:eq(1) p:contents()[0]->1', - }, - }, - { - name: "Click OL in empty table cell in div", - content: '
' + - '

a

' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '






' + - '
', - start: 'tr:eq(0) td:eq(1)->1', - do: async function () { - await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']); - }, - test: { - content: '
' + - '

a

' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '






' + - '
', - start: 'tr:eq(0) td:eq(1) br->0', - }, - }, - { - name: "Click OL in empty table cell in div (2)", - content: '
' + - '

a

' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '






' + - '
', - start: 'tr:eq(0) td:eq(1) br->0', - do: async function () { - await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']); - }, - test: { - content: '
' + - '

a

' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '






' + - '
', - start: 'tr:eq(0) td:eq(1) br->0', - }, - }, - { - name: "Click OL in empty table cell in div (3)", - content: '
' + - '

a

' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '






' + - '
', - start: 'tr:eq(0) td:eq(1)->0', - do: async function () { - await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']); - }, - test: { - content: '
' + - '

a

' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '






' + - '
', - start: 'tr:eq(0) td:eq(1) br->0', - }, - }, - { - name: "Click OL in table cell in div", - content: '
' + - '

a

' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '

aaa



' + - '
', - start: 'tr:eq(0) td:eq(1):contents(0)->1', - do: async function () { - await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']); - }, - test: { - content: '
' + - '

a

' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '

  1. aaa





' + - '
', - start: 'td li p:contents(0)->1', - }, - }, - { - name: "Click OL on image in table cell in div", - content: '
' + - '

a

' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '





' + - '
', - start: 'img->0', - do: async function () { - await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']); - }, - test: { - content: '
' + - '

a

' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '





' + - '
', - start: 'td li->1', - }, - }, - { - name: "Click OL with selected LI in OL", - content: '

x

' + - '
    ' + - '
  1. aaa

  2. ' + - '
  3. bbb

  4. ' + - '
  5. ccc

  6. ' + - '
  7. ddd

  8. ' + - '
' + - '

y

', - start: 'p:eq(2):contents(0)->1', - end: 'p:eq(3):contents(0)->1', - do: async function () { - await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']); - }, - test: { - content: '

x

' + - '
    ' + - '
  1. aaa

  2. ' + - '
' + - '

bbb

' + - '

ccc

' + - '
    ' + - '
  1. ddd

  2. ' + - '
' + - '

y

', - start: 'p:eq(2):contents(0)->1', - end: 'p:eq(3):contents(0)->1', - }, - }, - { - name: "Click OL with selected LI in UL", - content: '

x

' + - '
    ' + - '
  • aaa

  • ' + - '
  • bbb

  • ' + - '
  • ccc

  • ' + - '
  • ddd

  • ' + - '
' + - '

y

', - start: 'p:eq(2):contents(0)->1', - end: 'p:eq(3):contents(0)->1', - do: async function () { - await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']); - }, - test: { - content: '

x

' + - '
    ' + - '
  • aaa

  • ' + - '
' + - '
    ' + - '
  1. bbb

  2. ' + - '
  3. ccc

  4. ' + - '
' + - '
    ' + - '
  • ddd

  • ' + - '
' + - '

y

', - start: 'p:eq(2):contents(0)->1', - end: 'p:eq(3):contents(0)->1', - }, - }, - { - name: "Click OL after ENTER in p > b", - content: "

dom to edit

", - start: 'b:contents(0)->11', - do: async function () { - weTestUtils.keydown(13, $editable); // ENTER - await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']); - weTestUtils.keydown('a', $editable); // ENTER - }, - test: { - content: "

dom to edit

  1. a

", - start: 'b:eq(1):contents(0)->1', - }, - }, - { - name: "Click OL in font in H1 (with link) in div", - content: '

table of contents p23 (cfr: 34)

', - start: 'font:contents(0)->11', - do: async function () { - await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']); - }, - test: { - content: '
  1. table of contents p23 (cfr: 34)

', - start: 'font:contents(0)->11', - }, - }, - // Conversion from UL - { - name: "Click OL: ul -> ol", - content: '

dom not to edit

  • dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - do: function () { - $btnOL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  1. dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - }, - }, - { - name: "Click OL: ul -> ol (across li's)", - content: '

dom not to edit

  • dom to edit

  • dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - do: function () { - $btnOL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  1. dom to edit

  2. dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - }, - }, - { - name: "Click OL: ul -> ol (from second li)", - content: '

dom not to edit

  • xxx

  • dom to edit

', - start: 'li:eq(1) p:contents()[0]->1', - end: 'li:eq(1) p:contents()[0]->5', - do: function () { - $btnOL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  • xxx

  1. dom to edit

', - start: 'p:eq(2):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - }, - }, - { - name: "Click OL: ol ul -> ol ol (from indented li)", - content: '

dom not to edit

  1. xxx

    • dom to edit

', - start: 'li:eq(1) p:contents()[0]->1', - end: 'li:eq(1) p:contents()[0]->5', - do: function () { - $btnOL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  1. xxx

    1. dom to edit

', - start: 'p:eq(2):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - }, - }, - { - name: "Click OL: ol ul -> ol ol (across several indented li)", - content: '

dom not to edit

  1. xxx

    • dom to edit 1

    • dom to edit 2

', - start: 'li:eq(1) p:contents()[0]->1', - end: 'li:eq(2) p:contents()[0]->5', - do: function () { - $btnOL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  1. xxx

    1. dom to edit 1

    2. dom to edit 2

', - start: 'p:eq(2):contents()[0]->1', - end: 'p:eq(3):contents()[0]->5', - }, - }, - { - name: "Click OL: ol ul -> ol ol (from second indented li)", - content: '

dom not to edit

  1. xxx

    • dom not to edit

    • dom to edit

    • dom not to edit

', - start: 'li:eq(2) p:contents()[0]->1', - end: 'li:eq(2) p:contents()[0]->5', - do: function () { - $btnOL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  1. xxx

    • dom not to edit

    1. dom to edit

    • dom not to edit

', - start: 'p:eq(3):contents()[0]->1', - end: 'p:eq(3):contents()[0]->5', - }, - }, - // Conversion from Checklist - { - name: "Click OL: ul.o_checklist -> ol", - content: '

dom not to edit

  • dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - do: function () { - $btnOL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  1. dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - }, - }, - { - name: "Click OL: ul.o_checklist -> ol (across li's)", - content: '

dom not to edit

  • dom to edit

  • dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - do: function () { - $btnOL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  1. dom to edit

  2. dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - }, - }, - { - name: "Click OL: ul.o_checklist -> ol (from second li)", - content: '

dom not to edit

  • xxx

  • dom to edit

', - start: 'li:eq(1) p:contents()[0]->1', - end: 'li:eq(1) p:contents()[0]->5', - do: function () { - $btnOL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  • xxx

  1. dom to edit

', - start: 'p:eq(2):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - }, - }, - { - name: "Click OL: ol ul.o_checklist -> ol ol (from indented li)", - content: '

dom not to edit

  1. xxx

    • dom to edit

', - start: 'li:eq(1) p:contents()[0]->1', - end: 'li:eq(1) p:contents()[0]->5', - do: function () { - $btnOL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  1. xxx

    1. dom to edit

', - start: 'p:eq(2):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - }, - }, - { - name: "Click OL: ul ul.o_checklist -> ul ol (across several indented li)", - content: '

dom not to edit

  • xxx

    • dom to edit 1

    • dom to edit 2

', - start: 'li:eq(1) p:contents()[0]->1', - end: 'li:eq(2) p:contents()[0]->5', - do: function () { - $btnOL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  • xxx

    1. dom to edit 1

    2. dom to edit 2

', - start: 'p:eq(2):contents()[0]->1', - end: 'p:eq(3):contents()[0]->5', - }, - }, - { - name: "Click OL: ul ul.o_checklist -> ul ol (from second indented li)", - content: '

dom not to edit

  • xxx

    • dom not to edit

    • dom to edit

    • dom not to edit

', - start: 'li:eq(2) p:contents()[0]->1', - end: 'li:eq(2) p:contents()[0]->5', - do: function () { - $btnOL.mousedown().click(); - }, - test: { - content: '

dom not to edit

  • xxx

    • dom not to edit

    1. dom to edit

    • dom not to edit

', - start: 'p:eq(3):contents()[0]->1', - end: 'p:eq(3):contents()[0]->5', - }, - }, - ]; - - - var def = Promise.resolve(); - _.each(olTests, function (test) { - def = def.then(async function() { - testName = test.name; - wysiwyg.setValue(test.content); - var range = weTestUtils.select(test.start, test.end, $editable); - $(range.sc).mousedown(); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - await test.do(); - assert.deepEqual(wysiwyg.getValue(), test.test.content, testName); - if (wysiwyg.getValue() === test.test.content) { - assert.deepEqual(Wysiwyg.getRange($editable[0]), weTestUtils.select(test.test.start, test.test.end, $editable), testName + carretTestSuffix); - } else { - assert.notOk(true, testName + ' (Wrong DOM)'); - } - }); - }); - - return def.then(function(){ - wysiwyg.destroy(); - }); - }); -}); - -QUnit.test('Align', function (assert) { - assert.expect(20); - - return weTestUtils.createWysiwyg({ - debug: false, - wysiwygOptions: { - - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.$('.note-editable'); - - var $dropdownPara = wysiwyg.$('.note-para .dropdown-toggle'); - var $btnAlignLeft = wysiwyg.$('.note-align .note-icon-align-left'); - var $btnAlignCenter = wysiwyg.$('.note-align .note-icon-align-center'); - var $btnAlignRight = wysiwyg.$('.note-align .note-icon-align-right'); - var $btnAlignJustify = wysiwyg.$('.note-align .note-icon-align-justify'); - - var alignTests = [ - /* ALIGN LEFT */ - { - name: "Click ALIGN LEFT: p -> p align left (does nothing)", - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - do: async function () { - await testUtils.dom.triggerEvents($dropdownPara, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnAlignLeft, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - }, - }, - { - name: "Click ALIGN LEFT: p (parent align right) -> p align left (does nothing)", - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($dropdownPara, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnAlignLeft, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - }, - }, - { - name: "Click ALIGN LEFT: p (parent align left) -> p align left (does nothing)", - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($dropdownPara, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnAlignLeft, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(1):contents()[0]->5', - }, - }, - { - name: "Click ALIGN LEFT: p align justify & default -> p align right (across paragraphs)", - content: '

dom not to edit

dom to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($dropdownPara, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnAlignRight, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - }, - }, - /* ALIGN CENTER */ - { - name: "Click ALIGN CENTER: p -> p align center", - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - do: async function () { - await testUtils.dom.triggerEvents($dropdownPara, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnAlignCenter, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - }, - }, - { - name: "Click ALIGN CENTER: p align left & default -> p align center (across paragraphs)", - content: '

dom not to edit

dom to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($dropdownPara, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnAlignCenter, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - }, - }, - /* ALIGN RIGHT */ - { - name: "Click ALIGN RIGHT: p align center -> p align right", - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - do: async function () { - await testUtils.dom.triggerEvents($dropdownPara, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnAlignRight, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - }, - }, - { - name: "Click ALIGN RIGHT: p align center & default -> p align right (across paragraphs)", - content: '

dom not to edit

dom to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($dropdownPara, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnAlignRight, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - }, - }, - /* ALIGN JUSTIFY */ - { - name: "Click ALIGN JUSTIFY: p align right -> p align justify", - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - do: async function () { - await testUtils.dom.triggerEvents($dropdownPara, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnAlignJustify, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - }, - }, - { - name: "Click ALIGN JUSTIFY: p align right & default -> p align justify (across paragraphs)", - content: '

dom not to edit

dom to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - do: async function () { - await testUtils.dom.triggerEvents($dropdownPara, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnAlignJustify, ['mousedown', 'click']); - }, - test: { - content: '

dom not to edit

dom to edit

dom to edit

', - start: 'p:eq(1):contents()[0]->1', - end: 'p:eq(2):contents()[0]->5', - }, - }, - ]; - - var def = Promise.resolve(); - _.each(alignTests, function (test) { - def = def.then(async function() { - testName = test.name; - wysiwyg.setValue(test.content); - var range = weTestUtils.select(test.start, test.end, $editable); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - await test.do(); - assert.deepEqual(wysiwyg.getValue(), test.test.content, testName); - assert.deepEqual(Wysiwyg.getRange($editable[0]), weTestUtils.select(test.test.start, test.test.end, $editable), testName + carretTestSuffix); - }); - }); - return def.then(function() { - wysiwyg.destroy(); - }); - }); -}); - -QUnit.test('Indent/outdent', function (assert) { - assert.expect(20); - - return weTestUtils.createWysiwyg({ - debug: false, - wysiwygOptions: { - - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.$('.note-editable'); - - var $dropdownPara = wysiwyg.$('.note-para .dropdown-toggle'); - var $btnIndent = wysiwyg.$('.note-list .note-btn:eq(1)'); - var $btnOutdent = wysiwyg.$('.note-list .note-btn:first'); - - var indentTests = [ - /* INDENT */ - { - name: "Click INDENT: p -> indented p", - content: '

dom to edit

', - start: 'p:contents()[0]->1', - do: async function () { - await testUtils.dom.triggerEvents($dropdownPara, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnIndent, ['mousedown', 'click']); - }, - test: { - content: '

dom to edit

', - start: 'p:contents()[0]->1', - }, - }, - { - name: "Click INDENT: li -> indented li", - content: '
  • dom

  • to edit

', - start: 'p:eq(1):contents()[0]->1', - do: async function () { - await testUtils.dom.triggerEvents($dropdownPara, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnIndent, ['mousedown', 'click']); - }, - test: { - content: '
  • dom

    • to edit

', - start: 'p:eq(1):contents()[0]->1', - }, - }, - { - name: "Click INDENT: li -> indented li", - content: '

aaa

bbb

ccc

ddd

', - start: 'p:eq(1):contents()[0]->0', - end: 'p:eq(3):contents()[0]->3', - do: function () { - $dropdownPara.mousedown().click(); - $btnIndent.mousedown().click(); - }, - test: { - content: '

aaa

bbb

ccc

ddd

', - start: 'p:eq(1):contents()[0]->0', - end: 'p:eq(3):contents()[0]->3', - }, - }, - /* OUTDENT */ - { - name: "Click OUTDENT: indented p -> p", - content: '

dom to edit

', - start: 'p:contents()[0]->1', - do: async function () { - await testUtils.dom.triggerEvents($dropdownPara, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnOutdent, ['mousedown', 'click']); - }, - test: { - content: '

dom to edit

', - start: 'p:contents()[0]->1', - }, - }, - { - name: "Click OUTDENT: indented li -> li", - content: '
  • dom

    • to edit

', - start: 'p:eq(1):contents()[0]->1', - do: async function () { - await testUtils.dom.triggerEvents($dropdownPara, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnOutdent, ['mousedown', 'click']); - }, - test: { - content: '
  • dom

  • to edit

', - start: 'p:eq(1):contents()[0]->1', - }, - }, - { - name: "Click OUTDENT: indented li -> li (2)", - content: '
  • dom

    • to edit

', - start: 'p:eq(1):contents()[0]->1', - do: async function () { - await testUtils.dom.triggerEvents($dropdownPara, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnOutdent, ['mousedown', 'click']); - }, - test: { - content: '
  • dom

  • to edit

', - start: 'p:eq(1):contents()[0]->1', - }, - }, - { - name: "Click OUTDENT on LI in OL in OL", - content: '

x

' + - '
    ' + - '
  1. aaa

  2. ' + - '
    1. ' + - '
    2. bbb

    3. ' + - '
    4. ccc

    5. ' + - '
    6. ddd

    7. ' + - '
  3. ' + - '
  4. eee

  5. ' + - '
' + - '

y

', - start: 'ol ol p:eq(1):contents(0)->1', - do: async function () { - await testUtils.dom.triggerEvents($dropdownPara, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnOutdent, ['mousedown', 'click']); - }, - test: { - content: '

x

' + - '
    ' + - '
  1. aaa

  2. ' + - '
    1. ' + - '
    2. bbb

    3. ' + - '
  3. ' + - '
  4. ccc

  5. ' + - '
    1. ' + - '
    2. ddd

    3. ' + - '
  6. ' + - '
  7. eee

  8. ' + - '
' + - '

y

', - start: 'ol:first > li:eq(2) p:contents(0)->1', - }, - }, - { - name: "Click OUTDENT on LI in OL in OL (2)", - content: '

x

' + - '
    ' + - '
  1. aaa

  2. ' + - '
      ' + - '
    1. bbb

    2. ' + - '
    3. ccc

    4. ' + - '
    5. ddd

    6. ' + - '
    ' + - '
  3. eee

  4. ' + - '
' + - '

y

', - start: 'ol ol p:eq(1):contents(0)->1', - do: async function () { - await testUtils.dom.triggerEvents($dropdownPara, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnOutdent, ['mousedown', 'click']); - }, - test: { - content: '

x

' + - '
    ' + - '
  1. aaa

  2. ' + - '
      ' + - '
    1. bbb

    2. ' + - '
    ' + - '
  3. ccc

  4. ' + - '
      ' + - '
    1. ddd

    2. ' + - '
    ' + - '
  5. eee

  6. ' + - '
' + - '

y

', - start: 'li:eq(2) p:contents(0)->1', - }, - }, - { - name: "Click OUTDENT on LI in OL", - content: - '
    ' + - '
  1. aaa

  2. ' + - '
  3. bbb

  4. ' + - '
  5. ccc

  6. ' + - '
', - start: 'p:eq(1):contents(0)->1', - do: async function () { - await testUtils.dom.triggerEvents($dropdownPara, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnOutdent, ['mousedown', 'click']); - }, - test: { - content: - '
    ' + - '
  1. aaa

  2. ' + - '
' + - '

bbb

' + - '
    ' + - '
  1. ccc

  2. ' + - '
', - start: 'p:eq(1):contents(0)->1', - }, - }, - { - name: "Click OUTDENT on P with indent in a LI (must outdent the p)", - content: - '
    ' + - '
  • ' + - '
      ' + - '
    • ' + - '

      dom

      ' + - '
    • ' + - '
    ' + - '
  • ' + - '
', - start: 'p:contents(0)->1', - do: async function () { - await testUtils.dom.triggerEvents($dropdownPara, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($btnOutdent, ['mousedown', 'click']); - }, - test: { - content: - '
    ' + - '
  • ' + - '
      ' + - '
    • ' + - '

      dom

      ' + - '
    • ' + - '
    ' + - '
  • ' + - '
', - start: 'p:contents(0)->1', - }, - }, - ]; - - var def = Promise.resolve(); - _.each(indentTests, function (test) { - def = def.then(async function() { - testName = test.name; - wysiwyg.setValue(test.content); - var range = weTestUtils.select(test.start, test.end, $editable); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - await test.do(); - assert.deepEqual(wysiwyg.getValue(), test.test.content, testName); - assert.deepEqual(Wysiwyg.getRange($editable[0]), weTestUtils.select(test.test.start, test.test.end, $editable), testName + carretTestSuffix); - }); - }); - return def.then(function() { - wysiwyg.destroy(); - }); - }); -}); - -QUnit.test('checklist', function (assert) { - assert.expect(11); - - return weTestUtils.createWysiwyg({ - debug: false, - wysiwygOptions: { - generateOptions: function (options) { - options.toolbar[4][1] = ['ul', 'ol', 'checklist', 'paragraph']; - }, - }, - }).then(function (wysiwyg) { - var $editable = wysiwyg.$('.note-editable'); - - var $btnChecklist = wysiwyg.$('.note-para .fa-check-square'); - - var checklistTests = [ - { - name: "check checkbox in checklist with children", - content: '

x

' + - '
    ' + - '
  • aaa

  • ' + - '
  • ' + - '
      ' + - '
    • bbb

    • ' + - '
    • ccc

    • ' + - '
    • ddd

    • ' + - '
    ' + - '
  • ' + - '
  • eee

  • ' + - '
' + - '

y

', - do: async function () { - var $li = $editable.find('li:first'); - $li.trigger($.Event('mousedown', { - offsetX: -10, - })); - }, - test: { - content: '

x

' + - '
    ' + - '
  • aaa

  • ' + - '
  • ' + - '
      ' + - '
    • bbb

    • ' + - '
    • ccc

    • ' + - '
    • ddd

    • ' + - '
    ' + - '
  • ' + - '
  • eee

  • ' + - '
' + - '

y

', - }, - }, - { - name: "check checkbox in checklist with children (2)", - content: '

x

' + - '
    ' + - '
  • aaa

  • ' + - '
      ' + - '
    • bbb

    • ' + - '
    • ccc

    • ' + - '
    • ddd

    • ' + - '
    ' + - '
  • eee

  • ' + - '
' + - '

y

', - do: async function () { - var $li = $editable.find('li:first'); - $li.trigger($.Event('mousedown', { - offsetX: -10, - })); - }, - test: { - content: '

x

' + - '
    ' + - '
  • aaa

  • ' + - '
      ' + - '
    • bbb

    • ' + - '
    • ccc

    • ' + - '
    • ddd

    • ' + - '
    ' + - '
  • eee

  • ' + - '
' + - '

y

', - }, - }, - { - name: "uncheck checkbox in checklist with children", - content: '

x

' + - '
    ' + - '
  • aaa

  • ' + - '
  • ' + - '
      ' + - '
    • bbb

    • ' + - '
    • ccc

    • ' + - '
    • ddd

    • ' + - '
    ' + - '
  • ' + - '
  • eee

  • ' + - '
' + - '

y

', - do: async function () { - var $li = $editable.find('li:first'); - $li.trigger($.Event('mousedown', { - offsetX: -10, - })); - }, - test: { - content: '

x

' + - '
    ' + - '
  • aaa

  • ' + - '
  • ' + - '
      ' + - '
    • bbb

    • ' + - '
    • ccc

    • ' + - '
    • ddd

    • ' + - '
    ' + - '
  • ' + - '
  • eee

  • ' + - '
' + - '

y

', - }, - }, - { - name: "uncheck checkbox in checklist with children (2)", - content: '

x

' + - '
    ' + - '
  • aaa

  • ' + - '
      ' + - '
    • bbb

    • ' + - '
    • ccc

    • ' + - '
    • ddd

    • ' + - '
    ' + - '
  • eee

  • ' + - '
' + - '

y

', - do: async function () { - var $li = $editable.find('li:first'); - $li.trigger($.Event('mousedown', { - offsetX: -10, - })); - }, - test: { - content: '

x

' + - '
    ' + - '
  • aaa

  • ' + - '
      ' + - '
    • bbb

    • ' + - '
    • ccc

    • ' + - '
    • ddd

    • ' + - '
    ' + - '
  • eee

  • ' + - '
' + - '

y

', - }, - }, - { - name: "uncheck checkbox in checklist in checklist", - content: '

x

' + - '
    ' + - '
  • aaa

  • ' + - '
  • ' + - '
      ' + - '
    • bbb

    • ' + - '
    • ccc

    • ' + - '
    • ddd

    • ' + - '
    ' + - '
  • ' + - '
  • eee

  • ' + - '
' + - '

y

', - do: async function () { - var $li = $editable.find('ul ul li:eq(1)'); - $li.trigger($.Event('mousedown', { - offsetX: -10, - })); - }, - test: { - content: '

x

' + - '
    ' + - '
  • aaa

  • ' + - '
  • ' + - '
      ' + - '
    • bbb

    • ' + - '
    • ccc

    • ' + - '
    • ddd

    • ' + - '
    ' + - '
  • ' + - '
  • eee

  • ' + - '
' + - '

y

', - }, - }, - { - name: "uncheck checkbox in checklist in checklist (2)", - content: '

x

' + - '
    ' + - '
  • aaa

  • ' + - '
      ' + - '
    • bbb

    • ' + - '
    • ccc

    • ' + - '
    • ddd

    • ' + - '
    ' + - '
  • eee

  • ' + - '
' + - '

y

', - do: async function () { - var $li = $editable.find('ul ul li:eq(1)'); - $li.trigger($.Event('mousedown', { - offsetX: -10, - })); - }, - test: { - content: '

x

' + - '
    ' + - '
  • aaa

  • ' + - '
      ' + - '
    • bbb

    • ' + - '
    • ccc

    • ' + - '
    • ddd

    • ' + - '
    ' + - '
  • eee

  • ' + - '
' + - '

y

', - }, - }, - { - name: "check checkbox in checklist in checklist", - content: '

x

' + - '
    ' + - '
  • aaa

  • ' + - '
  • ' + - '
      ' + - '
    • bbb

    • ' + - '
    • ccc

    • ' + - '
    • ddd

    • ' + - '
    ' + - '
  • ' + - '
  • eee

  • ' + - '
' + - '

y

', - do: async function () { - var $li = $editable.find('ul ul li:eq(1)'); - $li.trigger($.Event('mousedown', { - offsetX: -10, - })); - }, - test: { - content: '

x

' + - '
    ' + - '
  • aaa

  • ' + - '
  • ' + - '
      ' + - '
    • bbb

    • ' + - '
    • ccc

    • ' + - '
    • ddd

    • ' + - '
    ' + - '
  • ' + - '
  • eee

  • ' + - '
' + - '

y

', - }, - }, - { - name: "check checkbox in checklist in checklist (2)", - content: '

x

' + - '
    ' + - '
  • aaa

  • ' + - '
      ' + - '
    • bbb

    • ' + - '
    • ccc

    • ' + - '
    • ddd

    • ' + - '
    ' + - '
  • eee

  • ' + - '
' + - '

y

', - do: async function () { - var $li = $editable.find('ul ul li:eq(1)'); - $li.trigger($.Event('mousedown', { - offsetX: -10, - })); - }, - test: { - content: '

x

' + - '
    ' + - '
  • aaa

  • ' + - '
      ' + - '
    • bbb

    • ' + - '
    • ccc

    • ' + - '
    • ddd

    • ' + - '
    ' + - '
  • eee

  • ' + - '
' + - '

y

', - }, - }, - { - name: "check checkbox in checklist in checklist (full)", - content: '

x

' + - '
    ' + - '
  • aaa

  • ' + - '
  • ' + - '
      ' + - '
    • bbb

    • ' + - '
    • ccc

    • ' + - '
    • ddd

    • ' + - '
    ' + - '
  • ' + - '
  • eee

  • ' + - '
' + - '

y

', - do: async function () { - var $li = $editable.find('ul ul li:eq(1)'); - $li.trigger($.Event('mousedown', { - offsetX: -10, - })); - }, - test: { - content: '

x

' + - '
    ' + - '
  • aaa

  • ' + - '
  • ' + - '
      ' + - '
    • bbb

    • ' + - '
    • ccc

    • ' + - '
    • ddd

    • ' + - '
    ' + - '
  • ' + - '
  • eee

  • ' + - '
' + - '

y

', - }, - }, - { - name: "check checkbox in checklist in checklist (full) (2)", - content: '

x

' + - '
    ' + - '
  • aaa

  • ' + - '
      ' + - '
    • bbb

    • ' + - '
    • ccc

    • ' + - '
    • ddd

    • ' + - '
    ' + - '
  • eee

  • ' + - '
' + - '

y

', - do: async function () { - var $li = $editable.find('ul ul li:eq(1)'); - $li.trigger($.Event('mousedown', { - offsetX: -10, - })); - }, - test: { - content: '

x

' + - '
    ' + - '
  • aaa

  • ' + - '
      ' + - '
    • bbb

    • ' + - '
    • ccc

    • ' + - '
    • ddd

    • ' + - '
    ' + - '
  • eee

  • ' + - '
' + - '

y

', - }, - }, - { - name: "convert 2 ul li ul li into two ul li ul.o_checklist li", - content: '
    ' + - '
  • ' + - '

    1

    ' + - '
  • ' + - '
  • ' + - '
      ' + - '
    • ' + - '

      2

      ' + - '
    • ' + - '
    • ' + - '

      3

      ' + - '
    • ' + - '
    • ' + - '

      4

      ' + - '
    • ' + - '
    ' + - '
  • ' + - '
  • ' + - '

    5

    ' + - '
  • ' + - '
', - start: 'p:eq(2):contents()[0]->0', - end: 'p:eq(3):contents()[0]->1', - do: function () { - $btnChecklist.mousedown().click(); - }, - test: { - content: '
    ' + - '
  • ' + - '

    1

    ' + - '
  • ' + - '
  • ' + - '
      ' + - '
    • ' + - '

      2

      ' + - '
    • ' + - '
    ' + - '
      ' + - '
    • ' + - '

      3

      ' + - '
    • ' + - '
    • ' + - '

      4

      ' + - '
    • ' + - '
    ' + - '
  • ' + - '
  • ' + - '

    5

    ' + - '
  • ' + - '
', - }, - }, - ]; - - var def = Promise.resolve(); - - _.each(checklistTests, function (test) { - def = def.then(async function(){ - testName = test.name; - wysiwyg.setValue(test.content); - if (test.start) { - var range = weTestUtils.select(test.start, test.end || test.start, $editable); - $(range.sc).mousedown(); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - } - await test.do(); - assert.deepEqual(wysiwyg.getValue(), test.test.content, testName); - }); - }); - - return def.then(function() { - wysiwyg.destroy(); - }); - }); -}); - -QUnit.test('Link', function (assert) { - assert.expect(19); - - return weTestUtils.createWysiwyg({ - debug: false, - wysiwygOptions: { - - }, - }).then(async function (wysiwyg) { - var $editable = wysiwyg.$('.note-editable'); - - var $btnLink = wysiwyg.$('.note-insert .note-icon-link'); - - var _clickLink = async function (callbackInit, test) { - await testUtils.dom.triggerEvents($btnLink, ['mousedown', 'click']); - await callbackInit(); - await testUtils.dom.triggerEvents($('.modal-dialog:visible .btn-primary:contains("Save")'), ['mousedown', 'click']); - - if (test.check) { - await test.check(); - } - if (test.content) { - assert.deepEqual(wysiwyg.getValue(), test.content, testName); - } - if (test.start) { - var range = weTestUtils.select(test.start, test.end, $editable); - assert.deepEqual(Wysiwyg.getRange($editable[0]), range, testName + carretTestSuffix); - } - }; - - var linkTests = [{ - name: "Click LINK: p -> a in p (w/ URL)", - async: true, - content: '

dom to edit

', - start: "p:contents()[0]->1", - end: "p:contents()[0]->5", - do: async function () { - assert.strictEqual($('.modal-dialog:visible #o_link_dialog_label_input').val(), 'om t', testName + ' (label)'); - await testUtils.fields.editInput($('.modal-dialog:visible #o_link_dialog_url_input'),'#'); - }, - test: { - content: '

dom to edit

', - start: 'a:contents()[0]->0', - end: 'a:contents()[0]->4', - }, - }, - { - name: "Click LINK: p -> a in p (w/ URL) (no selection)", - async: true, - content: '

do edit

', - start: 'p:contents()[0]->1', - do: async function () { - await testUtils.fields.editInput($('.modal-dialog:visible #o_link_dialog_label_input'),'om t'); - await testUtils.fields.editInput($('.modal-dialog:visible #o_link_dialog_url_input'),'#'); - }, - test: { - content: '

dom to edit

', - start: 'p->2', // link not selected, the user can continue to write - end: 'p->2', - }, - }, - { - name: "Click LINK: a.btn in div -> a.btn.btn-outline-alpha in div (edit) (no selection)", - content: '', - start: 'a:contents()[0]->5', - do: async function () { - assert.strictEqual($('.modal-dialog:visible #o_link_dialog_label_input').val(), 'dom to edit', testName + ' (label)'); - await testUtils.fields.editInput($('.modal-dialog:visible #o_link_dialog_url_input'),'#newlink'); - }, - test: { - content: '', - start: 'a->0', - end: 'a->1', - }, - }, - { - name: "Click LINK: p -> a in p (w/ Email)", - async: true, - content: '

dom to edit

', - start: 'p:contents()[0]->1', - end: 'p:contents()[0]->5', - do: async function () { - await testUtils.fields.editInput($('.modal-dialog:visible #o_link_dialog_url_input'),'john.coltrane@example.com'); - }, - test: { - content: '

dom to edit

', - start: 'a:contents()[0]->0', - end: 'a:contents()[0]->4', - }, - }, - { - name: "Click LINK: p -> a in p (w/ URL & Size Large)", - async: true, - content: '

dom to edit

', - start: 'p:contents()[0]->1', - end: 'p:contents()[0]->5', - do: async function () { - await testUtils.fields.editInput($('.modal-dialog:visible #o_link_dialog_url_input'),'#'); - await testUtils.fields.editInput($('.modal-dialog:visible [name="link_style_size"]'),"lg"); - }, - test: { - content: '

dom to edit

', - start: 'a:contents()[0]->0', - end: 'a:contents()[0]->4', - }, - }, - { - name: "Click LINK: a in p -> a.btn-outline-alpha in p with alpha color and target=\"_blank\"", - async: true, - content: '

dom to edit

', - start: 'a:contents()[0]->1', - do: async function () { - await testUtils.fields.editInput( $('.modal-dialog:visible #o_link_dialog_url_input'), '#'); - await testUtils.fields.editInput($('.modal-dialog:visible [name="link_style_shape"]'), "outline"); - await testUtils.dom.triggerEvents($('.modal-dialog:visible .o_link_dialog_color .o_link_dialog_color_item.btn-alpha'), ['mousedown', 'click']); - await testUtils.dom.triggerEvents($('.modal-dialog:visible .o_switch [name="is_new_window"]'), ['mousedown', 'click']); - }, - test: { - content: '

dom to edit

', - start: 'a->0', - end: 'a->1', - }, - }, - // POPOVER - { - name: "Click LINK in popover after adding link in p", - async: true, - content: '

dom to edit

', - start: "p:contents()[0]->1", - end: "p:contents()[0]->5", - do: async function () { - $('.modal-dialog:visible #o_link_dialog_url_input').val('/link'); - }, - test: { - check: async function () { - await testUtils.dom.triggerEvents($('.note-link-popover .note-btn .note-icon-link'), ['mousedown', 'click']); - - assert.strictEqual($('.modal-dialog:visible #o_link_dialog_label_input').val(), 'om t', testName + ' (label)'); - assert.strictEqual($('.modal-dialog:visible #o_link_dialog_url_input').val(), '/link', testName + ' (url)'); - await testUtils.fields.editInput($('.modal-dialog:visible #o_link_dialog_url_input'), '/newlink'); - await testUtils.dom.triggerEvents($('.modal-dialog:visible .modal-footer .btn.btn-primary:contains("Save")'), ['mousedown', 'click']); - assert.deepEqual(wysiwyg.getValue(), '

dom to edit

', testName); - }, - }, - }, - { - name: "Click UNLINK in popover after adding link in p", - async: true, - content: '

dom to edit

', - start: "p:contents()[0]->1", - end: "p:contents()[0]->5", - do: async function () { - $('.modal-dialog:visible #o_link_dialog_url_input').val('/link'); - }, - test: { - content: '

dom to edit

', - check: async function () { - await testUtils.dom.triggerEvents($('.note-link-popover .note-btn .note-icon-chain-broken'), ['mousedown', 'click']); - - var range = weTestUtils.select('p:contents()[0]->1', 'p:contents()[0]->5', $editable); - assert.deepEqual(Wysiwyg.getRange($editable[0]), range, testName + carretTestSuffix); - }, - }, - }, - ]; - - var def = Promise.resolve(); - _.each(linkTests, function (test) { - def = def.then(async function () { - testName = test.name; - wysiwyg.setValue(test.content); - var range = weTestUtils.select(test.start, test.end, $editable); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - await _clickLink(test.do, test.test); - }); - }); - return def.then(function () { - wysiwyg.destroy(); - }); - }); -}); - -QUnit.test('Table', function (assert) { - assert.expect(13); - - async function createTable(wysiwyg) { - await testUtils.dom.triggerEvents(wysiwyg.$('.note-table button:first'), ['mousedown', 'click']); - - var $grid = wysiwyg.$('.note-table .note-dimension-picker-mousecatcher'); - var pos = $grid.offset(); - $grid.trigger($.Event('mousemove', { - pageX: pos.left + 40, - pageY: pos.top + 40, - })); - await testUtils.dom.triggerEvents($grid, ['mousedown', 'click']); - } - - return weTestUtils.createWysiwyg({ - debug: false, - wysiwygOptions: {}, - }).then(async function (wysiwyg) { - var $editable = wysiwyg.getEditable(); - - // create a table in an empty dom - - wysiwyg.setValue('


'); - var range = weTestUtils.select('p->1', 'p->1', $editable); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - - await createTable(wysiwyg); - - assert.strictEqual($editable.html().replace(/\s+/g, ' '), - '


' + - '' + - '' + - '' + - '' + - '










' + - '


', - "should create a table in an empty dom (p > br)"); - - // create a table at start of p with content - - wysiwyg.setValue('

dom to edit

'); - range = weTestUtils.select('p:contents()[0]->0', 'p:contents()[0]->0', $editable); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - - await createTable(wysiwyg); - - assert.strictEqual($editable.html().replace(/\s+/g, ' '), - '


' + - '' + - '' + - '' + - '' + - '










' + - '

dom to edit

', - "should create a table at start of single p with content"); - - // create a table at end of p with content - - wysiwyg.setValue('

dom to edit

'); - range = weTestUtils.select('p:contents()[0]->11', 'p:contents()[0]->11', $editable); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - - await createTable(wysiwyg); - - assert.strictEqual($editable.html().replace(/\s+/g, ' '), - '

dom to edit

' + - '' + - '' + - '' + - '' + - '










' + - '


', - "should create a table at end of single p with content"); - - // create a table within p - - wysiwyg.setValue('

dom to edit

'); - range = weTestUtils.select('p:contents()[0]->5', 'p:contents()[0]->5', $editable); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - - await createTable(wysiwyg); - - assert.strictEqual($editable.html().replace(/\s+/g, ' '), - '

dom t

' + - '' + - '' + - '' + - '' + - '










' + - '

o edit

', - "should create a table"); - - // remove a table - - range = weTestUtils.select('td:first->0', 'td:first->0', $editable); - $(range.sc).mousedown(); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - - var $trash = $('.note-table-popover:visible button:has(.note-icon-trash)'); - - await testUtils.dom.triggerEvents($trash, ['mousedown', 'click']); - - assert.strictEqual($editable.html().replace(/\s+/g, ' '), - '

dom to edit

', - "should remove the table"); - - // re create a table and table in table - - await createTable(wysiwyg); - await createTable(wysiwyg); - - assert.strictEqual($editable.html().replace(/\s+/g, ' '), - '

dom t

' + - '' + - '' + - '' + - '' + - '


' + - '' + - '' + - '' + - '' + - '










' + - '










' + - '

o edit

', - "should create a table inside the table"); - - // remove inner table - - range = weTestUtils.select('td td:eq(1)->0', 'td td:eq(1)->0', $editable); - $(range.sc).mousedown(); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - - $trash = $('.note-table-popover:visible button:has(.note-icon-trash)'); - await testUtils.dom.triggerEvents($trash, ['mousedown', 'click']); - - assert.strictEqual($editable.html().replace(/\s+/g, ' '), - '

dom t

' + - '' + - '' + - '' + - '' + - '










' + - '

o edit

', - "should remove the inner table"); - - // use popover to change row and line - - wysiwyg.setValue('

dom t

' + - '' + - '' + - '' + - '' + - '

0-0

0-1

0-2

1-0

1-1

1-2

2-0

2-1

2-2

' + - '

o edit

'); - - // remove a row - - range = weTestUtils.select('td:eq(1)->0', 'td:eq(1)->0', $editable); - $(range.sc).mousedown(); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - await testUtils.dom.triggerEvents($('.note-table-popover:visible button:has(.note-icon-col-remove)'), ['mousedown', 'click']); - - assert.strictEqual($editable.html().replace(/\s+/g, ' '), - '

dom t

' + - '' + - '' + - '' + - '' + - '

0-0

0-2

1-0

1-2

2-0

2-2

' + - '

o edit

', - "should remove a row"); - - // remove a line - - range = weTestUtils.select('tr:eq(1) td:eq(1)->0', 'tr:eq(1) td:eq(1)->0', $editable); - $(range.sc).mousedown(); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - await testUtils.dom.triggerEvents($('.note-table-popover:visible button:has(.note-icon-row-remove)'), ['mousedown', 'click']); - - assert.strictEqual($editable.html().replace(/\s+/g, ' '), - '

dom t

' + - '' + - '' + - '' + - '

0-0

0-2

2-0

2-2

' + - '

o edit

', - "should remove a line"); - - // add a row after - - range = weTestUtils.select('tr:eq(1) td:first->0', 'tr:eq(1) td:first->0', $editable); - $(range.sc).mousedown(); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - await testUtils.dom.triggerEvents($('.note-table-popover:visible button:has(.note-icon-col-after)'), ['mousedown', 'click']); - - assert.strictEqual($editable.html().replace(/\s+/g, ' '), - '

dom t

' + - '' + - '' + - '' + - '

0-0


0-2

2-0


2-2

' + - '

o edit

', - "should add a row after"); - - // add a row before - - $(range.sc).mousedown(); - await testUtils.dom.triggerEvents($('.note-table-popover:visible button:has(.note-icon-col-before)'), ['mousedown', 'click']); - - assert.strictEqual($editable.html().replace(/\s+/g, ' '), - '

dom t

' + - '' + - '' + - '' + - '


0-0


0-2


2-0


2-2

' + - '

o edit

', - "should add a row before"); - - // add a line after - - $(range.sc).mousedown(); - await testUtils.dom.triggerEvents($('.note-table-popover:visible button:has(.note-icon-row-below)'), ['mousedown', 'click']); - - assert.strictEqual($editable.html().replace(/\s+/g, ' '), - '

dom t

' + - '' + - '' + - '' + - '' + - '


0-0


0-2


2-0


2-2





' + - '

o edit

', - "should add a line after"); - - // add a line before - - $(range.sc).mousedown(); - await testUtils.dom.triggerEvents($('.note-table-popover:visible button:has(.note-icon-row-above)'), ['mousedown', 'click']); - - assert.strictEqual($editable.html().replace(/\s+/g, ' '), - '

dom t

' + - '' + - '' + - '' + - '' + - '' + - '


0-0


0-2






2-0


2-2





' + - '

o edit

', - "should add a line before"); - - wysiwyg.destroy(); - }); -}); - -QUnit.test('CodeView', async function (assert) { - assert.expect(8); - - var wysiwyg = await weTestUtils.createWysiwyg({ - debug: false, - wysiwygOptions: { - codeview: true, - }, - }); - wysiwyg.setValue('

dom to edit

'); - - var $buttonCodeView = wysiwyg.$('button:has(.note-icon-code)'); - - // hide popover in CodeView mode and no range error when edit the content - var $editable = wysiwyg.getEditable(); - await testUtils.dom.triggerEvents($editable.find('img'), ['mousedown', 'click']); - assert.strictEqual($('.note-popover.note-image-popover:visible').length, 1, "should display the image popover"); - await testUtils.dom.triggerEvents($buttonCodeView, ['mousedown', 'click']); - assert.strictEqual($('textarea.note-codable:visible').length, 1, "should show the CodeView textarea"); - assert.strictEqual($editable.is(':visible'), false, "should hide the editable area"); - assert.strictEqual($('.note-popover:visible').length, 0, "should hide all popovers"); - assert.strictEqual($('.note-toolbar button:not(.disabled)').length, 1, "should disabled all buttons expect the codeview button"); - wysiwyg.$('textarea.note-codable').val('

dom to edit a

'); - await testUtils.dom.triggerEvents($buttonCodeView, ['mousedown', 'click']); - assert.strictEqual($('textarea.note-codable:visible').length, 0, "should hide the CodeView textarea"); - assert.strictEqual($editable.is(':visible'), true, "should show the editable area"); - assert.strictEqual($editable[0].style.height, '', "should reset the height (not auto or sizing)"); - // end - - wysiwyg.destroy(); -}); - -}); - -var imgWidth = 10; -var imgHeight = 10; - -var altDialogOpened; -var altDialogSaved; -var cropDialogOpened; -QUnit.module('Media', { - beforeEach: function () { - this.data = { - debug: false, - wysiwygOptions: { - - }, - mockRPC: function (route, args) { - if (route.indexOf('data:image/png;base64') === 0) { - return Promise.resolve(); - } - if (route.indexOf('youtube') !== -1) { - return Promise.resolve(); - } - if (route.indexOf('/web_editor/static/src/img/') === 0) { - return Promise.resolve(); - } - if (route === '/web_editor/attachment/add_url') { - return Promise.resolve({ - id: 1, - public: true, - name: 'image', - mimetype: 'image/png', - checksum: false, - url: '/web_editor/static/src/img/transparent.png', - image_src: '/web_editor/static/src/img/transparent.png', - type: 'url', - res_id: 0, - res_model: false, - access_token: false, - }); - } - return this._super(route, args); - }, - }; - - testUtils.mock.patch(AltDialog, { - init: function () { - this._super.apply(this, arguments); - altDialogOpened = this._opened; - }, - save: function () { - altDialogSaved = this._super.apply(this, arguments); - return altDialogSaved; - }, - }); - - testUtils.mock.patch(CropDialog, { - init: function () { - var self = this; - this._super.apply(this, arguments); - cropDialogOpened = new Promise (function (resolve) { - self.opened(function () { - var cropper = self.$cropperImage.data('cropper'); - cropper.clone(); - $.extend(cropper.image, { - naturalWidth: imgWidth, - naturalHeight: imgHeight, - aspectRatio: imgWidth / imgHeight, - }); - cropper.loaded = true; - cropper.build(); - cropper.render(); - resolve(); - }); - }); - }, - }); - }, - afterEach: function () { - testUtils.mock.unpatch(AltDialog); - testUtils.mock.unpatch(CropDialog); - $('body').off('submit.WysiwygTests'); - }, -}, function () { - - -var _clickMedia = async function (wysiwyg, assert, callbackInit, test) { - await testUtils.dom.triggerEvents(wysiwyg.$('.note-insert .fa-file-image-o'), ['mousedown', 'click']); - await callbackInit(); - - if (test.check) { - await test.check(); - } - if (test.content) { - assert.deepEqual(wysiwyg.getValue(), test.content, testName); - } - if (test.start) { - var range = weTestUtils.select(test.start, test.end, $editable); - assert.deepEqual(Wysiwyg.getRange($editable[0]), range, testName + carretTestSuffix); - } -}; - -var _uploadAndInsertImg = async function (url) { - $('.modal-dialog .o_we_url_input:first').val(url).trigger('input'); - await testUtils.nextTick(); - await testUtils.dom.triggerEvents($('.modal-dialog .o_upload_media_url_button:first'), ['mousedown', 'click']); -}; -var _insertVideo = async function (wysiwyg, assert, url, checkOptions) { - await testUtils.dom.triggerEvents($('.modal-dialog .nav-link:contains("Video")'), ['mousedown', 'click']); - $('.modal-dialog #o_video_text').val(url).trigger('change'); - if (checkOptions) { - assert.strictEqual($('.modal-dialog .o_yt_option').parent().css('display'), 'block', testName + ' (options)'); - } - await testUtils.dom.triggerEvents($('.modal-dialog .modal-footer .btn.btn-primary:visible'), ['mousedown', 'click']); -}; -var _insertPictogram = async function (className) { - await testUtils.dom.triggerEvents($('.modal-dialog .nav-link:contains("Pictogram")'), ['mousedown', 'click']); - await testUtils.dom.triggerEvents($('.modal-dialog .font-icons-icons .font-icons-icon.fa.' + className), ['mousedown', 'click']); - await testUtils.dom.triggerEvents($('.modal-dialog .modal-footer .btn.btn-primary:visible'), ['mousedown', 'click']); -}; -var _valueToRatio = function (value) { - return value < 0 ? 1 / (1 - value) : 1 + value; -}; - - -QUnit.test('Image', function (assert) { - assert.expect(22); - - return weTestUtils.createWysiwyg(this.data).then(function (wysiwyg) { - var $editable = wysiwyg.$('.note-editable'); - - var mediaTests = [{ - name: "Click ADD AN IMAGE URL in empty p: p -> img in p", - async: true, - content: '


', - start: "p->0", - do: async function () { - await _uploadAndInsertImg('https://www.odoo.com/logo.png'); - }, - test: { - content: '

\u200B\u200B

', - check: async function () { - assert.strictEqual($('.note-image-popover').css('display'), 'block', testName + ' (popover)'); - }, - }, - }, - { - name: "add an image in a table", - async: true, - content: '
' + - '' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - '
' + - ' aaa' + - ' ' + - ' bbb' + - ' ' + - ' ccc' + - '
' + - '
', - start: "td:eq(1):contents()[0]->18", - do: async function () { - await _uploadAndInsertImg('https://www.odoo.com/logo.png'); - }, - test: { - content: '
' + - '' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - '
' + - ' aaa' + - ' ' + - ' bbb' + - ' ' + - ' ccc' + - '
' + - '
', - check: async function () { - assert.strictEqual($('.note-image-popover').css('display'), 'block', testName + ' (popover)'); - }, - }, - }, - { - name: "add an image in an empty table", - async: true, - content: '
' + - '' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - '
' + - '
' + - '
' + - '
' + - '
' + - '
' + - '
' + - '
', - start: "br:eq(1)->0", - do: async function () { - await _uploadAndInsertImg('https://www.odoo.com/logo.png'); - }, - test: { - content: '
' + - '' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - '
' + - '
' + - '
' + - '
' + - '
' + - '
' + - '
' + - '
', - check: async function () { - assert.strictEqual($('.note-image-popover').css('display'), 'block', testName + ' (popover)'); - }, - }, - }, - /* IMAGE POPOVER */ - { - name: "Click PADDING XL in popover after adding image in empty p", - async: true, - content: '


', - start: "p->0", - do: async function () { - await _uploadAndInsertImg('https://www.odoo.com/logo.png'); - }, - test: { - content: '

\u200B\u200B

', - check: async function () { - await testUtils.dom.triggerEvents($('.note-image-popover .note-padding .dropdown-toggle'), ['mousedown', 'click']); - await testUtils.dom.triggerEvents($('.note-image-popover .note-padding .dropdown-item:contains("Xl")'), ['mousedown', 'click']); - }, - }, - }, - { - name: "Click IMAGE SIZE 25% in popover after adding image in empty p", - async: true, - content: '


', - start: "p->0", - do: async function () { - await _uploadAndInsertImg('https://www.odoo.com/logo.png'); - }, - test: { - content: '

\u200B\u200B

', - check: async function () { - await testUtils.dom.triggerEvents($('.note-image-popover .note-imagesize .note-btn:contains(25%)'), ['mousedown', 'click']); - }, - }, - }, - { - name: "Click FLOAT RIGHT in popover after adding image in empty p", - async: true, - content: '


', - start: "p->0", - do: async function () { - await _uploadAndInsertImg('https://www.odoo.com/logo.png'); - }, - test: { - content: '

\u200B\u200B

', - check: async function () { - await testUtils.dom.triggerEvents($('.note-image-popover .note-float .note-icon-align-right'), ['mousedown', 'click']); - }, - }, - }, - { - name: "Click FLOAT CENTER then FLOAT LEFT in popover after adding image in empty p", - async: true, - content: '


', - start: "p->0", - do: async function () { - await _uploadAndInsertImg('https://www.odoo.com/logo.png'); - }, - test: { - content: '

\u200B\u200B

', - check: async function () { - await testUtils.dom.triggerEvents($('.note-image-popover .note-float .note-icon-align-center'), ['mousedown', 'click']); - await testUtils.dom.triggerEvents($('.note-image-popover .note-float .note-icon-align-left'), ['mousedown', 'click']); - }, - }, - }, - { - name: "Click SHAPE ROUNDED in popover after adding image in empty p", - async: true, - content: '


', - start: "p->0", - do: async function () { - await _uploadAndInsertImg('https://www.odoo.com/logo.png'); - }, - test: { - content: '

\u200B\u200B

', - check: async function () { - await testUtils.dom.triggerEvents($('.note-image-popover .note-imageShape .note-btn:has(.fa-square)'), ['mousedown', 'click']); - }, - }, - }, - // Remove picture - { - name: "Click REMOVE in popover after adding image in empty p", - async: true, - content: '


', - start: "p->0", - do: async function () { - await _uploadAndInsertImg('https://www.odoo.com/logo.png'); - }, - test: { - content: '


', - check: async function () { - await testUtils.dom.triggerEvents($('.note-image-popover .note-btn .note-icon-trash'), ['mousedown', 'click']); - }, - }, - }, - // Describe picture - { - name: "Click DESCRIPTION in popover after adding image in empty p", - async: true, - content: '


', - start: "p->0", - do: async function () { - await _uploadAndInsertImg('https://www.odoo.com/logo.png'); - }, - test: { - check: async function () { - await altDialogOpened; - await testUtils.dom.triggerEvents($('.note-image-popover .note-btn:contains("Description")'), ['mousedown', 'click']); - $('.modal-dialog input#alt').val('Description'); - await testUtils.nextTick(); - $('.modal-dialog input#title').val('Title'); - await testUtils.nextTick(); - await testUtils.dom.triggerEvents($('.modal-dialog .modal-footer .btn.btn-primary:contains("Save")'), ['mousedown', 'click']); - await altDialogSaved; - var value = $(wysiwyg.getValue()); - // We can't simply compare the string result of getValue - // here, as the img tag has multiple attributes and the - // output order of the attributes is non-deterministic ! - assert.strictEqual(value.prop('tagName'), 'P', "should be a p"); - var contents = value.contents(); - assert.strictEqual(contents.length, 3, "should contain a text node, then an img, then another text node"); - var firstText = contents.eq(0); - assert.notOk(firstText.prop('tagName'), 'should not have a tag name since it is a pure text node'); - assert.strictEqual(firstText.text(), "\u200b"); - var img = contents.eq(1); - assert.strictEqual(img.prop('tagName'), "IMG", "second content should be an img"); - assert.strictEqual(img.prop('className'), "img-fluid o_we_custom_image", "img should have correct class"); - assert.strictEqual(img.data('src'), "/web_editor/static/src/img/transparent.png", "img should have correct data-src"); - assert.strictEqual(img.attr('alt'), "Description", "img should have correct alt"); - // FIXME The following assert fails about once every 100-120 builds. - // Given that the code is currently being refactored and given - // the fact that this assert only tests the title attribute, commenting - // the assert is the easiest "fix" - // assert.strictEqual(img.attr('title'), "Title", "img should have correct title"); - var secondText = contents.eq(2); - assert.notOk(secondText.prop('tagName'), 'should not have a tag name since it is a pure text node'); - assert.strictEqual(secondText.text(), "\u200b"); - }, - }, - }, - ]; - - var def = Promise.resolve(); - _.each(mediaTests, function (test) { - def = def.then(function () { - testName = test.name; - wysiwyg.setValue(test.content); - var range = weTestUtils.select(test.start, test.end, $editable); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - return _clickMedia(wysiwyg, assert, test.do, test.test); - }); - }); - return def.then(function () { - wysiwyg.destroy(); - }); - }); -}); - -QUnit.test('Image crop', function (assert) { - assert.expect(5); - - return weTestUtils.createWysiwyg(this.data).then(function (wysiwyg) { - var $editable = wysiwyg.$('.note-editable'); - - var mediaTests = [{ - name: "Click CROP 16:9 + ZOOM IN in popover after adding image in empty p", - async: true, - content: '


', - start: "p->0", - do: async function () { - await _uploadAndInsertImg('https://www.odoo.com/logo.png'); - }, - test: { - check: async function () { - var zoomRatio; - var $img = $editable.find('img'); - $img.attr('src', $img.data('src')); - await testUtils.dom.triggerEvents($('.note-image-popover .note-btn:has(.fa-crop)'), ['mousedown', 'click']); - await cropDialogOpened; - await testUtils.dom.triggerEvents($('.o_crop_image_dialog .o_crop_options .btn:contains("16:9")'), ['mousedown', 'click']); - var $zoomBtn = $('.o_crop_image_dialog .o_crop_options .btn:has(.fa-search-plus)'); - zoomRatio = _valueToRatio(Number($zoomBtn.data('value'))); - await testUtils.dom.triggerEvents($zoomBtn, ['mousedown', 'click']); - await testUtils.dom.triggerEvents($('.modal-dialog .modal-footer .btn.btn-primary:contains("Save")'), ['mousedown', 'click']); - - var $img = $(wysiwyg.getValue()).find('img.o_cropped_img_to_save'); - assert.strictEqual($img.data('aspect-ratio'), '16/9', testName + " (aspect-ratio)"); - assert.strictEqual($img.data('width'), imgWidth / zoomRatio, testName + " (zoom)"); - }, - }, - }, - { - name: "Click CROP ROTATE LEFT + FLIP HORIZONTAL in popover after adding image in empty p", - async: true, - content: '


', - start: "p->0", - do: async function () { - await _uploadAndInsertImg('https://www.odoo.com/logo.png'); - }, - test: { - check: async function () { - var $img = $editable.find('img'); - $img.attr('src', $img.data('src')); - await testUtils.dom.triggerEvents($('.note-image-popover .note-btn:has(.fa-crop)'), ['mousedown', 'click']); - await cropDialogOpened; - await testUtils.dom.triggerEvents($('.o_crop_image_dialog .o_crop_options .btn:contains("16:9")'), ['mousedown', 'click']); - await testUtils.dom.triggerEvents($('.o_crop_image_dialog .o_crop_options .btn:has(.fa-rotate-left)'), ['mousedown', 'click']); - await testUtils.dom.triggerEvents($('.o_crop_image_dialog .o_crop_options .btn:has(.fa-arrows-h)'), ['mousedown', 'click']); - await testUtils.dom.triggerEvents($('.modal-dialog .modal-footer .btn.btn-primary:contains("Save")'), ['mousedown', 'click']); - - var $img = $(wysiwyg.getValue()).find('img.o_cropped_img_to_save'); - assert.strictEqual($img.data('rotate'), -45, testName + " (rotate)"); - assert.strictEqual($img.data('scale-x'), -1, testName + " (flip)"); - }, - }, - }, - { - name: "Click CROP FREE in popover after adding image in empty p", - async: true, - content: '


', - start: "p->0", - do: async function () { - await _uploadAndInsertImg('https://www.odoo.com/logo.png'); - }, - test: { - check: async function () { - var cropFactor = 10; - var $img = $editable.find('img'); - $img.attr('src', $img.data('src')); - await testUtils.dom.triggerEvents($('.note-image-popover .note-btn:has(.fa-crop)'), ['mousedown', 'click']); - await cropDialogOpened; - var $cropperPoints = $('.modal-dialog .cropper-crop-box .cropper-point'); - var $pointW = $cropperPoints.filter('.point-w'); - var pos1 = $pointW.offset(); - var cropperWidth = $cropperPoints.filter('.point-e').offset().left - pos1.left; - $pointW.trigger($.Event("pointerdown", { - pageX: pos1.left, - pageY: pos1.top, - })); - $pointW.trigger($.Event("pointermove", { - pageX: pos1.left + (cropperWidth / cropFactor), - pageY: pos1.top, - })); - $pointW.trigger('pointerup'); - await testUtils.dom.triggerEvents($('.modal-dialog .modal-footer .btn.btn-primary:contains("Save")'), ['mousedown', 'click']); - - var $img = $(wysiwyg.getValue()).find('img.o_cropped_img_to_save'); - assert.strictEqual(Math.round($img.data('width')), Math.round(imgWidth - (imgWidth / cropFactor)), testName + " (rotate)"); - }, - }, - }, - ]; - - var def = Promise.resolve(); - _.each(mediaTests, function (test) { - def = def.then(function () { - testName = test.name; - wysiwyg.setValue(test.content); - var range = weTestUtils.select(test.start, test.end, $editable); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - return _clickMedia(wysiwyg, assert, test.do, test.test); - }); - }); - return def.then(function () { - wysiwyg.destroy(); - }); - }); -}); - -QUnit.test('Pictogram (fontawesome)', function (assert) { - assert.expect(8); - - return weTestUtils.createWysiwyg(this.data).then(function (wysiwyg) { - var $editable = wysiwyg.$('.note-editable'); - - var mediaTests = [{ - name: "Add PICTOGRAM in empty p: p -> span.fa in p", - async: true, - content: '


', - start: "p->0", - do: async function () { - await _insertPictogram('fa-glass'); - }, - test: { - content: '

\u200B\u200B

', - check: async function () { - assert.strictEqual($('.note-icon-popover').css('display'), 'block', testName + ' (popover)'); - }, - }, - }, - // Remove font - { - name: "Click REMOVE in popover after adding font in empty p", - async: true, - content: '


', - start: "p->0", - do: async function () { - await _insertPictogram('fa-glass'); - }, - test: { - content: '


', - check: async function () { - await testUtils.dom.triggerEvents($('.note-image-popover .note-btn .note-icon-trash'), ['mousedown', 'click']); - }, - }, - }, - // Icon size - { - name: "Click ICON SIZE then 5X in popover after adding pictogram in empty p", - async: true, - content: '


', - start: "p->0", - do: async function () { - await _insertPictogram('fa-glass'); - }, - test: { - content: '

\u200B\u200B

', - check: async function () { - await testUtils.dom.triggerEvents($('.note-icon-popover .note-faSize .dropdown-toggle'), ['mousedown', 'click']); - await testUtils.dom.triggerEvents($('.note-icon-popover .note-faSize .dropdown-item:contains("5x")'), ['mousedown', 'click']); - assert.ok($('.note-icon-popover .note-faSize .dropdown-item:contains("5x")').hasClass('active'), testName + ' (popover)'); - }, - }, - }, - // Spin - { - name: "Click SPIN in popover after adding pictogram in empty p", - async: true, - content: '


', - start: "p->0", - do: async function () { - await _insertPictogram('fa-glass'); - }, - test: { - content: '

\u200B\u200B

', - check: async function () { - await testUtils.dom.triggerEvents($('.note-icon-popover .note-faSpin .note-btn'), ['mousedown', 'click']); - }, - }, - }, - // Replace pictogram - { - name: "Add PICTOGRAM in empty p then replace it", - async: true, - content: '


', - start: "p->0", - do: async function () { - await _insertPictogram('fa-glass'); - }, - test: { - check: async function () { - return _clickMedia(wysiwyg, assert, async function () { - await _insertPictogram('fa-heart'); - }, { - content: '

\u200B\u200B

', - }); - }, - }, - }, - { - name: "Replace PICTOGRAM (i.fa => span.fa)", - async: true, - content: '
\n' + - '
\n' + - ' \n' + - '
Other content
\n' + - '
\n' + - '
', - start: "i->0", - do: async function () { - await _insertPictogram('fa-glass'); - }, - test: { - content: '
\n' + - '
\n' + - ' \n' + - '
Other content
\n' + - '
\n' + - '
', - }, - }, - ]; - - var def = Promise.resolve(); - _.each(mediaTests, function (test) { - def = def.then(async function () { - testName = test.name; - wysiwyg.setValue(test.content); - var range = weTestUtils.select(test.start, test.end, $editable); - await testUtils.dom.triggerEvents($(range.sc), ['mousedown', 'click']); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - return _clickMedia(wysiwyg, assert, test.do, test.test); - }); - }); - return def.then(function () { - wysiwyg.destroy(); - }); - }); -}); - -QUnit.test('Video', function (assert) { - assert.expect(10); - - return weTestUtils.createWysiwyg(this.data).then(function (wysiwyg) { - var $editable = wysiwyg.$('.note-editable'); - - var mediaTests = [{ - name: "Add VIDEO (youtube) in empty p: p -> div.media_iframe_video after p", - async: true, - content: '


', - start: "p->0", - do: async function () { - await _insertVideo(wysiwyg, assert, 'https://www.youtube.com/watch?v=xxxxxxxxxxx', true); - }, - test: { - content: '


 
 


', - check: async function () { - assert.strictEqual($('.note-video-popover').css('display'), 'block', testName + ' (popover)'); - }, - }, - }, - { - name: "Add VIDEO (youtube) in p in breakable in unbreakable in breakable: p -> div.media_iframe_video after p", - async: true, - content: '

tata yoyo

', - start: "p:contents()[0]->4", - do: async function () { - await _insertVideo(wysiwyg, assert, 'https://www.youtube.com/watch?v=xxxxxxxxxxx'); - }, - test: { - content: '

tata

' + - '
 
 
' + - '

yoyo

', - check: async function () { - assert.strictEqual($('.note-video-popover').css('display'), 'block', testName + ' (popover)'); - }, - }, - }, - // Remove video - { - name: "Click REMOVE in popover after adding video in empty p", - async: true, - content: '


', - start: "p->0", - do: async function () { - await _insertVideo(wysiwyg, assert, 'https://www.youtube.com/watch?v=xxxxxxxxxxx'); - }, - test: { - content: '


', - check: async function () { - await testUtils.dom.triggerEvents($('.note-image-popover .note-btn .note-icon-trash'), ['mousedown', 'click']); - }, - }, - }, - /* VIDEO POPOVER */ - // Multiple clicks - { - name: "Click FLOAT CENTER then FLOAT LEFT in popover after adding youtube video in empty p", - async: true, - content: '


', - start: "p->0", - do: async function () { - await _insertVideo(wysiwyg, assert, 'https://www.youtube.com/watch?v=xxxxxxxxxxx'); - }, - test: { - content: '


 
 


', - check: async function () { - await testUtils.dom.triggerEvents($('.note-image-popover .note-float .note-icon-align-center'), ['mousedown', 'click']); - await testUtils.dom.triggerEvents($('.note-image-popover .note-float .note-icon-align-left'), ['mousedown', 'click']); - }, - }, - }, - // Replace picture - { - name: "replace picture with video", - async: true, - content: '

', - start: "img->0", - do: async function () { - await _insertVideo(wysiwyg, assert, 'https://www.youtube.com/watch?v=xxxxxxxxxxx'); - }, - test: { - check: async function () { - assert.deepEqual(wysiwyg.getValue(), - '


 
 


', - testName); - }, - }, - }, - // Replace video - { - name: "replace video by pictogram", - async: true, - content: '


 
 


', - start: "div->0", - do: async function () { - await _insertPictogram('fa-glass'); - }, - test: { - check: async function () { - assert.deepEqual(wysiwyg.getValue(), - '

\u200B\u200B

', - testName); - }, - }, - }, - { - name: "replace video by pictogram (2)", - async: true, - content: '

aaa

 
 

bbb

', - start: "div->0", - do: async function () { - await _insertPictogram('fa-glass'); - }, - test: { - check: async function () { - assert.deepEqual(wysiwyg.getValue(), - '

aaabbb

', - testName); - }, - }, - }, - ]; - - var def = Promise.resolve(); - _.each(mediaTests, function (test) { - def = def.then(async function () { - testName = test.name; - wysiwyg.setValue(test.content); - var range = weTestUtils.select(test.start, test.end, $editable); - await testUtils.dom.triggerEvents($(range.sc), ['mousedown', 'click']); - Wysiwyg.setRange(range.sc, range.so, range.ec, range.eo); - return _clickMedia(wysiwyg, assert, test.do, test.test); - }); - }); - return def.then(function () { - wysiwyg.destroy(); - }); - }); -}); - - -}); -}); -}); -}); diff --git a/addons/web_editor/views/editor.xml b/addons/web_editor/views/editor.xml index 38d56407dbe..1d425a684e3 100644 --- a/addons/web_editor/views/editor.xml +++ b/addons/web_editor/views/editor.xml @@ -183,9 +183,6 @@