웹마스터 팁

게시판에 url을 쓰면 <a href="url">내용</a> 처럼 기본으로 자동 링크가 걸립니다.


문제는 target이 지정되어 있지 않아 해당 url을 클릭하면 현재 창에 뜬다는 것이죠. 전 이게 불편하더군요.
[HTML 편집기]로 직접 target을 지정하거나, URL 버튼을 이용해도 되지만, url이 많을 경우 버겁습니다. 귀찮기도 하구요. -_-;
 

그래서, XE 기본 편집기인 'xpresseditor'를 수정했습니다. 혹시나, 필요하신 분이 계실까 해서 올려 봅니다.

 

1.  에디터의 'URL' 버튼을 클릭하면 아래 그림처럼 나타나며, '_blank' 버튼을 클릭하면 본문 내용에 있는 A 태그 중에서 target이 지정되지 않은 링크에 target="_blank" 를 설정합니다.

sample.jpg

 


 

2. 수정한 파일

  • ./modules/editor/skins/xpresseditor/editor.html
  • ./modules/editor/skins/xpresseditor/css/default.css
  • ./modules/editor/skins/xpresseditor/js/Xpress_Editor.js

 

 

3. editor.html

  1. <li class="url xpress_xeditor_ui_hyperlink">
  2.     <button type="button" title="{$lang->edit->url}"><span>{$lang->edit->url}</span></button>
  3.     <!-- URL 레이어 -->
  4.     <div class="layer xpress_xeditor_hyperlink_layer" style="display:none;">
  5.         <fieldset>
  6.             <h3>{$lang->edit->hyperlink}</h3>
  7.             <input name="" class="link" type="text" value="http://" title="URL" />
  8.             <p><input name="" id="target" type="checkbox" value="" /><label for="target">{$lang->edit->target_blank}</label></p>
  9.         </fieldset>
  10.         <div class="btn_area">
  11.             <button type="button" class="confirm" title="{$lang->cmd_confirm}"><span>{$lang->cmd_confirm}</span></button>
  12.             <button type="button" class="cancel" title="{$lang->cmd_cancel}"><span>{$lang->cmd_cancel}</span></button>
  13.             <button type="button" class="blank" title="Make target='_blank'"></button>
  14.         </div>
  15.     </div>
  16.     <!-- /URL 레이어 -->
  17. </li>

 

4. default.css

./modules/editor/skins/xpresseditor/img/ 'btn_layer_blank.gif' 버튼 이미지를 만들어 업로드.

  1. .xpress-editor .tool .layer .btn_area button.confirm{ width:38px; height:21px; background:url(../img/btn_layer_confirm.gif) no-repeat;}
  2. .xpress-editor .tool .layer .btn_area button.cancel{ width:38px; height:21px; background:url(../img/btn_layer_cancel.gif) no-repeat;}
  3. .xpress-editor .tool .layer .btn_area button.blank{ width:41px; height:21px; background:url(../img/btn_layer_blank.gif) no-repeat;}

 

5. Xpress_Editor.js

  1. xe.XE_Hyperlink = $.Class({
  2.     name : "XE_Hyperlink",
  3.     sATagMarker : "HTTP://HUSKY_TMP.MARKER/",
  4.  
  5.     $init : function(elAppContainer){
  6.         this._assignHTMLObjects(elAppContainer);
  7.         this.sRXATagMarker = this.sATagMarker.replace(/\//g, "\\/").replace(/\./g, "\\.");
  8.     },
  9.  
  10.     _assignHTMLObjects : function(elAppContainer){
  11.         this.oHyperlinkLayer = $("DIV.xpress_xeditor_hyperlink_layer", elAppContainer).get(0);
  12.         this.oLinkInput  = $("INPUT[type=text]", this.oHyperlinkLayer).get(0);
  13.         this.oBtnConfirm = $("BUTTON.confirm", this.oHyperlinkLayer).get(0);
  14.         this.oBtnCancel  = $("BUTTON.cancel", this.oHyperlinkLayer).get(0);
  15.         this.oBtnBlank  = $("BUTTON.blank", this.oHyperlinkLayer).get(0); // add by 무얼까 mooin@hitel.net 2011-8-23
  16.         this.oCbNewWin   = $("INPUT[type=checkbox]", this.oHyperlinkLayer).get(0);
  17.     },
  18.  
  19.     $ON_MSG_APP_READY : function(){
  20.         this.oApp.exec("REGISTER_HOTKEY", ["ctrl+k", "XE_TOGGLE_HYPERLINK_LAYER", []]);
  21.  
  22.         this.oApp.registerBrowserEvent(this.oBtnConfirm, "mousedown", "XE_APPLY_HYPERLINK");
  23.         this.oApp.registerBrowserEvent(this.oBtnCancel, "mousedown", "HIDE_ACTIVE_LAYER");
  24.         this.oApp.registerBrowserEvent(this.oBtnBlank, "mousedown", "XE_MAKE_BLANK"); // add by 무얼까 mooin@hitel.net 2011-8-23
  25.         this.oApp.registerBrowserEvent(this.oLinkInput, "keydown", "EVENT_XE_HYPERLINK_KEYDOWN");
  26.  
  27.         this.oApp.exec("REGISTER_UI_EVENT", ["hyperlink", "click", "XE_TOGGLE_HYPERLINK_LAYER"]);
  28.     },
  29.  
  30.     $ON_XE_TOGGLE_HYPERLINK_LAYER : function(){
  31.         // hotkey may close the layer right away so delay here
  32.         this.oApp.delayedExec("TOGGLE_TOOLBAR_ACTIVE_LAYER", [this.oHyperlinkLayer, null, "XE_RESET_HYPERLINK_LAYER", []], 0);
  33.     },
  34.  
  35.     $ON_XE_RESET_HYPERLINK_LAYER : function(){
  36.         this.oApp.exec("FOCUS", []);
  37.         this.oSelection = this.oApp.getSelection();
  38.         var oAnchor = this.oSelection.findAncestorByTagName("A");
  39.         this.oCbNewWin.checked = true; // 무얼까가 'true'로 수정 2011-08-23
  40.         if(oAnchor){
  41.             this.oSelection.selectNode(oAnchor);
  42.             this.oSelection.select();
  43.  
  44.             var sTarget = oAnchor.target;
  45.             if(sTarget && sTarget == "_blank") this.oCbNewWin.checked = true;
  46.  
  47.             this.oLinkInput.value = oAnchor.href?oAnchor.href:"http://";
  48.         }else{
  49.             this.oLinkInput.value = "http://";
  50.         }
  51.  
  52.         this.oLinkInput.focus();
  53.         this.oLinkInput.value = this.oLinkInput.value;
  54.     },
  55.  
  56.     $ON_XE_APPLY_HYPERLINK : function(){
  57.         var sURL = this.oLinkInput.value, newWin = this.oCbNewWin.checked, sTarget = newWin?'_blank':'';
  58.  
  59.         this.oApp.exec("FOCUS", []);
  60.         this.oSelection = this.oApp.getSelection();
  61.  
  62.         if(this.oSelection.collapsed){
  63.             var str = "<a href=" + sURL + "' target="+sTarget+">" + sURL + "</a>";
  64.             this.oSelection.pasteHTML(str);
  65.         }else{
  66.             var nSession = Math.ceil(Math.random()*10000);
  67.             var sMarker  = this.sATagMarker+nSession;
  68.             var arg = ( sURL == "" ? ["unlink"] : ["createLink", false, sMarker+sURL] );
  69.             this.oApp.exec("EXECCOMMAND", arg);
  70.  
  71.             try { this.oSelection.setFromSelection() }catch(e){};
  72.             var oDoc = this.oApp.getWYSIWYGDocument();
  73.             $(oDoc.body.getElementsByTagName("A"))
  74.                 .filter('[href^="'+sMarker+'"]')
  75.                     .attr('href', function(){
  76.                             var rx = new RegExp('^'+sMarker.replace(/([\.\\])/g, '\\$1'), 'i');
  77.  
  78.                             if (sTarget) $(this).attr('target', sTarget);
  79.                             else $(this).removeAttr('target'+ ');
  80.  
  81.                             return this.href.replace(rx, '');
  82.                         });
  83.         }
  84.         this.oApp.exec("HIDE_ACTIVE_LAYER");
  85.  
  86.         setTimeout($.fnBind(function(){try{this.oSelection.select()}catch(e){}}, this), 0);
  87.     },
  88.  
  89.     /* add by 무얼까 mooin@hitel.net 2011-8-23
  90.      * a 태그에 target 속성이 없으면 target="_blank"로 설정
  91.      */
  92.     $ON_XE_MAKE_BLANK : function(){
  93.         var doc = this.oApp.getWYSIWYGDocument();
  94.         var oA = doc.getElementsByTagName("a");
  95.         for(var i=0;i<oA.length;i++) {
  96.             if( !oA[i].hasAttribute('target') ) {
  97.                 oA[i].setAttribute('target', '_blank');
  98.             }
  99.         }
  100.         this.oApp.exec("HIDE_ACTIVE_LAYER");
  101.     },
  102.  
  103.     _validateURL : function(sURL){
  104.         return /^(http|https|ftp|mailto):(?:\/\/)?((\w|-)+(?:[\.:@](\w|-))+)(?:\/|@)?([^"\?]*?)(?:\?([^\?"]*?))?$/.test(sURL);
  105.     },
  106.  
  107.     $ON_EVENT_XE_HYPERLINK_KEYDOWN : function(oEvent){
  108.         if (oEvent.keyCode == 13){
  109.             this.oApp.exec("XE_APPLY_HYPERLINK");
  110.             oEvent.preventDefault(); oEvent.stopPropagation();
  111.         }
  112.     }
  113. });

 

6. 추가로 위 하이퍼링크 설정 창의 '새 창으로' 체크박스가 기본으로 체크되어 있게 수정했습니다.

위 Xpress_Editor.js 파일 소스 중 4673 라인 참고

제목 글쓴이 날짜
울산안마【오피사이트.NET】울산스웨디시 울산마사지 울산1인샵 songkangkong767 2025.02.23
영등포오피 영등포출장안마 ⦑출장안마사이트.COM⦒ 영등포OP 영등포오피 영등포오피 koykoyah 2025.02.23
안양안마【오피쓰주소.COM】안양 안마 안양안마 안양안마 songkangkong767 2025.02.23
강동오피 ⦑출장안마사이트.COM⦒ 강동오피 강동출장마사지 강동오피 강동OP koykoyah 2025.02.23
광주마사지【출장안마사이트.COM】광주마사지 광주 마사지 광주마사지 songkangkong767 2025.02.23
목포오피 목포OP ⦑오피쓰주소.COM⦒ 목포휴게텔 목포오피 목포오피 koykoyah 2025.02.23
전주스웨디시【오피쓰주소.COM】전주 스웨디시 전주스웨디시 전주스웨디시 songkangkong767 2025.02.23
산본오피 ⦑오피쓰주소.COM⦒ 산본오피 산본출장마사지 산본오피 산본OP koykoyah 2025.02.23
대전안마【출장마사지안내.COM】대전 안마 대전안마 대전안마 songkangkong767 2025.02.23
분당오피 ⦑오피쓰.COM⦒ 분당OP 분당오피 분당출장샵 분당오피 koykoyah 2025.02.23
가락안마【오피사이트.NET】가락스웨디시 가락마사지 가락1인샵 songkangkong767 2025.02.23
부산오피 부산오피 ⦑출장안마사이트.COM⦒ 부산OP 부산스파 부산오피 koykoyah 2025.02.23
강서마사지【출장마사지안내.COM】강서스웨디시 강서1인샵 강서안마 songkangkong767 2025.02.23
답십리오피 답십리출장안마 ⦑오피.CLUB⦒ 답십리OP 답십리오피 답십리오피 koykoyah 2025.02.23
군산스웨디시【출장마사지안내.COM】군산안마 군산1인샵 군산마사지 songkangkong767 2025.02.23
강서오피 ⦑오피.CLUB⦒ 강서OP 강서오피 강서출장샵 강서오피 koykoyah 2025.02.23
수원스웨디시【오피사이트.NET】수원스웨디시 수원 스웨디시 수원스웨디시 songkangkong767 2025.02.23
울산오피 울산OP ⦑오피.CLUB⦒ 울산휴게텔 울산오피 울산오피 koykoyah 2025.02.23
부평마사지【오피사이트.NET】부평스웨디시 부평안마 부평1인샵 songkangkong767 2025.02.23
창원오피 ⦑오피.CLUB⦒ 창원오피 창원OP 창원건마 창원오피 koykoyah 2025.02.23