tinymce-rails 4.3.13 → 4.4.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ });