plugin.js 4.5 KB

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