plugin.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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.3.0 (2020-05-21)
  8. */
  9. (function () {
  10. 'use strict';
  11. var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
  12. var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools');
  13. var getNonEditableClass = function (editor) {
  14. return editor.getParam('noneditable_noneditable_class', 'mceNonEditable');
  15. };
  16. var getEditableClass = function (editor) {
  17. return editor.getParam('noneditable_editable_class', 'mceEditable');
  18. };
  19. var getNonEditableRegExps = function (editor) {
  20. var nonEditableRegExps = editor.getParam('noneditable_regexp', []);
  21. if (nonEditableRegExps && nonEditableRegExps.constructor === RegExp) {
  22. return [nonEditableRegExps];
  23. } else {
  24. return nonEditableRegExps;
  25. }
  26. };
  27. var hasClass = function (checkClassName) {
  28. return function (node) {
  29. return (' ' + node.attr('class') + ' ').indexOf(checkClassName) !== -1;
  30. };
  31. };
  32. var replaceMatchWithSpan = function (editor, content, cls) {
  33. return function (match) {
  34. var args = arguments, index = args[args.length - 2];
  35. var prevChar = index > 0 ? content.charAt(index - 1) : '';
  36. if (prevChar === '"') {
  37. return match;
  38. }
  39. if (prevChar === '>') {
  40. var findStartTagIndex = content.lastIndexOf('<', index);
  41. if (findStartTagIndex !== -1) {
  42. var tagHtml = content.substring(findStartTagIndex, index);
  43. if (tagHtml.indexOf('contenteditable="false"') !== -1) {
  44. return match;
  45. }
  46. }
  47. }
  48. return '<span class="' + cls + '" data-mce-content="' + editor.dom.encode(args[0]) + '">' + editor.dom.encode(typeof args[1] === 'string' ? args[1] : args[0]) + '</span>';
  49. };
  50. };
  51. var convertRegExpsToNonEditable = function (editor, nonEditableRegExps, e) {
  52. var i = nonEditableRegExps.length, content = e.content;
  53. if (e.format === 'raw') {
  54. return;
  55. }
  56. while (i--) {
  57. content = content.replace(nonEditableRegExps[i], replaceMatchWithSpan(editor, content, getNonEditableClass(editor)));
  58. }
  59. e.content = content;
  60. };
  61. var setup = function (editor) {
  62. var editClass, nonEditClass;
  63. var contentEditableAttrName = 'contenteditable';
  64. editClass = ' ' + global$1.trim(getEditableClass(editor)) + ' ';
  65. nonEditClass = ' ' + global$1.trim(getNonEditableClass(editor)) + ' ';
  66. var hasEditClass = hasClass(editClass);
  67. var hasNonEditClass = hasClass(nonEditClass);
  68. var nonEditableRegExps = getNonEditableRegExps(editor);
  69. editor.on('PreInit', function () {
  70. if (nonEditableRegExps.length > 0) {
  71. editor.on('BeforeSetContent', function (e) {
  72. convertRegExpsToNonEditable(editor, nonEditableRegExps, e);
  73. });
  74. }
  75. editor.parser.addAttributeFilter('class', function (nodes) {
  76. var i = nodes.length, node;
  77. while (i--) {
  78. node = nodes[i];
  79. if (hasEditClass(node)) {
  80. node.attr(contentEditableAttrName, 'true');
  81. } else if (hasNonEditClass(node)) {
  82. node.attr(contentEditableAttrName, 'false');
  83. }
  84. }
  85. });
  86. editor.serializer.addAttributeFilter(contentEditableAttrName, function (nodes) {
  87. var i = nodes.length, node;
  88. while (i--) {
  89. node = nodes[i];
  90. if (!hasEditClass(node) && !hasNonEditClass(node)) {
  91. continue;
  92. }
  93. if (nonEditableRegExps.length > 0 && node.attr('data-mce-content')) {
  94. node.name = '#text';
  95. node.type = 3;
  96. node.raw = true;
  97. node.value = node.attr('data-mce-content');
  98. } else {
  99. node.attr(contentEditableAttrName, null);
  100. }
  101. }
  102. });
  103. });
  104. };
  105. function Plugin () {
  106. global.add('noneditable', function (editor) {
  107. setup(editor);
  108. });
  109. }
  110. Plugin();
  111. }());