rev |
line source |
bsw/jbe@1309
|
1 /**
|
bsw/jbe@1309
|
2 * Toolbar Dialog
|
bsw/jbe@1309
|
3 *
|
bsw/jbe@1309
|
4 * @param {Element} link The toolbar link which causes the dialog to show up
|
bsw/jbe@1309
|
5 * @param {Element} container The dialog container
|
bsw/jbe@1309
|
6 *
|
bsw/jbe@1309
|
7 * @example
|
bsw/jbe@1309
|
8 * <!-- Toolbar link -->
|
bsw/jbe@1309
|
9 * <a data-wysihtml-command="insertImage">insert an image</a>
|
bsw/jbe@1309
|
10 *
|
bsw/jbe@1309
|
11 * <!-- Dialog -->
|
bsw/jbe@1309
|
12 * <div data-wysihtml-dialog="insertImage" style="display: none;">
|
bsw/jbe@1309
|
13 * <label>
|
bsw/jbe@1309
|
14 * URL: <input data-wysihtml-dialog-field="src" value="http://">
|
bsw/jbe@1309
|
15 * </label>
|
bsw/jbe@1309
|
16 * <label>
|
bsw/jbe@1309
|
17 * Alternative text: <input data-wysihtml-dialog-field="alt" value="">
|
bsw/jbe@1309
|
18 * </label>
|
bsw/jbe@1309
|
19 * </div>
|
bsw/jbe@1309
|
20 *
|
bsw/jbe@1309
|
21 * <script>
|
bsw/jbe@1309
|
22 * var dialog = new wysihtml.toolbar.Dialog(
|
bsw/jbe@1309
|
23 * document.querySelector("[data-wysihtml-command='insertImage']"),
|
bsw/jbe@1309
|
24 * document.querySelector("[data-wysihtml-dialog='insertImage']")
|
bsw/jbe@1309
|
25 * );
|
bsw/jbe@1309
|
26 * dialog.observe("save", function(attributes) {
|
bsw/jbe@1309
|
27 * // do something
|
bsw/jbe@1309
|
28 * });
|
bsw/jbe@1309
|
29 * </script>
|
bsw/jbe@1309
|
30 */
|
bsw/jbe@1309
|
31 (function(wysihtml) {
|
bsw/jbe@1309
|
32 var dom = wysihtml.dom,
|
bsw/jbe@1309
|
33 CLASS_NAME_OPENED = "wysihtml-command-dialog-opened",
|
bsw/jbe@1309
|
34 SELECTOR_FORM_ELEMENTS = "input, select, textarea",
|
bsw/jbe@1309
|
35 SELECTOR_FIELDS = "[data-wysihtml-dialog-field]",
|
bsw/jbe@1309
|
36 ATTRIBUTE_FIELDS = "data-wysihtml-dialog-field";
|
bsw/jbe@1309
|
37
|
bsw/jbe@1309
|
38
|
bsw/jbe@1309
|
39 wysihtml.toolbar.Dialog = wysihtml.lang.Dispatcher.extend(
|
bsw/jbe@1309
|
40 /** @scope wysihtml.toolbar.Dialog.prototype */ {
|
bsw/jbe@1309
|
41 constructor: function(link, container) {
|
bsw/jbe@1309
|
42 this.link = link;
|
bsw/jbe@1309
|
43 this.container = container;
|
bsw/jbe@1309
|
44 },
|
bsw/jbe@1309
|
45
|
bsw/jbe@1309
|
46 _observe: function() {
|
bsw/jbe@1309
|
47 if (this._observed) {
|
bsw/jbe@1309
|
48 return;
|
bsw/jbe@1309
|
49 }
|
bsw/jbe@1309
|
50
|
bsw/jbe@1309
|
51 var that = this,
|
bsw/jbe@1309
|
52 callbackWrapper = function(event) {
|
bsw/jbe@1309
|
53 var attributes = that._serialize();
|
bsw/jbe@1309
|
54 that.fire("save", attributes);
|
bsw/jbe@1309
|
55 that.hide();
|
bsw/jbe@1309
|
56 event.preventDefault();
|
bsw/jbe@1309
|
57 event.stopPropagation();
|
bsw/jbe@1309
|
58 };
|
bsw/jbe@1309
|
59
|
bsw/jbe@1309
|
60 dom.observe(that.link, "click", function() {
|
bsw/jbe@1309
|
61 if (dom.hasClass(that.link, CLASS_NAME_OPENED)) {
|
bsw/jbe@1309
|
62 setTimeout(function() { that.hide(); }, 0);
|
bsw/jbe@1309
|
63 }
|
bsw/jbe@1309
|
64 });
|
bsw/jbe@1309
|
65
|
bsw/jbe@1309
|
66 dom.observe(this.container, "keydown", function(event) {
|
bsw/jbe@1309
|
67 var keyCode = event.keyCode;
|
bsw/jbe@1309
|
68 if (keyCode === wysihtml.ENTER_KEY) {
|
bsw/jbe@1309
|
69 callbackWrapper(event);
|
bsw/jbe@1309
|
70 }
|
bsw/jbe@1309
|
71 if (keyCode === wysihtml.ESCAPE_KEY) {
|
bsw/jbe@1309
|
72 that.cancel();
|
bsw/jbe@1309
|
73 }
|
bsw/jbe@1309
|
74 });
|
bsw/jbe@1309
|
75
|
bsw/jbe@1309
|
76 dom.delegate(this.container, "[data-wysihtml-dialog-action=save]", "click", callbackWrapper);
|
bsw/jbe@1309
|
77
|
bsw/jbe@1309
|
78 dom.delegate(this.container, "[data-wysihtml-dialog-action=cancel]", "click", function(event) {
|
bsw/jbe@1309
|
79 that.cancel();
|
bsw/jbe@1309
|
80 event.preventDefault();
|
bsw/jbe@1309
|
81 event.stopPropagation();
|
bsw/jbe@1309
|
82 });
|
bsw/jbe@1309
|
83
|
bsw/jbe@1309
|
84 this._observed = true;
|
bsw/jbe@1309
|
85 },
|
bsw/jbe@1309
|
86
|
bsw/jbe@1309
|
87 /**
|
bsw/jbe@1309
|
88 * Grabs all fields in the dialog and puts them in key=>value style in an object which
|
bsw/jbe@1309
|
89 * then gets returned
|
bsw/jbe@1309
|
90 */
|
bsw/jbe@1309
|
91 _serialize: function() {
|
bsw/jbe@1309
|
92 var data = {},
|
bsw/jbe@1309
|
93 fields = this.container.querySelectorAll(SELECTOR_FIELDS),
|
bsw/jbe@1309
|
94 length = fields.length,
|
bsw/jbe@1309
|
95 i = 0;
|
bsw/jbe@1309
|
96
|
bsw/jbe@1309
|
97 for (; i<length; i++) {
|
bsw/jbe@1309
|
98 data[fields[i].getAttribute(ATTRIBUTE_FIELDS)] = fields[i].value;
|
bsw/jbe@1309
|
99 }
|
bsw/jbe@1309
|
100 return data;
|
bsw/jbe@1309
|
101 },
|
bsw/jbe@1309
|
102
|
bsw/jbe@1309
|
103 /**
|
bsw/jbe@1309
|
104 * Takes the attributes of the "elementToChange"
|
bsw/jbe@1309
|
105 * and inserts them in their corresponding dialog input fields
|
bsw/jbe@1309
|
106 *
|
bsw/jbe@1309
|
107 * Assume the "elementToChange" looks like this:
|
bsw/jbe@1309
|
108 * <a href="http://www.google.com" target="_blank">foo</a>
|
bsw/jbe@1309
|
109 *
|
bsw/jbe@1309
|
110 * and we have the following dialog:
|
bsw/jbe@1309
|
111 * <input type="text" data-wysihtml-dialog-field="href" value="">
|
bsw/jbe@1309
|
112 * <input type="text" data-wysihtml-dialog-field="target" value="">
|
bsw/jbe@1309
|
113 *
|
bsw/jbe@1309
|
114 * after calling _interpolate() the dialog will look like this
|
bsw/jbe@1309
|
115 * <input type="text" data-wysihtml-dialog-field="href" value="http://www.google.com">
|
bsw/jbe@1309
|
116 * <input type="text" data-wysihtml-dialog-field="target" value="_blank">
|
bsw/jbe@1309
|
117 *
|
bsw/jbe@1309
|
118 * Basically it adopted the attribute values into the corresponding input fields
|
bsw/jbe@1309
|
119 *
|
bsw/jbe@1309
|
120 */
|
bsw/jbe@1309
|
121 _interpolate: function(avoidHiddenFields) {
|
bsw/jbe@1309
|
122 var field,
|
bsw/jbe@1309
|
123 fieldName,
|
bsw/jbe@1309
|
124 newValue,
|
bsw/jbe@1309
|
125 focusedElement = document.querySelector(":focus"),
|
bsw/jbe@1309
|
126 fields = this.container.querySelectorAll(SELECTOR_FIELDS),
|
bsw/jbe@1309
|
127 length = fields.length,
|
bsw/jbe@1309
|
128 i = 0;
|
bsw/jbe@1309
|
129 for (; i<length; i++) {
|
bsw/jbe@1309
|
130 field = fields[i];
|
bsw/jbe@1309
|
131
|
bsw/jbe@1309
|
132 // Never change elements where the user is currently typing in
|
bsw/jbe@1309
|
133 if (field === focusedElement) {
|
bsw/jbe@1309
|
134 continue;
|
bsw/jbe@1309
|
135 }
|
bsw/jbe@1309
|
136
|
bsw/jbe@1309
|
137 // Don't update hidden fields
|
bsw/jbe@1309
|
138 // See https://github.com/xing/wysihtml5/pull/14
|
bsw/jbe@1309
|
139 if (avoidHiddenFields && field.type === "hidden") {
|
bsw/jbe@1309
|
140 continue;
|
bsw/jbe@1309
|
141 }
|
bsw/jbe@1309
|
142
|
bsw/jbe@1309
|
143 fieldName = field.getAttribute(ATTRIBUTE_FIELDS);
|
bsw/jbe@1309
|
144 newValue = (this.elementToChange && typeof(this.elementToChange) !== 'boolean') ? (this.elementToChange.getAttribute(fieldName) || "") : field.defaultValue;
|
bsw/jbe@1309
|
145 field.value = newValue;
|
bsw/jbe@1309
|
146 }
|
bsw/jbe@1309
|
147 },
|
bsw/jbe@1309
|
148
|
bsw/jbe@1309
|
149 update: function (elementToChange) {
|
bsw/jbe@1309
|
150 this.elementToChange = elementToChange ? elementToChange : this.elementToChange;
|
bsw/jbe@1309
|
151 this._interpolate();
|
bsw/jbe@1309
|
152 },
|
bsw/jbe@1309
|
153
|
bsw/jbe@1309
|
154 /**
|
bsw/jbe@1309
|
155 * Show the dialog element
|
bsw/jbe@1309
|
156 */
|
bsw/jbe@1309
|
157 show: function(elementToChange) {
|
bsw/jbe@1309
|
158 var firstField = this.container.querySelector(SELECTOR_FORM_ELEMENTS);
|
bsw/jbe@1309
|
159
|
bsw/jbe@1309
|
160 this._observe();
|
bsw/jbe@1309
|
161 this.update(elementToChange);
|
bsw/jbe@1309
|
162
|
bsw/jbe@1309
|
163 dom.addClass(this.link, CLASS_NAME_OPENED);
|
bsw/jbe@1309
|
164 this.container.style.display = "";
|
bsw/jbe@1309
|
165 this.isOpen = true;
|
bsw/jbe@1309
|
166 this.fire("show");
|
bsw/jbe@1309
|
167
|
bsw/jbe@1309
|
168 if (firstField && !elementToChange) {
|
bsw/jbe@1309
|
169 try {
|
bsw/jbe@1309
|
170 firstField.focus();
|
bsw/jbe@1309
|
171 } catch(e) {}
|
bsw/jbe@1309
|
172 }
|
bsw/jbe@1309
|
173 },
|
bsw/jbe@1309
|
174
|
bsw/jbe@1309
|
175 /**
|
bsw/jbe@1309
|
176 * Hide the dialog element
|
bsw/jbe@1309
|
177 */
|
bsw/jbe@1309
|
178 _hide: function(focus) {
|
bsw/jbe@1309
|
179 this.elementToChange = null;
|
bsw/jbe@1309
|
180 dom.removeClass(this.link, CLASS_NAME_OPENED);
|
bsw/jbe@1309
|
181 this.container.style.display = "none";
|
bsw/jbe@1309
|
182 this.isOpen = false;
|
bsw/jbe@1309
|
183 },
|
bsw/jbe@1309
|
184
|
bsw/jbe@1309
|
185 hide: function() {
|
bsw/jbe@1309
|
186 this._hide();
|
bsw/jbe@1309
|
187 this.fire("hide");
|
bsw/jbe@1309
|
188 },
|
bsw/jbe@1309
|
189
|
bsw/jbe@1309
|
190 cancel: function() {
|
bsw/jbe@1309
|
191 this._hide();
|
bsw/jbe@1309
|
192 this.fire("cancel");
|
bsw/jbe@1309
|
193 }
|
bsw/jbe@1309
|
194 });
|
bsw/jbe@1309
|
195 })(wysihtml); //jshint ignore:line
|
bsw/jbe@1309
|
196
|
bsw/jbe@1309
|
197 (function(wysihtml) {
|
bsw/jbe@1309
|
198 var dom = wysihtml.dom,
|
bsw/jbe@1309
|
199 SELECTOR_FIELDS = "[data-wysihtml-dialog-field]",
|
bsw/jbe@1309
|
200 ATTRIBUTE_FIELDS = "data-wysihtml-dialog-field";
|
bsw/jbe@1309
|
201
|
bsw/jbe@1309
|
202 wysihtml.toolbar.Dialog_bgColorStyle = wysihtml.toolbar.Dialog.extend({
|
bsw/jbe@1309
|
203 multiselect: true,
|
bsw/jbe@1309
|
204
|
bsw/jbe@1309
|
205 _serialize: function() {
|
bsw/jbe@1309
|
206 var data = {},
|
bsw/jbe@1309
|
207 fields = this.container.querySelectorAll(SELECTOR_FIELDS),
|
bsw/jbe@1309
|
208 length = fields.length,
|
bsw/jbe@1309
|
209 i = 0;
|
bsw/jbe@1309
|
210
|
bsw/jbe@1309
|
211 for (; i<length; i++) {
|
bsw/jbe@1309
|
212 data[fields[i].getAttribute(ATTRIBUTE_FIELDS)] = fields[i].value;
|
bsw/jbe@1309
|
213 }
|
bsw/jbe@1309
|
214 return data;
|
bsw/jbe@1309
|
215 },
|
bsw/jbe@1309
|
216
|
bsw/jbe@1309
|
217 _interpolate: function(avoidHiddenFields) {
|
bsw/jbe@1309
|
218 var field,
|
bsw/jbe@1309
|
219 fieldName,
|
bsw/jbe@1309
|
220 newValue,
|
bsw/jbe@1309
|
221 focusedElement = document.querySelector(":focus"),
|
bsw/jbe@1309
|
222 fields = this.container.querySelectorAll(SELECTOR_FIELDS),
|
bsw/jbe@1309
|
223 length = fields.length,
|
bsw/jbe@1309
|
224 i = 0,
|
bsw/jbe@1309
|
225 firstElement = (this.elementToChange) ? ((wysihtml.lang.object(this.elementToChange).isArray()) ? this.elementToChange[0] : this.elementToChange) : null,
|
bsw/jbe@1309
|
226 colorStr = (firstElement) ? firstElement.getAttribute('style') : null,
|
bsw/jbe@1309
|
227 color = (colorStr) ? wysihtml.quirks.styleParser.parseColor(colorStr, "background-color") : null;
|
bsw/jbe@1309
|
228
|
bsw/jbe@1309
|
229 for (; i<length; i++) {
|
bsw/jbe@1309
|
230 field = fields[i];
|
bsw/jbe@1309
|
231 // Never change elements where the user is currently typing in
|
bsw/jbe@1309
|
232 if (field === focusedElement) {
|
bsw/jbe@1309
|
233 continue;
|
bsw/jbe@1309
|
234 }
|
bsw/jbe@1309
|
235 // Don't update hidden fields3
|
bsw/jbe@1309
|
236 if (avoidHiddenFields && field.type === "hidden") {
|
bsw/jbe@1309
|
237 continue;
|
bsw/jbe@1309
|
238 }
|
bsw/jbe@1309
|
239 if (field.getAttribute(ATTRIBUTE_FIELDS) === "color") {
|
bsw/jbe@1309
|
240 if (color) {
|
bsw/jbe@1309
|
241 if (color[3] && color[3] != 1) {
|
bsw/jbe@1309
|
242 field.value = "rgba(" + color[0] + "," + color[1] + "," + color[2] + "," + color[3] + ");";
|
bsw/jbe@1309
|
243 } else {
|
bsw/jbe@1309
|
244 field.value = "rgb(" + color[0] + "," + color[1] + "," + color[2] + ");";
|
bsw/jbe@1309
|
245 }
|
bsw/jbe@1309
|
246 } else {
|
bsw/jbe@1309
|
247 field.value = "rgb(0,0,0);";
|
bsw/jbe@1309
|
248 }
|
bsw/jbe@1309
|
249 }
|
bsw/jbe@1309
|
250 }
|
bsw/jbe@1309
|
251 }
|
bsw/jbe@1309
|
252
|
bsw/jbe@1309
|
253 });
|
bsw/jbe@1309
|
254 })(wysihtml);
|
bsw/jbe@1309
|
255
|
bsw/jbe@1309
|
256 (function(wysihtml) {
|
bsw/jbe@1309
|
257 wysihtml.toolbar.Dialog_createTable = wysihtml.toolbar.Dialog.extend({
|
bsw/jbe@1309
|
258 show: function(elementToChange) {
|
bsw/jbe@1309
|
259 this.base(elementToChange);
|
bsw/jbe@1309
|
260 }
|
bsw/jbe@1309
|
261 });
|
bsw/jbe@1309
|
262 })(wysihtml);
|
bsw/jbe@1309
|
263
|
bsw/jbe@1309
|
264 (function(wysihtml) {
|
bsw/jbe@1309
|
265 var dom = wysihtml.dom,
|
bsw/jbe@1309
|
266 SELECTOR_FIELDS = "[data-wysihtml-dialog-field]",
|
bsw/jbe@1309
|
267 ATTRIBUTE_FIELDS = "data-wysihtml-dialog-field";
|
bsw/jbe@1309
|
268
|
bsw/jbe@1309
|
269 wysihtml.toolbar.Dialog_fontSizeStyle = wysihtml.toolbar.Dialog.extend({
|
bsw/jbe@1309
|
270 multiselect: true,
|
bsw/jbe@1309
|
271
|
bsw/jbe@1309
|
272 _serialize: function() {
|
bsw/jbe@1309
|
273 return {"size" : this.container.querySelector('[data-wysihtml-dialog-field="size"]').value};
|
bsw/jbe@1309
|
274 },
|
bsw/jbe@1309
|
275
|
bsw/jbe@1309
|
276 _interpolate: function(avoidHiddenFields) {
|
bsw/jbe@1309
|
277 var focusedElement = document.querySelector(":focus"),
|
bsw/jbe@1309
|
278 field = this.container.querySelector("[data-wysihtml-dialog-field='size']"),
|
bsw/jbe@1309
|
279 firstElement = (this.elementToChange) ? ((wysihtml.lang.object(this.elementToChange).isArray()) ? this.elementToChange[0] : this.elementToChange) : null,
|
bsw/jbe@1309
|
280 styleStr = (firstElement) ? firstElement.getAttribute('style') : null,
|
bsw/jbe@1309
|
281 size = (styleStr) ? wysihtml.quirks.styleParser.parseFontSize(styleStr) : null;
|
bsw/jbe@1309
|
282
|
bsw/jbe@1309
|
283 if (field && field !== focusedElement && size && !(/^\s*$/).test(size)) {
|
bsw/jbe@1309
|
284 field.value = size;
|
bsw/jbe@1309
|
285 }
|
bsw/jbe@1309
|
286 }
|
bsw/jbe@1309
|
287 });
|
bsw/jbe@1309
|
288 })(wysihtml);
|
bsw/jbe@1309
|
289
|
bsw/jbe@1309
|
290 (function(wysihtml) {
|
bsw/jbe@1309
|
291 var SELECTOR_FIELDS = "[data-wysihtml-dialog-field]",
|
bsw/jbe@1309
|
292 ATTRIBUTE_FIELDS = "data-wysihtml-dialog-field";
|
bsw/jbe@1309
|
293
|
bsw/jbe@1309
|
294 wysihtml.toolbar.Dialog_foreColorStyle = wysihtml.toolbar.Dialog.extend({
|
bsw/jbe@1309
|
295 multiselect: true,
|
bsw/jbe@1309
|
296
|
bsw/jbe@1309
|
297 _serialize: function() {
|
bsw/jbe@1309
|
298 var data = {},
|
bsw/jbe@1309
|
299 fields = this.container.querySelectorAll(SELECTOR_FIELDS),
|
bsw/jbe@1309
|
300 length = fields.length,
|
bsw/jbe@1309
|
301 i = 0;
|
bsw/jbe@1309
|
302
|
bsw/jbe@1309
|
303 for (; i<length; i++) {
|
bsw/jbe@1309
|
304 data[fields[i].getAttribute(ATTRIBUTE_FIELDS)] = fields[i].value;
|
bsw/jbe@1309
|
305 }
|
bsw/jbe@1309
|
306 return data;
|
bsw/jbe@1309
|
307 },
|
bsw/jbe@1309
|
308
|
bsw/jbe@1309
|
309 _interpolate: function(avoidHiddenFields) {
|
bsw/jbe@1309
|
310 var field, colourMode,
|
bsw/jbe@1309
|
311 styleParser = wysihtml.quirks.styleParser,
|
bsw/jbe@1309
|
312 focusedElement = document.querySelector(":focus"),
|
bsw/jbe@1309
|
313 fields = this.container.querySelectorAll(SELECTOR_FIELDS),
|
bsw/jbe@1309
|
314 length = fields.length,
|
bsw/jbe@1309
|
315 i = 0,
|
bsw/jbe@1309
|
316 firstElement = (this.elementToChange) ? ((wysihtml.lang.object(this.elementToChange).isArray()) ? this.elementToChange[0] : this.elementToChange) : null,
|
bsw/jbe@1309
|
317 colourStr = (firstElement) ? firstElement.getAttribute("style") : null,
|
bsw/jbe@1309
|
318 colour = (colourStr) ? styleParser.parseColor(colourStr, "color") : null;
|
bsw/jbe@1309
|
319
|
bsw/jbe@1309
|
320 for (; i<length; i++) {
|
bsw/jbe@1309
|
321 field = fields[i];
|
bsw/jbe@1309
|
322 // Never change elements where the user is currently typing in
|
bsw/jbe@1309
|
323 if (field === focusedElement) {
|
bsw/jbe@1309
|
324 continue;
|
bsw/jbe@1309
|
325 }
|
bsw/jbe@1309
|
326 // Don't update hidden fields3
|
bsw/jbe@1309
|
327 if (avoidHiddenFields && field.type === "hidden") {
|
bsw/jbe@1309
|
328 continue;
|
bsw/jbe@1309
|
329 }
|
bsw/jbe@1309
|
330 if (field.getAttribute(ATTRIBUTE_FIELDS) === "color") {
|
bsw/jbe@1309
|
331 colourMode = (field.dataset.colormode || "rgb").toLowerCase();
|
bsw/jbe@1309
|
332 colourMode = colourMode === "hex" ? "hash" : colourMode;
|
bsw/jbe@1309
|
333
|
bsw/jbe@1309
|
334 if (colour) {
|
bsw/jbe@1309
|
335 field.value = styleParser.unparseColor(colour, colourMode);
|
bsw/jbe@1309
|
336 } else {
|
bsw/jbe@1309
|
337 field.value = styleParser.unparseColor([0, 0, 0], colourMode);
|
bsw/jbe@1309
|
338 }
|
bsw/jbe@1309
|
339 }
|
bsw/jbe@1309
|
340 }
|
bsw/jbe@1309
|
341 }
|
bsw/jbe@1309
|
342
|
bsw/jbe@1309
|
343 });
|
bsw/jbe@1309
|
344 })(wysihtml);
|
bsw/jbe@1309
|
345
|
bsw/jbe@1309
|
346 /**
|
bsw/jbe@1309
|
347 * Converts speech-to-text and inserts this into the editor
|
bsw/jbe@1309
|
348 * As of now (2011/03/25) this only is supported in Chrome >= 11
|
bsw/jbe@1309
|
349 *
|
bsw/jbe@1309
|
350 * Note that it sends the recorded audio to the google speech recognition api:
|
bsw/jbe@1309
|
351 * http://stackoverflow.com/questions/4361826/does-chrome-have-buil-in-speech-recognition-for-input-type-text-x-webkit-speec
|
bsw/jbe@1309
|
352 *
|
bsw/jbe@1309
|
353 * Current HTML5 draft can be found here
|
bsw/jbe@1309
|
354 * http://lists.w3.org/Archives/Public/public-xg-htmlspeech/2011Feb/att-0020/api-draft.html
|
bsw/jbe@1309
|
355 *
|
bsw/jbe@1309
|
356 * "Accessing Google Speech API Chrome 11"
|
bsw/jbe@1309
|
357 * http://mikepultz.com/2011/03/accessing-google-speech-api-chrome-11/
|
bsw/jbe@1309
|
358 */
|
bsw/jbe@1309
|
359 (function(wysihtml) {
|
bsw/jbe@1309
|
360 var dom = wysihtml.dom;
|
bsw/jbe@1309
|
361
|
bsw/jbe@1309
|
362 var linkStyles = {
|
bsw/jbe@1309
|
363 position: "relative"
|
bsw/jbe@1309
|
364 };
|
bsw/jbe@1309
|
365
|
bsw/jbe@1309
|
366 var wrapperStyles = {
|
bsw/jbe@1309
|
367 left: 0,
|
bsw/jbe@1309
|
368 margin: 0,
|
bsw/jbe@1309
|
369 opacity: 0,
|
bsw/jbe@1309
|
370 overflow: "hidden",
|
bsw/jbe@1309
|
371 padding: 0,
|
bsw/jbe@1309
|
372 position: "absolute",
|
bsw/jbe@1309
|
373 top: 0,
|
bsw/jbe@1309
|
374 zIndex: 1
|
bsw/jbe@1309
|
375 };
|
bsw/jbe@1309
|
376
|
bsw/jbe@1309
|
377 var inputStyles = {
|
bsw/jbe@1309
|
378 cursor: "inherit",
|
bsw/jbe@1309
|
379 fontSize: "50px",
|
bsw/jbe@1309
|
380 height: "50px",
|
bsw/jbe@1309
|
381 marginTop: "-25px",
|
bsw/jbe@1309
|
382 outline: 0,
|
bsw/jbe@1309
|
383 padding: 0,
|
bsw/jbe@1309
|
384 position: "absolute",
|
bsw/jbe@1309
|
385 right: "-4px",
|
bsw/jbe@1309
|
386 top: "50%"
|
bsw/jbe@1309
|
387 };
|
bsw/jbe@1309
|
388
|
bsw/jbe@1309
|
389 var inputAttributes = {
|
bsw/jbe@1309
|
390 "x-webkit-speech": "",
|
bsw/jbe@1309
|
391 "speech": ""
|
bsw/jbe@1309
|
392 };
|
bsw/jbe@1309
|
393
|
bsw/jbe@1309
|
394 wysihtml.toolbar.Speech = function(parent, link) {
|
bsw/jbe@1309
|
395 var input = document.createElement("input");
|
bsw/jbe@1309
|
396 if (!wysihtml.browser.supportsSpeechApiOn(input)) {
|
bsw/jbe@1309
|
397 link.style.display = "none";
|
bsw/jbe@1309
|
398 return;
|
bsw/jbe@1309
|
399 }
|
bsw/jbe@1309
|
400 var lang = parent.editor.textarea.element.getAttribute("lang");
|
bsw/jbe@1309
|
401 if (lang) {
|
bsw/jbe@1309
|
402 inputAttributes.lang = lang;
|
bsw/jbe@1309
|
403 }
|
bsw/jbe@1309
|
404
|
bsw/jbe@1309
|
405 var wrapper = document.createElement("div");
|
bsw/jbe@1309
|
406
|
bsw/jbe@1309
|
407 wysihtml.lang.object(wrapperStyles).merge({
|
bsw/jbe@1309
|
408 width: link.offsetWidth + "px",
|
bsw/jbe@1309
|
409 height: link.offsetHeight + "px"
|
bsw/jbe@1309
|
410 });
|
bsw/jbe@1309
|
411
|
bsw/jbe@1309
|
412 dom.insert(input).into(wrapper);
|
bsw/jbe@1309
|
413 dom.insert(wrapper).into(link);
|
bsw/jbe@1309
|
414
|
bsw/jbe@1309
|
415 dom.setStyles(inputStyles).on(input);
|
bsw/jbe@1309
|
416 dom.setAttributes(inputAttributes).on(input);
|
bsw/jbe@1309
|
417
|
bsw/jbe@1309
|
418 dom.setStyles(wrapperStyles).on(wrapper);
|
bsw/jbe@1309
|
419 dom.setStyles(linkStyles).on(link);
|
bsw/jbe@1309
|
420
|
bsw/jbe@1309
|
421 var eventName = "onwebkitspeechchange" in input ? "webkitspeechchange" : "speechchange";
|
bsw/jbe@1309
|
422 dom.observe(input, eventName, function() {
|
bsw/jbe@1309
|
423 parent.execCommand("insertText", input.value);
|
bsw/jbe@1309
|
424 input.value = "";
|
bsw/jbe@1309
|
425 });
|
bsw/jbe@1309
|
426
|
bsw/jbe@1309
|
427 dom.observe(input, "click", function(event) {
|
bsw/jbe@1309
|
428 if (dom.hasClass(link, "wysihtml-command-disabled")) {
|
bsw/jbe@1309
|
429 event.preventDefault();
|
bsw/jbe@1309
|
430 }
|
bsw/jbe@1309
|
431
|
bsw/jbe@1309
|
432 event.stopPropagation();
|
bsw/jbe@1309
|
433 });
|
bsw/jbe@1309
|
434 };
|
bsw/jbe@1309
|
435 })(wysihtml);
|
bsw/jbe@1309
|
436
|
bsw/jbe@1309
|
437 /**
|
bsw/jbe@1309
|
438 * Toolbar
|
bsw/jbe@1309
|
439 *
|
bsw/jbe@1309
|
440 * @param {Object} parent Reference to instance of Editor instance
|
bsw/jbe@1309
|
441 * @param {Element} container Reference to the toolbar container element
|
bsw/jbe@1309
|
442 *
|
bsw/jbe@1309
|
443 * @example
|
bsw/jbe@1309
|
444 * <div id="toolbar">
|
bsw/jbe@1309
|
445 * <a data-wysihtml-command="createLink">insert link</a>
|
bsw/jbe@1309
|
446 * <a data-wysihtml-command="formatBlock" data-wysihtml-command-value="h1">insert h1</a>
|
bsw/jbe@1309
|
447 * </div>
|
bsw/jbe@1309
|
448 *
|
bsw/jbe@1309
|
449 * <script>
|
bsw/jbe@1309
|
450 * var toolbar = new wysihtml.toolbar.Toolbar(editor, document.getElementById("toolbar"));
|
bsw/jbe@1309
|
451 * </script>
|
bsw/jbe@1309
|
452 */
|
bsw/jbe@1309
|
453 (function(wysihtml) {
|
bsw/jbe@1309
|
454 var CLASS_NAME_COMMAND_DISABLED = "wysihtml-command-disabled",
|
bsw/jbe@1309
|
455 CLASS_NAME_COMMANDS_DISABLED = "wysihtml-commands-disabled",
|
bsw/jbe@1309
|
456 CLASS_NAME_COMMAND_ACTIVE = "wysihtml-command-active",
|
bsw/jbe@1309
|
457 CLASS_NAME_ACTION_ACTIVE = "wysihtml-action-active",
|
bsw/jbe@1309
|
458 dom = wysihtml.dom;
|
bsw/jbe@1309
|
459
|
bsw/jbe@1309
|
460 wysihtml.toolbar.Toolbar = Base.extend(
|
bsw/jbe@1309
|
461 /** @scope wysihtml.toolbar.Toolbar.prototype */ {
|
bsw/jbe@1309
|
462 constructor: function(editor, container, showOnInit) {
|
bsw/jbe@1309
|
463 this.editor = editor;
|
bsw/jbe@1309
|
464 this.container = typeof(container) === "string" ? document.getElementById(container) : container;
|
bsw/jbe@1309
|
465 this.composer = editor.composer;
|
bsw/jbe@1309
|
466
|
bsw/jbe@1309
|
467 this._getLinks("command");
|
bsw/jbe@1309
|
468 this._getLinks("action");
|
bsw/jbe@1309
|
469
|
bsw/jbe@1309
|
470 this._observe();
|
bsw/jbe@1309
|
471 if (showOnInit) { this.show(); }
|
bsw/jbe@1309
|
472
|
bsw/jbe@1309
|
473 if (editor.config.classNameCommandDisabled != null) {
|
bsw/jbe@1309
|
474 CLASS_NAME_COMMAND_DISABLED = editor.config.classNameCommandDisabled;
|
bsw/jbe@1309
|
475 }
|
bsw/jbe@1309
|
476 if (editor.config.classNameCommandsDisabled != null) {
|
bsw/jbe@1309
|
477 CLASS_NAME_COMMANDS_DISABLED = editor.config.classNameCommandsDisabled;
|
bsw/jbe@1309
|
478 }
|
bsw/jbe@1309
|
479 if (editor.config.classNameCommandActive != null) {
|
bsw/jbe@1309
|
480 CLASS_NAME_COMMAND_ACTIVE = editor.config.classNameCommandActive;
|
bsw/jbe@1309
|
481 }
|
bsw/jbe@1309
|
482 if (editor.config.classNameActionActive != null) {
|
bsw/jbe@1309
|
483 CLASS_NAME_ACTION_ACTIVE = editor.config.classNameActionActive;
|
bsw/jbe@1309
|
484 }
|
bsw/jbe@1309
|
485
|
bsw/jbe@1309
|
486 var speechInputLinks = this.container.querySelectorAll("[data-wysihtml-command=insertSpeech]"),
|
bsw/jbe@1309
|
487 length = speechInputLinks.length,
|
bsw/jbe@1309
|
488 i = 0;
|
bsw/jbe@1309
|
489 for (; i<length; i++) {
|
bsw/jbe@1309
|
490 new wysihtml.toolbar.Speech(this, speechInputLinks[i]);
|
bsw/jbe@1309
|
491 }
|
bsw/jbe@1309
|
492 },
|
bsw/jbe@1309
|
493
|
bsw/jbe@1309
|
494 _getLinks: function(type) {
|
bsw/jbe@1309
|
495 var links = this[type + "Links"] = wysihtml.lang.array(this.container.querySelectorAll("[data-wysihtml-" + type + "]")).get(),
|
bsw/jbe@1309
|
496 length = links.length,
|
bsw/jbe@1309
|
497 i = 0,
|
bsw/jbe@1309
|
498 mapping = this[type + "Mapping"] = {},
|
bsw/jbe@1309
|
499 link,
|
bsw/jbe@1309
|
500 group,
|
bsw/jbe@1309
|
501 name,
|
bsw/jbe@1309
|
502 value,
|
bsw/jbe@1309
|
503 dialog,
|
bsw/jbe@1309
|
504 tracksBlankValue;
|
bsw/jbe@1309
|
505
|
bsw/jbe@1309
|
506 for (; i<length; i++) {
|
bsw/jbe@1309
|
507 link = links[i];
|
bsw/jbe@1309
|
508 name = link.getAttribute("data-wysihtml-" + type);
|
bsw/jbe@1309
|
509 value = link.getAttribute("data-wysihtml-" + type + "-value");
|
bsw/jbe@1309
|
510 tracksBlankValue = link.getAttribute("data-wysihtml-" + type + "-blank-value");
|
bsw/jbe@1309
|
511 group = this.container.querySelector("[data-wysihtml-" + type + "-group='" + name + "']");
|
bsw/jbe@1309
|
512 dialog = this._getDialog(link, name);
|
bsw/jbe@1309
|
513
|
bsw/jbe@1309
|
514 mapping[name + ":" + value] = {
|
bsw/jbe@1309
|
515 link: link,
|
bsw/jbe@1309
|
516 group: group,
|
bsw/jbe@1309
|
517 name: name,
|
bsw/jbe@1309
|
518 value: value,
|
bsw/jbe@1309
|
519 tracksBlankValue: tracksBlankValue,
|
bsw/jbe@1309
|
520 dialog: dialog,
|
bsw/jbe@1309
|
521 state: false
|
bsw/jbe@1309
|
522 };
|
bsw/jbe@1309
|
523 }
|
bsw/jbe@1309
|
524 },
|
bsw/jbe@1309
|
525
|
bsw/jbe@1309
|
526 _getDialog: function(link, command) {
|
bsw/jbe@1309
|
527 var that = this,
|
bsw/jbe@1309
|
528 dialogElement = this.container.querySelector("[data-wysihtml-dialog='" + command + "']"),
|
bsw/jbe@1309
|
529 dialog, caretBookmark;
|
bsw/jbe@1309
|
530
|
bsw/jbe@1309
|
531 if (dialogElement) {
|
bsw/jbe@1309
|
532 if (wysihtml.toolbar["Dialog_" + command]) {
|
bsw/jbe@1309
|
533 dialog = new wysihtml.toolbar["Dialog_" + command](link, dialogElement);
|
bsw/jbe@1309
|
534 } else {
|
bsw/jbe@1309
|
535 dialog = new wysihtml.toolbar.Dialog(link, dialogElement);
|
bsw/jbe@1309
|
536 }
|
bsw/jbe@1309
|
537
|
bsw/jbe@1309
|
538 dialog.on("show", function() {
|
bsw/jbe@1309
|
539 caretBookmark = that.composer.selection.getBookmark();
|
bsw/jbe@1309
|
540 that.editor.fire("show:dialog", { command: command, dialogContainer: dialogElement, commandLink: link });
|
bsw/jbe@1309
|
541 });
|
bsw/jbe@1309
|
542
|
bsw/jbe@1309
|
543 dialog.on("save", function(attributes) {
|
bsw/jbe@1309
|
544 if (caretBookmark) {
|
bsw/jbe@1309
|
545 that.composer.selection.setBookmark(caretBookmark);
|
bsw/jbe@1309
|
546 }
|
bsw/jbe@1309
|
547 that._execCommand(command, attributes);
|
bsw/jbe@1309
|
548 that.editor.fire("save:dialog", { command: command, dialogContainer: dialogElement, commandLink: link });
|
bsw/jbe@1309
|
549 that._hideAllDialogs();
|
bsw/jbe@1309
|
550 that._preventInstantFocus();
|
bsw/jbe@1309
|
551 caretBookmark = undefined;
|
bsw/jbe@1309
|
552
|
bsw/jbe@1309
|
553 });
|
bsw/jbe@1309
|
554
|
bsw/jbe@1309
|
555 dialog.on("cancel", function() {
|
bsw/jbe@1309
|
556 if (caretBookmark) {
|
bsw/jbe@1309
|
557 that.composer.selection.setBookmark(caretBookmark);
|
bsw/jbe@1309
|
558 }
|
bsw/jbe@1309
|
559 that.editor.fire("cancel:dialog", { command: command, dialogContainer: dialogElement, commandLink: link });
|
bsw/jbe@1309
|
560 caretBookmark = undefined;
|
bsw/jbe@1309
|
561 that._preventInstantFocus();
|
bsw/jbe@1309
|
562 });
|
bsw/jbe@1309
|
563
|
bsw/jbe@1309
|
564 dialog.on("hide", function() {
|
bsw/jbe@1309
|
565 that.editor.fire("hide:dialog", { command: command, dialogContainer: dialogElement, commandLink: link });
|
bsw/jbe@1309
|
566 caretBookmark = undefined;
|
bsw/jbe@1309
|
567 });
|
bsw/jbe@1309
|
568
|
bsw/jbe@1309
|
569 }
|
bsw/jbe@1309
|
570 return dialog;
|
bsw/jbe@1309
|
571 },
|
bsw/jbe@1309
|
572
|
bsw/jbe@1309
|
573 /**
|
bsw/jbe@1309
|
574 * @example
|
bsw/jbe@1309
|
575 * var toolbar = new wysihtml.Toolbar();
|
bsw/jbe@1309
|
576 * // Insert a <blockquote> element or wrap current selection in <blockquote>
|
bsw/jbe@1309
|
577 * toolbar.execCommand("formatBlock", "blockquote");
|
bsw/jbe@1309
|
578 */
|
bsw/jbe@1309
|
579 execCommand: function(command, commandValue) {
|
bsw/jbe@1309
|
580 if (this.commandsDisabled) {
|
bsw/jbe@1309
|
581 return;
|
bsw/jbe@1309
|
582 }
|
bsw/jbe@1309
|
583
|
bsw/jbe@1309
|
584 this._execCommand(command, commandValue);
|
bsw/jbe@1309
|
585 },
|
bsw/jbe@1309
|
586
|
bsw/jbe@1309
|
587 _execCommand: function(command, commandValue) {
|
bsw/jbe@1309
|
588 // Make sure that composer is focussed (false => don't move caret to the end)
|
bsw/jbe@1309
|
589 this.editor.focus(false);
|
bsw/jbe@1309
|
590
|
bsw/jbe@1309
|
591 this.composer.commands.exec(command, commandValue);
|
bsw/jbe@1309
|
592 this._updateLinkStates();
|
bsw/jbe@1309
|
593 },
|
bsw/jbe@1309
|
594
|
bsw/jbe@1309
|
595 execAction: function(action) {
|
bsw/jbe@1309
|
596 var editor = this.editor;
|
bsw/jbe@1309
|
597 if (action === "change_view") {
|
bsw/jbe@1309
|
598 if (editor.currentView === editor.textarea || editor.currentView === "source") {
|
bsw/jbe@1309
|
599 editor.fire("change_view", "composer");
|
bsw/jbe@1309
|
600 } else {
|
bsw/jbe@1309
|
601 editor.fire("change_view", "textarea");
|
bsw/jbe@1309
|
602 }
|
bsw/jbe@1309
|
603 }
|
bsw/jbe@1309
|
604 if (action == "showSource") {
|
bsw/jbe@1309
|
605 editor.fire("showSource");
|
bsw/jbe@1309
|
606 }
|
bsw/jbe@1309
|
607 },
|
bsw/jbe@1309
|
608
|
bsw/jbe@1309
|
609 _observe: function() {
|
bsw/jbe@1309
|
610 var that = this,
|
bsw/jbe@1309
|
611 editor = this.editor,
|
bsw/jbe@1309
|
612 container = this.container,
|
bsw/jbe@1309
|
613 links = this.commandLinks.concat(this.actionLinks),
|
bsw/jbe@1309
|
614 length = links.length,
|
bsw/jbe@1309
|
615 i = 0;
|
bsw/jbe@1309
|
616
|
bsw/jbe@1309
|
617 for (; i<length; i++) {
|
bsw/jbe@1309
|
618 // 'javascript:;' and unselectable=on Needed for IE, but done in all browsers to make sure that all get the same css applied
|
bsw/jbe@1309
|
619 // (you know, a:link { ... } doesn't match anchors with missing href attribute)
|
bsw/jbe@1309
|
620 if (links[i].nodeName === "A") {
|
bsw/jbe@1309
|
621 dom.setAttributes({
|
bsw/jbe@1309
|
622 href: "javascript:;",
|
bsw/jbe@1309
|
623 unselectable: "on"
|
bsw/jbe@1309
|
624 }).on(links[i]);
|
bsw/jbe@1309
|
625 } else {
|
bsw/jbe@1309
|
626 dom.setAttributes({ unselectable: "on" }).on(links[i]);
|
bsw/jbe@1309
|
627 }
|
bsw/jbe@1309
|
628 }
|
bsw/jbe@1309
|
629
|
bsw/jbe@1309
|
630 // Needed for opera and chrome
|
bsw/jbe@1309
|
631 dom.delegate(container, "[data-wysihtml-command], [data-wysihtml-action]", "mousedown", function(event) { event.preventDefault(); });
|
bsw/jbe@1309
|
632
|
bsw/jbe@1309
|
633 dom.delegate(container, "[data-wysihtml-command]", "click", function(event) {
|
bsw/jbe@1309
|
634 var state,
|
bsw/jbe@1309
|
635 link = this,
|
bsw/jbe@1309
|
636 command = link.getAttribute("data-wysihtml-command"),
|
bsw/jbe@1309
|
637 commandValue = link.getAttribute("data-wysihtml-command-value"),
|
bsw/jbe@1309
|
638 commandObj = that.commandMapping[command + ":" + commandValue];
|
bsw/jbe@1309
|
639
|
bsw/jbe@1309
|
640 if (commandValue || !commandObj.dialog) {
|
bsw/jbe@1309
|
641 that.execCommand(command, commandValue);
|
bsw/jbe@1309
|
642 } else {
|
bsw/jbe@1309
|
643 state = getCommandState(that.composer, commandObj);
|
bsw/jbe@1309
|
644 commandObj.dialog.show(state);
|
bsw/jbe@1309
|
645 }
|
bsw/jbe@1309
|
646
|
bsw/jbe@1309
|
647 event.preventDefault();
|
bsw/jbe@1309
|
648 });
|
bsw/jbe@1309
|
649
|
bsw/jbe@1309
|
650 dom.delegate(container, "[data-wysihtml-action]", "click", function(event) {
|
bsw/jbe@1309
|
651 var action = this.getAttribute("data-wysihtml-action");
|
bsw/jbe@1309
|
652 that.execAction(action);
|
bsw/jbe@1309
|
653 event.preventDefault();
|
bsw/jbe@1309
|
654 });
|
bsw/jbe@1309
|
655
|
bsw/jbe@1309
|
656 editor.on("interaction:composer", function(event) {
|
bsw/jbe@1309
|
657 if (!that.preventFocus) {
|
bsw/jbe@1309
|
658 that._updateLinkStates();
|
bsw/jbe@1309
|
659 }
|
bsw/jbe@1309
|
660 });
|
bsw/jbe@1309
|
661
|
bsw/jbe@1309
|
662 this._ownerDocumentClick = function(event) {
|
bsw/jbe@1309
|
663 if (!wysihtml.dom.contains(that.container, event.target) && !wysihtml.dom.contains(that.composer.element, event.target)) {
|
bsw/jbe@1309
|
664 that._updateLinkStates();
|
bsw/jbe@1309
|
665 that._preventInstantFocus();
|
bsw/jbe@1309
|
666 }
|
bsw/jbe@1309
|
667 };
|
bsw/jbe@1309
|
668
|
bsw/jbe@1309
|
669 this.container.ownerDocument.addEventListener("click", this._ownerDocumentClick, false);
|
bsw/jbe@1309
|
670 this.editor.on("destroy:composer", this.destroy.bind(this));
|
bsw/jbe@1309
|
671
|
bsw/jbe@1309
|
672 if (this.editor.config.handleTables) {
|
bsw/jbe@1309
|
673 editor.on("tableselect:composer", function() {
|
bsw/jbe@1309
|
674 that.container.querySelectorAll('[data-wysihtml-hiddentools="table"]')[0].style.display = "";
|
bsw/jbe@1309
|
675 });
|
bsw/jbe@1309
|
676 editor.on("tableunselect:composer", function() {
|
bsw/jbe@1309
|
677 that.container.querySelectorAll('[data-wysihtml-hiddentools="table"]')[0].style.display = "none";
|
bsw/jbe@1309
|
678 });
|
bsw/jbe@1309
|
679 }
|
bsw/jbe@1309
|
680
|
bsw/jbe@1309
|
681 editor.on("change_view", function(currentView) {
|
bsw/jbe@1309
|
682 // Set timeout needed in order to let the blur event fire first
|
bsw/jbe@1309
|
683 setTimeout(function() {
|
bsw/jbe@1309
|
684 that.commandsDisabled = (currentView !== "composer");
|
bsw/jbe@1309
|
685 that._updateLinkStates();
|
bsw/jbe@1309
|
686 if (that.commandsDisabled) {
|
bsw/jbe@1309
|
687 dom.addClass(container, CLASS_NAME_COMMANDS_DISABLED);
|
bsw/jbe@1309
|
688 } else {
|
bsw/jbe@1309
|
689 dom.removeClass(container, CLASS_NAME_COMMANDS_DISABLED);
|
bsw/jbe@1309
|
690 }
|
bsw/jbe@1309
|
691 }, 0);
|
bsw/jbe@1309
|
692 });
|
bsw/jbe@1309
|
693 },
|
bsw/jbe@1309
|
694
|
bsw/jbe@1309
|
695 destroy: function() {
|
bsw/jbe@1309
|
696 this.container.ownerDocument.removeEventListener("click", this._ownerDocumentClick, false);
|
bsw/jbe@1309
|
697 },
|
bsw/jbe@1309
|
698
|
bsw/jbe@1309
|
699 _hideAllDialogs: function() {
|
bsw/jbe@1309
|
700 var commandMapping = this.commandMapping;
|
bsw/jbe@1309
|
701 for (var i in commandMapping) {
|
bsw/jbe@1309
|
702 if (commandMapping[i].dialog) {
|
bsw/jbe@1309
|
703 commandMapping[i].dialog.hide();
|
bsw/jbe@1309
|
704 }
|
bsw/jbe@1309
|
705 }
|
bsw/jbe@1309
|
706 },
|
bsw/jbe@1309
|
707
|
bsw/jbe@1309
|
708 _preventInstantFocus: function() {
|
bsw/jbe@1309
|
709 this.preventFocus = true;
|
bsw/jbe@1309
|
710 setTimeout(function() {
|
bsw/jbe@1309
|
711 this.preventFocus = false;
|
bsw/jbe@1309
|
712 }.bind(this),0);
|
bsw/jbe@1309
|
713 },
|
bsw/jbe@1309
|
714
|
bsw/jbe@1309
|
715 _updateLinkStates: function() {
|
bsw/jbe@1309
|
716
|
bsw/jbe@1309
|
717 var i, state, action, command, displayDialogAttributeValue,
|
bsw/jbe@1309
|
718 commandMapping = this.commandMapping,
|
bsw/jbe@1309
|
719 composer = this.composer,
|
bsw/jbe@1309
|
720 actionMapping = this.actionMapping;
|
bsw/jbe@1309
|
721 // every millisecond counts... this is executed quite often
|
bsw/jbe@1309
|
722 for (i in commandMapping) {
|
bsw/jbe@1309
|
723 command = commandMapping[i];
|
bsw/jbe@1309
|
724 if (this.commandsDisabled) {
|
bsw/jbe@1309
|
725 state = false;
|
bsw/jbe@1309
|
726 dom.removeClass(command.link, CLASS_NAME_COMMAND_ACTIVE);
|
bsw/jbe@1309
|
727 if (command.group) {
|
bsw/jbe@1309
|
728 dom.removeClass(command.group, CLASS_NAME_COMMAND_ACTIVE);
|
bsw/jbe@1309
|
729 }
|
bsw/jbe@1309
|
730 if (command.dialog) {
|
bsw/jbe@1309
|
731 command.dialog.hide();
|
bsw/jbe@1309
|
732 }
|
bsw/jbe@1309
|
733 } else {
|
bsw/jbe@1309
|
734 state = this.composer.commands.state(command.name, command.value);
|
bsw/jbe@1309
|
735 dom.removeClass(command.link, CLASS_NAME_COMMAND_DISABLED);
|
bsw/jbe@1309
|
736 if (command.group) {
|
bsw/jbe@1309
|
737 dom.removeClass(command.group, CLASS_NAME_COMMAND_DISABLED);
|
bsw/jbe@1309
|
738 }
|
bsw/jbe@1309
|
739 }
|
bsw/jbe@1309
|
740 if (command.state === state && !command.tracksBlankValue) {
|
bsw/jbe@1309
|
741 continue;
|
bsw/jbe@1309
|
742 }
|
bsw/jbe@1309
|
743
|
bsw/jbe@1309
|
744 command.state = state;
|
bsw/jbe@1309
|
745 if (state) {
|
bsw/jbe@1309
|
746 if (command.tracksBlankValue) {
|
bsw/jbe@1309
|
747 dom.removeClass(command.link, CLASS_NAME_COMMAND_ACTIVE);
|
bsw/jbe@1309
|
748 } else {
|
bsw/jbe@1309
|
749 dom.addClass(command.link, CLASS_NAME_COMMAND_ACTIVE);
|
bsw/jbe@1309
|
750 if (command.group) {
|
bsw/jbe@1309
|
751 dom.addClass(command.group, CLASS_NAME_COMMAND_ACTIVE);
|
bsw/jbe@1309
|
752 }
|
bsw/jbe@1309
|
753 // commands with fixed value can not have a dialog.
|
bsw/jbe@1309
|
754 if (command.dialog && (typeof command.value === "undefined" || command.value === null)) {
|
bsw/jbe@1309
|
755 if (state && typeof state === "object") {
|
bsw/jbe@1309
|
756 state = getCommandState(composer, command);
|
bsw/jbe@1309
|
757 command.state = state;
|
bsw/jbe@1309
|
758
|
bsw/jbe@1309
|
759 // If dialog has dataset.showdialogonselection set as true,
|
bsw/jbe@1309
|
760 // Dialog displays on text state becoming active regardless of clobal showToolbarDialogsOnSelection options value
|
bsw/jbe@1309
|
761 displayDialogAttributeValue = command.dialog.container.dataset ? command.dialog.container.dataset.showdialogonselection : false;
|
bsw/jbe@1309
|
762
|
bsw/jbe@1309
|
763 if (composer.config.showToolbarDialogsOnSelection || displayDialogAttributeValue) {
|
bsw/jbe@1309
|
764 command.dialog.show(state);
|
bsw/jbe@1309
|
765 } else {
|
bsw/jbe@1309
|
766 command.dialog.update(state);
|
bsw/jbe@1309
|
767 }
|
bsw/jbe@1309
|
768 } else {
|
bsw/jbe@1309
|
769 command.dialog.hide();
|
bsw/jbe@1309
|
770 }
|
bsw/jbe@1309
|
771 }
|
bsw/jbe@1309
|
772 }
|
bsw/jbe@1309
|
773 } else {
|
bsw/jbe@1309
|
774 if (command.tracksBlankValue) {
|
bsw/jbe@1309
|
775 dom.addClass(command.link, CLASS_NAME_COMMAND_ACTIVE);
|
bsw/jbe@1309
|
776 } else {
|
bsw/jbe@1309
|
777 dom.removeClass(command.link, CLASS_NAME_COMMAND_ACTIVE);
|
bsw/jbe@1309
|
778 if (command.group) {
|
bsw/jbe@1309
|
779 dom.removeClass(command.group, CLASS_NAME_COMMAND_ACTIVE);
|
bsw/jbe@1309
|
780 }
|
bsw/jbe@1309
|
781 // commands with fixed value can not have a dialog.
|
bsw/jbe@1309
|
782 if (command.dialog && !command.value) {
|
bsw/jbe@1309
|
783 command.dialog.hide();
|
bsw/jbe@1309
|
784 }
|
bsw/jbe@1309
|
785 }
|
bsw/jbe@1309
|
786 }
|
bsw/jbe@1309
|
787 }
|
bsw/jbe@1309
|
788
|
bsw/jbe@1309
|
789 for (i in actionMapping) {
|
bsw/jbe@1309
|
790 action = actionMapping[i];
|
bsw/jbe@1309
|
791
|
bsw/jbe@1309
|
792 if (action.name === "change_view") {
|
bsw/jbe@1309
|
793 action.state = this.editor.currentView === this.editor.textarea || this.editor.currentView === "source";
|
bsw/jbe@1309
|
794 if (action.state) {
|
bsw/jbe@1309
|
795 dom.addClass(action.link, CLASS_NAME_ACTION_ACTIVE);
|
bsw/jbe@1309
|
796 } else {
|
bsw/jbe@1309
|
797 dom.removeClass(action.link, CLASS_NAME_ACTION_ACTIVE);
|
bsw/jbe@1309
|
798 }
|
bsw/jbe@1309
|
799 }
|
bsw/jbe@1309
|
800 }
|
bsw/jbe@1309
|
801 },
|
bsw/jbe@1309
|
802
|
bsw/jbe@1309
|
803 show: function() {
|
bsw/jbe@1309
|
804 this.container.style.display = "";
|
bsw/jbe@1309
|
805 },
|
bsw/jbe@1309
|
806
|
bsw/jbe@1309
|
807 hide: function() {
|
bsw/jbe@1309
|
808 this.container.style.display = "none";
|
bsw/jbe@1309
|
809 }
|
bsw/jbe@1309
|
810 });
|
bsw/jbe@1309
|
811
|
bsw/jbe@1309
|
812 function getCommandState (composer, command) {
|
bsw/jbe@1309
|
813 var state = composer.commands.state(command.name, command.value);
|
bsw/jbe@1309
|
814
|
bsw/jbe@1309
|
815 // Grab first and only object/element in state array, otherwise convert state into boolean
|
bsw/jbe@1309
|
816 // to avoid showing a dialog for multiple selected elements which may have different attributes
|
bsw/jbe@1309
|
817 // eg. when two links with different href are selected, the state will be an array consisting of both link elements
|
bsw/jbe@1309
|
818 // but the dialog interface can only update one
|
bsw/jbe@1309
|
819 if (!command.dialog.multiselect && wysihtml.lang.object(state).isArray()) {
|
bsw/jbe@1309
|
820 state = state.length === 1 ? state[0] : true;
|
bsw/jbe@1309
|
821 }
|
bsw/jbe@1309
|
822
|
bsw/jbe@1309
|
823 return state;
|
bsw/jbe@1309
|
824 }
|
bsw/jbe@1309
|
825
|
bsw/jbe@1309
|
826 // Extend defaults
|
bsw/jbe@1309
|
827
|
bsw/jbe@1309
|
828 // Id of the toolbar element, pass falsey value if you don't want any toolbar logic
|
bsw/jbe@1309
|
829 wysihtml.Editor.prototype.defaults.toolbar = undefined;
|
bsw/jbe@1309
|
830
|
bsw/jbe@1309
|
831 // Whether toolbar is displayed after init by script automatically.
|
bsw/jbe@1309
|
832 // Can be set to false if toolobar is set to display only on editable area focus
|
bsw/jbe@1309
|
833 wysihtml.Editor.prototype.defaults.showToolbarAfterInit = true;
|
bsw/jbe@1309
|
834
|
bsw/jbe@1309
|
835 // With default toolbar it shows dialogs in toolbar when their related text format state becomes active (click on link in text opens link dialogue)
|
bsw/jbe@1309
|
836 wysihtml.Editor.prototype.defaults.showToolbarDialogsOnSelection= true;
|
bsw/jbe@1309
|
837
|
bsw/jbe@1309
|
838 // Bind toolbar initiation on editor instance creation
|
bsw/jbe@1309
|
839 wysihtml.extendEditor(function(editor) {
|
bsw/jbe@1309
|
840 if (editor.config.toolbar) {
|
bsw/jbe@1309
|
841 editor.toolbar = new wysihtml.toolbar.Toolbar(editor, editor.config.toolbar, editor.config.showToolbarAfterInit);
|
bsw/jbe@1309
|
842 editor.on('destroy:composer', function() {
|
bsw/jbe@1309
|
843 if (editor && editor.toolbar) {
|
bsw/jbe@1309
|
844 editor.toolbar.destroy();
|
bsw/jbe@1309
|
845 }
|
bsw/jbe@1309
|
846 });
|
bsw/jbe@1309
|
847 }
|
bsw/jbe@1309
|
848 });
|
bsw/jbe@1309
|
849
|
bsw/jbe@1309
|
850 })(wysihtml);
|