/* * 要素の位置やサイズに関する情報を扱う */ function() { var bind = function(obj, fn) { return function() { return fn.apply(obj, arguments); } }; this.styleSheets = []; /** * 指定要素のページ内での絶対位置を取得する */ this.getGeometry = function(node) { var style = node.currentStyle || window.getComputedStyle(node); var result = { width : node.offsetWidth, height : node.offsetHeight, left : 0, top : 0, right : node.offsetWidth, bottom : node.offsetHeight, borderTop : parseInt(style.borderTopWidth), borderRight : parseInt(style.borderRightWidth), borderBottom : parseInt(style.borderBottomWidth), borderLeft : parseInt(style.borderLeftWidth), paddingTop : parseInt(style.paddingTop), paddingRight : parseInt(style.paddingRight), paddingBottom : parseInt(style.paddingBottom), paddingLeft : parseInt(style.paddingLeft) }; var parent = node; while (parent) { result.left += parent.offsetLeft; result.top += parent.offsetTop; parent = parent.offsetParent; } if (document.all && document.compatMode == 'BackCompat') { //IE compat result.right += result.left; result.bottom += result.top; } else { result.right += result.left - result.borderLeft - result.borderRight; result.bottom += result.top - result.borderTop - result.borderBottom; } return result; }; this.getWindowSize = function() { if (window.innerWidth) return { width : window.innerWidth, height : window.innerHeight }; if (document.documentElement && document.documentElement.clientWidth) return { width : document.documentElement.clientWidth, height : document.documentElement.clientHeight }; if (document.body.clientWidth) return { width : document.body.clientWidth, height : document.body.clientHeight }; }; /** * 指定要素をリサイズ可能にする * 依存するライブラリ: * event.js, style.js * 影響を受けるプロパティ: * document.onmouseup * document.onmousemove * document.onselectstart */ this.resizable = function(node) { var HANDLE_SIZE = 7; var HANDLE_HALF = HANDLE_SIZE / 2; var geometry = this; var fixEvent = @INCLUDE(event.js); var selector = node.nodeName; if (node.id) selector += '#' + node.id; else if (node.className || node.styleClass) selector += '.' + (node.className || node.styleClass).split(/\s+/).join('.'); geometry.styleSheets.push((@INCLUDE(style.js))( selector + " div.n-handle," + selector + " div.ne-handle," + selector + " div.e-handle," + selector + " div.se-handle," + selector + " div.s-handle," + selector + " div.sw-handle," + selector + " div.w-handle," + selector + " div.nw-handle {" + " position:absolute;" + " opacity:0;" + //set 0.5 on debug " filter:alpha(opacity=0);" + //set 50 on debug " line-height:0px;" + "}" + selector + " div.n-handle," + selector + " div.s-handle {" + " width:100%;" + " height:" + HANDLE_SIZE + "px;" + " background-color:#FFAAAA;" + " cursor:n-resize;" + "}" + selector + " div.e-handle," + selector + " div.w-handle {" + " width:" + HANDLE_SIZE + "px;" + " height:100%;" + " background-color:#FFAAAA;" + " cursor:e-resize;" + "}" + selector + " div.ne-handle," + selector + " div.se-handle," + selector + " div.sw-handle," + selector + " div.nw-handle {" + " width:" + HANDLE_SIZE + "px;" + " height:" + HANDLE_SIZE + "px;" + " background-color:#AAAAFF;" + "}" + selector + " div.ne-handle { cursor:ne-resize; }" + selector + " div.se-handle { cursor:se-resize; }" + selector + " div.sw-handle { cursor:sw-resize; }" + selector + " div.nw-handle { cursor:nw-resize; }" )); //resize handles var prepare_events = function() { document.onmouseup = function(evt) { evt = fixEvent(evt).stop(); document.onmousemove = null; document.onmouseup = null; }; document.onselectstart = function(evt) { evt = fixEvent(evt).stop(); }; }; var new_handle = function(clazz) { var handle = node.appendChild(document.createElement('div')); handle.className = handle.styleClass = clazz; handle.innerHTML = ' '; return handle; }; var handles = { n : new_handle('n-handle'), e : new_handle('e-handle'), s : new_handle('s-handle'), w : new_handle('w-handle'), ne : new_handle('ne-handle'), se : new_handle('se-handle'), sw : new_handle('sw-handle'), nw : new_handle('nw-handle') }; handles.contains = function(el) { for (var key in this) { if (this[key] === el) return true; } return false; }; handles['n'].onmousedown = bind(geometry, function(evt) { var geom = this.getGeometry(node); evt = fixEvent(evt).stop(); var target = evt.target; target.offX = evt.pageX - geom.left; target.offY = evt.pageY - geom.top; document.onmousemove = bind(this, function(evt) { var geom = this.getGeometry(node); evt = fixEvent(evt).stop(); if (evt.pageY - target.offY < geom.bottom) { prefit(); node.style.top = (evt.pageY - target.offY) + 'px'; node.style.height = (geom.bottom - this.getGeometry(node).top) + 'px'; fit(); } }); prepare_events(); }); handles['ne'].onmousedown = bind(geometry, function(evt) { var geom = this.getGeometry(node); evt = fixEvent(evt).stop(); var target = evt.target; target.offX = evt.offsetX; target.offY = evt.offsetY; document.onmousemove = bind(this, function(evt) { var geom = geometry.getGeometry(node); evt = fixEvent(evt).stop(); if (evt.pageY - target.offY < geom.bottom && evt.pageX - target.offX > geom.left) { prefit(); node.style.top = (evt.pageY) + 'px'; node.style.width = (evt.pageX - geom.left) + 'px'; node.style.height = (geom.bottom - this.getGeometry(node).top) + 'px'; fit(); } }); prepare_events(); }); handles['e'].onmousedown = bind(geometry, function(evt) { evt = fixEvent(evt).stop(); var target = evt.target; target.offX = evt.offsetX; target.offY = evt.offsetY; document.onmousemove = bind(this, function(evt) { var geom = geometry.getGeometry(node); evt = fixEvent(evt).stop(); if (evt.pageX - target.offX > geom.left) { prefit(); node.style.width = (evt.pageX - target.offX - geom.left) + 'px'; fit(); } }); prepare_events(); }); handles['se'].onmousedown = bind(geometry, function(evt) { var geom = this.getGeometry(node); evt = fixEvent(evt).stop(); var target = evt.target; target.offX = evt.offsetX; target.offY = evt.offsetY; document.onmousemove = bind(this, function(evt) { var geom = geometry.getGeometry(node); evt = fixEvent(evt).stop(); if (evt.pageY - target.offY > geom.top && evt.pageX - target.offX > geom.left) { prefit(); node.style.width = (evt.pageX - target.offX - geom.left) + 'px'; node.style.height = (evt.pageY - target.offY - geom.top) + 'px'; fit(); } }); prepare_events(); }); handles['s'].onmousedown = bind(geometry, function(evt) { evt = fixEvent(evt).stop(); var geom = geometry.getGeometry(node); var target = evt.target; target.offX = evt.offsetX; //evt.pageX - geom.left; target.offY = evt.offsetY; //evt.pageY - geom.top + geom.height; document.onmousemove = bind(this, function(evt) { var geom = geometry.getGeometry(node); evt = fixEvent(evt).stop(); if (evt.pageY - target.offY > geom.top) { prefit(); node.style.height = (evt.pageY - geom.top - target.offY) + 'px'; fit(); } }); prepare_events(); }); handles['sw'].onmousedown = bind(geometry, function(evt) { evt = fixEvent(evt).stop(); var target = evt.target; target.offX = evt.offsetX; target.offY = evt.offsetY; document.onmousemove = bind(this, function(evt) { var geom = geometry.getGeometry(node); evt = fixEvent(evt).stop(); if (evt.pageY - target.offY > geom.top && evt.pageX - target.offX < geom.right) { prefit(); node.style.left = evt.pageX + 'px'; var moved = geometry.getGeometry(node); if (moved.left != geom.left) { node.style.width = (geom.right - evt.pageX) + 'px'; } node.style.height = (evt.pageY - target.offY - geom.top) + 'px'; fit(); } }); prepare_events(); }); handles['w'].onmousedown = bind(geometry, function(evt) { evt = fixEvent(evt).stop(); var target = evt.target; target.offX = evt.offsetX; target.offY = evt.offsetY; document.onmousemove = bind(this, function(evt) { var geom = geometry.getGeometry(node); evt = fixEvent(evt).stop(); if (evt.pageX - target.offX < geom.right) { prefit(); node.style.left = evt.pageX + 'px'; var moved = geometry.getGeometry(node); if (moved.left != geom.left) { node.style.width = (geom.right - evt.pageX) + 'px'; } fit(); } }); prepare_events(); }); handles['nw'].onmousedown = bind(geometry, function(evt) { evt = fixEvent(evt).stop(); var target = evt.target; target.offX = evt.offsetX; target.offY = evt.offsetY; document.onmousemove = bind(this, function(evt) { var geom = geometry.getGeometry(node); evt = fixEvent(evt).stop(); if (evt.pageY - target.offY < geom.bottom && evt.pageX - target.offX < geom.right) { prefit(); node.style.left = evt.pageX + 'px'; node.style.top = evt.pageY + 'px'; var moved = geometry.getGeometry(node); if (moved.left != geom.left) node.style.width = (geom.right - evt.pageX) + 'px'; if (moved.top != geom.top) node.style.height = (geom.bottom - evt.pageY) + 'px'; fit(); } }); prepare_events(); }); var prefit = function() { var children = node.childNodes; for (var i = 0; i < children.length; i++) { var child = children.item(i); if (child.nodeType != 1) continue; if (handles.contains(child)) continue; //child.style['_display'] = child.style.display; child.style.display = 'none'; } }; var postfit = function() { var children = node.childNodes; for (var i = 0; i < children.length; i++) { var child = children.item(i); if (child.nodeType != 1) continue; if (handles.contains(child)) continue; //child.style.display = child.style['_display']; child.style.display = ''; //delete child.style['_display']; } }; var fit = function() { if (typeof node.onfit == 'function') node.onfit(); var g = geometry.getGeometry(node); var off = geometry.getGeometry(handles['n'].offsetParent); g.left -= off.left; g.top -= off.top; if (document.all) { //IE g.borderTop = 0; g.borderRight = 0; g.borderBottom = 0; g.borderLeft = 0; } handles['n'].style.left = (g.left - g.borderLeft) + 'px'; handles['n'].style.top = (g.top - g.borderTop - HANDLE_HALF) + 'px'; handles['n'].style.width = g.width + 'px'; handles['ne'].style.top = (g.top - g.borderTop - HANDLE_HALF) + 'px'; handles['ne'].style.left = (g.left + g.width - g.borderLeft - g.borderRight - HANDLE_HALF) + 'px'; handles['e'].style.left = (g.width + g.left - g.borderLeft - g.borderRight - HANDLE_HALF) + 'px'; handles['e'].style.top = g.top + 'px'; handles['e'].style.height = g.height + 'px'; handles['se'].style.left = (g.width + g.left - g.borderLeft - HANDLE_HALF) + 'px'; handles['se'].style.top = (g.top + g.height - g.borderTop - HANDLE_HALF) + 'px'; handles['s'].style.left = (g.left - g.borderLeft - HANDLE_HALF) + 'px'; handles['s'].style.top = (g.top + g.height - g.borderTop - HANDLE_HALF) + 'px'; handles['s'].style.width = g.width + 'px'; handles['sw'].style.left = (g.left - g.borderLeft - HANDLE_HALF) + 'px'; handles['sw'].style.top = (g.top + g.height - g.borderTop - HANDLE_HALF) + 'px'; handles['w'].style.left = g.left - g.borderLeft - HANDLE_HALF + 'px'; handles['w'].style.top = g.top + 'px'; handles['w'].style.height = g.height + 'px'; handles['nw'].style.left = (g.left - g.borderLeft - HANDLE_HALF) + 'px'; handles['nw'].style.top = (g.top - g.borderTop - HANDLE_HALF) + 'px'; postfit(); }; fit(); }; this.finalize = function() { for (var i = 0; i < this.styleSheets.length; i++) this.styleSheets[i].parentNode.removeChild(this.styleSheets[i]); }; }