nicedit.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. (function($) {
  2. /**
  3. * Attach this editor to a target element.
  4. */
  5. Drupal.wysiwyg.editor.attach.nicedit = function(context, params, settings) {
  6. // Intercept and ignore submit handlers or they will revert changes made
  7. // since the instance was removed. The handlers are anonymous and hidden out
  8. // of scope in a closure so we can't unbind them. The same operations are
  9. // performed when the instance is detached anyway.
  10. var oldAddEvent = bkLib.addEvent;
  11. bkLib.addEvent = function(obj, type, fn) {
  12. if (type != 'submit') {
  13. oldAddEvent(obj, type, fn);
  14. }
  15. }
  16. // Attach editor.
  17. var editor = new nicEditor(settings);
  18. editor.panelInstance(params.field);
  19. // The old addEvent() must be restored after creating a new instance, as
  20. // plugins with dialogs use it to bind submit handlers to their forms.
  21. bkLib.addEvent = oldAddEvent;
  22. editor.addEvent('focus', function () {
  23. Drupal.wysiwyg.activeId = params.field;
  24. });
  25. };
  26. /**
  27. * Detach a single editor instance.
  28. */
  29. Drupal.wysiwyg.editor.detach.nicedit = function (context, params, trigger) {
  30. var instance = nicEditors.findEditor(params.field);
  31. if (!instance) {
  32. return;
  33. }
  34. if (trigger === 'serialize') {
  35. instance.saveContent();
  36. }
  37. else {
  38. instance.ne.removeInstance(params.field);
  39. instance.ne.removePanel();
  40. }
  41. };
  42. /**
  43. * Check if a DOM node is inside another or if they are the same.
  44. */
  45. function isInside (innerNode, outerNode) {
  46. var found = false;
  47. if (innerNode === outerNode) {
  48. return true;
  49. }
  50. $(innerNode).parents().each(function (index, parent) {
  51. if (parent === outerNode) {
  52. found = true;
  53. return false;
  54. }
  55. });
  56. return found;
  57. }
  58. /**
  59. * Instance methods for nicEdit.
  60. */
  61. Drupal.wysiwyg.editor.instance.nicedit = {
  62. insert: function (content) {
  63. var instance = nicEditors.findEditor(this.field),
  64. editingArea = instance.getElm(),
  65. sel = instance.getSel(), range;
  66. // IE.
  67. if (document.selection) {
  68. range = sel.createRange();
  69. // If the caret is not in the editing area, just append the content.
  70. if (!isInside(range.parentElement(), editingArea)) {
  71. editingArea.innerHTML += content;
  72. }
  73. else {
  74. // Insert content and set the caret after it.
  75. range.pasteHTML(content);
  76. range.select();
  77. range.collapse(false);
  78. }
  79. }
  80. else {
  81. // The code below doesn't work in IE, but it never gets here.
  82. // Convert selection to a range.
  83. // W3C compatible.
  84. if (sel.getRangeAt) {
  85. if (sel.rangeCount > 0) {
  86. range = sel.getRangeAt(0);
  87. }
  88. }
  89. // Safari.
  90. else {
  91. range = editingArea.ownerDocument.createRange();
  92. range.setStart(sel.anchorNode, sel.anchorOffset);
  93. range.setEnd(sel.focusNode, userSeletion.focusOffset);
  94. }
  95. // If the caret is not in the editing area, just append the content.
  96. if (sel.rangeCount == 0 || !isInside(range.commonAncestorContainer, editingArea)) {
  97. editingArea.innerHTML += content;
  98. return;
  99. }
  100. var fragment = editingArea.ownerDocument.createDocumentFragment();
  101. // Fragments don't support innerHTML.
  102. var wrapper = editingArea.ownerDocument.createElement('div');
  103. wrapper.innerHTML = content;
  104. while (wrapper.firstChild) {
  105. fragment.appendChild(wrapper.firstChild);
  106. }
  107. // Append a temporary node to control caret position.
  108. var tn = editingArea.ownerDocument.createElement('span');
  109. fragment.appendChild(tn);
  110. range.deleteContents();
  111. // Only fragment children are inserted.
  112. range.insertNode(fragment);
  113. // Move caret to temp node and remove it.
  114. range.setStartBefore(tn);
  115. range.setEndBefore(tn);
  116. sel.removeAllRanges();
  117. sel.addRange(range);
  118. tn.parentNode.removeChild(tn);
  119. }
  120. },
  121. setContent: function (content) {
  122. nicEditors.findEditor(this.field).setContent(content);
  123. },
  124. getContent: function () {
  125. return nicEditors.findEditor(this.field).getContent();
  126. }
  127. };
  128. })(jQuery);