From ce963d45cdf2703d2d4eedfa94394b178f86e0f1 Mon Sep 17 00:00:00 2001 From: Armen Kesablyan Date: Thu, 9 Feb 2012 17:11:38 -0800 Subject: More Text Tool Updates --- .../labs/rich-text-editor.reel/rich-text-editor.js | 166 +++++++++++++-------- 1 file changed, 107 insertions(+), 59 deletions(-) (limited to 'node_modules/labs/rich-text-editor.reel/rich-text-editor.js') diff --git a/node_modules/labs/rich-text-editor.reel/rich-text-editor.js b/node_modules/labs/rich-text-editor.reel/rich-text-editor.js index 3fece294..b88d5868 100644 --- a/node_modules/labs/rich-text-editor.reel/rich-text-editor.js +++ b/node_modules/labs/rich-text-editor.reel/rich-text-editor.js @@ -12,6 +12,8 @@ var Montage = require("montage/core/core").Montage, MutableEvent = require("montage/core/event/mutable-event").MutableEvent, Resizer = require("node_modules/labs/rich-text-editor.reel/rich-text-resizer").Resizer, Sanitizer = require("node_modules/labs/rich-text-editor.reel/rich-text-sanitizer").Sanitizer; + Point = require("montage/core/geometry/point").Point; + /** @class module:"montage/ui/rich-text-editor.reel".RichTextEditor @@ -148,7 +150,6 @@ exports.RichTextEditor = Montage.create(Component,/** @lends module:"montage/ui/ if (this._resizer) { this._needsHideResizer = true; } - if (this._sanitizer) { value = this._sanitizer.willSetValue(value, this._uniqueId); } @@ -296,7 +297,9 @@ exports.RichTextEditor = Montage.create(Component,/** @lends module:"montage/ui/ states: { enumerable: true, get: function() { - this.updateStates(); + if (this._statesDirty || !this._states) { + this.updateStates(); + } return this._states; } }, @@ -313,7 +316,6 @@ exports.RichTextEditor = Montage.create(Component,/** @lends module:"montage/ui/ action, states, state, - statesChanged = false, hasFocus = this._hasFocus; if (this._states == null || this._statesDirty) { @@ -339,16 +341,8 @@ exports.RichTextEditor = Montage.create(Component,/** @lends module:"montage/ui/ if (states[key] !== state) { states[key] = state; - statesChanged = true; } } - - if (statesChanged) { - this._states = states; - // As we do not use a setter, we need to manually dispatch a change event - this.dispatchEvent(MutableEvent.changeEventForKeyAndValue("states" , this._states)); - } - } } @@ -388,6 +382,10 @@ exports.RichTextEditor = Montage.create(Component,/** @lends module:"montage/ui/ enumerable: false, value: { bold: {enabled: true, needsValue:false, status: true}, + justifyleft: {enabled: true, needsValue:false, status: true}, + justifycenter: {enabled: true, needsValue:false, status: true}, + justifyright: {enabled: true, needsValue:false, status: true}, + justifyfull: {enabled: true, needsValue:false, status: true}, italic: {enabled: true, needsValue:false, status: true}, underline: {enabled: true, needsValue:false, status: true}, strikethrough: {enabled: true, needsValue:false, status: true}, @@ -536,6 +534,7 @@ exports.RichTextEditor = Montage.create(Component,/** @lends module:"montage/ui/ } this._adjustPadding(); + this._markDirty(); delete this._needsResetContent; } @@ -1011,6 +1010,12 @@ exports.RichTextEditor = Montage.create(Component,/** @lends module:"montage/ui/ event.preventDefault(); event.stopPropagation(); + // Remove the link popup + if (this._needsActiveLinkOn === false && this._activeLink) { + this._needsActiveLinkOn = null; + this.needsDraw = true; + } + // Update the caret if (event.x !== this._dragOverX || event.y !== this._dragOverY) { this._dragOverX = event.x; @@ -1365,9 +1370,11 @@ exports.RichTextEditor = Montage.create(Component,/** @lends module:"montage/ui/ thisRef._dispatchEditorEvent("editorChange"); }; - // Clear the cached value - this._dirtyValue = true; - this._dirtyTextValue = true; + if (!this._needsResetContent) { + // Clear the cached value + this._dirtyValue = true; + this._dirtyTextValue = true; + } if (!this._forceUpdateValuesTimeout) { this._forceUpdateValuesTimeout = setTimeout(updateValues, 1000); @@ -1519,60 +1526,85 @@ exports.RichTextEditor = Montage.create(Component,/** @lends module:"montage/ui/ popup, parentNode, nextSibling, - w, h, l, t, docH, docW, - maxWidth, + w, h, l, t, + left, right, leftWidth, rightWidth, style, popupExtraWidth = 53; // This is depending of the popup css + var offsetLeft, + offsetTop, + _findOffset = function(node) { + offsetLeft = node.offsetLeft; + offsetTop = node.offsetTop; + + while ((node = node.offsetParent) && node != editorElement) { + offsetLeft += node.offsetLeft; + offsetTop += node.offsetTop; + } + }; + + if (this._activeLink != element) { this._hideActiveLink(); if (element) { + + _findOffset(element); + parentNode = element.parentNode; nextSibling = element.nextSibling; - // sanity check: make sure we don't already have a popup installed for that element - if (!nextSibling || nextSibling.tagName !== "DIV" || !nextSibling.classList.contains("montage-link-popup")) { + oh = editorElement.offsetHeight; + ow = editorElement.offsetWidth; + st = editorElement.scrollTop; + sl = editorElement.scrollLeft; - oh = editorElement.offsetHeight; - ow = editorElement.offsetWidth; - st = editorElement.scrollTop; - sl = editorElement.scrollLeft; + w = element.offsetWidth -1, + h = element.offsetHeight -1, + l = offsetLeft, + t = offsetTop, - w = element.offsetWidth -1, - h = element.offsetHeight -1, - l = element.offsetLeft, - t = element.offsetTop, + style = ""; - style = ""; - if (t > 60 && t - st + h + 50 > oh) { - style = "bottom: " + (oh - t + 5) + "px;"; - } else { - style = "top: " + (t + h + 5 ) + "px;"; - } + // Should we display the popup on top or below the element? + if (t > 60 && t - st + h + 50 > oh) { + style = "bottom: " + (oh - t + 5) + "px;"; + } else { + style = "top: " + (t + h + 5 ) + "px;"; + } - var maxWidth = ow - l - popupExtraWidth + sl; - if (maxWidth < 150) { - maxWidth = 150; - } - if (l + maxWidth + popupExtraWidth - sl > ow) { - l = ow - maxWidth - popupExtraWidth + sl; + // Should we display the popup aligned on the left or right of the element? + left = sl; + right = sl + ow; + leftWidth = right - l; + rightWidth = l + w - left; + + if (leftWidth > rightWidth) { + //Let's align the popup to the left of the element or to the far left + if (leftWidth < 150) { + style += " left: " + (left + 5) + "px;"; + style += " max-width: " + (ow - 10 - popupExtraWidth) + "px;"; + } else { + style += " left: " + (left + l) + "px;"; + style += " max-width: " + (leftWidth - 5 - popupExtraWidth) + "px;"; } - if (l < 3) { - l = 3; + } else { + if (rightWidth < 150) { + style += " right: " + (left + 6) + "px;"; + style += " max-width: " + (ow - 10 - popupExtraWidth) + "px;"; + } else { + style += " right: " + (right - (left + l + w + 10)) + "px;"; + style += " max-width: " + (rightWidth - popupExtraWidth) + "px;"; } - style += " left: " + l + "px;" - style += "max-width: " + maxWidth + "px;" - + } - popup = document.createElement("DIV"); - popup.className = "montage-link-popup"; - popup.setAttribute("contentEditable", "false"); - popup.setAttribute("style", style); - popup.innerHTML = '' + element.href + ''; - parentNode.insertBefore(popup, nextSibling); + popup = document.createElement("DIV"); + popup.className = "montage-link-popup"; + popup.setAttribute("contentEditable", "false"); + popup.setAttribute("style", style); + popup.innerHTML = '' + element.href + ''; + editorElement.insertBefore(popup, null); - this._activeLink = element; - } + this._activeLink = element; } } } @@ -1642,25 +1674,41 @@ exports.RichTextEditor = Montage.create(Component,/** @lends module:"montage/ui/ value: function(contentNode) { var result = "", textNodeContents = [], + newLines = "", + gotText = false, _walkNode = function(node) { - var child; + var nodeName = node.nodeName, + child - if (node.nodeName == "STYLE") { + if (nodeName.match(/^(TITLE|STYLE|SCRIPT)$/)) { return; } - // TODO: We need to insert newlines after block elements (and remove any newline coming from HTML) + if (gotText && nodeName.match(/^(P|DIV|BR|TR|LI)$/)) { + newLines += "\n"; + } + for (child = node.firstChild; child; child = child.nextSibling) { - if (child.nodeType == 3) { // text node - textNodeContents.push(child.nodeValue); + if (child.nodeType == 3) { // text node + textNodeContents.push(newLines + child.nodeValue); + newLines = ""; + gotText = true; } else { - _walkNode(child); + if (child.nodeName != "BR" || child.nextSibling) { + _walkNode(child); + } } } + + if (gotText && nodeName.match(/^(TABLE|UL|OL)$/)) { + newLines += "\n"; + } }; - _walkNode(contentNode); - result = textNodeContents.join(""); + if (contentNode) { + _walkNode(contentNode); + result = textNodeContents.join(""); + } return result; } -- cgit v1.2.3