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,55 @@
1
+ /**
2
+ * SelectionMatcher.js
3
+ *
4
+ * Released under LGPL License.
5
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
6
+ *
7
+ * License: http://www.tinymce.com/license
8
+ * Contributing: http://www.tinymce.com/contributing
9
+ */
10
+
11
+ define('tinymce/inlite/core/SelectionMatcher', [
12
+ 'tinymce/inlite/core/Matcher',
13
+ 'tinymce/inlite/core/Measure'
14
+ ], function (Matcher, Measure) {
15
+ // textSelection :: String -> (Editor -> Matcher.result | Null)
16
+ var textSelection = function (id) {
17
+ return function (editor) {
18
+ if (!editor.selection.isCollapsed()) {
19
+ return Matcher.result(id, Measure.getSelectionRect(editor));
20
+ }
21
+
22
+ return null;
23
+ };
24
+ };
25
+
26
+ // emptyTextBlock :: [Elements], String -> (Editor -> Matcher.result | Null)
27
+ var emptyTextBlock = function (elements, id) {
28
+ return function (editor) {
29
+ var i, textBlockElementsMap = editor.schema.getTextBlockElements();
30
+
31
+ for (i = 0; i < elements.length; i++) {
32
+ if (elements[i].nodeName === 'TABLE') {
33
+ return null;
34
+ }
35
+ }
36
+
37
+ for (i = 0; i < elements.length; i++) {
38
+ if (elements[i].nodeName in textBlockElementsMap) {
39
+ if (editor.dom.isEmpty(elements[i])) {
40
+ return Matcher.result(id, Measure.getSelectionRect(editor));
41
+ }
42
+
43
+ return null;
44
+ }
45
+ }
46
+
47
+ return null;
48
+ };
49
+ };
50
+
51
+ return {
52
+ textSelection: textSelection,
53
+ emptyTextBlock: emptyTextBlock
54
+ };
55
+ });
@@ -0,0 +1,45 @@
1
+ /**
2
+ * SkinLoader.js
3
+ *
4
+ * Released under LGPL License.
5
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
6
+ *
7
+ * License: http://www.tinymce.com/license
8
+ * Contributing: http://www.tinymce.com/contributing
9
+ */
10
+
11
+ define('tinymce/inlite/core/SkinLoader', [
12
+ 'global!tinymce.EditorManager',
13
+ 'global!tinymce.DOM'
14
+ ], function (EditorManager, DOM) {
15
+ var fireSkinLoaded = function (editor, callback) {
16
+ var done = function () {
17
+ editor.fire('SkinLoaded');
18
+ callback();
19
+ };
20
+
21
+ if (editor.initialized) {
22
+ done();
23
+ } else {
24
+ editor.on('init', done);
25
+ }
26
+ };
27
+
28
+ var load = function (editor, skin, callback) {
29
+ var baseUrl = EditorManager.baseURL;
30
+ var skinUrl = baseUrl + '/skins/' + skin;
31
+
32
+ var done = function () {
33
+ fireSkinLoaded(editor, callback);
34
+ };
35
+
36
+ DOM.styleSheetLoader.load(skinUrl + '/skin.min.css', done);
37
+ editor.contentCSS.push(skinUrl + '/content.inline.min.css');
38
+ };
39
+
40
+ return {
41
+ load: load
42
+ };
43
+ });
44
+
45
+
@@ -0,0 +1,22 @@
1
+ /**
2
+ * UrlType.js
3
+ *
4
+ * Released under LGPL License.
5
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
6
+ *
7
+ * License: http://www.tinymce.com/license
8
+ * Contributing: http://www.tinymce.com/contributing
9
+ */
10
+
11
+ define('tinymce/inlite/core/UrlType', [
12
+ ], function () {
13
+ var isDomainLike = function (href) {
14
+ 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());
15
+ };
16
+
17
+ return {
18
+ isDomainLike: isDomainLike
19
+ };
20
+ });
21
+
22
+
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Conversions.js
3
+ *
4
+ * Released under LGPL License.
5
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
6
+ *
7
+ * License: http://www.tinymce.com/license
8
+ * Contributing: http://www.tinymce.com/contributing
9
+ */
10
+
11
+ define('tinymce/inlite/file/Conversions', [
12
+ 'global!tinymce.util.Promise'
13
+ ], function (Promise) {
14
+ var blobToBase64 = function (blob) {
15
+ return new Promise(function(resolve) {
16
+ var reader = new FileReader();
17
+
18
+ reader.onloadend = function() {
19
+ resolve(reader.result.split(',')[1]);
20
+ };
21
+
22
+ reader.readAsDataURL(blob);
23
+ });
24
+ };
25
+
26
+ return {
27
+ blobToBase64: blobToBase64
28
+ };
29
+ });
30
+
31
+
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Picker.js
3
+ *
4
+ * Released under LGPL License.
5
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
6
+ *
7
+ * License: http://www.tinymce.com/license
8
+ * Contributing: http://www.tinymce.com/contributing
9
+ */
10
+
11
+ define('tinymce/inlite/file/Picker', [
12
+ 'global!tinymce.util.Promise'
13
+ ], function (Promise) {
14
+ var pickFile = function () {
15
+ return new Promise(function (resolve) {
16
+ var fileInput;
17
+
18
+ fileInput = document.createElement("input");
19
+ fileInput.type = "file";
20
+ fileInput.style.position = 'fixed';
21
+ fileInput.style.left = 0;
22
+ fileInput.style.top = 0;
23
+ fileInput.style.opacity = 0.001;
24
+ document.body.appendChild(fileInput);
25
+
26
+ fileInput.onchange = function(e) {
27
+ resolve(Array.prototype.slice.call(e.target.files));
28
+ };
29
+
30
+ fileInput.click();
31
+ fileInput.parentNode.removeChild(fileInput);
32
+ });
33
+ };
34
+
35
+ return {
36
+ pickFile: pickFile
37
+ };
38
+ });
39
+
40
+
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Buttons.js
3
+ *
4
+ * Released under LGPL License.
5
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
6
+ *
7
+ * License: http://www.tinymce.com/license
8
+ * Contributing: http://www.tinymce.com/contributing
9
+ */
10
+
11
+ define('tinymce/inlite/ui/Buttons', [
12
+ 'tinymce/inlite/ui/Panel',
13
+ 'tinymce/inlite/file/Conversions',
14
+ 'tinymce/inlite/file/Picker',
15
+ 'tinymce/inlite/core/Actions'
16
+ ], function (Panel, Conversions, Picker, Actions) {
17
+ var addHeaderButtons = function (editor) {
18
+ var formatBlock = function (name) {
19
+ return function () {
20
+ Actions.formatBlock(editor, name);
21
+ };
22
+ };
23
+
24
+ for (var i = 1; i < 6; i++) {
25
+ var name = 'h' + i;
26
+
27
+ editor.addButton(name, {
28
+ text: name.toUpperCase(),
29
+ tooltip: 'Heading ' + i,
30
+ stateSelector: name,
31
+ onclick: formatBlock(name),
32
+ onPostRender: function () {
33
+ // TODO: Remove this hack that produces bold H1-H6 when we have proper icons
34
+ var span = this.getEl().firstChild.firstChild;
35
+ span.style.fontWeight = 'bold';
36
+ }
37
+ });
38
+ }
39
+ };
40
+
41
+ var addToEditor = function (editor) {
42
+ editor.addButton('quicklink', {
43
+ icon: 'link',
44
+ tooltip: 'Insert/Edit link',
45
+ stateSelector: 'a[href]',
46
+ onclick: function () {
47
+ Panel.showForm(editor, 'quicklink');
48
+ }
49
+ });
50
+
51
+ editor.addButton('quickimage', {
52
+ icon: 'image',
53
+ tooltip: 'Insert image',
54
+ onclick: function () {
55
+ Picker.pickFile().then(function (files) {
56
+ var blob = files[0];
57
+
58
+ Conversions.blobToBase64(blob).then(function (base64) {
59
+ Actions.insertBlob(editor, base64, blob);
60
+ });
61
+ });
62
+ }
63
+ });
64
+
65
+ editor.addButton('quicktable', {
66
+ icon: 'table',
67
+ tooltip: 'Insert table',
68
+ onclick: function () {
69
+ Panel.hide();
70
+ Actions.insertTable(editor, 2, 2);
71
+ }
72
+ });
73
+
74
+ addHeaderButtons(editor);
75
+ };
76
+
77
+ return {
78
+ addToEditor: addToEditor
79
+ };
80
+ });
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Forms.js
3
+ *
4
+ * Released under LGPL License.
5
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
6
+ *
7
+ * License: http://www.tinymce.com/license
8
+ * Contributing: http://www.tinymce.com/contributing
9
+ */
10
+
11
+ define('tinymce/inlite/ui/Forms', [
12
+ 'global!tinymce.util.Tools',
13
+ 'global!tinymce.ui.Factory',
14
+ 'global!tinymce.util.Promise',
15
+ 'tinymce/inlite/core/Actions',
16
+ 'tinymce/inlite/core/UrlType'
17
+ ], function (Tools, Factory, Promise, Actions, UrlType) {
18
+ var focusFirstTextBox = function (form) {
19
+ form.find('textbox').eq(0).each(function (ctrl) {
20
+ ctrl.focus();
21
+ });
22
+ };
23
+
24
+ var createForm = function (name, spec) {
25
+ var form = Factory.create(
26
+ Tools.extend({
27
+ type: 'form',
28
+ layout: 'flex',
29
+ direction: 'row',
30
+ padding: 5,
31
+ name: name,
32
+ spacing: 3
33
+ }, spec)
34
+ );
35
+
36
+ form.on('show', function () {
37
+ focusFirstTextBox(form);
38
+ });
39
+
40
+ return form;
41
+ };
42
+
43
+ var toggleVisibility = function (ctrl, state) {
44
+ return state ? ctrl.show() : ctrl.hide();
45
+ };
46
+
47
+ var askAboutPrefix = function (editor, href) {
48
+ return new Promise(function (resolve) {
49
+ editor.windowManager.confirm(
50
+ 'The URL you entered seems to be an external link. Do you want to add the required http:// prefix?',
51
+ function (result) {
52
+ var output = result === true ? 'http://' + href : href;
53
+ resolve(output);
54
+ }
55
+ );
56
+ });
57
+ };
58
+
59
+ var convertLinkToAbsolute = function (editor, href) {
60
+ return UrlType.isDomainLike(href) ? askAboutPrefix(editor, href) : Promise.resolve(href);
61
+ };
62
+
63
+ var createQuickLinkForm = function (editor, hide) {
64
+ var unlink = function () {
65
+ editor.focus();
66
+ Actions.unlink(editor);
67
+ hide();
68
+ };
69
+
70
+ return createForm('quicklink', {
71
+ items: [
72
+ {type: 'button', name: 'unlink', icon: 'unlink', onclick: unlink, tooltip: 'Remove link'},
73
+ {type: 'textbox', name: 'linkurl', placeholder: 'Paste or type a link'},
74
+ {type: 'button', icon: 'checkmark', subtype: 'primary', tooltip: 'Ok', onclick: 'submit'}
75
+ ],
76
+ onshow: function () {
77
+ var elm, linkurl = '';
78
+
79
+ elm = editor.dom.getParent(editor.selection.getStart(), 'a[href]');
80
+ if (elm) {
81
+ linkurl = editor.dom.getAttrib(elm, 'href');
82
+ }
83
+
84
+ this.fromJSON({
85
+ linkurl: linkurl
86
+ });
87
+
88
+ toggleVisibility(this.find('#unlink'), elm);
89
+ },
90
+ onsubmit: function (e) {
91
+ convertLinkToAbsolute(editor, e.data.linkurl).then(function (url) {
92
+ Actions.createLink(editor, url);
93
+ hide();
94
+ });
95
+ }
96
+ });
97
+ };
98
+
99
+ return {
100
+ createQuickLinkForm: createQuickLinkForm
101
+ };
102
+ });
@@ -0,0 +1,216 @@
1
+ /**
2
+ * Panel.js
3
+ *
4
+ * Released under LGPL License.
5
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
6
+ *
7
+ * License: http://www.tinymce.com/license
8
+ * Contributing: http://www.tinymce.com/contributing
9
+ */
10
+
11
+ define('tinymce/inlite/ui/Panel', [
12
+ 'global!tinymce.util.Tools',
13
+ 'global!tinymce.ui.Factory',
14
+ 'global!tinymce.DOM',
15
+ 'tinymce/inlite/ui/Toolbar',
16
+ 'tinymce/inlite/ui/Forms',
17
+ 'tinymce/inlite/core/Measure',
18
+ 'tinymce/inlite/core/Layout'
19
+ ], function (Tools, Factory, DOM, Toolbar, Forms, Measure, Layout) {
20
+ var DEFAULT_TEXT_SELECTION_ITEMS = 'bold italic | quicklink h2 h3 blockquote';
21
+ var DEFAULT_INSERT_TOOLBAR_ITEMS = 'quickimage quicktable';
22
+ var panel, currentRect;
23
+
24
+ var createToolbars = function (editor, toolbars) {
25
+ return Tools.map(toolbars, function (toolbar) {
26
+ return Toolbar.create(editor, toolbar.id, toolbar.items);
27
+ });
28
+ };
29
+
30
+ var getTextSelectionToolbarItems = function (settings) {
31
+ var value = settings.selection_toolbar;
32
+ return value ? value : DEFAULT_TEXT_SELECTION_ITEMS;
33
+ };
34
+
35
+ var getInsertToolbarItems = function (settings) {
36
+ var value = settings.insert_toolbar;
37
+ return value ? value : DEFAULT_INSERT_TOOLBAR_ITEMS;
38
+ };
39
+
40
+ var create = function (editor, toolbars) {
41
+ var items, settings = editor.settings;
42
+
43
+ items = createToolbars(editor, toolbars);
44
+ items = items.concat([
45
+ Toolbar.create(editor, 'text', getTextSelectionToolbarItems(settings)),
46
+ Toolbar.create(editor, 'insert', getInsertToolbarItems(settings)),
47
+ Forms.createQuickLinkForm(editor, hide)
48
+ ]);
49
+
50
+ return Factory.create({
51
+ type: 'floatpanel',
52
+ role: 'dialog',
53
+ classes: 'tinymce tinymce-inline arrow',
54
+ ariaLabel: 'Inline toolbar',
55
+ layout: 'flex',
56
+ direction: 'column',
57
+ align: 'stretch',
58
+ autohide: false,
59
+ autofix: true,
60
+ fixed: true,
61
+ border: 1,
62
+ items: items,
63
+ oncancel: function() {
64
+ editor.focus();
65
+ }
66
+ });
67
+ };
68
+
69
+ var showPanel = function (panel) {
70
+ if (panel) {
71
+ panel.show();
72
+ }
73
+ };
74
+
75
+ var movePanelTo = function (panel, pos) {
76
+ panel.moveTo(pos.x, pos.y);
77
+ };
78
+
79
+ var togglePositionClass = function (panel, relPos) {
80
+ relPos = relPos ? relPos.substr(0, 2) : '';
81
+
82
+ Tools.each({
83
+ t: 'down',
84
+ b: 'up',
85
+ c: 'center'
86
+ }, function(cls, pos) {
87
+ panel.classes.toggle('arrow-' + cls, pos === relPos.substr(0, 1));
88
+ });
89
+
90
+ if (relPos === 'cr') {
91
+ panel.classes.toggle('arrow-left', true);
92
+ panel.classes.toggle('arrow-right', false);
93
+ } else if (relPos === 'cl') {
94
+ panel.classes.toggle('arrow-left', true);
95
+ panel.classes.toggle('arrow-right', true);
96
+ } else {
97
+ Tools.each({
98
+ l: 'left',
99
+ r: 'right'
100
+ }, function(cls, pos) {
101
+ panel.classes.toggle('arrow-' + cls, pos === relPos.substr(1, 1));
102
+ });
103
+ }
104
+ };
105
+
106
+ var showToolbar = function (panel, id) {
107
+ var toolbars = panel.items().filter('#' + id);
108
+
109
+ if (toolbars.length > 0) {
110
+ toolbars[0].show();
111
+ panel.reflow();
112
+ }
113
+ };
114
+
115
+ var showPanelAt = function (panel, id, editor, targetRect) {
116
+ var contentAreaRect, panelRect, result, userConstainHandler;
117
+
118
+ showPanel(panel);
119
+ panel.items().hide();
120
+ showToolbar(panel, id);
121
+
122
+ userConstainHandler = editor.settings.inline_toolbar_position_handler;
123
+ contentAreaRect = Measure.getContentAreaRect(editor);
124
+ panelRect = DOM.getRect(panel.getEl());
125
+
126
+ if (id === 'insert') {
127
+ result = Layout.calcInsert(targetRect, contentAreaRect, panelRect);
128
+ } else {
129
+ result = Layout.calc(targetRect, contentAreaRect, panelRect);
130
+ }
131
+
132
+ if (result) {
133
+ panelRect = result.rect;
134
+ currentRect = targetRect;
135
+ movePanelTo(panel, Layout.userConstrain(userConstainHandler, targetRect, contentAreaRect, panelRect));
136
+
137
+ togglePositionClass(panel, result.position);
138
+ } else {
139
+ hide(panel);
140
+ }
141
+ };
142
+
143
+ var hasFormVisible = function () {
144
+ return panel.items().filter('form:visible').length > 0;
145
+ };
146
+
147
+ var showForm = function (editor, id) {
148
+ if (panel) {
149
+ panel.items().hide();
150
+ showToolbar(panel, id);
151
+
152
+ var contentAreaRect, panelRect, result, userConstainHandler;
153
+
154
+ showPanel(panel);
155
+ panel.items().hide();
156
+ showToolbar(panel, id);
157
+
158
+ userConstainHandler = editor.settings.inline_toolbar_position_handler;
159
+ contentAreaRect = Measure.getContentAreaRect(editor);
160
+ panelRect = DOM.getRect(panel.getEl());
161
+
162
+ result = Layout.calc(currentRect, contentAreaRect, panelRect);
163
+
164
+ if (result) {
165
+ panelRect = result.rect;
166
+ movePanelTo(panel, Layout.userConstrain(userConstainHandler, currentRect, contentAreaRect, panelRect));
167
+
168
+ togglePositionClass(panel, result.position);
169
+ }
170
+ }
171
+ };
172
+
173
+ var show = function (editor, id, targetRect, toolbars) {
174
+ if (!panel) {
175
+ panel = create(editor, toolbars);
176
+ panel.renderTo(document.body).reflow().moveTo(targetRect.x, targetRect.y);
177
+ editor.nodeChanged();
178
+ }
179
+
180
+ showPanelAt(panel, id, editor, targetRect);
181
+ };
182
+
183
+ var hide = function () {
184
+ if (panel) {
185
+ panel.hide();
186
+ }
187
+ };
188
+
189
+ var focus = function () {
190
+ if (panel) {
191
+ panel.find('toolbar:visible').eq(0).each(function (item) {
192
+ item.focus(true);
193
+ });
194
+ }
195
+ };
196
+
197
+ var remove = function () {
198
+ if (panel) {
199
+ panel.remove();
200
+ panel = null;
201
+ }
202
+ };
203
+
204
+ var inForm = function () {
205
+ return panel && panel.visible() && hasFormVisible();
206
+ };
207
+
208
+ return {
209
+ show: show,
210
+ showForm: showForm,
211
+ inForm: inForm,
212
+ hide: hide,
213
+ focus: focus,
214
+ remove: remove
215
+ };
216
+ });