plugin.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /**
  2. * Copyright (c) Tiny Technologies, Inc. All rights reserved.
  3. * Licensed under the LGPL or a commercial license.
  4. * For LGPL see License.txt in the project root for license information.
  5. * For commercial licenses see https://www.tiny.cloud/
  6. *
  7. * Version: 5.2.0 (2020-02-13)
  8. */
  9. (function () {
  10. 'use strict';
  11. var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
  12. var isValidId = function (id) {
  13. return /^[A-Za-z][A-Za-z0-9\-:._]*$/.test(id);
  14. };
  15. var getId = function (editor) {
  16. var selectedNode = editor.selection.getNode();
  17. var isAnchor = selectedNode.tagName === 'A' && editor.dom.getAttrib(selectedNode, 'href') === '';
  18. return isAnchor ? selectedNode.getAttribute('id') || selectedNode.getAttribute('name') : '';
  19. };
  20. var insert = function (editor, id) {
  21. var selectedNode = editor.selection.getNode();
  22. var isAnchor = selectedNode.tagName === 'A' && editor.dom.getAttrib(selectedNode, 'href') === '';
  23. if (isAnchor) {
  24. selectedNode.removeAttribute('name');
  25. selectedNode.id = id;
  26. editor.undoManager.add();
  27. } else {
  28. editor.focus();
  29. editor.selection.collapse(true);
  30. editor.execCommand('mceInsertContent', false, editor.dom.createHTML('a', { id: id }));
  31. }
  32. };
  33. var Anchor = {
  34. isValidId: isValidId,
  35. getId: getId,
  36. insert: insert
  37. };
  38. var insertAnchor = function (editor, newId) {
  39. if (!Anchor.isValidId(newId)) {
  40. editor.windowManager.alert('Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.');
  41. return true;
  42. } else {
  43. Anchor.insert(editor, newId);
  44. return false;
  45. }
  46. };
  47. var open = function (editor) {
  48. var currentId = Anchor.getId(editor);
  49. editor.windowManager.open({
  50. title: 'Anchor',
  51. size: 'normal',
  52. body: {
  53. type: 'panel',
  54. items: [{
  55. name: 'id',
  56. type: 'input',
  57. label: 'ID',
  58. placeholder: 'example'
  59. }]
  60. },
  61. buttons: [
  62. {
  63. type: 'cancel',
  64. name: 'cancel',
  65. text: 'Cancel'
  66. },
  67. {
  68. type: 'submit',
  69. name: 'save',
  70. text: 'Save',
  71. primary: true
  72. }
  73. ],
  74. initialData: { id: currentId },
  75. onSubmit: function (api) {
  76. if (!insertAnchor(editor, api.getData().id)) {
  77. api.close();
  78. }
  79. }
  80. });
  81. };
  82. var Dialog = { open: open };
  83. var register = function (editor) {
  84. editor.addCommand('mceAnchor', function () {
  85. Dialog.open(editor);
  86. });
  87. };
  88. var Commands = { register: register };
  89. var isAnchorNode = function (node) {
  90. return !node.attr('href') && (node.attr('id') || node.attr('name')) && !node.firstChild;
  91. };
  92. var setContentEditable = function (state) {
  93. return function (nodes) {
  94. for (var i = 0; i < nodes.length; i++) {
  95. if (isAnchorNode(nodes[i])) {
  96. nodes[i].attr('contenteditable', state);
  97. }
  98. }
  99. };
  100. };
  101. var setup = function (editor) {
  102. editor.on('PreInit', function () {
  103. editor.parser.addNodeFilter('a', setContentEditable('false'));
  104. editor.serializer.addNodeFilter('a', setContentEditable(null));
  105. });
  106. };
  107. var FilterContent = { setup: setup };
  108. var register$1 = function (editor) {
  109. editor.ui.registry.addToggleButton('anchor', {
  110. icon: 'bookmark',
  111. tooltip: 'Anchor',
  112. onAction: function () {
  113. return editor.execCommand('mceAnchor');
  114. },
  115. onSetup: function (buttonApi) {
  116. return editor.selection.selectorChangedWithUnbind('a:not([href])', buttonApi.setActive).unbind;
  117. }
  118. });
  119. editor.ui.registry.addMenuItem('anchor', {
  120. icon: 'bookmark',
  121. text: 'Anchor...',
  122. onAction: function () {
  123. return editor.execCommand('mceAnchor');
  124. }
  125. });
  126. };
  127. var Buttons = { register: register$1 };
  128. function Plugin () {
  129. global.add('anchor', function (editor) {
  130. FilterContent.setup(editor);
  131. Commands.register(editor);
  132. Buttons.register(editor);
  133. });
  134. }
  135. Plugin();
  136. }());