tinymce-rails 4.3.13 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -2
  3. data/app/assets/source/tinymce/tinymce.js +224 -51
  4. data/lib/tinymce/rails/version.rb +2 -2
  5. data/vendor/assets/javascripts/tinymce/plugins/advlist/plugin.js +1 -1
  6. data/vendor/assets/javascripts/tinymce/plugins/imagetools/plugin.js +1 -1
  7. data/vendor/assets/javascripts/tinymce/plugins/lists/plugin.js +1 -1
  8. data/vendor/assets/javascripts/tinymce/plugins/paste/plugin.js +1 -1
  9. data/vendor/assets/javascripts/tinymce/plugins/table/plugin.js +2 -2
  10. data/vendor/assets/javascripts/tinymce/skins/lightgray/skin.ie7.min.css +1 -1
  11. data/vendor/assets/javascripts/tinymce/skins/lightgray/skin.min.css +1 -1
  12. data/vendor/assets/javascripts/tinymce/themes/inlite/config/bolt/atomic.js +5 -0
  13. data/vendor/assets/javascripts/tinymce/themes/inlite/config/bolt/bootstrap-atomic.js +1491 -0
  14. data/vendor/assets/javascripts/tinymce/themes/inlite/config/bolt/bootstrap-browser.js +1491 -0
  15. data/vendor/assets/javascripts/tinymce/themes/inlite/config/bolt/bootstrap-demo.js +1491 -0
  16. data/vendor/assets/javascripts/tinymce/themes/inlite/config/bolt/bootstrap-prod.js +1491 -0
  17. data/vendor/assets/javascripts/tinymce/themes/inlite/config/bolt/browser.js +10 -0
  18. data/vendor/assets/javascripts/tinymce/themes/inlite/config/bolt/demo.js +8 -0
  19. data/vendor/assets/javascripts/tinymce/themes/inlite/config/bolt/prod.js +5 -0
  20. data/vendor/assets/javascripts/tinymce/themes/inlite/config/dent/depend.js +21 -0
  21. data/vendor/assets/javascripts/tinymce/themes/inlite/scratch/compile/bootstrap.js +1526 -0
  22. data/vendor/assets/javascripts/tinymce/themes/inlite/scratch/compile/theme.js +1589 -0
  23. data/vendor/assets/javascripts/tinymce/themes/inlite/scratch/inline/theme.js +1674 -0
  24. data/vendor/assets/javascripts/tinymce/themes/inlite/scratch/inline/theme.raw.js +1674 -0
  25. data/vendor/assets/javascripts/tinymce/themes/inlite/src/demo/css/demo.css +25 -0
  26. data/vendor/assets/javascripts/tinymce/themes/inlite/src/demo/html/demo.html +42 -0
  27. data/vendor/assets/javascripts/tinymce/themes/inlite/src/demo/js/tinymce/inlite/Demo.js +28 -0
  28. data/vendor/assets/javascripts/tinymce/themes/inlite/src/main/js/tinymce/inlite/Theme.js +143 -0
  29. data/vendor/assets/javascripts/tinymce/themes/inlite/src/main/js/tinymce/inlite/alien/Arr.js +22 -0
  30. data/vendor/assets/javascripts/tinymce/themes/inlite/src/main/js/tinymce/inlite/alien/Bookmark.js +130 -0
  31. data/vendor/assets/javascripts/tinymce/themes/inlite/src/main/js/tinymce/inlite/alien/Unlink.js +84 -0
  32. data/vendor/assets/javascripts/tinymce/themes/inlite/src/main/js/tinymce/inlite/alien/Uuid.js +34 -0
  33. data/vendor/assets/javascripts/tinymce/themes/inlite/src/main/js/tinymce/inlite/core/Actions.js +106 -0
  34. data/vendor/assets/javascripts/tinymce/themes/inlite/src/main/js/tinymce/inlite/core/Convert.js +37 -0
  35. data/vendor/assets/javascripts/tinymce/themes/inlite/src/main/js/tinymce/inlite/core/ElementMatcher.js +47 -0
  36. data/vendor/assets/javascripts/tinymce/themes/inlite/src/main/js/tinymce/inlite/core/Layout.js +95 -0
  37. data/vendor/assets/javascripts/tinymce/themes/inlite/src/main/js/tinymce/inlite/core/Matcher.js +39 -0
  38. data/vendor/assets/javascripts/tinymce/themes/inlite/src/main/js/tinymce/inlite/core/Measure.js +70 -0
  39. data/vendor/assets/javascripts/tinymce/themes/inlite/src/main/js/tinymce/inlite/core/PredicateId.js +32 -0
  40. data/vendor/assets/javascripts/tinymce/themes/inlite/src/main/js/tinymce/inlite/core/SelectionMatcher.js +55 -0
  41. data/vendor/assets/javascripts/tinymce/themes/inlite/src/main/js/tinymce/inlite/core/SkinLoader.js +45 -0
  42. data/vendor/assets/javascripts/tinymce/themes/inlite/src/main/js/tinymce/inlite/core/UrlType.js +22 -0
  43. data/vendor/assets/javascripts/tinymce/themes/inlite/src/main/js/tinymce/inlite/file/Conversions.js +31 -0
  44. data/vendor/assets/javascripts/tinymce/themes/inlite/src/main/js/tinymce/inlite/file/Picker.js +40 -0
  45. data/vendor/assets/javascripts/tinymce/themes/inlite/src/main/js/tinymce/inlite/ui/Buttons.js +80 -0
  46. data/vendor/assets/javascripts/tinymce/themes/inlite/src/main/js/tinymce/inlite/ui/Forms.js +102 -0
  47. data/vendor/assets/javascripts/tinymce/themes/inlite/src/main/js/tinymce/inlite/ui/Panel.js +216 -0
  48. data/vendor/assets/javascripts/tinymce/themes/inlite/src/main/js/tinymce/inlite/ui/Toolbar.js +126 -0
  49. data/vendor/assets/javascripts/tinymce/themes/inlite/src/test/js/atomic/alien/ArrTest.js +9 -0
  50. data/vendor/assets/javascripts/tinymce/themes/inlite/src/test/js/atomic/alien/UuidTest.js +10 -0
  51. data/vendor/assets/javascripts/tinymce/themes/inlite/src/test/js/atomic/core/ConvertTest.js +12 -0
  52. data/vendor/assets/javascripts/tinymce/themes/inlite/src/test/js/atomic/core/MatcherTest.js +51 -0
  53. data/vendor/assets/javascripts/tinymce/themes/inlite/src/test/js/atomic/core/UrlTypeTest.js +25 -0
  54. data/vendor/assets/javascripts/tinymce/themes/inlite/src/test/js/browser/ThemeTest.js +202 -0
  55. data/vendor/assets/javascripts/tinymce/themes/inlite/src/test/js/browser/alien/BookmarkTest.js +65 -0
  56. data/vendor/assets/javascripts/tinymce/themes/inlite/src/test/js/browser/alien/UnlinkTest.js +38 -0
  57. data/vendor/assets/javascripts/tinymce/themes/inlite/src/test/js/browser/core/ActionsTest.js +177 -0
  58. data/vendor/assets/javascripts/tinymce/themes/inlite/src/test/js/browser/core/ElementMatcher.js +69 -0
  59. data/vendor/assets/javascripts/tinymce/themes/inlite/src/test/js/browser/core/LayoutTest.js +118 -0
  60. data/vendor/assets/javascripts/tinymce/themes/inlite/src/test/js/browser/core/MeasureTest.js +62 -0
  61. data/vendor/assets/javascripts/tinymce/themes/inlite/src/test/js/browser/core/PredicateIdTest.js +26 -0
  62. data/vendor/assets/javascripts/tinymce/themes/inlite/src/test/js/browser/core/SelectionMatcherTest.js +76 -0
  63. data/vendor/assets/javascripts/tinymce/themes/inlite/src/test/js/browser/file/ConversionsTest.js +41 -0
  64. data/vendor/assets/javascripts/tinymce/themes/inlite/src/test/js/browser/file/SelectionMatcher.js +55 -0
  65. data/vendor/assets/javascripts/tinymce/themes/inlite/theme.js +1 -0
  66. data/vendor/assets/javascripts/tinymce/themes/modern/theme.js +1 -1
  67. data/vendor/assets/javascripts/tinymce/tinymce.js +13 -13
  68. metadata +57 -3
@@ -0,0 +1,1589 @@
1
+ /*jsc
2
+ ["tinymce/inlite/Theme","global!tinymce.ThemeManager","global!tinymce.util.Delay","tinymce/inlite/ui/Panel","tinymce/inlite/ui/Buttons","tinymce/inlite/core/SkinLoader","tinymce/inlite/core/SelectionMatcher","tinymce/inlite/core/ElementMatcher","tinymce/inlite/core/Matcher","tinymce/inlite/alien/Arr","tinymce/inlite/core/PredicateId","global!tinymce.util.Tools","global!tinymce.ui.Factory","global!tinymce.DOM","tinymce/inlite/ui/Toolbar","tinymce/inlite/ui/Forms","tinymce/inlite/core/Measure","tinymce/inlite/core/Layout","tinymce/inlite/file/Conversions","tinymce/inlite/file/Picker","tinymce/inlite/core/Actions","global!tinymce.EditorManager","global!tinymce.util.Promise","tinymce/inlite/alien/Uuid","tinymce/inlite/alien/Unlink","tinymce/inlite/core/UrlType","global!tinymce.geom.Rect","tinymce/inlite/core/Convert","tinymce/inlite/alien/Bookmark","global!tinymce.dom.TreeWalker","global!tinymce.dom.RangeUtils"]
3
+ jsc*/
4
+ defineGlobal("global!tinymce.ThemeManager", tinymce.ThemeManager);
5
+ defineGlobal("global!tinymce.util.Delay", tinymce.util.Delay);
6
+ defineGlobal("global!tinymce.util.Tools", tinymce.util.Tools);
7
+ defineGlobal("global!tinymce.ui.Factory", tinymce.ui.Factory);
8
+ defineGlobal("global!tinymce.DOM", tinymce.DOM);
9
+ /**
10
+ * Toolbar.js
11
+ *
12
+ * Released under LGPL License.
13
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
14
+ *
15
+ * License: http://www.tinymce.com/license
16
+ * Contributing: http://www.tinymce.com/contributing
17
+ */
18
+
19
+ define('tinymce/inlite/ui/Toolbar', [
20
+ 'global!tinymce.util.Tools',
21
+ 'global!tinymce.ui.Factory'
22
+ ], function (Tools, Factory) {
23
+ var setActiveItem = function (item, name) {
24
+ return function(state, args) {
25
+ var nodeName, i = args.parents.length;
26
+
27
+ while (i--) {
28
+ nodeName = args.parents[i].nodeName;
29
+ if (nodeName == 'OL' || nodeName == 'UL') {
30
+ break;
31
+ }
32
+ }
33
+
34
+ item.active(state && nodeName == name);
35
+ };
36
+ };
37
+
38
+ var getSelectorStateResult = function (itemName, item) {
39
+ var result = function (selector, handler) {
40
+ return {
41
+ selector: selector,
42
+ handler: handler
43
+ };
44
+ };
45
+
46
+ var activeHandler = function(state) {
47
+ item.active(state);
48
+ };
49
+
50
+ var disabledHandler = function (state) {
51
+ item.disabled(state);
52
+ };
53
+
54
+ if (itemName == 'bullist') {
55
+ return result('ul > li', setActiveItem(item, 'UL'));
56
+ }
57
+
58
+ if (itemName == 'numlist') {
59
+ return result('ol > li', setActiveItem(item, 'OL'));
60
+ }
61
+
62
+ if (item.settings.stateSelector) {
63
+ return result(item.settings.stateSelector, activeHandler);
64
+ }
65
+
66
+ if (item.settings.disabledStateSelector) {
67
+ return result(item.settings.disabledStateSelector, disabledHandler);
68
+ }
69
+
70
+ return null;
71
+ };
72
+
73
+ var bindSelectorChanged = function (editor, itemName, item) {
74
+ return function () {
75
+ var result = getSelectorStateResult(itemName, item);
76
+ if (result !== null) {
77
+ editor.selection.selectorChanged(result.selector, result.handler);
78
+ }
79
+ };
80
+ };
81
+
82
+ var create = function (editor, name, items) {
83
+ var toolbarItems = [], buttonGroup;
84
+
85
+ if (!items) {
86
+ return;
87
+ }
88
+
89
+ Tools.each(items.split(/[ ,]/), function(item) {
90
+ var itemName;
91
+
92
+ if (item == '|') {
93
+ buttonGroup = null;
94
+ } else {
95
+ if (Factory.has(item)) {
96
+ item = {type: item};
97
+ toolbarItems.push(item);
98
+ buttonGroup = null;
99
+ } else {
100
+ if (!buttonGroup) {
101
+ buttonGroup = {type: 'buttongroup', items: []};
102
+ toolbarItems.push(buttonGroup);
103
+ }
104
+
105
+ if (editor.buttons[item]) {
106
+ itemName = item;
107
+ item = editor.buttons[itemName];
108
+
109
+ if (typeof item == 'function') {
110
+ item = item();
111
+ }
112
+
113
+ item.type = item.type || 'button';
114
+
115
+ item = Factory.create(item);
116
+ item.on('postRender', bindSelectorChanged(editor, itemName, item));
117
+ buttonGroup.items.push(item);
118
+ }
119
+ }
120
+ }
121
+ });
122
+
123
+ return Factory.create({
124
+ type: 'toolbar',
125
+ layout: 'flow',
126
+ name: name,
127
+ items: toolbarItems
128
+ });
129
+ };
130
+
131
+ return {
132
+ create: create
133
+ };
134
+ });
135
+
136
+ defineGlobal("global!tinymce.util.Promise", tinymce.util.Promise);
137
+ /**
138
+ * Uuid.js
139
+ *
140
+ * Released under LGPL License.
141
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
142
+ *
143
+ * License: http://www.tinymce.com/license
144
+ * Contributing: http://www.tinymce.com/contributing
145
+ */
146
+
147
+ /**
148
+ * Generates unique ids this is the same as in core but since
149
+ * it's not exposed as a global we can't access it.
150
+ */
151
+ define("tinymce/inlite/alien/Uuid", [
152
+ ], function() {
153
+ var count = 0;
154
+
155
+ var seed = function () {
156
+ var rnd = function () {
157
+ return Math.round(Math.random() * 0xFFFFFFFF).toString(36);
158
+ };
159
+
160
+ return 's' + Date.now().toString(36) + rnd() + rnd() + rnd();
161
+ };
162
+
163
+ var uuid = function (prefix) {
164
+ return prefix + (count++) + seed();
165
+ };
166
+
167
+ return {
168
+ uuid: uuid
169
+ };
170
+ });
171
+
172
+ /**
173
+ * Bookmark.js
174
+ *
175
+ * Released under LGPL License.
176
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
177
+ *
178
+ * License: http://www.tinymce.com/license
179
+ * Contributing: http://www.tinymce.com/contributing
180
+ */
181
+
182
+ define('tinymce/inlite/alien/Bookmark', [
183
+ ], function () {
184
+ /**
185
+ * Returns a range bookmark. This will convert indexed bookmarks into temporary span elements with
186
+ * index 0 so that they can be restored properly after the DOM has been modified. Text bookmarks will not have spans
187
+ * added to them since they can be restored after a dom operation.
188
+ *
189
+ * So this: <p><b>|</b><b>|</b></p>
190
+ * becomes: <p><b><span data-mce-type="bookmark">|</span></b><b data-mce-type="bookmark">|</span></b></p>
191
+ *
192
+ * @param {DOMRange} rng DOM Range to get bookmark on.
193
+ * @return {Object} Bookmark object.
194
+ */
195
+ var create = function (dom, rng) {
196
+ var bookmark = {};
197
+
198
+ function setupEndPoint(start) {
199
+ var offsetNode, container, offset;
200
+
201
+ container = rng[start ? 'startContainer' : 'endContainer'];
202
+ offset = rng[start ? 'startOffset' : 'endOffset'];
203
+
204
+ if (container.nodeType == 1) {
205
+ offsetNode = dom.create('span', {'data-mce-type': 'bookmark'});
206
+
207
+ if (container.hasChildNodes()) {
208
+ offset = Math.min(offset, container.childNodes.length - 1);
209
+
210
+ if (start) {
211
+ container.insertBefore(offsetNode, container.childNodes[offset]);
212
+ } else {
213
+ dom.insertAfter(offsetNode, container.childNodes[offset]);
214
+ }
215
+ } else {
216
+ container.appendChild(offsetNode);
217
+ }
218
+
219
+ container = offsetNode;
220
+ offset = 0;
221
+ }
222
+
223
+ bookmark[start ? 'startContainer' : 'endContainer'] = container;
224
+ bookmark[start ? 'startOffset' : 'endOffset'] = offset;
225
+ }
226
+
227
+ setupEndPoint(true);
228
+
229
+ if (!rng.collapsed) {
230
+ setupEndPoint();
231
+ }
232
+
233
+ return bookmark;
234
+ };
235
+
236
+ /**
237
+ * Moves the selection to the current bookmark and removes any selection container wrappers.
238
+ *
239
+ * @param {Object} bookmark Bookmark object to move selection to.
240
+ */
241
+ var resolve = function (dom, bookmark) {
242
+ function restoreEndPoint(start) {
243
+ var container, offset, node;
244
+
245
+ function nodeIndex(container) {
246
+ var node = container.parentNode.firstChild, idx = 0;
247
+
248
+ while (node) {
249
+ if (node == container) {
250
+ return idx;
251
+ }
252
+
253
+ // Skip data-mce-type=bookmark nodes
254
+ if (node.nodeType != 1 || node.getAttribute('data-mce-type') != 'bookmark') {
255
+ idx++;
256
+ }
257
+
258
+ node = node.nextSibling;
259
+ }
260
+
261
+ return -1;
262
+ }
263
+
264
+ container = node = bookmark[start ? 'startContainer' : 'endContainer'];
265
+ offset = bookmark[start ? 'startOffset' : 'endOffset'];
266
+
267
+ if (!container) {
268
+ return;
269
+ }
270
+
271
+ if (container.nodeType == 1) {
272
+ offset = nodeIndex(container);
273
+ container = container.parentNode;
274
+ dom.remove(node);
275
+ }
276
+
277
+ bookmark[start ? 'startContainer' : 'endContainer'] = container;
278
+ bookmark[start ? 'startOffset' : 'endOffset'] = offset;
279
+ }
280
+
281
+ restoreEndPoint(true);
282
+ restoreEndPoint();
283
+
284
+ var rng = dom.createRng();
285
+
286
+ rng.setStart(bookmark.startContainer, bookmark.startOffset);
287
+
288
+ if (bookmark.endContainer) {
289
+ rng.setEnd(bookmark.endContainer, bookmark.endOffset);
290
+ }
291
+
292
+ return rng;
293
+ };
294
+
295
+ return {
296
+ create: create,
297
+ resolve: resolve
298
+ };
299
+ });
300
+
301
+
302
+
303
+ defineGlobal("global!tinymce.dom.TreeWalker", tinymce.dom.TreeWalker);
304
+ defineGlobal("global!tinymce.dom.RangeUtils", tinymce.dom.RangeUtils);
305
+ /**
306
+ * Unlink.js
307
+ *
308
+ * Released under LGPL License.
309
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
310
+ *
311
+ * License: http://www.tinymce.com/license
312
+ * Contributing: http://www.tinymce.com/contributing
313
+ */
314
+
315
+ /**
316
+ * Unlink implementation that doesn't leave partial links for example it would produce:
317
+ * a[b<a href="x">c]d</a>e -> a[bc]de
318
+ * instead of:
319
+ * a[b<a href="x">c]d</a>e -> a[bc]<a href="x">d</a>e
320
+ */
321
+ define("tinymce/inlite/alien/Unlink", [
322
+ 'tinymce/inlite/alien/Bookmark',
323
+ 'global!tinymce.util.Tools',
324
+ 'global!tinymce.dom.TreeWalker',
325
+ 'global!tinymce.dom.RangeUtils'
326
+ ], function (Bookmark, Tools, TreeWalker, RangeUtils) {
327
+ var getSelectedElements = function (rootElm, startNode, endNode) {
328
+ var walker, node, elms = [];
329
+
330
+ walker = new TreeWalker(startNode, rootElm);
331
+ for (node = startNode; node; node = walker.next()) {
332
+ if (node.nodeType === 1) {
333
+ elms.push(node);
334
+ }
335
+
336
+ if (node === endNode) {
337
+ break;
338
+ }
339
+ }
340
+
341
+ return elms;
342
+ };
343
+
344
+ var unwrapElements = function (editor, elms) {
345
+ var bookmark, dom, selection;
346
+
347
+ dom = editor.dom;
348
+ selection = editor.selection;
349
+ bookmark = Bookmark.create(dom, selection.getRng());
350
+
351
+ Tools.each(elms, function (elm) {
352
+ editor.dom.remove(elm, true);
353
+ });
354
+
355
+ selection.setRng(Bookmark.resolve(dom, bookmark));
356
+ };
357
+
358
+ var isLink = function (elm) {
359
+ return elm.nodeName === 'A' && elm.hasAttribute('href');
360
+ };
361
+
362
+ var getParentAnchorOrSelf = function (dom, elm) {
363
+ var anchorElm = dom.getParent(elm, isLink);
364
+ return anchorElm ? anchorElm : elm;
365
+ };
366
+
367
+ var getSelectedAnchors = function (editor) {
368
+ var startElm, endElm, rootElm, anchorElms, selection, dom, rng;
369
+
370
+ selection = editor.selection;
371
+ dom = editor.dom;
372
+ rng = selection.getRng();
373
+ startElm = getParentAnchorOrSelf(dom, RangeUtils.getNode(rng.startContainer, rng.startOffset));
374
+ endElm = RangeUtils.getNode(rng.endContainer, rng.endOffset);
375
+ rootElm = editor.getBody();
376
+ anchorElms = Tools.grep(getSelectedElements(rootElm, startElm, endElm), isLink);
377
+
378
+ return anchorElms;
379
+ };
380
+
381
+ var unlinkSelection = function (editor) {
382
+ unwrapElements(editor, getSelectedAnchors(editor));
383
+ };
384
+
385
+ return {
386
+ unlinkSelection: unlinkSelection
387
+ };
388
+ });
389
+
390
+ /**
391
+ * Actions.js
392
+ *
393
+ * Released under LGPL License.
394
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
395
+ *
396
+ * License: http://www.tinymce.com/license
397
+ * Contributing: http://www.tinymce.com/contributing
398
+ */
399
+
400
+ define('tinymce/inlite/core/Actions', [
401
+ 'tinymce/inlite/alien/Uuid',
402
+ 'tinymce/inlite/alien/Unlink'
403
+ ], function (Uuid, Unlink) {
404
+ var createTableHtml = function (cols, rows) {
405
+ var x, y, html;
406
+
407
+ html = '<table data-mce-id="mce" style="width: 100%">';
408
+ html += '<tbody>';
409
+
410
+ for (y = 0; y < rows; y++) {
411
+ html += '<tr>';
412
+
413
+ for (x = 0; x < cols; x++) {
414
+ html += '<td><br></td>';
415
+ }
416
+
417
+ html += '</tr>';
418
+ }
419
+
420
+ html += '</tbody>';
421
+ html += '</table>';
422
+
423
+ return html;
424
+ };
425
+
426
+ var getInsertedElement = function (editor) {
427
+ var elms = editor.dom.select('*[data-mce-id]');
428
+ return elms[0];
429
+ };
430
+
431
+ var insertTable = function (editor, cols, rows) {
432
+ editor.undoManager.transact(function () {
433
+ var tableElm, cellElm;
434
+
435
+ editor.insertContent(createTableHtml(cols, rows));
436
+
437
+ tableElm = getInsertedElement(editor);
438
+ tableElm.removeAttribute('data-mce-id');
439
+ cellElm = editor.dom.select('td,th', tableElm);
440
+ editor.selection.setCursorLocation(cellElm[0], 0);
441
+ });
442
+ };
443
+
444
+ var formatBlock = function (editor, formatName) {
445
+ editor.execCommand('FormatBlock', false, formatName);
446
+ };
447
+
448
+ var insertBlob = function (editor, base64, blob) {
449
+ var blobCache, blobInfo;
450
+
451
+ blobCache = editor.editorUpload.blobCache;
452
+ blobInfo = blobCache.create(Uuid.uuid('mceu'), blob, base64);
453
+ blobCache.add(blobInfo);
454
+
455
+ editor.insertContent(editor.dom.createHTML('img', {src: blobInfo.blobUri()}));
456
+ };
457
+
458
+ var collapseSelectionToEnd = function (editor) {
459
+ editor.selection.collapse(false);
460
+ };
461
+
462
+ var unlink = function (editor) {
463
+ editor.focus();
464
+ Unlink.unlinkSelection(editor);
465
+ collapseSelectionToEnd(editor);
466
+ };
467
+
468
+ var changeHref = function (editor, elm, url) {
469
+ editor.focus();
470
+ editor.dom.setAttrib(elm, 'href', url);
471
+ collapseSelectionToEnd(editor);
472
+ };
473
+
474
+ var insertLink = function (editor, url) {
475
+ editor.execCommand('mceInsertLink', false, {href: url});
476
+ collapseSelectionToEnd(editor);
477
+ };
478
+
479
+ var updateOrInsertLink = function (editor, url) {
480
+ var elm = editor.dom.getParent(editor.selection.getStart(), 'a[href]');
481
+ elm ? changeHref(editor, elm, url) : insertLink(editor, url);
482
+ };
483
+
484
+ var createLink = function (editor, url) {
485
+ url.trim().length === 0 ? unlink(editor) : updateOrInsertLink(editor, url);
486
+ };
487
+
488
+ return {
489
+ insertTable: insertTable,
490
+ formatBlock: formatBlock,
491
+ insertBlob: insertBlob,
492
+ createLink: createLink,
493
+ unlink: unlink
494
+ };
495
+ });
496
+
497
+ /**
498
+ * UrlType.js
499
+ *
500
+ * Released under LGPL License.
501
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
502
+ *
503
+ * License: http://www.tinymce.com/license
504
+ * Contributing: http://www.tinymce.com/contributing
505
+ */
506
+
507
+ define('tinymce/inlite/core/UrlType', [
508
+ ], function () {
509
+ var isDomainLike = function (href) {
510
+ return /^www\.|\.(com|org|edu|gov|uk|net|ca|de|jp|fr|au|us|ru|ch|it|nl|se|no|es|mil)$/i.test(href.trim());
511
+ };
512
+
513
+ return {
514
+ isDomainLike: isDomainLike
515
+ };
516
+ });
517
+
518
+
519
+
520
+ /**
521
+ * Forms.js
522
+ *
523
+ * Released under LGPL License.
524
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
525
+ *
526
+ * License: http://www.tinymce.com/license
527
+ * Contributing: http://www.tinymce.com/contributing
528
+ */
529
+
530
+ define('tinymce/inlite/ui/Forms', [
531
+ 'global!tinymce.util.Tools',
532
+ 'global!tinymce.ui.Factory',
533
+ 'global!tinymce.util.Promise',
534
+ 'tinymce/inlite/core/Actions',
535
+ 'tinymce/inlite/core/UrlType'
536
+ ], function (Tools, Factory, Promise, Actions, UrlType) {
537
+ var focusFirstTextBox = function (form) {
538
+ form.find('textbox').eq(0).each(function (ctrl) {
539
+ ctrl.focus();
540
+ });
541
+ };
542
+
543
+ var createForm = function (name, spec) {
544
+ var form = Factory.create(
545
+ Tools.extend({
546
+ type: 'form',
547
+ layout: 'flex',
548
+ direction: 'row',
549
+ padding: 5,
550
+ name: name,
551
+ spacing: 3
552
+ }, spec)
553
+ );
554
+
555
+ form.on('show', function () {
556
+ focusFirstTextBox(form);
557
+ });
558
+
559
+ return form;
560
+ };
561
+
562
+ var toggleVisibility = function (ctrl, state) {
563
+ return state ? ctrl.show() : ctrl.hide();
564
+ };
565
+
566
+ var askAboutPrefix = function (editor, href) {
567
+ return new Promise(function (resolve) {
568
+ editor.windowManager.confirm(
569
+ 'The URL you entered seems to be an external link. Do you want to add the required http:// prefix?',
570
+ function (result) {
571
+ var output = result === true ? 'http://' + href : href;
572
+ resolve(output);
573
+ }
574
+ );
575
+ });
576
+ };
577
+
578
+ var convertLinkToAbsolute = function (editor, href) {
579
+ return UrlType.isDomainLike(href) ? askAboutPrefix(editor, href) : Promise.resolve(href);
580
+ };
581
+
582
+ var createQuickLinkForm = function (editor, hide) {
583
+ var unlink = function () {
584
+ editor.focus();
585
+ Actions.unlink(editor);
586
+ hide();
587
+ };
588
+
589
+ return createForm('quicklink', {
590
+ items: [
591
+ {type: 'button', name: 'unlink', icon: 'unlink', onclick: unlink, tooltip: 'Remove link'},
592
+ {type: 'textbox', name: 'linkurl', placeholder: 'Paste or type a link'},
593
+ {type: 'button', icon: 'checkmark', subtype: 'primary', tooltip: 'Ok', onclick: 'submit'}
594
+ ],
595
+ onshow: function () {
596
+ var elm, linkurl = '';
597
+
598
+ elm = editor.dom.getParent(editor.selection.getStart(), 'a[href]');
599
+ if (elm) {
600
+ linkurl = editor.dom.getAttrib(elm, 'href');
601
+ }
602
+
603
+ this.fromJSON({
604
+ linkurl: linkurl
605
+ });
606
+
607
+ toggleVisibility(this.find('#unlink'), elm);
608
+ },
609
+ onsubmit: function (e) {
610
+ convertLinkToAbsolute(editor, e.data.linkurl).then(function (url) {
611
+ Actions.createLink(editor, url);
612
+ hide();
613
+ });
614
+ }
615
+ });
616
+ };
617
+
618
+ return {
619
+ createQuickLinkForm: createQuickLinkForm
620
+ };
621
+ });
622
+
623
+ defineGlobal("global!tinymce.geom.Rect", tinymce.geom.Rect);
624
+ /**
625
+ * Convert.js
626
+ *
627
+ * Released under LGPL License.
628
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
629
+ *
630
+ * License: http://www.tinymce.com/license
631
+ * Contributing: http://www.tinymce.com/contributing
632
+ */
633
+
634
+ define('tinymce/inlite/core/Convert', [
635
+ ], function () {
636
+ var fromClientRect = function (clientRect) {
637
+ return {
638
+ x: clientRect.left,
639
+ y: clientRect.top,
640
+ w: clientRect.width,
641
+ h: clientRect.height
642
+ };
643
+ };
644
+
645
+ var toClientRect = function (geomRect) {
646
+ return {
647
+ left: geomRect.x,
648
+ top: geomRect.y,
649
+ width: geomRect.w,
650
+ height: geomRect.h,
651
+ right: geomRect.x + geomRect.w,
652
+ bottom: geomRect.y + geomRect.h
653
+ };
654
+ };
655
+
656
+ return {
657
+ fromClientRect: fromClientRect,
658
+ toClientRect: toClientRect
659
+ };
660
+ });
661
+
662
+ /**
663
+ * Measure.js
664
+ *
665
+ * Released under LGPL License.
666
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
667
+ *
668
+ * License: http://www.tinymce.com/license
669
+ * Contributing: http://www.tinymce.com/contributing
670
+ */
671
+
672
+ define('tinymce/inlite/core/Measure', [
673
+ 'global!tinymce.DOM',
674
+ 'global!tinymce.geom.Rect',
675
+ 'tinymce/inlite/core/Convert'
676
+ ], function (DOM, Rect, Convert) {
677
+ var toAbsolute = function (rect) {
678
+ var vp = DOM.getViewPort();
679
+
680
+ return {
681
+ x: rect.x + vp.x,
682
+ y: rect.y + vp.y,
683
+ w: rect.w,
684
+ h: rect.h
685
+ };
686
+ };
687
+
688
+ var getElementRect = function (editor, elm) {
689
+ var pos, targetRect, root;
690
+
691
+ pos = DOM.getPos(editor.getContentAreaContainer());
692
+ targetRect = editor.dom.getRect(elm);
693
+ root = editor.dom.getRoot();
694
+
695
+ // Adjust targetPos for scrolling in the editor
696
+ if (root.nodeName == 'BODY') {
697
+ targetRect.x -= root.ownerDocument.documentElement.scrollLeft || root.scrollLeft;
698
+ targetRect.y -= root.ownerDocument.documentElement.scrollTop || root.scrollTop;
699
+ }
700
+
701
+ targetRect.x += pos.x;
702
+ targetRect.y += pos.y;
703
+
704
+ // We need to use these instead of the rect values since the style
705
+ // size properites might not be the same as the real size for a table
706
+ targetRect.w = elm.clientWidth > 0 ? elm.clientWidth : elm.offsetWidth;
707
+ targetRect.h = elm.clientHeight > 0 ? elm.clientHeight : elm.offsetHeight;
708
+
709
+ return targetRect;
710
+ };
711
+
712
+ var getPageAreaRect = function (editor) {
713
+ return DOM.getRect(editor.getElement().ownerDocument.body);
714
+ };
715
+
716
+ var getContentAreaRect = function (editor) {
717
+ return toAbsolute(DOM.getRect(editor.getContentAreaContainer() || editor.getBody()));
718
+ };
719
+
720
+ var getSelectionRect = function (editor) {
721
+ var clientRect = editor.selection.getBoundingClientRect();
722
+ return clientRect ? toAbsolute(Convert.fromClientRect(clientRect)) : null;
723
+ };
724
+
725
+ return {
726
+ getElementRect: getElementRect,
727
+ getPageAreaRect: getPageAreaRect,
728
+ getContentAreaRect: getContentAreaRect,
729
+ getSelectionRect: getSelectionRect
730
+ };
731
+ });
732
+
733
+ /**
734
+ * Layout.js
735
+ *
736
+ * Released under LGPL License.
737
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
738
+ *
739
+ * License: http://www.tinymce.com/license
740
+ * Contributing: http://www.tinymce.com/contributing
741
+ */
742
+
743
+ define('tinymce/inlite/core/Layout', [
744
+ 'global!tinymce.geom.Rect',
745
+ 'tinymce/inlite/core/Convert'
746
+ ], function (Rect, Convert) {
747
+ var result = function (rect, position) {
748
+ return {
749
+ rect: rect,
750
+ position: position
751
+ };
752
+ };
753
+
754
+ var moveTo = function (rect, toRect) {
755
+ return {x: toRect.x, y: toRect.y, w: rect.w, h: rect.h};
756
+ };
757
+
758
+ var calcByPositions = function (testPositions1, testPositions2, targetRect, contentAreaRect, panelRect) {
759
+ var relPos, relRect, outputPanelRect;
760
+
761
+ relPos = Rect.findBestRelativePosition(panelRect, targetRect, contentAreaRect, testPositions1);
762
+ targetRect = Rect.clamp(targetRect, contentAreaRect);
763
+
764
+ if (relPos) {
765
+ relRect = Rect.relativePosition(panelRect, targetRect, relPos);
766
+ outputPanelRect = moveTo(panelRect, relRect);
767
+ return result(outputPanelRect, relPos);
768
+ }
769
+
770
+ targetRect = Rect.intersect(contentAreaRect, targetRect);
771
+ if (targetRect) {
772
+ relPos = Rect.findBestRelativePosition(panelRect, targetRect, contentAreaRect, testPositions2);
773
+ if (relPos) {
774
+ relRect = Rect.relativePosition(panelRect, targetRect, relPos);
775
+ outputPanelRect = moveTo(panelRect, relRect);
776
+ return result(outputPanelRect, relPos);
777
+ }
778
+
779
+ outputPanelRect = moveTo(panelRect, targetRect);
780
+ return result(outputPanelRect, relPos);
781
+ }
782
+
783
+ return null;
784
+ };
785
+
786
+ var calcInsert = function (targetRect, contentAreaRect, panelRect) {
787
+ return calcByPositions(
788
+ ['cr-cl', 'cl-cr'],
789
+ ['bc-tc', 'bl-tl', 'br-tr'],
790
+ targetRect,
791
+ contentAreaRect,
792
+ panelRect
793
+ );
794
+ };
795
+
796
+ var calc = function (targetRect, contentAreaRect, panelRect) {
797
+ return calcByPositions(
798
+ ['tc-bc', 'bc-tc', 'tl-bl', 'bl-tl', 'tr-br', 'br-tr'],
799
+ ['bc-tc', 'bl-tl', 'br-tr'],
800
+ targetRect,
801
+ contentAreaRect,
802
+ panelRect
803
+ );
804
+ };
805
+
806
+ var userConstrain = function (handler, targetRect, contentAreaRect, panelRect) {
807
+ var userConstrainedPanelRect;
808
+
809
+ if (typeof handler === 'function') {
810
+ userConstrainedPanelRect = handler({
811
+ elementRect: Convert.toClientRect(targetRect),
812
+ contentAreaRect: Convert.toClientRect(contentAreaRect),
813
+ panelRect: Convert.toClientRect(panelRect)
814
+ });
815
+
816
+ return Convert.fromClientRect(userConstrainedPanelRect);
817
+ }
818
+
819
+ return panelRect;
820
+ };
821
+
822
+ return {
823
+ calcInsert: calcInsert,
824
+ calc: calc,
825
+ userConstrain: userConstrain
826
+ };
827
+ });
828
+
829
+ /**
830
+ * Panel.js
831
+ *
832
+ * Released under LGPL License.
833
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
834
+ *
835
+ * License: http://www.tinymce.com/license
836
+ * Contributing: http://www.tinymce.com/contributing
837
+ */
838
+
839
+ define('tinymce/inlite/ui/Panel', [
840
+ 'global!tinymce.util.Tools',
841
+ 'global!tinymce.ui.Factory',
842
+ 'global!tinymce.DOM',
843
+ 'tinymce/inlite/ui/Toolbar',
844
+ 'tinymce/inlite/ui/Forms',
845
+ 'tinymce/inlite/core/Measure',
846
+ 'tinymce/inlite/core/Layout'
847
+ ], function (Tools, Factory, DOM, Toolbar, Forms, Measure, Layout) {
848
+ var DEFAULT_TEXT_SELECTION_ITEMS = 'bold italic | quicklink h2 h3 blockquote';
849
+ var DEFAULT_INSERT_TOOLBAR_ITEMS = 'quickimage quicktable';
850
+ var panel, currentRect;
851
+
852
+ var createToolbars = function (editor, toolbars) {
853
+ return Tools.map(toolbars, function (toolbar) {
854
+ return Toolbar.create(editor, toolbar.id, toolbar.items);
855
+ });
856
+ };
857
+
858
+ var getTextSelectionToolbarItems = function (settings) {
859
+ var value = settings.selection_toolbar;
860
+ return value ? value : DEFAULT_TEXT_SELECTION_ITEMS;
861
+ };
862
+
863
+ var getInsertToolbarItems = function (settings) {
864
+ var value = settings.insert_toolbar;
865
+ return value ? value : DEFAULT_INSERT_TOOLBAR_ITEMS;
866
+ };
867
+
868
+ var create = function (editor, toolbars) {
869
+ var items, settings = editor.settings;
870
+
871
+ items = createToolbars(editor, toolbars);
872
+ items = items.concat([
873
+ Toolbar.create(editor, 'text', getTextSelectionToolbarItems(settings)),
874
+ Toolbar.create(editor, 'insert', getInsertToolbarItems(settings)),
875
+ Forms.createQuickLinkForm(editor, hide)
876
+ ]);
877
+
878
+ return Factory.create({
879
+ type: 'floatpanel',
880
+ role: 'dialog',
881
+ classes: 'tinymce tinymce-inline arrow',
882
+ ariaLabel: 'Inline toolbar',
883
+ layout: 'flex',
884
+ direction: 'column',
885
+ align: 'stretch',
886
+ autohide: false,
887
+ autofix: true,
888
+ fixed: true,
889
+ border: 1,
890
+ items: items,
891
+ oncancel: function() {
892
+ editor.focus();
893
+ }
894
+ });
895
+ };
896
+
897
+ var showPanel = function (panel) {
898
+ if (panel) {
899
+ panel.show();
900
+ }
901
+ };
902
+
903
+ var movePanelTo = function (panel, pos) {
904
+ panel.moveTo(pos.x, pos.y);
905
+ };
906
+
907
+ var togglePositionClass = function (panel, relPos) {
908
+ relPos = relPos ? relPos.substr(0, 2) : '';
909
+
910
+ Tools.each({
911
+ t: 'down',
912
+ b: 'up',
913
+ c: 'center'
914
+ }, function(cls, pos) {
915
+ panel.classes.toggle('arrow-' + cls, pos === relPos.substr(0, 1));
916
+ });
917
+
918
+ if (relPos === 'cr') {
919
+ panel.classes.toggle('arrow-left', true);
920
+ panel.classes.toggle('arrow-right', false);
921
+ } else if (relPos === 'cl') {
922
+ panel.classes.toggle('arrow-left', true);
923
+ panel.classes.toggle('arrow-right', true);
924
+ } else {
925
+ Tools.each({
926
+ l: 'left',
927
+ r: 'right'
928
+ }, function(cls, pos) {
929
+ panel.classes.toggle('arrow-' + cls, pos === relPos.substr(1, 1));
930
+ });
931
+ }
932
+ };
933
+
934
+ var showToolbar = function (panel, id) {
935
+ var toolbars = panel.items().filter('#' + id);
936
+
937
+ if (toolbars.length > 0) {
938
+ toolbars[0].show();
939
+ panel.reflow();
940
+ }
941
+ };
942
+
943
+ var showPanelAt = function (panel, id, editor, targetRect) {
944
+ var contentAreaRect, panelRect, result, userConstainHandler;
945
+
946
+ showPanel(panel);
947
+ panel.items().hide();
948
+ showToolbar(panel, id);
949
+
950
+ userConstainHandler = editor.settings.inline_toolbar_position_handler;
951
+ contentAreaRect = Measure.getContentAreaRect(editor);
952
+ panelRect = DOM.getRect(panel.getEl());
953
+
954
+ if (id === 'insert') {
955
+ result = Layout.calcInsert(targetRect, contentAreaRect, panelRect);
956
+ } else {
957
+ result = Layout.calc(targetRect, contentAreaRect, panelRect);
958
+ }
959
+
960
+ if (result) {
961
+ panelRect = result.rect;
962
+ currentRect = targetRect;
963
+ movePanelTo(panel, Layout.userConstrain(userConstainHandler, targetRect, contentAreaRect, panelRect));
964
+
965
+ togglePositionClass(panel, result.position);
966
+ } else {
967
+ hide(panel);
968
+ }
969
+ };
970
+
971
+ var hasFormVisible = function () {
972
+ return panel.items().filter('form:visible').length > 0;
973
+ };
974
+
975
+ var showForm = function (editor, id) {
976
+ if (panel) {
977
+ panel.items().hide();
978
+ showToolbar(panel, id);
979
+
980
+ var contentAreaRect, panelRect, result, userConstainHandler;
981
+
982
+ showPanel(panel);
983
+ panel.items().hide();
984
+ showToolbar(panel, id);
985
+
986
+ userConstainHandler = editor.settings.inline_toolbar_position_handler;
987
+ contentAreaRect = Measure.getContentAreaRect(editor);
988
+ panelRect = DOM.getRect(panel.getEl());
989
+
990
+ result = Layout.calc(currentRect, contentAreaRect, panelRect);
991
+
992
+ if (result) {
993
+ panelRect = result.rect;
994
+ movePanelTo(panel, Layout.userConstrain(userConstainHandler, currentRect, contentAreaRect, panelRect));
995
+
996
+ togglePositionClass(panel, result.position);
997
+ }
998
+ }
999
+ };
1000
+
1001
+ var show = function (editor, id, targetRect, toolbars) {
1002
+ if (!panel) {
1003
+ panel = create(editor, toolbars);
1004
+ panel.renderTo(document.body).reflow().moveTo(targetRect.x, targetRect.y);
1005
+ editor.nodeChanged();
1006
+ }
1007
+
1008
+ showPanelAt(panel, id, editor, targetRect);
1009
+ };
1010
+
1011
+ var hide = function () {
1012
+ if (panel) {
1013
+ panel.hide();
1014
+ }
1015
+ };
1016
+
1017
+ var focus = function () {
1018
+ if (panel) {
1019
+ panel.find('toolbar:visible').eq(0).each(function (item) {
1020
+ item.focus(true);
1021
+ });
1022
+ }
1023
+ };
1024
+
1025
+ var remove = function () {
1026
+ if (panel) {
1027
+ panel.remove();
1028
+ panel = null;
1029
+ }
1030
+ };
1031
+
1032
+ var inForm = function () {
1033
+ return panel && panel.visible() && hasFormVisible();
1034
+ };
1035
+
1036
+ return {
1037
+ show: show,
1038
+ showForm: showForm,
1039
+ inForm: inForm,
1040
+ hide: hide,
1041
+ focus: focus,
1042
+ remove: remove
1043
+ };
1044
+ });
1045
+
1046
+ /**
1047
+ * Conversions.js
1048
+ *
1049
+ * Released under LGPL License.
1050
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
1051
+ *
1052
+ * License: http://www.tinymce.com/license
1053
+ * Contributing: http://www.tinymce.com/contributing
1054
+ */
1055
+
1056
+ define('tinymce/inlite/file/Conversions', [
1057
+ 'global!tinymce.util.Promise'
1058
+ ], function (Promise) {
1059
+ var blobToBase64 = function (blob) {
1060
+ return new Promise(function(resolve) {
1061
+ var reader = new FileReader();
1062
+
1063
+ reader.onloadend = function() {
1064
+ resolve(reader.result.split(',')[1]);
1065
+ };
1066
+
1067
+ reader.readAsDataURL(blob);
1068
+ });
1069
+ };
1070
+
1071
+ return {
1072
+ blobToBase64: blobToBase64
1073
+ };
1074
+ });
1075
+
1076
+
1077
+
1078
+ /**
1079
+ * Picker.js
1080
+ *
1081
+ * Released under LGPL License.
1082
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
1083
+ *
1084
+ * License: http://www.tinymce.com/license
1085
+ * Contributing: http://www.tinymce.com/contributing
1086
+ */
1087
+
1088
+ define('tinymce/inlite/file/Picker', [
1089
+ 'global!tinymce.util.Promise'
1090
+ ], function (Promise) {
1091
+ var pickFile = function () {
1092
+ return new Promise(function (resolve) {
1093
+ var fileInput;
1094
+
1095
+ fileInput = document.createElement("input");
1096
+ fileInput.type = "file";
1097
+ fileInput.style.position = 'fixed';
1098
+ fileInput.style.left = 0;
1099
+ fileInput.style.top = 0;
1100
+ fileInput.style.opacity = 0.001;
1101
+ document.body.appendChild(fileInput);
1102
+
1103
+ fileInput.onchange = function(e) {
1104
+ resolve(Array.prototype.slice.call(e.target.files));
1105
+ };
1106
+
1107
+ fileInput.click();
1108
+ fileInput.parentNode.removeChild(fileInput);
1109
+ });
1110
+ };
1111
+
1112
+ return {
1113
+ pickFile: pickFile
1114
+ };
1115
+ });
1116
+
1117
+
1118
+
1119
+ /**
1120
+ * Buttons.js
1121
+ *
1122
+ * Released under LGPL License.
1123
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
1124
+ *
1125
+ * License: http://www.tinymce.com/license
1126
+ * Contributing: http://www.tinymce.com/contributing
1127
+ */
1128
+
1129
+ define('tinymce/inlite/ui/Buttons', [
1130
+ 'tinymce/inlite/ui/Panel',
1131
+ 'tinymce/inlite/file/Conversions',
1132
+ 'tinymce/inlite/file/Picker',
1133
+ 'tinymce/inlite/core/Actions'
1134
+ ], function (Panel, Conversions, Picker, Actions) {
1135
+ var addHeaderButtons = function (editor) {
1136
+ var formatBlock = function (name) {
1137
+ return function () {
1138
+ Actions.formatBlock(editor, name);
1139
+ };
1140
+ };
1141
+
1142
+ for (var i = 1; i < 6; i++) {
1143
+ var name = 'h' + i;
1144
+
1145
+ editor.addButton(name, {
1146
+ text: name.toUpperCase(),
1147
+ tooltip: 'Heading ' + i,
1148
+ stateSelector: name,
1149
+ onclick: formatBlock(name),
1150
+ onPostRender: function () {
1151
+ // TODO: Remove this hack that produces bold H1-H6 when we have proper icons
1152
+ var span = this.getEl().firstChild.firstChild;
1153
+ span.style.fontWeight = 'bold';
1154
+ }
1155
+ });
1156
+ }
1157
+ };
1158
+
1159
+ var addToEditor = function (editor) {
1160
+ editor.addButton('quicklink', {
1161
+ icon: 'link',
1162
+ tooltip: 'Insert/Edit link',
1163
+ stateSelector: 'a[href]',
1164
+ onclick: function () {
1165
+ Panel.showForm(editor, 'quicklink');
1166
+ }
1167
+ });
1168
+
1169
+ editor.addButton('quickimage', {
1170
+ icon: 'image',
1171
+ tooltip: 'Insert image',
1172
+ onclick: function () {
1173
+ Picker.pickFile().then(function (files) {
1174
+ var blob = files[0];
1175
+
1176
+ Conversions.blobToBase64(blob).then(function (base64) {
1177
+ Actions.insertBlob(editor, base64, blob);
1178
+ });
1179
+ });
1180
+ }
1181
+ });
1182
+
1183
+ editor.addButton('quicktable', {
1184
+ icon: 'table',
1185
+ tooltip: 'Insert table',
1186
+ onclick: function () {
1187
+ Panel.hide();
1188
+ Actions.insertTable(editor, 2, 2);
1189
+ }
1190
+ });
1191
+
1192
+ addHeaderButtons(editor);
1193
+ };
1194
+
1195
+ return {
1196
+ addToEditor: addToEditor
1197
+ };
1198
+ });
1199
+
1200
+ defineGlobal("global!tinymce.EditorManager", tinymce.EditorManager);
1201
+ /**
1202
+ * SkinLoader.js
1203
+ *
1204
+ * Released under LGPL License.
1205
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
1206
+ *
1207
+ * License: http://www.tinymce.com/license
1208
+ * Contributing: http://www.tinymce.com/contributing
1209
+ */
1210
+
1211
+ define('tinymce/inlite/core/SkinLoader', [
1212
+ 'global!tinymce.EditorManager',
1213
+ 'global!tinymce.DOM'
1214
+ ], function (EditorManager, DOM) {
1215
+ var fireSkinLoaded = function (editor, callback) {
1216
+ var done = function () {
1217
+ editor.fire('SkinLoaded');
1218
+ callback();
1219
+ };
1220
+
1221
+ if (editor.initialized) {
1222
+ done();
1223
+ } else {
1224
+ editor.on('init', done);
1225
+ }
1226
+ };
1227
+
1228
+ var load = function (editor, skin, callback) {
1229
+ var baseUrl = EditorManager.baseURL;
1230
+ var skinUrl = baseUrl + '/skins/' + skin;
1231
+
1232
+ var done = function () {
1233
+ fireSkinLoaded(editor, callback);
1234
+ };
1235
+
1236
+ DOM.styleSheetLoader.load(skinUrl + '/skin.min.css', done);
1237
+ editor.contentCSS.push(skinUrl + '/content.inline.min.css');
1238
+ };
1239
+
1240
+ return {
1241
+ load: load
1242
+ };
1243
+ });
1244
+
1245
+
1246
+
1247
+ /**
1248
+ * Matcher.js
1249
+ *
1250
+ * Released under LGPL License.
1251
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
1252
+ *
1253
+ * License: http://www.tinymce.com/license
1254
+ * Contributing: http://www.tinymce.com/contributing
1255
+ */
1256
+
1257
+ define('tinymce/inlite/core/Matcher', [
1258
+ ], function () {
1259
+ // result :: String, Rect -> Matcher.result
1260
+ var result = function (id, rect) {
1261
+ return {
1262
+ id: id,
1263
+ rect: rect
1264
+ };
1265
+ };
1266
+
1267
+ // match :: Editor, [(Editor -> Matcher.result | Null)] -> Matcher.result | Null
1268
+ var match = function (editor, matchers) {
1269
+ for (var i = 0; i < matchers.length; i++) {
1270
+ var f = matchers[i];
1271
+ var result = f(editor);
1272
+
1273
+ if (result) {
1274
+ return result;
1275
+ }
1276
+ }
1277
+
1278
+ return null;
1279
+ };
1280
+
1281
+ return {
1282
+ match: match,
1283
+ result: result
1284
+ };
1285
+ });
1286
+
1287
+ /**
1288
+ * SelectionMatcher.js
1289
+ *
1290
+ * Released under LGPL License.
1291
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
1292
+ *
1293
+ * License: http://www.tinymce.com/license
1294
+ * Contributing: http://www.tinymce.com/contributing
1295
+ */
1296
+
1297
+ define('tinymce/inlite/core/SelectionMatcher', [
1298
+ 'tinymce/inlite/core/Matcher',
1299
+ 'tinymce/inlite/core/Measure'
1300
+ ], function (Matcher, Measure) {
1301
+ // textSelection :: String -> (Editor -> Matcher.result | Null)
1302
+ var textSelection = function (id) {
1303
+ return function (editor) {
1304
+ if (!editor.selection.isCollapsed()) {
1305
+ return Matcher.result(id, Measure.getSelectionRect(editor));
1306
+ }
1307
+
1308
+ return null;
1309
+ };
1310
+ };
1311
+
1312
+ // emptyTextBlock :: [Elements], String -> (Editor -> Matcher.result | Null)
1313
+ var emptyTextBlock = function (elements, id) {
1314
+ return function (editor) {
1315
+ var i, textBlockElementsMap = editor.schema.getTextBlockElements();
1316
+
1317
+ for (i = 0; i < elements.length; i++) {
1318
+ if (elements[i].nodeName === 'TABLE') {
1319
+ return null;
1320
+ }
1321
+ }
1322
+
1323
+ for (i = 0; i < elements.length; i++) {
1324
+ if (elements[i].nodeName in textBlockElementsMap) {
1325
+ if (editor.dom.isEmpty(elements[i])) {
1326
+ return Matcher.result(id, Measure.getSelectionRect(editor));
1327
+ }
1328
+
1329
+ return null;
1330
+ }
1331
+ }
1332
+
1333
+ return null;
1334
+ };
1335
+ };
1336
+
1337
+ return {
1338
+ textSelection: textSelection,
1339
+ emptyTextBlock: emptyTextBlock
1340
+ };
1341
+ });
1342
+
1343
+ /**
1344
+ * ElementMatcher.js
1345
+ *
1346
+ * Released under LGPL License.
1347
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
1348
+ *
1349
+ * License: http://www.tinymce.com/license
1350
+ * Contributing: http://www.tinymce.com/contributing
1351
+ */
1352
+
1353
+ define('tinymce/inlite/core/ElementMatcher', [
1354
+ 'tinymce/inlite/core/Matcher',
1355
+ 'tinymce/inlite/core/Measure'
1356
+ ], function (Matcher, Measure) {
1357
+ // element :: Element, [PredicateId] -> (Editor -> Matcher.result | Null)
1358
+ var element = function (element, predicateIds) {
1359
+ return function (editor) {
1360
+ for (var i = 0; i < predicateIds.length; i++) {
1361
+ if (predicateIds[i].predicate(element)) {
1362
+ return Matcher.result(predicateIds[i].id, Measure.getElementRect(editor, element));
1363
+ }
1364
+ }
1365
+
1366
+ return null;
1367
+ };
1368
+ };
1369
+
1370
+ // parent :: [Elements], [PredicateId] -> (Editor -> Matcher.result | Null)
1371
+ var parent = function (elements, predicateIds) {
1372
+ return function (editor) {
1373
+ for (var i = 0; i < elements.length; i++) {
1374
+ for (var x = 0; x < predicateIds.length; x++) {
1375
+ if (predicateIds[x].predicate(elements[i])) {
1376
+ return Matcher.result(predicateIds[x].id, Measure.getElementRect(editor, elements[i]));
1377
+ }
1378
+ }
1379
+ }
1380
+
1381
+ return null;
1382
+ };
1383
+ };
1384
+
1385
+ return {
1386
+ element: element,
1387
+ parent: parent
1388
+ };
1389
+ });
1390
+
1391
+ /**
1392
+ * Arr.js
1393
+ *
1394
+ * Released under LGPL License.
1395
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
1396
+ *
1397
+ * License: http://www.tinymce.com/license
1398
+ * Contributing: http://www.tinymce.com/contributing
1399
+ */
1400
+
1401
+ define('tinymce/inlite/alien/Arr', [
1402
+ ], function () {
1403
+ var flatten = function (arr) {
1404
+ return arr.reduce(function (results, item) {
1405
+ return Array.isArray(item) ? results.concat(flatten(item)) : results.concat(item);
1406
+ }, []);
1407
+ };
1408
+
1409
+ return {
1410
+ flatten: flatten
1411
+ };
1412
+ });
1413
+
1414
+ /**
1415
+ * PredicateId.js
1416
+ *
1417
+ * Released under LGPL License.
1418
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
1419
+ *
1420
+ * License: http://www.tinymce.com/license
1421
+ * Contributing: http://www.tinymce.com/contributing
1422
+ */
1423
+
1424
+ define('tinymce/inlite/core/PredicateId', [
1425
+ 'global!tinymce.util.Tools'
1426
+ ], function (Tools) {
1427
+ var create = function (id, predicate) {
1428
+ return {
1429
+ id: id,
1430
+ predicate: predicate
1431
+ };
1432
+ };
1433
+
1434
+ // fromContextToolbars :: [ContextToolbar] -> [PredicateId]
1435
+ var fromContextToolbars = function (toolbars) {
1436
+ return Tools.map(toolbars, function (toolbar) {
1437
+ return create(toolbar.id, toolbar.predicate);
1438
+ });
1439
+ };
1440
+
1441
+ return {
1442
+ create: create,
1443
+ fromContextToolbars: fromContextToolbars
1444
+ };
1445
+ });
1446
+
1447
+ /**
1448
+ * Theme.js
1449
+ *
1450
+ * Released under LGPL License.
1451
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
1452
+ *
1453
+ * License: http://www.tinymce.com/license
1454
+ * Contributing: http://www.tinymce.com/contributing
1455
+ */
1456
+
1457
+ define('tinymce/inlite/Theme', [
1458
+ 'global!tinymce.ThemeManager',
1459
+ 'global!tinymce.util.Delay',
1460
+ 'tinymce/inlite/ui/Panel',
1461
+ 'tinymce/inlite/ui/Buttons',
1462
+ 'tinymce/inlite/core/SkinLoader',
1463
+ 'tinymce/inlite/core/SelectionMatcher',
1464
+ 'tinymce/inlite/core/ElementMatcher',
1465
+ 'tinymce/inlite/core/Matcher',
1466
+ 'tinymce/inlite/alien/Arr',
1467
+ 'tinymce/inlite/core/PredicateId'
1468
+ ], function(ThemeManager, Delay, Panel, Buttons, SkinLoader, SelectionMatcher, ElementMatcher, Matcher, Arr, PredicateId) {
1469
+ var getSelectionElements = function (editor) {
1470
+ var node = editor.selection.getNode();
1471
+ var elms = editor.dom.getParents(node);
1472
+ return elms;
1473
+ };
1474
+
1475
+ var createToolbar = function (editor, selector, id, items) {
1476
+ var selectorPredicate = function (elm) {
1477
+ return editor.dom.is(elm, selector);
1478
+ };
1479
+
1480
+ return {
1481
+ predicate: selectorPredicate,
1482
+ id: id,
1483
+ items: items
1484
+ };
1485
+ };
1486
+
1487
+ var getToolbars = function (editor) {
1488
+ var contextToolbars = editor.contextToolbars;
1489
+
1490
+ return Arr.flatten([
1491
+ contextToolbars ? contextToolbars : [],
1492
+ createToolbar(editor, 'img', 'image', 'alignleft aligncenter alignright')
1493
+ ]);
1494
+ };
1495
+
1496
+ var findMatchResult = function (editor, toolbars) {
1497
+ var result, elements, contextToolbarsPredicateIds;
1498
+
1499
+ elements = getSelectionElements(editor);
1500
+ contextToolbarsPredicateIds = PredicateId.fromContextToolbars(toolbars);
1501
+
1502
+ result = Matcher.match(editor, [
1503
+ ElementMatcher.element(elements[0], contextToolbarsPredicateIds),
1504
+ SelectionMatcher.textSelection('text'),
1505
+ SelectionMatcher.emptyTextBlock(elements, 'insert'),
1506
+ ElementMatcher.parent(elements, contextToolbarsPredicateIds)
1507
+ ]);
1508
+
1509
+ return result && result.rect ? result : null;
1510
+ };
1511
+
1512
+ var togglePanel = function (editor) {
1513
+ var toggle = function () {
1514
+ var toolbars = getToolbars(editor);
1515
+ var result = findMatchResult(editor, toolbars);
1516
+ result ? Panel.show(editor, result.id, result.rect, toolbars) : Panel.hide();
1517
+ };
1518
+
1519
+ return function () {
1520
+ if (!editor.removed) {
1521
+ toggle();
1522
+ }
1523
+ };
1524
+ };
1525
+
1526
+ var ignoreWhenFormIsVisible = function (f) {
1527
+ return function () {
1528
+ if (!Panel.inForm()) {
1529
+ f();
1530
+ }
1531
+ };
1532
+ };
1533
+
1534
+ var bindContextualToolbarsEvents = function (editor) {
1535
+ var throttledTogglePanel = Delay.throttle(togglePanel(editor), 0);
1536
+ var throttledTogglePanelWhenNotInForm = Delay.throttle(ignoreWhenFormIsVisible(togglePanel(editor)), 0);
1537
+
1538
+ editor.on('blur hide ObjectResizeStart', Panel.hide);
1539
+ editor.on('click', throttledTogglePanel);
1540
+ editor.on('nodeChange mouseup', throttledTogglePanelWhenNotInForm);
1541
+ editor.on('ResizeEditor ResizeWindow keyup', throttledTogglePanel);
1542
+ editor.on('remove', Panel.remove);
1543
+
1544
+ editor.shortcuts.add('Alt+F10', '', Panel.focus);
1545
+ };
1546
+
1547
+ var overrideLinkShortcut = function (editor) {
1548
+ editor.shortcuts.remove('meta+k');
1549
+ editor.shortcuts.add('meta+k', '', function () {
1550
+ var toolbars = getToolbars(editor);
1551
+ var result = result = Matcher.match(editor, [
1552
+ SelectionMatcher.textSelection('quicklink')
1553
+ ]);
1554
+
1555
+ if (result) {
1556
+ Panel.show(editor, result.id, result.rect, toolbars);
1557
+ }
1558
+ });
1559
+ };
1560
+
1561
+ var renderInlineUI = function (editor) {
1562
+ var skinName = editor.settings.skin || 'lightgray';
1563
+
1564
+ SkinLoader.load(editor, skinName, function () {
1565
+ bindContextualToolbarsEvents(editor);
1566
+ overrideLinkShortcut(editor);
1567
+ });
1568
+
1569
+ return {};
1570
+ };
1571
+
1572
+ var fail = function (message) {
1573
+ throw new Error(message);
1574
+ };
1575
+
1576
+ ThemeManager.add('inlite', function (editor) {
1577
+ Buttons.addToEditor(editor);
1578
+
1579
+ var renderUI = function () {
1580
+ return editor.inline ? renderInlineUI(editor) : fail('inlite theme only supports inline mode.');
1581
+ };
1582
+
1583
+ return {
1584
+ renderUI: renderUI
1585
+ };
1586
+ });
1587
+
1588
+ return function() {};
1589
+ });