if (wysihtml5.browser.supported()) { module("wysihtml5.Editor contenteditable mode", { setup: function() { wysihtml5.dom.insertCSS([ "#wysihtml5-test-editable { width: 50%; height: 100px; margin-top: 5px; font-style: italic; border: 2px solid red; border-radius: 2px; }", "#wysihtml5-test-editable:focus { margin-top: 10px; }", "#wysihtml5-test-editable:disabled { margin-top: 20px; }" ]).into(document); this.editableArea = document.createElement("div"); this.editableArea.id = "wysihtml5-test-editable"; this.editableArea.className = "wysihtml5-test-class"; this.editableArea.title = "Please enter your foo"; this.editableArea.innerHTML = "hey tiff, what's up?"; this.originalBodyClassName = document.body.className; document.body.appendChild(this.editableArea); }, teardown: function() { var leftover; this.editableArea.parentNode.removeChild(this.editableArea); while (leftover = document.querySelector("div.wysihtml5-sandbox, div.wysihtml5-test-class")) { leftover.parentNode.removeChild(leftover); } document.body.className = this.originalBodyClassName; } }); // Editor initiation tests asyncTest("Basic test", function() { expect(14); var that = this; var editor = new wysihtml5.Editor(this.editableArea); editor.on("load", function() { var editableElement = that.editableArea; ok(true, "Load callback triggered"); ok(wysihtml5.dom.hasClass(document.body, "wysihtml5-supported"), "
received correct class name"); ok(wysihtml5.dom.hasClass(editableElement, "wysihtml5-test-class"), "editable kept its original class name"); ok(wysihtml5.dom.hasClass(editableElement, "wysihtml5-sandbox"), "editable added its own sandbox class name"); equal(editor.config.contentEditableMode, true, "contentEditableMode deduced correctly as editable is initiated on non textarea"); equal(editor.config.noTextarea, true, "noTextarea mode deduced correctly as editable is initiated on non textarea"); equal(editableElement.style.display, "", "Editor contenteditable is visible"); equal(editor.currentView.name, "composer", "Current view is 'composer'"); equal(editableElement.getAttribute("contentEditable"), "true", "Element is editable"); equal(typeof editor.textarea, "undefined", "Textarea correctly not available on editor instance"); equal(editor.composer.element, editableElement, "contentEditable element available on editor instance"); equal(editableElement.innerHTML.toLowerCase(), "hey tiff, what's up?", "Initial value preserved in editor"); ok(wysihtml5.dom.hasClass(editableElement, "wysihtml5-editor"), "Editor element has correct class name"); equal(typeof editor.synchronizer, "undefined", "Syncronizer correctly not initiated in contenteditable mode"); start(); }); }); // EVENTS TESTS asyncTest("Check events", function() { expect(17); var that = this; var editor = new wysihtml5.Editor(this.editableArea); editor.on("beforeload", function() { ok(true, "'beforeload' event correctly fired"); }); editor.on("load", function() { var composerElement = that.editableArea; editor.on("focus", function(event) { ok(true, "'focus' event correctly fired"); ok(event, "event is defined"); ok(event instanceof Event, "event is instance of 'Event'"); ok(event && event.type === 'focus', "event is of type 'focus'"); }); editor.on("blur", function(event) { ok(true, "'blur' event correctly fired"); ok(event, "event is defined"); ok(event instanceof Event, "event is instance of 'Event'"); ok(event && event.type === 'blur', "event is of type 'blur'"); }); editor.on("change", function(event) { ok(true, "'change' event correctly fired"); ok(event, "event is defined"); ok(event instanceof Event, "event is instance of 'Event'"); ok(event && event.type === 'change', "event is of type 'change'"); }); editor.on("custom_event", function(event) { ok(true, "'custom_event' correctly fired"); ok(event, "event is defined"); ok(event && event.type === 'custom_event', "event is of type 'custom_event'"); }); happen.once(composerElement, {type: "focus"}); editor.stopObserving("focus"); // Modify innerHTML in order to force 'change' event to trigger onblur composerElement.innerHTML = "foobar"; happen.once(composerElement, {type: "blur"}); happen.once(composerElement, {type: "focusout"}); equal(wysihtml5.dom.getStyle("margin-top").from(composerElement), "5px", ":focus styles are correctly unset"); editor.fire("custom_event", { type: 'custom_event' }); setTimeout(function() { start(); }, 100); }); }); asyncTest("Check events paste", function() { expect(12); var that = this; var editor = new wysihtml5.Editor(this.editableArea); editor.on("load", function() { var composerElement = that.editableArea; editor.on("paste", function(event) { ok(event, "event is defined"); ok(event instanceof Event, "event is instance of 'Event'"); ok(event && event.type === 'paste', "event is of type 'paste'"); }); //Assure that the event on the dom element works as expected that.editableArea.addEventListener('paste', function (event) { ok(event, "event is defined"); ok(event instanceof Event, "event is instance of 'Event'"); ok(event && event.type === 'paste', "event is of type 'paste'"); }); happen.once(composerElement, {type: "paste"}); //Just to show that not happen.js is the source of error var event = new Event('paste'); that.editableArea.dispatchEvent(event); //QUnit.triggerEvent(composerElement, 'paste'); setTimeout(function() { start(); }, 100); }); }); asyncTest("Check events drop", function() { expect(12); var that = this; var editor = new wysihtml5.Editor(this.editableArea); editor.on("load", function() { var composerElement = that.editableArea; //if changing from drop to paste it works editor.on('drop', function(event) { ok(event, "event is defined"); ok(event instanceof Event, "event is instance of 'Event'"); ok(event && event.type === 'drop', "event is of type 'drop'"); }); editor.on('paste', function(event) { ok(false, "No 'paste' event was fired."); }); //Assure that the event on the dom element works as expected that.editableArea.addEventListener('drop', function (event) { ok(event, "event is defined"); ok(event instanceof Event, "event is instance of 'Event'"); ok(event && event.type === 'drop', "event is of type 'drop'"); }); happen.once(composerElement, {type: "drop"}); //Just to show that not happen.js is the source of error var event = new Event('drop'); that.editableArea.dispatchEvent(event); //QUnit.triggerEvent(composerElement, 'drop'); setTimeout(function() { start(); }, 100); }); }); // Placeholder tests asyncTest("Check placeholder", function() { expect(12); var that = this; var placeholderText = "enter text ..."; this.editableArea.innerHTML = ""; this.editableArea.setAttribute("data-placeholder", "enter text ..."); var editor = new wysihtml5.Editor(this.editableArea); editor.on("load", function() { var composerElement = that.editableArea; equal(wysihtml5.dom.getTextContent(composerElement), placeholderText, "Placeholder text correctly copied into textarea"); ok(wysihtml5.dom.hasClass(composerElement, "placeholder"), "Editor got 'placeholder' css class"); ok(editor.hasPlaceholderSet(), "'hasPlaceholderSet' returns correct value when placeholder is actually set"); editor.fire("focus:composer"); equal(wysihtml5.dom.getTextContent(composerElement), "", "Editor is empty after focus"); ok(!wysihtml5.dom.hasClass(composerElement, "placeholder"), "Editor hasn't got 'placeholder' css class"); ok(!editor.hasPlaceholderSet(), "'hasPlaceholderSet' returns correct value when placeholder isn't actually set"); editor.fire("blur:composer"); equal(wysihtml5.dom.getTextContent(composerElement), placeholderText, "Editor restored placeholder text after unfocus"); editor.fire("focus:composer"); equal(wysihtml5.dom.getTextContent(composerElement), ""); composerElement.innerHTML = "some content"; editor.fire("blur:composer"); equal(wysihtml5.dom.getTextContent(composerElement), "some content"); ok(!wysihtml5.dom.hasClass(composerElement, "placeholder"), "Editor hasn't got 'placeholder' css class"); editor.fire("focus:composer"); // Following html causes innerText and textContent to report an empty string var html = 'foo
").toLowerCase(), "foobar
", output = "foobar
"; var that = this, parserRules = { script: undefined }, input = this.editableArea.innerHTML, output = input; var editor = new wysihtml5.Editor(this.editableArea, { parserRules: parserRules, parser: function(html, config) { if (typeof html !== "string") { html = html.innerHTML; ok(true, "Custom parser is run element upon initiation"); } equal(html.toLowerCase(), input, "HTML passed into parser is equal to the one which just got inserted"); equal(config.rules, parserRules, "Rules passed into parser are equal to those given to the editor"); return html.replace(/\