link.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /**
  2. * 超链接
  3. * @file
  4. * @since 1.2.6.1
  5. */
  6. /**
  7. * 插入超链接
  8. * @command link
  9. * @method execCommand
  10. * @param { String } cmd 命令字符串
  11. * @param { Object } options 设置自定义属性,例如:url、title、target
  12. * @example
  13. * ```javascript
  14. * editor.execCommand( 'link', '{
  15. * url:'ueditor.baidu.com',
  16. * title:'ueditor',
  17. * target:'_blank'
  18. * }' );
  19. * ```
  20. */
  21. /**
  22. * 返回当前选中的第一个超链接节点
  23. * @command link
  24. * @method queryCommandValue
  25. * @param { String } cmd 命令字符串
  26. * @return { Element } 超链接节点
  27. * @example
  28. * ```javascript
  29. * editor.queryCommandValue( 'link' );
  30. * ```
  31. */
  32. /**
  33. * 取消超链接
  34. * @command unlink
  35. * @method execCommand
  36. * @param { String } cmd 命令字符串
  37. * @example
  38. * ```javascript
  39. * editor.execCommand( 'unlink');
  40. * ```
  41. */
  42. UE.plugins['link'] = function(){
  43. function optimize( range ) {
  44. var start = range.startContainer,end = range.endContainer;
  45. if ( start = domUtils.findParentByTagName( start, 'a', true ) ) {
  46. range.setStartBefore( start );
  47. }
  48. if ( end = domUtils.findParentByTagName( end, 'a', true ) ) {
  49. range.setEndAfter( end );
  50. }
  51. }
  52. UE.commands['unlink'] = {
  53. execCommand : function() {
  54. var range = this.selection.getRange(),
  55. bookmark;
  56. if(range.collapsed && !domUtils.findParentByTagName( range.startContainer, 'a', true )){
  57. return;
  58. }
  59. bookmark = range.createBookmark();
  60. optimize( range );
  61. range.removeInlineStyle( 'a' ).moveToBookmark( bookmark ).select();
  62. },
  63. queryCommandState : function(){
  64. return !this.highlight && this.queryCommandValue('link') ? 0 : -1;
  65. }
  66. };
  67. function doLink(range,opt,me){
  68. var rngClone = range.cloneRange(),
  69. link = me.queryCommandValue('link');
  70. optimize( range = range.adjustmentBoundary() );
  71. var start = range.startContainer;
  72. if(start.nodeType == 1 && link){
  73. start = start.childNodes[range.startOffset];
  74. if(start && start.nodeType == 1 && start.tagName == 'A' && /^(?:https?|ftp|file)\s*:\s*\/\//.test(start[browser.ie?'innerText':'textContent'])){
  75. start[browser.ie ? 'innerText' : 'textContent'] = utils.html(opt.textValue||opt.href);
  76. }
  77. }
  78. if( !rngClone.collapsed || link){
  79. range.removeInlineStyle( 'a' );
  80. rngClone = range.cloneRange();
  81. }
  82. if ( rngClone.collapsed ) {
  83. var a = range.document.createElement( 'a'),
  84. text = '';
  85. if(opt.textValue){
  86. text = utils.html(opt.textValue);
  87. delete opt.textValue;
  88. }else{
  89. text = utils.html(opt.href);
  90. }
  91. domUtils.setAttributes( a, opt );
  92. start = domUtils.findParentByTagName( rngClone.startContainer, 'a', true );
  93. if(start && domUtils.isInNodeEndBoundary(rngClone,start)){
  94. range.setStartAfter(start).collapse(true);
  95. }
  96. a[browser.ie ? 'innerText' : 'textContent'] = text;
  97. range.insertNode(a).selectNode( a );
  98. } else {
  99. range.applyInlineStyle( 'a', opt );
  100. }
  101. }
  102. UE.commands['link'] = {
  103. execCommand : function( cmdName, opt ) {
  104. var range;
  105. opt._href && (opt._href = utils.unhtml(opt._href,/[<">]/g));
  106. opt.href && (opt.href = utils.unhtml(opt.href,/[<">]/g));
  107. opt.textValue && (opt.textValue = utils.unhtml(opt.textValue,/[<">]/g));
  108. doLink(range=this.selection.getRange(),opt,this);
  109. //闭合都不加占位符,如果加了会在a后边多个占位符节点,导致a是图片背景组成的列表,出现空白问题
  110. range.collapse().select(true);
  111. },
  112. queryCommandValue : function() {
  113. var range = this.selection.getRange(),
  114. node;
  115. if ( range.collapsed ) {
  116. // node = this.selection.getStart();
  117. //在ie下getstart()取值偏上了
  118. node = range.startContainer;
  119. node = node.nodeType == 1 ? node : node.parentNode;
  120. if ( node && (node = domUtils.findParentByTagName( node, 'a', true )) && ! domUtils.isInNodeEndBoundary(range,node)) {
  121. return node;
  122. }
  123. } else {
  124. //trace:1111 如果是<p><a>xx</a></p> startContainer是p就会找不到a
  125. range.shrinkBoundary();
  126. var start = range.startContainer.nodeType == 3 || !range.startContainer.childNodes[range.startOffset] ? range.startContainer : range.startContainer.childNodes[range.startOffset],
  127. end = range.endContainer.nodeType == 3 || range.endOffset == 0 ? range.endContainer : range.endContainer.childNodes[range.endOffset-1],
  128. common = range.getCommonAncestor();
  129. node = domUtils.findParentByTagName( common, 'a', true );
  130. if ( !node && common.nodeType == 1){
  131. var as = common.getElementsByTagName( 'a' ),
  132. ps,pe;
  133. for ( var i = 0,ci; ci = as[i++]; ) {
  134. ps = domUtils.getPosition( ci, start ),pe = domUtils.getPosition( ci,end);
  135. if ( (ps & domUtils.POSITION_FOLLOWING || ps & domUtils.POSITION_CONTAINS)
  136. &&
  137. (pe & domUtils.POSITION_PRECEDING || pe & domUtils.POSITION_CONTAINS)
  138. ) {
  139. node = ci;
  140. break;
  141. }
  142. }
  143. }
  144. return node;
  145. }
  146. },
  147. queryCommandState : function() {
  148. //判断如果是视频的话连接不可用
  149. //fix 853
  150. var img = this.selection.getRange().getClosedNode(),
  151. flag = img && (img.className == "edui-faked-video" || img.className.indexOf("edui-upload-video")!=-1);
  152. return flag ? -1 : 0;
  153. }
  154. };
  155. };