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,126 @@
1
+ /**
2
+ * Toolbar.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/Toolbar', [
12
+ 'global!tinymce.util.Tools',
13
+ 'global!tinymce.ui.Factory'
14
+ ], function (Tools, Factory) {
15
+ var setActiveItem = function (item, name) {
16
+ return function(state, args) {
17
+ var nodeName, i = args.parents.length;
18
+
19
+ while (i--) {
20
+ nodeName = args.parents[i].nodeName;
21
+ if (nodeName == 'OL' || nodeName == 'UL') {
22
+ break;
23
+ }
24
+ }
25
+
26
+ item.active(state && nodeName == name);
27
+ };
28
+ };
29
+
30
+ var getSelectorStateResult = function (itemName, item) {
31
+ var result = function (selector, handler) {
32
+ return {
33
+ selector: selector,
34
+ handler: handler
35
+ };
36
+ };
37
+
38
+ var activeHandler = function(state) {
39
+ item.active(state);
40
+ };
41
+
42
+ var disabledHandler = function (state) {
43
+ item.disabled(state);
44
+ };
45
+
46
+ if (itemName == 'bullist') {
47
+ return result('ul > li', setActiveItem(item, 'UL'));
48
+ }
49
+
50
+ if (itemName == 'numlist') {
51
+ return result('ol > li', setActiveItem(item, 'OL'));
52
+ }
53
+
54
+ if (item.settings.stateSelector) {
55
+ return result(item.settings.stateSelector, activeHandler);
56
+ }
57
+
58
+ if (item.settings.disabledStateSelector) {
59
+ return result(item.settings.disabledStateSelector, disabledHandler);
60
+ }
61
+
62
+ return null;
63
+ };
64
+
65
+ var bindSelectorChanged = function (editor, itemName, item) {
66
+ return function () {
67
+ var result = getSelectorStateResult(itemName, item);
68
+ if (result !== null) {
69
+ editor.selection.selectorChanged(result.selector, result.handler);
70
+ }
71
+ };
72
+ };
73
+
74
+ var create = function (editor, name, items) {
75
+ var toolbarItems = [], buttonGroup;
76
+
77
+ if (!items) {
78
+ return;
79
+ }
80
+
81
+ Tools.each(items.split(/[ ,]/), function(item) {
82
+ var itemName;
83
+
84
+ if (item == '|') {
85
+ buttonGroup = null;
86
+ } else {
87
+ if (Factory.has(item)) {
88
+ item = {type: item};
89
+ toolbarItems.push(item);
90
+ buttonGroup = null;
91
+ } else {
92
+ if (!buttonGroup) {
93
+ buttonGroup = {type: 'buttongroup', items: []};
94
+ toolbarItems.push(buttonGroup);
95
+ }
96
+
97
+ if (editor.buttons[item]) {
98
+ itemName = item;
99
+ item = editor.buttons[itemName];
100
+
101
+ if (typeof item == 'function') {
102
+ item = item();
103
+ }
104
+
105
+ item.type = item.type || 'button';
106
+
107
+ item = Factory.create(item);
108
+ item.on('postRender', bindSelectorChanged(editor, itemName, item));
109
+ buttonGroup.items.push(item);
110
+ }
111
+ }
112
+ }
113
+ });
114
+
115
+ return Factory.create({
116
+ type: 'toolbar',
117
+ layout: 'flow',
118
+ name: name,
119
+ items: toolbarItems
120
+ });
121
+ };
122
+
123
+ return {
124
+ create: create
125
+ };
126
+ });
@@ -0,0 +1,9 @@
1
+ test('atomic/alien/ArrTest', [
2
+ 'tinymce/inlite/alien/Arr'
3
+ ], function (Arr) {
4
+ var testFlatten = function () {
5
+ assert.eq(Arr.flatten([1, 2, [3, 4, [5, 6]], [7, 8], 9]), [1, 2, 3, 4, 5, 6, 7, 8, 9]);
6
+ };
7
+
8
+ testFlatten();
9
+ });
@@ -0,0 +1,10 @@
1
+ test('atomic/alien/UuidTest', [
2
+ 'tinymce/inlite/alien/Uuid'
3
+ ], function (Uuid) {
4
+ var testUuid = function () {
5
+ assert.eq(Uuid.uuid('mce').indexOf('mce'), 0);
6
+ assert.eq(Uuid.uuid('mce') !== Uuid.uuid('mce'), true);
7
+ };
8
+
9
+ testUuid();
10
+ });
@@ -0,0 +1,12 @@
1
+ test('atomic/core/ConvertTest', [
2
+ 'tinymce/inlite/core/Convert'
3
+ ], function (Convert) {
4
+ var testConvert = function () {
5
+ assert.eq({x: 1, y: 2, w: 3, h: 4}, Convert.fromClientRect({left: 1, top: 2, width: 3, height: 4}));
6
+ assert.eq({x: 2, y: 3, w: 4, h: 5}, Convert.fromClientRect({left: 2, top: 3, width: 4, height: 5}));
7
+ assert.eq({left: 1, top: 2, width: 3, height: 4, bottom: 2 + 4, right: 1 + 3}, Convert.toClientRect({x: 1, y: 2, w: 3, h: 4}));
8
+ assert.eq({left: 2, top: 3, width: 4, height: 5, bottom: 3 + 5, right: 2 + 4}, Convert.toClientRect({x: 2, y: 3, w: 4, h: 5}));
9
+ };
10
+
11
+ testConvert();
12
+ });
@@ -0,0 +1,51 @@
1
+ test('browser/atomic/MatcherTest', [
2
+ 'tinymce/inlite/core/Matcher'
3
+ ], function (Matcher) {
4
+ var testMatch = function (mockEditor, matches, expectedResult) {
5
+ var result;
6
+
7
+ result = Matcher.match(mockEditor, matches);
8
+ assert.eq(expectedResult, result);
9
+ };
10
+
11
+ var match = function (key) {
12
+ return function (editor) {
13
+ return editor[key];
14
+ };
15
+ };
16
+
17
+ var testMatcher = function () {
18
+ var mockEditor = {
19
+ success1: 'success1',
20
+ success2: 'success2',
21
+ failure: null
22
+ };
23
+
24
+ testMatch(mockEditor, [
25
+ match('success1')
26
+ ], 'success1');
27
+
28
+ testMatch(mockEditor, [
29
+ match(null),
30
+ match('success2')
31
+ ], 'success2');
32
+
33
+ testMatch(mockEditor, [
34
+ match('success1'),
35
+ match('success2')
36
+ ], 'success1');
37
+
38
+ testMatch(mockEditor, [
39
+ match(null)
40
+ ], null);
41
+
42
+ testMatch(mockEditor, [
43
+ match(null),
44
+ match(null)
45
+ ], null);
46
+
47
+ testMatch(mockEditor, [], null);
48
+ };
49
+
50
+ testMatcher();
51
+ });
@@ -0,0 +1,25 @@
1
+ test('atomic/core/UrlTypeTest', [
2
+ 'tinymce/inlite/core/UrlType'
3
+ ], function (UrlType) {
4
+ var testIsDomainLike = function () {
5
+ var mostUsedTopLevelDomains = [
6
+ 'com', 'org', 'edu', 'gov', 'uk', 'net', 'ca', 'de', 'jp',
7
+ 'fr', 'au', 'us', 'ru', 'ch', 'it', 'nl', 'se', 'no', 'es', 'mil'
8
+ ];
9
+
10
+ assert.eq(UrlType.isDomainLike('www.site.com'), true);
11
+ assert.eq(UrlType.isDomainLike('www.site.xyz'), true);
12
+ assert.eq(UrlType.isDomainLike(' www.site.xyz'), true);
13
+ assert.eq(UrlType.isDomainLike('site.xyz'), false);
14
+
15
+ mostUsedTopLevelDomains.forEach(function (tld) {
16
+ assert.eq(UrlType.isDomainLike('site.' + tld), true);
17
+ assert.eq(UrlType.isDomainLike(' site.' + tld), true);
18
+ assert.eq(UrlType.isDomainLike('site.' + tld + ' '), true);
19
+ });
20
+
21
+ assert.eq(UrlType.isDomainLike('/a/b'), false);
22
+ };
23
+
24
+ testIsDomainLike();
25
+ });
@@ -0,0 +1,202 @@
1
+ asynctest('browser/core/ThemeTest', [
2
+ 'ephox.mcagar.api.TinyLoader',
3
+ 'ephox.mcagar.api.TinyApis',
4
+ 'ephox.mcagar.api.TinyActions',
5
+ 'ephox.mcagar.api.TinyDom',
6
+ 'tinymce/inlite/Theme',
7
+ 'ephox.agar.api.Pipeline',
8
+ 'ephox.agar.api.Chain',
9
+ 'ephox.agar.api.UiFinder',
10
+ 'ephox.agar.api.Mouse',
11
+ 'ephox.agar.api.GeneralSteps',
12
+ 'ephox.agar.api.UiControls',
13
+ 'ephox.agar.api.FocusTools'
14
+ ], function (TinyLoader, TinyApis, TinyActions, TinyDom, Theme, Pipeline, Chain, UiFinder, Mouse, GeneralSteps, UiControls, FocusTools) {
15
+ var success = arguments[arguments.length - 2];
16
+ var failure = arguments[arguments.length - 1];
17
+ var dialogRoot = TinyDom.fromDom(document.body);
18
+
19
+ var cWaitForContextToolbar = Chain.fromChainsWith(dialogRoot, [
20
+ UiFinder.cWaitForState('label', '.mce-tinymce-inline', function (elm) {
21
+ return elm.dom().style.display === "";
22
+ })
23
+ ]);
24
+
25
+ var cClickToolbarButton = function (ariaLabel) {
26
+ return Chain.fromChains([
27
+ UiFinder.cFindIn('div[aria-label="' + ariaLabel + '"]'),
28
+ Mouse.cTrueClick
29
+ ]);
30
+ };
31
+
32
+ var sClickFocusedButton = Chain.asStep(TinyDom.fromDom(document), [
33
+ FocusTools.cGetFocused,
34
+ Mouse.cTrueClick
35
+ ]);
36
+
37
+ var sClickContextButton = function (ariaLabel) {
38
+ return Chain.asStep({}, [
39
+ cWaitForContextToolbar,
40
+ cClickToolbarButton(ariaLabel)
41
+ ]);
42
+ };
43
+
44
+ var sWaitForToolbar = function () {
45
+ return Chain.asStep({}, [
46
+ cWaitForContextToolbar
47
+ ]);
48
+ };
49
+
50
+ var sBoldTests = function (tinyApis) {
51
+ return GeneralSteps.sequence([
52
+ tinyApis.sSetContent('<p>a</p>'),
53
+ tinyApis.sSetSelection([0, 0], 0, [0, 0], 1),
54
+ sClickContextButton('Bold'),
55
+ tinyApis.sAssertContent('<p><strong>a</strong></p>')
56
+ ]);
57
+ };
58
+
59
+ var sH2Tests = function (tinyApis) {
60
+ return GeneralSteps.sequence([
61
+ tinyApis.sSetContent('<p>a</p>'),
62
+ tinyApis.sSetSelection([0, 0], 0, [0, 0], 1),
63
+ sClickContextButton('Heading 2'),
64
+ tinyApis.sAssertContent('<h2>a</h2>')
65
+ ]);
66
+ };
67
+
68
+ var sInsertLink = function (url) {
69
+ return Chain.asStep({}, [
70
+ cWaitForContextToolbar,
71
+ cClickToolbarButton('Insert/Edit link'),
72
+ cWaitForContextToolbar,
73
+ UiFinder.cFindIn('input'),
74
+ UiControls.cSetValue(url),
75
+ cWaitForContextToolbar,
76
+ cClickToolbarButton('Ok')
77
+ ]);
78
+ };
79
+
80
+ var cWaitForConfirmDialog = Chain.fromChainsWith(dialogRoot, [
81
+ UiFinder.cWaitForState('window element', '.mce-window', function () {
82
+ return true;
83
+ })
84
+ ]);
85
+
86
+ var cClickButton = function (btnText) {
87
+ return Chain.fromChains([
88
+ UiFinder.cFindIn('button:contains("' + btnText + '")'),
89
+ Mouse.cTrueClick
90
+ ]);
91
+ };
92
+
93
+ var sClickConfirmButton = function (btnText) {
94
+ return Chain.asStep({}, [
95
+ cWaitForConfirmDialog,
96
+ cClickButton(btnText)
97
+ ]);
98
+ };
99
+
100
+ var sInsertLinkConfirmPrefix = function (url, btnText) {
101
+ return GeneralSteps.sequence([
102
+ sInsertLink(url),
103
+ sClickConfirmButton(btnText)
104
+ ]);
105
+ };
106
+
107
+ var sUnlink = Chain.asStep({}, [
108
+ cWaitForContextToolbar,
109
+ cClickToolbarButton('Insert/Edit link'),
110
+ cWaitForContextToolbar,
111
+ cClickToolbarButton('Remove link')
112
+ ]);
113
+
114
+ var sLinkTests = function (tinyApis) {
115
+ var sContentActionTest = function (inputHtml, spath, soffset, fpath, foffset, expectedHtml, sAction) {
116
+ return GeneralSteps.sequence([
117
+ tinyApis.sSetContent(inputHtml),
118
+ tinyApis.sSetSelection(spath, soffset, fpath, foffset),
119
+ sAction,
120
+ tinyApis.sAssertContent(expectedHtml)
121
+ ]);
122
+ };
123
+
124
+ var sLinkTest = function (inputHtml, spath, soffset, fpath, foffset, url, expectedHtml) {
125
+ return sContentActionTest(inputHtml, spath, soffset, fpath, foffset, expectedHtml, sInsertLink(url));
126
+ };
127
+
128
+ var sUnlinkTest = function (inputHtml, spath, soffset, fpath, foffset, expectedHtml) {
129
+ return sContentActionTest(inputHtml, spath, soffset, fpath, foffset, expectedHtml, sUnlink);
130
+ };
131
+
132
+ var sLinkWithConfirmOkTest = function (inputHtml, spath, soffset, fpath, foffset, url, expectedHtml) {
133
+ return sContentActionTest(inputHtml, spath, soffset, fpath, foffset, expectedHtml, sInsertLinkConfirmPrefix(url, 'Ok'));
134
+ };
135
+
136
+ var sLinkWithConfirmCancelTest = function (inputHtml, spath, soffset, fpath, foffset, url, expectedHtml) {
137
+ return sContentActionTest(inputHtml, spath, soffset, fpath, foffset, expectedHtml, sInsertLinkConfirmPrefix(url, 'Cancel'));
138
+ };
139
+
140
+ return GeneralSteps.sequence([
141
+ sLinkWithConfirmOkTest('<p>a</p>', [0, 0], 0, [0, 0], 1, 'www.site.com', '<p><a href="http://www.site.com">a</a></p>'),
142
+ sLinkWithConfirmCancelTest('<p>a</p>', [0, 0], 0, [0, 0], 1, 'www.site.com', '<p><a href="www.site.com">a</a></p>'),
143
+ sLinkTest('<p>a</p>', [0, 0], 0, [0, 0], 1, '#1', '<p><a href="#1">a</a></p>'),
144
+ sLinkTest('<p><a id="x" href="#1">a</a></p>', [0, 0, 0], 0, [0, 0, 0], 1, '#2', '<p><a id="x" href="#2">a</a></p>'),
145
+ sLinkTest('<p><a href="#3">a</a></p>', [0, 0, 0], 0, [0, 0, 0], 1, '', '<p>a</p>'),
146
+ sUnlinkTest('<p><a id="x" href="#1">a</a></p>', [0, 0, 0], 0, [0, 0, 0], 1, '<p>a</p>')
147
+ ]);
148
+ };
149
+
150
+ var sInsertTableTests = function (tinyApis) {
151
+ return GeneralSteps.sequence([
152
+ tinyApis.sSetContent('<p><br></p><p>b</p>'),
153
+ tinyApis.sSetCursor([0], 0),
154
+ sClickContextButton('Insert table'),
155
+ tinyApis.sAssertContent([
156
+ '<table style="width: 100%;">',
157
+ '<tbody>',
158
+ '<tr>',
159
+ '<td>&nbsp;</td>',
160
+ '<td>&nbsp;</td>',
161
+ '</tr>',
162
+ '<tr>',
163
+ '<td>&nbsp;</td>',
164
+ '<td>&nbsp;</td>',
165
+ '</tr>',
166
+ '</tbody>',
167
+ '</table>',
168
+ '<p>b</p>'
169
+ ].join('\n')
170
+ )
171
+ ]);
172
+ };
173
+
174
+ var sAriaTests = function (tinyApis, tinyActions) {
175
+ return GeneralSteps.sequence([
176
+ tinyApis.sSetContent('<p>a</p>'),
177
+ tinyApis.sSetSelection([0, 0], 0, [0, 0], 1),
178
+ sWaitForToolbar(),
179
+ tinyActions.sContentKeydown(121, {alt: true}),
180
+ sClickFocusedButton,
181
+ tinyApis.sAssertContent('<p><strong>a</strong></p>')
182
+ ]);
183
+ };
184
+
185
+ TinyLoader.setup(function (editor, onSuccess, onFailure) {
186
+ var tinyApis = TinyApis(editor), tinyActions = TinyActions(editor);
187
+
188
+ Pipeline.async({}, [
189
+ sBoldTests(tinyApis),
190
+ sH2Tests(tinyApis),
191
+ sLinkTests(tinyApis),
192
+ sInsertTableTests(tinyApis),
193
+ sAriaTests(tinyApis, tinyActions)
194
+ ], onSuccess, onFailure);
195
+ }, {
196
+ theme: 'inlite',
197
+ plugins: 'image table link paste contextmenu textpattern',
198
+ insert_toolbar: 'quickimage media quicktable',
199
+ selection_toolbar: 'bold italic | quicklink h1 h2 blockquote',
200
+ inline: true
201
+ }, success, failure);
202
+ });
@@ -0,0 +1,65 @@
1
+ asynctest('browser/alien/BookmarkTest', [
2
+ 'ephox/tinymce',
3
+ 'ephox.agar.api.Pipeline',
4
+ 'ephox.agar.api.Chain',
5
+ 'ephox.agar.api.Cursors',
6
+ 'ephox.agar.api.Assertions',
7
+ 'ephox.mcagar.api.TinyDom',
8
+ 'tinymce/inlite/alien/Bookmark'
9
+ ], function (tinymce, Pipeline, Chain, Cursors, Assertions, TinyDom, Bookmark) {
10
+ var success = arguments[arguments.length - 2];
11
+ var failure = arguments[arguments.length - 1];
12
+
13
+ var toNativeRange = function (range) {
14
+ var domRange = document.createRange();
15
+ domRange.setStart(range.start().dom(), range.soffset());
16
+ domRange.setEnd(range.finish().dom(), range.foffset());
17
+ return domRange;
18
+ };
19
+
20
+ var rangeToBookmark = function (dom) {
21
+ return function (range) {
22
+ return Bookmark.create(dom, range);
23
+ };
24
+ };
25
+
26
+ var bookmarkToRange = function (dom) {
27
+ return function (bookmark) {
28
+ return Bookmark.resolve(dom, bookmark);
29
+ };
30
+ };
31
+
32
+ var cAssertRangeEq = function (expected) {
33
+ return Chain.op(function (actual) {
34
+ Assertions.assertEq(expected.start().dom(), actual.startContainer, 'Not equal startContainer');
35
+ Assertions.assertEq(expected.soffset(), actual.startOffset, 'Not equal startOffset');
36
+ Assertions.assertEq(expected.finish().dom(), actual.endContainer, 'Not equal endContainer');
37
+ Assertions.assertEq(expected.foffset(), actual.endOffset, 'Not equal endOffset');
38
+ });
39
+ };
40
+
41
+ var sTestBookmark = function (html, path) {
42
+ var dom = tinymce.DOM;
43
+ var elm = TinyDom.fromDom(dom.create('div', {}, html));
44
+
45
+ return Chain.asStep(elm, [
46
+ Cursors.cFollowPath(Cursors.pathFrom(path)),
47
+ Chain.mapper(toNativeRange),
48
+ Chain.mapper(rangeToBookmark(dom)),
49
+ Chain.mapper(bookmarkToRange(dom)),
50
+ cAssertRangeEq(Cursors.calculate(elm, Cursors.pathFrom(path)))
51
+ ]);
52
+ };
53
+
54
+ Pipeline.async({}, [
55
+ sTestBookmark('abc', {element: [0], offset: 0}),
56
+ sTestBookmark('abc', {element: [0], offset: 1}),
57
+ sTestBookmark('abc', {start: {element: [0], offset: 0}, finish: {element: [0], offset: 1}}),
58
+ sTestBookmark('<b>a</b>', {element: [0, 0], offset: 0}),
59
+ sTestBookmark('<b>a</b>', {element: [0, 0], offset: 0}),
60
+ sTestBookmark('<b>a</b>', {start: {element: [0, 0], offset: 0}, finish: {element: [0, 0], offset: 1}}),
61
+ sTestBookmark('<b>a</b><b>b</b>', {start: {element: [0, 0], offset: 0}, finish: {element: [1, 0], offset: 1}})
62
+ ], function () {
63
+ success();
64
+ }, failure);
65
+ });