summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGorash <chm@odoo.com>2019-08-13 14:18:41 +0000
committerDavid Monjoie <dmo@odoo.com>2019-08-21 19:11:31 +0000
commit1eb1c2b029c7216c70becbf4cd0d9e6535deea96 (patch)
treefa58b034e569278d605e6363fb471e0b2e44d2b4
parent912996fe902c41cafa12dcfe09713ce9857f95ab (diff)
[REF] web_editor: adapt wysiwyg tests to older summernote version
These modifications crystalize the behavior of the old editor, even if it makes less sense than the behavior of the saas-12.2 one. In some cases, the only reasonable adaptation we could do for 13.0 was to delete the tests, as these tests relied on mechanisms of the newer version of summernote introduced in saas-12.2 which cannot be easily replicated in the older version from 12.0 that we are reintroducing in this PR. It is sad to see these tests go, but we knew this was going to be something we would lose in reverting back to the older editor. That being said, since these tests were not present back in 12.0, we are simply back to the 12.0 state of things, not worse. Don't weep for them though, they will be back in Odoo 14. Part of PR 35677. Co-authored-by: Nicolas Bayet <nby@odoo.com> Co-authored-by: Antoine Guenet <age@odoo.com> Co-authored-by: Christophe Matthieu <chm@odoo.com> Co-authored-by: David Monjoie <dmo@odoo.com>
-rw-r--r--addons/mass_mailing/static/tests/mass_mailing_html_tests.js88
-rw-r--r--addons/web_editor/static/tests/field_html_tests.js482
-rw-r--r--addons/web_editor/static/tests/wysiwyg_keyboard_tests.js4423
-rw-r--r--addons/web_editor/static/tests/wysiwyg_snippets_tests.js413
-rw-r--r--addons/web_editor/static/tests/wysiwyg_tests.js4182
-rw-r--r--addons/web_editor/views/editor.xml3
6 files changed, 15 insertions, 9576 deletions
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) {
' />'+
'</form>',
res_id: 1,
- mockRPC: function (route, args) {
- if (args.method === "write") {
- var values = args.args[1];
- assert.strictEqual(values.body_html,
- '<div class="field_body" style="background-color:red;"><p>c<b>od</b>e to edit</p></div>',
- "should save the content");
- assert.strictEqual(values.body_arch,
- '<div class="field_body"><p>c<b>od</b>e to edit</p></div>',
- "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: '<form>' +
- ' <header style="min-height:31px;">' +
- ' <button name="action_put_in_queue" type="object" class="oe_highlight" string="Send Now"/>' +
- ' </header>' +
- ' <field name="body_arch" class="oe_edit_only" widget="mass_mailing_html"' +
- ' options="{' +
- ' \'snippets\': \'template.assets\',' +
- ' \'cssEdit\': \'template.assets\',' +
- ' \'inline-field\': \'body_html\'' +
- ' }"' +
- ' />' +
- '</form>',
- 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(),
- '<p>t<font style="background-color: rgb(0, 255, 255);">oto t</font><font class="bg-gamma">oto&nbsp;to</font>to</p><p>tata</p>',
+ '<p>t<font style="background-color: rgb(0, 255, 255);">oto t</font><font style="" class="bg-gamma">oto&nbsp;</font><font class="bg-gamma" style="">to</font>to</p><p>tata</p>',
"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 = '<p class="pull-right" style="float: right;">toto ' +
- '<img data-class="fa fa-star" data-style="color: red;" src="/web_editor/font_to_img/61445/rgb(255,0,0)/13" style="border-style:none;vertical-align:middle;height: auto; width: auto;">' +
- 'toto toto</p><p>tata</p>';
-
- var form = await testUtils.createView({
- View: FormView,
- model: 'note.note',
- data: this.data,
- arch: '<form>' +
- '<field name="body" widget="html" style="height: 100px" options="{\'style-inline\': true}"/>' +
- '</form>',
- res_id: 1,
- mockRPC: function (route, args) {
- if (args.method === "write") {
- assert.strictEqual(args.args[1].body,
- '<p class="pull-right" style="margin:0px;font-size:13px;font-family:&quot;Lucida Grande&quot;, Helvetica, Verdana, Arial, sans-serif;float:right;">' +
- 'toto ' +
- '<img ' +
- 'data-class="fa fa-star" ' +
- 'data-style="color: red;" ' +
- 'style="border-style:none;vertical-align:middle;color: red; height: auto; width: auto;" ' +
- 'data-src="/web_editor/font_to_img/61445/rgb(255,0,0)/13"' +
- '>' +
- 'toto toto' +
- '</p>' +
- '<p style="margin:0px;font-size:13px;font-family:&quot;Lucida Grande&quot;, Helvetica, Verdana, Arial, sans-serif;">' +
- 'tata' +
- '</p>',
- "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(),
- '<p class="pull-right" style="float: right;">' +
- 'toto ' +
- '<img data-class="fa fa-star" data-style="color: red;" ' +
- 'style="border-style:none;vertical-align:middle;height: auto; width: auto;" ' +
- 'data-src="/web_editor/font_to_img/61445/rgb(255,0,0)/13">' +
- 'toto toto' +
- '</p>' +
- '<p>tata</p>',
- "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(),
- '<p class="pull-right">' +
- 'toto ' +
- '<span class="fa fa-star o_fake_not_editable" style="color: red;" contenteditable="false"></span>' +
- 'toto toto' +
- '</p>' +
- '<p>tata</p>',
- "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,73 +359,7 @@ 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: '<form>' +
- '<field name="body" widget="html" style="height: 100px" options="{\'cssEdit\': \'template.assets\'}"/>' +
- '</form>',
- res_id: 1,
- });
- var $field = form.$('.oe_form_field[name="body"]');
- assert.strictEqual($field.children('.o_readonly').html(),
- '<p>toto toto toto</p><p>tata</p>',
- "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(),
- '<p>toto toto toto</p><p>tata</p>',
- "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: '<form>' +
- '<field name="body" widget="html" style="height: 100px" options="{\'cssEdit\': \'template.assets\'}"/>' +
- '</form>',
- 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({
@@ -507,291 +367,18 @@ QUnit.test('save immediately before iframe is rendered in edit mode', async func
model: 'note.note',
data: this.data,
arch: '<form>' +
- '<field name="body" widget="html" style="height: 100px" options="{\'cssEdit\': \'template.assets\', \'style-inline\': true}"/>' +
- '</form>',
- 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,
- arch: '<form>' +
'<field name="body" widget="html" style="height: 100px" options="{\'cssEdit\': \'template.assets\'}"/>' +
'</form>',
res_id: 1,
- mockRPC: function (route, args) {
- if (args.method === "write") {
- assert.strictEqual(args.args[1].body,
- '<p>t<font class="bg-gamma">oto toto&nbsp;</font>toto</p><p>tata</p>',
- "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: '<form>' +
- '<field name="body" widget="html" style="height: 100px" options="{\'snippets\': \'web_editor.snippets\'}"/>' +
- '</form>',
- 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: '<form>' +
- '<field name="body" widget="html" style="height: 100px" options="{\'snippets\': \'web_editor.snippets\'}"/>' +
- '</form>',
- 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, ' '),
- '<div class=\"s_hr pt32 pb32\"> <hr class=\"s_hr_1px s_hr_solid w-100 mx-auto\"> </div><p>toto toto toto</p><p>tata</p>',
- "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: '<form>' +
- '<field name="body" widget="html" style="height: 100px" options="{\'snippets\': \'web_editor.snippets\', \'cssEdit\': \'template.assets\'}"/>' +
- '</form>',
- 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: '<form>' +
- '<field name="body" widget="html" style="height: 100px" options="{\'snippets\': \'web_editor.snippets\', \'cssEdit\': \'template.assets_all_style\'}"/>' +
- '</form>',
- 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, ' '),
- '<div class=\"s_hr pt32 pb32\"> <hr class=\"s_hr_1px s_hr_solid w-100 mx-auto\"> </div><p>toto toto toto</p><p>tata</p>',
- "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: '<form>' +
- '<field name="body" widget="html" style="height: 100px" options="{\'snippets\': \'web_editor.snippets\', \'cssEdit\': \'template.assets_all_style\'}"/>' +
- '</form>',
- 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, ' '),
- '<div class=\"s_hr pt32 pb32 built focus\"> <hr class=\"s_hr_1px s_hr_solid w-100 mx-auto\"> </div><p>toto toto toto</p><p>tata</p>',
- "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, ' '),
- '<div class=\"s_hr pt32 pb32 built\"> <hr class=\"s_hr_1px s_hr_solid w-100 mx-auto\"> ' +
- '</div><div class=\"s_hr pt32 pb32 built focus\"> <hr class=\"s_hr_1px s_hr_solid w-100 mx-auto\"> ' +
- '</div><p>toto toto toto</p><p>tata</p>',
- "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: '<form>' +
- '<field name="body" widget="html" style="height: 100px" options="{\'cssEdit\': \'template.assets\'}"/>' +
- '</form>',
- 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 = [
- ' <noteditable id="a">',
- ' content_a_0',
- ' <noteditable id="b">content_b_0</noteditable>',
- ' <editable id="c">',
- ' content_c_0',
- ' <noteditable id="d">content_d_0</noteditable>',
- ' <noteditable id="e">',
- ' content_e_0',
- ' <editable id="f">content_f_0</editable>',
- ' content_e_1',
- ' </noteditable>',
- ' content_c_4',
- ' </editable>',
- ' <noteditable id="g">content_g_0</noteditable>',
- ' <editable id="h">',
- ' content_h_0',
- ' <noteditable id="i">content_i_0</noteditable>',
- ' content_h_2',
- ' </editable>',
- ' <editable id="j">',
- ' content_j_0',
- ' <editable id="k">content_k_0</editable>',
- ' <editable id="l">content_l_0</editable>',
- ' content_j_4',
- ' </editable>',
- ' </noteditable>',
- ' <editable id="m">content_m_0</editable>',
- ' <editable id="n">content_n_0</editable>',
- ''
-].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: "<p class='unbreakable'>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->1",
- end: "p:contents()[0]->1",
- key: 'ENTER',
- }],
- test: {
- content: '<p class="unbreakable">d<br>om to edit</p>',
- 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: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->3",
- keyCode: 66,
- }],
- test: {
- content: "<p>domB to edit</p>",
- start: "p:contents()[0]->4",
- end: null,
- check: function ($editable, assert) {
- assert.ok(true);
- },
- },
- },
- {
- name: "visible char in a link tag entirely selected",
- content: '<div><a href="#">dom to edit</a></div>',
- steps: [{
- start: "a:contents()[0]->0",
- end: "a:contents()[0]->11",
- key: 'a',
- }],
- test: {
- content: '<div><a href="#">&#8203;a&#8203;</a></div>',
- start: "a:contents()[0]->2",
- },
- },
- {
- name: "'a' on a selection of all the contents of a complex dom",
- content: "<p><b>dom</b></p><p><b>to<br>completely</b>remov<i>e</i></p>",
- steps: [{
- start: "p:contents()[0]->0",
- end: "i:contents()[0]->1",
- key: 'a',
- }],
- test: {
- content: "<p><b>a</b></p>",
- start: "b:contents()[0]->1",
- },
- },
- {
- name: "'a' on a selection of all the contents of a complex dom (2)",
- content: "<h1 class=\"a\"><font style=\"font-size: 62px;\"><b>dom to</b>edit</font></h1>",
- steps: [{
- start: "font:contents()[0]->0",
- end: "font:contents()[1]->4",
- key: 'a',
- }],
- test: {
- content: "<h1 class=\"a\"><font style=\"font-size: 62px;\"><b>a</b></font></h1>",
- start: "b:contents()[0]->1",
- },
- },
- {
- name: "'a' before an image",
- content: '<p>xxx <img src="/web_editor/static/src/img/transparent.png"> yyy</p>',
- steps: [{
- start: "p:contents()[0]->4",
- key: 'a',
- }],
- test: {
- content: '<p>xxx a<img data-src="/web_editor/static/src/img/transparent.png"> yyy</p>',
- start: "p:contents()[0]->5",
- },
- },
- {
- name: "'a' before an image (2)",
- content: '<p>xxx <img src="/web_editor/static/src/img/transparent.png"> yyy</p>',
- steps: [{
- start: "img->0",
- key: 'a',
- }],
- test: {
- content: '<p>xxx a<img data-src="/web_editor/static/src/img/transparent.png"> yyy</p>',
- start: "p:contents()[0]->5",
- },
- },
- {
- name: "'a' before an image in table",
- content: '<table><tbody><tr><td><p>xxx</p></td><td><p><img src="/web_editor/static/src/img/transparent.png"></p></td><td><p>yyy</p></td></tr></tbody></table>',
- steps: [{
- start: "img->0",
- key: 'a',
- }],
- test: {
- content: '<table><tbody><tr><td><p>xxx</p></td><td><p>a<img data-src="/web_editor/static/src/img/transparent.png"></p></td><td><p>yyy</p></td></tr></tbody></table>',
- start: "p:eq(1):contents()[0]->1",
- },
- },
- {
- name: "'a' on invisible text before an image in table",
- content: '<table><tbody><tr><td><p>xxx</p></td><td><p><img src="/web_editor/static/src/img/transparent.png"></p></td><td><p>yyy</p></td></tr></tbody></table>',
- steps: [{
- start: "p:eq(1)->0",
- key: 'a',
- }],
- test: {
- content: '<table><tbody><tr><td><p>xxx</p></td><td><p>a<img data-src="/web_editor/static/src/img/transparent.png"></p></td><td><p>yyy</p></td></tr></tbody></table>',
- start: "p:eq(1):contents()[0]->1",
- },
- },
- {
- name: "'a' before an image in table without spaces",
- content: '<table><tbody><tr><td><p>xxx</p></td><td><p><img src="/web_editor/static/src/img/transparent.png"></p></td><td><p>yyy</p></td></tr></tbody></table>',
- steps: [{
- start: "img->0",
- key: 'a',
- }],
- test: {
- content: '<table><tbody><tr><td><p>xxx</p></td><td><p>a<img data-src="/web_editor/static/src/img/transparent.png"></p></td><td><p>yyy</p></td></tr></tbody></table>',
- start: "p:eq(1):contents()[0]->1",
- },
- },
- {
- name: "'a' before an image in table without spaces (2)",
- content: '<table><tbody><tr><td><p>xxx</p></td><td><p><img src="/web_editor/static/src/img/transparent.png"></p></td><td><p>yyy</p></td></tr></tbody></table>',
- steps: [{
- start: "td:eq(1)->0",
- key: 'a',
- }],
- test: {
- content: '<table><tbody><tr><td><p>xxx</p></td><td><p>a<img data-src="/web_editor/static/src/img/transparent.png"></p></td><td><p>yyy</p></td></tr></tbody></table>',
- start: "p:eq(1):contents()[0]->1",
- },
- },
- {
- name: "'a' before an image in table with spaces",
- content:
- '<table><tbody>\n' +
- ' <tr>\n' +
- ' <td>\n' +
- ' <p>xxx</p>\n' +
- ' </td>\n' +
- ' <td>\n' +
- ' <p><img src="/web_editor/static/src/img/transparent.png"></p>\n' +
- ' </td>\n' +
- ' <td>\n' +
- ' <p>yyy</p>\n' +
- ' </td>\n' +
- ' </tr>\n' +
- '</tbody></table>',
- steps: [{
- start: "img->0",
- key: 'a',
- }],
- test: {
- content:
- '<table><tbody>\n' +
- ' <tr>\n' +
- ' <td>\n' +
- ' <p>xxx</p>\n' +
- ' </td>\n' +
- ' <td>\n' +
- ' <p>a<img data-src="/web_editor/static/src/img/transparent.png"></p>\n' +
- ' </td>\n' +
- ' <td>\n' +
- ' <p>yyy</p>\n' +
- ' </td>\n' +
- ' </tr>\n' +
- '</tbody></table>',
- start: "p:eq(1):contents()[0]->1",
- },
- },
- {
- name: "'a' before an image in table with spaces (2)",
- content:
- '<table><tbody>\n' +
- ' <tr>\n' +
- ' <td>\n' +
- ' <p>xxx</p>\n' +
- ' </td>\n' +
- ' <td>\n' +
- ' <p><img src="/web_editor/static/src/img/transparent.png"></p>\n' +
- ' </td>\n' +
- ' <td>\n' +
- ' <p>yyy</p>\n' +
- ' </td>\n' +
- ' </tr>\n' +
- '</tbody></table>',
- steps: [{
- start: "td:eq(1)->1",
- key: 'a',
- }],
- test: {
- content:
- '<table><tbody>\n' +
- ' <tr>\n' +
- ' <td>\n' +
- ' <p>xxx</p>\n' +
- ' </td>\n' +
- ' <td>\n' +
- ' <p>a<img data-src="/web_editor/static/src/img/transparent.png"></p>\n' +
- ' </td>\n' +
- ' <td>\n' +
- ' <p>yyy</p>\n' +
- ' </td>\n' +
- ' </tr>\n' +
- '</tbody></table>',
- start: "p:eq(1):contents()[0]->1",
- },
- },
- {
- name: "'a' before an image in table with spaces (3)",
- content:
- '<table><tbody>\n' +
- ' <tr>\n' +
- ' <td>\n' +
- ' <p>xxx</p>\n' +
- ' </td>\n' +
- ' <td>\n' +
- ' <p><img src="/web_editor/static/src/img/transparent.png"></p>\n' +
- ' </td>\n' +
- ' <td>\n' +
- ' <p>yyy</p>\n' +
- ' </td>\n' +
- ' </tr>\n' +
- '</tbody></table>',
- steps: [{
- start: "td:eq(1):contents()[0]->12",
- key: 'a',
- }],
- test: {
- content:
- '<table><tbody>\n' +
- ' <tr>\n' +
- ' <td>\n' +
- ' <p>xxx</p>\n' +
- ' </td>\n' +
- ' <td>\n' +
- ' <p>a<img data-src="/web_editor/static/src/img/transparent.png"></p>\n' +
- ' </td>\n' +
- ' <td>\n' +
- ' <p>yyy</p>\n' +
- ' </td>\n' +
- ' </tr>\n' +
- '</tbody></table>',
- start: "p:eq(1):contents()[0]->1",
- },
- },
- {
- name: "'a' on begin of a span with fake_editable",
- content:
- '<div class="o_fake_not_editable" contentEditable="false">\n' +
- ' <div>\n' +
- ' <label>\n' +
- ' <input type="checkbox"/>\n' +
- ' <span class="o_fake_editable" contentEditable="true">\n' +
- ' dom to edit\n' +
- ' </span>\n' +
- ' </label>\n' +
- ' </div>\n' +
- '</div>',
- steps: [{
- start: "span:contents(0)->10",
- key: 'a',
- }],
- test: {
- content:
- '<div>\n' +
- ' <div>\n' +
- ' <label>\n' +
- ' <input type="checkbox">\n' +
- ' <span>\n' +
- ' adom to edit\n' +
- ' </span>\n' +
- ' </label>\n' +
- ' </div>\n' +
- '</div>',
- start: "span:contents(0)->11",
- },
- },
- {
- name: "'a' on all contents of p starting with an icon",
- content: '<p><span class="fa fa-star"></span>bbb</p>',
- steps: [{
- start: "span->0",
- end: 'p:contents(1)->3',
- key: 'a',
- }],
- test: {
- content: '<p>a</p>',
- start: "p:contents()[0]->1",
- },
- },
- {
- name: "' ' at start of p",
- content: '<p>dom to edit</p>',
- steps: [{
- start: "p:contents()[0]->0",
- key: ' ',
- }],
- test: {
- content: '<p>&nbsp;dom to edit</p>',
- start: "p:contents()[0]->1",
- },
- },
- {
- name: "' ' at end of p",
- content: '<p>dom to edit</p>',
- steps: [{
- start: "p:contents()[0]->11",
- key: ' ',
- }],
- test: {
- content: '<p>dom to edit&nbsp;</p>',
- start: "p:contents()[0]->12",
- },
- },
- {
- name: "' ' within p",
- content: '<p>dom to edit</p>',
- steps: [{
- start: "p:contents()[0]->2",
- key: ' ',
- }],
- test: {
- content: '<p>do m to edit</p>',
- start: "p:contents()[0]->3",
- },
- },
- {
- name: "' ' before space within p",
- content: '<p>dom to edit</p>',
- steps: [{
- start: "p:contents()[0]->3",
- key: ' ',
- }],
- test: {
- content: '<p>dom&nbsp;&nbsp;to edit</p>',
- start: "p:contents()[0]->4",
- },
- },
- {
- name: "' ' after space within p",
- content: '<p>dom to edit</p>',
- steps: [{
- start: "p:contents()[0]->4",
- key: ' ',
- }],
- test: {
- content: '<p>dom&nbsp;&nbsp;to edit</p>',
- start: "p:contents()[0]->5",
- },
- },
- {
- name: "3x ' ' at start of p",
- content: '<p>dom to edit</p>',
- steps: [{
- start: "p:contents()[0]->0",
- key: ' ',
- }, {
- key: ' ',
- }, {
- key: ' ',
- }],
- test: {
- content: '<p>&nbsp;&nbsp;&nbsp;dom to edit</p>',
- start: "p:contents()[0]->3",
- },
- },
- {
- name: "3x ' ' at end of p",
- content: '<p>dom to edit</p>',
- steps: [{
- start: "p:contents()[0]->11",
- key: ' ',
- }, {
- key: ' ',
- }, {
- key: ' ',
- }],
- test: {
- content: '<p>dom to edit&nbsp;&nbsp;&nbsp;</p>',
- start: "p:contents()[0]->14",
- },
- },
- {
- name: "3x ' ' within p",
- content: '<p>dom to edit</p>',
- steps: [{
- start: "p:contents()[0]->2",
- key: ' ',
- }, {
- key: ' ',
- }, {
- key: ' ',
- }],
- test: {
- content: '<p>do&nbsp;&nbsp;&nbsp;m to edit</p>',
- start: "p:contents()[0]->5",
- },
- },
- {
- name: "3x ' ' before space in p",
- content: '<p>dom to edit</p>',
- steps: [{
- start: "p:contents()[0]->3",
- key: ' ',
- }, {
- key: ' ',
- }, {
- key: ' ',
- }],
- test: {
- content: '<p>dom&nbsp;&nbsp;&nbsp;&nbsp;to edit</p>',
- start: "p:contents()[0]->6",
- },
- },
- {
- name: "3x ' ' after space in p",
- content: '<p>dom to edit</p>',
- steps: [{
- start: "p:contents()[0]->4",
- key: ' ',
- }, {
- key: ' ',
- }, {
- key: ' ',
- }],
- test: {
- content: '<p>dom&nbsp;&nbsp;&nbsp;&nbsp;to edit</p>',
- start: "p:contents()[0]->7",
- },
- },
- {
- name: "'a' in unbreakable with font",
- content: '<div class="unbreakable">dom <span class="fa fa-heart"></span>to edit</div>',
- steps: [{
- start: "div:contents(2)->2",
- key: 'a',
- }],
- test: {
- content: '<div class="unbreakable">dom <span class="fa fa-heart"></span>toa edit</div>',
- start: "div:contents(2)->3",
- },
- },
- {
- name: "'a' on begin of unbreakable inline node",
- content: 'dom <strong class="unbreakable">to</strong> edit',
- steps: [{
- start: "strong:contents(0)->0",
- key: 'a',
- }],
- test: {
- content: 'dom <strong class="unbreakable">ato</strong> edit',
- start: "strong:contents(0)->1",
- },
- },
- {
- name: "'a' on end of unbreakable inline node",
- content: '<div>dom <strong class="unbreakable">to</strong> edit</div>',
- steps: [{
- start: "strong:contents(0)->2",
- key: 'a',
- }],
- test: {
- content: '<div>dom <strong class="unbreakable">toa</strong> edit</div>',
- start: "strong:contents(0)->3",
- },
- },
- {
- name: "'1' on begin of value of a field currency",
- content:
- '<noteditable>\n' +
- '<b data-oe-type="monetary" class="oe_price editable">$&nbsp;<span class="oe_currency_value">750.00</span></b>\n' +
- '</noteditable>',
- steps: [{
- start: "span:contents(0)->0",
- key: '1',
- }],
- test: {
- content:
- '<noteditable>\n' +
- '<b data-oe-type="monetary" class="oe_price editable">$&nbsp;<span class="oe_currency_value">1750.00</span></b>\n' +
- '</noteditable>',
- start: "span:contents(0)->1",
- },
- },
- {
- name: "'1' on end of value of a field currency",
- content:
- '<noteditable>\n' +
- '<b data-oe-type="monetary" class="oe_price editable">$&nbsp;<span class="oe_currency_value">750.00</span></b>\n' +
- '</noteditable>',
- steps: [{
- start: "span:contents(0)->6",
- key: '1',
- }],
- test: {
- content:
- '<noteditable>\n' +
- '<b data-oe-type="monetary" class="oe_price editable">$&nbsp;<span class="oe_currency_value">750.001</span></b>\n' +
- '</noteditable>',
- start: "span:contents(0)->7",
- },
- },
- {
- name: "'1' on begin of editable in noteditable",
- content:
- '<noteditable contenteditable="false">\n' +
- '<b data-oe-type="monetary" class="oe_price editable" contenteditable="true">$&nbsp;<span class="oe_currency_value">750.00</span></b>\n' +
- '</noteditable>',
- steps: [{
- start: "span:contents(0)->0",
- key: '1',
- }],
- test: {
- content:
- '<noteditable>\n' +
- '<b data-oe-type="monetary" class="oe_price editable">$&nbsp;<span class="oe_currency_value">1750.00</span></b>\n' +
- '</noteditable>',
- start: "span:contents(0)->1",
- },
- },
- {
- name: "'1' on end of editable in noteditable",
- content:
- '<noteditable contenteditable="false">\n' +
- '<b data-oe-type="monetary" class="oe_price editable" contenteditable="true">$&nbsp;<span class="oe_currency_value">750.00</span></b>\n' +
- '</noteditable>',
- steps: [{
- start: "span:contents(0)->6",
- key: '1',
- }],
- test: {
- content:
- '<noteditable>\n' +
- '<b data-oe-type="monetary" class="oe_price editable">$&nbsp;<span class="oe_currency_value">750.001</span></b>\n' +
- '</noteditable>',
- start: "span:contents(0)->7",
- },
- },
- {
- name: "'a' on editable with before&after in noteditable",
- content:
- '<style>#test-before-after:before { content: "placeholder";} #test-before-after:after { content: "\\00a0";}</style>\n' +
- '<noteditable contenteditable="false">\n' +
- '<b id="test-before-after" class="editable" contenteditable="true"></b>\n' +
- '</noteditable>',
- steps: [{
- start: "b->0",
- key: 'a',
- }],
- test: {
- content:
- '<style>#test-before-after:before { content: "placeholder";} #test-before-after:after { content: "\\00a0";}</style>\n' +
- '<noteditable>\n' +
- '<b id="test-before-after" class="editable">a</b>\n' +
- '</noteditable>',
- start: "b:contents(0)->1",
- },
- },
- {
- name: "'a' in empty li",
- content: '<ul><li><p><br></p></li></ul>',
- steps: [{
- start: "p->1",
- key: 'a',
- }],
- test: {
- content: '<ul><li><p>a</p></li></ul>',
- 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: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->1",
- key: 'ENTER',
- }],
- test: {
- content: "<p>d</p><p>om to edit</p>",
- start: "p:contents()[1]->0",
- },
- },
- {
- name: "in p: 2x ENTER",
- content: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->1",
- key: 'ENTER',
- }, {
- key: 'ENTER',
- }],
- test: {
- content: "<p>d</p><p><br></p><p>om to edit</p>",
- start: "p:contents()[2]->0",
- },
- },
- {
- name: "in p: SHIFT+ENTER",
- content: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->1",
- key: 'ENTER',
- shiftKey: true,
- }],
- test: {
- content: "<p>d<br>om to edit</p>",
- start: "p:contents()[2]->0",
- },
- },
- {
- name: "in empty-p: SHIFT+ENTER",
- content: "<p><br></p>",
- steps: [{
- start: "p->1",
- key: 'ENTER',
- shiftKey: true,
- }],
- test: {
- content: "<p><br><br></p>",
- start: "br:eq(1)->0",
- },
- },
- {
- name: "in p: 2x SHIFT+ENTER",
- content: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->1",
- key: 'ENTER',
- shiftKey: true,
- }, {
- key: 'ENTER',
- shiftKey: true,
- }],
- test: {
- content: "<p>d<br><br>om to edit</p>",
- start: "p:contents()[3]->0",
- },
- },
- {
- name: "in empty-p: 2x SHIFT+ENTER",
- content: "<p><br></p>",
- steps: [{
- start: "p->1",
- key: 'ENTER',
- shiftKey: true,
- }, {
- key: 'ENTER',
- shiftKey: true,
- }],
- test: {
- content: "<p><br><br><br></p>",
- start: "br:eq(2)->0",
- },
- },
- {
- name: "in p: ENTER -> SHIFT+ENTER",
- content: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->1",
- key: 'ENTER',
- }, {
- key: 'ENTER',
- shiftKey: true,
- }],
- test: {
- content: "<p>d</p><p><br>om to edit</p>",
- start: "p:eq(1):contents()[1]->0",
- },
- },
- {
- name: "in p: ENTER on selection",
- content: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->1",
- end: "p:contents()[0]->7",
- key: 'ENTER',
- }],
- test: {
- content: "<p>d</p><p>edit</p>",
- start: "p:contents()[1]->0",
- end: "p:contents()[1]->0",
- },
- },
- {
- name: "in p: SHIFT+ENTER on selection",
- content: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->1",
- end: "p:contents()[0]->7",
- key: 'ENTER',
- shiftKey: true,
- }],
- test: {
- content: "<p>d<br>edit</p>",
- start: "p:contents()[2]->0",
- },
- },
-
- // list UL / OL
-
- {
- name: "in li: SHIFT+ENTER at start",
- content: "<ul><li>dom to edit</li></ul>",
- steps: [{
- start: "li:contents()[0]->0",
- key: 'ENTER',
- shiftKey: true,
- }],
- test: {
- content: "<ul><li><br>dom to edit</li></ul>",
- start: "li:contents()[1]->0",
- },
- },
- {
- name: "in li: SHIFT+ENTER within contents",
- content: "<ul><li>dom to edit</li></ul>",
- steps: [{
- start: "li:contents()[0]->5",
- key: 'ENTER',
- shiftKey: true,
- }],
- test: {
- content: "<ul><li>dom t<br>o edit</li></ul>",
- start: "li:contents()[2]->0",
- },
- },
- {
- name: "in empty-li: SHIFT+ENTER",
- content: "<ul><li><br></li></ul>",
- steps: [{
- start: "li:contents()[0]->0",
- key: 'ENTER',
- shiftKey: true,
- }],
- test: {
- content: "<ul><li><br><br></li></ul>",
- start: "br:eq(1)->0",
- },
- },
- {
- name: "in li: SHIFT+ENTER on selection",
- content: "<ul><li>dom to edit</li></ul>",
- steps: [{
- start: "li:contents()[0]->1",
- end: "li:contents()[0]->7",
- key: 'ENTER',
- shiftKey: true,
- }],
- test: {
- content: "<ul><li>d<br>edit</li></ul>",
- start: "li:contents()[2]->0",
- },
- },
- {
- name: "in li: ENTER at start",
- content: "<ul><li>dom to edit</li></ul>",
- steps: [{
- start: "li:contents()[0]->0",
- key: 'ENTER',
- }],
- test: {
- content: "<ul><li><br></li><li>dom to edit</li></ul>",
- start: "li:contents()[1]->0",
- },
- },
- {
- name: "in li: ENTER within contents",
- content: "<ul><li>dom to edit</li></ul>",
- steps: [{
- start: "li:contents()[0]->5",
- key: 'ENTER',
- }],
- test: {
- content: "<ul><li>dom t</li><li>o edit</li></ul>",
- start: "li:eq(1):contents()[0]->0",
- },
- },
- {
- name: "in li: ENTER on selection",
- content: "<ul><li>dom to edit</li></ul>",
- steps: [{
- start: "li:contents()[0]->1",
- end: "li:contents()[0]->7",
- key: 'ENTER',
- }],
- test: {
- content: "<ul><li>d</li><li>edit</li></ul>",
- start: "li:eq(1):contents()[0]->0",
- },
- },
- {
- name: "in li: ENTER on selection of all contents",
- content: "<ul><li>dom to edit</li></ul>",
- steps: [{
- start: "li:contents()[0]->0",
- end: "li:contents()[0]->11",
- key: 'ENTER',
- }],
- test: {
- content: "<p><br></p>",
- start: "br->0",
- },
- },
- {
- name: "in li: ENTER -> 'a' on selection of all contents",
- content: "<ul><li>dom to edit</li></ul>",
- steps: [{
- start: "li:contents()[0]->0",
- end: "li:contents()[0]->11",
- key: 'ENTER',
- }, {
- key: 'a',
- }],
- test: {
- content: "<p>a</p>",
- start: "p:contents()[0]->1",
- },
- },
- {
- name: "across 2 li: ENTER on partial selection",
- content: "<ul><li>dom to edit</li><li>dom to edit</li></ul>",
- steps: [{
- start: "li:contents()[0]->1",
- end: "li:eq(1):contents()[0]->4",
- key: 'ENTER',
- }],
- test: {
- content: "<ul><li>d</li><li>to edit</li></ul>",
- start: "li:eq(1):contents()[0]->0", // we are after the <br>, the carret is on the li with an offset equal to the node length
- },
- },
- {
- name: "in li: ENTER at end",
- content: "<ul><li><p>dom to edit</p></li></ul>",
- steps: [{
- start: "p:contents()[0]->11",
- key: 'ENTER',
- }],
- test: {
- content: "<ul><li><p>dom to edit</p></li><li><p><br></p></li></ul>",
- start: "br->0",
- },
- },
- {
- name: "in li: 2x ENTER at end",
- content: "<ul><li><p>dom to edit</p></li></ul>",
- steps: [{
- start: "p:contents()[0]->11",
- key: 'ENTER',
- }, {
- key: 'ENTER',
- }],
- test: {
- content: "<ul><li><p>dom to edit</p></li></ul><p><br></p>",
- start: "br->0",
- },
- },
- {
- name: "in ul.list-group > li: ENTER at end",
- content: '<ul class="list-group"><li><p>dom to edit</p></li></ul>',
- steps: [{
- start: "p:contents()[0]->11",
- key: 'ENTER',
- }, {
- key: 'ENTER',
- }],
- test: {
- content: '<ul class="list-group"><li><p>dom to edit</p></li><li><p><br></p></li><li><p><br></p></li></ul>',
- start: "p:eq(2) br->0",
- },
- },
- {
- name: "in indented-li: 2x ENTER at end",
- content: "<ul><li><p>aaa</p></li><ul><li><p>dom to edit</p></li></ul><li><p>bbb</p></li></ul>",
- steps: [{
- start: "ul ul p:contents()[0]->11",
- key: 'ENTER',
- }, {
- key: 'ENTER',
- }],
- test: {
- content: "<ul><li><p>aaa</p></li><ul><li><p>dom to edit</p></li></ul><li><p><br></p></li><li><p>bbb</p></li></ul>",
- start: "p:eq(2) br->0",
- },
- },
- {
- name: "in indented-li with font: 2x ENTER at end",
- content: "<ul><li><p>aaa</p></li><ul><li><p><font style=\"color\">dom to edit</font></p></li></ul><li><p>bbb</p></li></ul>",
- steps: [{
- start: "font:contents()[0]->11",
- key: 'ENTER',
- }, {
- key: 'ENTER',
- }],
- test: {
- content: "<ul><li><p>aaa</p></li><ul><li><p><font style=\"color\">dom to edit</font></p></li></ul><li><p><font style=\"color\"><br></font></p></li><li><p>bbb</p></li></ul>",
- start: "p:eq(2) br->0",
- },
- },
- {
- name: "in li > empty-p: ENTER",
- content: "<ul><li><p><br></p></li></ul>",
- steps: [{
- start: "p:contents()[0]->0",
- key: 'ENTER',
- }],
- test: {
- content: "<p><br></p>",
- start: "br->0",
- },
- },
- {
- name: "in li > p > empty-b: ENTER",
- content: "<ul><li><p><b><br></b></p></li></ul>",
- steps: [{
- start: "b:contents()[0]->0",
- key: 'ENTER',
- }],
- test: {
- content: "<p><b><br></b></p>",
- start: "br->0",
- },
- },
- {
- name: "in ul.o_checklist > li.o_checked > p: ENTER at end",
- content: '<ul class="o_checklist"><li class="o_checked"><p>test</p></li></ul>',
- steps: [{
- start: "p:contents()[0]->4",
- key: 'ENTER',
- }],
- test: {
- content: '<ul class="o_checklist"><li class="o_checked"><p>test</p></li><li><p><br></p></li></ul>',
- start: "br->0",
- },
- },
- {
- name: "in ul.o_checklist > li.o_checked > p > b: ENTER within text",
- content: '<ul class="o_checklist"><li class="o_checked"><p><b>test</b></p></li></ul>',
- steps: [{
- start: "b:contents()[0]->2",
- key: 'ENTER',
- }],
- test: {
- content: '<ul class="o_checklist"><li class="o_checked"><p><b>te</b></p></li><li><p><b>st</b></p></li></ul>',
- start: "b:eq(1):contents()[0]->0",
- },
- },
-
- // end list UL / OL
-
- {
- name: "after p > b: SHIFT+ENTER",
- content: "<p><b>dom</b> to edit</p>",
- steps: [{
- start: "p:contents()[1]->0",
- key: 'ENTER',
- shiftKey: true,
- }],
- test: {
- content: "<p><b>dom</b><br>&nbsp;to edit</p>",
- start: "p:contents()[2]->0",
- },
- },
- {
- name: "in p > b: ENTER -> 'a'",
- content: "<p><b>dom to edit</b></p>",
- steps: [{
- start: "b:contents()[0]->2",
- key: 'ENTER',
- }, {
- key: 'a',
- }],
- test: {
- content: "<p><b>do</b></p><p><b>am to edit</b></p>",
- start: "b:eq(1):contents()[0]->1",
- },
- },
- {
- name: "after p > b: ENTER -> 'a'",
- content: "<p><b>dom</b> to edit</p>",
- steps: [{
- start: "p:contents()[1]->0",
- key: 'ENTER',
- }, {
- key: 'a',
- }],
- test: {
- content: "<p><b>dom</b></p><p>a to edit</p>",
- start: "p:eq(1):contents()[0]->1",
- },
- },
- {
- name: "after p > b: SHIFT+ENTER -> 'a'",
- content: "<p><b>dom</b>&nbsp;to edit</p>",
- steps: [{
- start: "p:contents()[1]->0",
- key: 'ENTER',
- shiftKey: true,
- }, {
- key: 'a',
- }],
- test: {
- content: "<p><b>dom</b><br>a to edit</p>",
- start: "p:contents()[2]->1",
- },
- },
- {
- name: "in p (other-p > span.a before - p > span.b after): ENTER at beginning",
- content: "<p><span class=\"a\">dom to</span></p><p><span class=\"b\">edit</span></p>",
- steps: [{
- start: "p:eq(1):contents()[0]->0",
- key: 'ENTER',
- }],
- test: {
- content: "<p><span class=\"a\">dom to</span></p><p><span class=\"b\"><br></span></p><p><span class=\"b\">edit</span></p>",
- start: "span:eq(2):contents()[0]->0",
- },
- },
- {
- name: "in p (other-p > span.a before - p > span.b after): ENTER -> 'a' at beginning",
- content: "<p><span class=\"a\">dom to</span></p><p><span class=\"b\">edit</span></p>",
- steps: [{
- start: "p:eq(1):contents()[0]->0",
- key: 'ENTER',
- }, {
- key: 'a',
- }],
- test: {
- content: "<p><span class=\"a\">dom to</span></p><p><span class=\"b\"><br></span></p><p><span class=\"b\">aedit</span></p>",
- start: "span:eq(2):contents()[0]->1",
- },
- },
- {
- name: "in p (other-p > span.a before - p > span.b after): SHIFT+ENTER at beginning",
- content: "<p><span class=\"a\">dom to</span></p><p><span class=\"b\">edit</span></p>",
- steps: [{
- start: "p:eq(1):contents()[0]->0",
- key: 'ENTER',
- shiftKey: true,
- }],
- test: {
- content: "<p><span class=\"a\">dom to</span></p><p><span class=\"b\"><br>edit</span></p>",
- 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: "<p><span class=\"a\">dom to</span></p><p><span class=\"b\">edit</span></p>",
- steps: [{
- start: "p:eq(1):contents()[0]->0",
- key: 'ENTER',
- shiftKey: true,
- }, {
- key: 'a',
- }],
- test: {
- content: "<p><span class=\"a\">dom to</span></p><p><span class=\"b\"><br>aedit</span></p>",
- start: "span:eq(1):contents()[1]->1",
- },
- },
- {
- name: "in p: ENTER on selection of all contents",
- content: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->0",
- end: "p:contents()[0]->11",
- key: 'ENTER',
- }],
- test: {
- content: "<p><br></p><p><br></p>",
- start: "p:eq(1) br->0",
- },
- },
- {
- name: "in p: ENTER -> 'a' on selection of all contents",
- content: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->0",
- end: "p:contents()[0]->11",
- key: 'ENTER',
- }, {
- key: 'a',
- }],
- test: {
- content: "<p><br></p><p>a</p>",
- start: "p:eq(1):contents()[0]->1",
- },
- },
- {
- name: "in p: SHIFT+ENTER on selection of all contents",
- content: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->0",
- end: "p:contents()[0]->11",
- key: 'ENTER',
- shiftKey: true,
- }],
- test: {
- content: "<p><br><br></p>",
- start: "br:eq(1)->0",
- },
- },
- {
- name: "in p: SHIFT+ENTER -> 'a' on selection of all contents",
- content: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->0",
- end: "p:contents()[0]->11",
- key: 'ENTER',
- shiftKey: true,
- }, {
- key: 'a',
- }],
- test: {
- content: "<p><br>a</p>",
- start: "p:contents()[1]->1",
- },
- },
- {
- name: "in p: 2x ENTER -> 'a' on selection of all contents",
- content: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->3",
- key: 'ENTER',
- }, {
- key: 'ENTER',
- }, {
- key: 'a',
- }],
- test: {
- content: "<p>dom</p><p><br></p><p>a to edit</p>",
- start: "p:eq(2):contents()[0]->1",
- },
- },
- {
- name: "in p > b: ENTER at start",
- content: "<p><b>dom to edit</b></p>",
- steps: [{
- start: "b:contents()[0]->0",
- key: 'ENTER',
- }],
- test: {
- content: "<p><b><br></b></p><p><b>dom to edit</b></p>",
- start: "b:eq(1):contents()[0]->0",
- },
- },
- {
- name: "in p > b: ENTER",
- content: "<p><b>dom to edit</b></p>",
- steps: [{
- start: "b:contents()[0]->3",
- key: 'ENTER',
- }],
- test: {
- content: "<p><b>dom</b></p><p><b>&nbsp;to edit</b></p>",
- start: "b:eq(1):contents()[0]->0",
- },
- },
- {
- name: "in p > b: SHIFT+ENTER -> ENTER",
- content: "<p><b>dom to edit</b></p>",
- steps: [{
- start: "b:contents()[0]->3",
- key: 'ENTER',
- shiftKey: true,
- }, {
- key: 'ENTER',
- }],
- test: {
- content: "<p><b>dom<br>&#8203;</b></p><p><b>&nbsp;to edit</b></p>",
- start: "b:eq(1):contents()[0]->0",
- },
- },
- {
- name: "in p > b: ENTER -> a'",
- content: "<p><b>dom to edit</b></p>",
- steps: [{
- start: "b:contents()[0]->3",
- key: 'ENTER',
- }, {
- key: 'a',
- }],
- test: {
- content: "<p><b>dom</b></p><p><b>a to edit</b></p>",
- start: "b:eq(1):contents()[0]->1",
- },
- },
- {
- name: "in p > b: SHIFT+ENTER",
- content: "<p><b>dom to edit</b></p>",
- steps: [{
- start: "b:contents()[0]->3",
- key: 'ENTER',
- shiftKey: true,
- }],
- test: {
- content: "<p><b>dom<br>&nbsp;to edit</b></p>",
- start: "b:contents()[2]->0",
- },
- },
- {
- name: "in p > b: SHIFT+ENTER -> 'a'",
- content: "<p><b>dom to edit</b></p>",
- steps: [{
- start: "b:contents()[0]->3",
- key: 'ENTER',
- shiftKey: true,
- }, {
- key: 'a',
- }],
- test: {
- content: "<p><b>dom<br>a to edit</b></p>",
- start: "b:contents()[2]->1",
- },
- },
- {
- name: "in p > b: SHIFT+ENTER -> ENTER -> 'a'",
- content: "<p><b>dom to edit</b></p>",
- steps: [{
- start: "b:contents()[0]->3",
- key: 'ENTER',
- shiftKey: true,
- }, {
- key: 'ENTER',
- }, {
- key: 'a',
- }],
- test: {
- content: "<p><b>dom<br>&#8203;</b></p><p><b>a to edit</b></p>",
- start: "b:eq(1):contents()[0]->1",
- },
- },
- {
- name: "in span > b: ENTER",
- content: "<span><b>dom to edit</b></span>",
- steps: [{
- start: "b:contents()[0]->3",
- key: 'ENTER',
- }],
- test: {
- content: "<span><b>dom</b></span><br><span><b>&#8203;&nbsp;to edit</b></span>",
- start: "b:eq(1):contents()[0]->1",
- },
- },
- {
- name: "in span > b: SHIFT+ENTER -> ENTER",
- content: "<span><b>dom to edit</b></span>",
- steps: [{
- start: "b:contents()[0]->3",
- key: 'ENTER',
- shiftKey: true,
- }, {
- key: 'ENTER',
- }],
- test: {
- content: "<span><b>dom<br></b></span><br><span><b>&#8203;&nbsp;to edit</b></span>",
- start: "b:eq(1):contents()[0]->1",
- },
- },
- {
- name: "in span > b: ENTER -> a'",
- content: "<span><b>dom to edit</b></span>",
- steps: [{
- start: "b:contents()[0]->3",
- key: 'ENTER',
- }, {
- key: 'a',
- }],
- test: {
- content: "<span><b>dom</b></span><br><span><b>a to edit</b></span>",
- start: "b:eq(1):contents()[0]->1",
- },
- },
- {
- name: "in span > b: SHIFT+ENTER",
- content: "<span><b>dom to edit</b></span>",
- steps: [{
- start: "b:contents()[0]->3",
- key: 'ENTER',
- shiftKey: true,
- }],
- test: {
- content: "<span><b>dom<br>&nbsp;to edit</b></span>",
- start: "b:contents()[2]->0",
- },
- },
- {
- name: "in span > b: SHIFT+ENTER -> 'a'",
- content: "<span><b>dom to edit</b></span>",
- steps: [{
- start: "b:contents()[0]->3",
- key: 'ENTER',
- shiftKey: true,
- }, {
- key: 'a',
- }],
- test: {
- content: "<span><b>dom<br>a to edit</b></span>",
- start: "b:contents()[2]->1",
- },
- },
- {
- name: "in span > b: SHIFT+ENTER -> ENTER -> 'a'",
- content: "<span><b>dom to edit</b></span>",
- steps: [{
- start: "b:contents()[0]->3",
- key: 'ENTER',
- shiftKey: true,
- }, {
- key: 'ENTER',
- }, {
- key: 'a',
- }],
- test: {
- content: "<span><b>dom<br></b></span><br><span><b>a to edit</b></span>",
- start: "b:eq(1):contents()[0]->1",
- },
- },
- {
- name: "in p: 2x SHIFT+ENTER -> 'a'",
- content: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->3",
- key: 'ENTER',
- shiftKey: true,
- }, {
- key: 'ENTER',
- shiftKey: true,
- }, {
- key: 'a',
- }],
- test: {
- content: "<p>dom<br><br>a to edit</p>",
- start: "p:contents()[3]->1",
- },
- },
- {
- name: "in p: ENTER -> SHIFT+ENTER -> 'a'",
- content: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->3",
- key: 'ENTER',
- }, {
- key: 'ENTER',
- shiftKey: true,
- }, {
- key: 'a',
- }],
- test: {
- content: "<p>dom</p><p><br>a to edit</p>",
- start: "p:eq(1):contents()[1]->1",
- },
- },
- {
- name: "in empty-p (p before and after): ENTER -> 'a'",
- content: "<p>dom </p><p><br></p><p>to edit</p>",
- steps: [{
- start: "p:eq(1):contents()[0]->0",
- key: 'ENTER',
- }, {
- key: 'a',
- }],
- test: {
- content: "<p>dom </p><p><br></p><p>a</p><p>to edit</p>",
- start: "p:eq(2):contents()[0]->1",
- },
- },
- {
- name: "in p: SHIFT+ENTER at end",
- content: "<p>dom </p><p>to edit</p>",
- steps: [{
- start: "p:first:contents()[0]->4",
- key: 'ENTER',
- shiftKey: true,
- }],
- test: {
- content: "<p>dom <br>&#8203;</p><p>to edit</p>",
- start: "p:first:contents()[2]->0",
- },
- },
- {
- name: "in p: SHIFT+ENTER at end -> '寺'",
- content: "<p>dom </p><p>to edit</p>",
- steps: [{
- start: "p:first:contents()[0]->4",
- key: 'ENTER',
- shiftKey: true,
- }, {
- keyCode: 23546, /*temple in chinese*/
- }],
- test: {
- content: "<p>dom <br>寺</p><p>to edit</p>",
- start: "p:first:contents()[2]->1",
- },
- },
- {
- name: "in empty-p (div > a after): 3x SHIFT+ENTER -> 'a'",
- content: "<p><br></p><div><a href='#'>dom to edit</a></div>",
- steps: [{
- start: "p->1",
- key: 'ENTER',
- shiftKey: true,
- },
- {
- key: 'ENTER',
- shiftKey: true,
- },
- {
- key: 'ENTER',
- shiftKey: true,
- },
- {
- key: 'a',
- }
- ],
- test: {
- content: "<p><br><br><br>a</p><div><a href=\"#\">dom to edit</a></div>",
- start: "p:contents()[3]->1",
- },
- },
-
- // Buttons
-
- {
- name: "in div > a.btn: ENTER -> 'a' at start (before invisible space)",
- content: "<div class=\"unbreakable\"><a class=\"btn\" href=\"#\">&#8203;dom to edit&#8203;</a></div>",
- steps: [{
- start: "a:contents()[0]->0",
- key: 'ENTER',
- }, {
- key: 'a',
- }],
- test: {
- content: "<div class=\"unbreakable\"><a class=\"btn\" href=\"#\">Label</a><a class=\"btn\" href=\"#\">&#8203;adom to edit&#8203;</a></div>",
- // 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: "<div class=\"unbreakable\"><a class=\"btn\" href=\"#\">&#8203;dom to edit&#8203;</a></div>",
- steps: [{
- start: "a:contents()[0]->1",
- key: 'ENTER',
- }, {
- key: 'a',
- }],
- test: {
- content: "<div class=\"unbreakable\"><a class=\"btn\" href=\"#\">Label</a><a class=\"btn\" href=\"#\">&#8203;adom to edit&#8203;</a></div>",
- // 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: "<div class=\"unbreakable\"><a class=\"btn\" href=\"#\">&#8203;dom to edit&#8203;</a></div>",
- steps: [{
- start: "a:contents()[0]->6",
- key: 'ENTER',
- }, {
- key: 'a',
- }],
- test: {
- content: "<div class=\"unbreakable\"><a class=\"btn\" href=\"#\">dom t</a><a class=\"btn\" href=\"#\">&#8203;ao edit&#8203;</a></div>",
- start: "a:eq(1):contents()[0]->2",
- },
- },
- {
- name: "in div > a.btn: ENTER -> 'a' at end (before invisible space)",
- content: "<div class=\"unbreakable\"><a class=\"btn\" href=\"#\">&#8203;dom to edit&#8203;</a></div>",
- steps: [{
- start: "a:contents()[0]->12",
- key: 'ENTER',
- }, {
- key: 'a',
- }],
- test: {
- content: "<div class=\"unbreakable\"><a class=\"btn\" href=\"#\">dom to edit</a><a class=\"btn\" href=\"#\">&#8203;a&#8203;</a></div>",
- start: "a:eq(1):contents()[0]->2",
- },
- },
- {
- name: "in div > a.btn: ENTER -> 'a' at end (after invisible space)",
- content: "<div class=\"unbreakable\"><a class=\"btn\" href=\"#\">&#8203;dom to edit&#8203;</a></div>",
- steps: [{
- start: "a:contents()[0]->13",
- key: 'ENTER',
- }, {
- key: 'a',
- }],
- test: {
- content: "<div class=\"unbreakable\"><a class=\"btn\" href=\"#\">dom to edit</a><a class=\"btn\" href=\"#\">&#8203;a&#8203;</a></div>",
- start: "a:eq(1):contents()[0]->2",
- },
- },
- {
- name: "in div > button.btn: ENTER -> 'a' at end (after invisible space)",
- content: "<div class=\"unbreakable\"><button class=\"btn\" href=\"#\">&#8203;dom to edit&#8203;</button></div>",
- steps: [{
- start: "button:contents()[0]->13",
- key: 'ENTER',
- }, {
- key: 'a',
- }],
- test: {
- content: "<div class=\"unbreakable\"><button class=\"btn\" href=\"#\">dom to edit</button><button class=\"btn\" href=\"#\">&#8203;a&#8203;</button></div>",
- start: "button:eq(1):contents()[0]->2",
- },
- },
- {
- name: "in div > a.btn: ENTER -> 'a' on partial selection",
- content: "<div class=\"unbreakable\"><a class=\"btn\" href=\"#\">&#8203;dom to edit&#8203;</a></div>",
- steps: [{
- start: "a:contents()[0]->4",
- end: "a:contents()[0]->8",
- key: 'ENTER',
- }, {
- key: 'a',
- }],
- test: {
- content: "<div class=\"unbreakable\"><a class=\"btn\" href=\"#\">dom</a><a class=\"btn\" href=\"#\">&#8203;aedit&#8203;</a></div>",
- start: "a:eq(1):contents()[0]->2",
- },
- },
- {
- name: "in div > a.btn: ENTER -> 'a' on selection of all visible text",
- content: "<div class=\"unbreakable\"><a class=\"btn\" href=\"#\">dom to edit</a></div>",
- steps: [{
- start: "a:contents()[0]->0",
- end: "a:contents()[0]->11",
- key: 'ENTER',
- }, {
- key: 'a',
- }],
- test: {
- content: "<div class=\"unbreakable\"><a class=\"btn\" href=\"#\">Label</a><a class=\"btn\" href=\"#\">&#8203;a&#8203;</a></div>",
- // 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: "<div class=\"unbreakable\"><a class=\"btn\" href=\"#\">dom not to edit</a><a class=\"btn\" href=\"#\">other dom not to edit</a></div>",
- steps: [{
- start: "a:contents()[0]->0",
- end: "a:eq(1):contents()[0]->11",
- key: 'ENTER',
- }],
- test: {
- content: "<div class=\"unbreakable\"><a class=\"btn\" href=\"#\">Label</a><a class=\"btn\" href=\"#\">&#8203;ot to edit&#8203;</a></div>",
- 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: "<span><b>dom to edit</b></span>",
- steps: [{
- start: "b:contents()[0]->3",
- key: 'ENTER',
- shiftKey: true,
- }, {
- key: 'BACKSPACE',
- }, {
- key: 'a',
- }],
- test: {
- content: "<span><b>doma to edit</b></span>",
- start: "b:contents()[0]->4",
- },
- },
- {
- name: "in span > b: SHIFT+ENTER -> ENTER -> BACKSPACE",
- content: "<span><b>dom to edit</b></span>",
- steps: [{
- start: "b:contents()[0]->3",
- key: 'ENTER',
- shiftKey: true,
- }, {
- key: 'ENTER',
- }, {
- key: 'BACKSPACE',
- }],
- test: {
- content: "<span><b>dom<br>&nbsp;to edit</b></span>",
- start: "b:contents(2)->0",
- },
- },
- {
- name: "in span > b: SHIFT+ENTER -> ENTER -> BACKSPACE -> 'a'",
- content: "<span><b>dom to edit</b></span>",
- steps: [{
- start: "b:contents()[0]->3",
- key: 'ENTER',
- shiftKey: true,
- }, {
- key: 'ENTER',
- }, {
- key: 'BACKSPACE',
- }, {
- key: 'a',
- }],
- test: {
- content: "<span><b>dom<br>a to edit</b></span>",
- start: "b:contents()[2]->1",
- },
- },
- {
- name: "in p > b: 2x SHIFT+ENTER -> BACKSPACE",
- content: "<p><b>dom to edit</b></p>",
- steps: [{
- start: "b:contents()[0]->3",
- key: 'ENTER',
- shiftKey: true,
- }, {
- key: 'ENTER',
- shiftKey: true,
- }, {
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p><b>dom<br>&nbsp;to edit</b></p>",
- start: "b:contents()[2]->0",
- },
- },
- {
- name: "in p > b: 2x ENTER -> 2x BACKSPACE",
- content: "<p><b>dom to edit</b></p>",
- steps: [{
- start: "b:contents()[0]->3",
- key: 'ENTER',
- shiftKey: false
- }, {
- key: 'ENTER',
- shiftKey: false
- }, {
- key: 'BACKSPACE',
- }, {
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p><b>dom&nbsp;to edit</b></p>",
- start: "b:contents()[0]->3",
- },
- },
- {
- name: "in empty-p: 2x ENTER -> 2x BACKSPACE",
- content: "<p><br></p>",
- steps: [{
- start: "p->1",
- key: 'ENTER',
- shiftKey: false
- }, {
- key: 'ENTER',
- shiftKey: false
- }, {
- key: 'BACKSPACE',
- }, {
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p><br></p>",
- start: "p:contents()[0]->0",
- },
- },
- {
- name: "in empty-p (p before): ENTER -> 2x BACKSPACE",
- content: "<p>dom not to edit</p><p><br></p>",
- steps: [{
- start: "p:eq(1)->1",
- key: 'ENTER',
- shiftKey: false
- }, {
- key: 'BACKSPACE',
- }, {
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p>dom not to edit</p>",
- start: "p:first:contents()[0]->15",
- },
- },
- {
- name: "in p > b: 2x SHIFT+ENTER -> BACKSPACE -> 'a'",
- content: "<p><b>dom to edit</b></p>",
- steps: [{
- start: "b:contents()[0]->3",
- key: 'ENTER',
- shiftKey: true,
- }, {
- key: 'ENTER',
- shiftKey: true,
- }, {
- key: 'BACKSPACE',
- }, {
- key: 'a',
- }],
- test: {
- content: "<p><b>dom<br>a to edit</b></p>",
- start: "b:contents()[2]->1",
- },
- },
- {
- name: "in li -> ENTER before br -> 'a'",
- content: "<ul><li><p>dom<br/>&nbsp;to edit</p></li></ul>",
- steps: [{
- start: "p:contents()[0]->3",
- key: 'ENTER',
- }, {
- key: 'a',
- }],
- test: {
- content: "<ul><li><p>dom</p></li><li><p>a<br>&nbsp;to edit</p></li></ul>",
- start: "p:eq(1):contents()[0]->1",
- },
- },
- {
- name: "in li -> ENTER after br -> 'a'",
- content: "<ul><li><p>dom<br/>&nbsp;to edit</p></li></ul>",
- steps: [{
- start: "p:contents()[2]->0",
- key: 'ENTER',
- }, {
- key: 'a',
- }],
- test: {
- content: "<ul><li><p>dom<br>&#8203;</p></li><li><p>a to edit</p></li></ul>",
- start: "p:eq(1):contents()[0]->1",
- },
- },
- {
- name: "within p (p before and after): 3x SHIFT+ENTER -> 3x BACKSPACE",
- content: "<p>dom not to edit</p><p>dom to edit</p><p>dom not to edit</p>",
- 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: "<p>dom not to edit</p><p>dom to edit</p><p>dom not to edit</p>",
- start: "p:eq(1):contents()[0]->5",
- },
- },
- {
- name: "in h1.a > font: 'a' on selection of all contents",
- content: "<h1 class=\"a\"><font style=\"font-size: 62px;\">dom to edit</font></h1>",
- steps: [{
- start: "h1->0",
- end: "h1->1",
- key: 'a',
- }],
- test: {
- content: "<h1 class=\"a\"><font style=\"font-size: 62px;\">a</font></h1>",
- start: "font:contents()[0]->1",
- },
- },
- {
- name: "in complex-dom: BACKSPACE on partial selection (requires merging non-similar blocks)",
- content: "<p class=\"a\">pif</p><p><span><b>paf</b></span></p><ul><li><p>p<i>ouf</i></p></li></ul>",
- steps: [{
- start: 'p:contents()[0]->2',
- end: 'i:contents()[0]->2',
- key: 'BACKSPACE',
- }],
- test: {
- content: '<p class=\"a\">pi<i>f</i></p>',
- start: "p:contents()[0]->2",
- },
- },
- {
- name: "in complex-dom: DELETE on partial selection (requires merging non-similar blocks)",
- content: "<p class=\"a\">pif</p><p><span><b>paf</b></span></p><ul><li><p>p<i>ouf</i></p></li></ul>",
- steps: [{
- start: 'p:contents()[0]->2',
- end: 'i:contents()[0]->2',
- key: 'DELETE',
- }],
- test: {
- content: '<p class=\"a\">pi<i>f</i></p>',
- start: "p:contents()[0]->2",
- },
- },
-
- // paragraph outdent
-
- {
- name: "in p (h1 before): TAB -> BACKSPACE at start (must indent then outdent)",
- content: "<h1>dom not to edit</h1><p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->0",
- key: 'TAB',
- }, {
- key: 'BACKSPACE',
- }],
- test: {
- content: "<h1>dom not to edit</h1><p>dom to edit</p>",
- start: "p:contents()[0]->0",
- },
- },
- {
- name: "in p (h1 before): TAB -> 2x BACKSPACE at start (must indent then outdent, then merge blocks)",
- content: "<h1>dom not to edit</h1><p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->0",
- key: 'TAB',
- }, {
- key: 'BACKSPACE',
- }, {
- key: 'BACKSPACE',
- }],
- test: {
- content: "<h1>dom not to editdom to edit</h1>",
- start: "h1:contents()[0]->15",
- },
- },
- {
- name: "in ul > li > ul > 1st li > empty p (other ul li ul before): BACKSPACE at start",
- content: '<ul><li><p>1</p></li><li class="o_indent"><ul><li><p>2</p></li></ul><ul class="o_checklist"><li id="checklist-id-1"><p><br></p></li></ul></li><li><p>3</p></li></ul>',
- steps: [{
- start: "p:eq(2)->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: '<ul><li><p>1</p></li><li class="o_indent"><ul><li><p>2</p></li></ul></li><li><p>3</p></li></ul>',
- start: "p:eq(1):contents()[0]->1",
- },
- },
- {
- name: "in ul > li > p > text (li > text before): BACKSPACE at start",
- content: '<ul><li>1</li><li>2</li><li><p><br></p></li><li>3</li></ul>',
- steps: [{
- start: "p:contents()[0]->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: '<ul><li>1</li><li><p>2</p></li><li>3</li></ul>',
- start: "p:contents()[0]->1",
- },
- },
- {
- name: "in ul > li > p > text (li > text before): 3x BACKSPACE after first character",
- content: '<ul><li>1</li><li>2</li><li><p>34</p></li><li>5</li></ul>',
- steps: [{
- start: "p:contents()[0]->1",
- key: 'BACKSPACE',
- }, {
- key: 'BACKSPACE',
- }, {
- key: 'BACKSPACE',
- }],
- test: {
- content: '<ul><li>1</li><li><p>4</p></li><li>5</li></ul>',
- start: "p:contents()[0]->0",
- },
- },
- {
- name: "in ul > li > text (li > p > text before): BACKSPACE at start",
- content: '<ul><li>1</li><li><p>2</p></li><li>3</li><li>4</li></ul>',
- steps: [{
- start: "li:eq(2):contents()[0]->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: '<ul><li>1</li><li><p>23</p></li><li>4</li></ul>',
- start: "p:contents()[0]->1",
- },
- },
- {
- name: "in ul > li > text (li > p > text before): 3x BACKSPACE after first character",
- content: '<ul><li>1</li><li><p>2</p></li><li>34</li><li>5</li></ul>',
- steps: [{
- start: "li:eq(2):contents()[0]->1",
- key: 'BACKSPACE',
- }, {
- key: 'BACKSPACE',
- }, {
- key: 'BACKSPACE',
- }],
- test: {
- content: '<ul><li>1</li><li><p>4</p></li><li>5</li></ul>',
- start: "p:contents()[0]->0",
- },
- },
- {
- name: "in ul > li > p > text (li > text after): DELETE at end",
- content: '<ul><li>1</li><li><p><br></p></li><li>2</li><li>3</li></ul>',
- steps: [{
- start: "p->0",
- key: 'DELETE',
- }],
- test: {
- content: '<ul><li>1</li><li><p>2</p></li><li>3</li></ul>',
- start: "p:contents()[0]->0",
- },
- },
- {
- name: "in ul > li > p > text (li > text after): 3x DELETE before last character",
- content: '<ul><li>1</li><li><p>23</p></li><li>4</li><li>5</li></ul>',
- steps: [{
- start: "p:contents()[0]->1",
- key: 'DELETE',
- }, {
- key: 'DELETE',
- }, {
- key: 'DELETE',
- }],
- test: {
- content: '<ul><li>1</li><li><p>2</p></li><li>5</li></ul>',
- start: "p:contents()[0]->1",
- },
- },
- {
- name: "in ul > li > text (li > p > text after): DELETE at end",
- content: '<ul><li>1</li><li>2</li><li><p>3</p></li><li>4</li></ul>',
- steps: [{
- start: "li:eq(1):contents()[0]->1",
- key: 'DELETE',
- }],
- test: {
- content: '<ul><li>1</li><li><p>23</p></li><li>4</li></ul>',
- start: "p:contents()[0]->1",
- },
- },
- {
- name: "in ul > li > text (li > p > text after): 3x DELETE before last character",
- content: '<ul><li>1</li><li>23</li><li><p>4</p></li><li>5</li></ul>',
- steps: [{
- start: "li:eq(1):contents()[0]->1",
- key: 'DELETE',
- }, {
- key: 'DELETE',
- }, {
- key: 'DELETE',
- }],
- test: {
- content: '<ul><li>1</li><li><p>2</p></li><li>5</li></ul>',
- start: "p:contents()[0]->1",
- },
- },
- {
- name: "in ul.list-group (div > p > text before): BACKSPACE at start",
- content: '<div><p>1</p></div><ul class="list-group list-group-flush"><li class="list-group-item"><p><br></p></li></ul>',
- steps: [{
- start: "p:eq(1)->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: '<div><p>1</p></div><ul class="list-group list-group-flush"><li class="list-group-item"><p><br></p></li></ul>',
- start: "p:eq(1)->0",
- },
- },
- // List indent
- {
- name: "ENTER -> TAB -> a' at end of li > p (split -> indent -> write)",
- content: '<ul><li><p>a</p></li></ul>',
- steps: [{
- start: "p:contents()[0]->1",
- key: 'ENTER',
- },
- {
- key: 'TAB',
- },
- {
- key: 'a',
- }],
- test: {
- content: '<ul><li><p>a</p></li><li class="o_indent"><ul><li><p>a</p></li></ul></li></ul>',
- 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: "<ul><li>dom to edit</li></ul>",
- steps: [{
- start: "li:contents()[0]->0",
- key: 'TAB',
- }],
- test: {
- content: "<ul><li class=\"o_indent\"><ul><li>dom to edit</li></ul></li></ul>",
- start: "ul ul li:contents()[0]->0",
- },
- },
- {
- name: "in indented-li: SHIFT+TAB at start",
- content: "<ul><ul><li>dom to edit</li></ul></ul>",
- steps: [{
- start: "li:contents()[0]->0",
- key: 'TAB',
- shiftKey: true,
- }],
- test: {
- content: "<ul><li>dom to edit</li></ul>",
- start: "li:contents()[0]->0",
- },
- },
- {
- name: "in li: TAB within contents",
- content: "<ul><li>dom to edit</li></ul>",
- steps: [{
- start: "li:contents()[0]->5",
- key: 'TAB',
- }],
- test: {
- content: "<ul><li>dom t&nbsp;&nbsp;&nbsp;&nbsp;o edit</li></ul>",
- start: "li:contents()[0]->9",
- },
- },
- {
- name: "in li: SHIFT+TAB within contents (should do nothing)",
- content: "<ul><li>dom to edit</li></ul>",
- steps: [{
- start: "li:contents()[0]->5",
- key: 'TAB',
- shiftKey: true,
- }],
- test: {
- content: "<ul><li>dom to edit</li></ul>",
- start: "li:contents()[0]->5",
- },
- },
- {
- name: "in td > p: TAB within contents",
- content: "<table><tbody><tr><td><p>dom to edit</p></td><td><p>node</p></td></tr></tbody></table>",
- steps: [{
- start: "p:contents()[0]->5",
- key: 'TAB',
- }],
- test: {
- content: "<table><tbody><tr><td><p>dom to edit</p></td><td><p>node</p></td></tr></tbody></table>",
- start: "td:eq(1) p:contents(0)->0",
- },
- },
- {
- name: "in p: TAB at start",
- content: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->0",
- key: 'TAB',
- }],
- test: {
- content: "<p style=\"margin-left: 1.5em;\">dom to edit</p>",
- start: "p:contents()[0]->0",
- },
- },
- {
- name: "in indented-p: SHIFT+TAB at start",
- content: "<p style=\"margin-left: 1.5em;\">dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->0",
- key: 'TAB',
- shiftKey: true,
- }],
- test: {
- content: "<p>dom to edit</p>",
- start: "p:contents()[0]->0",
- },
- },
- {
- name: "in p: TAB -> BACKSPACE at start",
- content: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->0",
- key: 'TAB',
- }, {
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p>dom to edit</p>",
- start: "p:contents()[0]->0",
- },
- },
- {
- name: "in p > b: TAB at start",
- content: "<p>dom <b>to edit</b></p>",
- steps: [{
- start: "b:contents()[0]->0",
- key: 'TAB',
- }],
- test: {
- content: "<p>dom <b>&nbsp;&nbsp;&nbsp;&nbsp;to edit</b></p>",
- start: "b:contents()[0]->4",
- },
- },
- {
- name: "in p > b: TAB -> BACKSPACE at start",
- content: "<p>dom <b>to edit</b></p>",
- steps: [{
- start: "b:contents()[0]->0",
- key: 'TAB',
- }, {
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p>dom <b>&nbsp;&nbsp;&nbsp;to edit</b></p>",
- 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: '<p>aaa<span class="fa fa-star"></span>bbb</p>',
- steps: [{
- start: "p:contents()[2]->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: '<p>aaabbb</p>',
- start: "p:contents()[0]->3",
- },
- },
- {
- name: "in empty-p (no br): BACKSPACE (must insert br)",
- content: "<p></p>",
- steps: [{
- start: "p->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p><br></p>", // 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: "<p><br></p>",
- steps: [{
- start: "p->1",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p><br></p>", // The br is there to ensure the carret can enter the p tag
- start: "br->0",
- },
- },
- {
- name: "in p (empty-p before): BACKSPACE",
- content: "<p><br></p><p>dom to edit</p>",
- steps: [{
- start: "p:eq(1):contents()[0]->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p>dom to edit</p>",
- start: "p:contents()[0]->0",
- },
- },
- {
- name: "in p (empty-p.a before): BACKSPACE",
- content: "<p class=\"a\"><br></p><p>dom to edit</p>",
- steps: [{
- start: "p:eq(1):contents()[0]->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p>dom to edit</p>",
- start: "p:contents()[0]->0",
- },
- },
- {
- name: "in p: BACKSPACE within text",
- content: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->5",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p>dom o edit</p>", // 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: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->5",
- key: 'BACKSPACE',
- }, {
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p>domo edit</p>", // 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: "<p><span class=\"a\">dom to</span></p><p><span class=\"b\">edit</span></p>",
- steps: [{
- start: "p:eq(1):contents()[0]->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p><span class=\"a\">dom to</span><span class=\"b\">edit</span></p>",
- start: "span:eq(0):contents()[0]->6",
- },
- },
- {
- name: "in p (p > span.a before - span.a after): BACKSPACE (must merge them)",
- content: "<p><span class=\"a\">dom to&nbsp;</span></p><p><span class=\"a\">edit</span></p>",
- steps: [{
- start: "p:eq(1):contents()[0]->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p><span class=\"a\">dom to&nbsp;edit</span></p>",
- start: "span:contents()[0]->7",
- },
- },
- {
- name: "in p (b before): BACKSPACE",
- content: "<p><b>dom</b> to edit</p>",
- steps: [{
- start: "p:contents()[1]->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p><b>do</b>&nbsp;to edit</p>",
- start: "b:contents()[0]->2",
- },
- },
- {
- name: "in p (div > span.a before - span.a after): BACKSPACE at beginning (must do nothing)",
- content: "<div><span class=\"a\">dom to&nbsp;</span></div><p><span class=\"a\">edit</span></p>",
- steps: [{
- start: "p:contents()[0]->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<div><span class=\"a\">dom to&nbsp;</span></div><p><span class=\"a\">edit</span></p>",
- start: "span:eq(1):contents()[0]->0",
- },
- },
- {
- name: "in p: BACKSPACE on partial selection",
- content: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->1",
- end: "p:contents()[0]->7",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p>dedit</p>",
- start: "p:contents()[0]->1",
- },
- },
- {
- name: "across 2 p's: BACKSPACE on partial selection",
- content: "<p>dom</p><p>to edit</p>",
- steps: [{
- start: "p:contents()[0]->1",
- end: "p:eq(1):contents()[0]->3",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p>dedit</p>",
- start: "p:contents()[0]->1",
- },
- },
- {
- name: "in p: BACKSPACE within text, with space at beginning",
- content: "<p> dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->10",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p>dom o edit</p>",
- start: "p:contents()[0]->4",
- },
- },
- {
- name: "in p: BACKSPACE within text, with one space at beginning",
- content: "<p> dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->6",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p>&nbsp;dom o edit</p>",
- start: "p:contents()[0]->5",
- },
- },
- {
- name: "in p: BACKSPACE within text, with space at end",
- content: "<p>dom to edit </p>",
- steps: [{
- start: "p:contents()[0]->5",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p>dom o edit</p>",
- start: "p:contents()[0]->4",
- },
- },
- {
- name: "in p: BACKSPACE within text, with one space at end",
- content: "<p>dom to edit </p>",
- steps: [{
- start: "p:contents()[0]->5",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p>dom o edit&nbsp;</p>",
- start: "p:contents()[0]->4",
- },
- },
- {
- name: "in p: BACKSPACE within text, with space at beginning and end",
- content: "<p> dom to edit </p>",
- steps: [{
- start: "p:contents()[0]->10",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p>dom o edit</p>",
- start: "p:contents()[0]->4",
- },
- },
- {
- name: "in p: BACKSPACE within text, with one space at beginning and one at end",
- content: "<p> dom to edit </p>",
- steps: [{
- start: "p:contents()[0]->6",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p>&nbsp;dom o edit&nbsp;</p>",
- start: "p:contents()[0]->5",
- },
- },
- {
- name: "in p: BACKSPACE after \\w<br>\\w",
- content: "<p>dom to edi<br>t</p>",
- steps: [{
- start: "p:contents()[2]->1",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p>dom to edi<br>&#8203;</p>",
- start: "p:contents()[2]->1",
- },
- },
- {
- name: "in p: BACKSPACE -> 'a' within text, after \\s\\w",
- content: "<p>dom t</p>",
- steps: [{
- start: "p:contents()[0]->5",
- key: 'BACKSPACE',
- }, {
- key: 'a',
- }],
- test: {
- content: "<p>dom a</p>",
- start: "p:contents()[0]->5",
- },
- },
- {
- name: "in pre: BACKSPACE within text, with space at beginning",
- content: "<pre> dom to edit</pre>",
- steps: [{
- start: "pre:contents()[0]->10",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<pre> dom o edit</pre>",
- start: "pre:contents()[0]->9",
- },
- },
- {
- name: "in pre: BACKSPACE within text, with one space at beginning",
- content: "<pre> dom to edit</pre>",
- steps: [{
- start: "pre:contents()[0]->6",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<pre> dom o edit</pre>",
- start: "pre:contents()[0]->5",
- },
- },
- {
- name: "in pre: BACKSPACE within text, with space at end",
- content: "<pre>dom to edit </pre>",
- steps: [{
- start: "pre:contents()[0]->5",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<pre>dom o edit </pre>",
- start: "pre:contents()[0]->4",
- },
- },
- {
- name: "in pre: BACKSPACE within text, with one space at end",
- content: "<pre>dom to edit </pre>",
- steps: [{
- start: "pre:contents()[0]->5",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<pre>dom o edit </pre>",
- start: "pre:contents()[0]->4",
- },
- },
- {
- name: "in pre: BACKSPACE within text, with space at beginning and end",
- content: "<pre> dom to edit </pre>",
- steps: [{
- start: "pre:contents()[0]->10",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<pre> dom o edit </pre>",
- start: "pre:contents()[0]->9",
- },
- },
- {
- name: "in pre: BACKSPACE within text, with one space at beginning and one at end",
- content: "<pre> dom to edit </pre>",
- steps: [{
- start: "pre:contents()[0]->6",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<pre> dom o edit </pre>",
- start: "pre:contents()[0]->5",
- },
- },
-
- // list UL / OL
-
- {
- name: "from p to ul > li: BACKSPACE on whole list",
- content: "<p>dom not to edit</p><ul><li><p>dom to edit</p></li></ul>",
- steps: [{
- start: "p:contents()[0]->15",
- end: "p:eq(1):contents()[0)->11",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p>dom not to edit</p>",
- start: "p:contents()[0]->15",
- },
- },
- {
- name: "in ul > second-li > p: BACKSPACE within text",
- content: "<ul><li><p>dom to</p></li><li><p>edit</p></li></ul>",
- steps: [{
- start: "p:eq(1):contents()[0]->4",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<ul><li><p>dom to</p></li><li><p>edi</p></li></ul>",
- start: "p:eq(1):contents()[0]->3",
- },
- },
- {
- name: "in ul > second-li > empty-p: BACKSPACE at beginning",
- content: "<ul><li><p><br></p></li><li><p><br></p></li></ul>",
- steps: [{
- start: "p:eq(1)->1",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<ul><li><p><br></p></li></ul>",
- start: "p:first:contents()[0]->0",
- },
- },
- {
- name: "in ul > indented-li (no other li - p before): BACKSPACE at beginning",
- content: "<p>dom to</p><ul><ul><li>edit</li></ul></ul>",
- steps: [{
- start: "li:contents()[0]->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p>dom to</p><ul><li>edit</li></ul>",
- start: "li:contents()[0]->0",
- },
- },
- {
- name: "in ul > indented-li (no other li - p before): BACKSPACE -> 'a' at beginning",
- content: "<p>dom to</p><ul><ul><li>edit</li></ul></ul>",
- steps: [{
- start: "li:contents()[0]->0",
- key: 'BACKSPACE',
- }, {
- key: 'a',
- }],
- test: {
- content: "<p>dom to</p><ul><li>aedit</li></ul>",
- start: "li:contents()[0]->1",
- },
- },
- {
- name: "in ul > indented-li (no other li - none before): BACKSPACE at beginning",
- content: "<ul><ul><li>dom to edit</li></ul></ul>",
- steps: [{
- start: "li:contents()[0]->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<ul><li>dom to edit</li></ul>",
- start: "li:contents()[0]->0",
- },
- },
- {
- name: "in li: BACKSPACE on partial selection",
- content: "<ul><li>dom to edit</li></ul>",
- steps: [{
- start: "li:contents()[0]->1",
- end: "li:contents()[0]->7",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<ul><li>dedit</li></ul>",
- start: "li:contents()[0]->1",
- },
- },
- {
- name: "across 2 li: BACKSPACE on partial selection",
- content: "<ul><li>dom to edit</li><li>dom to edit</li></ul>",
- steps: [{
- start: "li:contents()[0]->1",
- end: "li:eq(1):contents()[0]->7",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<ul><li>dedit</li></ul>",
- start: "li:contents()[0]->1",
- },
- },
- {
- name: "in li (no other li): BACKSPACE on selection of all contents",
- content: "<ul><li>dom to edit</li></ul>",
- steps: [{
- start: "li:contents()[0]->0",
- end: "li:contents()[0]->11",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<ul><li><br></li></ul>",
- start: "li->0",
- },
- },
- {
- name: "in li (no other li): BACKSPACE -> 'a' on selection of all contents",
- content: "<ul><li>dom to edit</li></ul>",
- steps: [{
- start: "li:contents()[0]->0",
- end: "li:contents()[0]->11",
- key: 'BACKSPACE',
- }, {
- key: 'a',
- }],
- test: {
- content: "<ul><li><p>a</p></li></ul>",
- start: "p:contents()[0]->1",
- },
- },
- {
- name: "in empty-li: BACKSPACE (must remove list)",
- content: "<ul><li><br></li></ul>",
- steps: [{
- start: "li:contents()[0]->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p><br></p>",
- start: "br->0",
- },
- },
- {
- name: "in empty-li (no other li - empty-p before): BACKSPACE -> 'a'",
- content: "<p><br></p><ul><li><br></li></ul>",
- steps: [{
- start: "li:contents()[0]->0",
- key: 'BACKSPACE',
- }, {
- key: 'a',
- }],
- test: {
- content: "<p><br></p><p>a</p>",
- start: "p:eq(1):contents()[0]->1",
- },
- },
- {
- name: "in empty-li (no other li - p before): BACKSPACE",
- content: "<p>toto</p><ul><li><br></li></ul>",
- steps: [{
- start: "li:contents()[0]->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p>toto</p><p><br></p>",
- start: "br->0",
- },
- },
- {
- name: "in li (no other li - p before): BACKSPACE at start",
- content: "<p>toto</p><ul><li>&nbsp;<img src='/web_editor/static/src/img/transparent.png'></li></ul>",
- steps: [{
- start: "li:contents()[0]->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p>toto</p><p>&nbsp;<img data-src=\"/web_editor/static/src/img/transparent.png\"></p>",
- start: "p:eq(1):contents()[0]->0",
- },
- },
- {
- name: "in empty-indented-li (other li - no other indented-li): BACKSPACE",
- content: "<ul><li><p>toto</p></li><ul><li><br></li></ul><li><p>tutu</p></li></ul>",
- steps: [{
- start: "ul ul li:contents()[0]->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<ul><li><p>toto</p></li><li><br></li><li><p>tutu</p></li></ul>",
- start: "li:eq(1) br->0",
- },
- },
- {
- name: "in empty-indented-li (other li - other indented-li): BACKSPACE",
- content: "<ul><li><p>toto</p></li><ul><li><br></li><li><br></li></ul><li><p>tutu</p></li></ul>",
- steps: [{
- start: "ul ul li:contents()[0]->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<ul><li><p>toto</p></li><li><br></li><ul><li><br></li></ul><li><p>tutu</p></li></ul>",
- start: "li:eq(1) br->0",
- },
- },
- {
- name: "in empty-indented-li (no other li, no other indented-li): BACKSPACE",
- content: "<ul><ul><li><br></li></ul></ul>",
- steps: [{
- start: "li:contents()[0]->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<ul><li><br></li></ul>",
- start: "br->0",
- },
- },
- {
- name: "in indented-li (other li, other indented-li): BACKSPACE at start",
- content: "<ul><li><p>toto</p></li><ul><li><p>xxx</p></li><li><p>yyy</p></li></ul><li><p>tutu</p></li></ul>",
- steps: [{
- start: "ul ul li:contents()[0]->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<ul><li><p>toto</p></li><li><p>xxx</p></li><ul><li><p>yyy</p></li></ul><li><p>tutu</p></li></ul>",
- start: "p:eq(1):contents()[0]->0",
- },
- },
- {
- name: "in li > second-p: BACKSPACE at start",
- content: "<ul><li><p>toto</p></li><li><p>xxx</p><p>yyy</p></li><li><p>tutu</p></li></ul>",
- steps: [{
- start: "li:eq(1) p:eq(1):contents()[0]->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<ul><li><p>toto</p></li><li><p>xxxyyy</p></li><li><p>tutu</p></li></ul>",
- start: "li:eq(1) p:contents()[0]->3",
- },
- },
- {
- name: "in li (li after): BACKSPACE at start, with spaces",
- content: "<p>dom to edit&nbsp; </p><ul><li><p> &nbsp; dom to edit</p></li><li><p>dom not to edit</p></li></ul>",
- steps: [{
- start: "p:eq(1):contents()[0]->6",
- key: 'BACKSPACE',
- }, {
- key: 'BACKSPACE',
- }, {
- key: 'BACKSPACE',
- }, {
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p>dom to edit&nbsp;dom to edit</p><ul><li><p>dom not to edit</p></li></ul>",
- start: "p:contents()[0]->12",
- },
- },
- {
- name: "in li > p: BACKSPACE after single character",
- content: "<ul><li><p>a</p></li></ul>",
- steps: [{
- start: "p:contents()[0]->1",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<ul><li><p><br></p></li></ul>",
- start: "br->0",
- },
- },
- {
- name: "in li > p: BACKSPACE -> 'a' after single character",
- content: "<ul><li><p>a</p></li></ul>",
- steps: [{
- start: "p:contents()[0]->1",
- key: 'BACKSPACE',
- }, {
- key: 'a',
- }],
- test: {
- content: "<ul><li><p>a</p></li></ul>",
- start: "p:contents()[0]->1",
- },
- },
-
- // end list UL / OL
-
- {
- name: "in p: BACKSPACE on selection of all contents",
- content: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->0",
- end: "p:contents()[0]->11",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p><br></p>",
- start: "p->0",
- },
- },
- {
- name: "in p: BACKSPACE -> 'a' on selection of all contents",
- content: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->0",
- end: "p:contents()[0]->11",
- key: 'BACKSPACE',
- }, {
- key: 'a',
- }],
- test: {
- content: "<p>a</p>",
- start: "p:contents()[0]->1",
- },
- },
- {
- name: "in complex-dom: BACKSPACE on selection of most contents",
- content: "<p><b>dom</b></p><p><b>to<br>partially</b>re<i>m</i>ove</p>",
- steps: [{
- start: "b:contents()[0]->2",
- end: "i:contents()[0]->1",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p><b>do</b>ove</p>",
- start: "b:contents()[0]->2",
- },
- },
- {
- name: "in complex-dom: BACKSPACE on selection of all contents",
- content: "<p><b>dom</b></p><p><b>to<br>completely</b>remov<i>e</i></p>",
- steps: [{
- start: "p:contents()[0]->0",
- end: "i:contents()[0]->1",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p><br></p>",
- start: "br->0",
- },
- },
- {
- name: "in p: BACKSPACE after br",
- content: "<p>dom <br>to edit</p>",
- steps: [{
- start: "p:contents()[2]->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p>dom to edit</p>",
- start: "p:contents()[0]->4",
- },
- },
- {
- name: "in complex-dom (span > b -> ENTER in contents)",
- content: "<span><b>dom<br></b></span><br><span><b>&nbsp;to edit</b></span>",
- steps: [{
- start: "b:eq(1):contents()[0]->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<span><b>dom<br>&nbsp;to edit</b></span>",
- start: "b:contents(2)->0",
- },
- },
- {
- name: "in complex-dom (span > b -> ENTER in contents): 2 x BACKSPACE",
- content: "<span><b>dom<br></b></span><br><span><b>a to edit</b></span>",
- steps: [{
- start: "b:eq(1):contents()[0]->1",
- key: 'BACKSPACE',
- }, {
- key: 'BACKSPACE',
- }],
- test: {
- content: "<span><b>dom<br>&nbsp;to edit</b></span>",
- start: "b:contents(2)->0",
- },
- },
- {
- name: "in p (hr before): BACKSPACE",
- content: '<p>aaa</p><hr><p>bbb</p>',
- steps: [{
- start: "p:eq(1):contents()[0]->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: '<p>aaabbb</p>',
- start: "p:contents()[0]->3",
- },
- },
- {
- name: "in p with multi br[id] (p before and after) (1)",
- content: '<p>dom not to edit</p><p><br id="br-1"><br id="br-2"><br id="br-3"><br id="br-4"></p><p>dom not to edit</p>',
- steps: [{
- start: "p:eq(1)->2",
- key: 'BACKSPACE',
- }],
- test: {
- content: '<p>dom not to edit</p><p><br id="br-1"><br id="br-3"><br id="br-4"></p><p>dom not to edit</p>',
- start: "p:eq(1)->1",
- },
- },
- {
- name: "in p with multi br[id] (p before and after) (2)",
- content: '<p>dom not to edit</p><p><br id="br-1"><br id="br-2"><br id="br-3"><br id="br-4"></p><p>dom not to edit</p>',
- steps: [{
- start: "br:eq(2)->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: '<p>dom not to edit</p><p><br id="br-1"><br id="br-3"><br id="br-4"></p><p>dom not to edit</p>',
- start: "p:eq(1)->1",
- },
- },
- {
- name: "in p with multi br[id] (p before and after): 2x BACKSPACE",
- content: '<p>dom not to edit</p><p><br id="br-1"><br id="br-2"><br id="br-3"><br id="br-4"></p><p>dom not to edit</p>',
- steps: [{
- start: "p:eq(1)->2",
- key: 'BACKSPACE',
- }, {
- key: 'BACKSPACE',
- }],
- test: {
- content: '<p>dom not to edit</p><p><br id="br-3"><br id="br-4"></p><p>dom not to edit</p>',
- start: "p:eq(1)->0",
- },
- },
- {
- name: "in p with multi br (p before and after) (1)",
- content: '<p>dom not to edit</p><p><br><br><br><br></p><p>dom not to edit</p>',
- steps: [{
- start: "p:eq(1)->2",
- key: 'BACKSPACE',
- }],
- test: {
- content: '<p>dom not to edit</p><p><br><br><br></p><p>dom not to edit</p>',
- start: "p:eq(1)->1",
- },
- },
- {
- name: "in p with multi br (p before and after) (2)",
- content: '<p>dom not to edit</p><p><br><br><br><br></p><p>dom not to edit</p>',
- steps: [{
- start: "br:eq(2)->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: '<p>dom not to edit</p><p><br><br><br></p><p>dom not to edit</p>',
- start: "p:eq(1)->1",
- },
- },
- {
- name: "in p with multi br (p before and after): 2x BACKSPACE",
- content: '<p>dom not to edit</p><p><br><br><br><br></p><p>dom not to edit</p>',
- steps: [{
- start: "p:eq(1)->2",
- key: 'BACKSPACE',
- }, {
- key: 'BACKSPACE',
- }],
- test: {
- content: '<p>dom not to edit</p><p><br><br></p><p>dom not to edit</p>',
- start: "p:eq(1)->0",
- },
- },
- {
- name: "in p: BACKSPACE within text after \w+<br>",
- content: '<p>dom to<br>edit</p>',
- steps: [{
- start: "p:contents()[2]->3",
- key: 'BACKSPACE',
- }],
- test: {
- content: '<p>dom to<br>edt</p>',
- start: "p:contents()[2]->2",
- },
- },
-
- // table
-
- {
- name: "in empty-td (td before): BACKSPACE -> 'a' at start",
- content: '<table class="table table-bordered"><tbody><tr><td><p><br></p></td><td><p><br></p></td></tr></tbody></table>',
- steps: [{
- start: "p:eq(1)->1",
- key: 'BACKSPACE',
- }, {
- key: 'a',
- }],
- test: {
- content: '<table class="table table-bordered"><tbody><tr><td><p><br></p></td><td><p>a</p></td></tr></tbody></table>',
- start: "p:eq(1):contents()[0]->1",
- },
- },
- {
- name: "in td (td before): 2x BACKSPACE -> 'a' after first character",
- content: '<table class="table table-bordered"><tbody><tr><td><p>dom not to edit</p></td><td><p>dom to edit</p></td></tr></tbody></table>',
- steps: [{
- start: "p:eq(1):contents()[0]->1",
- key: 'BACKSPACE',
- }, {
- key: 'BACKSPACE',
- }, {
- key: 'a',
- }],
- test: {
- content: '<table class="table table-bordered"><tbody><tr><td><p>dom not to edit</p></td><td><p>aom to edit</p></td></tr></tbody></table>',
- start: "p:eq(1):contents()[0]->1",
- },
- },
- {
- name: "in td (no other td): BACKSPACE within text",
- content: '<table class="table table-bordered"><tbody><tr><td><p>dom to edit</p></td></tr></tbody></table>',
- steps: [{
- start: "p:contents()[0]->5",
- key: 'BACKSPACE',
- }],
- test: {
- content: '<table class="table table-bordered"><tbody><tr><td><p>dom o edit</p></td></tr></tbody></table>',
- start: "p:contents()[0]->4",
- },
- },
- {
- name: "in complex-dom (empty-td (td before) -> 2x SHIFT-ENTER): 3x BACKSPACE -> 'a'",
- content: '<table class="table table-bordered"><tbody><tr><td><p>dom not to edit</p></td><td><p><br><br><br></p></td></tr></tbody></table>',
- steps: [{
- start: 'p:eq(1)->3',
- key: 'BACKSPACE',
- }, {
- key: 'BACKSPACE',
- }, {
- key: 'BACKSPACE',
- }, {
- key: 'a',
- }],
- test: {
- content: '<table class="table table-bordered"><tbody><tr><td><p>dom not to edit</p></td><td><p>a</p></td></tr></tbody></table>',
- start: "p:eq(1):contents()[0]->1",
- },
- },
- {
- name: "in h1: BACKSPACE on full selection -> 'a'",
- content: '<h1>dom to delete</h1>',
- steps: [{
- start: 'h1:contents()[0]->0',
- end: 'h1:contents()[0]->13',
- key: 'BACKSPACE',
- }, {
- key: 'a',
- }],
- test: {
- content: '<h1>a</h1>',
- start: "h1:contents()[0]->1",
- },
- },
- {
- name: "in h1: BACKSPACE on full selection -> BACKSPACE -> 'a'",
- content: '<h1>dom to delete</h1>',
- steps: [{
- start: 'h1:contents()[0]->0',
- end: 'h1:contents()[0]->13',
- key: 'BACKSPACE',
- }, {
- key: 'BACKSPACE',
- }, {
- key: 'a',
- }],
- test: {
- content: '<p>a</p>',
- start: "p:contents()[0]->1",
- },
- },
- {
- name: "in h1: BACKSPACE on full selection -> DELETE -> 'a'",
- content: '<h1>dom to delete</h1>',
- steps: [{
- start: 'h1:contents()[0]->0',
- end: 'h1:contents()[0]->13',
- key: 'BACKSPACE',
- }, {
- key: 'DELETE',
- }, {
- key: 'a',
- }],
- test: {
- content: '<h1>a</h1>',
- start: "h1:contents()[0]->1",
- },
- },
-
- // merging non-similar blocks
-
- {
- name: "in p (h1 before): BACKSPACE at start",
- content: '<h1>node to merge with</h1><p>node to merge</p>',
- steps: [{
- start: 'p:contents()[0]->0',
- key: 'BACKSPACE',
- }],
- test: {
- content: '<h1>node to merge withnode to merge</h1>',
- start: "h1:contents()[0]->18",
- },
- },
- {
- name: "in empty-p (h1 before): BACKSPACE",
- content: "<h1>dom to edit</h1><p><br></p>",
- steps: [{
- start: "p->1",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<h1>dom to edit</h1>",
- start: "h1:contents()[0]->11",
- },
- },
- {
- name: "in empty-p (h1 before): 2x BACKSPACE",
- content: "<h1>dom to edit</h1><p><br></p>",
- steps: [{
- start: "p->1",
- key: 'BACKSPACE',
- }, {
- key: 'BACKSPACE',
- }],
- test: {
- content: "<h1>dom to edi</h1>",
- start: "h1:contents()[0]->10",
- },
- },
- {
- name: "in p (ul before): BACKSPACE at start",
- content: '<ul><li><p>node to merge with</p></li></ul><p>node to merge</p>',
- steps: [{
- start: 'p:eq(1):contents()[0]->0',
- key: 'BACKSPACE',
- }],
- test: {
- content: '<ul><li><p>node to merge withnode to merge</p></li></ul>',
- start: "p:contents()[0]->18",
- },
- },
- {
- name: "in p > b (ul before, i after): BACKSPACE at start",
- content: '<ul><li><p>node to merge with</p></li></ul><p><b>node</b><i> to merge</i></p>',
- steps: [{
- start: 'b:contents()[0]->0',
- key: 'BACKSPACE',
- }],
- test: {
- content: '<ul><li><p>node to merge with<b>node</b><i> to merge</i></p></li></ul>',
- start: "p:contents()[0]->18",
- },
- },
- {
- name: "in p > b (ul > i before, i after): BACKSPACE at start",
- content: '<ul><li><p><i>node to merge with</i></p></li></ul><p><b>node</b><i> to merge</i></p>',
- steps: [{
- start: 'b:contents()[0]->0',
- key: 'BACKSPACE',
- }],
- test: {
- content: '<ul><li><p><i>node to merge with</i><b>node</b><i> to merge</i></p></li></ul>',
- start: "i:contents()[0]->18",
- },
- },
- {
- name: "in p.c (p.a > span.b before - span.b after): BACKSPACE at beginning",
- content: "<p class=\"a\"><span class=\"b\">dom to&nbsp;</span></p><p class=\"c\"><span class=\"b\">edit</span></p>",
- steps: [{
- start: "p:eq(1):contents()[0]->0",
- key: 'BACKSPACE',
- }],
- test: {
- content: "<p class=\"a\"><span class=\"b\">dom to&nbsp;edit</span></p>",
- start: "span:eq(0):contents()[0]->7",
- },
- },
- {
- name: "from h1 to p: BACKSPACE",
- content: '<h1>node to merge with</h1><p>node to merge</p>',
- steps: [{
- start: 'h1:contents()[0]->5',
- end: 'p:contents()[0]->2',
- key: 'BACKSPACE',
- }],
- test: {
- content: '<h1>node de to merge</h1>',
- start: "h1:contents()[0]->5",
- },
- },
- {
- name: "from h1 to p: BACKSPACE at start",
- content: '<h1><b>node to merge with</b></h1><p>node to merge</p>',
- steps: [{
- start: 'b:contents()[0]->0',
- end: 'p:contents()[0]->2',
- key: 'BACKSPACE',
- }],
- test: {
- content: '<p>de to merge</p>',
- 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: "<p></p>",
- steps: [{
- start: "p->0",
- key: 'DELETE',
- }],
- test: {
- content: "<p><br></p>", // 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: "<p><br></p>",
- steps: [{
- start: "p->0",
- key: 'DELETE',
- }],
- test: {
- content: "<p><br></p>", // 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: "<p>\n <br>\n</p>",
- steps: [{
- start: "p->1",
- key: 'DELETE',
- }],
- test: {
- content: "<p>\n <br>\n</p>", // 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: "<p><br></p><p>dom to edit</p>",
- steps: [{
- start: "p->0",
- key: 'DELETE',
- }],
- test: {
- content: "<p>dom to edit</p>",
- start: "p:contents()[0]->0",
- },
- },
- {
- name: "in empty-p (p after): DELETE (2)",
- content: "<p>\n <br>\n</p><p>\n dom to edit</p>",
- steps: [{
- start: "p:contents()[1]->0",
- key: 'DELETE',
- }],
- test: {
- content: "<p>dom to edit</p>",
- start: "p:contents()[0]->0",
- },
- },
- {
- name: "in empty-p.a (p after): DELETE",
- content: "<p class=\"a\"><br></p><p>dom to edit</p>",
- steps: [{
- start: "p->0",
- key: 'DELETE',
- }],
- test: {
- content: "<p>dom to edit</p>",
- start: "p:contents()[0]->0",
- },
- },
- {
- name: "in empty-p.a (p after): DELETE (2)",
- content: "<p class=\"a\"><br></p><p>dom to edit</p>",
- steps: [{
- start: "p->1",
- key: 'DELETE',
- }],
- test: {
- content: "<p>dom to edit</p>",
- start: "p:contents()[0]->0",
- },
- },
- {
- name: "in p: DELETE at start",
- content: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->0",
- key: 'DELETE',
- }],
- test: {
- content: "<p>om to edit</p>", // 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: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->0",
- key: 'DELETE',
- }, {
- key: 'DELETE',
- }],
- test: {
- content: "<p>m to edit</p>", // 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: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->5",
- key: 'DELETE',
- }],
- test: {
- content: "<p>dom t edit</p>",
- start: "p:contents()[0]->5",
- },
- },
- {
- name: "in p: DELETE within text, with space at beginning",
- content: "<p> dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->10",
- key: 'DELETE',
- }],
- test: {
- content: "<p>dom t edit</p>",
- start: "p:contents()[0]->5",
- },
- },
- {
- name: "in p: DELETE within text, with one space at beginning",
- content: "<p> dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->6",
- key: 'DELETE',
- }],
- test: {
- content: "<p>&nbsp;dom t edit</p>",
- start: "p:contents()[0]->6",
- },
- },
- {
- name: "in p: DELETE within text, with space at end",
- content: "<p>dom to edit </p>",
- steps: [{
- start: "p:contents()[0]->5",
- key: 'DELETE',
- }],
- test: {
- content: "<p>dom t edit</p>",
- start: "p:contents()[0]->5",
- },
- },
- {
- name: "in p: DELETE within text, with one space at end",
- content: "<p>dom to edit </p>",
- steps: [{
- start: "p:contents()[0]->5",
- key: 'DELETE',
- }],
- test: {
- content: "<p>dom t edit&nbsp;</p>",
- start: "p:contents()[0]->5",
- },
- },
- {
- name: "in p: DELETE within text, with space at beginning and end",
- content: "<p> dom to edit </p>",
- steps: [{
- start: "p:contents()[0]->10",
- key: 'DELETE',
- }],
- test: {
- content: "<p>dom t edit</p>",
- start: "p:contents()[0]->5",
- },
- },
- {
- name: "in p: DELETE within text, with one space at beginning and one at end",
- content: "<p> dom to edit </p>",
- steps: [{
- start: "p:contents()[0]->6",
- key: 'DELETE',
- }],
- test: {
- content: "<p>&nbsp;dom t edit&nbsp;</p>",
- start: "p:contents()[0]->6",
- },
- },
- {
- name: "in p: DELETE -> 'a' within text, before \\w\\s",
- content: "<p>dom t</p>",
- steps: [{
- start: "p:contents()[0]->2",
- key: 'DELETE',
- }, {
- key: 'a',
- }],
- test: {
- content: "<p>doa t</p>",
- start: "p:contents()[0]->3",
- },
- },
- {
- name: "in pre: DELETE within text, with space at beginning",
- content: "<pre> dom to edit</pre>",
- steps: [{
- start: "pre:contents()[0]->10",
- key: 'DELETE',
- }],
- test: {
- content: "<pre> dom t edit</pre>",
- start: "pre:contents()[0]->10",
- },
- },
- {
- name: "in pre: DELETE within text, with one space at beginning",
- content: "<pre> dom to edit</pre>",
- steps: [{
- start: "pre:contents()[0]->6",
- key: 'DELETE',
- }],
- test: {
- content: "<pre> dom t edit</pre>",
- start: "pre:contents()[0]->6",
- },
- },
- {
- name: "in pre: DELETE within text, with space at end",
- content: "<pre>dom to edit </pre>",
- steps: [{
- start: "pre:contents()[0]->5",
- key: 'DELETE',
- }],
- test: {
- content: "<pre>dom t edit </pre>",
- start: "pre:contents()[0]->5",
- },
- },
- {
- name: "in pre: DELETE within text, with one space at end",
- content: "<pre>dom to edit </pre>",
- steps: [{
- start: "pre:contents()[0]->5",
- key: 'DELETE',
- }],
- test: {
- content: "<pre>dom t edit </pre>",
- start: "pre:contents()[0]->5",
- },
- },
- {
- name: "in pre: DELETE within text, with space at beginning and end",
- content: "<pre> dom to edit </pre>",
- steps: [{
- start: "pre:contents()[0]->10",
- key: 'DELETE',
- }],
- test: {
- content: "<pre> dom t edit </pre>",
- start: "pre:contents()[0]->10",
- },
- },
- {
- name: "in pre: DELETE within text, with one space at beginning and one at end",
- content: "<pre> dom to edit </pre>",
- steps: [{
- start: "pre:contents()[0]->6",
- key: 'DELETE',
- }],
- test: {
- content: "<pre> dom t edit </pre>",
- start: "pre:contents()[0]->6",
- },
- },
-
- // list UL / OL
-
- {
- name: "in empty-li (no other li): DELETE (must do nothing)",
- content: "<ul><li><br></li></ul>",
- steps: [{
- start: "li:contents()[0]->0",
- key: 'DELETE',
- }],
- test: {
- content: "<ul><li><br></li></ul>",
- start: "li->0",
- },
- },
- {
- name: "from p to li > p: DELETE on whole list",
- content: "<p>dom not to edit</p><ul><li><p>dom to edit</p></li></ul>",
- steps: [{
- start: "p:contents()[0]->15",
- end: "p:eq(1):contents()[0)->11",
- key: 'DELETE',
- }],
- test: {
- content: "<p>dom not to edit</p>",
- start: "p:contents()[0]->15",
- },
- },
- {
- name: "in empty-li (no other li): DELETE -> 'a' (must write into it)",
- content: "<ul><li><br></li></ul>",
- steps: [{
- start: "li:contents()[0]->0",
- key: 'DELETE',
- }, {
- key: 'a',
- }],
- test: {
- content: "<ul><li><p>a</p></li></ul>",
- start: "p:contents()[0]->1",
- },
- },
- {
- name: "in li (li after): DELETE at end (must move contents of second li to carret)",
- content: "<ul><li>dom to&nbsp;</li><li>edit</li></ul>",
- steps: [{
- start: "li:contents()[0]->7",
- key: 'DELETE',
- }],
- test: {
- content: "<ul><li>dom to&nbsp;edit</li></ul>",
- 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: "<ul><li>dom to&nbsp;</li><li>edit</li></ul>",
- steps: [{
- start: "li:contents()[0]->7",
- key: 'DELETE',
- }, {
- key: 'a',
- }],
- test: {
- content: "<ul><li>dom to aedit</li></ul>",
- start: "li:contents()[0]->8",
- },
- },
- {
- name: "in li > p: DELETE before single character",
- content: "<ul><li><p>a</p></li></ul>",
- steps: [{
- start: "p:contents()[0]->0",
- key: 'DELETE',
- }],
- test: {
- content: "<ul><li><p><br></p></li></ul>",
- start: "br->0",
- },
- },
- {
- name: "in li > p: DELETE -> 'a' before single character",
- content: "<ul><li><p>a</p></li></ul>",
- steps: [{
- start: "p:contents()[0]->0",
- key: 'DELETE',
- }, {
- key: 'a',
- }],
- test: {
- content: "<ul><li><p>a</p></li></ul>",
- start: "p:contents()[0]->1",
- },
- },
- {
- name: "in li > p (p after): DELETE at end",
- content: "<ul><li><p>toto</p></li><li><p>xxx</p><p>yyy</p></li><li><p>tutu</p></li></ul>",
- steps: [{
- start: "li:eq(1) p:eq(0):contents()[0]->3",
- key: 'DELETE',
- }],
- test: {
- content: "<ul><li><p>toto</p></li><li><p>xxxyyy</p></li><li><p>tutu</p></li></ul>",
- start: "li:eq(1) p:eq(0):contents()[0]->3",
- },
- },
- {
- name: "in li > p (b before - p after): DELETE at end",
- content: "<ul><li><p>toto</p></li><li><p><b>x</b>xx</p><p><b>y</b>yy</p></li><li><p>tutu</p></li></ul>",
- steps: [{
- start: "li:eq(1) p:eq(0):contents()[1]->2",
- key: 'DELETE',
- }],
- test: {
- content: "<ul><li><p>toto</p></li><li><p><b>x</b>xx<b>y</b>yy</p></li><li><p>tutu</p></li></ul>",
- start: "li:eq(1) p:eq(0):contents()[1]->2",
- },
- },
- {
- name: "in li > p (p.o_default_snippet_text after): DELETE at end",
- content: '<ul><li><p>toto</p></li><li><p>xxx</p><p class="o_default_snippet_text">yyy</p></li><li><p>tutu</p></li></ul>',
- steps: [{
- start: "li:eq(1) p:eq(0):contents()[0]->3",
- key: 'DELETE',
- }],
- test: {
- content: "<ul><li><p>toto</p></li><li><p>xxxyyy</p></li><li><p>tutu</p></li></ul>",
- start: "li:eq(1) p:eq(0):contents()[0]->3",
- },
- },
- {
- name: "in indented-ul > li: DELETE at end (must do nothing)",
- content: "<ul><ul><li>dom to edit</li></ul></ul>",
- steps: [{
- start: "li:contents()[0]->11",
- key: 'DELETE',
- }],
- test: {
- content: "<ul><ul><li>dom to edit</li></ul></ul>",
- start: "li:contents()[0]->11",
- },
- },
- {
- name: "in indented-ul > li: DELETE at end -> 'a' at end (must write)",
- content: "<ul><ul><li>dom to edit</li></ul></ul>",
- steps: [{
- start: "li:contents()[0]->11",
- key: 'DELETE',
- }, {
- key: 'a',
- }],
- test: {
- content: "<ul><ul><li>dom to edita</li></ul></ul>",
- start: "li:contents()[0]->12",
- },
- },
- {
- name: "in indented-ul > li (non-indented-li after): DELETE at end",
- content: "<ul><ul><li>dom to edit</li></ul><li>dom to edit</li></ul>",
- steps: [{
- start: "li:contents()[0]->11",
- key: 'DELETE',
- }],
- test: {
- content: "<ul><ul><li>dom to editdom to edit</li></ul></ul>",
- start: "li:contents()[0]->11",
- },
- },
- {
- name: "in ul > li (indented-li after): DELETE at end",
- content: "<ul><li>dom to edit</li><ul><li>dom to edit</li></ul></ul>",
- steps: [{
- start: "li:contents()[0]->11",
- key: 'DELETE',
- }],
- test: {
- content: "<ul><li>dom to editdom to edit</li></ul>",
- start: "li:contents()[0]->11",
- },
- },
- {
- name: "in li: DELETE on partial selection",
- content: "<ul><li>dom to edit</li></ul>",
- steps: [{
- start: "li:contents()[0]->1",
- end: "li:contents()[0]->7",
- key: 'DELETE',
- }],
- test: {
- content: "<ul><li>dedit</li></ul>",
- start: "li:contents()[0]->1",
- },
- },
- {
- name: "across 2 li: DELETE on partial selection",
- content: "<ul><li>dom to edit</li><li>dom to edit</li></ul>",
- steps: [{
- start: "li:contents()[0]->1",
- end: "li:eq(1):contents()[0]->7",
- key: 'DELETE',
- }],
- test: {
- content: "<ul><li>dedit</li></ul>",
- start: "li:contents()[0]->1",
- },
- },
- {
- name: "in li: DELETE on selection of all contents",
- content: "<ul><li>dom to edit</li></ul>",
- steps: [{
- start: "li:contents()[0]->0",
- end: "li:contents()[0]->11",
- key: 'DELETE',
- }],
- test: {
- content: "<ul><li><br></li></ul>",
- start: "li->0",
- },
- },
- {
- name: "in li: DELETE -> 'a' on selection of all contents",
- content: "<ul><li>dom to edit</li></ul>",
- steps: [{
- start: "li:contents()[0]->0",
- end: "li:contents()[0]->11",
- key: 'DELETE',
- }, {
- key: 'a',
- }],
- test: {
- content: "<ul><li><p>a</p></li></ul>",
- start: "p:contents()[0]->1",
- },
- },
-
- // end list UL / OL
-
- {
- name: "in p (b before): DELETE",
- content: "<p><b>dom</b>to edit</p>",
- steps: [{
- start: "b:contents()[0]->3",
- key: 'DELETE',
- }],
- test: {
- content: "<p><b>dom</b>o edit</p>",
- start: "p:contents(1)->0",
- },
- },
- {
- name: "in p > span.a (div > span.a after): DELETE at end (must do nothing)",
- content: "<p><span class=\"a\">dom to</span></p><div><span class=\"a\">edit</span></div>",
- steps: [{
- start: "span:contents()[0]->6",
- key: 'DELETE',
- }],
- test: {
- content: "<p><span class=\"a\">dom to</span></p><div><span class=\"a\">edit</span></div>",
- start: "span:contents()[0]->6",
- },
- },
- {
- name: "in p: DELETE on partial selection",
- content: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->1",
- end: "p:contents()[0]->7",
- key: 'DELETE',
- }],
- test: {
- content: "<p>dedit</p>",
- start: "p:contents()[0]->1",
- },
- },
- {
- name: "across 2 p: DELETE on partial selection",
- content: "<p>dom</p><p>to edit</p>",
- steps: [{
- start: "p:contents()[0]->1",
- end: "p:eq(1):contents()[0]->3",
- key: 'DELETE',
- }],
- test: {
- content: "<p>dedit</p>",
- start: "p:contents()[0]->1",
- },
- },
- {
- name: "in p: DELETE on selection of all contents",
- content: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->0",
- end: "p:contents()[0]->11",
- key: 'DELETE',
- }],
- test: {
- content: "<p><br></p>",
- start: "p->0",
- },
- },
- {
- name: "in p: DELETE -> 'a' on selection of all contents",
- content: "<p>dom to edit</p>",
- steps: [{
- start: "p:contents()[0]->0",
- end: "p:contents()[0]->11",
- key: 'DELETE',
- }, {
- key: 'a',
- }],
- test: {
- content: "<p>a</p>",
- start: "p:contents()[0]->1",
- },
- },
- {
- name: "in p: DELETE before br",
- content: "<p>dom <br>to edit</p>",
- steps: [{
- start: "p:contents()[0]->4",
- key: 'DELETE',
- }],
- test: {
- content: "<p>dom&nbsp;to edit</p>",
- start: "p:contents()[0]->4",
- },
- },
- {
- name: "in complex-dom: DELETE on selection of most contents",
- content: "<p><b>dom</b></p><p><b>to<br>partially</b>re<i>m</i>ove</p>",
- steps: [{
- start: "b:contents()[0]->2",
- end: "i:contents()[0]->1",
- key: 'DELETE',
- }],
- test: {
- content: "<p><b>do</b>ove</p>",
- start: "b:contents()[0]->2",
- },
- },
- {
- name: "in complex-dom: DELETE on selection of all contents",
- content: "<p><b>dom</b></p><p><b>to<br>completely</b>remov<i>e</i></p>",
- steps: [{
- start: "p:contents()[0]->0",
- end: "i:contents()[0]->1",
- key: 'DELETE',
- }],
- test: {
- content: "<p><br></p>",
- start: "br->0",
- },
- },
- {
- name: "in complex-dom (span > b -> ENTER): DELETE",
- content: "<span><b>dom</b></span><br><span><b> to edit</b></span>",
- steps: [{
- start: "b:eq(0):contents()[0]->3",
- key: 'DELETE',
- }],
- test: {
- content: "<span><b>dom&nbsp;to edit</b></span>",
- start: "b:contents()[0]->3",
- },
- },
- {
- name: "in p (span.fa after): DELETE",
- content: '<p>aaa<span class="fa fa-star"></span>bbb</p>',
- steps: [{
- start: "p:contents()[0]->3",
- key: 'DELETE',
- }],
- test: {
- content: '<p>aaabbb</p>',
- start: "p:contents()[0]->3",
- },
- },
- {
- name: "in p (hr after): DELETE",
- content: '<p>aaa</p><hr><p>bbb</p>',
- steps: [{
- start: "p:eq(0):contents()[0]->3",
- key: 'DELETE',
- }],
- test: {
- content: '<p>aaabbb</p>',
- start: "p:contents()[0]->3",
- },
- },
-
- // table
-
- {
- name: "in empty-td (td after): DELETE -> 'a' at start",
- content: '<table class="table table-bordered"><tbody><tr><td><p><br></p></td><td><p><br></p></td></tr></tbody></table>',
- steps: [{
- start: "p->1",
- key: 'DELETE',
- }, {
- key: 'a',
- }],
- test: {
- content: '<table class="table table-bordered"><tbody><tr><td><p>a</p></td><td><p><br></p></td></tr></tbody></table>',
- start: "p:contents()[0]->1",
- },
- },
- {
- name: "in td (td after): 2x DELETE -> 'a' after first character",
- content: '<table class="table table-bordered"><tbody><tr><td><p>dom to edit</p></td><td><p>dom not to edit</p></td></tr></tbody></table>',
- steps: [{
- start: "p:contents()[0]->1",
- key: 'DELETE',
- }, {
- key: 'DELETE',
- }, {
- key: 'a',
- }],
- test: {
- content: '<table class="table table-bordered"><tbody><tr><td><p>da to edit</p></td><td><p>dom not to edit</p></td></tr></tbody></table>',
- start: "p:contents()[0]->2",
- },
- },
- {
- name: "in td: DELETE within text",
- content: '<table class="table table-bordered"><tbody><tr><td><p>dom to edit</p></td></tr></tbody></table>',
- steps: [{
- start: "p:contents()[0]->4",
- key: 'DELETE',
- }],
- test: {
- content: '<table class="table table-bordered"><tbody><tr><td><p>dom o edit</p></td></tr></tbody></table>',
- 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: "<p>dom to edit&nbsp; </p><ul><li><p> &nbsp; dom to edit</p></li><li><p>dom not to edit</p></li></ul>",
- steps: [{
- start: "p:contents()[0]->11",
- key: 'DELETE',
- }, {
- key: 'DELETE',
- }, {
- key: 'DELETE',
- }, {
- key: 'DELETE',
- }],
- test: {
- content: "<p>dom to editdom to edit</p><ul><li><p>dom not to edit</p></li></ul>",
- start: "p:contents()[0]->11",
- },
- },
- {
- name: "in h1 (p after): DELETE at end",
- content: '<h1>node to merge with</h1><p>node to merge</p>',
- steps: [{
- start: 'h1:contents()[0]->18',
- key: 'DELETE',
- }],
- test: {
- content: '<h1>node to merge withnode to merge</h1>',
- start: "h1:contents()[0]->18",
- },
- },
- {
- name: "in h1 (empty-p after): DELETE at end",
- content: "<h1>dom to edit</h1><p><br></p>",
- steps: [{
- start: "h1:contents()[0]->11",
- key: 'DELETE',
- }],
- test: {
- content: "<h1>dom to edit</h1>",
- start: "h1:contents()[0]->11",
- },
- },
- {
- name: "in h1 (empty-p after): 2x DELETE at end",
- content: "<h1>dom to edit</h1><p><br></p>",
- steps: [{
- start: "h1:contents()[0]->11",
- key: 'DELETE',
- }, {
- key: 'DELETE',
- }],
- test: {
- content: "<h1>dom to edit</h1>",
- start: "h1:contents()[0]->11",
- },
- },
- {
- name: "in li > p (p after): DELETE at end",
- content: '<ul><li><p>node to merge with</p></li></ul><p>node to merge</p>',
- steps: [{
- start: 'p:contents()[0]->18',
- key: 'DELETE',
- }],
- test: {
- content: '<ul><li><p>node to merge withnode to merge</p></li></ul>',
- start: "p:contents()[0]->18",
- },
- },
- {
- name: "in li > p (i before - p > b after): DELETE at end",
- content: '<ul><li><p><i>node to merge</i> with</p></li></ul><p><b>node</b> to merge</p>',
- steps: [{
- start: 'p:contents()[1]->5',
- key: 'DELETE',
- }],
- test: {
- content: '<ul><li><p><i>node to merge</i>&nbsp;with<b>node</b> to merge</p></li></ul>',
- start: "p:contents()[1]->5",
- },
- },
- {
- name: "in li > p > i (b before - p > b after): DELETE at end",
- content: '<ul><li><p><b>node to </b><i>merge with</i></p></li></ul><p><b>node</b> to merge</p>',
- steps: [{
- start: 'i:contents()[0]->10',
- key: 'DELETE',
- }],
- test: {
- content: '<ul><li><p><b>node to </b><i>merge with</i><b>node</b> to merge</p></li></ul>',
- start: "i:contents()[0]->10",
- },
- },
- {
- name: "in p.a > span.b (p.c > span.b after): DELETE at end",
- content: "<p class=\"a\"><span class=\"b\">dom to&nbsp;</span></p><p class=\"c\"><span class=\"b\">edit</span></p>",
- steps: [{
- start: "span:contents()[0]->7",
- key: 'DELETE',
- }],
- test: {
- content: "<p class=\"a\"><span class=\"b\">dom to&nbsp;edit</span></p>",
- start: "span:contents()[0]->7",
- },
- },
-];
-
-var keyboardTestsDeleteDOM = [
- '<div style="margin:0px; padding:0px;">',
- ' <p style="margin:0px; padding:0px;">',
- ' Dear Ready Mat',
- ' <br><br>',
- ' Here is',
- ' the quotation <strong>SO003</strong>',
- ' amounting in <strong>$&nbsp;1,127.50</strong>',
- ' from YourCompany.',
- ' <br><br>',
- ' Do not hesitate to contact us if you have any question.',
- ' <br><br>',
- ' </p>',
- ' <table width="100%">',
- ' <tbody><tr>',
- ' <td>',
- ' <strong>Virtual Interior Design</strong><br>On Site ',
- ' </td>',
- ' <td width="100px" align="right">',
- ' 10 Hours',
- ' </td>',
- ' </tr>',
- ' </tbody></table>',
- '</div>',
- ' '
-].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('<br>', ''),
- 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(/<strong>SO003<\/strong>\s+/, '&nbsp;'),
- 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: '<p>toto toto toto</p><p>tata</p>',
- },
- }).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, ' '),
- '<p>toto toto toto</p><div class=\"s_hr pt32 pb32\"> <hr class=\"s_hr_1px s_hr_solid w-100 mx-auto\"> </div><p>tata</p>',
- "should drop the snippet");
-
- testUtils.mock.intercept(wysiwyg, "snippet_focused", function () {
- assert.strictEqual($editable.html().replace(/\s+/g, ' '),
- '<p>toto toto toto</p><div class=\"s_hr pt32 pb32 built focus\"> <hr class=\"s_hr_1px s_hr_solid w-100 mx-auto\"> </div><p>tata</p>',
- "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:
- '<div class="s_hr pt32 pb32"> ' +
- '<hr class="s_hr_1px s_hr_solid w-100 mx-auto"> ' +
- '<img class="img-fluid o_we_custom_image" data-src="/web_editor/static/src/img/transparent.png"> ' +
- '</div>' +
- '<h1>test</h1>' +
- '<p><b>test</b></p>',
- },
- }).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:
- '<div class="s_hr pt32 pb32"> ' +
- '<hr class="s_hr_1px s_hr_solid w-100 mx-auto"> ' +
- '<img class="img-fluid o_we_custom_image" data-src="/web_editor/static/src/img/transparent.png"> ' +
- '</div>' +
- '<h1>test</h1>' +
- '<p><b>test</b></p>',
- },
- }).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: '<p>toto toto toto</p><p>tata</p>',
- },
- }).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, ' '),
- '<p>toto toto toto</p><div class=\"s_hr pt32 pb32 built cleanForSave\"> <hr class=\"s_hr_1px s_hr_solid w-100 mx-auto\"> </div><p>tata</p>',
- "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: '<div class="s_hr pt32 pb32"> <hr class="s_hr_1px s_hr_solid w-100 mx-auto"> </div>',
- },
- }).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, ' '),
- '<div class=\"s_hr pt32 pb32 cleanForSave\"> <hr class=\"s_hr_1px s_hr_solid w-100 mx-auto\"> </div>',
- "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: '<div class="s_hr pt32 pb32"> <hr class="s_hr_1px s_hr_solid w-100 mx-auto"> </div>',
- },
- }).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: '<div class="s_hr pt32 pb32"> <hr class="s_hr_1px s_hr_solid w-100 mx-auto"> </div><h1>test</h1><p><b>test</b></p>',
- },
- }).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, ' '),
- '<h1>test</h1><div class="s_hr pt32 pb32 move cleanForSave"> <hr class="s_hr_1px s_hr_solid w-100 mx-auto"> </div><p><b>test</b></p>',
- "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: '<div class="s_hr pt32 pb32"> <hr class="s_hr_1px s_hr_solid w-100 mx-auto"> </div><h1>test</h1><p><b>test</b></p>',
- },
- }).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, ' '),
- '<div class="s_hr pt32 pb32 focus"> <hr class="s_hr_1px s_hr_solid w-100 mx-auto"> </div><div class="s_hr pt32 pb32 clone"> <hr class="s_hr_1px s_hr_solid w-100 mx-auto"> </div><h1>test</h1><p><b>test</b></p>',
- "should duplicate the snippet");
-
- wysiwyg.save().then(function (result) {
- assert.strictEqual(result.html.replace(/\s+/g, ' '),
- '<div class="s_hr pt32 pb32 cleanForSave"> <hr class="s_hr_1px s_hr_solid w-100 mx-auto"> </div><div class="s_hr pt32 pb32 clone cleanForSave"> <hr class="s_hr_1px s_hr_solid w-100 mx-auto"> </div><h1>test</h1><p><b>test</b></p>',
- "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: '<h1>test</h1><div class="s_hr pt32 pb32"> <hr class="s_hr_1px s_hr_solid w-100 mx-auto"> </div><p><b>test</b></p>',
- },
- }).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, ' '),
- '<h1>test</h1><div class="s_hr pt32 pb32 focus align-items-center"> <hr class="s_hr_1px s_hr_solid w-100 mx-auto"> </div><p><b>test</b></p>',
- "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, ' '),
- '<h1>test</h1><div class="s_hr pt32 pb32 focus align-items-end"> <hr class="s_hr_1px s_hr_solid w-100 mx-auto"> </div><p><b>test</b></p>',
- "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:
- '<h1>Big Title</h1>' +
- '<section class="test_option_all pt32 pb32">' +
- ' <div class="container">' +
- ' <div class="row">' +
- ' <div class="col-lg-10 offset-lg-1 pt32 pb32">' +
- ' <h2>Title</h2>' +
- ' <p class="lead o_default_snippet_text">Content</p>' +
- ' </div>' +
- ' </div>' +
- ' </div>' +
- '</section>',
- },
- 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: '<div class="s_hr pt32 pb32"> ' +
- '<img class="img-fluid o_we_custom_image test_option_all" data-src="/web_editor/static/src/img/transparent.png"> ' +
- '</div>',
- },
- }).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: '<p>dom not to edit</p><p>dom to edit</p>',
- 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: '<p>dom not to edit</p><h1>dom to edit</h1>',
- start: 'h1:contents()[0]->0',
- end: 'h1:contents()[0]->11',
- },
- },
- {
- name: "Click CODE: h1 -> pre",
- content: '<p>dom not to edit</p><h1>dom to edit</h1>',
- 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: '<p>dom not to edit</p><pre>dom to edit</pre>',
- start: 'pre:contents()[0]->0',
- end: 'pre:contents()[0]->11',
- },
- },
- {
- name: "Click NORMAL: pre -> p",
- content: '<p>dom not to edit</p><pre>dom to edit</pre>',
- 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: '<p>dom not to edit</p><p>dom to edit</p>',
- 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: '<p><br></p>',
- start: 'p->1',
- do: async function () {
- await testUtils.dom.triggerEvents($dropdownStyle, ['mousedown', 'click']);
- await testUtils.dom.triggerEvents($btnsStyle.find('h1'), ['mousedown', 'click']);
- },
- test: {
- content: '<h1><br></h1>',
- 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: '<p>dom not to edit</p><p>dom to edit</p>',
- 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: '<p>dom not to edit</p><p>d<b>om t</b>o edit</p>',
- start: 'b:contents()[0]->0',
- end: 'b:contents()[0]->4',
- },
- },
- {
- name: "Click BOLD then 'a': normal -> bold (empty p)",
- content: '<p><br></p>',
- start: 'p->1',
- do: async function () {
- await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']);
- weTestUtils.keydown('a', $editable);
- },
- test: {
- content: '<p><b>a</b></p>',
- start: 'b:contents()[0]->1',
- },
- },
- {
- name: "Click BOLD: normal -> bold (across paragraphs)",
- content: '<p>dom to edit</p><p>dom to edit</p>',
- start: 'p:contents()[0]->1',
- end: 'p:eq(1):contents()[0]->5',
- do: async function () {
- await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']);
- },
- test: {
- content: '<p>d<b>om to edit</b></p><p><b>dom t</b>o edit</p>',
- start: 'b:contents()[0]->0',
- end: 'b:eq(1):contents()[0]->5',
- },
- },
- {
- name: "Click BOLD then 'a': normal -> bold (no selection)",
- content: '<p>dom not to edit</p><p>dom to edit</p>',
- start: 'p:eq(1):contents()[0]->4',
- do: async function () {
- await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']);
- weTestUtils.keydown('a', $editable);
- },
- test: {
- content: '<p>dom not to edit</p><p>dom <b>a</b>to edit</p>',
- start: 'b:contents()[0]->1',
- },
- },
- {
- name: "Click BOLD: bold -> normal",
- content: '<p>dom not to edit</p><p><b>dom to edit</b></p>',
- start: 'b:contents()[0]->0',
- end: 'b:contents()[0]->11',
- do: async function () {
- await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']);
- },
- test: {
- content: '<p>dom not to edit</p><p>dom to edit</p>',
- start: 'p:eq(1):contents()[0]->0',
- end: 'p:eq(1):contents()[0]->11',
- },
- },
- {
- name: "Click BOLD: bold -> normal (partial selection)",
- content: '<p>dom not to edit</p><p><b>dom to edit</b></p>',
- start: 'b:contents()[0]->4',
- end: 'b:contents()[0]->6',
- do: async function () {
- await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']);
- },
- test: {
- content: '<p>dom not to edit</p><p><b>dom </b>to<b>&nbsp;edit</b></p>',
- start: 'p:eq(1):contents()[1]->0',
- end: 'p:eq(1):contents()[1]->2',
- },
- },
- {
- name: "Click BOLD: bold -> normal (no selection)",
- content: '<p>dom not to edit</p><p><b>dom to edit</b></p>',
- start: 'b:contents()[0]->4',
- do: async function () {
- await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']);
- },
- test: {
- content: '<p>dom not to edit</p><p><b>dom </b>\u200B<b>to edit</b></p>',
- start: 'p:eq(1):contents()[1]->1',
- },
- },
- {
- name: "Click BOLD: bold + normal -> normal",
- content: '<p><b>dom </b>to edit</p>',
- start: 'b:contents()[0]->1',
- end: 'p:contents()[1]->4',
- do: async function () {
- await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']);
- },
- test: {
- content: '<p><b>dom to e</b>dit</p>',
- start: 'b:contents()[0]->1',
- end: 'b:contents()[0]->8',
- },
- },
- {
- name: "Click BOLD: normal -> bold (with fontawesome)",
- content: '<p>aaa<span class="fa fa-heart"></span>bbb</p>',
- start: 'p:contents()[0]->1',
- end: 'p:contents()[2]->2',
- do: async function () {
- await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']);
- },
- test: {
- content: '<p>a<b>aa<span class="fa fa-heart"></span>bb</b>b</p>',
- start: 'b:contents()[0]->0',
- end: 'b:contents()[2]->2',
- },
- },
- {
- name: "Click BOLD + click BOLD: normal -> bold -> normal (with fontawesome)",
- content: '<p>aaa<span class="fa fa-heart"></span>bbb</p>',
- 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: '<p>aaa<span class="fa fa-heart"></span>bbb</p>',
- start: 'p:contents()[0]->1',
- end: 'p:contents()[2]->2',
- },
- },
- {
- name: "Click BOLD: bold -> normal (with fontawesome)",
- content: '<p><b>aaa<span class="fa fa-heart"></span>bbb</b></p>',
- start: 'b:contents()[0]->1',
- end: 'b:contents()[2]->2',
- do: async function () {
- await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']);
- },
- test: {
- content: '<p><b>a</b>aa<span class="fa fa-heart"></span>bb<b>b</b></p>',
- start: 'p:contents()[1]->0',
- end: 'p:contents()[3]->2',
- },
- },
- {
- name: "Click BOLD: bold -> normal (at start of dom)",
- content: '<p><b>abc</b></p>',
- start: 'b:contents()[0]->0',
- do: function () {
- $btnBold.mousedown().click();
- },
- test: {
- content: '<p>\u200B<b>abc</b></p>',
- start: 'p:contents()[0]->1',
- end: 'p:contents()[0]->1',
- },
- },
- /* ITALIC */
- {
- name: "Click ITALIC: bold -> bold + italic",
- content: '<p>dom not to edit</p><p><b>dom to edit</b></p>',
- start: 'b:contents()[0]->1',
- end: 'b:contents()[0]->5',
- do: async function () {
- await testUtils.dom.triggerEvents($btnItalic, ['mousedown', 'click']);
- },
- test: {
- content: '<p>dom not to edit</p><p><b>d<i>om t</i>o edit</b></p>',
- start: 'i:contents()[0]->0',
- end: 'i:contents()[0]->4',
- },
- },
- {
- name: "Click ITALIC: bold & normal -> italic & bold + italic (across paragraphs)",
- content: '<p>dom <b>to</b> edit</p><p><b>dom to edit</b></p>',
- start: 'p:contents()[0]->1',
- end: 'b:eq(1):contents()[0]->5',
- do: async function () {
- await testUtils.dom.triggerEvents($btnItalic, ['mousedown', 'click']);
- },
- test: {
- content: '<p>d<i>om <b>to</b> edit</i></p><p><b><i>dom t</i>o edit</b></p>',
- start: 'i:contents()[0]->0',
- end: 'i:eq(1):contents()[0]->5',
- },
- },
- /* UNDERLINE */
- {
- name: "Click UNDERLINE: bold -> bold + underlined",
- content: '<p>dom not to edit</p><p><b>dom to edit</b></p>',
- start: 'b:contents()[0]->1',
- end: 'b:contents()[0]->5',
- do: async function () {
- await testUtils.dom.triggerEvents($btnUnderline, ['mousedown', 'click']);
- },
- test: {
- content: '<p>dom not to edit</p><p><b>d<u>om t</u>o edit</b></p>',
- start: 'u:contents()[0]->0',
- end: 'u:contents()[0]->4',
- },
- },
- {
- name: "Click UNDERLINE: bold & normal -> underlined & bold + underlined (across paragraphs)",
- content: '<p>dom <b>to</b> edit</p><p><b>dom to edit</b></p>',
- start: 'p:contents()[0]->1',
- end: 'b:eq(1):contents()[0]->5',
- do: async function () {
- await testUtils.dom.triggerEvents($btnUnderline, ['mousedown', 'click']);
- },
- test: {
- content: '<p>d<u>om <b>to</b> edit</u></p><p><b><u>dom t</u>o edit</b></p>',
- start: 'u:contents()[0]->0',
- end: 'u:eq(1):contents()[0]->5',
- },
- },
- /* strikethrough */
- {
- name: "Click strikethrough: bold -> bold + strikethrough",
- content: '<p>dom not to edit</p><p><b>dom to edit</b></p>',
- start: 'b:contents()[0]->1',
- end: 'b:contents()[0]->5',
- do: async function () {
- await testUtils.dom.triggerEvents($strikethrough, ['mousedown', 'click']);
- },
- test: {
- content: '<p>dom not to edit</p><p><b>d<s>om t</s>o edit</b></p>',
- start: 's:contents()[0]->0',
- end: 's:contents()[0]->4',
- },
- },
- {
- name: "Click strikethrough: bold & normal -> strikethrough & bold + strikethrough (across paragraphs)",
- content: '<p>dom <b>to</b> edit</p><p><b>dom to edit</b></p>',
- start: 'p:contents()[0]->1',
- end: 'b:eq(1):contents()[0]->5',
- do: async function () {
- await testUtils.dom.triggerEvents($strikethrough, ['mousedown', 'click']);
- },
- test: {
- content: '<p>d<s>om <b>to</b> edit</s></p><p><b><s>dom t</s>o edit</b></p>',
- start: 's:contents()[0]->0',
- end: 's:eq(1):contents()[0]->5',
- },
- },
- /* superscript */
- {
- name: "Click superscript: bold -> bold + superscript",
- content: '<p>dom not to edit</p><p><b>dom to edit</b></p>',
- start: 'b:contents()[0]->1',
- end: 'b:contents()[0]->5',
- do: async function () {
- await testUtils.dom.triggerEvents($superscript, ['mousedown', 'click']);
- },
- test: {
- content: '<p>dom not to edit</p><p><b>d<sup>om t</sup>o edit</b></p>',
- start: 'sup:contents()[0]->0',
- end: 'sup:contents()[0]->4',
- },
- },
- {
- name: "Click superscript: bold & normal -> superscript & bold + superscript (across paragraphs)",
- content: '<p>dom <b>to</b> edit</p><p><b>dom to edit</b></p>',
- start: 'p:contents()[0]->1',
- end: 'b:eq(1):contents()[0]->5',
- do: async function () {
- await testUtils.dom.triggerEvents($superscript, ['mousedown', 'click']);
- },
- test: {
- content: '<p>d<sup>om <b>to</b> edit</sup></p><p><b><sup>dom t</sup>o edit</b></p>',
- start: 'sup:contents()[0]->0',
- end: 'sup:eq(1):contents()[0]->5',
- },
- },
- /* subscript */
- {
- name: "Click subscript: bold -> bold + subscript",
- content: '<p>dom not to edit</p><p><b>dom to edit</b></p>',
- start: 'b:contents()[0]->1',
- end: 'b:contents()[0]->5',
- do: async function () {
- await testUtils.dom.triggerEvents($subscript, ['mousedown', 'click']);
- },
- test: {
- content: '<p>dom not to edit</p><p><b>d<sub>om t</sub>o edit</b></p>',
- start: 'sub:contents()[0]->0',
- end: 'sub:contents()[0]->4',
- },
- },
- {
- name: "Click subscript: bold & normal -> subscript & bold + subscript (across paragraphs)",
- content: '<p>dom <b>to</b> edit</p><p><b>dom to edit</b></p>',
- start: 'p:contents()[0]->1',
- end: 'b:eq(1):contents()[0]->5',
- do: async function () {
- await testUtils.dom.triggerEvents($subscript, ['mousedown', 'click']);
- },
- test: {
- content: '<p>d<sub>om <b>to</b> edit</sub></p><p><b><sub>dom t</sub>o edit</b></p>',
- start: 'sub:contents()[0]->0',
- end: 'sub:eq(1):contents()[0]->5',
- },
- },
- /* REMOVE FONT STYLE */
- {
- name: "Click REMOVE FONT STYLE: bold -> normal",
- content: '<p>dom not to edit</p><p><b>dom to edit</b></p>',
- start: 'b:contents()[0]->1',
- end: 'b:contents()[0]->5',
- do: async function () {
- await testUtils.dom.triggerEvents($btnRemoveStyles, ['mousedown', 'click']);
- },
- test: {
- content: '<p>dom not to edit</p><p><b>d</b>om t<b>o edit</b></p>',
- 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: '<p>dom <b>t<i>o</i></b> e<u>dit</u></p><p><b><u>dom</u> to edit</b></p>',
- start: 'p:contents()[0]->1',
- end: 'u:eq(1):contents()[0]->3',
- do: async function () {
- await testUtils.dom.triggerEvents($btnRemoveStyles, ['mousedown', 'click']);
- },
- test: {
- content: '<p>dom to edit</p><p>dom<b>&nbsp;to edit</b></p>',
- start: 'p:contents()[0]->1',
- end: 'p:eq(1):contents()[0]->3',
- },
- },
- {
- name: "Click REMOVE FONT STYLE: complex -> normal",
- content: '<p>aaa<font style="background-color: rgb(255, 255, 0);">bbb</font></p><p><font style="color: rgb(255, 0, 0);">ccc</font></p>',
- start: 'p:contents()[0]->1',
- end: 'font:eq(1):contents()[0]->1',
- do: async function () {
- await testUtils.dom.triggerEvents($btnRemoveStyles, ['mousedown', 'click']);
- },
- test: {
- content: '<p>aaabbb</p><p>c<font style="color: rgb(255, 0, 0);">cc</font></p>',
- start: 'p:contents()[0]->1',
- end: 'p:eq(1):contents()[0]->1',
- },
- },
- {
- name: "Click REMOVE FONT STYLE: complex -> normal (with icon)",
- content: '<p>a<b>a</b>a<span class="bg-alpha text-alpha fa fa-heart" style="font-size: 10px;"></span>b<b><i>b</i>b</b></p>',
- start: 'p:contents()[0]->0',
- end: 'i:contents()[0]->1',
- do: async function () {
- await testUtils.dom.triggerEvents($btnRemoveStyles, ['mousedown', 'click']);
- },
- test: {
- content: '<p>aaa<span class="fa fa-heart"></span>bb<b>b</b></p>',
- start: 'p:contents()[0]->0',
- end: 'p:contents()[2]->2',
- },
- },
- /* COMPLEX */
- {
- name: "COMPLEX Click BOLD: italic -> italic bold (partial selection)",
- content: '<p>dom not to edit</p><p><i>dom to edit</i></p>',
- start: 'i:contents()[0]->1',
- end: 'i:contents()[0]->5',
- do: async function () {
- await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']);
- },
- test: {
- content: '<p>dom not to edit</p><p><i>d<b>om t</b>o edit</i></p>',
- start: 'b:contents()[0]->0',
- end: 'b:contents()[0]->4',
- },
- },
- {
- name: "COMPLEX Click BOLD then 'a': italic bold -> italic (across paragraphs)",
- content: '<p><b><i>dom to edit</i></b></p><p><i><b>dom to edit</b></i></p>',
- 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: '<p><b><i>d</i></b><i>om to edit</i></p><p><i>dom ta<b>o edit</b></i></p>',
- },
- },
- {
- name: "COMPLEX Click BOLD then 'a': bold italic -> italic (no selection)",
- content: '<p><b><i>dom to edit</i></b></p>',
- start: 'i:contents()[0]->4',
- do: async function () {
- await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']);
- weTestUtils.keydown('a', $editable, {
- firstDeselect: true,
- });
- },
- test: {
- content: '<p><b><i>dom </i></b><i>a</i><b><i>to edit</i></b></p>',
- },
- },
- {
- name: "COMPLEX Click BOLD then 'a': underlined italic -> underlined italic bold (across paragraphs)",
- content: '<p><u><i>dom to edit</i></u></p><p><i><u>dom to edit</u></i></p>',
- 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: '<p><u><i>d<b>om to edit</b></i></u></p><p><i><u><b>dom ta</b>o edit</u></i></p>',
- },
- },
- {
- name: "COMPLEX Click BOLD then 'a': underlined italic -> underlined italic bold (no selection)",
- content: '<p><u><i>dom to edit</i></u></p>',
- start: 'i:contents()[0]->1',
- do: async function () {
- await testUtils.dom.triggerEvents($btnBold, ['mousedown', 'click']);
- weTestUtils.keydown('a', $editable, {
- firstDeselect: true,
- });
- },
- test: {
- content: '<p><u><i>d<b>a</b>om to edit</i></u></p>',
- },
- },
- ];
-
- 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: '<p>dom not to edit</p><p>dom to edit</p>',
- 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: '<p>dom not to edit</p><p>d<font style="font-size: 18px;">om t</font>o edit</p>',
- start: 'font:contents()[0]->0',
- end: 'font:contents()[0]->4',
- },
- },
- {
- name: "Click DEFAULT: 18px -> default",
- content: '<p>dom not to edit</p><p><font style="font-size: 18px;">dom to edit</font></p>',
- 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: '<p>dom not to edit</p><p><font style="font-size: 18px;">d</font>om t<font style="font-size: 18px;">o edit</font></p>',
- start: 'p:eq(1):contents()[1]->0',
- end: 'p:eq(1):contents()[1]->4',
- },
- },
- {
- name: "Click 18: 26px -> 18px",
- content: '<p><font style="font-size: 26px;">dom to edit</font></p>',
- 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: '<p>' +
- '<font style="font-size: 26px;">d</font>' +
- '<font style="font-size: 18px;">om t</font>' +
- '<font style="font-size: 26px;">o edit</font></p>',
- start: 'font:eq(1):contents()[0]->0',
- end: 'font:eq(1):contents()[0]->4',
- },
- },
- {
- name: "Click 18 then 'a' (no selection): default -> 18px",
- content: '<p>dom not to edit</p><p>dom to edit</p>',
- 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: '<p>dom not to edit</p><p>d<font style="font-size: 18px;">a</font>om to edit</p>',
- start: 'font:contents()[0]->1',
- },
- },
- {
- name: "Click 18 then 'a' (no selection): 26px -> 18px",
- content: '<p><font style="font-size: 26px;">dom to edit</font></p>',
- 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: '<p>' +
- '<font style="font-size: 26px;">d</font>' +
- '<font style="font-size: 18px;">a</font>' +
- '<font style="font-size: 26px;">om to edit</font></p>',
- 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: '<p>dom not to edit</p><p>dom to edit</p>',
- 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: '<p>dom not to edit</p><p>d<font class="text-alpha">om t</font>o edit</p>',
- start: 'font:contents()[0]->0',
- end: 'font:contents()[0]->4',
- },
- },
- {
- name: "Click THEME COLORS - BLACK 25: alpha theme color & default -> black 25",
- content: '<p>dom not to edit</p><p>do<font class="text-alpha">m to </font>edit</p>',
- 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: '<p>dom not to edit</p><p>d<font class="text-black-25">om t</font><font class="text-alpha">o </font>edit</p>',
- start: 'font:contents()[0]->0',
- end: 'font:contents()[0]->4',
- },
- },
- {
- name: "Click COMMON COLORS - BLUE #0000FF: black 25 & default -> blue #0000FF",
- content: '<p>dom not to edit</p><p>do<font class="text-black-25">m to </font>edit</p>',
- 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: '<p>dom not to edit</p><p>d<font style="color: rgb(0, 0, 255);">om t</font><font class="text-black-25">o </font>edit</p>',
- start: 'font:contents()[0]->0',
- end: 'font:contents()[0]->4',
- },
- },
- {
- name: "Click RESET TO DEFAULT: black 25 & default -> default",
- content: '<p>dom not to edit</p><p>do<font class="text-black-25">m to </font>edit</p>',
- 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: '<p>dom not to edit</p><p>dom t<font class="text-black-25">o </font>edit</p>',
- 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: '<p>dom not to edit</p><p>do<font style="color: rgb(0, 0, 255);">m to </font>edit</p>',
- 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(),
- '<p>dom not to edit</p><p>d<font style="color: rgb(135, 90, 123);">om t</font><font style="color: rgb(0, 0, 255);">o </font>edit</p>',
- 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: '<p>dom to edit</p>',
- 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: '<p>d<font style="color: rgb(255, 0, 100);">om to</font> edit</p>',
- start: 'font:contents()[0]->0',
- end: 'font:contents()[0]->5',
- },
- },
- {
- name: "CUSTOM COLOR: change hue, saturation and lightness inputs",
- content: '<p>dom to edit</p>',
- 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: '<p>d<font style="color: rgb(153, 51, 90);">om to</font> edit</p>',
- start: 'font:contents()[0]->0',
- end: 'font:contents()[0]->5',
- },
- },
- {
- name: "CUSTOM COLOR: mousedown on area",
- content: '<p>dom to edit</p>',
- 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: '<p>d<font style="color: rgb(207, 175, 175);">om to</font> edit</p>',
- start: 'font:contents()[0]->0',
- end: 'font:contents()[0]->5',
- },
- },
- {
- name: "CUSTOM COLOR: mousedow on sliders",
- content: '<p>dom to edit</p>',
- 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: '<p>d<font style="color: rgba(131, 255, 0, 0.6);">om to</font> edit</p>',
- start: 'font:contents()[0]->0',
- end: 'font:contents()[0]->5',
- },
- },
- {
- name: "Apply a color on a fontawesome",
- content: '<p>dom <i class="fa fa-glass"/>not to edit</p>',
- 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: '<p>dom <i class="fa fa-glass" style="color: rgb(0, 0, 255);"></i>not to edit</p>',
- start: 'p->2',
- },
- },
- {
- name: "Apply a color on a font with text",
- content: '<p>dom <i class="fa fa-glass"/>not to edit</p>',
- 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: '<p>d<font style="color: rgb(0, 0, 255);">om&nbsp;</font><i class="fa fa-glass" style="color: rgb(0, 0, 255);"></i><font style="color: rgb(0, 0, 255);">not to</font> edit</p>',
- start: 'font:eq(0):contents()[0]->0',
- end: 'font:eq(1):contents()[0]->6',
- },
- },
- {
- name: "Apply color, then 'a' (no selection)",
- content: '<p>dom not to edit</p>',
- 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: '<p>d<font style="color: rgb(0, 0, 255);">a</font>om not to edit</p>',
- start: 'font:contents()[0]->1',
- },
- },
- {
- name: "Apply color on two ranges with the same color",
- content: '<p>do<br><span class="toto"> </span>m not to edit</p>',
- 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: '<p>d<font style="color: rgb(0, 0, 255);">o</font><br><span class="toto"> </span><font style="color: rgb(0, 0, 255);">m no</font>t t<font style=\"color: rgb(0, 0, 255);\">o e</font>dit</p>',
- 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: '<p>dom not to edit</p><p>dom to edit</p>',
- 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: '<p>dom not to edit</p><p>d<font class="bg-alpha">om t</font>o edit</p>',
- start: 'font:contents()[0]->0',
- end: 'font:contents()[0]->4',
- },
- },
- {
- name: "Click THEME COLORS - BLACK 25: alpha theme color & default -> black 25",
- content: '<p>dom not to edit</p><p>do<font class="bg-alpha">m to </font>edit</p>',
- 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: '<p>dom not to edit</p><p>d<font class="bg-black-25">om t</font><font class="bg-alpha">o </font>edit</p>',
- start: 'font:contents()[0]->0',
- end: 'font:contents()[0]->4',
- },
- },
- {
- name: "Click COMMON COLORS - BLUE #0000FF: black 25 & default -> blue #0000FF",
- content: '<p>dom not to edit</p><p>do<font class="bg-black-25">m to </font>edit</p>',
- 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: '<p>dom not to edit</p><p>d<font style="background-color: rgb(0, 0, 255);">om t</font><font class="bg-black-25">o </font>edit</p>',
- start: 'font:contents()[0]->0',
- end: 'font:contents()[0]->4',
- },
- },
- {
- name: "Click RESET TO DEFAULT: black 25 & default -> default",
- content: '<p>dom not to edit</p><p>do<font class="bg-black-25">m to </font>edit</p>',
- 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: '<p>dom not to edit</p><p>dom t<font class="bg-black-25">o </font>edit</p>',
- 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: '<p>dom not to edit</p><p>do<font style="background-color: rgb(0, 0, 255);">m to </font>edit</p>',
- 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(),
- '<p>dom not to edit</p><p>d<font style="background-color: rgb(135, 90, 123);">om t</font><font style="background-color: rgb(0, 0, 255);">o </font>edit</p>',
- 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: '<p>dom not to edit</p><p>dom to edit</p>',
- 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: '<p>dom not to edit</p><ul><li><p>dom to edit</p></li></ul>',
- start: 'p:eq(1):contents()[0]->1',
- end: 'p:eq(1):contents()[0]->5',
- },
- },
- {
- name: "Click UL: p -> ul (across paragraphs)",
- content: '<p>dom not to edit</p><p>dom to edit</p><p>dom to edit</p>',
- 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: '<p>dom not to edit</p><ul><li><p>dom to edit</p></li><li><p>dom to edit</p></li></ul>',
- start: 'p:eq(1):contents()[0]->1',
- end: 'p:eq(2):contents()[0]->5',
- },
- },
- {
- name: "Click UL: ul -> p",
- content: '<p>dom not to edit</p><ul><li><p>dom to edit</p></li></ul>',
- 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: '<p>dom not to edit</p><p>dom to edit</p>',
- start: 'p:eq(1):contents()[0]->1',
- end: 'p:eq(1):contents()[0]->5',
- },
- },
- {
- name: "Click UL: p -> ul (across li's)",
- content: '<p>dom not to edit</p><ul><li><p>dom to edit</p></li><li><p>dom to edit</p></li></ul>',
- 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: '<p>dom not to edit</p><p>dom to edit</p><p>dom to edit</p>',
- start: 'p:eq(1):contents()[0]->1',
- end: 'p:eq(2):contents()[0]->5',
- },
- },
- {
- name: "Click UL: ul -> p (from second li)",
- content: '<p>dom not to edit</p><ul><li><p>xxx</p></li><li><p>dom to edit</p></li></ul>',
- 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: '<p>dom not to edit</p><ul><li><p>xxx</p></li></ul><p>dom to edit</p>',
- start: 'p:eq(2):contents()[0]->1',
- end: 'p:eq(2):contents()[0]->5',
- },
- },
- // Conversion from OL
- {
- name: "Click UL: ol -> ul",
- content: '<p>dom not to edit</p><ol><li><p>dom to edit</p></li></ol>',
- start: 'p:eq(1):contents()[0]->1',
- end: 'p:eq(1):contents()[0]->5',
- do: function () {
- $btnUL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ul><li><p>dom to edit</p></li></ul>',
- start: 'p:eq(1):contents()[0]->1',
- end: 'p:eq(1):contents()[0]->5',
- },
- },
- {
- name: "Click UL: ol -> ul (across li's)",
- content: '<p>dom not to edit</p><ol><li><p>dom to edit</p></li><li><p>dom to edit</p></li></ol>',
- start: 'p:eq(1):contents()[0]->1',
- end: 'p:eq(2):contents()[0]->5',
- do: function () {
- $btnUL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ul><li><p>dom to edit</p></li><li><p>dom to edit</p></li></ul>',
- start: 'p:eq(1):contents()[0]->1',
- end: 'p:eq(2):contents()[0]->5',
- },
- },
- {
- name: "Click UL: ol -> ul (from second li)",
- content: '<p>dom not to edit</p><ol><li><p>xxx</p></li><li><p>dom to edit</p></li></ol>',
- start: 'li:eq(1) p:contents()[0]->1',
- end: 'li:eq(1) p:contents()[0]->5',
- do: function () {
- $btnUL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ol><li><p>xxx</p></li></ol><ul><li><p>dom to edit</p></li></ul>',
- 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: '<p>dom not to edit</p><ul><li><p>xxx</p></li><ol><li><p>dom to edit</p></li></ol></ul>',
- start: 'li:eq(1) p:contents()[0]->1',
- end: 'li:eq(1) p:contents()[0]->5',
- do: function () {
- $btnUL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ul><li><p>xxx</p></li><ul><li><p>dom to edit</p></li></ul></ul>',
- 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: '<p>dom not to edit</p><ul><li><p>xxx</p></li><ol><li><p>dom to edit 1</p></li><li><p>dom to edit 2</p></li></ol></ul>',
- start: 'li:eq(1) p:contents()[0]->1',
- end: 'li:eq(2) p:contents()[0]->5',
- do: function () {
- $btnUL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ul><li><p>xxx</p></li><ul><li><p>dom to edit 1</p></li><li><p>dom to edit 2</p></li></ul></ul>',
- 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: '<p>dom not to edit</p><ul><li><p>xxx</p></li><ol><li><p>dom not to edit</p></li><li><p>dom to edit</p></li><li><p>dom not to edit</p></li></ol></ul>',
- start: 'li:eq(2) p:contents()[0]->1',
- end: 'li:eq(2) p:contents()[0]->5',
- do: function () {
- $btnUL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ul><li><p>xxx</p></li><ol><li><p>dom not to edit</p></li></ol><ul><li><p>dom to edit</p></li></ul><ol><li><p>dom not to edit</p></li></ol></ul>',
- 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: '<p>dom not to edit</p><ul class="o_checklist"><li><p>dom to edit</p></li></ul>',
- start: 'p:eq(1):contents()[0]->1',
- end: 'p:eq(1):contents()[0]->5',
- do: function () {
- $btnUL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ul><li><p>dom to edit</p></li></ul>',
- 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: '<p>dom not to edit</p><ul class="o_checklist"><li><p>dom to edit</p></li><li><p>dom to edit</p></li></ul>',
- start: 'p:eq(1):contents()[0]->1',
- end: 'p:eq(2):contents()[0]->5',
- do: function () {
- $btnUL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ul><li><p>dom to edit</p></li><li><p>dom to edit</p></li></ul>',
- 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: '<p>dom not to edit</p><ul class="o_checklist"><li><p>xxx</p></li><li><p>dom to edit</p></li></ul>',
- start: 'li:eq(1) p:contents()[0]->1',
- end: 'li:eq(1) p:contents()[0]->5',
- do: function () {
- $btnUL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ul class="o_checklist"><li><p>xxx</p></li></ul><ul><li><p>dom to edit</p></li></ul>',
- 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: '<p>dom not to edit</p><ul><li><p>xxx</p></li><ul class="o_checklist"><li><p>dom to edit</p></li></ul></ul>',
- start: 'li:eq(1) p:contents()[0]->1',
- end: 'li:eq(1) p:contents()[0]->5',
- do: function () {
- $btnUL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ul><li><p>xxx</p></li><ul><li><p>dom to edit</p></li></ul></ul>',
- 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: '<p>dom not to edit</p><ul><li><p>xxx</p></li><ul class="o_checklist"><li><p>dom to edit 1</p></li><li><p>dom to edit 2</p></li></ul></ul>',
- start: 'li:eq(1) p:contents()[0]->1',
- end: 'li:eq(2) p:contents()[0]->5',
- do: function () {
- $btnUL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ul><li><p>xxx</p></li><ul><li><p>dom to edit 1</p></li><li><p>dom to edit 2</p></li></ul></ul>',
- 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: '<p>dom not to edit</p><ul><li><p>xxx</p></li><ul class="o_checklist"><li><p>dom not to edit</p></li><li><p>dom to edit</p></li><li><p>dom not to edit</p></li></ul></ul>',
- start: 'li:eq(2) p:contents()[0]->1',
- end: 'li:eq(2) p:contents()[0]->5',
- do: function () {
- $btnUL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ul><li><p>xxx</p></li><ul class="o_checklist"><li><p>dom not to edit</p></li></ul><ul><li><p>dom to edit</p></li></ul><ul class="o_checklist"><li><p>dom not to edit</p></li></ul></ul>',
- 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: '<p>dom not to edit</p><p>dom to edit</p>',
- 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: '<p>dom not to edit</p><ol><li><p>dom to edit</p></li></ol>',
- start: 'p:eq(1):contents()[0]->1',
- end: 'p:eq(1):contents()[0]->5',
- },
- },
- {
- name: "Click OL: p -> ol (across paragraphs)",
- content: '<p>dom not to edit</p><p>dom to edit</p><p>dom to edit</p>',
- 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: '<p>dom not to edit</p><ol><li><p>dom to edit</p></li><li><p>dom to edit</p></li></ol>',
- start: 'p:eq(1):contents()[0]->1',
- end: 'p:eq(2):contents()[0]->5',
- },
- },
- {
- name: "Click OL: ol -> p",
- content: '<p>dom not to edit</p><ol><li><p>dom to edit</p></li></ol>',
- 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: '<p>dom not to edit</p><p>dom to edit</p>',
- start: 'p:eq(1):contents()[0]->1',
- end: 'p:eq(1):contents()[0]->5',
- },
- },
- {
- name: "Click OL: p -> ol (across li's)",
- content: '<p>dom not to edit</p><ol><li><p>dom to edit</p></li><li><p>dom to edit</p></li></ol>',
- 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: '<p>dom not to edit</p><p>dom to edit</p><p>dom to edit</p>',
- start: 'p:eq(1):contents()[0]->1',
- end: 'p:eq(2):contents()[0]->5',
- },
- },
- {
- name: "Click OL: ol -> p (from second li) (2)",
- content: '<p>dom not to edit</p><ol><li><p>dom to edit</p></li><li><p>dom to edit</p></li></ol>',
- start: 'li:eq(0) p:contents()[0]->1',
- do: async function () {
- await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']);
- },
- test: {
- content: '<p>dom not to edit</p><p>dom to edit</p><ol><li><p>dom to edit</p></li></ol>',
- start: 'p:eq(1):contents()[0]->1',
- },
- },
- {
- name: "Click OL: ol -> p (from second li)",
- content: '<p>dom not to edit</p><ol><li><p>dom to edit</p></li><li><p>dom to edit</p></li></ol>',
- 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: '<p>dom not to edit</p><p>dom to edit</p><ol><li><p>dom to edit</p></li></ol>',
- 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: '<p>a</p>' +
- '<ul>' +
- '<li><p>b</p></li>' +
- '<ul>' +
- '<li><p>c</p></li>' +
- '<li><p>d</p></li>' +
- '</ul>' +
- '<li><p>e</p></li>' +
- '</ul>',
- 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: '<p>a</p>' +
- '<ul>' +
- '<li><p>b</p></li>' +
- '<li><p>c</p></li>' +
- '<ul>' +
- '<li><p>d</p></li>' +
- '</ul>' +
- '<li><p>e</p></li>' +
- '</ul>',
- start: 'ul li:eq(1) p:contents()[0]->1',
- },
- },
- {
- name: "Click OL in empty table cell in div",
- content: '<div>' +
- '<p>a</p>' +
- '<table>' +
- '<tbody>' +
- '<tr>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '</tr>' +
- '<tr>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '</tr>' +
- '</tbody>' +
- '</table>' +
- '</div>',
- start: 'tr:eq(0) td:eq(1)->1',
- do: async function () {
- await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']);
- },
- test: {
- content: '<div>' +
- '<p>a</p>' +
- '<table>' +
- '<tbody>' +
- '<tr>' +
- '<td><br></td>' +
- '<td><ol><li><p><br></p></li></ol></td>' +
- '<td><br></td>' +
- '</tr>' +
- '<tr>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '</tr>' +
- '</tbody>' +
- '</table>' +
- '</div>',
- start: 'tr:eq(0) td:eq(1) br->0',
- },
- },
- {
- name: "Click OL in empty table cell in div (2)",
- content: '<div>' +
- '<p>a</p>' +
- '<table>' +
- '<tbody>' +
- '<tr>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '</tr>' +
- '<tr>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '</tr>' +
- '</tbody>' +
- '</table>' +
- '</div>',
- start: 'tr:eq(0) td:eq(1) br->0',
- do: async function () {
- await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']);
- },
- test: {
- content: '<div>' +
- '<p>a</p>' +
- '<table>' +
- '<tbody>' +
- '<tr>' +
- '<td><br></td>' +
- '<td><ol><li><p><br></p></li></ol></td>' +
- '<td><br></td>' +
- '</tr>' +
- '<tr>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '</tr>' +
- '</tbody>' +
- '</table>' +
- '</div>',
- start: 'tr:eq(0) td:eq(1) br->0',
- },
- },
- {
- name: "Click OL in empty table cell in div (3)",
- content: '<div>' +
- '<p>a</p>' +
- '<table>' +
- '<tbody>' +
- '<tr>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '</tr>' +
- '<tr>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '</tr>' +
- '</tbody>' +
- '</table>' +
- '</div>',
- start: 'tr:eq(0) td:eq(1)->0',
- do: async function () {
- await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']);
- },
- test: {
- content: '<div>' +
- '<p>a</p>' +
- '<table>' +
- '<tbody>' +
- '<tr>' +
- '<td><br></td>' +
- '<td><ol><li><p><br></p></li></ol></td>' +
- '<td><br></td>' +
- '</tr>' +
- '<tr>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '</tr>' +
- '</tbody>' +
- '</table>' +
- '</div>',
- start: 'tr:eq(0) td:eq(1) br->0',
- },
- },
- {
- name: "Click OL in table cell in div",
- content: '<div>' +
- '<p>a</p>' +
- '<table>' +
- '<tbody>' +
- '<tr>' +
- '<td><br></td>' +
- '<td>aaa</td>' +
- '<td><br></td>' +
- '</tr>' +
- '<tr>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '</tr>' +
- '</tbody>' +
- '</table>' +
- '</div>',
- start: 'tr:eq(0) td:eq(1):contents(0)->1',
- do: async function () {
- await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']);
- },
- test: {
- content: '<div>' +
- '<p>a</p>' +
- '<table>' +
- '<tbody>' +
- '<tr>' +
- '<td><br></td>' +
- '<td><ol><li><p>aaa</p></li></ol></td>' +
- '<td><br></td>' +
- '</tr>' +
- '<tr>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '</tr>' +
- '</tbody>' +
- '</table>' +
- '</div>',
- start: 'td li p:contents(0)->1',
- },
- },
- {
- name: "Click OL on image in table cell in div",
- content: '<div>' +
- '<p>a</p>' +
- '<table>' +
- '<tbody>' +
- '<tr>' +
- '<td><br></td>' +
- '<td><img data-src="/web_editor/static/src/img/transparent.png"></td>' +
- '<td><br></td>' +
- '</tr>' +
- '<tr>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '</tr>' +
- '</tbody>' +
- '</table>' +
- '</div>',
- start: 'img->0',
- do: async function () {
- await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']);
- },
- test: {
- content: '<div>' +
- '<p>a</p>' +
- '<table>' +
- '<tbody>' +
- '<tr>' +
- '<td><br></td>' +
- '<td><ol><li><img data-src="/web_editor/static/src/img/transparent.png"></li></ol></td>' +
- '<td><br></td>' +
- '</tr>' +
- '<tr>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '<td><br></td>' +
- '</tr>' +
- '</tbody>' +
- '</table>' +
- '</div>',
- start: 'td li->1',
- },
- },
- {
- name: "Click OL with selected LI in OL",
- content: '<p>x</p>' +
- '<ol>' +
- '<li><p>aaa</p></li>' +
- '<li><p>bbb</p></li>' +
- '<li><p>ccc</p></li>' +
- '<li><p>ddd</p></li>' +
- '</ol>' +
- '<p>y</p>',
- 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: '<p>x</p>' +
- '<ol>' +
- '<li><p>aaa</p></li>' +
- '</ol>' +
- '<p>bbb</p>' +
- '<p>ccc</p>' +
- '<ol>' +
- '<li><p>ddd</p></li>' +
- '</ol>' +
- '<p>y</p>',
- start: 'p:eq(2):contents(0)->1',
- end: 'p:eq(3):contents(0)->1',
- },
- },
- {
- name: "Click OL with selected LI in UL",
- content: '<p>x</p>' +
- '<ul>' +
- '<li><p>aaa</p></li>' +
- '<li><p>bbb</p></li>' +
- '<li><p>ccc</p></li>' +
- '<li><p>ddd</p></li>' +
- '</ul>' +
- '<p>y</p>',
- 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: '<p>x</p>' +
- '<ul>' +
- '<li><p>aaa</p></li>' +
- '</ul>' +
- '<ol>' +
- '<li><p>bbb</p></li>' +
- '<li><p>ccc</p></li>' +
- '</ol>' +
- '<ul>' +
- '<li><p>ddd</p></li>' +
- '</ul>' +
- '<p>y</p>',
- start: 'p:eq(2):contents(0)->1',
- end: 'p:eq(3):contents(0)->1',
- },
- },
- {
- name: "Click OL after ENTER in p > b",
- content: "<p><b>dom to edit</b></p>",
- 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: "<p><b>dom to edit</b></p><ol><li><p><b>a</b></p></li></ol>",
- start: 'b:eq(1):contents(0)->1',
- },
- },
- {
- name: "Click OL in font in H1 (with link) in div",
- content: '<div><h1><font style="font-size: 62px;">table of contents <a href="p23">p23</a> (cfr: 34)</font></h1></div>',
- start: 'font:contents(0)->11',
- do: async function () {
- await testUtils.dom.triggerEvents($btnOL, ['mousedown', 'click']);
- },
- test: {
- content: '<div><ol><li><h1><font style="font-size: 62px;">table of contents <a href="p23">p23</a> (cfr: 34)</font></h1></li></ol></div>',
- start: 'font:contents(0)->11',
- },
- },
- // Conversion from UL
- {
- name: "Click OL: ul -> ol",
- content: '<p>dom not to edit</p><ul><li><p>dom to edit</p></li></ul>',
- start: 'p:eq(1):contents()[0]->1',
- end: 'p:eq(1):contents()[0]->5',
- do: function () {
- $btnOL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ol><li><p>dom to edit</p></li></ol>',
- start: 'p:eq(1):contents()[0]->1',
- end: 'p:eq(1):contents()[0]->5',
- },
- },
- {
- name: "Click OL: ul -> ol (across li's)",
- content: '<p>dom not to edit</p><ul><li><p>dom to edit</p></li><li><p>dom to edit</p></li></ul>',
- start: 'p:eq(1):contents()[0]->1',
- end: 'p:eq(2):contents()[0]->5',
- do: function () {
- $btnOL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ol><li><p>dom to edit</p></li><li><p>dom to edit</p></li></ol>',
- start: 'p:eq(1):contents()[0]->1',
- end: 'p:eq(2):contents()[0]->5',
- },
- },
- {
- name: "Click OL: ul -> ol (from second li)",
- content: '<p>dom not to edit</p><ul><li><p>xxx</p></li><li><p>dom to edit</p></li></ul>',
- start: 'li:eq(1) p:contents()[0]->1',
- end: 'li:eq(1) p:contents()[0]->5',
- do: function () {
- $btnOL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ul><li><p>xxx</p></li></ul><ol><li><p>dom to edit</p></li></ol>',
- 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: '<p>dom not to edit</p><ol><li><p>xxx</p></li><ul><li><p>dom to edit</p></li></ul></ol>',
- start: 'li:eq(1) p:contents()[0]->1',
- end: 'li:eq(1) p:contents()[0]->5',
- do: function () {
- $btnOL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ol><li><p>xxx</p></li><ol><li><p>dom to edit</p></li></ol></ol>',
- 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: '<p>dom not to edit</p><ol><li><p>xxx</p></li><ul><li><p>dom to edit 1</p></li><li><p>dom to edit 2</p></li></ul></ol>',
- start: 'li:eq(1) p:contents()[0]->1',
- end: 'li:eq(2) p:contents()[0]->5',
- do: function () {
- $btnOL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ol><li><p>xxx</p></li><ol><li><p>dom to edit 1</p></li><li><p>dom to edit 2</p></li></ol></ol>',
- 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: '<p>dom not to edit</p><ol><li><p>xxx</p></li><ul><li><p>dom not to edit</p></li><li><p>dom to edit</p></li><li><p>dom not to edit</p></li></ul></ol>',
- start: 'li:eq(2) p:contents()[0]->1',
- end: 'li:eq(2) p:contents()[0]->5',
- do: function () {
- $btnOL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ol><li><p>xxx</p></li><ul><li><p>dom not to edit</p></li></ul><ol><li><p>dom to edit</p></li></ol><ul><li><p>dom not to edit</p></li></ul></ol>',
- 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: '<p>dom not to edit</p><ul class="o_checklist"><li><p>dom to edit</p></li></ul>',
- start: 'p:eq(1):contents()[0]->1',
- end: 'p:eq(1):contents()[0]->5',
- do: function () {
- $btnOL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ol><li><p>dom to edit</p></li></ol>',
- 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: '<p>dom not to edit</p><ul class="o_checklist"><li><p>dom to edit</p></li><li><p>dom to edit</p></li></ul>',
- start: 'p:eq(1):contents()[0]->1',
- end: 'p:eq(2):contents()[0]->5',
- do: function () {
- $btnOL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ol><li><p>dom to edit</p></li><li><p>dom to edit</p></li></ol>',
- 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: '<p>dom not to edit</p><ul class="o_checklist"><li><p>xxx</p></li><li><p>dom to edit</p></li></ul>',
- start: 'li:eq(1) p:contents()[0]->1',
- end: 'li:eq(1) p:contents()[0]->5',
- do: function () {
- $btnOL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ul class="o_checklist"><li><p>xxx</p></li></ul><ol><li><p>dom to edit</p></li></ol>',
- 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: '<p>dom not to edit</p><ol><li><p>xxx</p></li><ul class="o_checklist"><li><p>dom to edit</p></li></ul></ol>',
- start: 'li:eq(1) p:contents()[0]->1',
- end: 'li:eq(1) p:contents()[0]->5',
- do: function () {
- $btnOL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ol><li><p>xxx</p></li><ol><li><p>dom to edit</p></li></ol></ol>',
- 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: '<p>dom not to edit</p><ul><li><p>xxx</p></li><ul class="o_checklist"><li><p>dom to edit 1</p></li><li><p>dom to edit 2</p></li></ul></ul>',
- start: 'li:eq(1) p:contents()[0]->1',
- end: 'li:eq(2) p:contents()[0]->5',
- do: function () {
- $btnOL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ul><li><p>xxx</p></li><ol><li><p>dom to edit 1</p></li><li><p>dom to edit 2</p></li></ol></ul>',
- 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: '<p>dom not to edit</p><ul><li><p>xxx</p></li><ul class="o_checklist"><li><p>dom not to edit</p></li><li><p>dom to edit</p></li><li><p>dom not to edit</p></li></ul></ul>',
- start: 'li:eq(2) p:contents()[0]->1',
- end: 'li:eq(2) p:contents()[0]->5',
- do: function () {
- $btnOL.mousedown().click();
- },
- test: {
- content: '<p>dom not to edit</p><ul><li><p>xxx</p></li><ul class="o_checklist"><li><p>dom not to edit</p></li></ul><ol><li><p>dom to edit</p></li></ol><ul class="o_checklist"><li><p>dom not to edit</p></li></ul></ul>',
- 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: '<p>dom not to edit</p><p>dom to edit</p>',
- 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: '<p>dom not to edit</p><p>dom to edit</p>',
- start: 'p:eq(1):contents()[0]->1',
- },
- },
- {
- name: "Click ALIGN LEFT: p (parent align right) -> p align left (does nothing)",
- content: '<div style="text-align: right;"><p>dom not to edit</p><p>dom to edit</p></div>',
- 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: '<div style="text-align: right;"><p>dom not to edit</p><p style="text-align: left;">dom to edit</p></div>',
- 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: '<div style="text-align: left;"><p>dom not to edit</p><p>dom to edit</p></div>',
- 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: '<div style="text-align: left;"><p>dom not to edit</p><p>dom to edit</p></div>',
- 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: '<p>dom not to edit</p><p style="text-align: justify;">dom to edit</p><p>dom to edit</p>',
- 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: '<p>dom not to edit</p><p style="text-align: right;">dom to edit</p><p style="text-align: right;">dom to edit</p>',
- 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: '<p>dom not to edit</p><p>dom to edit</p>',
- 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: '<p>dom not to edit</p><p style="text-align: center;">dom to edit</p>',
- start: 'p:eq(1):contents()[0]->1',
- },
- },
- {
- name: "Click ALIGN CENTER: p align left & default -> p align center (across paragraphs)",
- content: '<p>dom not to edit</p><p style="text-align: left;">dom to edit</p><p>dom to edit</p>',
- 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: '<p>dom not to edit</p><p style="text-align: center;">dom to edit</p><p style="text-align: center;">dom to edit</p>',
- 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: '<p>dom not to edit</p><p style="text-align: center;">dom to edit</p>',
- 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: '<p>dom not to edit</p><p style="text-align: right;">dom to edit</p>',
- start: 'p:eq(1):contents()[0]->1',
- },
- },
- {
- name: "Click ALIGN RIGHT: p align center & default -> p align right (across paragraphs)",
- content: '<p>dom not to edit</p><p style="text-align: center;">dom to edit</p><p>dom to edit</p>',
- 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: '<p>dom not to edit</p><p style="text-align: right;">dom to edit</p><p style="text-align: right;">dom to edit</p>',
- 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: '<p>dom not to edit</p><p style="text-align: right;">dom to edit</p>',
- 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: '<p>dom not to edit</p><p style="text-align: justify;">dom to edit</p>',
- start: 'p:eq(1):contents()[0]->1',
- },
- },
- {
- name: "Click ALIGN JUSTIFY: p align right & default -> p align justify (across paragraphs)",
- content: '<p>dom not to edit</p><p style="text-align: right;">dom to edit</p><p>dom to edit</p>',
- 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: '<p>dom not to edit</p><p style="text-align: justify;">dom to edit</p><p style="text-align: justify;">dom to edit</p>',
- 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: '<p>dom to edit</p>',
- start: 'p:contents()[0]->1',
- do: async function () {
- await testUtils.dom.triggerEvents($dropdownPara, ['mousedown', 'click']);
- await testUtils.dom.triggerEvents($btnIndent, ['mousedown', 'click']);
- },
- test: {
- content: '<p style="margin-left: 1.5em;">dom to edit</p>',
- start: 'p:contents()[0]->1',
- },
- },
- {
- name: "Click INDENT: li -> indented li",
- content: '<ul><li><p>dom</p></li><li><p>to edit</p></li></ul>',
- 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: '<ul><li><p>dom</p></li><li class="o_indent"><ul><li><p>to edit</p></li></ul></li></ul>',
- start: 'p:eq(1):contents()[0]->1',
- },
- },
- {
- name: "Click INDENT: li -> indented li",
- content: '<p>aaa</p><p>bbb</p><p>ccc</p><p>ddd</p>',
- start: 'p:eq(1):contents()[0]->0',
- end: 'p:eq(3):contents()[0]->3',
- do: function () {
- $dropdownPara.mousedown().click();
- $btnIndent.mousedown().click();
- },
- test: {
- content: '<p>aaa</p><p style="margin-left: 1.5em;">bbb</p><p style="margin-left: 1.5em;">ccc</p><p style="margin-left: 1.5em;">ddd</p>',
- start: 'p:eq(1):contents()[0]->0',
- end: 'p:eq(3):contents()[0]->3',
- },
- },
- /* OUTDENT */
- {
- name: "Click OUTDENT: indented p -> p",
- content: '<p style="margin-left: 1.5em;">dom to edit</p>',
- start: 'p:contents()[0]->1',
- do: async function () {
- await testUtils.dom.triggerEvents($dropdownPara, ['mousedown', 'click']);
- await testUtils.dom.triggerEvents($btnOutdent, ['mousedown', 'click']);
- },
- test: {
- content: '<p>dom to edit</p>',
- start: 'p:contents()[0]->1',
- },
- },
- {
- name: "Click OUTDENT: indented li -> li",
- content: '<ul><li><p>dom</p></li><li><ul><li><p>to edit</p></li></ul></li></ul>',
- 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: '<ul><li><p>dom</p></li><li><p>to edit</p></li></ul>',
- start: 'p:eq(1):contents()[0]->1',
- },
- },
- {
- name: "Click OUTDENT: indented li -> li (2)",
- content: '<ul><li><p>dom</p></li><ul><li><p>to edit</p></li></ul></ul>',
- 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: '<ul><li><p>dom</p></li><li><p>to edit</p></li></ul>',
- start: 'p:eq(1):contents()[0]->1',
- },
- },
- {
- name: "Click OUTDENT on LI in OL in OL",
- content: '<p>x</p>' +
- '<ol>' +
- '<li><p>aaa</p></li>' +
- '<li><ol>' +
- '<li><p>bbb</p></li>' +
- '<li><p>ccc</p></li>' +
- '<li><p>ddd</p></li>' +
- '</ol></li>' +
- '<li><p>eee</p></li>' +
- '</ol>' +
- '<p>y</p>',
- 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: '<p>x</p>' +
- '<ol>' +
- '<li><p>aaa</p></li>' +
- '<li><ol>' +
- '<li><p>bbb</p></li>' +
- '</ol></li>' +
- '<li><p>ccc</p></li>' +
- '<li><ol>' +
- '<li><p>ddd</p></li>' +
- '</ol></li>' +
- '<li><p>eee</p></li>' +
- '</ol>' +
- '<p>y</p>',
- start: 'ol:first > li:eq(2) p:contents(0)->1',
- },
- },
- {
- name: "Click OUTDENT on LI in OL in OL (2)",
- content: '<p>x</p>' +
- '<ol>' +
- '<li><p>aaa</p></li>' +
- '<ol>' +
- '<li><p>bbb</p></li>' +
- '<li><p>ccc</p></li>' +
- '<li><p>ddd</p></li>' +
- '</ol>' +
- '<li><p>eee</p></li>' +
- '</ol>' +
- '<p>y</p>',
- 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: '<p>x</p>' +
- '<ol>' +
- '<li><p>aaa</p></li>' +
- '<ol>' +
- '<li><p>bbb</p></li>' +
- '</ol>' +
- '<li><p>ccc</p></li>' +
- '<ol>' +
- '<li><p>ddd</p></li>' +
- '</ol>' +
- '<li><p>eee</p></li>' +
- '</ol>' +
- '<p>y</p>',
- start: 'li:eq(2) p:contents(0)->1',
- },
- },
- {
- name: "Click OUTDENT on LI in OL",
- content:
- '<ol>' +
- '<li><p>aaa</p></li>' +
- '<li><p>bbb</p></li>' +
- '<li><p>ccc</p></li>' +
- '</ol>',
- 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:
- '<ol>' +
- '<li><p>aaa</p></li>' +
- '</ol>' +
- '<p>bbb</p>' +
- '<ol>' +
- '<li><p>ccc</p></li>' +
- '</ol>',
- start: 'p:eq(1):contents(0)->1',
- },
- },
- {
- name: "Click OUTDENT on P with indent in a LI (must outdent the p)",
- content:
- '<ul>' +
- '<li>' +
- '<ul>' +
- '<li>' +
- '<p style="margin-left: 1.5em;">dom</p>' +
- '</li>' +
- '</ul>' +
- '</li>' +
- '</ul>',
- start: 'p:contents(0)->1',
- do: async function () {
- await testUtils.dom.triggerEvents($dropdownPara, ['mousedown', 'click']);
- await testUtils.dom.triggerEvents($btnOutdent, ['mousedown', 'click']);
- },
- test: {
- content:
- '<ul>' +
- '<li>' +
- '<ul>' +
- '<li>' +
- '<p>dom</p>' +
- '</li>' +
- '</ul>' +
- '</li>' +
- '</ul>',
- 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: '<p>x</p>' +
- '<ul class="o_checklist">' +
- '<li><p>aaa</p></li>' +
- '<li>' +
- '<ul class="o_checklist">' +
- '<li><p>bbb</p></li>' +
- '<li><p>ccc</p></li>' +
- '<li><p>ddd</p></li>' +
- '</ul>' +
- '</li>' +
- '<li><p>eee</p></li>' +
- '</ul>' +
- '<p>y</p>',
- do: async function () {
- var $li = $editable.find('li:first');
- $li.trigger($.Event('mousedown', {
- offsetX: -10,
- }));
- },
- test: {
- content: '<p>x</p>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>aaa</p></li>' +
- '<li>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>bbb</p></li>' +
- '<li class="o_checked"><p>ccc</p></li>' +
- '<li class="o_checked"><p>ddd</p></li>' +
- '</ul>' +
- '</li>' +
- '<li><p>eee</p></li>' +
- '</ul>' +
- '<p>y</p>',
- },
- },
- {
- name: "check checkbox in checklist with children (2)",
- content: '<p>x</p>' +
- '<ul class="o_checklist">' +
- '<li><p>aaa</p></li>' +
- '<ul class="o_checklist">' +
- '<li><p>bbb</p></li>' +
- '<li><p>ccc</p></li>' +
- '<li><p>ddd</p></li>' +
- '</ul>' +
- '<li><p>eee</p></li>' +
- '</ul>' +
- '<p>y</p>',
- do: async function () {
- var $li = $editable.find('li:first');
- $li.trigger($.Event('mousedown', {
- offsetX: -10,
- }));
- },
- test: {
- content: '<p>x</p>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>aaa</p></li>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>bbb</p></li>' +
- '<li class="o_checked"><p>ccc</p></li>' +
- '<li class="o_checked"><p>ddd</p></li>' +
- '</ul>' +
- '<li><p>eee</p></li>' +
- '</ul>' +
- '<p>y</p>',
- },
- },
- {
- name: "uncheck checkbox in checklist with children",
- content: '<p>x</p>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>aaa</p></li>' +
- '<li>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>bbb</p></li>' +
- '<li class="o_checked"><p>ccc</p></li>' +
- '<li class="o_checked"><p>ddd</p></li>' +
- '</ul>' +
- '</li>' +
- '<li><p>eee</p></li>' +
- '</ul>' +
- '<p>y</p>',
- do: async function () {
- var $li = $editable.find('li:first');
- $li.trigger($.Event('mousedown', {
- offsetX: -10,
- }));
- },
- test: {
- content: '<p>x</p>' +
- '<ul class="o_checklist">' +
- '<li><p>aaa</p></li>' +
- '<li>' +
- '<ul class="o_checklist">' +
- '<li><p>bbb</p></li>' +
- '<li><p>ccc</p></li>' +
- '<li><p>ddd</p></li>' +
- '</ul>' +
- '</li>' +
- '<li><p>eee</p></li>' +
- '</ul>' +
- '<p>y</p>',
- },
- },
- {
- name: "uncheck checkbox in checklist with children (2)",
- content: '<p>x</p>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>aaa</p></li>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>bbb</p></li>' +
- '<li class="o_checked"><p>ccc</p></li>' +
- '<li class="o_checked"><p>ddd</p></li>' +
- '</ul>' +
- '<li><p>eee</p></li>' +
- '</ul>' +
- '<p>y</p>',
- do: async function () {
- var $li = $editable.find('li:first');
- $li.trigger($.Event('mousedown', {
- offsetX: -10,
- }));
- },
- test: {
- content: '<p>x</p>' +
- '<ul class="o_checklist">' +
- '<li><p>aaa</p></li>' +
- '<ul class="o_checklist">' +
- '<li><p>bbb</p></li>' +
- '<li><p>ccc</p></li>' +
- '<li><p>ddd</p></li>' +
- '</ul>' +
- '<li><p>eee</p></li>' +
- '</ul>' +
- '<p>y</p>',
- },
- },
- {
- name: "uncheck checkbox in checklist in checklist",
- content: '<p>x</p>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>aaa</p></li>' +
- '<li>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>bbb</p></li>' +
- '<li class="o_checked"><p>ccc</p></li>' +
- '<li class="o_checked"><p>ddd</p></li>' +
- '</ul>' +
- '</li>' +
- '<li><p>eee</p></li>' +
- '</ul>' +
- '<p>y</p>',
- do: async function () {
- var $li = $editable.find('ul ul li:eq(1)');
- $li.trigger($.Event('mousedown', {
- offsetX: -10,
- }));
- },
- test: {
- content: '<p>x</p>' +
- '<ul class="o_checklist">' +
- '<li><p>aaa</p></li>' +
- '<li>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>bbb</p></li>' +
- '<li><p>ccc</p></li>' +
- '<li class="o_checked"><p>ddd</p></li>' +
- '</ul>' +
- '</li>' +
- '<li><p>eee</p></li>' +
- '</ul>' +
- '<p>y</p>',
- },
- },
- {
- name: "uncheck checkbox in checklist in checklist (2)",
- content: '<p>x</p>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>aaa</p></li>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>bbb</p></li>' +
- '<li class="o_checked"><p>ccc</p></li>' +
- '<li class="o_checked"><p>ddd</p></li>' +
- '</ul>' +
- '<li><p>eee</p></li>' +
- '</ul>' +
- '<p>y</p>',
- do: async function () {
- var $li = $editable.find('ul ul li:eq(1)');
- $li.trigger($.Event('mousedown', {
- offsetX: -10,
- }));
- },
- test: {
- content: '<p>x</p>' +
- '<ul class="o_checklist">' +
- '<li><p>aaa</p></li>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>bbb</p></li>' +
- '<li><p>ccc</p></li>' +
- '<li class="o_checked"><p>ddd</p></li>' +
- '</ul>' +
- '<li><p>eee</p></li>' +
- '</ul>' +
- '<p>y</p>',
- },
- },
- {
- name: "check checkbox in checklist in checklist",
- content: '<p>x</p>' +
- '<ul class="o_checklist">' +
- '<li><p>aaa</p></li>' +
- '<li>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>bbb</p></li>' +
- '<li><p>ccc</p></li>' +
- '<li><p>ddd</p></li>' +
- '</ul>' +
- '</li>' +
- '<li><p>eee</p></li>' +
- '</ul>' +
- '<p>y</p>',
- do: async function () {
- var $li = $editable.find('ul ul li:eq(1)');
- $li.trigger($.Event('mousedown', {
- offsetX: -10,
- }));
- },
- test: {
- content: '<p>x</p>' +
- '<ul class="o_checklist">' +
- '<li><p>aaa</p></li>' +
- '<li>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>bbb</p></li>' +
- '<li class="o_checked"><p>ccc</p></li>' +
- '<li><p>ddd</p></li>' +
- '</ul>' +
- '</li>' +
- '<li><p>eee</p></li>' +
- '</ul>' +
- '<p>y</p>',
- },
- },
- {
- name: "check checkbox in checklist in checklist (2)",
- content: '<p>x</p>' +
- '<ul class="o_checklist">' +
- '<li><p>aaa</p></li>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>bbb</p></li>' +
- '<li><p>ccc</p></li>' +
- '<li><p>ddd</p></li>' +
- '</ul>' +
- '<li><p>eee</p></li>' +
- '</ul>' +
- '<p>y</p>',
- do: async function () {
- var $li = $editable.find('ul ul li:eq(1)');
- $li.trigger($.Event('mousedown', {
- offsetX: -10,
- }));
- },
- test: {
- content: '<p>x</p>' +
- '<ul class="o_checklist">' +
- '<li><p>aaa</p></li>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>bbb</p></li>' +
- '<li class="o_checked"><p>ccc</p></li>' +
- '<li><p>ddd</p></li>' +
- '</ul>' +
- '<li><p>eee</p></li>' +
- '</ul>' +
- '<p>y</p>',
- },
- },
- {
- name: "check checkbox in checklist in checklist (full)",
- content: '<p>x</p>' +
- '<ul class="o_checklist">' +
- '<li><p>aaa</p></li>' +
- '<li>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>bbb</p></li>' +
- '<li><p>ccc</p></li>' +
- '<li class="o_checked"><p>ddd</p></li>' +
- '</ul>' +
- '</li>' +
- '<li><p>eee</p></li>' +
- '</ul>' +
- '<p>y</p>',
- do: async function () {
- var $li = $editable.find('ul ul li:eq(1)');
- $li.trigger($.Event('mousedown', {
- offsetX: -10,
- }));
- },
- test: {
- content: '<p>x</p>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>aaa</p></li>' +
- '<li>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>bbb</p></li>' +
- '<li class="o_checked"><p>ccc</p></li>' +
- '<li class="o_checked"><p>ddd</p></li>' +
- '</ul>' +
- '</li>' +
- '<li><p>eee</p></li>' +
- '</ul>' +
- '<p>y</p>',
- },
- },
- {
- name: "check checkbox in checklist in checklist (full) (2)",
- content: '<p>x</p>' +
- '<ul class="o_checklist">' +
- '<li><p>aaa</p></li>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>bbb</p></li>' +
- '<li><p>ccc</p></li>' +
- '<li class="o_checked"><p>ddd</p></li>' +
- '</ul>' +
- '<li><p>eee</p></li>' +
- '</ul>' +
- '<p>y</p>',
- do: async function () {
- var $li = $editable.find('ul ul li:eq(1)');
- $li.trigger($.Event('mousedown', {
- offsetX: -10,
- }));
- },
- test: {
- content: '<p>x</p>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>aaa</p></li>' +
- '<ul class="o_checklist">' +
- '<li class="o_checked"><p>bbb</p></li>' +
- '<li class="o_checked"><p>ccc</p></li>' +
- '<li class="o_checked"><p>ddd</p></li>' +
- '</ul>' +
- '<li><p>eee</p></li>' +
- '</ul>' +
- '<p>y</p>',
- },
- },
- {
- name: "convert 2 ul li ul li into two ul li ul.o_checklist li",
- content: '<ul>' +
- '<li>' +
- '<p>1</p>' +
- '</li>' +
- '<li class="o_indent">' +
- '<ul>' +
- '<li>' +
- '<p>2</p>' +
- '</li>' +
- '<li>' +
- '<p>3</p>' +
- '</li>' +
- '<li>' +
- '<p>4</p>' +
- '</li>' +
- '</ul>' +
- '</li>' +
- '<li>' +
- '<p>5</p>' +
- '</li>' +
- '</ul>',
- start: 'p:eq(2):contents()[0]->0',
- end: 'p:eq(3):contents()[0]->1',
- do: function () {
- $btnChecklist.mousedown().click();
- },
- test: {
- content: '<ul>' +
- '<li>' +
- '<p>1</p>' +
- '</li>' +
- '<li class="o_indent">' +
- '<ul>' +
- '<li>' +
- '<p>2</p>' +
- '</li>' +
- '</ul>' +
- '<ul class="o_checklist">' +
- '<li>' +
- '<p>3</p>' +
- '</li>' +
- '<li>' +
- '<p>4</p>' +
- '</li>' +
- '</ul>' +
- '</li>' +
- '<li>' +
- '<p>5</p>' +
- '</li>' +
- '</ul>',
- },
- },
- ];
-
- 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: '<p>dom to edit</p>',
- 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: '<p>d<a href="#">om t</a>o edit</p>',
- start: 'a:contents()[0]->0',
- end: 'a:contents()[0]->4',
- },
- },
- {
- name: "Click LINK: p -> a in p (w/ URL) (no selection)",
- async: true,
- content: '<p>do edit</p>',
- 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: '<p>d<a href="#">om t</a>o edit</p>',
- 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: '<div><a href="#" class="btn btn-outline-alpha btn-lg">dom to edit</a></div>',
- 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: '<div><a href="#newlink" class="btn btn-outline-alpha btn-lg">dom to edit</a></div>',
- start: 'a->0',
- end: 'a->1',
- },
- },
- {
- name: "Click LINK: p -> a in p (w/ Email)",
- async: true,
- content: '<p>dom to edit</p>',
- 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: '<p>d<a href="mailto:john.coltrane@example.com">om t</a>o edit</p>',
- start: 'a:contents()[0]->0',
- end: 'a:contents()[0]->4',
- },
- },
- {
- name: "Click LINK: p -> a in p (w/ URL & Size Large)",
- async: true,
- content: '<p>dom to edit</p>',
- 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: '<p>d<a href="#" class="btn-lg">om t</a>o edit</p>',
- 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: '<p><a href="#">dom to edit</a></p>',
- 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: '<p><a href="#" target="_blank" class="btn btn-outline-alpha">dom to edit</a></p>',
- start: 'a->0',
- end: 'a->1',
- },
- },
- // POPOVER
- {
- name: "Click LINK in popover after adding link in p",
- async: true,
- content: '<p>dom to edit</p>',
- 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(), '<p>d<a href="/newlink">om t</a>o edit</p>', testName);
- },
- },
- },
- {
- name: "Click UNLINK in popover after adding link in p",
- async: true,
- content: '<p>dom to edit</p>',
- 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: '<p>dom to edit</p>',
- 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('<p><br></p>');
- 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, ' '),
- '<p><br></p>' +
- '<table class=\"table table-bordered\"><tbody>' +
- '<tr><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '<tr><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '<tr><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '</tbody></table>' +
- '<p><br></p>',
- "should create a table in an empty dom (p > br)");
-
- // create a table at start of p with content
-
- wysiwyg.setValue('<p>dom to edit</p>');
- 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, ' '),
- '<p><br></p>' +
- '<table class=\"table table-bordered\"><tbody>' +
- '<tr><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '<tr><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '<tr><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '</tbody></table>' +
- '<p>dom to edit</p>',
- "should create a table at start of single p with content");
-
- // create a table at end of p with content
-
- wysiwyg.setValue('<p>dom to edit</p>');
- 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, ' '),
- '<p>dom to edit</p>' +
- '<table class=\"table table-bordered\"><tbody>' +
- '<tr><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '<tr><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '<tr><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '</tbody></table>' +
- '<p><br></p>',
- "should create a table at end of single p with content");
-
- // create a table within p
-
- wysiwyg.setValue('<p>dom to edit</p>');
- 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, ' '),
- '<p>dom t</p>' +
- '<table class=\"table table-bordered\"><tbody>' +
- '<tr><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '<tr><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '<tr><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '</tbody></table>' +
- '<p>o edit</p>',
- "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, ' '),
- '<p>dom to edit</p>',
- "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, ' '),
- '<p>dom t</p>' +
- '<table class=\"table table-bordered\"><tbody>' +
- '<tr><td><p><br></p>' +
- '<table class=\"table table-bordered\"><tbody>' +
- '<tr><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '<tr><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '<tr><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '</tbody></table>' +
- '<p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '<tr><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '<tr><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '</tbody></table>' +
- '<p>o edit</p>',
- "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, ' '),
- '<p>dom t</p>' +
- '<table class=\"table table-bordered\"><tbody>' +
- '<tr><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '<tr><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '<tr><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '</tbody></table>' +
- '<p>o edit</p>',
- "should remove the inner table");
-
- // use popover to change row and line
-
- wysiwyg.setValue('<p>dom t</p>' +
- '<table class=\"table table-bordered\"><tbody>' +
- '<tr><td><p>0-0</p></td><td><p>0-1</p></td><td><p>0-2</p></td></tr>' +
- '<tr><td><p>1-0</p></td><td><p>1-1</p></td><td><p>1-2</p></td></tr>' +
- '<tr><td><p>2-0</p></td><td><p>2-1</p></td><td><p>2-2</p></td></tr>' +
- '</tbody></table>' +
- '<p>o edit</p>');
-
- // 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, ' '),
- '<p>dom t</p>' +
- '<table class=\"table table-bordered\"><tbody>' +
- '<tr><td><p>0-0</p></td><td><p>0-2</p></td></tr>' +
- '<tr><td><p>1-0</p></td><td><p>1-2</p></td></tr>' +
- '<tr><td><p>2-0</p></td><td><p>2-2</p></td></tr>' +
- '</tbody></table>' +
- '<p>o edit</p>',
- "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, ' '),
- '<p>dom t</p>' +
- '<table class=\"table table-bordered\"><tbody>' +
- '<tr><td><p>0-0</p></td><td><p>0-2</p></td></tr>' +
- '<tr><td><p>2-0</p></td><td><p>2-2</p></td></tr>' +
- '</tbody></table>' +
- '<p>o edit</p>',
- "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, ' '),
- '<p>dom t</p>' +
- '<table class=\"table table-bordered\"><tbody>' +
- '<tr><td><p>0-0</p></td><td><p><br></p></td><td><p>0-2</p></td></tr>' +
- '<tr><td><p>2-0</p></td><td><p><br></p></td><td><p>2-2</p></td></tr>' +
- '</tbody></table>' +
- '<p>o edit</p>',
- "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, ' '),
- '<p>dom t</p>' +
- '<table class=\"table table-bordered\"><tbody>' +
- '<tr><td><p><br></p></td><td><p>0-0</p></td><td><p><br></p></td><td><p>0-2</p></td></tr>' +
- '<tr><td><p><br></p></td><td><p>2-0</p></td><td><p><br></p></td><td><p>2-2</p></td></tr>' +
- '</tbody></table>' +
- '<p>o edit</p>',
- "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, ' '),
- '<p>dom t</p>' +
- '<table class=\"table table-bordered\"><tbody>' +
- '<tr><td><p><br></p></td><td><p>0-0</p></td><td><p><br></p></td><td><p>0-2</p></td></tr>' +
- '<tr><td><p><br></p></td><td><p>2-0</p></td><td><p><br></p></td><td><p>2-2</p></td></tr>' +
- '<tr><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '</tbody></table>' +
- '<p>o edit</p>',
- "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, ' '),
- '<p>dom t</p>' +
- '<table class=\"table table-bordered\"><tbody>' +
- '<tr><td><p><br></p></td><td><p>0-0</p></td><td><p><br></p></td><td><p>0-2</p></td></tr>' +
- '<tr><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '<tr><td><p><br></p></td><td><p>2-0</p></td><td><p><br></p></td><td><p>2-2</p></td></tr>' +
- '<tr><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td><td><p><br></p></td></tr>' +
- '</tbody></table>' +
- '<p>o edit</p>',
- "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('<p>dom to edit <img src="/web_editor/static/src/img/transparent.png"></p>');
-
- 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('<p>dom to edit a <img src="/web_editor/static/src/img/transparent.png"></p>');
- 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: '<p><br></p>',
- start: "p->0",
- do: async function () {
- await _uploadAndInsertImg('https://www.odoo.com/logo.png');
- },
- test: {
- content: '<p>\u200B<img class="img-fluid o_we_custom_image" data-src="/web_editor/static/src/img/transparent.png">\u200B</p>',
- check: async function () {
- assert.strictEqual($('.note-image-popover').css('display'), 'block', testName + ' (popover)');
- },
- },
- },
- {
- name: "add an image in a table",
- async: true,
- content: '<section><div class="container"><div class="row"><div class="col-lg-6">' +
- '<table class="table table-bordered">' +
- ' <tbody>' +
- ' <tr>' +
- ' <td>' +
- ' aaa' +
- ' </td>' +
- ' <td>' +
- ' bbb' +
- ' </td>' +
- ' <td>' +
- ' ccc' +
- ' </td>' +
- ' </tr>' +
- ' </tbody>' +
- '</table>' +
- '</div></div></div></section>',
- start: "td:eq(1):contents()[0]->18",
- do: async function () {
- await _uploadAndInsertImg('https://www.odoo.com/logo.png');
- },
- test: {
- content: '<section><div class="container"><div class="row"><div class="col-lg-6">' +
- '<table class="table table-bordered">' +
- ' <tbody>' +
- ' <tr>' +
- ' <td>' +
- ' aaa' +
- ' </td>' +
- ' <td>' +
- ' bb<img class="img-fluid o_we_custom_image" data-src="/web_editor/static/src/img/transparent.png">b' +
- ' </td>' +
- ' <td>' +
- ' ccc' +
- ' </td>' +
- ' </tr>' +
- ' </tbody>' +
- '</table>' +
- '</div></div></div></section>',
- check: async function () {
- assert.strictEqual($('.note-image-popover').css('display'), 'block', testName + ' (popover)');
- },
- },
- },
- {
- name: "add an image in an empty table",
- async: true,
- content: '<section><div class="container"><div class="row"><div class="col-lg-6">' +
- '<table class="table table-bordered">' +
- ' <tbody>' +
- ' <tr>' +
- ' <td>' +
- ' <br>' +
- ' </td>' +
- ' <td>' +
- ' <br>' +
- ' </td>' +
- ' <td>' +
- ' <br>' +
- ' </td>' +
- ' </tr>' +
- ' </tbody>' +
- '</table>' +
- '</div></div></div></section>',
- start: "br:eq(1)->0",
- do: async function () {
- await _uploadAndInsertImg('https://www.odoo.com/logo.png');
- },
- test: {
- content: '<section><div class="container"><div class="row"><div class="col-lg-6">' +
- '<table class="table table-bordered">' +
- ' <tbody>' +
- ' <tr>' +
- ' <td>' +
- ' <br>' +
- ' </td>' +
- ' <td>' +
- ' <img class="img-fluid o_we_custom_image" data-src="/web_editor/static/src/img/transparent.png"><br>' +
- ' </td>' +
- ' <td>' +
- ' <br>' +
- ' </td>' +
- ' </tr>' +
- ' </tbody>' +
- '</table>' +
- '</div></div></div></section>',
- 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: '<p><br></p>',
- start: "p->0",
- do: async function () {
- await _uploadAndInsertImg('https://www.odoo.com/logo.png');
- },
- test: {
- content: '<p>\u200B<img class="img-fluid o_we_custom_image padding-xl" data-src="/web_editor/static/src/img/transparent.png">\u200B</p>',
- 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: '<p><br></p>',
- start: "p->0",
- do: async function () {
- await _uploadAndInsertImg('https://www.odoo.com/logo.png');
- },
- test: {
- content: '<p>\u200B<img class="img-fluid o_we_custom_image" data-src="/web_editor/static/src/img/transparent.png" style="width: 25%;">\u200B</p>',
- 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: '<p><br></p>',
- start: "p->0",
- do: async function () {
- await _uploadAndInsertImg('https://www.odoo.com/logo.png');
- },
- test: {
- content: '<p>\u200B<img class="img-fluid o_we_custom_image pull-right" data-src="/web_editor/static/src/img/transparent.png">\u200B</p>',
- 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: '<p><br></p>',
- start: "p->0",
- do: async function () {
- await _uploadAndInsertImg('https://www.odoo.com/logo.png');
- },
- test: {
- content: '<p>\u200B<img class="img-fluid o_we_custom_image pull-left" data-src="/web_editor/static/src/img/transparent.png">\u200B</p>',
- 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: '<p><br></p>',
- start: "p->0",
- do: async function () {
- await _uploadAndInsertImg('https://www.odoo.com/logo.png');
- },
- test: {
- content: '<p>\u200B<img class="img-fluid o_we_custom_image rounded" data-src="/web_editor/static/src/img/transparent.png">\u200B</p>',
- 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: '<p><br></p>',
- start: "p->0",
- do: async function () {
- await _uploadAndInsertImg('https://www.odoo.com/logo.png');
- },
- test: {
- content: '<p><br></p>',
- 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: '<p><br></p>',
- 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: '<p><br></p>',
- 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: '<p><br></p>',
- 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: '<p><br></p>',
- 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: '<p><br></p>',
- start: "p->0",
- do: async function () {
- await _insertPictogram('fa-glass');
- },
- test: {
- content: '<p>\u200B<span class="fa fa-glass"></span>\u200B</p>',
- 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: '<p><br></p>',
- start: "p->0",
- do: async function () {
- await _insertPictogram('fa-glass');
- },
- test: {
- content: '<p><br></p>',
- 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: '<p><br></p>',
- start: "p->0",
- do: async function () {
- await _insertPictogram('fa-glass');
- },
- test: {
- content: '<p>\u200B<span class="fa fa-glass fa-5x"></span>\u200B</p>',
- 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: '<p><br></p>',
- start: "p->0",
- do: async function () {
- await _insertPictogram('fa-glass');
- },
- test: {
- content: '<p>\u200B<span class="fa fa-glass fa-spin"></span>\u200B</p>',
- 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: '<p><br></p>',
- 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: '<p>\u200B<span class="fa fa-heart"></span>\u200B</p>',
- });
- },
- },
- },
- {
- name: "Replace PICTOGRAM (i.fa => span.fa)",
- async: true,
- content: '<div class="row">\n' +
- ' <div class="col-lg-12">\n' +
- ' <i class="fa fa-heart rounded-circle"></i>\n' +
- ' <div>Other content</div>\n' +
- ' </div>\n' +
- '</div>',
- start: "i->0",
- do: async function () {
- await _insertPictogram('fa-glass');
- },
- test: {
- content: '<div class="row">\n' +
- ' <div class="col-lg-12">\n' +
- ' <span class="rounded-circle fa fa-glass"></span>\n' +
- ' <div>Other content</div>\n' +
- ' </div>\n' +
- '</div>',
- },
- },
- ];
-
- 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: '<p><br></p>',
- start: "p->0",
- do: async function () {
- await _insertVideo(wysiwyg, assert, 'https://www.youtube.com/watch?v=xxxxxxxxxxx', true);
- },
- test: {
- content: '<p><br></p><div class="media_iframe_video" data-oe-expression="about:blank"><div class="css_editable_mode_display">&nbsp;</div><div class="media_iframe_video_size">&nbsp;</div><iframe src="about:blank" frameborder="0"></iframe></div><p><br></p>',
- 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: '<breakable><unbreakable><breakable><p>tata yoyo</p></breakable></unbreakable></breakable>',
- start: "p:contents()[0]->4",
- do: async function () {
- await _insertVideo(wysiwyg, assert, 'https://www.youtube.com/watch?v=xxxxxxxxxxx');
- },
- test: {
- content: '<breakable><unbreakable><breakable><p>tata</p></breakable>' +
- '<div class="media_iframe_video" data-oe-expression="about:blank"><div class="css_editable_mode_display">&nbsp;</div><div class="media_iframe_video_size">&nbsp;</div><iframe src="about:blank" frameborder="0"></iframe></div>' +
- '<breakable><p> yoyo</p></breakable></unbreakable></breakable>',
- 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: '<p><br></p>',
- start: "p->0",
- do: async function () {
- await _insertVideo(wysiwyg, assert, 'https://www.youtube.com/watch?v=xxxxxxxxxxx');
- },
- test: {
- content: '<p><br></p>',
- 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: '<p><br></p>',
- start: "p->0",
- do: async function () {
- await _insertVideo(wysiwyg, assert, 'https://www.youtube.com/watch?v=xxxxxxxxxxx');
- },
- test: {
- content: '<p><br></p><div class="media_iframe_video pull-left" data-oe-expression="about:blank"><div class="css_editable_mode_display">&nbsp;</div><div class="media_iframe_video_size">&nbsp;</div><iframe src="about:blank" frameborder="0"></iframe></div><p><br></p>',
- 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: '<p><img src="https://www.odoo.com/logo.png"></p>',
- 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(),
- '<p><br></p><div class="media_iframe_video" data-oe-expression="about:blank"><div class="css_editable_mode_display">&nbsp;</div><div class="media_iframe_video_size">&nbsp;</div><iframe src="about:blank" frameborder="0"></iframe></div><p><br></p>',
- testName);
- },
- },
- },
- // Replace video
- {
- name: "replace video by pictogram",
- async: true,
- content: '<p><br></p><div class="media_iframe_video" data-oe-expression="about:blank"><div class="css_editable_mode_display">&nbsp;</div><div class="media_iframe_video_size">&nbsp;</div><iframe src="about:blank" frameborder="0"></iframe></div><p><br></p>',
- start: "div->0",
- do: async function () {
- await _insertPictogram('fa-glass');
- },
- test: {
- check: async function () {
- assert.deepEqual(wysiwyg.getValue(),
- '<p>\u200B<span class="fa fa-glass"></span>\u200B</p>',
- testName);
- },
- },
- },
- {
- name: "replace video by pictogram (2)",
- async: true,
- content: '<p>aaa</p><div class="media_iframe_video" data-oe-expression="about:blank"><div class="css_editable_mode_display">&nbsp;</div><div class="media_iframe_video_size">&nbsp;</div><iframe src="about:blank" frameborder="0"></iframe></div><p>bbb</p>',
- start: "div->0",
- do: async function () {
- await _insertPictogram('fa-glass');
- },
- test: {
- check: async function () {
- assert.deepEqual(wysiwyg.getValue(),
- '<p>aaa<span class="fa fa-glass"></span>bbb</p>',
- 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 @@
<script type="text/javascript" src="/web_editor/static/tests/test_utils.js"/>
<script type="text/javascript" src="/web_editor/static/tests/field_html_tests.js"/>
- <script type="text/javascript" src="/web_editor/static/tests/wysiwyg_tests.js"/>
- <script type="text/javascript" src="/web_editor/static/tests/wysiwyg_keyboard_tests.js"/>
- <script type="text/javascript" src="/web_editor/static/tests/wysiwyg_snippets_tests.js"/>
</xpath>
</template>