/**
* @file modules/widget/js/widget.js
* @author zero (zero@nzeo.com)
* @brief 위젯 관리용 자바스크립트
**/
/* document.write(ln)의 경우 ajax로 처리시 가로채기 위한 함수 */
document.write = document.writeln = function(str){
if ( str.match(/^<\//) ) return;
if ( !window.opera ) str = str.replace(/&(?![#a-z0-9]+;)/g, "&");
str = str.replace(/(<[a-z]+)/g, "$1 xmlns='http://www.w3.org/1999/xhtml'");
var div = null;
if(document.createElementNS) div = document.createElementNS("http://www.w3.org/1999/xhtml","div");
else div = xCreateElement('div');
xInnerHtml(div, str);
var pos;
pos = document.getElementsByTagName("*");
pos = pos[pos.length - 1];
var nodes = div.childNodes;
while ( nodes.length ) {
pos.parentNode.appendChild( nodes[0] );
}
};
/* DOM 속성을 구하기 위한 몇가지 함수들.. */
// style의 값을 구하는게 IE랑 그외가 다름.
function getStyle(obj) {
var style = obj.getAttribute("style");
if(typeof(style)=="object") style = style["cssText"];
return style;
}
// float: 값을 구하는게 IE랑 그외가 다름
function getFloat(obj) {
var cssFloat = xIE4Up?obj.style.styleFloat:obj.style.cssFloat;
if(!cssFloat) cssFloat = 'left';
return cssFloat;
}
function setFloat(obj, fl) {
if(xIE4Up) obj.style.styleFloat = fl;
else obj.style.cssFloat = fl;
}
// padding값을 구하는 함수 (없을 경우 0으로 세팅), zbxe의 위젯에서만 사용
function getPadding(obj, direct) {
var padding = obj.getAttribute("widget_padding_"+direct);
if(!padding || padding == null) padding = 0;
return padding;
}
/* 위젯 핸들링 시작 */
var zonePageObj = null;
var zoneModuleSrl = 0;
function doStartPageModify(zoneID, module_srl) {
zonePageObj = xGetElementById(zoneID);
zoneModuleSrl = module_srl;
// 위젯 크기/여백 조절 레이어를 가장 밖으로 뺌
var obj = xGetElementById("tmpPageSizeLayer");
var dummy = xCreateElement("div");
xInnerHtml(dummy, xInnerHtml(obj));
dummy.id="pageSizeLayer";
dummy.style.visibility = "hidden";
dummy.style.position = "absolute";
dummy.style.left = 0;
dummy.style.top = 0;
document.body.appendChild(dummy);
obj.parentNode.removeChild(obj);
// 모든 위젯들의 크기를 정해진 크기로 맞춤
doFitBorderSize();
// 드래그와 리사이즈와 관련된 이벤트 리스너 생성
xAddEventListener(document,"click",doCheckWidget);
xAddEventListener(document,"mousedown",doCheckWidgetDrag);
}
// 내용 모두 삭제
function removeAllWidget() {
xInnerHtml(zonePageObj, '');
}
/**
* 특정 영역에 편집된 위젯들을 약속된 태그로 변환하여 return
**/
function getWidgetContent(obj) {
var html = "";
if(typeof(obj)=='undefined' || !obj) obj = zonePageObj;
var childObj = obj.firstChild;
while(childObj) {
if(childObj.nodeName == "DIV" && childObj.getAttribute("widget")) {
var widget = childObj.getAttribute("widget");
if(widget) {
switch(widget) {
case 'widgetBox' :
html += getWidgetBoxCode(childObj, widget);
break;
case 'widgetContent' :
html += getContentWidgetCode(childObj, widget);
break;
default :
html += getWidgetCode(childObj, widget);
break;
}
}
}
childObj = childObj.nextSibling;
}
return html;
}
// 컨텐츠 위젯 코드 구함
function getContentWidgetCode(childObj, widget) {
var cobj = childObj.firstChild;
while(cobj) {
if(cobj.nodeName == "DIV" && cobj.className == "widgetContent") {
var body = xInnerHtml(cobj);
return '
';
}
cobj = cobj.nextSibling;
}
}
// 위젯 박스 컨텐츠 코드 구함
function getWidgetBoxCode(childObj, widget) {
var cobj = childObj.firstChild;
while(cobj) {
if(cobj.className == "widgetBorder" || cobj.className == "widgetBoxBorder") {
var c2obj = cobj.firstChild;
while(c2obj) {
if(c2obj.className == "nullWidget") {
var body = getWidgetContent(c2obj);
return '
';
}
c2obj = c2obj.nextSibling;
}
}
cobj = cobj.nextSibling;
}
}
// 일반 위젯 컨텐츠 코드 구함
function getWidgetCode(childObj, widget) {
var attrs = "";
var code = "";
for(var i=0;i';
}
/**
* 직접 내용을 입력하는 위젯을 추가
**/
// 팝업 띄움
function doAddContent(mid) {
var url = request_uri.setQuery('module','widget').setQuery('act','dispWidgetAdminAddContent').setQuery('module_srl',zoneModuleSrl).setQuery('mid',mid);
popopen(url, "addContent");
}
// 직접 내용을 입력하기 위한 에디터 활성화 작업 및 form 데이터 입력
function doSyncPageContent() {
if(opener && opener.selectedWidget) {
var fo_obj = xGetElementById("content_fo");
var sel_obj = opener.selectedWidget;
fo_obj.style.value = getStyle(opener.selectedWidget);
fo_obj.widget_padding_left.value = getPadding(sel_obj, 'left');
fo_obj.widget_padding_right.value = getPadding(sel_obj,'right');
fo_obj.widget_padding_bottom.value = getPadding(sel_obj,'bottom');
fo_obj.widget_padding_top.value = getPadding(sel_obj,'top');
var obj = sel_obj.firstChild;
while(obj && obj.className != "widgetContent") obj = obj.nextSibling;
if(obj && obj.className == "widgetContent") {
var content = Base64.decode(xInnerHtml(obj));
xGetElementById("content_fo").content.value = content;
}
}
editorStart(1, "module_srl", "content", false, 400 );
//editor_upload_start(1);
setFixedPopupSize();
}
// 부모창에 위젯을 추가
function completeAddContent(fo_obj) {
var editor_sequence = fo_obj.getAttribute('editor_sequence');
var content = editorGetContent(editor_sequence);
var tpl = ''+
'';
opener.doAddWidgetCode(tpl);
window.close();
}
/* 박스 위젯 추가 */
function doAddWidgetBox() {
var tpl = ''+
'';
xInnerHtml(zonePageObj, xInnerHtml(zonePageObj)+tpl);
doFitBorderSize();
}
/* 일반 위젯을 추가하기 위해 위젯 팝업창을 띄움 */
function doAddWidget(fo) {
var sel = fo.widget_list;
var idx = sel.selectedIndex;
var val = sel.options[idx].value;
var module_srl = fo.module_srl.value;
var url = current_url.setQuery('module','widget').setQuery('act','dispWidgetGenerateCodeInPage').setQuery('selected_widget', val).setQuery('module_srl', module_srl);
popopen(url,'GenerateWidgetCode');
}
// widgetBorder에 height를 widgetOutput와 맞춰줌
function doFitBorderSize() {
var obj_list = xGetElementsByClassName('widgetBorder', zonePageObj);
for(var i=0;ixPageX(zonePageObj)+xWidth(zonePageObj)) px = xPageX(zonePageObj)+xWidth(zonePageObj)-xWidth(layer)-5;
xLeft(layer, px);
xTop(layer, py);
layer.style.visibility = "visible";
try {
formObj.width.focus();
} catch(e) {
}
}
function doHideWidgetSizeSetup() {
var layer = xGetElementById("pageSizeLayer");
layer.style.visibility = "hidden";
layer.style.display = "none";
}
function _getSize(value) {
if(!value) return 0;
var type = "px";
if(value.lastIndexOf("%")>=0) type = "%";
var num = parseInt(value,10);
if(num<1) return 0;
if(type == "%" && num > 100) num = 100;
return ""+num+type;
}
function _getBorderStyle(fld_color, fld_thick, fld_type) {
var color = fld_color.value;
color = color.replace(/^#/,'');
if(!color) color = '#FFFFFF';
else color = '#'+color;
var width = fld_thick.value;
if(!width) width = '0px';
else width = parseInt(width,10)+'px';
var style = fld_type.options[fld_type.selectedIndex].value;
if(!style) style = 'solid';
var str = color+' '+width+' '+style;
return str;
}
function _getBGColorStyle(fld_color) {
var color = fld_color.replace(/^#/,'');
if(!color) color = '#FFFFFF';
else color = '#'+color;
return color;
}
function doApplyWidgetSize(fo_obj) {
if(selectedSizeWidget) {
if(fo_obj.widget_align.selectedIndex == 1) setFloat(selectedSizeWidget, 'right');
else setFloat(selectedSizeWidget, 'left');
var width = _getSize(fo_obj.width.value);
if(width) selectedSizeWidget.style.width = width;
var height = _getSize(fo_obj.height.value);
if(height && height != "100%") selectedSizeWidget.style.height = height;
else {
selectedSizeWidget.style.height = '';
var widgetBorder = xGetElementsByClassName('widgetBorder',selectedSizeWidget);
for(var i=0;i zoneRight) nx = zoneRight;
if(cssFloat == 'right') nx = sx + pWidth;
var new_width = nx - sx;
if(new_width < minWidth) new_width = minWidth;
var new_height = ny - sy;
if(new_height < minHeight) new_height = minHeight;
if( zoneRight < sx+new_width) new_width = zoneRight - sx;
// 위젯의 크기 조절
xWidth(tobj.nextSibling.nextSibling, new_width);
xHeight(tobj.nextSibling.nextSibling, new_height);
xWidth(tobj.parentNode, new_width);
xHeight(tobj.parentNode, new_height);
// 위젯 리사이즈 (좌측)
} else if(tobj.className == 'widgetResizeLeft' || tobj.className == 'widgetBoxResizeLeft') {
if(nx < zoneLeft) nx = zoneLeft;
if(cssFloat == 'left') nx = sx;
var new_width = pWidth + (sx - nx);
if(new_width < minWidth) new_width = minWidth;
var new_height = ny - sy;
if(new_height < minHeight) new_height = minHeight;
// 위젯의 크기 조절
xWidth(tobj.nextSibling, new_width);
xHeight(tobj.nextSibling, new_height);
xWidth(tobj.parentNode, new_width);
xHeight(tobj.parentNode, new_height);
// 위젯 드래그
} else {
var obj = widgetGetTmpObject(tobj);
xLeft(obj, parseInt(xPageX(obj),10) + parseInt(dx,10));
xTop(obj, parseInt(xPageY(obj),10) + parseInt(dy,10));
// 박스 안에 있을 경우에는 박스내의 위젯하고 자리를 바꾸고 그 외의 경우에는 박스를 빠져 나간다
if(tobj.parentNode != zonePageObj) {
// 박스내에 있는 위젯들을 구함
var widgetList = xGetElementsByClassName("widgetOutput",tobj.parentNode);
for(var i=0;i= l && tobj.xDPX <= ll && tobj.xDPY >= t && tobj.xDPY <= tt && tobj.parentNode == target_obj.parentNode) {
var next1 = target_obj.nextSibling;
if(!next1) {
next1 = xCreateElement("DIV");
target_obj.parentNode.appendChild(next1);
}
var next2 = tobj.nextSibling;
if(!next2) {
next2 = xCreateElement("DIV");
tobj.parentNode.appendChild(next2);
}
if(next1) next1.parentNode.insertBefore(tobj, next1);
if(next2) next2.parentNode.insertBefore(target_obj, next2);
doFitBorderSize();
widgetList = null;
return;
}
}
widgetList = null;
// 만약 다른 위젯과 자리를 바꾸지 못하였는데 자기 부모창밖에 있는게 확인이 되면 박스 밖으로 내보낸다.
var l = xPageX(tobj.parentNode);
var t = xPageY(tobj.parentNode);
var ll = parseInt(l,10) + parseInt(xWidth(tobj.parentNode),10);
var tt = parseInt(t,10) + parseInt(xHeight(tobj.parentNode),10);
if( (tobj.xDPX < l || tobj.xDPX > ll) || (tobj.xDPY < t || tobj.xDPY > tt) ) {
zonePageObj.insertBefore(tobj, tobj.parentNode.parentNode.parentNode);
doFitBorderSize();
return;
}
// 박스 밖에 있을 경우에는 다른 위젯과 자리를 바꾸거나 박스내에 들어가도록 한다
} else {
// 이동하려는 위젯이 박스 위젯이 아니라면 박스 위젯들을 구해서 입력 유무를 검사한다
if(tobj.getAttribute("widget")!="widgetBox") {
var boxList = xGetElementsByClassName("nullWidget", zonePageObj);
for(var i=0;i= l && tobj.xDPX <= ll && tobj.xDPY >= t && tobj.xDPY <= tt) {
if(target_obj.className == "nullWidget") {
target_obj.appendChild(tobj);
// 이동을 멈춤
widgetManualEnd();
doFitBorderSize();
boxList = null;
return;
}
}
}
boxList = null;
}
// 다른 위젯들을 구해서 자리를 바꿈
var widgetList = xGetElementsByClassName("widgetOutput",zonePageObj);
for(var i=0;i= l && tobj.xDPX <= ll && tobj.xDPY >= t && tobj.xDPY <= tt && tobj.parentNode == target_obj.parentNode) {
var next1 = target_obj.nextSibling;
if(!next1) next1 = target_obj.parentNode.lastChild;
if(!next1) {
next1 = xCreateElement("DIV");
target_obj.parentNode.appendChild(next1);
}
var next2 = tobj.nextSibling;
if(!next2) {
next2 = xCreateElement("DIV");
tobj.parentNode.appendChild(next2);
}
if(next1) next1.parentNode.insertBefore(tobj, next1);
if(next2) next2.parentNode.insertBefore(target_obj, next2);
doFitBorderSize();
widgetList = null;
return;
}
}
widgetList = null;
}
}
}
// 드래그 종료 (이동되는 object가 이동할 곳에 서서히 이동되는 것처럼 보이는 효과)
function widgetDragEnd(tobj, px, py) {
var obj = widgetGetTmpObject(tobj);
widgetDisapear = widgetDisapearObject(obj, tobj);
widgetDragDisable(tobj.getAttribute('id'));
}
// 스르르 사라지게 함 (일단 사라지게 하는 기능을 제거.. 속도 문제)
function widgetDisapearObject(obj, tobj) {
xInnerHtml(tobj,xInnerHtml(obj));
xInnerHtml(obj,'');
xDisplay(obj, 'none');
obj.parentNode.removeChild(obj);
widgetTmpObject[tobj.id] = null;
return;
var it = 5;
var ib = 1;
var x = parseInt(xPageX(obj),10);
var y = parseInt(xPageY(obj),10);
var ldt = (x - parseInt(xPageX(tobj),10)) / ib;
var tdt = (y - parseInt(xPageY(tobj),10)) / ib;
return setInterval(function() {
if(ib < 1) {
clearInterval(widgetDisapear);
xInnerHtml(tobj,xInnerHtml(obj));
xInnerHtml(obj,'');
xDisplay(obj, 'none');
obj.parentNode.removeChild(obj);
widgetTmpObject[tobj.id] = null;
return;
}
ib -= 5;
x-=ldt;
y-=tdt;
xLeft(obj, x);
xTop(obj, y);
}, it/ib);
}
// 마우스다운 이벤트 발생시 호출됨
function widgetMouseDown(e) {
var evt = new xEvent(e);
var obj = evt.target;
while(obj && !obj.draggable) {
obj = xParent(obj, true);
}
if(obj) {
xPreventDefault(e);
obj.xDPX = evt.pageX;
obj.xDPY = evt.pageY;
widgetDragManager.obj = obj;
xAddEventListener(document, 'mouseup', widgetMouseUp, false);
if (obj.dragStart) obj.dragStart(obj, evt.pageX, evt.pageY);
}
}
// 마우스 버튼을 놓았을때 동작될 함수 (각종 이벤트 해제 및 변수 설정 초기화)
function widgetMouseUp(e) {
if (widgetDragManager.obj) {
xPreventDefault(e);
xRemoveEventListener(document, 'mouseup', widgetMouseUp, false);
if (widgetDragManager.obj.dragEnd) {
var evt = new xEvent(e);
widgetDragManager.obj.dragEnd(widgetDragManager.obj, evt.pageX, evt.pageY);
}
widgetDragManager.obj = null;
widgetDragManager.isDrag = false;
}
}
// 드래그할때의 object이동등을 담당
function widgetDragMouseMove(e) {
var evt = new xEvent(e);
if(widgetDragManager.obj) {
xPreventDefault(e);
var obj = widgetDragManager.obj;
var dx = evt.pageX - obj.xDPX;
var dy = evt.pageY - obj.xDPY;
obj.xDPX = evt.pageX;
obj.xDPY = evt.pageY;
if (obj.drag) {
obj.drag(obj, dx, dy);
} else {
xMoveTo(obj, xLeft(obj) + dx, xTop(obj) + dy);
}
}
}
// 해당 object 에 더 이상 drag가 되지 않도록 설정
function widgetDragDisable(id) {
if (!widgetDragManager) return;
var obj = xGetElementById(id);
obj.draggable = false;
obj.dragStart = null;
obj.drag = null;
obj.dragEnd = null;
//obj.style.backgroundColor = obj.getAttribute('source_color');
xRemoveEventListener(obj, 'mousedown', widgetMouseDown, false);
return;
}
// 강제로 드래그를 종료시킴
function widgetManualEnd() {
var tobj = widgetDragManager.obj;
if(!tobj) return;
xRemoveEventListener(document, 'mouseup', widgetMouseUp, false);
var obj = widgetGetTmpObject(tobj);
widgetDisapear = widgetDisapearObject(obj, tobj);
widgetDragDisable(tobj.getAttribute('id'));
widgetDragManager.obj = null;
widgetDragManager.isDrag = false;
}