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,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
+ });