aboutsummaryrefslogtreecommitdiff
path: root/node_modules/labs/rich-text-editor.reel/rich-text-resizer.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/labs/rich-text-editor.reel/rich-text-resizer.js')
-rw-r--r--node_modules/labs/rich-text-editor.reel/rich-text-resizer.js349
1 files changed, 349 insertions, 0 deletions
diff --git a/node_modules/labs/rich-text-editor.reel/rich-text-resizer.js b/node_modules/labs/rich-text-editor.reel/rich-text-resizer.js
new file mode 100644
index 00000000..5da834f4
--- /dev/null
+++ b/node_modules/labs/rich-text-editor.reel/rich-text-resizer.js
@@ -0,0 +1,349 @@
1/* <copyright>
2 This file contains proprietary software owned by Motorola Mobility, Inc.<br/>
3 No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/>
4 (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved.
5 </copyright> */
6/**
7 @module "montage/ui/rich-text-resizer.js"
8 @requires montage/core/core
9*/
10var Montage = require("montage/core/core").Montage,
11 dom = require("montage/ui/dom"),
12 Point = require("montage/core/geometry/point").Point;
13
14/**
15 @class module:"montage/ui/rich-text-resizer.js".Resizer
16 @extends module:montage/core/core.Montage
17*/
18exports.Resizer = Montage.create(Montage,/** @lends module:"montage/ui/rich-text-resizer.js".Resizer# */ {
19
20 _editor: {
21 value: null
22 },
23
24 _element: {
25 value: null
26 },
27
28 element: {
29 get: function() {
30 return this._element;
31 }
32 },
33
34 initialize: {
35 value: function(editor) {
36 this._editor = editor;
37 }
38 },
39
40 show: {
41 value: function(element) {
42 // Remove the current resizer
43 if (this._element) {
44 this._removeResizer(element);
45 }
46 if (element) {
47 this._addResizer(element);
48 }
49 this._element = element;
50 }
51 },
52
53 hide: {
54 value: function() {
55 this._removeResizer(this._element);
56 this._element = null;
57 }
58 },
59
60 cleanup: {
61 value: function(contentNode) {
62 var cleanContentNode = contentNode,
63 resizers = contentNode.getElementsByClassName("montage-resizer"),
64 nbrResizers,
65 resizer,
66 i;
67
68 if (resizers) {
69 // We don't want to hide the resizer, just return a copy of the content without the resizer
70 cleanContentNode = contentNode.cloneNode(true);
71 resizers = cleanContentNode.getElementsByClassName("montage-resizer");
72 nbrResizers = resizers.length;
73
74 // Note: We should not have more than one resizer, this is just in case...
75 for (i = 0; i < nbrResizers; i ++) {
76 resizer = resizers[0];
77 resizer.parentNode.removeChild(resizer);
78 }
79 }
80
81 return cleanContentNode;
82 }
83 },
84
85 draw : {
86 value: function() {
87 var thisRef = this;
88
89 if (this._draggedElement) {
90 // Resize the resizer frame
91 var frame = this._draggedElement.parentNode.firstChild,
92 zero = Point.create().init(0, 0),
93 framePosition = dom.convertPointFromNodeToPage(frame, zero),
94 cursor = this._cursorPosition,
95 direction = this._draggedElement.id.substring("editor-resizer-".length),
96 info = this._resizerFrameInfo,
97 ratio = info.ratio,
98 height = frame.clientHeight,
99 width = frame.clientWidth,
100 top = parseFloat(frame.style.top, 10),
101 left = parseFloat(frame.style.left, 10),
102 minSize = 15;
103
104 element = this._draggedElement.parentNode.previousSibling;
105
106 if (direction == "n") {
107 height += framePosition.y - cursor.y;
108 top = info.top - (height - info.height);
109 } else if (direction == "ne") {
110 height += framePosition.y - cursor.y;
111 width = Math.round(height * ratio);
112 if (cursor.x > (framePosition.x + width)) {
113 width = cursor.x - framePosition.x;
114 height = Math.round(width / ratio);
115 }
116 top = info.top - (height - info.height);
117 } else if (direction == "e") {
118 width = cursor.x - framePosition.x;
119 } else if (direction == "se") {
120 height = cursor.y - framePosition.y;
121 width = Math.round(height * ratio);
122 if (cursor.x > (framePosition.x + width)) {
123 width = cursor.x - framePosition.x;
124 height = Math.round(width / ratio);
125 }
126 } else if (direction == "s") {
127 height = cursor.y - framePosition.y;
128 } else if (direction == "sw") {
129 height = cursor.y - framePosition.y;
130 width = Math.round(height * ratio);
131 if (cursor.x <= framePosition.x - width + frame.clientWidth) {
132 width = frame.clientWidth + framePosition.x - cursor.x;
133 height = Math.round(width / ratio);
134 }
135 left = info.left - (width - info.width);
136 } else if (direction == "w") {
137 width += framePosition.x - cursor.x;
138 left = info.left - (width - info.width);
139 } else if (direction == "nw") {
140 height += framePosition.y - cursor.y;
141 width = Math.round(height * ratio);
142 if (cursor.x <= framePosition.x - width + frame.clientWidth) {
143 width = frame.clientWidth + framePosition.x - cursor.x;
144 height = Math.round(width / ratio);
145 }
146 top = info.top - (height - info.height);
147 left = info.left - (width - info.width);
148 }
149
150 //set the frame's new height and width
151 if (height > minSize && width > minSize) {
152 frame.style.height = height + "px";
153 frame.style.width = width + "px";
154 frame.style.top = top + "px";
155 frame.style.left = left + "px";
156 }
157
158 if (this._finalizeDrag) {
159 this._draggedElement.parentNode.classList.remove("dragged");
160 delete this._finalizeDrag;
161 delete this._resizerFrameInfo;
162 delete this._draggedElement;
163
164 // Remove the resizer, we don't wont it in case of undo!
165 this._removeResizer(element);
166
167 // Prevent the editor to try to delete the resizer from now on due to a selection change
168 this._editor._selectingResizer = true;
169
170 // Take the element offline to modify it
171 var div = document.createElement("div"),
172 offlineElement,
173 savedID;
174 div.innerHTML = element ? element.outerHTML : "";
175 offlineElement = div.firstChild;
176
177 // Resize the element now that it's offline
178 offlineElement.width = (width + 1);
179 offlineElement.height = (height + 1);
180 offlineElement.style.removeProperty("width");
181 offlineElement.style.removeProperty("height");
182
183 savedID = offlineElement.id;
184 offlineElement.id = "montage-editor-resized-image";
185
186 // Inject the resized element into the contentEditable using execCommand in order to be in the browser undo queue
187 document.execCommand("inserthtml", false, div.innerHTML);
188 element = document.getElementById(offlineElement.id);
189 if (element && savedID !== undefined) {
190 element.id = savedID;
191 }
192 this._element = element;
193
194 // Add back the resizer
195 this._addResizer(element);
196
197 // Reset the selection (using the editor's internal
198 offset = this._editor._nodeOffset(element);
199 range = document.createRange();
200 range.setStart(element.parentNode, offset);
201 range.setEnd(element.parentNode, offset + 1);
202 this._editor._selectedRange = range;
203
204 // Note: Chrome (and maybe other browsers) will fire 2 selectionchange event asynchronously, to work around it let's use a timer
205 setTimeout(function() {delete thisRef._editor._selectingResizer;}, 0);
206 } else {
207 this._draggedElement.parentNode.classList.add("dragged");