#459, #458 본문 자동링크 및 이미지 크기 조절 기능을 애드온으로 분리

git-svn-id: http://xe-core.googlecode.com/svn/sandbox@4129 201d5d3c-b55e-5fd7-737f-ddc643e51545
This commit is contained in:
zero 2008-04-22 09:41:34 +00:00
parent 6097f5a584
commit 70f1aa438a
12 changed files with 284 additions and 219 deletions

View file

@ -0,0 +1,22 @@
<?php
if(!defined("__ZBXE__")) exit();
/**
* @file autolink.addon.php
* @author zero (zero@nzeo.com)
* @brief 자동 링크 애드온
**/
if($called_position == 'after_module_proc' && Context::getResponseMethod()!="XMLRPC") {
Context::loadLang("./addons/autolink/lang");
$open_cur_window = Context::getLang('open_cur_window');
$open_new_window = Context::getLang('open_new_window');
$script_code = <<<EndOfScript
<script type="text/javascript"> function addUrlLink() { var objs = xGetElementsByClassName('xe_content'); if(objs.length<1) return; var rep_list = new Array(); var url_regx = new RegExp("(http|https|ftp|news)://([-/.a-zA-Z0-9_~#%$?&=:200-377()]+)","gi"); for(var i=0;i<objs.length;i++) { var as = xGetElementsByTagName('A', objs[i]); for(var j=0;j<as.length;j++) { xInnerHtml(as[j], xInnerHtml(as[j]).replace('://',';//')); as[j].setAttribute('href', as[j].getAttribute('href').replace('://',';//')); } xInnerHtml(objs[i], xInnerHtml(objs[i]).replace(url_regx, "<a href=\"$1://$2\" onclick=\"window.open(this.href); return false;\">$1://$2</a>")); for(var j=0;j<as.length;j++) { xInnerHtml(as[j], xInnerHtml(as[j]).replace(';//','://')); as[j].setAttribute('href', as[j].getAttribute('href').replace(';//','://')); } xAddEventListener(objs[i], 'mouseover', showUrlOpener); } } function showUrlOpener(e) { var evt = new xEvent(e); var obj = evt.target; var layer = xGetElementById('zbXEUrlOpener'); if(!layer) { layer = xCreateElement('div'); layer.style.position = 'absolute'; layer.style.border = '3px solid #DDDDDD'; layer.style.backgroundColor = '#FFFFFF'; layer.style.padding = '5px'; layer.style.visibility = 'hidden'; layer.style.lineHeight = '1.6'; layer.setAttribute('id','zbXEUrlOpener'); document.body.appendChild(layer); } if(obj && obj.nodeName == 'A' && obj.getAttribute('href') && !/#/.test(obj.getAttribute('href'))) { var href = obj.getAttribute('href'); if(href.length>40) href = href.substr(0,40)+'...'; var html = ''+ '<a href="'+obj.getAttribute('href')+'" style="text-decoration:none; color:#555555;">'+href+'</a> [{$open_cur_window}]<br />'+ '<a href="'+obj.getAttribute('href')+'" onclick="window.open(this.href); return false;" style="text-decoration:none; color:#555555;">'+href+'</a> [{$open_new_window}]'; xInnerHtml(layer, html); xLeft(layer, evt.pageX-20); xTop(layer, evt.pageY-10); layer.style.visibility = 'visible'; } else { layer.style.visibility = 'hidden'; } } xAddEventListener(window,'load', addUrlLink); </script>
EndOfScript;
Context::addHtmlHeader($script_code);
}
?>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<addon version="0.1">
<title xml:lang="ko">자동 링크 애드온</title>
<author email_address="zero@zeroboard.com" link="http://www.zeroboard.com" date="2008. 4. 22">
<name xml:lang="ko">zero</name>
<description xml:lang="ko">
게시글과 댓글의 내용중 http로 시작되는 일반 문자열에 자동으로 링크를 걸고 각 링크에 마우스 오버시 새창과 현재창 메뉴가 나타나도록 꾸미는 애드온입니다.
</description>
</author>
</addon>

View file

@ -0,0 +1,9 @@
<?php
/**
* @file addons/autolink/lang/ko.lang.php
* @author zero (zero@zeroboard.com)
* @brief 한국어 언어팩 (기본적인 내용만 수록)
**/
$lang->open_cur_window = "현재창";
$lang->open_new_window = "새창";
?>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<addon version="0.1">
<title xml:lang="ko">본문내 이미지 조절 애드온</title>
<author email_address="zero@zeroboard.com" link="http://www.zeroboard.com" date="2008. 4. 22">
<name xml:lang="ko">zero</name>
<description xml:lang="ko">
본문내에 삽입된 이미지의 크기를 본문크기에 맞게 하고 클릭시 원본을 보여주는 애드온입니다.
</description>
</author>
</addon>

View file

@ -0,0 +1,5 @@
@charset "utf-8";
#forOriginalImageAreaBackground { z-index:1001; background-color:#AAAAAA; top:0px; left:0px; position:relative; padding:0; border:8px solid #444444; white-space:nowrap; }
#forOriginalImageArea { visibility:hidden; padding:0px; margin:0px; width:100%; height:100%; top:0px; left:0px; position:absolute; z-index:1000; text-align:left; overflow:hidden; background-color:#000000;}
#fororiginalimage { z-index:1002; margin:0; padding:0; }

View file

@ -0,0 +1,212 @@
/**
* @brief 화면내에서 상위 영역보다 이미지가 크면 리사이즈를 하고 클릭시 원본을 보여줄수 있도록 변경
**/
function resizeImageContents() {
// 일단 모든 이미지에 대한 체크를 시작
var objs = xGetElementsByTagName("IMG");
for(var i in objs) {
var obj = objs[i];
if(!obj.parentNode) continue;
if(/\/modules\//i.test(obj.src)) continue;
if(/\/layouts\//i.test(obj.src)) continue;
if(/\/widgets\//i.test(obj.src)) continue;
if(/\/classes\//i.test(obj.src)) continue;
if(/\/common\/tpl\//i.test(obj.src)) continue;
if(/\/member_extra_info\//i.test(obj.src)) continue;
// 상위 node의 className이 document_ 또는 comment_ 로 시작하지 않으면 패스
var parent = obj.parentNode;
while(parent) {
if(parent.className && parent.className.search(/xe_content|document_|comment_/i) != -1) break;
parent = parent.parentNode;
}
if (!parent || parent.className.search(/xe_content|document_|comment_/i) < 0) continue;
if(parent.parentNode) xWidth(parent, xWidth(parent.parentNode));
parent.style.width = '100%';
parent.style.overflow = 'hidden';
var parent_width = xWidth(parent);
if(parent.parentNode && xWidth(parent.parentNode)<parent_width) parent_width = xWidth(parent.parentNode);
var obj_width = xWidth(obj);
var obj_height = xHeight(obj);
// 만약 선택된 이미지의 가로 크기가 부모의 가로크기보다 크면 리사이즈 (이때 부모의 가로크기 - 2 정도로 지정해줌)
if(obj_width > parent_width - 2) {
obj.style.cursor = "pointer";
var new_w = parent_width - 2;
var new_h = Math.round(obj_height * new_w/obj_width);
xWidth(obj, new_w);
xHeight(obj, new_h);
xAddEventListener(obj,"click", showOriginalImage);
// 선택된 이미지가 부모보다 작을 경우 일단 원본 이미지를 불러와서 비교
} else {
var orig_img = new Image();
orig_img.src = obj.src;
if(orig_img.width > parent_width - 2 || orig_img.width != obj_width) {
obj.style.cursor = "pointer";
xAddEventListener(obj,"click", showOriginalImage);
}
}
}
}
xAddEventListener(window, "load", resizeImageContents);
/**
* @brief 본문내에서 컨텐츠 영역보다 이미지의 경우 원본 크기를 보여줌
**/
function showOriginalImage(evt) {
var e = new xEvent(evt);
var obj = e.target;
var src = obj.src;
if(!xGetElementById("forOriginalImageArea")) {
var dummy = xCreateElement("div");
dummy.id = "forOriginalImageArea";
dummy.style.visibility = "hidden";
xInnerHtml(dummy, "<div id=\"forOriginalImageAreaBackground\"><img src=\""+request_uri+"common/tpl/images/blank.gif\" alt=\"original image\" border=\"0\" id=\"fororiginalimage\" /></div>");
document.body.appendChild(dummy);
}
var orig_image = xGetElementById("fororiginalimage");
var tmp_image = new Image();
tmp_image.src = src;
var image_width = tmp_image.width;
var image_height = tmp_image.height;
orig_image.style.margin = "0px 0px 0px 0px";
orig_image.style.cursor = "move";
orig_image.src = src;
var areabg = xGetElementById("forOriginalImageAreaBackground");
xWidth(areabg, image_width+16);
xHeight(areabg, image_height+16);
var area = xGetElementById("forOriginalImageArea");
xLeft(area, xScrollLeft());
xTop(area, xScrollTop());
xWidth(area, xWidth(document));
xHeight(area, xHeight(document));
area.style.visibility = "visible";
var area_width = xWidth(area);
var area_height = xHeight(area);
var x = parseInt((area_width-image_width)/2,10);
var y = parseInt((area_height-image_height)/2,10);
if(x<0) x = 0;
if(y<0) y = 0;
xLeft(areabg, x);
xTop(areabg, y);
var sel_list = xGetElementsByTagName("select");
for (var i = 0; i < sel_list.length; ++i) sel_list[i].style.visibility = "hidden";
xAddEventListener(orig_image, "mousedown", origImageDragEnable);
xAddEventListener(orig_image, "dblclick", closeOriginalImage);
xAddEventListener(window, "scroll", closeOriginalImage);
xAddEventListener(window, "resize", closeOriginalImage);
xAddEventListener(document, 'keydown',closeOriginalImage);
areabg.style.visibility = 'visible';
}
/**
* @brief 원본 이미지 보여준 닫는 함수
**/
function closeOriginalImage(evt) {
var area = xGetElementById("forOriginalImageArea");
if(area.style.visibility != "visible") return;
area.style.visibility = "hidden";
xGetElementById("forOriginalImageAreaBackground").style.visibility = "hidden";
var sel_list = xGetElementsByTagName("select");
for (var i = 0; i < sel_list.length; ++i) sel_list[i].style.visibility = "visible";
xRemoveEventListener(area, "mousedown", closeOriginalImage);
xRemoveEventListener(window, "scroll", closeOriginalImage);
xRemoveEventListener(window, "resize", closeOriginalImage);
xRemoveEventListener(document, 'keydown',closeOriginalImage);
}
/**
* @brief 원본 이미지 드래그
**/
var origDragManager = {obj:null, isDrag:false}
function origImageDragEnable(evt) {
var e = new xEvent(evt);
var obj = e.target;
if(obj.id != "fororiginalimage") return;
obj.draggable = true;
obj.startX = e.pageX;
obj.startY = e.pageY;
if(!origDragManager.isDrag) {
origDragManager.isDrag = true;
xAddEventListener(document, "mousemove", origImageDragMouseMove, false);
}
xAddEventListener(document, "mousedown", origImageDragMouseDown, false);
}
function origImageDrag(obj, px, py) {
var x = px - obj.startX;
var y = py - obj.startY;
var areabg = xGetElementById("forOriginalImageAreaBackground");
xLeft(areabg, xLeft(areabg)+x);
xTop(areabg, xTop(areabg)+y);
obj.startX = px;
obj.startY = py;
}
function origImageDragMouseDown(evt) {
var e = new xEvent(evt);
var obj = e.target;
if(obj.id != "fororiginalimage" || !obj.draggable) return;
if(obj) {
xPreventDefault(evt);
obj.startX = e.pageX;
obj.startY = e.pageY;
origDragManager.obj = obj;
xAddEventListener(document, 'mouseup', origImageDragMouseUp, false);
origImageDrag(obj, e.pageX, e.pageY);
}
}
function origImageDragMouseUp(evt) {
if(origDragManager.obj) {
xPreventDefault(evt);
xRemoveEventListener(document, 'mouseup', origImageDragMouseUp, false);
xRemoveEventListener(document, 'mousemove', origImageDragMouseMove, false);
xRemoveEventListener(document, 'mousemdown', origImageDragMouseDown, false);
origDragManager.obj.draggable = false;
origDragManager.obj = null;
origDragManager.isDrag = false;
}
}
function origImageDragMouseMove(evt) {
var e = new xEvent(evt);
var obj = e.target;
if(!obj) return;
if(obj.id != "fororiginalimage") {
xPreventDefault(evt);
xRemoveEventListener(document, 'mouseup', origImageDragMouseUp, false);
xRemoveEventListener(document, 'mousemove', origImageDragMouseMove, false);
xRemoveEventListener(document, 'mousemdown', origImageDragMouseDown, false);
origDragManager.obj.draggable = false;
origDragManager.obj = null;
origDragManager.isDrag = false;
return;
}
xPreventDefault(evt);
origDragManager.obj = obj;
xAddEventListener(document, 'mouseup', origImageDragMouseUp, false);
origImageDrag(obj, e.pageX, e.pageY);
}

View file

@ -0,0 +1,14 @@
<?php
if(!defined("__ZBXE__")) exit();
/**
* @file reaize_image.addon.php
* @author zero (zero@nzeo.com)
* @brief 본문내 이미지 조절 애드온
**/
if($called_position == 'after_module_proc' && Context::getResponseMethod()!="XMLRPC") {
Context::addJsFile('./addons/resize_image/js/resize_image.js');
Context::addCSSFile('./addons/resize_image/css/resize_image.css');
}
?>

View file

@ -89,10 +89,6 @@ a.bold { font-weight:bold; }
/* xe layer */
#waitingforserverresponse { border:2px solid #444444; font-weight:bold; color:#444444; padding: 7px 5px 5px 25px; background:#FFFFFF url("../tpl/images/loading.gif") no-repeat 5px 5px; top:40px; left:40px; position:absolute; z-index:100; visibility:hidden; }
#fororiginalimageareabg { z-index:1001; background-color:#FFFFFF; width:100%; height:100%; top:0px; left:0px; position:relative; padding:20px 10px 10px 10px; border:8px solid #DDDDDD; }
#fororiginalimagearea { visibility:hidden; padding:0px; margin:0px; width:100%; height:100%; top:0px; left:0px; position:absolute; z-index:1000; text-align:left; overflow:hidden; }
#fororiginalimage { z-index:1002; }
#closeOriginalImageBtn { position:absolute; right:8px; top:5px; cursor:pointer; width:50px; height:12px; z-index:1003; }
#popup_menu_area { position:absolute; left:0px; top:0px; z-index:1003; visibility:hidden; border:2px solid #D9D9D9; background-color:#FFFFFF; padding:0; }
#popup_menu_area .box { border:1px solid #CACACA; background-color:#FFFFFF; padding:7px; }
#popup_menu_area .item { color:#333333; cursor:pointer; margin:0; padding:3px 0 3px 0; white-space:nowrap; }

View file

@ -220,62 +220,6 @@ function displayMultimedia(src, width, height, auto_start, flashvars) {
document.writeln(html);
}
/**
* @brief 화면내에서 상위 영역보다 이미지가 크면 리사이즈를 하고 클릭시 원본을 보여줄수 있도록 변경
**/
function resizeImageContents() {
// 일단 모든 이미지에 대한 체크를 시작
var objs = xGetElementsByTagName("IMG");
for(var i in objs) {
var obj = objs[i];
if(!obj.parentNode) continue;
if(/\/modules\//i.test(obj.src)) continue;
if(/\/layouts\//i.test(obj.src)) continue;
if(/\/widgets\//i.test(obj.src)) continue;
if(/\/classes\//i.test(obj.src)) continue;
if(/\/common\/tpl\//i.test(obj.src)) continue;
if(/\/member_extra_info\//i.test(obj.src)) continue;
// 상위 node의 className이 document_ 또는 comment_ 로 시작하지 않으면 패스
var parent = obj.parentNode;
while(parent) {
if(parent.className && parent.className.search(/xe_content|document_|comment_/i) != -1) break;
parent = parent.parentNode;
}
if (!parent || parent.className.search(/xe_content|document_|comment_/i) < 0) continue;
if(parent.parentNode) xWidth(parent, xWidth(parent.parentNode));
parent.style.width = '100%';
parent.style.overflow = 'hidden';
var parent_width = xWidth(parent);
if(parent.parentNode && xWidth(parent.parentNode)<parent_width) parent_width = xWidth(parent.parentNode);
var obj_width = xWidth(obj);
var obj_height = xHeight(obj);
// 만약 선택된 이미지의 가로 크기가 부모의 가로크기보다 크면 리사이즈 (이때 부모의 가로크기 - 2 정도로 지정해줌)
if(obj_width > parent_width - 2) {
obj.style.cursor = "pointer";
var new_w = parent_width - 2;
var new_h = Math.round(obj_height * new_w/obj_width);
xWidth(obj, new_w);
xHeight(obj, new_h);
xAddEventListener(obj,"click", showOriginalImage);
// 선택된 이미지가 부모보다 작을 경우 일단 원본 이미지를 불러와서 비교
} else {
var orig_img = new Image();
orig_img.src = obj.src;
if(orig_img.width > parent_width - 2 || orig_img.width != obj_width) {
obj.style.cursor = "pointer";
xAddEventListener(obj,"click", showOriginalImage);
}
}
}
}
xAddEventListener(window, "load", resizeImageContents);
/**
* @brief 에디터에서 사용되는 내용 여닫는 코드 (고정, zbxe용)
**/
@ -359,163 +303,6 @@ function setFixedPopupSize() {
window.scrollTo(0,0);
}
/**
* @brief 본문내에서 컨텐츠 영역보다 이미지의 경우 원본 크기를 보여줌
**/
function showOriginalImage(evt) {
var e = new xEvent(evt);
var obj = e.target;
var src = obj.src;
if(!xGetElementById("fororiginalimagearea")) {
var dummy = xCreateElement("div");
dummy.id = "fororiginalimagearea";
dummy.style.visibility = "hidden";
xInnerHtml(dummy, "<div id=\"fororiginalimageareabg\"><img src=\""+request_uri+"common/tpl/images/blank.gif\" alt=\"original image\" border=\"0\" id=\"fororiginalimage\" /><img src=\""+request_uri+"common/tpl/images/original_image_box_close.gif\" alt=\"close original image\" border=\"0\" onclick=\"closeOriginalImage()\" id=\"closeOriginalImageBtn\"/></div>");
document.body.appendChild(dummy);
}
var orig_image = xGetElementById("fororiginalimage");
var tmp_image = new Image();
tmp_image.src = src;
var image_width = tmp_image.width;
var image_height = tmp_image.height;
orig_image.style.margin = "0px 0px 0px 0px";
orig_image.style.cursor = "move";
orig_image.src = src;
var areabg = xGetElementById("fororiginalimageareabg");
xWidth(areabg, image_width+36);
xHeight(areabg, image_height+46);
var area = xGetElementById("fororiginalimagearea");
xLeft(area, xScrollLeft());
xTop(area, xScrollTop());
xWidth(area, xWidth(document));
xHeight(area, xHeight(document));
area.style.visibility = "visible";
var area_width = xWidth(area);
var area_height = xHeight(area);
var x = parseInt((area_width-image_width)/2,10);
var y = parseInt((area_height-image_height)/2,10);
if(x<0) x = 0;
if(y<0) y = 0;
xLeft(areabg, x);
xTop(areabg, y);
var sel_list = xGetElementsByTagName("select");
for (var i = 0; i < sel_list.length; ++i) sel_list[i].style.visibility = "hidden";
xAddEventListener(orig_image, "mousedown", origImageDragEnable);
xAddEventListener(orig_image, "dblclick", closeOriginalImage);
xAddEventListener(window, "scroll", closeOriginalImage);
xAddEventListener(window, "resize", closeOriginalImage);
xAddEventListener(document, 'keydown',closeOriginalImage);
areabg.style.visibility = 'visible';
}
/**
* @brief 원본 이미지 보여준 닫는 함수
**/
function closeOriginalImage(evt) {
var area = xGetElementById("fororiginalimagearea");
if(area.style.visibility != "visible") return;
area.style.visibility = "hidden";
xGetElementById("fororiginalimageareabg").style.visibility = "hidden";
var sel_list = xGetElementsByTagName("select");
for (var i = 0; i < sel_list.length; ++i) sel_list[i].style.visibility = "visible";
xRemoveEventListener(area, "mousedown", closeOriginalImage);
xRemoveEventListener(window, "scroll", closeOriginalImage);
xRemoveEventListener(window, "resize", closeOriginalImage);
xRemoveEventListener(document, 'keydown',closeOriginalImage);
}
/**
* @brief 원본 이미지 드래그
**/
var origDragManager = {obj:null, isDrag:false}
function origImageDragEnable(evt) {
var e = new xEvent(evt);
var obj = e.target;
if(obj.id != "fororiginalimage") return;
obj.draggable = true;
obj.startX = e.pageX;
obj.startY = e.pageY;
if(!origDragManager.isDrag) {
origDragManager.isDrag = true;
xAddEventListener(document, "mousemove", origImageDragMouseMove, false);
}
xAddEventListener(document, "mousedown", origImageDragMouseDown, false);
}
function origImageDrag(obj, px, py) {
var x = px - obj.startX;
var y = py - obj.startY;
var areabg = xGetElementById("fororiginalimageareabg");
xLeft(areabg, xLeft(areabg)+x);
xTop(areabg, xTop(areabg)+y);
obj.startX = px;
obj.startY = py;
}
function origImageDragMouseDown(evt) {
var e = new xEvent(evt);
var obj = e.target;
if(obj.id != "fororiginalimage" || !obj.draggable) return;
if(obj) {
xPreventDefault(evt);
obj.startX = e.pageX;
obj.startY = e.pageY;
origDragManager.obj = obj;
xAddEventListener(document, 'mouseup', origImageDragMouseUp, false);
origImageDrag(obj, e.pageX, e.pageY);
}
}
function origImageDragMouseUp(evt) {
if(origDragManager.obj) {
xPreventDefault(evt);
xRemoveEventListener(document, 'mouseup', origImageDragMouseUp, false);
xRemoveEventListener(document, 'mousemove', origImageDragMouseMove, false);
xRemoveEventListener(document, 'mousemdown', origImageDragMouseDown, false);
origDragManager.obj.draggable = false;
origDragManager.obj = null;
origDragManager.isDrag = false;
}
}
function origImageDragMouseMove(evt) {
var e = new xEvent(evt);
var obj = e.target;
if(!obj) return;
if(obj.id != "fororiginalimage") {
xPreventDefault(evt);
xRemoveEventListener(document, 'mouseup', origImageDragMouseUp, false);
xRemoveEventListener(document, 'mousemove', origImageDragMouseMove, false);
xRemoveEventListener(document, 'mousemdown', origImageDragMouseDown, false);
origDragManager.obj.draggable = false;
origDragManager.obj = null;
origDragManager.isDrag = false;
return;
}
xPreventDefault(evt);
origDragManager.obj = obj;
xAddEventListener(document, 'mouseup', origImageDragMouseUp, false);
origImageDrag(obj, e.pageX, e.pageY);
}
/**
* @brief 이름, 게시글등을 클릭하였을 경우 팝업 메뉴를 보여주는 함수
**/

Binary file not shown.

Before

Width:  |  Height:  |  Size: 610 B

View file

@ -171,7 +171,7 @@
$content = $this->get('content');
// url에 대해서 정규표현식으로 치환
$content = preg_replace('!([^>^"^\'^=])(http|https|ftp|mms):\/\/([^ ^<^"^\']*)!is','$1<a href="$2://$3" onclick="window.open(this.href);return false;">$2://$3</a>',' '.$content);
//$content = preg_replace('!([^>^"^\'^=])(http|https|ftp|mms):\/\/([^ ^<^"^\']*)!is','$1<a href="$2://$3" onclick="window.open(this.href);return false;">$2://$3</a>',' '.$content);
// 이 댓글을... 팝업메뉴를 출력할 경우
if($add_popup_menu && Context::get('is_logged') ) {

View file

@ -246,7 +246,7 @@
$content = $this->get('content');
// url에 대해서 정규표현식으로 치환
$content = preg_replace('!([^>^"^\'^=])(http|https|ftp|mms):\/\/([^ ^<^"^\']*)!is','$1<a href="$2://$3" onclick="window.open(this.href);return false;">$2://$3</a>',' '.$content);
//$content = preg_replace('!([^>^"^\'^=])(http|https|ftp|mms):\/\/([^ ^<^"^\']*)!is','$1<a href="$2://$3" onclick="window.open(this.href);return false;">$2://$3</a>',' '.$content);
// 이 게시글을... 팝업메뉴를 출력할 경우
if($add_popup_menu) {