cheditor5 특정 이미지 업로드시 검게 출력되는 문제 수정

This commit is contained in:
thisgun
2021-01-25 12:26:28 +09:00
parent ddde0d7641
commit 682f6620cb
14 changed files with 2468 additions and 213 deletions

View File

@ -1,9 +1,9 @@
// ================================================================
// CHEditor 5.1.9.3
// CHEditor 5.1.9.3-p4
// ----------------------------------------------------------------
// Homepage: http://www.chcode.com
// EMail: support@chcode.com
// Copyright (c) 1997-2016 CHSOFT
// Copyright (c) 1997-2020 CHSOFT
// ================================================================
var GB = {
colors: ['#000000','#313131','#434343','#535353','#666666','#999999','#a0a0a0','#b5b5b5','#c0c0c0','#dcdcdc','#eeeeee','#ffffff',
@ -517,7 +517,7 @@ function setConfig() {
useModifyTable : true,
useMap : true,
useTextBlock : true,
useFullScreen : true,
useFullScreen : false,
usePageBreak : false
},
base, elem, i, editorUri, locationAbs;
@ -557,9 +557,9 @@ function setConfig() {
this.currentRS = {};
this.resizeEditor = {};
this.setFullScreenMode = false;
this.modalElementZIndex = 1001;
this.modalElementZIndex = 10001;
this.config = config;
this.templateFile = 'template.xml';
this.templateFile = this.undefined(this.browser.mobile) ? 'template.xml' : 'template-mobile.xml';
this.templatePath = config.editorPath + this.templateFile;
this.W3CRange = !(this.undefined(window.getSelection));
this.inputForm = 'textAreaId';
@ -1082,31 +1082,10 @@ cheditor.prototype = {
showError('현재 브라우저에서 ' + self.templateFile + ' 파일을 사용할 수 없습니다.');
}
},
/*
getCDATASection : function (node) {
var elem, data;
if (node.hasChildNodes()) {
elem = node.firstChild;
while (elem && elem.nodeType !== GB.node.cdata_section) {
elem = elem.nextSibling;
}
if (elem && elem.nodeType === GB.node.cdata_section) {
data = elem.data;
data = data.replace(/\n/g, '');
data = data.replace(/(\s+?)<([^>]*)>/g, '<$2>');
data = this.trimSpace(data);
return data;
}
}
return null;
},
*/
getCDATASection : function (node) {
var text = node.textContent || node.text;
text = text.replace(/\n/g, '');
text = text.replace(/(\s+?)<([^>]*)>/g, '<$2>');
text = this.trimSpace(text);
return text;
return this.trimSpace(text.replace(/\n/g, '').replace(/(\s+?)<([^>]*)>/g, '<$2>'));
},
setToolbarBgPosition : function (elem, attr) {
@ -2044,7 +2023,7 @@ cheditor.prototype = {
container.style.width = self.config.editorWidth;
self.cheditor.container = container;
},
/*
loadTemplate : function (xmlDoc) {
var self = this,
tmpl = xmlDoc.getElementsByTagName('Template').item(0),
@ -2091,55 +2070,6 @@ cheditor.prototype = {
self.cheditor.htmlEditable.style.visibility = 'hidden';
container.appendChild(self.cheditor.htmlEditable);
},
*/
loadTemplate : function (xmlDoc) {
var cdata, container, dragHandle, html, modalFrame, popupWindow, tmpDiv, tmpl, toolbar;
tmpl = xmlDoc.getElementsByTagName('Template').item(0);
if (!tmpl) {
throw 'Template 노드를 설정할 수 없습니다.';
}
cdata = tmpl.getElementsByTagName('Container').item(0).getElementsByTagName('Html').item(0);
if (!cdata) {
throw 'XML CDATA 오류';
}
html = this.getCDATASection(cdata);
tmpDiv = document.createElement('div');
tmpDiv.innerHTML = html;
container = tmpDiv.firstChild;
toolbar = tmpl.getElementsByTagName('Toolbar').item(0);
this.createEditorElement(container, toolbar);
cdata = tmpl.getElementsByTagName('PopupWindow').item(0).getElementsByTagName('Html').item(0);
if (!cdata) {
throw 'XML CDATA 오류';
}
html = this.getCDATASection(cdata);
tmpDiv.innerHTML = html;
popupWindow = tmpDiv.firstChild;
this.cheditor.popupElem = popupWindow;
dragHandle = popupWindow.firstChild;
this.cheditor.dragHandle = dragHandle;
this.cheditor.popupTitle = dragHandle.getElementsByTagName('label')[0];
this.cheditor.popupFrameWrapper = dragHandle.nextSibling;
container.appendChild(popupWindow);
modalFrame = document.createElement('div');
modalFrame.className = 'cheditor-modalPopupTransparent';
this.cheditor.modalBackground = modalFrame;
this.cheditor.modalBackground.id = 'popupModalBackground';
this.cheditor.modalBackground.className = 'cheditor-popupModalBackground';
container.parentNode.insertBefore(modalFrame, container);
this.cheditor.htmlEditable = document.createElement('iframe');
this.cheditor.htmlEditable.style.display = 'none';
this.cheditor.htmlEditable.style.width = '1px';
this.cheditor.htmlEditable.style.height = '1px';
this.cheditor.htmlEditable.style.visibility = 'hidden';
container.appendChild(this.cheditor.htmlEditable);
},
imageEvent : function (img, action) {
var self = this,
@ -5063,7 +4993,12 @@ cheditor.prototype = {
if (!(this.undefined(GB.popupWindow[popupName]))) {
var popup = GB.popupWindow[popupName];
if (popupName === 'ImageUpload' && window.File && window.FileReader && window.FileList && window.Blob) {
popup.tmpl = 'image.html5.html';
if (this.browser.mobile) {
popup.tmpl = 'image.html5.m.html';
popup.width = 450; // 팝업 윈도우 가로 폭 크기(px)
} else {
popup.tmpl = 'image.html5.html';
}
}
this.popupWinLoad(popup);
} else {

View File

@ -133,4 +133,15 @@ body {
line-height: 1em;
font-family: 'Malgun Gothic', gulim, tahoma, helvetica;
font-size: 12px;
}
.webgl_logo_wrapper {
text-align: center;
margin-top: 40px;
border-top: #cccccc 1px solid;
}
.webgl_logo_wrapper img {
width: 50px;
height: 50px;
vertical-align: middle;
}

View File

@ -0,0 +1,136 @@
#uploadWindow {
display: none;
}
.clear { clear: both; }
#container {
padding: 0;
}
.imageListWrapperHtml5, .imageListWrapper, .dragOver {
background-color: #fff;
position: absolute;
height: 250px;
width: 255px;
overflow-y: scroll;
border-radius: 4px;
border: 2px #66b2ff solid;
}
/* .imageListWrapperHtml5 {
border: 2px #66b2ff dashed;
} */
.imageListWrapper {
border: 1px #aaa solid;
box-shadow: 0 0 3px #aaa;
}
.dragOver {
border: 2px #ff3399 dashed;
}
#imageInfoBox {
position: absolute;
left: 300px;
}
.imageInfoTitle {
text-align: center;
background-color: #e0e0e0;
width: 130px;
font-family: "Malgun Gothic",gulim;
font-weight: bold;
font-size: 12px;
}
.imageInfoTitle span {
display: inline-block;
margin-top: -1px;
line-height: 22px;
}
.remove-button {
width: 93px;
height: 22px;
cursor: pointer;
vertical-align: middle;
}
.imageBox, .imageBoxHighlighted {
width: 120px;
height: 90px;
margin: 3px 3px;
float: left;
}
.imageBox_theImage,.imageBox_theImage_over {
width: 100%;
height: 100%;
position: relative;
display: block;
background-color: #fff;
}
.imageBox .imageBox_theImage{
border: 1px solid #e0e0e0;
background-image: url('../icons/dot.gif');
background-position: center center;
background-repeat: no-repeat;
}
.imageBox .imageBox_theImage_over {
border: 1px solid #a0a0a0;
background-image: url('../icons/dot.gif');
background-position: center center;
background-repeat: no-repeat;
cursor: pointer;
}
.imageBoxHighlighted .imageBox_theImage {
border: 1px solid #ff6600;
}
.imageBoxHighlighted .imageBox_theImage_over {
border: 1px solid #ff6600;
background-image: url('../icons/dot.gif');
background-position: center center;
background-repeat: no-repeat;
}
.removeButton, .removeButton_over {
display: none;
position: absolute;
cursor: pointer;
background-image: url(../icons/imageUpload/cross-small.png);
background-repeat: no-repeat;
background-position: center center;
}
.removeButton {
border: 1px solid #a0a0a0;
}
.removeButton_over {
border: 1px solid #808080;
}
#insertionMarker {
height: 102px;
width: 6px;
position: absolute;
display: none;
}
#insertionMarker img {
float: left;
}
#dragDropContent{
position: absolute;
z-index: 10;
display: none;
}
.button {
width: 64px;
height: 22px;
margin: 0 2px;
cursor: pointer;
vertical-align: middle;
}
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #fff;
line-height: 1em;
font-family: 'Malgun Gothic', gulim, tahoma, helvetica;
font-size: 12px;
}

View File

@ -14,6 +14,8 @@ a.cheditor-tag-path-elem:hover {
border-top: 1px #ccc solid;
position: relative;
text-align: left;
-webkit-box-sizing: content-box;
box-sizing: content-box;
}
.cheditor-tb-wrapper {
border-right: 1px #ccc solid;
@ -21,11 +23,10 @@ a.cheditor-tag-path-elem:hover {
border-bottom: 1px #ccc solid;
position: relative;
display: block;
-webkit-box-sizing: inherit;
box-sizing: inherit;
background-color: #f0f0f0;
zoom:1;
height:auto ! important;
}
.cheditor-tb-wrapper:after{display:block;visibility:hidden;clear:both;content:""}
.cheditor-tb-wrapper-readonly {
border-right: 1px #ccc solid;
border-left: 1px #ccc solid;
@ -423,6 +424,8 @@ a.cheditor-tag-path-elem:hover {
box-shadow: 0 0 10px #bbb;
padding: 0;
overflow: hidden;
-webkit-box-sizing: content-box;
box-sizing: content-box;
}
.cheditor-popup-cmd-button {
width: 64px;
@ -437,6 +440,8 @@ a.cheditor-tag-path-elem:hover {
padding: 10px;
border: none;
text-align: center;
-webkit-box-sizing: content-box;
box-sizing: content-box;
}
.cheditor-popup-cframe iframe {

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -6,7 +6,7 @@
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="../css/imageupload.css" />
<script src="js/dialog.js" type="text/javascript"></script>
<script src="js/image.html5.js" type="text/javascript"></script>
<script src="js/image.html5.js" type="text/javascript"></script>
</head>
<body>
<div id="uploadWindow">
@ -65,9 +65,7 @@
<div style="margin-top:5px;font-size: 12px">
<input type="checkbox" name="use_spacer" value="1" checked="checked" />사진 여백 넣기
</div>
<div style="text-align:center;margin-top:15px">
<span style="font-size:12px;font-family:Malgun Gothic,dotum,tahoma;">(전체 사진에 적용됨)</span>
</div>
<div id="webgl_logo_wrapper" class="webgl_logo_wrapper"></div>
</form>
</div>
</div>

View File

@ -0,0 +1,78 @@
<!DOCTYPE html>
<html>
<head>
<title>CHEditor</title>
<meta name="robots" content="noindex, nofollow" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="../css/imageupload.m.css" />
<script src="js/dialog.js" type="text/javascript"></script>
<script src="js/image.html5.m.js" type="text/javascript"></script>
</head>
<body>
<div id="uploadWindow">
<div id="container">
<div style="margin: 0px 0px 10px 0px;">
<img src="../icons/imageUpload/remove_all.gif" class="remove-button" onclick="removeImages();"
alt="" style="vertical-align: middle" />
<input type="file" name="imageUpload[]" accept="image/jpeg,image/png,image/gif" id="inputImageUpload" multiple="multiple"
onchange="selectedFiles(event)" style="vertical-align: middle; visibility: hidden; width: 0px"/>
<img id="fileSelectButton" src="../icons/imageUpload/add.gif" alt="image button" onclick="inputImageUpload.click()"
style="vertical-align: middle; margin-left: -5px; cursor: pointer"/>
<span style="left:308px; top:5px;position:absolute;"><span id="imageCount">0</span>장 / 최대 <span id="maxImageNum"></span>장 사진</span>
</div>
<div id="imageListWrapper" class="imageListWrapperHtml5"></div>
<div id="imageInfoBox">
<div>
<div class="imageInfoTitle"><span>크기 줄이기</span></div>
<div style="text-align:left;font-size:12px;margin-top:7px;line-height:1.4em; padding-left: 5px">
<div>
<span style="vertical-align: middle">가로:</span>
<select name="resizeSelectBox" id="idResizeSelectBox" style="font-size: 12px; vertical-align: middle"></select>
<span style="vertical-align: middle">픽셀</span>
<div style="margin-top: 5px; display:none" id="idUserInputWrapper">
<span style="vertical-align: middle">입력:</span>
<input type="text" maxlength="4"
style="font-size: 12px; width:40px; vertical-align: middle" name="resizeWidth" id="idResizeWidth" />
<span style="vertical-align: middle">픽셀</span>
</div>
</div>
<div style="margin-top: 10px">사진 높이는 자동으로 설정됩니다.</div>
</div>
</div>
<div style="margin-top: 20px">
<div class="imageInfoTitle"><span>정렬</span></div>
<form name="fm_alignment" id="id_alignment" style="display: inline">
<table style="margin:7px auto 10px auto;border:0;padding:0;border-spacing:0">
<tr>
<td style="text-align: center">
<img src="../icons/image_align_left.png" alt="" /><br />
<input type="radio" name="alignment" value="left" checked="checked" />
</td>
<td style="text-align: center">
<img src="../icons/image_align_center.png" style="margin: 0px 5px" alt="" /><br />
<input type="radio" name="alignment" value="center" />
</td>
<td style="text-align: center">
<img src="../icons/image_align_right.png" alt="" /><br />
<input type="radio" name="alignment" value="right" />
</td>
</tr>
</table>
<div style="margin-top:5px;font-size: 12px">
<input type="checkbox" name="para" value="1" checked="checked" />한줄에 한 장씩 넣기
</div>
<div style="margin-top:5px;font-size: 12px">
<input type="checkbox" name="use_spacer" value="1" checked="checked" />사진 여백 넣기
</div>
</form>
</div>
</div>
</div>
<div class="clear"></div>
<div style="text-align:center;top:310px;width:100%;position:absolute;" id="buttonWrapper"></div>
</div>
<div id="dragDropContent"></div>
<div id="removeImageButton" class="removeButton" style="width:13px;height:13px"></div>
<div id="insertionMarker"></div>
</body>
</html>

View File

@ -0,0 +1,75 @@
// -------------------------------------------------------
// CHEditor WebGL Fragment Shader
// -------------------------------------------------------
precision highp float;
uniform sampler2D u_image;
uniform vec2 u_resolution;
uniform vec2 u_srcResolution;
vec4 getTextureColor(vec2 loc) {
return texture2D(u_image, loc / u_srcResolution);
}
void main() {
vec2 ratio = u_srcResolution / u_resolution;
vec2 ratioHalf = ceil(ratio / 1.0);
vec2 loc = gl_FragCoord.xy;
loc.y = u_resolution.y - loc.y;
float weight = 0.0;
float weights = 0.0;
float weights_alpha = 0.0;
vec3 gx_rgb = vec3(0.0);
float gx_a = 0.0;
float center_y = (loc.y + 0.5) * ratio.y;
float y = floor(loc.y * ratio.y);
float y_length = (loc.y + 1.0) * ratio.y;
for (int i = 0; i < 5000; i++) {
if (y >= y_length) {
break;
}
float dy = abs(center_y - (y + 0.5)) / ratioHalf.y;
float center_x = (loc.x + 0.5) * ratio.x;
float part_w = dy * dy;
float x = floor(loc.x * ratio.x);
float x_length = (loc.x + 1.0) * ratio.x;
for (int j = 0; j < 5000; j++) {
if (x >= x_length) {
break;
}
float dx = abs(center_x - (x + 0.5)) / ratioHalf.x;
float w = sqrt(part_w + dx * dx);
if (w >= -1.0 && w <= 1.0) {
// Hermite 필터
weight = 2.0 * w * w * w - 3.0 * w * w + 1.0;
if (weight > 0.0) {
vec4 pixel = getTextureColor(vec2(x, y)) * 255.0;
// 알파 채널
gx_a += weight * pixel.a;
weights_alpha += weight;
if (pixel.a < 255.0) {
weight = weight * pixel.a / 250.0;
}
gx_rgb += weight * pixel.rgb;
weights += weight;
}
}
x++;
}
y++;
}
gx_rgb = (gx_rgb / weights) / 255.0;
gx_a = (gx_a / weights_alpha) / 255.0;
gl_FragColor = vec4(gx_rgb, gx_a);
}

View File

@ -1,6 +1,7 @@
// ================================================================
// CHEditor 5
// ================================================================
var activeImage = null,
browser = null,
button,
@ -29,14 +30,160 @@ var activeImage = null,
offsetX_marker = -3,
offsetY_marker = -3,
readyToMove = false,
selectedFilesNum = 0,
showThumbnailSize = { width: 120, height: 90 },
tmpLeft = 0,
tmpTop = 0,
uploadImagePath = '',
uploadMaxNumber = 12,
uploadScript;
// deleteScript;
uploadScript,
useWebGL = false;
if (ArrayBuffer && !ArrayBuffer.prototype.slice) {
ArrayBuffer.prototype.slice = function (start, end) {
var len = this.byteLength;
start || isFinite(start) && 0 < start && start < len || (start = 0);
end || (isFinite(end && start < end && end < len) || (end = len - 1));
return new DataView(this, start, end).buffer;
};
}
function GLScale(options) {
if (!(this instanceof GLScale)) {
return new GLScale(options);
}
this.precompile(options);
return this.scale.bind(this);
}
GLScale.prototype.precompile = function (options) {
var ctxOptions, vertex, fragment, resolutionLocation, positionLocation;
this.canvas = document.createElement('canvas');
this.canvas.width = options.width;
this.canvas.height = options.height;
ctxOptions = {preserveDrawingBuffer: true};
this.gl = this.canvas.getContext('webgl', ctxOptions) || this.canvas.getContext('experimental-webgl', ctxOptions);
if (!this.gl) {
throw new Error('Could not initialize webgl context');
}
vertex = GLScale.compileShader(this.gl, GLScale.Hermite.vertex, this.gl.VERTEX_SHADER);
fragment = GLScale.compileShader(this.gl, GLScale.Hermite.fragment, this.gl.FRAGMENT_SHADER);
this.program = GLScale.createProgram(this.gl, vertex, fragment);
this.gl.useProgram(this.program);
this.gl.bindTexture(this.gl.TEXTURE_2D, this.gl.createTexture());
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
resolutionLocation = this.gl.getUniformLocation(this.program, 'u_resolution');
this.gl.uniform2f(resolutionLocation, options.width, options.height);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.gl.createBuffer());
positionLocation = this.gl.getAttribLocation(this.program, 'a_position');
this.gl.enableVertexAttribArray(positionLocation);
this.gl.vertexAttribPointer(positionLocation, 2, this.gl.FLOAT, false, 0, 0);
};
GLScale.prototype.scale = function (image, cb) {
var srcResolutionLocation;
if (typeof image === 'string') {
return this.loadImage(image, function (err, image) {
if (!err) {
return this.scale(image, cb);
}
});
}
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, image);
srcResolutionLocation = this.gl.getUniformLocation(this.program, 'u_srcResolution');
this.gl.uniform2f(srcResolutionLocation, image.width, image.height);
this.setRectangle(0, 0, image.width, image.height);
this.gl.drawArrays(this.gl.TRIANGLES, 0, 6);
this.gl.finish();
if (cb) {
cb(this.canvas);
}
return this;
};
GLScale.prototype.setRectangle = function (x, y, width, height) {
var x1 = x,
x2 = x + width,
y1 = y,
y2 = y + height;
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array([
x1, y1,
x2, y1,
x1, y2,
x1, y2,
x2, y1,
x2, y2
]), this.gl.STATIC_DRAW);
};
GLScale.loadImage = function (url, cb) {
var image = new Image();
image.onload = cb.bind(this, null, image);
image.onerror = cb.bind(this);
image.src = url;
return this;
};
GLScale.prototype.loadImage = GLScale.loadImage;
GLScale.toBlob = (function toBlob() {
var CanvasPrototype = window.HTMLCanvasElement.prototype;
if (CanvasPrototype.toBlob) {
return CanvasPrototype.toBlob;
}
return function (callback, type, quality) {
var binStr = atob(this.toDataURL(type, quality).split(',')[1]),
len = binStr.length,
arr = new Uint8Array(len), i = 0;
for (; i < len; i++) {
arr[i] = binStr.charCodeAt(i);
}
callback(new Blob([arr], {type: type || 'image/png'}));
};
})();
GLScale.compileShader = function (gl, shaderSource, shaderType) {
var shader = gl.createShader(shaderType);
gl.shaderSource(shader, shaderSource);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
throw new Error('Could not compile shader: ' + gl.getShaderInfoLog(shader));
}
return shader;
};
GLScale.createProgram = function (gl, vertexShader, fragmentShader) {
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
throw new Error('Program failed to link: ' + gl.getProgramInfoLog (program));
}
return program;
};
function createInsertionMaker() {
var wrapper = document.getElementById('insertionMarker'),
@ -76,7 +223,7 @@ function showContents() {
spacerNo = 1, i, imgBox, theImg, lastSpacer;
for (i = 0; i < uploadMaxNumber; i++) {
if (i > 0 && ((i % 4) === 0)) {
if (i > 0 && i % 4 === 0) {
imageListWrapper.appendChild(spacer(spacerNo++));
}
@ -89,7 +236,7 @@ function showContents() {
imgBox.appendChild(theImg);
imageListWrapper.appendChild(imgBox);
if (i === (uploadMaxNumber - 1)) {
if (i === uploadMaxNumber - 1) {
lastSpacer = spacer(spacerNo);
lastSpacer.style.height = "7px";
imageListWrapper.appendChild(lastSpacer);
@ -130,7 +277,7 @@ function getTopPos(inputObj) {
inputObj = inputObj.offsetParent;
while (inputObj) {
if (inputObj.tagName.toLowerCase() !== 'html') {
returnValue += (inputObj.offsetTop - inputObj.scrollTop);
returnValue += inputObj.offsetTop - inputObj.scrollTop;
if (browser.msie) {
returnValue += inputObj.clientTop;
}
@ -182,7 +329,7 @@ function reOrder() {
imgBox[i].className = 'imageBox';
imgBox[i].firstChild.className = 'imageBox_theImage';
if (imgNum > 0 && (imgNum % 4) === 0) {
if (imgNum > 0 && imgNum % 4 === 0) {
breakline.push(imgBox[i].id);
}
@ -199,28 +346,6 @@ function reOrder() {
}
}
function img_delete_post(el){
if( el.firstChild.tagName.toLowerCase() === 'img' ){
var src = el.firstChild.getAttribute('src'),
filesrc = src.replace(/^.*[\\\/]/, ''),
data = "filesrc="+filesrc;
var xhr = new XMLHttpRequest();
xhr.open('POST', deleteScript, true);
//Send the proper header information along with the request
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.addEventListener("error", function (evt) {
try {
console.log("파일 전송 중 오류: " + evt.target.error.code);
} catch(ex) {
}
}, false);
xhr.send(data);
}
}
function showDelete() {
var self = this, btn;
@ -231,7 +356,7 @@ function showDelete() {
getDivCoordinates();
self.className = 'imageBox_theImage_over';
btn = document.getElementById('removeImageButton');
btn.style.left = (showThumbnailSize.width - parseInt(btn.style.width, 10) - 1) + 'px';
btn.style.left = showThumbnailSize.width - parseInt(btn.style.width, 10) - 1 + 'px';
btn.style.top = '-1px';
self.appendChild(btn);
@ -250,7 +375,6 @@ function showDelete() {
var images = self.getElementsByTagName('img'), i, moveobj, target;
for (i = 0; i < images.length; i++) {
img_delete_post(self);
self.removeChild(images[i]);
}
@ -279,6 +403,7 @@ function showDelete() {
this.style.display = 'none';
document.body.appendChild(ev.target);
oEditor.removeEvent(self, 'mouseover', showDelete);
self.removeAttribute('title');
};
}
@ -318,16 +443,16 @@ function imgComplete(img, imgSize, boxId) {
if (imgSize.width > showThumbnailSize.width || imgSize.height > showThumbnailSize.height) {
if (imgSize.width > imgSize.height) {
resizeW = (imgSize.width > showThumbnailSize.width) ? showThumbnailSize.width : imgSize.width;
resizeH = Math.round((imgSize.height * resizeW) / imgSize.width);
resizeW = imgSize.width > showThumbnailSize.width ? showThumbnailSize.width : imgSize.width;
resizeH = Math.round(imgSize.height * resizeW / imgSize.width);
} else {
resizeH = (imgSize.height > showThumbnailSize.height) ? showThumbnailSize.height : imgSize.height;
resizeW = Math.round((imgSize.width * resizeH) / imgSize.height);
resizeH = imgSize.height > showThumbnailSize.height ? showThumbnailSize.height : imgSize.height;
resizeW = Math.round(imgSize.width * resizeH / imgSize.height);
}
if (resizeH > showThumbnailSize.height) {
resizeH = (imgSize.height > showThumbnailSize.height) ? showThumbnailSize.height : imgSize.height;
resizeW = Math.round((imgSize.width * resizeH) / imgSize.height);
resizeH = imgSize.height > showThumbnailSize.height ? showThumbnailSize.height : imgSize.height;
resizeW = Math.round(imgSize.width * resizeH / imgSize.height);
}
} else {
@ -357,6 +482,7 @@ function imgComplete(img, imgSize, boxId) {
}
elem.style.backgroundImage = "url('" + uploadImagePath + "/dot.gif')";
setElemTitle(elem, imgSize.width, imgSize.height);
oEditor.addEvent(elem, 'mouseover', showDelete);
elem.onmouseout = function () {
this.className = 'imageBox_theImage';
@ -366,26 +492,30 @@ function imgComplete(img, imgSize, boxId) {
setImageCount();
}
function setElemTitle(elem, width, height) {
elem.setAttribute('title', 'Width: ' + width + 'px, Height: ' + height + 'px');
}
function showUploadWindow() {
// ----------------------------------------------------------------------------------
var uploadWindow = document.getElementById("uploadWindow"),
uploadWindowWidth = 700,
winWidth, el, i, j, imgBox, img;
if (!(oEditor.undefined(window.innerWidth))) {
if (!oEditor.undefined(window.innerWidth)) {
winWidth = window.innerWidth;
} else if (document.documentElement &&
(!(oEditor.undefined(document.documentElement.clientWidth))) &&
!oEditor.undefined(document.documentElement.clientWidth) &&
document.documentElement.clientWidth !== 0) {
winWidth = document.documentElement.clientWidth;
} else if (document.body && (!(oEditor.undefined(document.body.clientWidth)))) {
} else if (document.body && !oEditor.undefined(document.body.clientWidth)) {
winWidth = document.body.clientWidth;
} else {
alert('현재 브라우저를 지원하지 않습니다.');
return;
}
uploadWindow.style.left = winWidth / 2 - (uploadWindowWidth / 2) + 'px';
uploadWindow.style.left = winWidth / 2 - uploadWindowWidth / 2 + 'px';
uploadWindow.style.display = "block";
uploadWindow.style.width = uploadWindowWidth + 'px';
@ -401,11 +531,9 @@ function showUploadWindow() {
if (imgBox.className !== 'imageBox_theImage') {
continue;
}
if (imgBox.firstChild && (imgBox.firstChild.src === modifyImages[i])) {
if (imgBox.firstChild && imgBox.firstChild.src === modifyImages[i]) {
break;
}
if (imgBox.firstChild === null) {
img = new Image();
img.src = modifyImages[i];
@ -439,11 +567,11 @@ function removeImages() {
remove = img.getElementsByTagName('img');
for (j = 0; j < remove.length; j++) {
img_delete_post(img);
img.removeChild(remove[j]);
}
img.parentNode.className = 'imageBox';
img.removeAttribute('title');
oEditor.removeEvent(img, 'mouseover', showDelete);
}
}
@ -491,7 +619,7 @@ function startMoveTimer() {
if (moveTimer >= 0 && moveTimer < 10) {
moveTimer++;
setTimeout('startMoveTimer()', 8);
setTimeout(startMoveTimer(), 8);
}
if (moveTimer === 5) {
@ -524,7 +652,7 @@ function getMouseButtn(e) {
if (code) {
if (browser.msie && browser.version < 9) {
code = code === 1 ? 0 : (code === 4 ? 1 : code);
code = code === 1 ? 0 : code === 4 ? 1 : code;
}
}
@ -644,9 +772,9 @@ function dragDropMove(e) {
}
if (divXPositions[prop] < leftPos &&
(divXPositions[prop] + divWidth[prop] * 0.7) > leftPos &&
divXPositions[prop] + divWidth[prop] * 0.7 > leftPos &&
divYPositions[prop] < topPos &&
(divYPositions[prop] + divWidth[prop]) > topPos) {
divYPositions[prop] + divWidth[prop] > topPos) {
if (browser.msie) {
offsetX = offsetX_marker;
offsetY = offsetY_marker;
@ -912,8 +1040,8 @@ DoUpload.prototype = {
offset += 2;
for (i = 0; i < tags; i++) {
if (view.getUint16(offset + (i * 12), little) === 0x0112) {
return view.getUint16(offset + (i * 12) + 8, little);
if (view.getUint16(offset + i * 12, little) === 0x0112) {
return view.getUint16(offset + i * 12 + 8, little);
}
}
} else if ((marker & 0xff00) !== 0xff00) {
@ -951,62 +1079,140 @@ DoUpload.prototype = {
},
imageResize : function (image, filetype, resizeWidth, orientation, addWaterMark) {
var canvas = document.createElement("canvas"),
width = image.width,
height = image.height,
bitmapData, ctx, rotateImg, rotateW, rotateH, angle, step, offcanvas, offctx, dHeight, dWidth;
// 카메라를 돌려서 찍은 경우, 높이를 가로 사이즈로 정한 다음 리사이징 처리. 이 경우, 파일 크기와 처리 속도가
// 증가한다.
// if (orientation === 6 || orientation === 8) {
// var ratio = resizeWidth / height;
// dHeight = height * ratio;
// dWidth = width * ratio;
// } else {
dHeight = Math.ceil(resizeWidth / width * height);
dWidth = resizeWidth;
// }
canvas.width = dWidth;
canvas.height = dHeight;
ctx = canvas.getContext("2d");
step = Math.ceil(Math.log(image.width / resizeWidth) / Math.log(2));
if (step > 1) {
offcanvas = document.createElement('canvas');
offctx = offcanvas.getContext('2d');
offcanvas.width = width / 2;
offcanvas.height = height / 2;
offctx.drawImage(image, 0, 0, offcanvas.width, offcanvas.height);
offctx.drawImage(offcanvas, 0, 0, offcanvas.width / 2, offcanvas.height / 2);
ctx.drawImage(offcanvas, 0, 0, offcanvas.width / 2, offcanvas.height / 2, 0, 0, dWidth, dHeight);
} else {
ctx.drawImage(image, 0, 0, dWidth, dHeight);
}
if (orientation === 6 || orientation === 8 || orientation === 3) {
angle = orientation === 6 ? Math.PI / 2 : (orientation === 8 ? -Math.PI / 2 : 180 * Math.PI / 2);
bitmapData = canvas.toDataURL(filetype, oEditor.config.imgJpegQuality);
rotateImg = new Image();
rotateImg.src = bitmapData;
rotateW = orientation !== 3 ? dHeight : dWidth;
rotateH = orientation !== 3 ? dWidth : dHeight;
canvas.width = rotateW;
canvas.height = rotateH;
var canvas, source_w = image.width, source_h = image.height,
resize_h, resize_w, ratio_w, ratio_h, ratio_w_half, ratio_h_half,
source_img, resize_img, source_data, resize_data, j, i,
x2, weight, weights, weights_alpha, gx_a, gx_b, gx_g, gx_r, center_x, center_y, x_start, x_stop,
y_start, y_stop, y, dy, part_w, x, dx, w, pos_x,
ctx, gl, imageData = null;
// 카메라 로테이션 보정
if (orientation > 0) {
canvas = document.createElement("canvas");
canvas.width = source_w;
canvas.height = source_h;
ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.rotate(angle);
ctx.drawImage(rotateImg, -dWidth / 2, -dHeight / 2);
switch (orientation) {
case 2 :
ctx.translate(-1, 0, 0, 1, canvas.width, 0); break;
case 3 :
ctx.translate(-1, 0, 0, -1, canvas.width, canvas.height); break;
case 4 :
ctx.translate(1, 0, 0, -1, 0, canvas.height); break;
case 5 :
ctx.translate(0, 1, 1, 0, 0, 0); break;
case 6 :
ctx.translate(0, 1, -1, 0, canvas.height, 0); break;
case 7 :
ctx.translate(0, -1, -1, 0, canvas.height, canvas.width); break;
case 8 :
ctx.translate(0, -1, 1, 0, 0, canvas.width); break;
default: break;
}
ctx.drawImage(image, 0, 0);
imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
ctx.restore();
source_w = canvas.width;
source_h = canvas.height;
}
if (source_w > resizeWidth) {
resize_w = resizeWidth;
resize_h = Math.ceil(resize_w / source_w * source_h);
try {
gl = GLScale({
width: resize_w, height: resize_h
});
gl(imageData || image, function (gl_canvas) {
canvas = gl_canvas;
});
} catch (ignore) {
canvas = document.createElement("canvas");
ctx = canvas.getContext("2d");
canvas.width = source_w;
canvas.height = source_h;
if (imageData) {
ctx.putImageData(imageData, 0, 0);
} else {
ctx.drawImage(image, 0, 0);
}
ratio_w = source_w / resize_w;
ratio_h = source_h / resize_h;
ratio_w_half = Math.ceil(ratio_w / 2);
ratio_h_half = Math.ceil(ratio_h / 2);
source_img = ctx.getImageData(0, 0, source_w, source_h);
resize_img = ctx.createImageData(resize_w, resize_h);
source_data = source_img.data;
resize_data = resize_img.data;
for (j = 0; j < resize_h; j++) {
for (i = 0; i < resize_w; i++) {
x2 = (i + j * resize_w) * 4;
weight = weights = weights_alpha = 0;
gx_r = gx_g = gx_b = gx_a = 0;
center_y = (j + 0.5) * ratio_h;
x_start = Math.floor(i * ratio_w);
x_stop = Math.ceil((i + 1) * ratio_w);
y_start = Math.floor(j * ratio_h);
y_stop = Math.ceil((j + 1) * ratio_h);
x_stop = Math.min(x_stop, source_w);
y_stop = Math.min(y_stop, source_h);
for (y = y_start; y < y_stop; y++) {
dy = Math.abs(center_y - (y + 0.5)) / ratio_h_half;
center_x = (i + 0.5) * ratio_w;
part_w = dy * dy;
for (x = x_start; x < x_stop; x++) {
dx = Math.abs(center_x - (x + 0.5)) / ratio_w_half;
w = Math.sqrt(part_w + dx * dx);
if (w >= 1) {
continue;
}
// Hermite 필터
weight = 2 * w * w * w - 3 * w * w + 1;
pos_x = 4 * (x + y * source_w);
// 알파 채널
gx_a += weight * source_data[pos_x + 3];
weights_alpha += weight;
if (source_data[pos_x + 3] < 255) {
weight = weight * source_data[pos_x + 3] / 250;
}
gx_r += weight * source_data[pos_x];
gx_g += weight * source_data[pos_x + 1];
gx_b += weight * source_data[pos_x + 2];
weights += weight;
}
}
resize_data[x2] = gx_r / weights;
resize_data[x2 + 1] = gx_g / weights;
resize_data[x2 + 2] = gx_b / weights;
resize_data[x2 + 3] = gx_a / weights_alpha;
}
}
canvas.width = resize_w;
canvas.height = resize_h;
ctx.putImageData(resize_img, 0, 0);
}
} else {
canvas = document.createElement("canvas"),
canvas.width = source_w; canvas.height = source_h;
ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0);
resize_h = source_h;
resize_w = source_w;
}
if (this.reader.watermark && addWaterMark) {
@ -1014,14 +1220,15 @@ DoUpload.prototype = {
ctx.drawImage(this.reader.watermark,
canvas.width - this.reader.watermark.width, canvas.height - this.reader.watermark.height);
}
return canvas.toDataURL(filetype, oEditor.config.imgJpegQuality);
},
canvasToBlob : function (bitmapData, mimetype) {
var raw = atob(bitmapData.split(',')[1]),
var i = 0,
intArray = [],
len = bitmapData.length,
i = 0;
raw = atob(bitmapData.split(',')[1]);
for (; i < len; i++) {
intArray.push(raw.charCodeAt(i));
@ -1030,8 +1237,7 @@ DoUpload.prototype = {
},
makeThumbnail : function (image, type, name, orientation) {
var canvas = document.createElement("canvas"),
width,
var width,
xhr = new XMLHttpRequest(),
data = new FormData(),
bitmapData, file;
@ -1041,11 +1247,10 @@ DoUpload.prototype = {
bitmapData = this.imageResize(image, type, width, orientation);
file = this.canvasToBlob(bitmapData, type);
data.append(inputFileName, file, 'thumb_' + name); // RFC Level 2
xhr.addEventListener("loadend", function () {
// loadend
}, false);
xhr.addEventListener("error", function () {
@ -1060,20 +1265,19 @@ DoUpload.prototype = {
filename = evt.target.file.name,
filetype = evt.target.file.type,
file = evt.target.file,
blob, image, orientation = 1;
blob, image, orientation = 1, slice = 64 * 1024;
if (slice > file.size - 1) {
slice = file.size;
}
if (evt.target.readyState === FileReader.DONE) {
blob = new self.MyBlob(self.NewBlob(evt.target.result, filetype));
try {
orientation = self.getOrientation(evt.target.result.slice(0, 64 * 1024));
} catch(err) {
orientation = self.getOrientation(evt.target.result.slice(0, slice));
}
image = new Image();
image.onload = function () {
var bitmapData = null,
canvas = document.createElement("canvas"),
data = new FormData(),
fileFormat,
imgBox = file.boxElem,
@ -1083,7 +1287,7 @@ DoUpload.prototype = {
xhr.open('POST', uploadScript, true);
if (imageResizeWidth > 0 && this.width > imageResizeWidth) {
if (imageResizeWidth > 0) {
bitmapData = self.imageResize(this, filetype, imageResizeWidth, orientation, true);
file = self.canvasToBlob(bitmapData, filetype);
}
@ -1099,7 +1303,7 @@ DoUpload.prototype = {
}
xhr.addEventListener("error", function (evt) {
alert("파일 전송 중 오류: " + evt.target.error.code);
alert("파일 전송 중 오류: " + evt.toString());
}, false);
xhr.addEventListener("loadend", function onLoadendImageHandler(xhrevt) {
@ -1132,7 +1336,6 @@ DoUpload.prototype = {
height: img.height,
width: img.width
};
imageCompletedList[imgBox.id] = imgInfo;
imgComplete(this, imgInfo, imgBox.id);
imgBox.appendChild(img);
@ -1263,13 +1466,14 @@ function setResizeWidth() {
imageResizeWidth = value;
} else {
imageResizeInput.value = '';
imageResizeWidth = oEditor.config.imgMaxWidth;
imageResizeInput.setAttribute('placeholder', oEditor.config.imgMaxWidth.toString());
}
}
}
function init(dialog) {
var dlg, i, elem, input, select, value, name;
var dlg, i, elem, input, select, value, name, xhr_f, xhr_v, tmpcanvas, glicon;
oEditor = this;
oEditor.dialog = dialog;
@ -1279,14 +1483,12 @@ function init(dialog) {
uploadImagePath = oEditor.config.iconPath + 'imageUpload';
uploadMaxNumber = oEditor.config.imgUploadNumber;
uploadScript = oEditor.config.editorPath + 'imageUpload/upload.php';
deleteScript = oEditor.config.editorPath + 'imageUpload/delete.php';
imageListWrapper = document.getElementById("imageListWrapper");
imageResizeWidth = oEditor.config.imgMaxWidth;
imageResizeInput = document.getElementById('idResizeWidth');
select = document.getElementById('idResizeSelectBox');
if (imageResizeWidth > 0) {
if (oEditor.config.imgMaxWidth > 0) {
imageResizeWidth = oEditor.config.imgMaxWidth;
for (i = 0; i < oEditor.config.imgResizeValue.length; i++) {
name = value = oEditor.config.imgResizeValue[i];
if (value > oEditor.config.imgMaxWidth) {
@ -1300,6 +1502,9 @@ function init(dialog) {
select.onchange = function () {
if (this.value < 0) {
document.getElementById('idUserInputWrapper').style.display = '';
imageResizeInput.value = '';
imageResizeWidth = oEditor.config.imgMaxWidth;
imageResizeInput.focus();
} else {
document.getElementById('idUserInputWrapper').style.display = 'none';
imageResizeWidth = this.value;
@ -1326,7 +1531,6 @@ function init(dialog) {
initGallery();
showUploadWindow();
createInsertionMaker();
selectedFilesNum = 0;
oEditor.addEvent(imageListWrapper, 'dragover', dragOver);
oEditor.addEvent(imageListWrapper, 'dragleave', dragOut);
@ -1343,6 +1547,38 @@ function init(dialog) {
if (browser.mobile) {
input = document.getElementById('inputImageUpload');
input.setAttribute('capture', 'gallery');
input.setAttribute('capture', 'filesystem');
}
tmpcanvas = document.createElement('canvas');
if (tmpcanvas.getContext('webgl', {preserveDrawingBuffer: true}) ||
tmpcanvas.getContext('experimental-webgl', {preserveDrawingBuffer: true}))
{
useWebGL = true;
GLScale.Hermite = { vertex: '', fragment: '' };
xhr_v = new XMLHttpRequest();
xhr_f = new XMLHttpRequest();
xhr_f.open('POST', 'js/fragment-shader.glsl', true);
xhr_f.addEventListener("load", function (evt) {
if (evt.target.status === 200) {
GLScale.Hermite.fragment = this.responseText;
} else {
useWebGL = false;
}
});
xhr_v.open('POST', 'js/vertex-shader.glsl', true);
xhr_v.addEventListener("load", function (evt) {
if (evt.target.status === 200) {
GLScale.Hermite.vertex = this.responseText;
} else {
useWebGL = false;
}
});
xhr_f.send();
xhr_v.send();
}
glicon = new Image();
glicon.className = 'webgl_logo';
glicon.src = uploadImagePath + (useWebGL ? "/webgl.png" : "/webgl-off.png");
document.getElementById('webgl_logo_wrapper').appendChild(glicon);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
// -------------------------------------------------------
// CHEditor WebGL Vertex Shader
// -------------------------------------------------------
attribute vec2 a_position;
uniform vec2 u_resolution;
void main() {
vec2 clipSpace = (a_position / u_resolution * 2.0) - 1.0;
gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
}

View File

@ -0,0 +1,175 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
// ================================================================
// CHEditor Template
// ================================================================
-->
<Template>
<Container>
<Html>
<![CDATA[
<div class="cheditor-container">
<div id="toolbar" style="padding:4px;height:47px"></div>
<div id="editWrapper" class="cheditor-editarea-wrapper" style="clear:left">
<iframe frameborder="0" class="cheditor-editarea"></iframe>
<textarea class="cheditor-editarea-text-content" spellcheck="false"></textarea>
</div>
<div id="modifyBlock" class="cheditor-modify-block"></div>
<div id="tagPath" class="cheditor-tag-path">
<span class="cheditor-status-bar">&lt;html&gt; </span>
</div>
<div id="resizeBar" class="cheditor-resizebar"></div>
<div id="viewMode" class="cheditor-viewmode">
<div id="rich" class="cheditor-tab-rich" title="입력 모드" alt="">&#160;</div>
<div id="code" class="cheditor-tab-code-off" title="HTML 편집" alt="">&#160;</div>
<div id="preview" class="cheditor-tab-preview-off" title="미리 보기" alt="">&#160;</div>
</div>
</div>
]]>
</Html>
</Container>
<PopupWindow>
<Html>
<![CDATA[
<div class="cheditor-popup-window" onselectstart="return false">
<div class="cheditor-popup-drag-handle">
<div class="cheditor-popup-titlebar">
<span><label class="cheditor-popup-title"></label></span>
</div>
</div>
<div class="cheditor-popup-cframe" id="cheditor-popup-cframe"></div>
</div>
]]>
</Html>
</PopupWindow>
<Toolbar>
<Image file="toolbar.png" />
<Group name="Format">
<Button name="Bold" tooltip="진하게">
<Attribute class="cheditor-tb-bg" width="24" height="23" check="1">
<Icon position="144" width="16" class="cheditor-tb-icon" margin="4px" />
<Execution method="doCmd" value="Bold" />
</Attribute>
</Button>
<Button name="Italic" tooltip="기울임">
<Attribute class="cheditor-tb-bg" width="23" height="23" check="1">
<Icon position="160" width="16" class="cheditor-tb-icon" />
<Execution method="doCmd" value="Italic" />
</Attribute>
</Button>
<Button name="Underline" tooltip="밑줄">
<Attribute class="cheditor-tb-bg" width="23" height="23" check="1">
<Icon position="176" width="16" class="cheditor-tb-icon" />
<Execution method="doCmd" value="Underline" />
</Attribute>
</Button>
</Group>
<Group name="Alignment">
<Button name="JustifyLeft" tooltip="왼쪽 정렬">
<Attribute class="cheditor-tb-bg" width="24" height="23" check="1">
<Icon position="286" width="16" class="cheditor-tb-icon" margin="4px" />
<Execution method="doCmd" value="JustifyLeft" />
</Attribute>
</Button>
<Button name="JustifyCenter" tooltip="가운데 정렬">
<Attribute class="cheditor-tb-bg" width="23" height="23" check="1">
<Icon position="302" width="16" class="cheditor-tb-icon" />
<Execution method="doCmd" value="JustifyCenter" />
</Attribute>
</Button>
<Button name="JustifyRight" tooltip="오른쪽 정렬">
<Attribute class="cheditor-tb-bg" width="23" height="23" check="1">
<Icon position="318" width="16" class="cheditor-tb-icon" />
<Execution method="doCmd" value="JustifyRight" />
</Attribute>
</Button>
<Button name="JustifyFull" tooltip="양쪽 정렬">
<Attribute class="cheditor-tb-bg" width="23" height="23" check="1">
<Icon position="334" width="16" class="cheditor-tb-icon" />
<Execution method="doCmd" value="JustifyFull" />
</Attribute>
</Button>
</Group>
<Group name="List">
<Button name="OrderedList" tooltip="문단 번호">
<Attribute class="cheditor-tb-bg" width="24" height="23" check="1" type="combo">
<Icon position="350" width="16" class="cheditor-tb-icon" margin="4px" />
<Execution method="doCmd" value="InsertOrderedList" />
</Attribute>
</Button>
<Button name="OrderedListCombo" tooltip="문단 번호 확장">
<Attribute class="cheditor-tb-bgcombo" width="10" height="23" type="combobox" node="OrderedList">
<Icon width="10" class="cheditor-tb-combo" margin="0px" />
<Execution method="showPulldown" value="OrderedList" />
</Attribute>
</Button>
<Button name="UnOrderedList" tooltip="글 머리표">
<Attribute class="cheditor-tb-bg" width="23" height="23" check="1" type="combo">
<Icon position="366" width="16" class="cheditor-tb-icon" />
<Execution method="doCmd" value="InsertUnOrderedList" />
</Attribute>
</Button>
<Button name="UnOrderedListCombo" tooltip="글 머리표 확장">
<Attribute class="cheditor-tb-bgcombo" width="10" height="23" type="combobox" node="UnOrderedList">
<Icon width="10" class="cheditor-tb-combo" margin="0px" />
<Execution method="showPulldown" value="UnOrderedList" />
</Attribute>
</Button>
</Group>
<Group name="Split">
</Group>
<Group name="FontName">
<Button name="FontName" tooltip="글꼴">
<Attribute class="cheditor-tb-bg55" width="55" height="23" check="1">
<Icon class="cheditor-tb-text" alt="굴림" />
<Execution method="showPulldown" value="FontName" />
</Attribute>
</Button>
</Group>
<Group name="FontSize">
<Button name="FontSize" tooltip="글꼴 크기">
<Attribute class="cheditor-tb-bg40" width="41" height="23" check="1">
<Icon class="cheditor-tb-text" alt="9pt" />
<Execution method="showPulldown" value="FontSize" />
</Attribute>
</Button>
</Group>
<Group name="Link">
<Button name="Link" tooltip="하이퍼링크">
<Attribute class="cheditor-tb-bg" width="24" height="23">
<Icon position="558" width="16" class="cheditor-tb-icon" margin="4px" />
<Execution method="windowOpen" value="Link" />
</Attribute>
</Button>
<Button name="UnLink" tooltip="하이퍼링크 없애기">
<Attribute class="cheditor-tb-bg" width="23" height="23" check="1">
<Icon position="574" width="16" class="cheditor-tb-icon" />
<Execution method="doCmd" value="UnLink" />
</Attribute>
</Button>
</Group>
<Group name="ImageUpload">
<Button name="Image" tooltip="내 PC 사진 넣기">
<Attribute class="cheditor-tb-bg44" width="50" height="23">
<Icon position="590" width="36" class="cheditor-tb-icon36" margin="6px" />
<Execution method="windowOpen" value="ImageUpload" />
</Attribute>
</Button>
</Group>
<Group name="Media">
<Button name="Flash" tooltip="플래쉬 동영상">
<Attribute class="cheditor-tb-bg" width="24" height="23">
<Icon position="662" width="16" class="cheditor-tb-icon" margin="4px" />
<Execution method="windowOpen" value="FlashMovie" />
</Attribute>
</Button>
<Button name="SmileyIcon" tooltip="표정 아이콘">
<Attribute class="cheditor-tb-bg" width="23" height="23">
<Icon position="494" width="16" class="cheditor-tb-icon" />
<Execution method="windowOpen" value="EmotionIcon" />
</Attribute>
</Button>
</Group>
</Toolbar>
</Template>

View File

@ -10,7 +10,7 @@
<![CDATA[
<div class="cheditor-container">
<div id="toolbar" style="padding:4px;height:47px"></div>
<div id="editWrapper" class="cheditor-editarea-wrapper">
<div id="editWrapper" class="cheditor-editarea-wrapper" style="clear:left">
<iframe frameborder="0" class="cheditor-editarea"></iframe>
<textarea class="cheditor-editarea-text-content" spellcheck="false"></textarea>
</div>
@ -73,6 +73,18 @@
</Button>
</Group>
<Group name="Edit">
<Button name="Copy" tooltip="복사하기">
<Attribute class="cheditor-tb-bg" width="24" height="23" check="1">
<Icon position="64" width="16" class="cheditor-tb-icon" margin="4px" />
<Execution method="doCmd" value="Copy" />
</Attribute>
</Button>
<Button name="Cut" tooltip="오려두기">
<Attribute class="cheditor-tb-bg" width="23" height="23" check="1">
<Icon position="80" width="16" class="cheditor-tb-icon" />
<Execution method="doCmd" value="Cut" />
</Attribute>
</Button>
<Button name="Paste" tooltip="텍스트로 붙이기">
<Attribute class="cheditor-tb-bg" width="23" height="23">
<Icon position="96" width="16" class="cheditor-tb-icon" />