diff --git a/.gitignore b/.gitignore index 28780e356..e27caf303 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,7 @@ test.php *.sh log g5_tree -cheditor*/ +cheditor5.*/ ckeditor*/ log/ g5_tree/ diff --git a/bbs/write_update.php b/bbs/write_update.php index 0d52074ba..2dbbddde1 100644 --- a/bbs/write_update.php +++ b/bbs/write_update.php @@ -692,7 +692,7 @@ if (!($w == 'u' || $w == 'cu') && $config['cf_email_use'] && $board['bo_use_emai delete_cache_latest($bo_table); if ($file_upload_msg) - alert($file_upload_msg, G5_HTTP_BBS_URL.'/board.php?bo_table='.$bo_table.'&wr_id='.$wr_id.'&page='.$page.$qstr); + alert($file_upload_msg, G5_HTTP_BBS_URL.'/board.php?bo_table='.$bo_table.'&wr_id='.$wr_id.$qstr); else goto_url(G5_HTTP_BBS_URL.'/board.php?bo_table='.$bo_table.'&wr_id='.$wr_id.$qstr); ?> diff --git a/plugin/PHPMailer/VERSION b/plugin/PHPMailer/VERSION index 1c26b6f22..07b26572f 100644 --- a/plugin/PHPMailer/VERSION +++ b/plugin/PHPMailer/VERSION @@ -1 +1 @@ -5.2.19 \ No newline at end of file +5.2.22 diff --git a/plugin/PHPMailer/class.phpmailer.php b/plugin/PHPMailer/class.phpmailer.php index 6afcf9ae9..477ee826e 100644 --- a/plugin/PHPMailer/class.phpmailer.php +++ b/plugin/PHPMailer/class.phpmailer.php @@ -31,7 +31,7 @@ class PHPMailer * The PHPMailer Version number. * @var string */ - public $Version = '5.2.19'; + public $Version = '5.2.22'; /** * Email priority. @@ -1364,19 +1364,24 @@ class PHPMailer */ protected function sendmailSend($header, $body) { - if (!empty($this->Sender)) { + // CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped. + if (!empty($this->Sender) and self::isShellSafe($this->Sender)) { if ($this->Mailer == 'qmail') { - $sendmail = sprintf('%s -f%s', escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender)); + $sendmailFmt = '%s -f%s'; } else { - $sendmail = sprintf('%s -oi -f%s -t', escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender)); + $sendmailFmt = '%s -oi -f%s -t'; } } else { if ($this->Mailer == 'qmail') { - $sendmail = sprintf('%s', escapeshellcmd($this->Sendmail)); + $sendmailFmt = '%s'; } else { - $sendmail = sprintf('%s -oi -t', escapeshellcmd($this->Sendmail)); + $sendmailFmt = '%s -oi -t'; } } + + // TODO: If possible, this should be changed to escapeshellarg. Needs thorough testing. + $sendmail = sprintf($sendmailFmt, escapeshellcmd($this->Sendmail), $this->Sender); + if ($this->SingleTo) { foreach ($this->SingleToArray as $toAddr) { if (!@$mail = popen($sendmail, 'w')) { @@ -1422,6 +1427,40 @@ class PHPMailer return true; } + /** + * Fix CVE-2016-10033 and CVE-2016-10045 by disallowing potentially unsafe shell characters. + * + * Note that escapeshellarg and escapeshellcmd are inadequate for our purposes, especially on Windows. + * @param string $string The string to be validated + * @see https://github.com/PHPMailer/PHPMailer/issues/924 CVE-2016-10045 bug report + * @access protected + * @return boolean + */ + protected static function isShellSafe($string) + { + // Future-proof + if (escapeshellcmd($string) !== $string + or !in_array(escapeshellarg($string), array("'$string'", "\"$string\"")) + ) { + return false; + } + + $length = strlen($string); + + for ($i = 0; $i < $length; $i++) { + $c = $string[$i]; + + // All other characters have a special meaning in at least one common shell, including = and +. + // Full stop (.) has a special meaning in cmd.exe, but its impact should be negligible here. + // Note that this does permit non-Latin alphanumeric characters based on the current locale. + if (!ctype_alnum($c) && strpos('@_-.', $c) === false) { + return false; + } + } + + return true; + } + /** * Send mail using the PHP mail() function. * @param string $header The message headers @@ -1442,7 +1481,10 @@ class PHPMailer $params = null; //This sets the SMTP envelope sender which gets turned into a return-path header by the receiver if (!empty($this->Sender) and $this->validateAddress($this->Sender)) { - $params = sprintf('-f%s', escapeshellarg($this->Sender)); + // CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped. + if (self::isShellSafe($this->Sender)) { + $params = sprintf('-f%s', $this->Sender); + } } if (!empty($this->Sender) and !ini_get('safe_mode') and $this->validateAddress($this->Sender)) { $old_from = ini_get('sendmail_from'); @@ -2450,6 +2492,7 @@ class PHPMailer /** * Add an attachment from a path on the filesystem. + * Never use a user-supplied path to a file! * Returns false if the file could not be found or read. * @param string $path Path to the attachment. * @param string $name Overrides the attachment name. @@ -2975,6 +3018,7 @@ class PHPMailer * displayed inline with the message, not just attached for download. * This is used in HTML messages that embed the images * the HTML refers to using the $cid value. + * Never use a user-supplied path to a file! * @param string $path Path to the attachment. * @param string $cid Content ID of the attachment; Use this to reference * the content when using an embedded image in HTML. @@ -3338,12 +3382,14 @@ class PHPMailer * Create a message body from an HTML string. * Automatically inlines images and creates a plain-text version by converting the HTML, * overwriting any existing values in Body and AltBody. - * $basedir is used when handling relative image paths, e.g. + * Do not source $message content from user input! + * $basedir is prepended when handling relative URLs, e.g. and must not be empty * will look for an image file in $basedir/images/a.png and convert it to inline. - * If you don't want to apply these transformations to your HTML, just set Body and AltBody yourself. + * If you don't provide a $basedir, relative paths will be left untouched (and thus probably break in email) + * If you don't want to apply these transformations to your HTML, just set Body and AltBody directly. * @access public * @param string $message HTML message string - * @param string $basedir base directory for relative paths to images + * @param string $basedir Absolute path to a base directory to prepend to relative paths to images * @param boolean|callable $advanced Whether to use the internal HTML to text converter * or your own custom converter @see PHPMailer::html2text() * @return string $message The transformed message Body @@ -3352,6 +3398,10 @@ class PHPMailer { preg_match_all('/(src|background)=["\'](.*)["\']/Ui', $message, $images); if (array_key_exists(2, $images)) { + if (strlen($basedir) > 1 && substr($basedir, -1) != '/') { + // Ensure $basedir has a trailing / + $basedir .= '/'; + } foreach ($images[2] as $imgindex => $url) { // Convert data URIs into embedded images if (preg_match('#^data:(image[^;,]*)(;base64)?,#', $url, $match)) { @@ -3369,18 +3419,24 @@ class PHPMailer $message ); } - } elseif (substr($url, 0, 4) !== 'cid:' && !preg_match('#^[a-z][a-z0-9+.-]*://#i', $url)) { - // Do not change urls for absolute images (thanks to corvuscorax) + continue; + } + if ( + // Only process relative URLs if a basedir is provided (i.e. no absolute local paths) + !empty($basedir) + // Ignore URLs containing parent dir traversal (..) + && (strpos($url, '..') === false) // Do not change urls that are already inline images + && substr($url, 0, 4) !== 'cid:' + // Do not change absolute URLs, including anonymous protocol + && !preg_match('#^[a-z][a-z0-9+.-]*:?//#i', $url) + ) { $filename = basename($url); $directory = dirname($url); if ($directory == '.') { $directory = ''; } $cid = md5($url) . '@phpmailer.0'; // RFC2392 S 2 - if (strlen($basedir) > 1 && substr($basedir, -1) != '/') { - $basedir .= '/'; - } if (strlen($directory) > 1 && substr($directory, -1) != '/') { $directory .= '/'; } diff --git a/plugin/PHPMailer/class.pop3.php b/plugin/PHPMailer/class.pop3.php index 32d614b35..f10e688e3 100644 --- a/plugin/PHPMailer/class.pop3.php +++ b/plugin/PHPMailer/class.pop3.php @@ -34,7 +34,7 @@ class POP3 * @var string * @access public */ - public $Version = '5.2.19'; + public $Version = '5.2.22'; /** * Default POP3 port number. diff --git a/plugin/PHPMailer/class.smtp.php b/plugin/PHPMailer/class.smtp.php index 04ced6581..89321171b 100644 --- a/plugin/PHPMailer/class.smtp.php +++ b/plugin/PHPMailer/class.smtp.php @@ -30,7 +30,7 @@ class SMTP * The PHPMailer SMTP version number. * @var string */ - const VERSION = '5.2.19'; + const VERSION = '5.2.22'; /** * SMTP line break constant. @@ -81,7 +81,7 @@ class SMTP * @deprecated Use the `VERSION` constant instead * @see SMTP::VERSION */ - public $Version = '5.2.19'; + public $Version = '5.2.22'; /** * SMTP server port number. diff --git a/plugin/PHPMailer/examples/contactform.phps b/plugin/PHPMailer/examples/contactform.phps new file mode 100644 index 000000000..d85e20456 --- /dev/null +++ b/plugin/PHPMailer/examples/contactform.phps @@ -0,0 +1,71 @@ +isSMTP(); + $mail->Host = 'localhost'; + $mail->Port = 25; + + //Use a fixed address in your own domain as the from address + //**DO NOT** use the submitter's address here as it will be forgery + //and will cause your messages to fail SPF checks + $mail->setFrom('from@example.com', 'First Last'); + //Send the message to yourself, or whoever should receive contact for submissions + $mail->addAddress('whoto@example.com', 'John Doe'); + //Put the submitter's address in a reply-to header + //This will fail if the address provided is invalid, + //in which case we should ignore the whole request + if ($mail->addReplyTo($_POST['email'], $_POST['name'])) { + $mail->Subject = 'PHPMailer contact form'; + //Keep it simple - don't use HTML + $mail->isHTML(false); + //Build a simple message body + $mail->Body = <<send()) { + //The reason for failing to send will be in $mail->ErrorInfo + //but you shouldn't display errors to users - process the error, log it on your server. + $msg = 'Sorry, something went wrong. Please try again later.'; + } else { + $msg = 'Message sent! Thanks for contacting us.'; + } + } else { + $msg = 'Invalid email address, message ignored.'; + } +} +?> + + + + + Contact form + + +

Contact us

+$msg"; +} ?> +
+
+
+
+ +
+ + diff --git a/plugin/PHPMailer/examples/contentsutf8.html b/plugin/PHPMailer/examples/contentsutf8.html index 81a202405..035d10c8d 100644 --- a/plugin/PHPMailer/examples/contentsutf8.html +++ b/plugin/PHPMailer/examples/contentsutf8.html @@ -15,6 +15,7 @@

Russian text: Пустое тело сообщения

Armenian text: Հաղորդագրությունը դատարկ է

Czech text: Prázdné tělo zprávy

+

Emoji: 😂 🦄 💥 📤 📧

diff --git a/plugin/PHPMailer/examples/scripts/XRegExp.js b/plugin/PHPMailer/examples/scripts/XRegExp.js index ebdb9c948..feb66798a 100644 --- a/plugin/PHPMailer/examples/scripts/XRegExp.js +++ b/plugin/PHPMailer/examples/scripts/XRegExp.js @@ -259,7 +259,7 @@ if (XRegExp) { //--------------------------------- - // Overriden native methods + // Overridden native methods //--------------------------------- // Adds named capture support (with backreferences returned as `result.name`), and fixes two diff --git a/plugin/PHPMailer/examples/send_file_upload.phps b/plugin/PHPMailer/examples/send_file_upload.phps index 3004c7628..ab60fd104 100644 --- a/plugin/PHPMailer/examples/send_file_upload.phps +++ b/plugin/PHPMailer/examples/send_file_upload.phps @@ -17,7 +17,7 @@ if (array_key_exists('userfile', $_FILES)) { $mail->setFrom('from@example.com', 'First Last'); $mail->addAddress('whoto@example.com', 'John Doe'); $mail->Subject = 'PHPMailer file sender'; - $mail->msgHTML("My message body"); + $mail->Body = 'My message body'; // Attach the uploaded file $mail->addAttachment($uploadfile, 'My uploaded file'); if (!$mail->send()) { diff --git a/plugin/PHPMailer/examples/send_multiple_file_upload.phps b/plugin/PHPMailer/examples/send_multiple_file_upload.phps index ddb761468..72f21153e 100644 --- a/plugin/PHPMailer/examples/send_multiple_file_upload.phps +++ b/plugin/PHPMailer/examples/send_multiple_file_upload.phps @@ -12,7 +12,7 @@ if (array_key_exists('userfile', $_FILES)) { $mail->setFrom('from@example.com', 'First Last'); $mail->addAddress('whoto@example.com', 'John Doe'); $mail->Subject = 'PHPMailer file sender'; - $mail->msgHTML('My message body'); + $mail->Body = 'My message body'; //Attach multiple files one by one for ($ct = 0; $ct < count($_FILES['userfile']['tmp_name']); $ct++) { $uploadfile = tempnam(sys_get_temp_dir(), sha1($_FILES['userfile']['name'][$ct])); diff --git a/plugin/PHPMailer/extras/htmlfilter.php b/plugin/PHPMailer/extras/htmlfilter.php index 7727487e5..a86ef579d 100644 --- a/plugin/PHPMailer/extras/htmlfilter.php +++ b/plugin/PHPMailer/extras/htmlfilter.php @@ -433,7 +433,7 @@ function tln_getnxtag($body, $offset) * * @param string $attvalue the by-ref value to check. * @param string $regex the regular expression to check against. - * @param boolean $hex whether the entites are hexadecimal. + * @param boolean $hex whether the entities are hexadecimal. * @return boolean True or False depending on whether there were matches. */ function tln_deent(&$attvalue, $regex, $hex = false) @@ -772,7 +772,7 @@ function tln_fixstyle($body, $pos, $trans_image_path, $block_external_images) tln_defang($contentTemp); tln_unspace($contentTemp); - $match = Array('/\/\*.*\*\//', + $match = array('/\/\*.*\*\//', '/expression/i', '/behaviou*r/i', '/binding/i', @@ -780,7 +780,7 @@ function tln_fixstyle($body, $pos, $trans_image_path, $block_external_images) '/javascript/i', '/script/i', '/position/i'); - $replace = Array('','idiocy', 'idiocy', 'idiocy', 'idiocy', 'idiocy', 'idiocy', ''); + $replace = array('','idiocy', 'idiocy', 'idiocy', 'idiocy', 'idiocy', 'idiocy', ''); $contentNew = preg_replace($match, $replace, $contentTemp); if ($contentNew !== $contentTemp) { $content = $contentNew; diff --git a/plugin/editor/cheditor5/backup_template.xml b/plugin/editor/cheditor5/backup_template.xml new file mode 100644 index 000000000..b1a1470a8 --- /dev/null +++ b/plugin/editor/cheditor5/backup_template.xml @@ -0,0 +1,380 @@ + + + \ No newline at end of file diff --git a/plugin/editor/cheditor5/cheditor.js b/plugin/editor/cheditor5/cheditor.js new file mode 100644 index 000000000..adc925981 --- /dev/null +++ b/plugin/editor/cheditor5/cheditor.js @@ -0,0 +1,7963 @@ +// ================================================================ +// CHEditor 5.1.9.3 +// ---------------------------------------------------------------- +// Homepage: http://www.chcode.com +// EMail: support@chcode.com +// Copyright (c) 1997-2016 CHSOFT +// ================================================================ +var GB = { + colors: ['#000000','#313131','#434343','#535353','#666666','#999999','#a0a0a0','#b5b5b5','#c0c0c0','#dcdcdc','#eeeeee','#ffffff', + '#ff0000','#ff8000','#ffff00','#80ff00','#00ff00','#00ff99','#00ffff','#0080ff','#0000ff','#7f00ff','#ff00ff','#ff007f', + '#ffcccc','#ffe5cc','#ffffcc','#e5ffcc','#ccffcc','#ccffe5','#ccffff','#cce5ff','#ccccff','#e5ccff','#ffccff','#ffcce5', + '#ff9999','#ffcc99','#ffff99','#ccff99','#99ff99','#99ffcc','#99ffff','#99ccff','#9999ff','#cc99ff','#ff99ff','#ff99cc', + '#ff6666','#ffb266','#ffff66','#b2ff66','#66ff66','#66ffb2','#66ffff','#66b2ff','#6666ff','#b266ff','#ff66ff','#ff66b2', + '#ff3333','#ff9933','#ffff33','#99ff33','#33ff33','#33ff99','#33ffff','#3399ff','#3333ff','#9933ff','#ff33ff','#ff3399', + '#cc0000','#cc6600','#cccc00','#66cc00','#00cc00','#00cc66','#00cccc','#0066cc','#0000cc','#6600cc','#cc00cc','#cc0066', + '#990000','#994c00','#999900','#4c9900','#009900','#00994c','#009999','#004c99','#000099','#4c0099','#990099','#99004c', + '#660000','#663300','#666600','#336600','#006600','#006633','#006666','#003366','#000066','#330066','#660066','#660033'], + offElementTags: { + button: 1, embed: 1, fieldset: 1, form: 1, hr: 1, img: 1, input: 1, object: 1, select: 1, table: 1, textarea: 1 + }, + selfClosingTags: { + area: 1, base: 1, br: 1, col: 1, command: 1, embed: 1, hr: 1, img: 1, input: 1, keygen: 1, link: 1, meta: 1, + param: 1, source: 1, track: 1, wbr: 1 + }, + textFormatTags: { + a: 1, addr: 1, acronym: 1, b: 1, bdo: 1, big: 1, cite: 1, code: 1, del: 1, dfn: 1, em: 1, font: 1, i: 1, ins: 1, kbd: 1, + q: 1, samp: 1, small: 1, strike: 1, strong: 1, sub: 1, sup: 1, time: 1, tt: 1, u: 1, 'var': 1, span: 1 + }, + textFormatBlockTags: { + address: 1, div: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, p: 1, pre: 1, code: 1, section: 1, aside: 1, article: 1, figcaption: 1 + }, + newLineBeforeTags: { + address: 1, article: 1, aside: 1, audio: 1, blockquote: 1, body: 1, canvas: 1, code: 1, comment: 1, dd: 1, div: 1, + dl: 1, fieldset: 1, figcaption: 1, figure: 1, footer: 1, form: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, head: 1, + header: 1, hggroup: 1, hr: 1, li: 1, noscript: 1, ol: 1, output: 1, p: 1, pre: 1, script: 1, section: 1, table: 1, + tbody: 1, td: 1, tfoot: 1, th: 1, thead: 1, title: 1, tr: 1, ul: 1, video: 1 + }, + lineHeightBlockTags: { + address: 1, article: 1, aside: 1, blockquote: 1, code: 1, dd: 1, div: 1, dt: 1, figcaption: 1, figure: 1, + h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, li: 1, p: 1, pre: 1, section: 1, td: 1, th: 1 + }, + listTags: { dd: 1, dt: 1, li: 1 }, + lineBreakTags: { address: 1, article: 1, aside: 1, dd: 1, div: 1, dt: 1, figcaption: 1, li: 1, p: 1, section: 1 }, + doctype: '', + popupWindow: { + ColorPicker : {tmpl : 'color_picker.html', width : 420, title : '색상 선택'}, + Embed : {tmpl : 'media.html', width : 430, title : '미디어'}, + EmotionIcon : {tmpl : 'icon.html', width : 300, title : '표정 아이콘'}, + FlashMovie : {tmpl : 'flash.html', width : 584, title : '플래쉬 동영상'}, + GoogleMap : {tmpl : 'google_map.html', width : 538, title : '구글 지도'}, + ImageUpload : {tmpl : 'image.html', width : 700, title : '내 PC 사진 넣기'}, + ImageUrl : {tmpl : 'image_url.html', width : 350, title : '웹 사진 넣기'}, + Layout : {tmpl : 'layout.html', width : 430, title : '레이아웃'}, + Link : {tmpl : 'link.html', width : 350, title : '하이퍼링크'}, + ModifyTable : {tmpl : 'table_modify.html', width : 430, title : '표 고치기'}, + Symbol : {tmpl : 'symbol.html', width : 450, title : '특수 문자'}, + Table : {tmpl : 'table.html', width : 430, title : '표 만들기'} + }, + fontName: { + kr : ['맑은 고딕', '돋움', '굴림', '바탕', '궁서'], + en : ['Arial', 'Comic Sans MS', 'Courier New', 'Georgia', 'HeadLineA', 'Impact', 'Tahoma', 'Times New Roman', 'Verdana'] + }, + fontStyle: { + FontSize: 'font-size', FontName: 'font-family', ForeColor: 'color', BackColor: 'background-color' + }, + textAlign: { + JustifyLeft: '', JustifyCenter: 'center', JustifyRight: 'right', JustifyFull: 'justify' + }, + listStyle: { + ordered: { + decimal: '숫자', 'lower-alpha': '영문 소문자', 'upper-alpha': '영문 대문자', 'lower-roman': '로마 소문자', 'upper-roman': '로마 대문자' + }, + unOrdered: {desc: '동그라미', circle: '빈 원', square: '사각형'} + }, + fontSize: { + pt: [7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36], + px: [9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72] + }, + formatBlock: { + P: '일반 텍스트', + H1: '제목 1', + H2: '제목 2', + H3: '제목 3', + H4: '제목 4', + H5: '제목 5', + H6: '제목 6', + ADDRESS: 'Address', + DIV: 'DIV', + PRE: 'Preformatted (PRE)' + }, + lineHeight: { + '한 줄 간격': 1, '1.15': 1.15, '1.5': 1.5, '1.7': 1.7, '1.8': 1.8, '두 줄 간격': 2 + }, + textBlock: [ + ['1px #dedfdf solid','#f7f7f7'], + ['1px #aee8e8 solid','#bfffff'], + ['1px #d3bceb solid','#e6ccff'], + ['1px #e8e88b solid','#ffff99'], + ['1px #c3e89e solid','#d6ffad'], + ['1px #e8c8b7 solid','#ffdcc9'], + ['1px #666666 dashed','#ffffff'], + ['1px #d4d4d4 solid','#ffffff'], + ['1px #cccccc inset','#f7f7f7'] + ], + node: { + element: 1, attribute: 2, text: 3, cdata_section: 4, entity_reference: 5, entity: 6, + processing_instruction: 7, comment: 8, document: 9, document_type: 10, document_fragment: 11, + notation: 12 + }, + + selection: { none: 1, text: 2, element: 3 }, + readyState: { 0: 'uninitialized', 1: 'loading', 2: 'loaded', 3: 'interactive', 4: 'complete' }, + dragWindow: null, + colorDropper: null, + readyEditor: 0, + browser: {} +}; + +function isUndefined(obj) { + return obj === void(0); // obj === undefined; +} + +function detechBrowser() { + function detect(ua) { + var iosdevice = getFirstMatch(/(ipod|iphone|ipad)/i).toLowerCase(), + likeAndroid = /like android/i.test(ua), + android = !likeAndroid && /android/i.test(ua), + versionIdentifier = getFirstMatch(/version\/(\d+(\.\d+)?)/i), + tablet = /tablet/i.test(ua), + mobile = !tablet && /[^\-]mobi/i.test(ua), + result, + osVersion = '', + osMajorVersion, + osname, + app; + + function getFirstMatch(regex) { + var match = ua.match(regex); + return (match && match.length > 1 && match[1]) || ''; + } + + if (/opera|opr/i.test(ua)) { + result = { + name: 'Opera', opera: true, + version: versionIdentifier || getFirstMatch(/(?:opera|opr)[\s\/](\d+(\.\d+)?)/i) + }; + } else if (/windows phone/i.test(ua)) { + result = { + name: 'Windows Phone', windowsphone: true, msie: true, + version: getFirstMatch(/iemobile\/(\d+(\.\d+)?)/i) + }; + } else if (/msie|trident/i.test(ua)) { + result = { + name: 'Internet Explorer', msie: true, version: getFirstMatch(/(?:msie |rv:)(\d+(\.\d+)?)/i) + }; + } else if (/edge/i.test(ua)) { + result = { + name: 'edge', edge: true, version: getFirstMatch(/(?:edge)\/(\d+(\.\d+)?)/i) + }; + } else if (/chrome|crios|crmo/i.test(ua)) { + result = { + name: 'Chrome', chrome: true, version: getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i) + }; + } else if (iosdevice) { + result = { + name: iosdevice === 'iphone' ? 'iPhone' : iosdevice === 'ipad' ? 'iPad' : 'iPod' + }; + if (versionIdentifier) { + result.version = versionIdentifier; + } + } else if (/firefox|iceweasel/i.test(ua)) { + result = { + name: 'Firefox', firefox: true, + version: getFirstMatch(/(?:firefox|iceweasel)[ \/](\d+(\.\d+)?)/i) + }; + if (/\((mobile|tablet);[^\)]*rv:[\d\.]+\)/i.test(ua)) { + result.firefoxos = true; + } + } else if (/silk/i.test(ua)) { + result = { + name: 'Amazon Silk', silk: true, version : getFirstMatch(/silk\/(\d+(\.\d+)?)/i) + }; + } else if (android) { + result = { name: 'Android', version: versionIdentifier }; + } else if (/phantom/i.test(ua)) { + result = { + name: 'PhantomJS', phantom: true, version: getFirstMatch(/phantomjs\/(\d+(\.\d+)?)/i) + }; + } else if (/blackberry|\bbb\d+/i.test(ua) || /rim\stablet/i.test(ua)) { + result = { + name: 'BlackBerry', blackberry: true, + version: versionIdentifier || getFirstMatch(/blackberry[\d]+\/(\d+(\.\d+)?)/i) + }; + } else if (/(web|hpw)os/i.test(ua)) { + result = { + name: 'WebOS', webos: true, + version: versionIdentifier || getFirstMatch(/w(?:eb)?osbrowser\/(\d+(\.\d+)?)/i) + }; + if (/touchpad\//i.test(ua)) { + result.touchpad = true; + } + } else if (/safari/i.test(ua)) { + result = { + name: 'Safari', safari: true, version: versionIdentifier + }; + } else { + result = {}; + } + + if (/(apple)?webkit/i.test(ua)) { + result.name = result.name || 'Webkit'; + result.webkit = true; + if (!result.version && versionIdentifier) { + result.version = versionIdentifier; + } + } else if (!result.opera && /gecko\//i.test(ua)) { + result.gecko = true; + result.version = result.version || getFirstMatch(/gecko\/(\d+(\.\d+)?)/i); + result.name = result.name || 'Gecko'; + } + if (android || result.silk) { + result.android = true; + } else if (iosdevice) { + result[iosdevice] = true; + result.ios = true; + } + + if (iosdevice) { + osVersion = getFirstMatch(/os (\d+([_\s]\d+)*) like mac os x/i); + osVersion = osVersion.replace(/[_\s]/g, '.'); + } else if (android) { + osVersion = getFirstMatch(/android[ \/\-](\d+(\.\d+)*)/i); + } else if (result.windowsphone) { + osVersion = getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i); + } else if (result.webos) { + osVersion = getFirstMatch(/(?:web|hpw)os\/(\d+(\.\d+)*)/i); + } else if (result.blackberry) { + osVersion = getFirstMatch(/rim\stablet\sos\s(\d+(\.\d+)*)/i); + } + + if (osVersion) { + result.osversion = osVersion; + } + + osMajorVersion = osVersion.split('.')[0]; + if (tablet || iosdevice === 'ipad' || + (android && (osMajorVersion === 3 || (osMajorVersion === 4 && !mobile))) || + result.silk) { + result.tablet = true; + } else if (mobile || iosdevice === 'iphone' || iosdevice === 'ipod' || android || + result.blackberry || result.webos) { + result.mobile = true; + } + + if (result.edge || + (result.msie && result.version >= 10) || + (result.chrome && result.version >= 20) || + (result.firefox && result.version >= 20.0) || + (result.safari && result.version >= 6) || + (result.opera && result.version >= 10.0) || + (result.ios && result.osversion && result.osversion.split('.')[0] >= 6) || + (result.blackberry && result.version >= 10.1)) { + result.a = true; + } else if ((result.msie && result.version < 10) || + (result.chrome && result.version < 20) || + (result.firefox && result.version < 20.0) || + (result.safari && result.version < 6) || + (result.opera && result.version < 10.0) || + (result.ios && result.osversion && result.osversion.split('.')[0] < 6)) { + result.c = true; + } else { + result.x = true; + } + + osname = ''; + if (/windows/i.test(ua)) { + osname = 'Windows'; + } else if (/mac/i.test(ua)) { + osname = 'MacOS'; + } else if (/x11/i.test(ua)) { + osname = 'UNIX'; + } else if (/linux/i.test(ua)) { + osname = 'Linux'; + } else if (/sunos/i.test(ua)) { + osname = 'Solaris'; + } else { + osname = 'Unknown OS'; + } + result.osname = osname; + + if (osname === 'Windows') { + app = getFirstMatch(/(Windows NT\s(\d+)\.(\d+))/i); + switch (app) { + case 'Windows NT 5.1' : result.os = 'Windows XP'; break; + case 'Windows NT 5.2' : result.os = 'Windows 2003'; break; + case 'Windows NT 6.0' : result.os = 'Windows Vista'; break; + case 'Windows NT 6.1' : result.os = 'Windows 7'; break; + case 'Windows NT 6.2' : result.os = 'Windows 8'; break; + case 'Windows NT 6.3' : result.os = 'Windows 8.1'; break; + case 'Windows NT 10.0' : result.os = 'Windows 10'; break; + default : result.os = app; + } + } + + if (result.msie) { + if (result.version > 10) { + result.msie_a = true; + result.msie_bogus = true; + } else if (result.version > 8) { + result.msie_b = true; + result.msie_bogus = false; + } else { + result.msie_c = true; + result.msie_bogus = (result.os === 'Windows XP'); + } + } + return result; + } + return detect(!isUndefined(navigator) ? navigator.userAgent : null); +} + +function URI(uri) { + this.scheme = null; + this.authority = null; + this.path = ''; + this.query = null; + this.fragment = null; + + this.parseUri = function (uri) { + var m = uri.match(/^(([A-Za-z][0-9A-Za-z+.\-]*)(:))?((\/\/)([^\/?#]*))?([^?#]*)((\?)([^#]*))?((#)(.*))?/); + this.scheme = m[3] ? m[2] : null; + this.authority = m[5] ? m[6] : null; + this.path = m[7]; + this.query = m[9] ? m[10] : null; + this.fragment = m[12] ? m[13] : null; + return this; + }; + + this.azToString = function () { + var result = ''; + if (this.scheme !== null) { + result = result + this.scheme + ':'; + } + if (this.authority !== null) { + result = result + '//' + this.authority; + } + if (this.path !== null) { + result = result + this.path; + } + if (this.query !== null) { + result = result + '?' + this.query; + } + if (this.fragment !== null) { + result = result + '#' + this.fragment; + } + return result; + }; + + this.toAbsolute = function (location) { + var baseUri = new URI(location), + URIAbs = this, + target = new URI(), + removeDotSegments = function (path) { + var result = '', rm; + while (path) { + if (path.substr(0, 3) === '../' || path.substr(0, 2) === './') { + path = path.replace(/^\.+/, '').substr(1); + } else if (path.substr(0, 3) === '/./' || path === '/.') { + path = '/' + path.substr(3); + } else if (path.substr(0, 4) === '/../' || path === '/..') { + path = '/' + path.substr(4); + result = result.replace(/\/?[^\/]*$/, ''); + } else if (path === '.' || path === '..') { + path = ''; + } else { + rm = path.match(/^\/?[^\/]*/)[0]; + path = path.substr(rm.length); + result = result + rm; + } + } + return result; + }; + + if (baseUri.scheme === null) { + return false; + } + if (URIAbs.scheme !== null && URIAbs.scheme.toLowerCase() === baseUri.scheme.toLowerCase()) { + URIAbs.scheme = null; + } + + if (URIAbs.scheme !== null) { + target.scheme = URIAbs.scheme; + target.authority = URIAbs.authority; + target.path = removeDotSegments(URIAbs.path); + target.query = URIAbs.query; + } else { + if (URIAbs.authority !== null) { + target.authority = URIAbs.authority; + target.path = removeDotSegments(URIAbs.path); + target.query = URIAbs.query; + } else { + if (URIAbs.path === '') { + target.path = baseUri.path; + target.query = URIAbs.query || baseUri.query; + } else { + if (URIAbs.path.substr(0, 1) === '/') { + target.path = removeDotSegments(URIAbs.path); + } else { + if (baseUri.authority !== null && baseUri.path === '') { + target.path = '/' + URIAbs.path; + } else { + target.path = baseUri.path.replace(/[^\/]+$/, '') + URIAbs.path; + } + target.path = removeDotSegments(target.path); + } + target.query = URIAbs.query; + } + target.authority = baseUri.authority; + } + target.scheme = baseUri.scheme; + } + target.fragment = URIAbs.fragment; + return target; + }; + if (uri) { + this.parseUri(uri); + } +} + +function setConfig() { + var config = { + allowedOnEvent : true, + colorToHex : true, + docTitle : '내 문서', + editAreaMargin : '5px 10px', + editorBgColor : '#fff', + editorFontColor : '#000', + editorFontName : '"맑은 고딕", "Malgun Gothic", gulim', + editorFontSize : '12px', + editorHeight : '300px', + editorPath : null, + editorWidth : '100%', + exceptedElements : { script: true, style: true, iframe: false }, + fontSizeValue : 'px', // [pt, px] + fullHTMLSource : false, + imgBlockMargin : '5px 0px', + imgCaptionFigure : 'border: 1px #ccc solid; background-color: #f0f0f0; margin: 0', + imgCaptionText : 'margin: 5px 5px; text-align: left; line-height: 17px', + imgCaptionWrapper : '', + imgDefaultAlign : 'left', // [left, center, right] + imgJpegQuality : 0.92, // JPEG 사진의 퀄리티 값, 최대값 1 + imgMaxWidth : 800, // 사진 최대 가로 크기, 이 크기 보다 크면 리사이징 처리 + imgResizeMinLimit : 32, // 사진 리사이징의 사용자 직접 입력 값이 이 값 보다 작으면, 이 값으로 설정 + imgResizeSelected : 800, // 사진 리사이징의 선택 입력 폼의 기본 선택 값 + imgResizeValue : [120, 240, 320, 640, 800, -1], // -1 = 사용자 직접 입력 + imgSetAttrAlt : true, + imgSetAttrWidth : 1, // -1 = (width="100%"; height="auto"), 0 = 설정 안함, 1 = 기본값 + imgUploadNumber : 12, + imgUploadSortName : false, + imgWaterMarkAlpha : 1, // 워터마크 불투명도 (최대값 1) + imgWaterMarkUrl : '', // 워터마크 이미지 URL (예: 'http://udomain.com/cheditor/icons/watermark.png') + includeHostname : true, + lineHeight : 1.7, + linkTarget : '_blank', + makeThumbnail : false, // 사진의 썸네일 이미지 생성, 가로 크기는 thumbnailWidth 값, 세로는 자동 계산 + paragraphCss : false, // true =

, false =

+ removeIndent : false, + showTagPath : false, + tabIndent : 3, + tabIndex : 0, + thumbnailWidth : 120, + + // 버튼 사용 유무 + useSource : true, + usePreview : true, + usePrint : true, + useNewDocument : true, + useUndo : true, + useRedo : true, + useCopy : true, + useCut : true, + usePaste : true, + usePasteFromWord : true, + useSelectAll : true, + useStrikethrough : true, + useUnderline : true, + useItalic : true, + useSuperscript : false, + useSubscript : false, + useJustifyLeft : true, + useJustifyCenter : true, + useJustifyRight : true, + useJustifyFull : true, + useBold : true, + useOrderedList : true, + useUnOrderedList : true, + useOutdent : true, + useIndent : true, + useFontName : true, + useFormatBlock : true, + useFontSize : true, + useLineHeight : true, + useBackColor : true, + useForeColor : true, + useRemoveFormat : true, + useClearTag : true, + useSymbol : true, + useLink : true, + useUnLink : true, + useFlash : true, + useMedia : false, + useImage : true, + useImageUrl : false, + useSmileyIcon : true, + useHR : true, + useTable : true, + useModifyTable : true, + useMap : true, + useTextBlock : true, + useFullScreen : true, + usePageBreak : false + }, + base, elem, i, editorUri, locationAbs; + + if (config.editorPath === null) { + base = location.href; + elem = document.getElementsByTagName('base'); + for (i = 0; i < elem.length; i++) { + if (elem[i].href) { + base = elem[i].href; + } + } + elem = document.getElementsByTagName('script'); + for (i = 0; i < elem.length; i++) { + if (elem[i].src) { + editorUri = new URI(elem[i].src); + if (/\/cheditor\.js$/.test(editorUri.path)) { + locationAbs = editorUri.toAbsolute(base).azToString(); + delete locationAbs.query; + delete locationAbs.fragment; + config.editorPath = locationAbs.replace(/[^\/]+$/, ''); + } + } + } + if (config.editorPath === null) { + throw 'CHEditor 경로가 바르지 않습니다.\nmyeditor.config.editorPath를 설정하여 주십시오.'; + } + } + + this.storedSelections = []; + this.keyPressStoredSelections = []; + this.images = []; + this.editImages = {}; + this.cheditor = {}; + this.toolbar = {}; + this.pulldown = {}; + this.currentRS = {}; + this.resizeEditor = {}; + this.setFullScreenMode = false; + this.modalElementZIndex = 1001; + this.config = config; + this.templateFile = 'template.xml'; + this.templatePath = config.editorPath + this.templateFile; + this.W3CRange = !(this.undefined(window.getSelection)); + this.inputForm = 'textAreaId'; + this.range = null; + this.tempTimer = null; + this.cheditor.tabSpaces = ''; + this.cheditor.modifyState = false; + this.cheditor.tabSpaces = new Array(this.config.tabIndent + 1).join(' '); +} + +function cheditor() { + this.toType = (function (global) { + var toString = cheditor.prototype.toString, + re = /^.*\s(\w+).*$/; + + return function (obj) { + if (obj === global) { + return 'global'; + } + return toString.call(obj).replace(re, '$1').toLowerCase(); + }; + }(this)); + + this.undefined = isUndefined; + GB.browser = this.browser = detechBrowser(); + + if (this.undefined(document.execCommand)) { + alert('현재 브라우저에서 CHEditor를 실행할 수 없습니다.'); + return null; + } + if (this.browser.msie && this.browser.version < 7) { + alert('CHEditor는 Internet Explorer 7 이하 버전은 지원하지 않습니다.'); + return null; + } + + try { + setConfig.call(this); + this.cheditor.id = (this.undefined(GB.readyEditor)) ? 1 : GB.readyEditor++; + } catch (e) { + alert(e.toString()); + return null; + } + + return this; +} + +cheditor.prototype = { + //---------------------------------------------------------------- + resetData : function () { + if (GB.browser.msie) { + if (this.undefined(this.cheditor.editArea.onreadystatechange)) { + GB.browser.version = 11; + } + GB.browser.msie_bogus = (GB.browser.version < 8 || GB.browser.version > 10); + document.execCommand('BackgroundImageCache', false, true); + } + this.resetEditArea(); + }, + + appendContents : function (contents) { + var div = this.doc.createElement('div'); + this.editAreaFocus(); + div.innerHTML = String(this.trimSpace(contents)); + + while (div.hasChildNodes()) { + this.doc.body.appendChild(div.firstChild); + } + this.editAreaFocus(); + }, + + insertContents : function (contents) { + this.editAreaFocus(); + this.doCmdPaste(String(this.trimSpace(contents))); + }, + + replaceContents : function (contents) { + this.editAreaFocus(); + this.doc.body.innerHTML = ''; + this.loadContents(contents); + this.editAreaFocus(); + }, + + loadContents : function (contents) { + if (typeof contents === 'string') { + contents = this.trimSpace(contents); + if (contents) { + this.cheditor.editArea.style.visibility = 'hidden'; + this.doc.body.innerHTML = contents; + this.cheditor.editArea.style.visibility = 'visible'; + } + } + }, + + setFolderPath : function () { + if (this.config.editorPath.charAt(this.config.editorPath.length - 1) !== '/') { + this.config.editorPath += '/'; + } + this.config.iconPath = this.config.editorPath + 'icons/'; + this.config.cssPath = this.config.editorPath + 'css/'; + this.config.popupPath = this.config.editorPath + 'popup/'; + }, + + checkInputForm : function () { + var textarea = document.getElementById(this.inputForm); + if (!textarea) { + throw 'ID가 "' + this.inputForm + '"인 textarea 개체를 찾을 수 없습니다.'; + } + textarea.style.display = 'none'; + this.cheditor.textarea = textarea; + }, + + setDesignMode : function (designMode, doc) { + var mode = designMode ? 'on' : 'off'; + + doc = doc || this.doc; + if (GB.browser.msie) { + if (doc.body.contentEditable !== designMode) { + doc.body.contentEditable = designMode; + } + return; + } + if (doc.designMode !== mode) { + doc.designMode = mode; + } + }, + + openDoc : function (doc, contents) { + var html = '' + + '' + this.config.docTitle + '' + + ''; + + doc.open(); + + if (typeof contents === 'string') { + html += this.trimSpace(contents); + } + + html += ''; + doc.write(html); + doc.close(); + }, + + getWindowHandle : function (iframeObj) { + var iframeWin; + if (iframeObj.contentWindow) { + iframeWin = iframeObj.contentWindow; + } else { + throw '현재 브라우저에서 에디터를 실행할 수 없습니다.'; + } + return iframeWin; + }, + + resetDoc : function () { + if (this.undefined(this.cheditor.editArea)) { + return false; + } + try { + this.editArea = this.getWindowHandle(this.cheditor.editArea); + this.doc = GB.browser.msie ? this.editArea.document : this.cheditor.editArea.contentDocument; + this.resetData(); + return true; + } catch (e) { + alert(e.toString()); + return false; + } + }, + + resetEditArea : function () { + this.openDoc(this.doc, this.cheditor.textarea.value); + this.setDocumentProp(); + }, + + resetDocumentBody : function () { + this.doc.body.parentNode.replaceChild(this.doc.createElement('body'), this.doc.body); + this.setDocumentBodyProp(); + }, + + setDocumentBodyProp : function () { + this.doc.body.setAttribute('spellcheck', 'false'); + this.doc.body.setAttribute('hidefocus', ''); + }, + + setDocumentProp : function () { + var oSheet, + bodyCss = 'font-size:' + this.config.editorFontSize + + '; font-family:' + this.config.editorFontName + + '; color:' + this.config.editorFontColor + + '; margin:' + this.config.editAreaMargin + + '; line-height:' + this.config.lineHeight, + tableCss = 'font-size:' + this.config.editorFontSize + '; line-height:' + this.config.lineHeight, + self = this; + + this.setDefaultCss({css: 'editarea.css', doc: this.doc}); + + oSheet = this.doc.styleSheets[0]; + if (!this.W3CRange) { + oSheet.addRule('body', bodyCss); + oSheet.addRule('table', tableCss); + } else { + oSheet.insertRule('body {' + bodyCss + '}', 0); + oSheet.insertRule('table {' + tableCss + '}', 1); + } + + this.setDocumentBodyProp(); + this.cheditor.bogusSpacerName = 'ch_bogus_spacer'; + + this.addEvent(this.doc, 'paste', function (event) { + self.handlePaste(event); + }); + + if (!GB.browser.msie) { + this.doc.execCommand('defaultParagraphSeparator', false, 'p'); + } + + this.setDesignMode(true); + this.initDefaultParagraphSeparator(); + }, + + initDefaultParagraphSeparator : function () { + var p = this.doc.createElement('p'), br; + + if (this.doc.body.firstChild && this.doc.body.firstChild.nodeName.toLowerCase() === 'br') { + this.doc.body.removeChild(this.doc.body.firstChild); + } + + if (this.W3CRange) { + if (!this.doc.body.hasChildNodes()) { + this.doc.body.appendChild(p); + if (!GB.browser.msie && !GB.browser.edge) { + br = this.doc.createElement('br'); + br.className = this.cheditor.bogusSpacerName; + p.appendChild(br); + this.placeCaretAt(p, false); + } else { + this.placeCaretAt(p, false); + } + } + } else { + this.doc.body.appendChild(p); + this.placeCaretAt(p, false); + } + }, + + handleBeforePaste : function () { + var range = this.getRange(), commonAncestorContainer, startOffset, wrapper; + this.backupRange(); + + if (!range.collapsed) { + range.deleteContents(); + range = this.getRange(); + } + + commonAncestorContainer = range.commonAncestorContainer; + startOffset = range.startOffset; + wrapper = this.doc.createElement('div'); + + if (startOffset < 1 && commonAncestorContainer.nodeType === GB.node.text) { + commonAncestorContainer.parentNode.insertBefore(wrapper, commonAncestorContainer); + } else { + range.insertNode(wrapper); + } + + this.placeCaretAt(wrapper, false); + return wrapper; + }, + + handlePaste : function (ev) { + var text, clip, elem, wrapper, pNode, space = [], div, self = this; + if (this.cheditor.mode === 'preview') { + return; + } + if (this.cheditor.paste !== 'text' && this.cheditor.mode === 'rich' && this.W3CRange) { + wrapper = this.handleBeforePaste(); + setTimeout(function () { + if (wrapper) { + if (wrapper.hasChildNodes()) { + text = wrapper.innerHTML; + text = text.replace(/[\r\n]/g, '\u00a0'); + text = text.replace(/]+)>(\s+| +)<\/font>/gi, '\u00a0'); + text = text.replace(/]+)>(\s+| +)<\/span>/gi, '\u00a0'); + text = text.replace(/<\/?(font)\s?([^>]+)?>/gi, ''); + text = text.replace(/([\s ]+)<\/strong>/gi, '\u00a0'); + text = text.replace(/([\s ]+)<\/b>/gi, '\u00a0'); + text = text.replace(/([\s ]+)<\/em>/gi, '\u00a0'); + text = text.replace(/([\s ]+)<\/i>/gi, '\u00a0'); + text = text.replace(/<\/?(colgroup|col\s?([^>]+))>/gi, ''); + text = text.replace(/<(\/)?strong>/gi, '<$1b>'); + text = text.replace(/<(\/)?em>/gi, '<$1i>'); + + wrapper.innerHTML = text; + if (wrapper.firstChild.nodeType === GB.node.text) { + text = wrapper.firstChild.data; + text = text.replace(/^( +|\s+)/g, ''); + wrapper.firstChild.data = text; + } + + elem = wrapper.firstChild; + while (elem) { + wrapper.parentNode.insertBefore(elem, wrapper); + elem = wrapper.firstChild; + } + } + + pNode = wrapper.parentNode; + if (pNode) { + if (pNode.firstChild === wrapper && pNode.lastChild === wrapper) { + pNode.parentNode.removeChild(pNode); + } else { + pNode.removeChild(wrapper); + } + } + self.setImageEvent(true); + } + }, 50); + return; + } + + if (ev !== null) { + clip = ev.clipboardData; + this.stopEvent(ev); + } + + text = this.trimSpace((this.undefined(clip) || clip === null) ? + window.clipboardData.getData('Text') : + clip.getData('text/plain')); + + if (text !== '') { + text = text.replace(/\r/g, ''); + if (this.cheditor.mode === 'code') { + div = this.doc.createElement('div'); + text = this.htmlEncode(text); + text = text.replace(/\s{2,}/gm, '\n'); + text = text.replace(/[\u200b\ufeff\xa0\u3000]+/g, ''); + + if (GB.browser.msie && GB.browser.version < 9) { + text = text.replace(/\n/g, '
'); + text = text.replace(/\t/g, '__CHEDITOR_TAB_SPACE__'); + text = text.replace(/\s/gm, ' '); + } + div.innerHTML = text; + div.id = 'clipboardData'; + this.insertHTML(div); + return; + } + + text = this.htmlEncode(text); + text = text.replace(/[\r\n]+/g, '\n'); + text = text.split('\n').join('
'); + + text = text.replace(/(\s{2,})/g, function (a, b) { + space = b.split(/\s/); + space.shift(); + return ' ' + space.join(' '); + }); + this.insertHTML(text); + self.setImageEvent(true); + } + }, + + editAreaFocus : function () { + this.editArea.focus(); + }, + + resizeGetY : function (evt) { + return GB.browser.msie ? + window.event.clientY + document.documentElement.scrollTop + document.body.scrollTop : + evt.clientY + window.pageYOffset; + }, + + resizeStart : function (evt) { + var self = this; + self.currentRS.elNode = self.cheditor.mode === 'code' ? self.cheditor.textContent : self.cheditor.editArea; + self.currentRS.cursorStartY = self.resizeGetY(evt); + self.currentRS.elStartTop = parseInt(self.currentRS.elNode.style.height, 10); + + if (isNaN(self.currentRS.elStartTop)) { + self.currentRS.elStartTop = 0; + } + + evt = evt || window.event; + + self.resizeEditor.stopFunc = function (event) { + self.resizeStop(event); + }; + self.resizeEditor.moveFunc = function (event) { + self.resizeMove(event); + }; + + if (GB.browser.msie) { + self.setDesignMode(false); + } + + self.currentRS.elNode.style.visibility = 'hidden'; + self.addEvent(document, 'mousemove', self.resizeEditor.moveFunc); + self.addEvent(document, 'mouseup', self.resizeEditor.stopFunc); + self.stopEvent(evt); + }, + + resizeMove : function (evt) { + var offset = this.resizeGetY(evt), + height = this.currentRS.elStartTop + offset - this.currentRS.cursorStartY; + if (height < 1) { + this.resizeStop(evt); + height = 1; + } + this.config.editorHeight = this.currentRS.elNode.style.height = height + 'px'; + this.stopEvent(evt); + }, + + resizeStop : function (evt) { + this.stopEvent(evt); + this.removeEvent(document, 'mouseup', this.resizeEditor.stopFunc); + this.removeEvent(document, 'mousemove', this.resizeEditor.moveFunc); + this.currentRS.elNode.style.visibility = 'visible'; + if (GB.browser.msie) { + this.setDesignMode(true); + } + if (this.cheditor.mode === 'code') { + this.config.editorHeight = (parseInt(this.config.editorHeight, 10) + + parseInt(this.cheditor.textContent.getAttribute('xbar-height'), 10)) + 'px'; + this.cheditor.textContent.focus(); + } else if (this.cheditor.mode === 'rich') { + this.editAreaFocus(); + } + }, + + switchEditorMode : function (changeMode) { + var self = this, i, className, interval; + + this.editAreaFocus(); + if (this.cheditor.mode === changeMode) { + return; + } + + for (i in this.cheditor.modetab) { + if (this.cheditor.modetab.hasOwnProperty(i)) { + className = this.cheditor.modetab[i].className; + className = className.replace(/\-off$/, ''); + if (i !== changeMode) { + this.cheditor.modetab[i].className = className + '-off'; + } else { + this.cheditor.modetab[i].className = className; + } + } + } + + switch (changeMode) { + case 'rich' : + this.richMode(); + this.showTagSelector(true); + break; + case 'code' : + if (this.cheditor.modifyState) { + interval = setInterval(function () { + if (!self.cheditor.modifyState) { + clearInterval(interval); + self.editMode(); + } + }, 10); + } else { + this.editMode(); + } + this.showTagSelector(false); + break; + case 'preview' : + this.previewMode(); + this.showTagSelector(false); + } + this.cheditor.mode = changeMode; + }, + + initTemplate : function () { + var self = this, + httpRequest = null, + showError = function (msg) { + alert(self.templateFile + ' 파일 로딩 중 오류가 발생하였습니다.\n원인: ' + msg); + }, + templateReady = function () { + var event; + if (httpRequest.readyState === 4) { + if (httpRequest.status === 200) { + try { + self.xmlDoc = httpRequest.responseXML || httpRequest; + self.loadTemplate(self.xmlDoc); + if (self.W3CRange) { + event = document.createEvent('Event'); + event.initEvent(self.cheditor.id, true, true); + document.dispatchEvent(event); + } else { + document.documentElement.loadEvent = self.cheditor.id; + } + } catch (e) { + showError(e.toString()); + } + } else { + showError('XMLHttpRequest. Status ' + httpRequest.status); + } + } + }; + + if (window.XMLHttpRequest) { + httpRequest = new XMLHttpRequest(); + if (httpRequest.overrideMimeType) { + httpRequest.overrideMimeType('text/xml'); + } + httpRequest.onreadystatechange = templateReady; + try { + httpRequest.open('GET', self.templatePath, true); + } + catch (e) { + showError(e + '참고: 에디터를 웹 서버에서 실행하여 주십시오.'); + } + httpRequest.send(); + } else if (window.ActiveXObject) { + httpRequest = new window.ActiveXObject('Microsoft.XMLDOM'); + httpRequest.async = true; + httpRequest.onreadystatechange = templateReady; + httpRequest.load(self.templatePath); + } else { + 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; + }, + + setToolbarBgPosition : function (elem, attr) { + elem.style.backgroundPosition = attr; + }, + + getToolbarBgPosition : function (elem) { + var pos; + switch (elem.className) { + case 'cheditor-tb-bg' : pos = 3; break; + case 'cheditor-tb-bg-last' : pos = 6; break; + case 'cheditor-tb-bg-single' : pos = 9; break; + case 'cheditor-tb-bg30-first' : pos = 12; break; + case 'cheditor-tb-bg30' : pos = 15; break; + case 'cheditor-tb-bg30-last' : pos = 18; break; + case 'cheditor-tb-bg55' : pos = 21; break; + case 'cheditor-tb-bg40' : pos = 24; break; + case 'cheditor-tb-bg44' : pos = 27; break; + case 'cheditor-tb-bgcombo' : pos = 30; break; + case 'cheditor-tb-bgcombo-last' : pos = 33; break; + default : pos = 0; + } + return pos; + }, + + toolbarMouseOverUp : function (elem) { + var pos, obj; + if (elem.checked) { + return; + } + this.setToolbarBgPosition(elem.button, '0 ' + (~(((elem.pos + 1) * elem.height)) + 1) + 'px'); + + if ((elem.name === 'combobox' && elem.prev && elem.prev.checked) || + (elem.name === 'combo' && elem.next && elem.next.checked)) { + return; + } + if (elem.type === 'combobox') { + if (elem.prev.checked) { + return; + } + obj = elem.prev; + pos = '0px ' + (~(((obj.pos + 1) * obj.height)) + 1) + 'px'; + this.setToolbarBgPosition(obj.button, pos); + } else if (elem.type === 'combo') { + if (elem.prev && !elem.prev.checked && !elem.prev.active) { + obj = elem.prev; + pos = (~(obj.width) + 1) + 'px ' + (~(obj.pos * obj.height) + 1) + 'px'; + this.setToolbarBgPosition(obj.button, pos); + } + if (elem.next) { + if (elem.next.checked) { + return; + } + obj = elem.next; + pos = (~(obj.width) + 1) + 'px ' + (~(((obj.pos + 1) * obj.height)) + 1) + 'px'; + this.setToolbarBgPosition(obj.button, pos); + } + } else { + if (!elem.prev || (elem.prev && elem.prev.checked)) { + return; + } + obj = elem.prev; + if (obj.className === 'cheditor-tb-bg-first') { + pos = (~(obj.width) + 1) + 'px 0'; + } else { + pos = (~(obj.width) + 1) + 'px ' + (~(obj.pos * obj.height) + 1) + 'px'; + } + this.setToolbarBgPosition(obj.button, pos); + } + }, + + toolbarMouseDownOut : function (elem, mousedown) { + if (elem.next && elem.next.checked && !mousedown) { + this.setToolbarBgPosition(elem.button, (~(elem.width * 2) + 1) + 'px ' + + (~(elem.pos * elem.height) + 1) + 'px'); + } + if (elem.prev) { + if (elem.prev.active || (elem.prev.type === 'combo' && elem.checked)) { + return; + } + if (elem.prev.checked) { + this.setToolbarBgPosition(elem.prev.button, '0 ' + + (~((elem.prev.pos + 2) * elem.prev.height) + 1) + 'px'); + return; + } + if (mousedown) { + this.setToolbarBgPosition(elem.prev.button, (~(elem.prev.width * 2) + 1) + 'px ' + + (~(elem.prev.pos * elem.prev.height) + 1) + 'px'); + } else { + this.setToolbarBgPosition(elem.prev.button, + '0 ' + (~(elem.prev.pos * elem.prev.height) + 1) + 'px'); + } + } + }, + + toolbarButtonChecked : function (elem) { + this.setToolbarBgPosition(elem.button, '0 ' + (~((elem.pos + 2) * elem.height) + 1) + 'px'); + if (elem.prev && elem.prev.type === 'combo') { + if (elem.prev.checked || elem.checked) { + return; + } + this.setToolbarBgPosition(elem.prev.button, (~(elem.prev.width * 2) + 1) + 'px ' + + (~(elem.prev.pos * elem.prev.height) + 1) + 'px'); + } + if (elem.prev && !elem.prev.checked) { + if (elem.checked) { + this.setToolbarBgPosition(elem.prev.button, (~(elem.prev.width * 2) + 1) + 'px ' + + (~(elem.prev.pos * elem.prev.height) + 1) + 'px'); + } else { + this.setToolbarBgPosition(elem.prev.button, '0 ' + (~(elem.prev.pos * elem.prev.height) + 1) + 'px'); + } + } + }, + + toolbarButtonUnchecked : function (elem) { + if (elem.type === 'combobox' && !elem.checked) { + if (elem.prev.checked) { + this.setToolbarBgPosition(elem.button, + (~(elem.width) + 1) + 'px ' + (~(((elem.pos + 1) * elem.height)) + 1) + 'px'); + return; + } + this.setToolbarBgPosition(elem.prev.button, '0 ' + (~(elem.prev.pos * elem.prev.height) + 1) + 'px'); + } + this.setToolbarBgPosition(elem.button, '0 ' + (~(elem.pos * elem.height) + 1) + 'px'); + if (elem.prev && elem.prev.name === 'BackColor') { + this.setToolbarBgPosition(elem.prev.button, '0 ' + (~(elem.prev.pos * elem.prev.height) + 1) + 'px'); + } + }, + + makeToolbarGrayscale : function (image) { + var context, imageData, filter, imgWidth = image.width, imgHeight = image.height, + canvas = this.doc.createElement('canvas'); + + filter = function (pixels) { + var d = pixels.data, i, r, g, b; + for (i = 0; i < d.length; i += 4) { + r = d[i]; + g = d[i + 1]; + b = d[i + 2]; + d[i] = d[i + 1] = d[i + 2] = (r + g + b) / 3; + } + return pixels; + }; + + context = canvas.getContext('2d'); + canvas.width = imgWidth; + canvas.height = imgHeight; + context.drawImage(image, 0, 0); + + imageData = context.getImageData(0, 0, imgWidth, imgHeight); + filter(imageData); + context.putImageData(imageData, 0, 0); + return canvas.toDataURL(); + }, + + toolbarSetBackgroundImage : function (elem, disable) { + var css = elem.firstChild.className, + tbEnable = (this.cheditor.toolbarGrayscale && elem.firstChild.style.backgroundImage); + + css = css.replace(/-disable$/i, ''); + if (disable) { + if (tbEnable) { + elem.firstChild.style.backgroundImage = 'url(' + this.cheditor.toolbarGrayscale + ')'; + } + css = css + '-disable'; + elem.style.cursor = 'default'; + } else { + if (tbEnable) { + elem.firstChild.style.backgroundImage = 'url(' + this.toolbar.icon + ')'; + } + elem.style.cursor = 'pointer'; + } + elem.firstChild.className = css; + }, + + toolbarDisable : function (elem, disable) { + if (disable) { + this.toolbarSetBackgroundImage(elem.button, true); + this.toolbarButtonUnchecked(elem); + this.toolbarMouseDownOut(elem); + this.toolbar[elem.name].disabled = true; + return true; + } + this.toolbarSetBackgroundImage(elem.button, false); + this.toolbar[elem.name].disabled = false; + return false; + }, + + colorConvert : function (color, which, opacity) { + var colorDefs = [ + { + re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/, + process : function (bits) { + return [ + parseInt(bits[1], 10), + parseInt(bits[2], 10), + parseInt(bits[3], 10), + 1 + ]; + } + }, + { + re : /^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d+(?:\.\d+)?|\.\d+)\s*\)/, + process : function (bits) { + return [ + parseInt(bits[1], 10), + parseInt(bits[2], 10), + parseInt(bits[3], 10), + parseFloat(bits[4]) + ]; + } + }, + { + re: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/, + process : function (bits) { + return [ + parseInt(bits[1], 16), + parseInt(bits[2], 16), + parseInt(bits[3], 16), + 1 + ]; + } + }, + { + re: /^([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])$/, + process : function (bits) { + return [ + parseInt(bits[1] * 2, 16), + parseInt(bits[2] * 2, 16), + parseInt(bits[3] * 2, 16), + 1 + ]; + } + } + ], r = null, g = null, b = null, a = null, i, re, processor, bits, channels, min, rData = null; + + if (!which) { + which = 'rgba'; + } + + color = color.replace(/^\s*#|\s*$/g, ''); + if (color.length === 3) { + color = color.replace(/(.)/g, '$1$1'); + } + + color = color.toLowerCase(); + which = which.toLowerCase(); + + for (i = 0; i < colorDefs.length; i++) { + re = colorDefs[i].re; + processor = colorDefs[i].process; + bits = re.exec(color); + if (bits) { + channels = processor(bits); + r = channels[0]; + g = channels[1]; + b = channels[2]; + a = channels[3]; + } + } + + r = (r < 0 || isNaN(r)) ? 0 : ((r > 255) ? 255 : r); + g = (g < 0 || isNaN(g)) ? 0 : ((g > 255) ? 255 : g); + b = (b < 0 || isNaN(b)) ? 0 : ((b > 255) ? 255 : b); + a = (a < 0 || isNaN(a)) ? 0 : ((a > 1) ? 1 : a); + + function hex(x) { + return ('0' + parseInt(x, 10).toString(16)).slice(-2); + } + + switch (which) { + case 'rgba': + if (opacity) { + a = (255 - (min = Math.min(r, g, b))) / 255; + r = ((r - min) / a).toFixed(0); + g = ((g - min) / a).toFixed(0); + b = ((b - min) / a).toFixed(0); + a = a.toFixed(4); + } + rData = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')'; + break; + case 'rgb': + rData = 'rgb(' + r + ',' + g + ',' + b + ')'; + break; + case 'hex': + if (isNaN(parseInt(r, 10)) || isNaN(parseInt(g, 10)) || isNaN(parseInt(b, 10))) { + return color; + } + rData = '#' + hex(r) + hex(g) + hex(b); + break; + } + return rData; + }, + + toolbarUpdate : function (srcElement) { + var toolbar = this.toolbar, + range = this.getRange(), + isCollapsed = this.rangeCollapsed(range), + sType = GB.selection.text, + bControl = false, bTable = false, ancestorsLen = 0, bNoOff = { 'Link': 1 }, ancestors = [], + i, j, btn, cmd, autoOff, bDisable, el, wrapper, fontAttr, oldName, span, newAttr, defaultAttr, + state, css, node, alignment, pNode; + + pNode = srcElement || this.getRangeElement(range); + switch (pNode.nodeType) { + case GB.node.element: + sType = GB.selection.element; + break; + case GB.node.text: + sType = GB.selection.text; + pNode = pNode.parentNode; + break; + default: + return; + } + + if (sType === GB.selection.element && !isCollapsed) { + bControl = GB.offElementTags[pNode.nodeName.toLowerCase()]; + } else { + node = pNode; + while (node && node.nodeType === GB.node.element && node.nodeName.toLowerCase() !== 'body') { + ancestors.push(node); + if (node.nodeName.toLowerCase() === 'td' || node.nodeName.toLowerCase() === 'th') { + bTable = true; + } + node = node.parentNode; + } + ancestorsLen = ancestors.length; + } + + if (!bTable && sType === GB.selection.element && + (pNode.nodeName.toLowerCase() === 'table' || pNode.nodeName.toLowerCase() === 'td' || + pNode.nodeName.toLowerCase() === 'th')) { + bTable = true; + } + + alignment = { JustifyCenter : 'center', JustifyRight : 'right', JustifyFull : 'justify' }; + + for (i in toolbar) { + if (!toolbar.hasOwnProperty(i)) { + continue; + } + + btn = toolbar[i]; + if (!btn.cmd) { + continue; + } + + cmd = btn.cmd; + autoOff = false; + + if (bControl && sType === GB.selection.element) { + if (btn.group !== 'Alignment') { + autoOff = !(pNode.nodeName.toLowerCase() === 'img' && bNoOff[cmd]); + } + } + + if (btn.name === 'ModifyTable') { + autoOff = !bTable; + } + + bDisable = this.toolbarDisable(btn, autoOff); + + if (btn.name === 'ForeColor' || btn.name === 'BackColor') { + btn.button.lastChild.style.display = bDisable ? 'none' : 'block'; + } + if (btn.autocheck === null) { + continue; + } + + switch (cmd) { + case 'Copy' : + case 'Cut' : + this.toolbarDisable(btn, isCollapsed); + break; + case 'UnLink' : + if (GB.browser.firefox) { + this.toolbarDisable(btn, (pNode.nodeName.toLowerCase() !== 'a' && !pNode.getAttribute('href'))); + } else { + this.toolbarDisable(btn, this.doc.queryCommandEnabled(cmd) === false); + } + break; + case 'FormatBlock' : + wrapper = btn.button.firstChild; + oldName = wrapper.firstChild; + el = false; + span = document.createElement('span'); + for (j = 0; j < ancestorsLen; j++) { + if (GB.formatBlock[ancestors[j].nodeName]) { + span.appendChild(document.createTextNode(ancestors[j].nodeName)); + wrapper.replaceChild(span, oldName); + el = true; + break; + } + } + if (!el) { + span.appendChild(document.createTextNode('스타일')); + wrapper.replaceChild(span, oldName); + } + this.unselectionElement(span); + break; + case 'ForeColor' : + case 'BackColor' : + if (cmd === 'BackColor' && !GB.browser.msie) { + cmd = 'HiliteColor'; + } + fontAttr = this.doc.queryCommandValue(cmd); + if (fontAttr && !/^[rgb|#]/.test(fontAttr)) { + fontAttr = (((fontAttr & 0x0000ff) << 16) | (fontAttr & 0x00ff00) | ((fontAttr & 0xff0000) >>> 16)).toString(16); + fontAttr = '#000000'.slice(0, 7 - fontAttr.length) + fontAttr; + } else { + fontAttr = (cmd === 'ForeColor') ? this.config.editorFontColor : this.config.editorBgColor; + } + btn.button.lastChild.style.backgroundColor = fontAttr; + break; + case 'FontName' : + case 'FontSize' : + fontAttr = this.doc.queryCommandValue(cmd); + wrapper = btn.button.firstChild; + span = this.doc.createElement('span'); + + if (cmd === 'FontSize') { + fontAttr = pNode.style.fontSize; + if (!fontAttr) { + for (i = 0; i < ancestors.length; i++) { + fontAttr = ancestors[i].style.fontSize; + if (fontAttr) { + break; + } + } + } + } + if (fontAttr) { + newAttr = fontAttr; + newAttr = newAttr.replace(/'/g, ''); + span.appendChild(this.doc.createTextNode(newAttr)); + wrapper.replaceChild(span, wrapper.firstChild); + } + if (!span.hasChildNodes()) { + defaultAttr = (cmd === 'FontSize') ? this.config.editorFontSize : this.config.editorFontName; + if (wrapper.hasChildNodes()) { + wrapper.removeChild(wrapper.firstChild); + } + defaultAttr = defaultAttr.replace(/'/g, ''); + span.appendChild(this.doc.createTextNode(defaultAttr)); + wrapper.appendChild(span); + } + this.unselectionElement(span); + break; + case 'LineHeight': + wrapper = btn.button.firstChild; + this.unselectionElement(wrapper.firstChild); + break; + default : + if (!this.doc.queryCommandSupported(cmd)) { + continue; + } + state = this.doc.queryCommandState(cmd); + if (state === null) { + continue; + } + + if (GB.browser.msie && state === false && alignment[cmd]) { + el = pNode; + while (el && el.nodeName.toLowerCase() !== 'body') { + if (GB.lineHeightBlockTags[el.nodeName.toLowerCase()]) { + css = this.getCssValue(el); + if (css) { + for (j = 0; j < css.length; j++) { + if (css[j].name.toLowerCase() === 'text-align' && css[j].value === alignment[cmd]) { + state = true; + break; + } + } + } + } + el = el.parentNode; + } + } + + if (state) { + btn.checked = true; + this.toolbarButtonChecked(btn); + if (btn.type === 'combo' && btn.name === btn.next.node) { + btn.next.active = true; + this.setToolbarBgPosition(btn.next.button, + (~(btn.next.width) + 1) + 'px ' + (~(((btn.next.pos + 1) * btn.next.height)) + 1) + 'px'); + } + } else { + this.toolbarButtonUnchecked(btn); + btn.checked = false; + if (btn.next) { + btn.next.active = false; + if (btn.type === 'combo' && btn.name === btn.next.node) { + this.toolbarButtonUnchecked(btn.next); + } + } + } + + } + } + }, + + createButton : function (name, attr, prev) { + var self = this, + elem, icon, btnIcon, iconPos, method, cmd, check, type, node, btnHeight, btnWidth, text, + span, obj, btnClass, comboOut; + + method = attr.getElementsByTagName('Execution')[0].getAttribute('method'); + cmd = attr.getElementsByTagName('Execution')[0].getAttribute('value'); + check = attr.getAttribute('check'); + type = attr.getAttribute('type'); + node = attr.getAttribute('node'); + + btnClass = attr.getAttribute('class'); + btnWidth = attr.getAttribute('width'); + btnHeight = attr.getAttribute('height'); + + elem = document.createElement('div'); + elem.style.width = btnWidth + 'px'; + elem.setAttribute('name', name); + elem.style.height = btnHeight + 'px'; + elem.style.border = '0px solid transparent'; + + icon = attr.getElementsByTagName('Icon')[0]; + btnIcon = document.createElement('div'); + btnIcon.className = icon.getAttribute('class'); + btnIcon.style.marginLeft = icon.getAttribute('margin') || '3px'; + + iconPos = icon.getAttribute('position'); + if (iconPos) { + btnIcon.style.backgroundImage = 'url(' + self.toolbar.icon + ')'; + btnIcon.style.backgroundRepeat = 'no-repeat'; + self.setToolbarBgPosition(btnIcon, (~iconPos + 1) + 'px center'); + } else { + text = icon.getAttribute('alt'); + if (text) { + span = document.createElement('span'); + span.appendChild(document.createTextNode(text)); + btnIcon.appendChild(span); + } + } + + elem.appendChild(btnIcon); + obj = { 'autocheck': check, + 'button': elem, + 'className': btnClass, + 'checked': false, + 'cmd': cmd, + 'colorNode': {}, + 'disabled': false, + 'group': '', + 'height': btnHeight, + 'method': method, + 'name': name, + 'next': null, + 'node': node, + 'num': 0, + 'pos': 0, + 'prev': prev, + 'type': type, + 'width': btnWidth }; + + if (prev) { + prev.next = obj; + } + + elem.attr = obj; + self.toolbar[name] = obj; + + self.addEvent(elem, 'mouseover', function (ev) { + if (!obj.disabled) { + self.toolbarMouseOverUp(obj); + } + self.stopEvent(ev || window.event); + }); + + self.addEvent(elem, 'mousedown', function (ev) { + if (!obj.checked && !obj.disabled) { + self.toolbarButtonChecked(obj); + self.toolbarMouseDownOut(obj, true); + if (obj.prev && obj.prev.type === 'combo' && !obj.prev.checked) { + self.setToolbarBgPosition(obj.prev.button, + '0 ' + (~((self.getToolbarBgPosition(obj.prev.button) + 1) * obj.prev.height) + 1) + 'px'); + } + } + if (obj.next) { + obj.next.button.style.visibility = 'hidden'; + obj.next.button.style.visibility = 'visible'; + } + self.stopEvent(ev || window.event); + }); + + self.addEvent(elem, 'click', function (ev) { + if (obj.disabled) { + return; + } + switch (obj.method) { + case 'doCmd' : + self.backupRange(); + self.doCmd(obj.cmd, null); + break; + case 'windowOpen' : + self.windowOpen(obj.cmd); + break; + case 'showPulldown' : + if (obj.checked) { + obj.checked = false; + self.boxHideAll(); + self.toolbarButtonUnchecked(obj); + return; + } + obj.checked = true; + self.showPulldown(obj.cmd, obj.button); + self.toolbarButtonChecked(obj); + self.toolbarMouseDownOut(obj, true); + break; + default : + alert('지원하지 않는 명령입니다.'); + } + self.stopEvent(ev || window.event); + }); + + comboOut = function (combo, startPos) { + self.setToolbarBgPosition(combo.button, + startPos + 'px ' + (~(((self.getToolbarBgPosition(combo.button) + (combo.checked ? 2 : 1)) * combo.height)) + 1) + 'px'); + }; + + self.addEvent(elem, 'mouseout', function () { + if (!obj.checked) { + if (obj.type === 'combo') { + if (obj.next) { + if (!obj.next.checked) { + self.toolbarButtonUnchecked(obj.next); + self.toolbarMouseDownOut(obj.next, false); + } else { + return; + } + } + } + if (obj.type === 'combobox' && obj.prev.checked) { + self.setToolbarBgPosition(obj.button, + (~(obj.width) + 1) + 'px ' + (~(((obj.pos + 1) * obj.height)) + 1) + 'px'); + return; + } + self.toolbarButtonUnchecked(obj); + self.toolbarMouseDownOut(obj, false); + } else { + if (obj.node && obj.node === obj.prev.name) { + if (!obj.prev.checked) { + self.setToolbarBgPosition(obj.prev.button, + '0 ' + (~((self.getToolbarBgPosition(obj.prev.button) + 1) * obj.prev.height) + 1) + 'px'); + } + comboOut(obj, 0); + } + } + }); + + return obj; + }, + + showToolbar : function (toolbar, toolbarWrapper) { + var self = this, + i, j, grpName, btn, btnLen, prevObj, attr, btnName, btnObj = null, btnNum, spacer, + currentColor, fullscreen, child, len, + toolbarIcon = toolbar.getElementsByTagName('Image').item(0).getAttribute('file'), + tmpArr = toolbarIcon.split(/\./), + group = toolbar.getElementsByTagName('Group'), + grpNum = group.length, + appendSpaceBlock = function (pNode) { + var split = document.createElement('div'); + split.className = 'cheditor-tb-split'; + pNode.appendChild(split); + }, + onClickEventHandler = function () { + if (self.setFullScreenMode) { + this.className = 'cheditor-tb-fullscreen'; + this.setAttribute('title', '전체 화면'); + } else { + this.className = 'cheditor-tb-fullscreen-actual'; + this.setAttribute('title', '이전 크기로 복원'); + } + self.fullScreenMode(); + }; + + self.toolbar.icon = self.config.iconPath + toolbarIcon; + self.toolbar.iconDisable = self.config.iconPath + tmpArr[0] + '-disable' + '.' + tmpArr[1]; + toolbarWrapper.className = 'cheditor-tb-wrapper'; + + fullscreen = document.createElement('span'); + if (self.config.useFullScreen === true) { + fullscreen.appendChild(document.createTextNode('\u00a0')); + fullscreen.className = 'cheditor-tb-fullscreen'; + fullscreen.setAttribute('title', '전체 화면'); + (function () { + fullscreen.onclick = onClickEventHandler; + })(); + } else { + fullscreen.clsaaName = 'cheditor-tb-fullscreen-disable'; + } + toolbarWrapper.appendChild(fullscreen); + + for (i = 0; i < grpNum; i++) { + grpName = group[i].getAttribute('name'); + if (grpName === 'Split') { + appendSpaceBlock(toolbarWrapper); + continue; + } + + btn = group[i].getElementsByTagName('Button'); + btnLen = btn.length; + btnNum = 0; btnObj = null; + + for (j = 0; j < btnLen; j++) { + attr = btn[j].getElementsByTagName('Attribute')[0]; + btnName = btn[j].getAttribute('name'); + if (!attr.getAttribute('node') && self.config['use' + btnName] !== true) { + continue; + } + if (attr.getAttribute('type') === 'combobox' && self.config['use' + attr.getAttribute('node')] !== true) { + continue; + } + + btnObj = self.createButton(btnName, attr, btnObj); + self.toolbar[btnObj.name].num = btnNum++; + self.toolbar[btnObj.name].group = grpName; + + if (btn[j].getAttribute('tooltip') !== null) { + btnObj.button.setAttribute('title', btn[j].getAttribute('tooltip')); + } + + if (btnObj.name === 'ForeColor' || btnObj.name === 'BackColor') { + currentColor = document.createElement('div'); + currentColor.className = 'cheditor-tb-color-btn'; + currentColor.style.backgroundColor = attr.getAttribute('default'); + btnObj.button.appendChild(currentColor); + } + toolbarWrapper.appendChild(btnObj.button); + } + + if (btnObj === null) { + continue; + } + + prevObj = btnObj.prev; + + if (!prevObj) { + btnObj.button.className = btnObj.className; + if (btnObj.className === 'cheditor-tb-bg') { + btnObj.className = btnObj.className + '-single'; + btnObj.button.className = btnObj.className; + } + btnObj.pos = self.getToolbarBgPosition(btnObj.button); + } else { + btnObj.className = btnObj.className + '-last'; + btnObj.button.className = btnObj.className; + btnObj.pos = self.getToolbarBgPosition(btnObj.button); + while (prevObj) { + prevObj.button.className = prevObj.className; + prevObj.pos = self.getToolbarBgPosition(prevObj.button); + btnObj = prevObj; + prevObj = prevObj.prev; + } + btnObj.className = btnObj.className + '-first'; + btnObj.button.className = btnObj.className; + btnObj.pos = self.getToolbarBgPosition(btnObj.button); + } + spacer = document.createElement('div'); + spacer.className = 'cheditor-tb-button-spacer'; + toolbarWrapper.appendChild(spacer); + } + + appendSpaceBlock(toolbarWrapper); + + if (GB.browser.msie) { + child = toolbarWrapper.getElementsByTagName('div'); + len = child.length; + for (i = 0; i < len; i++) { + self.unselectionElement(child[i]); + } + self.unselectionElement(toolbarWrapper); + } else { + self.unselectionElement(toolbarWrapper); + } + }, + + unselectionElement : function (elem) { + if (!elem || elem.nodeType !== GB.node.element) { + return; + } + if (GB.browser.msie) { + elem.setAttribute('unselectable', 'on'); + elem.setAttribute('contentEditable', 'false'); + } else { + elem.onselectstart = new Function('return false'); + } + }, + + createEditorElement : function (container, toolbar) { + var child = container.firstChild, + self = this, + i, id, tab, tabId, editArea, done = false, frameEl = false, tryScroll, textContent, node, + + onClickEventHandler = function () { + self.switchEditorMode(this.getAttribute('mode')); + }, + onMouseDownEventHandler = function (evt) { + self.resizeStart(evt); + }, + modeOnMouseDownEventHandler = function (evt) { + self.backupRange(); + self.stopEvent(evt); + }, + + pNode = self.cheditor.textarea.parentNode, + nNode = self.cheditor.textarea.nextSibling; + + if (!child) { + return; + } + + do { + id = child.getAttribute('id'); + switch (id) { + case 'toolbar' : + self.showToolbar(toolbar, child); + self.cheditor.toolbarWrapper = child; + break; + case 'viewMode' : + self.cheditor[id] = child; + self.cheditor.mode = 'rich'; + + if (child.hasChildNodes()) { + tab = child.childNodes; + self.cheditor.modetab = {}; + for (i = 0; i < tab.length; i++) { + tabId = tab[i].getAttribute('id'); + if (!tabId) { + continue; + } + if ((tabId === 'code' && self.config.useSource === false) || + (tabId === 'preview' && self.config.usePreview === false)) { + tab[i].style.display = 'none'; + tab[i].removeAttribute('id'); + continue; + } + + tab[i].setAttribute('mode', tabId); + tab[i].onclick = onClickEventHandler; + tab[i].onmousedown = modeOnMouseDownEventHandler; + tab[i].removeAttribute('id'); + self.cheditor.modetab[tabId] = tab[i]; + self.unselectionElement(tab[i]); + } + } + break; + case 'editWrapper' : + node = child.firstChild; + while (node) { + if (node.nodeName.toLowerCase() === 'iframe') { + editArea = node; + } else if (node.nodeName.toLowerCase() === 'textarea') { + textContent = node; + } + node = node.nextSibling; + } + + editArea.style.height = self.config.editorHeight; + editArea.style.backgroundColor = this.config.editorBgColor; + + self.cheditor.editArea = editArea; + self.cheditor.editWrapper = child; + self.cheditor.textContent = textContent; + break; + case 'modifyBlock' : + self.cheditor.editBlock = child; + break; + case 'tagPath' : + if (self.config.showTagPath) { + self.cheditor.tagPath = child.firstChild; + child.style.display = 'block'; + } + break; + case 'resizeBar' : + self.cheditor.resizeBar = child; + child.onmousedown = onMouseDownEventHandler; + self.unselectionElement(child); + break; + default : break; + } + child.removeAttribute('id'); + child = child.nextSibling; + } while (child); + + if (!nNode) { + pNode.appendChild(container); + } else { + pNode.insertBefore(container, nNode); + } + + function ready() { + if (done) { + return; + } + done = true; + } + + if (GB.browser.msie) { + frameEl = window.frameElement !== null; + if (document.documentElement.doScroll && !frameEl) { + tryScroll = function () { + if (done) { + return; + } + try { + document.documentElement.doScroll('left'); + ready(); + } catch (e) { + setTimeout(tryScroll, 10); + } + }; + tryScroll(); + } + self.addEvent(document, 'readystatechange', function () { + if (document.readyState === 'complete') { + ready(); + } + }); + } else { + self.addEvent(document, 'DOMContentLoaded', function () { + ready(); + }); + } + + container.style.width = self.config.editorWidth; + self.cheditor.container = container; + }, + + loadTemplate : function (xmlDoc) { + var self = this, + tmpl = xmlDoc.getElementsByTagName('Template').item(0), + toolbar = tmpl.getElementsByTagName('Toolbar').item(0), + cdata = tmpl.getElementsByTagName('Container').item(0).getElementsByTagName('Html').item(0), + html = self.getCDATASection(cdata), + tmpDiv = document.createElement('div'), + container, popupWindow, modalFrame, dragHandle; + + if (!(tmpl.getElementsByTagName('Image').item(0).getAttribute('file'))) { + throw '툴바 아이콘 이미지 파일 이름이 정의되지 않았습니다.'; + } + + tmpDiv.innerHTML = html; + + container = tmpDiv.firstChild; + self.createEditorElement(container, toolbar); + + cdata = tmpl.getElementsByTagName('PopupWindow').item(0).getElementsByTagName('Html').item(0); + html = self.getCDATASection(cdata); + tmpDiv.innerHTML = html; + + popupWindow = tmpDiv.firstChild; + self.cheditor.popupElem = popupWindow; + + dragHandle = popupWindow.firstChild; + self.cheditor.dragHandle = dragHandle; + self.cheditor.popupTitle = dragHandle.getElementsByTagName('label')[0]; + self.cheditor.popupFrameWrapper = dragHandle.nextSibling; + + container.appendChild(popupWindow); + + modalFrame = document.createElement('div'); + modalFrame.className = 'cheditor-modalPopupTransparent'; + self.cheditor.modalBackground = modalFrame; + self.cheditor.modalBackground.id = 'popupModalBackground'; + self.cheditor.modalBackground.className = 'cheditor-popupModalBackground'; + container.parentNode.insertBefore(modalFrame, container); + + self.cheditor.htmlEditable = document.createElement('iframe'); + self.cheditor.htmlEditable.style.display = 'none'; + self.cheditor.htmlEditable.style.width = '1px'; + self.cheditor.htmlEditable.style.height = '1px'; + self.cheditor.htmlEditable.style.visibility = 'hidden'; + container.appendChild(self.cheditor.htmlEditable); + }, + + imageEvent : function (img, action) { + var self = this, + onMouseUpEventHandler = function () { + self.cheditor.editBlock.style.display = 'block'; + self.modifyImage(this); + }, + onClickEventHandler = function () { + self.cheditor.editBlock.style.display = 'block'; + self.modifyImage(this); + }; + + if (GB.browser.msie) { + if (!action) { + img.onmouseup = null; + return; + } + (function () { + img.onmouseup = onMouseUpEventHandler; + })(); + } else { + if (!action) { + self.removeEvent(img, 'click', onClickEventHandler); + return; + } + this.addEvent(img, 'click', onClickEventHandler); + } + }, + + setImageEvent : function (action) { + var images = this.doc.images, i, + len = images.length; + + for (i = 0; i < len; i++) { + if (/icons\/em\//.test(images[i].src)) { + continue; + } + this.imageEvent(images[i], action); + } + }, + + run : function () { + var self = this, + showEditor = function () { + var grayImage = null; + + if (!self.resetDoc()) { + return; + } + self.editAreaFocus(); + self.setEditorEvent(); + + if (GB.browser.msie && GB.browser.version > 8 || GB.browser.a) { + grayImage = new Image(); + grayImage.onload = function () { + self.cheditor.toolbarGrayscale = self.makeToolbarGrayscale(this); + self.toolbarUpdate(); + }; + grayImage.src = self.toolbar.icon; + grayImage.style.width = '750px'; grayImage.style.height = '16px'; + } else { + self.cheditor.toolbarGrayscale = null; + self.toolbarUpdate(); + } + self.setImageEvent(true); + self.removeEvent(document, self.cheditor.id, showEditor); + }; + + try { + this.setFolderPath(); + this.checkInputForm(); + } + catch (e) { + alert(e.toString()); + return; + } + + self.setDefaultCss({css: 'ui.css', doc: window.document}); + + if (this.W3CRange) { + this.addEvent(document, this.cheditor.id, showEditor); + } else { + document.documentElement.loadEvent = 0; + document.documentElement.attachEvent('onpropertychange', function (evt) { + if (evt.propertyName === 'loadEvent') { + showEditor(); + } + }); + } + + this.initTemplate(); + }, + + fullScreenMode : function () { + var self = this, + container = self.cheditor.container, + windowSize, height, + child = container.firstChild, + except = 0, + editorHeight = parseInt(self.config.editorHeight, 10), + + containerReSize = function () { + windowSize = self.getWindowSize(); + container.style.width = windowSize.width + 'px'; + if (self.cheditor.mode === 'code') { + self.resizeTextContent(); + height = (windowSize.height - except - 6 - parseInt(self.cheditor.textContent.getAttribute('xbar-height'), 10)); + self.cheditor.textContent.style.height = height + 'px'; + } + self.cheditor.editArea.style.height = (windowSize.height - except - 6) + 'px'; + }, + onMouseDownEventHandler = function (evt) { + self.resizeStart(evt); + }; + + self.editAreaFocus(); + self.boxHideAll(); + self.cheditor.editArea.style.visibility = 'hidden'; + + if (!self.setFullScreenMode) { + container.className = 'cheditor-container-fullscreen'; + + if (GB.browser.msie && GB.browser.version < 7) { + self.cheditor.fullScreenFlag = document.createElement('span'); + self.cheditor.fullScreenFlag.style.display = 'none'; + container.parentNode.insertBefore(self.cheditor.fullScreenFlag, container); + document.body.insertBefore(container, document.body.firstChild); + } + + while (child) { + if (child.className !== 'cheditor-editarea-wrapper' && + child.className !== 'cheditor-popup-window' && + child.className !== '') { + except += child.offsetHeight; + } + child = child.nextSibling; + } + + (function () { + window.onresize = containerReSize; + })(); + + containerReSize(); + self.cheditor.resizeBar.onmousedown = null; + self.cheditor.resizeBar.className = 'cheditor-resizebar-off'; + } else { + window.onresize = null; + container.removeAttribute('style'); + container.className = 'cheditor-container'; + container.style.width = self.config.editorWidth; + + if (self.cheditor.mode === 'code') { + height = editorHeight - parseInt(self.cheditor.textContent.getAttribute('xbar-height'), 10); + self.cheditor.textContent.style.height = height + 'px'; + } else { + self.cheditor.editArea.style.height = editorHeight + 'px'; + } + + (function () { + self.cheditor.resizeBar.onmousedown = onMouseDownEventHandler; + })(); + self.cheditor.resizeBar.className = 'cheditor-resizebar'; + + if (GB.browser.msie && GB.browser.version < 7) { + self.cheditor.fullScreenFlag.parentNode.replaceChild(container, self.cheditor.fullScreenFlag); + } + } + + self.cheditor.editArea.style.visibility = 'visible'; + self.setFullScreenMode = !(self.setFullScreenMode); + self.editAreaFocus(); + }, + + showPulldown : function (cmd, btn) { + switch (cmd) { + case 'FontName' : + this.showFontTypeMenu(btn); + break; + case 'FontSize' : + this.showFontSizeMenu(btn); + break; + case 'FormatBlock' : + this.showFormatBlockMenu(btn); + break; + case 'ForeColor' : + case 'BackColor' : + this.showColorMenu(btn); + break; + case 'TextBlock' : + this.showTextBlockMenu(btn); + break; + case 'LineHeight' : + this.showLineHeightMenu(btn); + break; + case 'OrderedList' : + case 'UnOrderedList' : + this.showOrderedListMenu(btn); + } + }, + + setPulldownClassName : function (labels, pNode) { + var i = 0, label; + for (; i < labels.length; i++) { + label = labels[i]; + if (label.getAttribute('name') === pNode.firstChild.firstChild.firstChild.nodeValue) { + label.parentNode.style.backgroundImage = 'url(' + this.config.editorPath + 'icons/checked.png)'; + label.parentNode.style.backgroundPosition = '0 center'; + label.parentNode.style.backgroundRepeat = 'no-repeat'; + } else { + label.parentNode.style.backgroundImage = ''; + } + label.parentNode.className = 'cheditor-pulldown-mouseout'; + } + }, + + showOrderedListMenu : function (pNode) { + var self = this, + menu = pNode.getAttribute('name'), + elem = self.pulldown[menu]; + + (function () { + if (!elem) { + var cmd = (menu === 'UnOrderedListCombo') ? 'InsertUnOrderedList' : 'InsertOrderedList', + outputHtml = document.createElement('div'), + onClickEventHandler = function () { + self.doCmdPopup(cmd, this.id, self.toolbar[menu].prev.checked); + }, + onMouseOverEventHandler = function () { + self.pulldownMouseOver(this); + }, + onMouseOutEventHandler = function () { + self.pulldownMouseOut(this); + }, + list = (cmd === 'InsertUnOrderedList') ? GB.listStyle.unOrdered : GB.listStyle.ordered, + i, div, label, li, ol; + + for (i in list) { + if (list.hasOwnProperty(i)) { + div = document.createElement('div'); + label = document.createElement('label'); + div.id = i; + + (function () { + div.onclick = onClickEventHandler; + div.onmouseover = onMouseOverEventHandler; + div.onmouseout = onMouseOutEventHandler; + })(); + + self.pulldownMouseOut(div); + + label.style.fontFamily = 'verdana'; + label.style.textAlign = 'center'; + label.style.width = '15px'; + label.setAttribute('name', i); + + li = document.createElement('li'); + li.appendChild(document.createTextNode(list[i])); + + ol = document.createElement('ul'); + ol.style.width = '90px'; + ol.style.padding = '0 15px'; + ol.style.margin = '0px'; + ol.style.listStyleType = i; + ol.style.cursor = 'default'; + ol.style.textAlign = 'left'; + ol.appendChild(li); + label.appendChild(ol); + div.appendChild(label); + outputHtml.appendChild(div); + } + } + self.createWindow(110, outputHtml); + self.createPulldownFrame(outputHtml, menu); + } + })(); + + self.windowPos(pNode, menu); + self.displayWindow(pNode, menu); + }, + + showColorMenu : function (pNode) { + var menu = pNode.getAttribute('name'), + elem = this.pulldown[menu], + selectedColor = this.colorConvert(pNode.lastChild.style.backgroundColor, 'hex'), + i, len, nodes, node, outputHtml; + + if (!elem) { + outputHtml = this.setColorTable(menu); + this.createWindow(220, outputHtml); + this.createPulldownFrame(outputHtml, menu); + elem = this.pulldown[menu]; + elem.firstChild.className = 'cheditor-pulldown-color-container'; + } + + this.toolbar[menu].colorNode.selectedValue.style.backgroundColor = selectedColor; + this.toolbar[menu].colorNode.colorPicker.hidePicker(); + this.toolbar[menu].colorNode.colorPicker.fromString(selectedColor); + this.toolbar[menu].colorNode.showPicker = false; + + nodes = elem.getElementsByTagName('span'); + len = nodes.length; + + for (i = 0; i < len; i++) { + node = nodes[i]; + node.style.backgroundImage = ''; + if (node.id && node.id.toLowerCase() === selectedColor.toLowerCase()) { + node.style.backgroundImage = 'url("' + this.config.iconPath + '/color_picker_tick.png")'; + node.style.backgroundRepeat = 'no-repeat'; + node.style.backgroundPosition = 'center center'; + + } + } + this.toolbar[menu].colorNode.selectedValue.style.backgroundImage = 'url("' + + this.config.iconPath + '/color_picker_tick.png")'; + this.toolbar[menu].colorNode.selectedValue.style.backgroundRepeat = 'no-repeat'; + this.toolbar[menu].colorNode.selectedValue.style.backgroundPosition = 'center center'; + this.windowPos(pNode, menu); + this.displayWindow(pNode, menu); + }, + + showFontTypeMenu : function (pNode) { + var self = this, + menu = pNode.getAttribute('name'), + elem = self.pulldown[menu]; + + (function () { + if (!elem) { + var fonts = null, type, i, div, label, + outputHtml = self.doc.createElement('div'), + onClickEventHandler = function () { + self.doCmdPopup(menu, this.id); + }, + onMouseOverEventHandler = function () { + self.pulldownMouseOver(this); + }, + onMouseOutEventHandler = function () { + self.pulldownMouseOut(this); + }; + + for (type in GB.fontName) { + if (GB.fontName.hasOwnProperty(type)) { + fonts = GB.fontName[type]; + for (i = 0; i < fonts.length; i++) { + div = self.doc.createElement('div'); + label = self.doc.createElement('label'); + div.id = fonts[i]; + (function () { + div.onclick = onClickEventHandler; + div.onmouseover = onMouseOverEventHandler; + div.onmouseout = onMouseOutEventHandler; + })(); + label.style.fontFamily = fonts[i];//(type !== 'kr') ? fonts[i] : this.config.editorFontName; + label.appendChild(self.doc.createTextNode(fonts[i])); + label.setAttribute('name', fonts[i]); + div.appendChild(label); + outputHtml.appendChild(div); + } + } + } + self.createWindow(155, outputHtml); + self.createPulldownFrame(outputHtml, menu); + elem = self.pulldown[menu]; + } + })(); + + self.setPulldownClassName(elem.firstChild.getElementsByTagName('LABEL'), pNode); + self.windowPos(pNode, menu); + self.displayWindow(pNode, menu); + }, + + showFormatBlockMenu : function (pNode) { + var self = this, + menu = pNode.getAttribute('name'), + elem = self.pulldown[menu]; + + (function () { + if (!elem) { + var para, label, fontSize, div, + outputHtml = document.createElement('div'), + onClickEventHandler = function () { + self.doCmdPopup('FormatBlock', '<' + this.id + '>'); + }, + onMouseOverEventHandler = function () { + self.pulldownMouseOver(this); + }, + onMouseOutEventHandler = function () { + self.pulldownMouseOut(this); + }; + + for (para in GB.formatBlock) { + if (GB.formatBlock.hasOwnProperty(para)) { + div = document.createElement('div'); + div.id = para; + (function () { + div.onclick = onClickEventHandler; + div.onmouseover = onMouseOverEventHandler; + div.onmouseout = onMouseOutEventHandler; + })(); + label = document.createElement('label'); + if (para.match(/H[123456]/)) { + fontSize = {'H1': '2em','H2': '1.5em','H3': '1.17em','H4': '1em','H5': '0.83em','H6': '0.75em'}; + label.style.fontWeight = 'bold'; + label.style.fontSize = fontSize[para]; + label.style.lineHeight = 1.4; + } else if (para === 'ADDRESS') { + label.style.fontStyle = 'italic'; + } + + label.appendChild(document.createTextNode(GB.formatBlock[para])); + div.appendChild(label); + label.setAttribute('name', GB.formatBlock[para]); + outputHtml.appendChild(div); + + } + } + self.createWindow(150, outputHtml); + self.createPulldownFrame(outputHtml, menu); + elem = self.pulldown[menu]; + } + })(); + + self.setPulldownClassName(elem.firstChild.getElementsByTagName('label'), pNode); + self.windowPos(pNode, menu); + self.displayWindow(pNode, menu); + }, + + showFontSizeMenu : function (pNode) { + var self = this, + menu = pNode.getAttribute('name'), + elem = self.pulldown[menu]; + + (function () { + if (!elem) { + var size, div, label, text, i, + value = GB.fontSize[self.config.fontSizeValue], + len = value.length, + outputHtml = document.createElement('div'), + onClickEventHandler = function (e) { + self.stopEvent(e); + self.doCmdPopup(menu, this.id); + }, + onMouseOverEventHandler = function () { + self.pulldownMouseOver(this); + }, + onMouseOutEventHandler = function () { + self.pulldownMouseOut(this); + }; + + for (i = 0; i < len; i++) { + size = value[i]; + div = document.createElement('div'); + label = document.createElement('label'); + text = size > 48 ? '가' : (size > 28 ? '가나다' : '가나다라'); + size = size + self.config.fontSizeValue; + div.id = size; + (function () { + div.onclick = onClickEventHandler; + div.onmouseover = onMouseOverEventHandler; + div.onmouseout = onMouseOutEventHandler; + })(); + div.style.fontSize = size; + label.style.fontFamily = self.config.editorFontName; + label.setAttribute('name', size); + label.appendChild(document.createTextNode(text + '(' + size + ')')); + div.appendChild(label); + outputHtml.appendChild(div); + } + self.createWindow(350, outputHtml); + outputHtml.style.height = '300px'; + outputHtml.style.overflow = 'auto'; + self.createPulldownFrame(outputHtml, menu); + elem = self.pulldown[menu]; + } + })(); + + self.setPulldownClassName(elem.firstChild.getElementsByTagName('LABEL'), pNode); + self.windowPos(pNode, menu); + self.displayWindow(pNode, menu); + }, + + showLineHeightMenu : function (pNode) { + var self = this, + menu = pNode.getAttribute('name'), + elem = self.pulldown[menu]; + + (function () { + if (!elem) { + var i, div, label, text, + outputHtml = document.createElement('div'), + onClickEventHandler = function () { + self.doCmdPopup('LineHeight', this.id); + }, + onMouseOverEventHandler = function () { + self.pulldownMouseOver(this); + }, + onMouseOutEventHandler = function () { + self.pulldownMouseOut(this); + }; + + for (i in GB.lineHeight) { + if (!(GB.lineHeight.hasOwnProperty(i))) { + continue; + } + if (!GB.lineHeight[i]) { + break; + } + div = document.createElement('div'); + label = document.createElement('label'); + text = i; + + div.id = GB.lineHeight[i]; + (function () { + div.onclick = onClickEventHandler; + div.onmouseover = onMouseOverEventHandler; + div.onmouseout = onMouseOutEventHandler; + })(); + + label.style.fontFamily = self.config.editorFontName; + label.setAttribute('name', GB.lineHeight[i]); + label.appendChild(document.createTextNode(text)); + div.appendChild(label); + outputHtml.appendChild(div); + } + self.createWindow(100, outputHtml); + self.createPulldownFrame(outputHtml, menu); + elem = self.pulldown[menu]; + } + })(); + + self.setPulldownClassName(elem.firstChild.getElementsByTagName('LABEL'), pNode); + self.windowPos(pNode, menu); + self.displayWindow(pNode, menu); + }, + + showTextBlockMenu : function (pNode) { + var self = this, + menu = pNode.getAttribute('name'), + elem = self.pulldown[menu]; + + (function () { + if (!elem) { + var i, wrapper, div, label, + outputHtml = document.createElement('div'), + onClickEventHandler = function () { + self.boxStyle(this); + }, + onMouseOverEventHandler = function () { + this.className = 'cheditor-pulldown-textblock-over'; + }, + onMouseOutEventHandler = function () { + this.className = 'cheditor-pulldown-textblock-out'; + }, + quote = GB.textBlock; + + for (i = 0; i < quote.length; i++) { + wrapper = document.createElement('div'); + div = document.createElement('div'); + (function () { + div.onclick = onClickEventHandler; + wrapper.onmouseover = onMouseOverEventHandler; + wrapper.onmouseout = onMouseOutEventHandler; + })(); + wrapper.className = 'cheditor-pulldown-textblock-out'; + div.id = i; + div.style.border = quote[i][0]; + div.style.backgroundColor = quote[i][1]; + div.style.fontFamily = self.config.editorFontName; + + label = document.createElement('label'); + label.appendChild(document.createTextNode('가나다라 ABC')); + div.appendChild(label); + wrapper.appendChild(div); + outputHtml.appendChild(wrapper); + } + self.createWindow(160, outputHtml); + self.createPulldownFrame(outputHtml, menu); + elem = self.pulldown[menu]; + elem.firstChild.className = 'cheditor-pulldown-textblock-container'; + } + })(); + + self.windowPos(pNode, menu); + self.displayWindow(pNode, menu); + }, + + createPulldownFrame : function (contents, id) { + var div = document.createElement('div'); + div.className = 'cheditor-pulldown-frame'; + div.appendChild(contents); + this.pulldown[id] = div; + this.cheditor.container.firstChild.appendChild(div); + }, + + setDefaultCss : function (ar) { + var cssFile, head, found = false, children, i, href, css; + + ar = ar || {css: 'editarea.css', doc: this.doc}; + cssFile = this.config.cssPath + ar.css; + head = ar.doc.getElementsByTagName('head')[0]; + + if (this.undefined(head)) { + return; + } + + if (head.hasChildNodes()) { + children = head.childNodes; + for (i = 0; i < children.length; i++) { + if (children[i].nodeName.toLowerCase() === 'link') { + href = children[i].getAttribute('href'); + if (href && href === cssFile) { + found = true; + break; + } + } + } + } + + if (!found) { + css = head.appendChild(ar.doc.createElement('link')); + css.setAttribute('type', 'text/css'); + css.setAttribute('rel', 'stylesheet'); + css.setAttribute('media', 'all'); + css.setAttribute('href', this.config.cssPath + ar.css); + } + }, + + setEditorEvent : function () { + var self = this, + onKeyDownEventHandler = function (evt) { + if (self.cheditor.mode === 'preview') { + self.stopEvent(evt); + return; + } + self.doOnKeyDown(evt); + }, + onKeyPressEventHandler = function (evt) { + if (self.cheditor.mode === 'preview') { + self.stopEvent(evt); + return; + } + self.doOnKeyPress(evt); + }, + onKeyUpEventHandler = function (evt) { + if (self.cheditor.mode === 'preview') { + self.stopEvent(evt); + return; + } + self.doOnKeyUp(evt); + }, + onMouseUpEventHandler = function (evt) { + if (self.cheditor.mode === 'rich') { + if (evt.clientX <= self.doc.body.offsetWidth) { + self.doEditorEvent(evt); + } else { + self.restoreRange(); + } + return; + } + if (self.cheditor.mode === 'preview') { + self.stopEvent(evt); + } + }, + onMouseDownEventHandler = function (evt) { + if (self.cheditor.mode === 'rich') { + if (evt.clientX <= self.doc.body.offsetWidth) { + // self.clearSelection(); + } else { + self.backupRange(); + } + self.boxHideAll(); + return; + } + if (self.cheditor.mode === 'preview') { + self.stopEvent(evt); + } + }; + + (function () { + self.addEvent(self.doc, 'keydown', onKeyDownEventHandler); + self.addEvent(self.doc, 'keypress', onKeyPressEventHandler); + self.addEvent(self.doc, 'keyup', onKeyUpEventHandler); + self.addEvent(self.doc, 'mouseup', onMouseUpEventHandler); + self.addEvent(self.doc, 'mousedown', onMouseDownEventHandler); + })(); + }, + + addEvent : function (evTarget, evType, evHandler) { + if (evTarget.addEventListener) { + evTarget.addEventListener(evType, evHandler, false); + } else { + evTarget.attachEvent('on' + evType, evHandler); + } + }, + + removeEvent : function (elem, ev, func) { + if (elem.removeEventListener) { + elem.removeEventListener(ev, func, false); + } else { + elem.detachEvent('on' + ev, func); + } + }, + + stopEvent : function (ev) { + if (ev && ev.preventDefault) { + ev.preventDefault(); + ev.stopPropagation(); + } else { + ev = ev || window.event; + ev.cancelBubble = true; + ev.returnValue = false; + } + }, + + toolbarButtonOut : function (elemButton, nTop) { + elemButton.style.top = -nTop + 'px'; + }, + + toolbarButtonOver : function (elemButton) { + var nTop = elemButton.style.top.substring(0, elemButton.style.top.length - 2); + elemButton.style.top = nTop - 22 + 'px'; + }, + + getElement : function (elem, tag) { + if (!elem || !tag) { + return null; + } + while (elem && elem.nodeName.toLowerCase() !== tag.toLowerCase()) { + if (elem.nodeName.toLowerCase() === 'body') { + break; + } + elem = elem.parentNode; + } + return elem; + }, + + hyperLink : function (href, target, title) { + var self = this, + links = null, i, + createLinks = function () { + var range = self.restoreRange(), + selectedLinks = [], + linkRange = self.createRange(), selection = null, container = null, k; + + self.backupRange(range); + + if (self.W3CRange) { + self.doc.execCommand("CreateLink", false, href); + selection = self.getSelection(); + + for (i = 0; i < selection.rangeCount; ++i) { + range = selection.getRangeAt(i); + container = range.commonAncestorContainer; + + if (self.getSelectionType(range) === GB.selection.text) { + container = container.parentNode; + } + + if (container.nodeName.toLowerCase() === 'a') { + selectedLinks.push(container); + } else { + links = container.getElementsByTagName('a'); + for (k = 0; k < links.length; ++k) { + linkRange.selectNodeContents(links[k]); + if (linkRange.compareBoundaryPoints(range.END_TO_START, range) < 1 && + linkRange.compareBoundaryPoints(range.START_TO_END, range) > -1) + { + selectedLinks.push(links[k]); + } + } + } + } + linkRange.detach(); + } else { + range = self.doc.selection.createRange(); + range.execCommand("UnLink", false); + range.execCommand("CreateLink", false, href); + + switch (self.getSelectionType(range)) { + case GB.selection.text : + container = range.parentElement(); + break; + case GB.selection.element : + container = range.item(0).parentNode; + break; + default : return null; + } + + if (container.nodeName.toLowerCase() === 'a') { + selectedLinks.push(container); + } else { + links = container.getElementsByTagName('a'); + for (i = 0; i < links.length; ++i) { + linkRange.moveToElementText(links[i]); + if (linkRange.compareEndPoints("StartToEnd", range) > -1 && + linkRange.compareEndPoints("EndToStart", range) < 1) + { + selectedLinks.push(links[i]); + } + } + } + } + return selectedLinks; + }; + + this.editArea.focus(); + links = createLinks(); + if (links) { + for (i = 0; i < links.length; ++i) { + if (target) { + links[i].setAttribute("target", target); + } + if (title) { + links[i].setAttribute("title", title); + } + } + } + }, + + getOffsetBox : function (el) { + var box = el.getBoundingClientRect(), + doc = this.doc.documentElement, + body = this.doc.body, + scrollTop = doc.scrollTop || body.scrollTop, + scrollLeft = doc.scrollLeft || body.scrollLeft, + clientTop = doc.clientTop || body.clientTop || 0, + clientLeft = doc.clientLeft || body.clientLeft || 0, + top = box.top + scrollTop - clientTop, + left = box.left + scrollLeft - clientLeft; + + return { top: Math.round(top), left: Math.round(left) }; + }, + + makeSpacerElement : function () { + var elem, + para = this.doc.createElement('p'); + + if (GB.browser.msie && GB.browser.version < 11 && GB.browser.version > 8) { + elem = this.doc.createComment(this.cheditor.bogusSpacerName); + } else if (GB.browser.msie_c) { + elem = this.createNbspTextNode(); + } else { + elem = this.doc.createElement('br'); + elem.className = this.cheditor.bogusSpacerName; + } + + para.appendChild(elem); + return para; + }, + + boxStyle : function (el) { + var range, elem, ctx, textRange, frag, pNode, + blockQuote = this.doc.createElement('blockquote'), + para = null; + + this.editAreaFocus(); + range = this.range || this.getRange() + + blockQuote.style.border = GB.textBlock[el.id][0]; + blockQuote.style.backgroundColor = GB.textBlock[el.id][1]; + blockQuote.style.padding = '5px 10px'; + + if (!this.W3CRange) { + ctx = range.htmlText; + blockQuote.innerHTML = ctx || ' '; + range.select(); + this.insertHTML(blockQuote); + textRange = this.getRange(); + elem = range.parentElement(); + textRange.moveToElementText(elem); + textRange.collapse(false); + textRange.select(); + } else { + try { + frag = range.extractContents(); + if (!frag.firstChild) { + para = this.makeSpacerElement(); + blockQuote.appendChild(para); + } else { + blockQuote.appendChild(frag); + } + + range.insertNode(blockQuote); + pNode = blockQuote.parentNode; + + while (pNode && pNode.nodeName.toLowerCase() !== 'body') { + if (pNode.nodeName.toLowerCase() === 'p' || pNode.nodeName.toLowerCase() === 'div') { + pNode.parentNode.insertBefore(blockQuote, pNode.nextSibling); + break; + } + pNode = pNode.parentNode; + } + this.placeCaretAt(para || blockQuote, false); + } catch (ignore) { + // -- + } + } + this.boxHideAll(); + }, + + insertFlash : function (elem) { + var embed = null, pos, str, obj, child, movieHeight, params = [], movieWidth, i, + div = this.doc.createElement('div'); + + this.editAreaFocus(); + this.restoreRange(); + + if (typeof elem === 'string') { + elem = this.trimSpace(elem); + pos = elem.toLowerCase().indexOf('embed'); + + if (pos !== -1) { + str = elem.substr(pos); + pos = str.indexOf('>'); + div.innerHTML = '<' + str.substr(0, pos) + '>'; + embed = div.firstChild; + } else { + div.innerHTML = elem; + obj = div.getElementsByTagName('object')[0]; + + if (obj && obj.hasChildNodes()) { + child = obj.firstChild; + movieWidth = (isNaN(obj.width) !== true) ? obj.width : 320; + movieHeight = (isNaN(obj.height) !== true) ? obj.height : 240; + do { + if ((child.nodeName.toLowerCase() === 'param') && + (!this.undefined(child.name) && !this.undefined(child.value))) { + params.push({key: (child.name === 'movie') ? 'src' : child.name, val: child.value}); + } + child = child.nextSibling; + } while (child); + + if (params.length > 0) { + embed = this.doc.createElement('embed'); + embed.setAttribute('width', movieWidth); + embed.setAttribute('height', movieHeight); + for (i = 0; i < params.length; i++) { + embed.setAttribute(params[i].key, params[i].val); + } + embed.setAttribute('type', 'application/x-shockwave-flash'); + } + } + } + + if (embed) { + if (this.W3CRange) { + this.insertNodeAtSelection(embed); + } else { + this.doCmdPaste(embed.outerHTML); + } + } + } + }, + + insertHtmlPopup : function (elem) { + this.editAreaFocus(); + this.restoreRange(); + + if (!this.W3CRange) { + this.doCmdPaste((this.toType(elem) === 'string') ? elem : elem.outerHTML); + } else { + this.insertNodeAtSelection(elem); + } + this.clearStoredSelections(); + }, + + insertHTML : function (html) { + if (!this.W3CRange) { + this.getRange().pasteHTML((this.toType(html) === 'string') ? html : html.outerHTML); + } else { + this.insertNodeAtSelection(html); + } + }, + + placeCaretAt : function (elem, az) { + var range = this.createRange(), + selection = this.getSelection(); + + if (this.undefined(az)) { + az = false; + } + + if (this.W3CRange) { + selection.removeAllRanges(); + try { + if (elem.lastChild && elem.lastChild.nodeName.toLowerCase() === 'br') { + az = true; + } + range.selectNodeContents(elem); + } catch (e) { + range.selectNode(elem); + } + + range.collapse(az); + + try { + selection.addRange(range); + } catch (e) { + this.placeCaretAt(this.doc.body, az); + } + } else if (elem.nodeType === GB.node.element) { + range.moveToElementText(elem); + range.collapse(az); + range.select(); + } + }, + + selectNodeContents : function (node, pos) { + var collapsed = !this.undefined(pos), + selection = this.getSelection(), + range = this.getRange(); + + if (node.nodeType === GB.node.element) { + range.selectNode(node); + if (collapsed) { + range.collapse(pos); + } + } + selection.removeAllRanges(); + selection.addRange(range); + return range; + }, + + insertNodeAtSelection : function (insertNode) { + var range = this.getRange(), + selection = this.getSelection(), + frag = this.doc.createDocumentFragment(), + lastNode = null, + elem, commonAncestorContainer, startOffset, pNode, tmpWrapper; + + if (!range.collapsed) { + range.deleteContents(); + range = this.getRange(); + } + + commonAncestorContainer = range.commonAncestorContainer; + startOffset = range.startOffset; + pNode = commonAncestorContainer; + + if (pNode.nodeType === GB.node.text) { + pNode = pNode.parentNode; + } + + this.removeBogusSpacer(pNode); + + if (typeof insertNode === 'string') { + tmpWrapper = this.doc.createElement('div'); + tmpWrapper.innerHTML = insertNode; + + elem = tmpWrapper.firstChild; + while (elem) { + lastNode = frag.appendChild(elem); + elem = tmpWrapper.firstChild; + } + } else { + lastNode = frag.appendChild(insertNode); + } + + if (startOffset < 1 && commonAncestorContainer.nodeType === GB.node.text) { + commonAncestorContainer.parentNode.insertBefore(frag, commonAncestorContainer); + } else { + range.insertNode(frag); + } + + if (lastNode) { + range = range.cloneRange(); + range.setStartAfter(lastNode); + selection.removeAllRanges(); + selection.addRange(range); + } + this.toolbarUpdate(); + return lastNode; + }, + + findBogusSpacer : function (elem, all) { + var self = this, result = []; + (function findBogusSpacer(elem) { + var i = 0, node; + for (; i < elem.childNodes.length; i++) { + node = elem.childNodes[i]; + if ((node.nodeType === GB.node.element && node.className === self.cheditor.bogusSpacerName) || + (node.nodeType === GB.node.comment && node.nodeValue === self.cheditor.bogusSpacerName)) { + result.push(node); + } + if (node.nodeType === GB.node.text && node.nodeValue === '\u00a0' && !node.nextSibling) { + result.push(node); + } + if (all) { + findBogusSpacer(node); + } + } + })(elem); + return result; + }, + + removeBogusSpacer : function (elem, removeEmpty, all) { + var remove = this.findBogusSpacer(elem, all), i = 0; + for (; i < remove.length; i++) { + remove[i].parentNode.removeChild(remove[i]); + } + if (removeEmpty && !(elem.hasChildNodes())) { + elem.parentNode.removeChild(elem); + } + }, + + ieGetRangeAt : function (range) { + var self = this, start = {}, end = {}; + + function convert(result, bStart) { + var point = range.duplicate(), + span = self.doc.createElement('span'), + parent = point.parentElement(), + cursor = self.createRange(), + compareStr = bStart ? 'StartToStart' : 'StartToEnd'; + + point.collapse(bStart); + parent.appendChild(span); + cursor.moveToElementText(span); + + while (cursor.compareEndPoints(compareStr, point) > 0 && span.previousSibling) { + parent.insertBefore(span, span.previousSibling); + cursor.moveToElementText(span); + } + + result.container = span.nextSibling || span.previousSibling; + if (result.container === null) { + result.container = span.parentNode; + } + parent.removeChild(span); + } + + convert(start, true); convert(end, false); + return { startContainer: start.container, endContainer: end.container }; + }, + + applyLineHeight : function (opt) { + var range = this.getRange(), + isBlockElement = function (elem) { + return GB.lineHeightBlockTags[elem.toLowerCase()]; + }, + getNextLeaf = function (elem, endLeaf, value) { + while (!elem.nextSibling) { + elem = elem.parentNode; + if (!elem) { + return elem; + } + } + + if (elem === endLeaf) { + return elem; + } + + var leaf = elem.nextSibling; + if (isBlockElement(leaf.nodeName)) { + leaf.style.lineHeight = value; + } + + while (leaf.firstChild) { + leaf = leaf.firstChild; + if (leaf.nodeType !== GB.node.text && isBlockElement(leaf.nodeName)) { + leaf.style.lineHeight = value; + } + } + return leaf; + }, + applyBlockElement = function (elem) { + while (elem) { + if (elem.nodeName.toLowerCase() === "body") { + para = self.doc.createElement("p"); + para.style.lineHeight = opt; + + if (elem.firstChild) { + elem.insertBefore(para, elem.firstChild); + } else { + elem.appendChild(para); + break; + } + + nextNode = para.nextSibling; + while (nextNode) { + if (isBlockElement(nextNode.nodeName)) { + break; + } + para.appendChild(nextNode); + nextNode = para.nextSibling; + } + break; + } + + if (isBlockElement(elem.nodeName)) { + elem.style.lineHeight = opt; + break; + } + elem = elem.parentNode; + } + }, + ieRange, startContainer, endContainer, para, nextNode, startLeaf, endLeaf, nextLeaf; + + if (!this.W3CRange) { + ieRange = this.ieGetRangeAt(range); + startContainer = ieRange.startContainer; + endContainer = ieRange.endContainer; + } else { + startContainer = range.startContainer; + endContainer = range.endContainer; + } + + if (!this.doc.body.hasChildNodes() || !startContainer || !endContainer) { + throw "Object Error"; + } + + if (startContainer && startContainer.nodeName.toLowerCase() === "body") { + startContainer = startContainer.firstChild; + } + + try { + if (startContainer === endContainer) { + applyBlockElement(startContainer); + } else { + startLeaf = startContainer; + while (startLeaf) { + if (startLeaf.nodeName.toLowerCase() === "body" || isBlockElement(startLeaf.nodeName)) { + break; + } + startLeaf = startLeaf.parentNode; + } + + endLeaf = endContainer; + while (endLeaf) { + if (endLeaf.nodeName.toLowerCase() === "body" || isBlockElement(endLeaf.nodeName)) { + break; + } + endLeaf = endLeaf.parentNode; + } + + if (startLeaf === endLeaf) { + if (isBlockElement(startLeaf.nodeName)) { + startLeaf.style.lineHeight = opt; + } else { + para = this.doc.createElement("p"); + para.style.lineHeight = opt; + startLeaf.insertBefore(para, startLeaf.firstChild); + + nextNode = para.nextSibling; + while (nextNode) { + if (isBlockElement(nextNode.nodeName)) { + break; + } + para.appendChild(nextNode); + nextNode = para.nextSibling; + } + } + } else { + applyBlockElement(startLeaf); + while (startLeaf) { + nextLeaf = getNextLeaf(startLeaf, endLeaf, opt); + if (startLeaf === endLeaf) { + break; + } + startLeaf = nextLeaf; + } + } + } + } catch (ignore) { + // -- + } + }, + + doInsertImage : function (imgs, para, insertSpace) { + var range, i, count = 0, imgAttr, img, space, lastNode = null, pNode, div, selection, + len = imgs.length, self = this, + fragment = this.doc.createDocumentFragment(); + + function checkPara(pNode) { + var result = true, text; + if (!pNode.hasChildNodes()) { + return false; + } + self.getNodeTree(pNode, function (node) { + if (!node.node || node === pNode) { + return; + } + if (node.type === GB.node.text) { + text = self.trimSpace(node.node.nodeValue); + if (!text || text === '\u00a0') { + result = false; + } + } else if (node.type === GB.node.element + && (node.name === 'br' && node.node.className === self.cheditor.bogusSpacerName)) { + result = false; + } + }); + return result; + } + + this.editAreaFocus(); + range = this.restoreRange(); + pNode = this.getRangeElement(range); + if (!pNode) { + return; + } + + if (pNode.nodeName.toLowerCase() === 'body') { + pNode = this.doc.createElement('p'); + if (this.W3CRange) { + range.insertNode(pNode); + } else { + range.pasteHTML(pNode.outerHTML); + } + } + + if (para) { + do { + if (GB.lineHeightBlockTags[pNode.nodeName.toLowerCase()]) { + break; + } + pNode = pNode.parentNode; + } while (pNode && pNode.nodeName.toLowerCase() !== 'body'); + } + + for (i in imgs) { + if (!imgs.hasOwnProperty(i) || this.undefined(imgs[i])) { + continue; + } + imgAttr = imgs[i]; + img = this.doc.createElement('img'); + img.setAttribute('src', imgAttr.fileUrl); + + if (this.config.imgSetAttrWidth === 1) { + img.style.width = imgAttr.width; + img.style.height = imgAttr.height; + } else if (this.config.imgSetAttrWidth === -1) { + img.style.width = '100%'; + img.style.height = 'auto'; + } + + if (this.config.imgSetAttrAlt) { + img.setAttribute('alt', imgAttr.alt || imgAttr.origName); + } else { + img.removeAttribute('alt'); + } + + count++; + if (para) { + lastNode = fragment.appendChild(this.doc.createElement('p')); + if (imgAttr.align !== 'left') { + lastNode.style.textAlign = imgAttr.align; + } + lastNode.appendChild(img); + if (insertSpace && count < len) { + space = this.makeSpacerElement(); + fragment.appendChild(space); + } + } else { + lastNode = fragment.appendChild(img); + if (insertSpace && count < len) { + fragment.appendChild(this.doc.createTextNode('\u00a0')); + } + } + this.images.push(imgAttr); + } + + if (lastNode) { + if (para) { + if (pNode.nodeName.toLowerCase() === 'p') { + if (!checkPara(pNode)) { + pNode.parentNode.replaceChild(fragment, pNode); + } else { + pNode.parentNode.insertBefore(fragment, pNode.nextSibling); + } + } else { + if (!this.W3CRange) { + div = this.doc.createElement('div'); + div.appendChild(fragment); + range.pasteHTML(div.innerHTML); + } else { + range.insertNode(fragment); + } + } + this.placeCaretAt(lastNode.nextSibling ? lastNode.nextSibling : lastNode, false); + } else { + if (!this.W3CRange) { + div = this.doc.createElement('div'); + div.appendChild(fragment); + range.pasteHTML(div.innerHTML); + } else { + range.deleteContents(); + range.insertNode(fragment); + range.setStartAfter(lastNode); + range.setEndAfter(lastNode); + selection = this.getSelection(); + selection.removeAllRanges(); + selection.addRange(range); + } + } + this.setImageEvent(true); + } + }, + + showTagSelector : function (on) { + if (this.config.showTagPath !== true) { + return; + } + this.cheditor.tagPath.style.display = on ? 'block' : 'none'; + }, + + getTextContentSelectionPos : function (newline) { + var textContent = this.cheditor.textContent, + start, end, docRange, startRange, endRange, textContentLength, normalizedText; + + if (typeof textContent.selectionStart === 'number') { + start = textContent.selectionStart; + end = textContent.selectionEnd; + } else { + textContentLength = textContent.value.length; + normalizedText = textContent.value.replace(/\r\n/g, '\n'); + docRange = document.selection.createRange(); + startRange = textContent.createTextRange(); + endRange = startRange.duplicate(); + endRange.collapse(false); + startRange.moveToBookmark(docRange.getBookmark()); + + if (startRange.compareEndPoints('StartToEnd', endRange) > -1) { + start = end = textContentLength; + } else { + start = -startRange.moveStart('character', -textContentLength); + if (newline) { + start += normalizedText.slice(0, start).split('\n').length - 1; + } + if (startRange.compareEndPoints('EndToEnd', endRange) > -1) { + end = textContentLength; + } else { + end = -startRange.moveEnd('character', -textContentLength); + if (newline) { + end += normalizedText.slice(0, end).split('\n').length - 1; + } + } + } + } + return { startPos: start, endPos: end }; + }, + + removeEmptyBogusTag : function (content) { + if (/^<(p|div)([^>]+?)?>( |\s+?)<\/(p|div)>$/g.test(this.trimSpace(content))) { + return ''; + } + if (/^]+?)?>$/g.test(content)) { + return ''; + } + return content; + }, + + setTextContentSelection : function (startPos, endPos, content) { + var textContent = this.cheditor.textContent, range, top; + + content = this.removeEmptyBogusTag(content); + + if (!content) { + textContent.focus(); + return; + } + if (startPos === 0 && endPos === 0) { + textContent.value = content; + textContent.focus(); + return; + } + textContent.select(); + if (typeof textContent.setSelectionRange === 'function') { + textContent.value = content; + textContent.setSelectionRange(startPos, startPos); + textContent.focus(); + if (this.browser.msie || this.browser.edge) { + setTimeout(function () { + top = textContent.scrollTop; + if (top > 0) { + textContent.scrollTop = top + textContent.clientHeight / 2; + } + textContent.selectionEnd = endPos; + }, 0); + } else { + textContent.selectionEnd = endPos; + } + } else { + range = document.selection.createRange(); + textContent.value = content; + range.moveEnd('character', endPos - content.length); + range.moveStart('character', startPos); + range.select(); + top = textContent.scrollTop; + if (top > 0) { + textContent.scrollTop = top + textContent.clientHeight / 2; + } + } + }, + + richMode : function () { + var char, collapsed, cursor, endNode, endPos, endRange, outputHTML = null, pNode, pos, range, + scrollTop, selection, startNode, startPos, startRange, textContent = null, textContentLength; + + if (this.cheditor.mode === 'code' && typeof this.resizeTextContent !== 'undefined') { + this.cheditor.textContent.focus(); + textContent = this.makeHtmlContent(); + textContentLength = textContent.length; + + pos = this.getTextContentSelectionPos(true); + startPos = pos.startPos; + endPos = pos.endPos; + + collapsed = startPos === endPos; + cursor = startPos; + + if (textContent.charAt(startPos) === '>') { + startPos++; + collapsed = true; + } else { + while (cursor > -1) { + char = textContent.charAt(cursor); + if (char === '&' + && textContent.charAt(cursor + 1) === 'n' && textContent.charAt(cursor + 2) === 'b' + && textContent.charAt(cursor + 3) === 's' && textContent.charAt(cursor + 4) === 'p' + && textContent.charAt(cursor + 5) === ';') + { + startPos = cursor; + collapsed = endPos < (startPos + 6); + break; + } + if (char === '>') { + break; + } + if (char === '<') { + startPos = cursor; + collapsed = true; + break; + } + cursor--; + } + } + + if (!collapsed) { + cursor = endPos; + if (textContent.charAt(endPos - 1) === '<' || + (textContent.charAt(endPos) === '\n' && cursor === textContentLength - 1)) { + endPos = startPos; + } else { + while (cursor < textContentLength) { + char = textContent.charAt(cursor); + if (char === '<') { + break; + } + if (char === '>') { + endPos = startPos; + break; + } + cursor++; + } + } + } else { + endPos = startPos; + } + + if (startPos > 0 && endPos < textContentLength - 1) { + outputHTML = textContent.substring(0, startPos); + outputHTML += ''; + outputHTML += textContent.substring(startPos, endPos); + outputHTML += ''; + outputHTML += textContent.substring(endPos, textContent.length); + textContent = outputHTML; + } + + this.cheditor.textContent.value = ''; + this.removeEvent(window, 'resize', this.resizeTextContent); + this.putContents(this.convertContentsSpacer(textContent)); + } + + this.range = null; + this.cheditor.textContent.blur(); + this.cheditor.textContent.removeAttribute('start-pos'); + this.cheditor.textContent.removeAttribute('end-pos'); + this.cheditor.textContent.style.display = 'none'; + this.cheditor.toolbarWrapper.style.display = ''; + this.cheditor.toolbarWrapper.className = 'cheditor-tb-wrapper'; + this.cheditor.editArea.style.visibility = 'hidden'; + + if (!this.setFullScreenMode) { + this.cheditor.editArea.style.height = this.config.editorHeight; + } + + this.cheditor.editArea.style.display = 'block'; + this.cheditor.editArea.style.visibility = 'visible'; + this.setDesignMode(true); + this.editAreaFocus(); + + if (outputHTML) { + startNode = this.doc.getElementById('startBogusNode'); + endNode = this.doc.getElementById('endBogusNode'); + if (startNode && endNode) { + scrollTop = 0; + pNode = startNode; + if (pNode) { + while (pNode.offsetParent) { + scrollTop += pNode.offsetTop; + pNode = pNode.offsetParent; + } + scrollTop -= this.getWindowSize(this.doc).height / 2; + } + + if (this.doc.compatMode === 'CSS1Compat') { + this.doc.documentElement.scrollTop = scrollTop; + } else { + this.doc.body.scrollTop = scrollTop; + } + + if (this.W3CRange) { + selection = this.clearSelection(); + range = this.createRange(); + range.setStartAfter(startNode); + range.setEndBefore(endNode); + try { + selection.addRange(range); + } catch (ignore) { + // display: none? + } + } else { + startRange = this.createRange(); + endRange = startRange.duplicate(); + startRange.moveToElementText(startNode); + endRange.moveToElementText(endNode); + startRange.setEndPoint('StartToEnd', startRange); + startRange.setEndPoint('EndToEnd', endRange); + startRange.select(); + } + + pNode = startNode.parentNode; + pNode.removeChild(startNode); + pNode = endNode.parentNode; + pNode.removeChild(endNode); + } + } + + this.setImageEvent(true); + this.toolbarUpdate(); + }, + + editMode : function () { + var self = this, + editorWidth, scrollBarWidth, scrollBarHeight, resize, content = null, borderWidth = 1, borderHeight = 1, + startPos, endPos, startNode, endNode, startEndNode, + editorHeight = this.cheditor.editWrapper.offsetHeight, + textContent = this.cheditor.textContent, + startNodeValue = 'startBogusNode', endNodeValue = 'endBogusNode', + startNodeCommentTag = '', endNodeCommentTag = '', + range = this.restoreRange(); + + if (this.cheditor.mode === 'preview') { + if (textContent.getAttribute('start-pos')) { + startPos = parseInt(textContent.getAttribute('start-pos'), 10); + textContent.removeAttribute('start-pos'); + + if (textContent.getAttribute('end-pos')) { + endPos = parseInt(textContent.getAttribute('end-pos'), 10); + textContent.removeAttribute('end-pos'); + } else { + endPos = startPos; + } + content = textContent.value.replace(/\r\n/g, '\n'); + } else { + this.placeCaretAt(this.doc.body.firstChild || this.doc.body, true); + range = this.getRange(); + } + } + + if (!content) { + startEndNode = this.insertStartEndNode(range); + startNode = this.doc.createComment(startNodeValue); + endNode = this.doc.createComment(endNodeValue); + startEndNode.startNode.parentNode.replaceChild(startNode, startEndNode.startNode); + startEndNode.endNode.parentNode.replaceChild(endNode, startEndNode.endNode); + startEndNode.startNode = startNode; + startEndNode.endNode = endNode; + + content = this.getContents(startEndNode); + + startPos = content.search(startNodeCommentTag); + endPos = content.search(endNodeCommentTag); + endPos -= endNodeCommentTag.length + 2; + content = content.replace(startNodeCommentTag, '').replace(endNodeCommentTag, ''); + + } + + this.resetDocumentBody(); + this.cheditor.editArea.style.display = 'none'; + this.cheditor.toolbarWrapper.className = 'cheditor-tb-wrapper-code'; + this.cheditor.editBlock.style.display = 'none'; + + textContent.value = ''; + textContent.style.lineHeight = '17px'; + textContent.style.width = '100px'; + textContent.style.height = '100px'; + textContent.style.display = 'block'; + + scrollBarWidth = textContent.offsetWidth - 100; + scrollBarHeight = textContent.offsetHeight - 100; + if (this.browser.msie && this.browser.version < 8) { + scrollBarHeight += 2; + } + + textContent.setAttribute('xbar-height', scrollBarHeight.toString()); + textContent.setAttribute('ybar-width', scrollBarWidth.toString()); + + resize = textContent.offsetHeight + (editorHeight - textContent.offsetHeight) - scrollBarHeight - borderHeight; + textContent.style.height = resize + 'px'; + + this.resizeTextContent = function () { + editorWidth = self.cheditor.editWrapper.offsetWidth; + resize = textContent.offsetWidth + (editorWidth - textContent.offsetWidth) - scrollBarWidth - borderWidth; + self.cheditor.textContent.style.width = resize + 'px'; + }; + + (function () { + self.addEvent(window, 'resize', self.resizeTextContent); + self.resizeTextContent(); + })(); + + this.setTextContentSelection(startPos, endPos, content); + this.setDesignMode(false); + }, + + makeHtmlContent : function () { + var content = this.trimSpace(this.cheditor.textContent.value); + content = this.trimZeroSpace(content); + return content || '

 

'; + }, + + resetStatusBar : function () { + if (this.config.showTagPath) { + this.cheditor.tagPath.innerHTML = '<html> <body> '; + } + }, + + previewMode : function () { + var content, oSheet, pos = this.getTextContentSelectionPos(false); + + if (this.cheditor.mode === 'code' && typeof this.resizeTextContent !== 'undefined') { + this.cheditor.textContent.setAttribute('start-pos', pos.startPos.toString()); + this.cheditor.textContent.setAttribute('end-pos', pos.endPos.toString()); + content = this.makeHtmlContent(); + this.cheditor.textContent.blur(); + this.cheditor.textContent.style.display = 'none'; + this.removeEvent(window, 'resize', this.resizeTextContent); + this.putContents(content); + } + + this.clearSelection(); + this.cheditor.editBlock.style.display = 'none'; + this.cheditor.toolbarWrapper.className = 'cheditor-tb-wrapper-preview'; + if (!this.setFullScreenMode) { + this.cheditor.editArea.style.height = this.config.editorHeight; + } + this.cheditor.editArea.style.display = 'block'; + + if (GB.browser.msie && parseInt(GB.browser.version, 10) === 8) { + try { + oSheet = this.doc.styleSheets[0]; + oSheet.addRule('p:before', 'content:"\u200b"'); + } catch (ignore) { + // ignore + } + } + this.setImageEvent(false); + this.setDesignMode(false); + }, + + convertContentsSpacer : function (content) { + var self = this, bogusBr = true, + excepted = '<\/span><\/span>', + reSpacer = new RegExp('<([^>]+)>(' + excepted + ')?(?: |\s+?|\u00a0)(' + excepted + ')?<\/([^>]+)>', 'g'); + + if (GB.browser.msie && GB.browser.msie_bogus === false) { + bogusBr = false; + } + content = content.replace(/\s{2,}|[\r\n\t]+?/gm, ''); + content = content.replace(reSpacer, + function (all, open, excepted_a, excepted_b, close) { + var tagName = self.trimSpace(open.split(' ')[0]).toLowerCase(), rdata = null; + if (GB.lineHeightBlockTags[tagName] || GB.textFormatTags[tagName]) { + rdata = '<' + open + '>' + (excepted_a || ''); + rdata += bogusBr ? '
' : + ''; + rdata += (excepted_b || '') + ''; + } + return rdata || all; + } + ); + return content; + }, + + putContents : function (content) { + if (this.config.fullHTMLSource) { + content = content.substr(content.search(/') + 1); + content = '' + content; + this.doc.open(); + this.doc.write('' + content + ''); + this.doc.close(); + } else { + content = 'remove_this' + content; + this.doc.body.innerHTML = content; + this.doc.body.removeChild(this.doc.body.firstChild); + } + }, + + getImages : function () { + var img = this.doc.body.getElementsByTagName('img'), + imgLength = this.images.length, + imgs = [], i, imgId, j; + + for (i = 0; i < img.length; i++) { + if (img[i].src) { + imgId = img[i].src; + imgId = imgId.slice(imgId.lastIndexOf('/') + 1); + for (j = 0; j < imgLength; j++) { + if (this.images[j].fileName === imgId) { + imgs.push(this.images[j]); + break; + } + } + } + } + return imgs.length > 0 ? imgs : null; + }, + + getElementStyle : function (elem) { + return (window.getComputedStyle) ? this.doc.defaultView.getComputedStyle(elem, null) : elem.currentStyle; + }, + + getElementDefaultDisplay : function (elem) { + return (window.getComputedStyle ? this.doc.defaultView.getComputedStyle(elem, null) : elem.currentStyle).display; + }, + + tabRepeat : function (count) { + var i = 0, tab = ''; + if (count < 1) { + return tab; + } + for (; i < count; i++) { + tab += this.cheditor.tabSpaces; + } + return tab; + }, + + htmlEncode : function (text) { + //text = text.replace(/\n{2,}$/g, '\n'); + //text = text.replace(/&/g, '&'); + text = text.replace(//g, '>'); + text = text.replace(/\u00a0/g, ' '); + //text = text.replace(/]+)> <\/font>/mgi, ''); + //text = text.replace(/\x22/g, '"'); + return text; + }, + + checkDocLinks : function () { + var links = this.doc.links, + len = links.length, + host = location.host, + i, href; + + this.cheditor.links = []; + + for (i = 0; i < len; i++) { + if (!this.config.includeHostname) { + href = links[i].href; + if (href.indexOf(host) !== -1) { + links[i].setAttribute('href', href.substring(href.indexOf(host) + host.length)); + } + } + if (this.config.linkTarget !== '' && this.config.linkTarget !== null) { + if (!(links[i].getAttribute('target'))) { + links[i].setAttribute('target', this.config.linkTarget); + } + } + if (GB.browser.msie) { + this.cheditor.links.push(links[i]); + } + } + }, + + checkDocImages : function () { + var img = this.doc.images, + len = img.length, + host = location.host, + i = 0, imgUrl; + + for (; i < len; i++) { + if (!this.config.includeHostname) { + imgUrl = img[i].src; + if (imgUrl) { + if (imgUrl.indexOf(host) !== -1) { + img[i].src = imgUrl.substring(imgUrl.indexOf(host) + host.length); + } + } + } + if (img[i].style.width) { + img[i].removeAttribute('width'); + } + if (img[i].style.height) { + img[i].removeAttribute('height'); + } + } + }, + + createNbspTextNode : function () { + return this.doc.createTextNode('\u00a0'); + }, + + getNodeTree : function (pNode, callback) { + function Node(node) { + this.node = node; + this.name = node.nodeName.toLowerCase(); + this.type = node.nodeType; + this.parent = node.parentNode; + this.indent = 0; + } + (function recurse(cNode, indent) { + var i, child, + node = new Node(cNode), + children = cNode.childNodes, + len = children.length; + + node.indent = indent; + + for (i = 0; i < len; i++) { + child = children[i]; + if (child) { + recurse(child, indent + 1); + } + } + + if (node.name !== 'body') { + callback(node); + } + })(pNode, -1); + }, + + getContents : function (startEndNode) { + var self = this, + mydoc, indentNodes = [], i, node, msie_c = typeof this.browser.msie_c !== 'undefined', + allowedIndent = this.getContents.caller !== this.getBodyContents, + insertTabSpace = function (indent) { + return msie_c ? self.doc.createComment('Tab Size:' + indent) : + self.doc.createTextNode('\n' + self.tabRepeat(indent)); + }; + + function checkChildNodes(child) { + if (!child) { + return null; + } + if (!startEndNode) { + return child; + } + do { + if (child !== startEndNode.startNode && child !== startEndNode.endNode) { + break; + } + child = child.nextSibling; + } while (child); + + return child; + } + + this.checkDocLinks(); + this.checkDocImages(); + this.getNodeTree(this.doc.body, function (node) { + if (!node.node) { + return; + } + if (self.config.exceptedElements[node.name]) { + node.parent.replaceChild(self.doc.createTextNode(''), node.node); + return; + } + + switch (node.type) { + case GB.node.text : + if (!self.isTextVisible(node.node.nodeValue)) { + node.parent.replaceChild(self.doc.createTextNode(''), node.node); + } + break; + case GB.node.element : + if (node.node.className === self.cheditor.bogusSpacerName) { + if (node.node.firstChild === null) { + if (node.name === 'br') { + node.parent.removeChild(node.node); + if (!checkChildNodes(node.parent.firstChild)) { + node.parent.appendChild(self.createNbspTextNode()); + } + } else { + node.node.appendChild(self.createNbspTextNode()); + } + } else if (!checkChildNodes(node.node.firstChild)) { + node.node.appendChild(self.createNbspTextNode()); + } + node.node.className = ''; + } + if ((node.name === 'p' || node.name === 'div') && !checkChildNodes(node.node.firstChild)) { + node.node.appendChild(self.createNbspTextNode()); + } + if (GB.newLineBeforeTags[node.name] && allowedIndent) { + if (node.node.firstChild && (node.node.firstChild.nodeType === GB.node.element)) { + node.node.insertBefore(insertTabSpace(node.indent + 1), node.node.firstChild); + node.node.appendChild(insertTabSpace(node.indent)); + } + indentNodes.push(node); + } + if (GB.selfClosingTags[node.name]) { + node.node.setAttribute('self-close-tag', '1'); + } + break; + case GB.node.comment : + if (node.node.nodeValue === self.cheditor.bogusSpacerName) { + node.parent.removeChild(node.node); + if (!checkChildNodes(node.parent.firstChild)) { + node.parent.appendChild(self.createNbspTextNode()); + } else if (node.parent.firstChild.nodeName.toLowerCase() === 'br') { + node.parent.replaceChild(self.createNbspTextNode(), node.node.firstChild); + } + } + } + }); + + for (i in indentNodes) { + if (indentNodes.hasOwnProperty(i)) { + node = indentNodes[i]; + node.parent.insertBefore(insertTabSpace(node.indent), node.node); + + if (node.node.nextSibling) { + node.node.nextSibling.parentNode.insertBefore(insertTabSpace(node.indent), node.node.nextSibling); + } else { + node.parent.appendChild(insertTabSpace(node.indent)); + } + } + } + + indentNodes = []; + mydoc = this.doc.body.innerHTML; + mydoc = mydoc.replace(/^\s*[\r\n]/gm, '').replace(/\u200b/g, ''); + + if (msie_c) { + mydoc = mydoc.replace(/(?:[\r\n]*)/g, + function (a, b) { + return '\n' + self.tabRepeat(b); + }).replace(/<(\/?)([A-Za-z]+)([^>]*)>/g, + function (a, close, tag, attr) { + attr = attr.replace(/\s(\w+)=([^'"\s>]+)/g, + function (a, k, v) { + return ' ' + k.toLowerCase() + '="' + v + '"'; + }).replace(/([A-Za-z\-]+)(?:\s*):\s+?/g, + function (a, k) { + return k.toLowerCase() + ': '; + }); + return '<' + close + tag.toLowerCase() + attr + '>'; + } + ); + } + + mydoc = mydoc.replace(/<[^>]+>/gm, function (match) { + match = match.replace(/\sself-close-tag="1"([^>]+)?/g, '$1 /'); + + if (self.config.allowedOnEvent !== true) { + match = match.replace(/\s+on([A-Za-z]+)=("[^"]*"|'[^']*'|[^\s>]*)/g, ''); + } + + if (self.config.colorToHex) { + match = match.replace(/(background-color|color)\s*([:=])\s*(rgba?)\(\s*(\d+)\s*,\s*(\d+),\s*(\d+)\)/ig, + function (all, p, s, rgb, r, g, b) { + return p + s + ' ' + self.colorConvert(rgb + '(' + r + ',' + g + ',' + b + ')', 'hex'); + }); + } else { + match = match.replace(/(background-color|color)\s*([:=])\s*(#[A-Fa-f0-9]{3,6})/ig, + function (all, p, s, hex) { + return p + s + ' ' + self.colorConvert(hex, 'rgb'); + }); + } + + return match; + }); + + return mydoc; + }, + + returnContents : function (mydoc) { + mydoc = this.removeEmptyBogusTag(mydoc); + this.setDesignMode(true); + this.cheditor.textarea.value = mydoc; + return mydoc; + }, + + makeAmpTag : function (str) { + return str.replace(/</g, '&lt;').replace(/>/g, '&gt;'); + }, + + removeAmpTag : function (str) { + if (this.config.removeIndent) { + str = str.replace(/^[\t]+/gm, ''); + } + return str.replace (/&lt;/g, '<').replace(/&gt;/g, '>'); + }, + + getOutputContents : function () { + this.resetViewHTML(); + return this.removeAmpTag(this.getContents(null)); + }, + + outputHTML : function () { + return '\n' + + '\n' + + ' \n' + + ' ' + this.config.docTitle + '\n' + + ' \n' + + ' \n' + + this.returnContents(this.getOutputContents()) + + ' \n' + + ''; + }, + + getBodyContents : function () { + return (this.cheditor.mode === 'code') ? this.makeHtmlContent() : this.getContents(null); + }, + + outputBodyHTML : function () { + return this.returnContents(this.getOutputContents()); + }, + + outputBodyText : function () { + return this.returnContents(this.getBodyText()); + }, + + getBodyText : function () { + this.resetViewHTML(); + return this.trimSpace(String(GB.browser.msie ? this.doc.body.innerText : this.doc.body.textContent)); + }, + + returnFalse : function () { + var img = this.doc.images, i; + this.editAreaFocus(); + + for (i = 0; i < img.length; i++) { + if (img[i].src) { + if (img[i].getAttribute('onload')) { + img[i].onload = 'true'; + } + } else { + img[i].removeAttribute('onload'); + img[i].removeAttribute('className'); + } + } + return false; + }, + + trimZeroSpace : function (str) { + return str ? str.replace(/[\ufeff\u200b\xa0\u3000]+/gm, '') : ''; + }, + + trimSpace : function (str) { + return str ? str.replace(/^[\s\ufeff\u200b\xa0\u3000]+|[\s\ufeff\u200b\xa0\u3000]+$/g, '') : ''; + }, + + makeRandomString : function () { + var chars = '_-$@!#0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz', + len = 32, + clen = chars.length, + rData = '', i, rnum; + + for (i = 0; i < len; i++) { + rnum = Math.floor(Math.random() * clen); + rData += chars.substring(rnum, rnum + 1); + } + return rData; + }, + + strLength : function (str) { + var len = str.length, mbytes = 0, i, c; + for (i = 0; i < len; i++) { + c = str.charCodeAt(i); + if (c > 128) { + mbytes++; + } + } + return (len - mbytes) + (mbytes * 2); + }, + + resetViewHTML : function () { + if (this.cheditor.mode === 'code') { + this.switchEditorMode('rich'); + } + }, + + contentsLengthAll : function () { + return this.strLength(this.outputHTML()); + }, + + contentsLength : function () { + var content = String(this.trimSpace(this.outputBodyHTML())); + if (!content) { + return 0; + } + return this.strLength(content); + }, + + inputLength : function () { + var content = this.getBodyText(); + if (content === '') { + return 0; + } + return this.strLength(content); + }, + + displayWindow : function (pNode, id) { + var pullDown = this.pulldown[id]; + this.editAreaFocus(); + this.backupRange(); + this.boxHideAll(id); + pullDown.style.visibility = 'visible'; + pullDown.style.zIndex = 10002; + pullDown.focus(); + }, + + pulldownMouseOver : function (el) { + if (el.className === 'cheditor-pulldown-selected') { + return; + } + el.className = 'cheditor-pulldown-mouseover'; + }, + pulldownMouseOut : function (el) { + if (el.className === 'cheditor-pulldown-selected') { + return; + } + el.className = 'cheditor-pulldown-mouseout'; + }, + + windowPos : function (pNode, id) { + var left = pNode.offsetLeft, box = this.pulldown[id]; + + if (this.toolbar[id].type === 'combobox') { + left -= parseInt(this.toolbar[this.toolbar[id].node].width, 10); + } + if (this.toolbar[id].prev && !this.toolbar[id].next) { + left -= 1; + } + box.style.left = left + 'px'; + box.style.top = pNode.offsetTop + parseInt(pNode.style.height, 10) + 'px'; + }, + + boxHideAll : function (showId) { + var menu, box, ishide; + for (menu in this.pulldown) { + if (this.pulldown.hasOwnProperty(menu)) { + box = this.pulldown[menu]; + if (box) { + box.style.visibility = 'hidden'; + ishide = this.undefined(showId) ? true : (menu !== showId); + if (ishide && this.toolbar[menu].checked) { + this.toolbar[menu].checked = false; + this.toolbarButtonUnchecked(this.toolbar[menu]); + } + } + } + } + this.editAreaFocus(); + }, + + createWindow : function (width, elem) { + elem.className = 'cheditor-pulldown-container'; + elem.style.width = width + 'px'; + }, + + setColorTable : function (menu) { + var self = this, + pulldown = document.createElement('div'), + len = GB.colors.length, + container = document.createElement('div'), + selected = document.createElement('input'), + selectedValue = document.createElement('input'), + cellWrapper = document.createElement('div'), + br = document.createElement('div'), + reset = document.createElement('span'), + pickerSwitch = document.createElement('span'), + button = document.createElement('img'), + showTooltip = '더 많은 색 보기', + hideTooltip = '감추기', + i, cell, color = 0, colorPicker, cellBorder, + onMouseOverEventHandler = function () { + colorPicker.fromString(this.id); + this.parentNode.className = 'cheditor-pulldown-color-cell-over'; + }, + onMouseOutEventHandler = function () { + this.parentNode.className = 'cheditor-pulldown-color-cell'; + }, + onClickEventHandler = function () { + self.doCmdPopup(menu, this.id); + }, + onResetEventHandler = function () { + colorPicker.fromString(self.colorConvert(selectedValue.style.backgroundColor, 'hex')); + }, + onPickerEventHandler = function () { + if (self.toolbar[menu].colorNode.showPicker) { + colorPicker.hidePicker(); + self.toolbar[menu].colorNode.showPicker = false; + pickerSwitch.setAttribute('title', showTooltip); + } else { + colorPicker.showPicker(); + self.toolbar[menu].colorNode.showPicker = true; + pickerSwitch.setAttribute('title', hideTooltip); + } + }, + onSubmitEventHandler = function () { + self.doCmdPopup(menu, selected.value); + }; + + selected.setAttribute('type', 'text'); + selected.setAttribute('maxlength', '7'); + selected.className = 'cheditor-pulldown-color-selected'; + + selectedValue.setAttribute('type', 'text'); + selectedValue.onfocus = function () { + selected.focus(); + }; + + selectedValue.style.cursor = 'default'; + selectedValue.className = 'cheditor-pulldown-color-selected'; + selected.style.marginLeft = '-1px'; + selected.style.borderLeft = 'none'; + selected.spellcheck = false; + + cellWrapper.style.margin = '2px'; + cellWrapper.style.position = 'relative'; + container.style.position = 'relative'; + + br.style.clear = 'both'; + br.style.height = '0px'; + colorPicker = new GB.colorDropper(selected, {'iconDir': this.config.iconPath}); + + for (i = 0; i < len; i++) { + if (i % 13 === 0) { + cellWrapper.appendChild(br.cloneNode(true)); + if (i === 26) { + cellWrapper.lastChild.style.height = '4px'; + } + len++; + continue; + } + cellBorder = document.createElement('span'); + cellBorder.className = 'cheditor-pulldown-color-cell'; + cell = document.createElement('span'); + cell.id = GB.colors[color]; + cell.style.backgroundColor = GB.colors[color++]; + cell.appendChild(document.createTextNode('\u00a0')); + cellBorder.appendChild(cell); + cellWrapper.appendChild(cellBorder); + (function () { + cell.onclick = onClickEventHandler; + cell.onmouseover = onMouseOverEventHandler; + cell.onmouseout = onMouseOutEventHandler; + })(); + } + + cellWrapper.appendChild(br); + cellWrapper.appendChild(selectedValue); + cellWrapper.appendChild(selected); + + reset.appendChild(document.createTextNode('\u00a0')); + reset.className = 'cheditor-pulldown-color-reset'; + reset.onclick = onResetEventHandler; + + cellWrapper.appendChild(reset); + + pickerSwitch.appendChild(document.createTextNode('\u00a0')); + pickerSwitch.className = 'cheditor-pulldown-color-show-picker'; + pickerSwitch.setAttribute('title', showTooltip); + pickerSwitch.onclick = onPickerEventHandler; + cellWrapper.appendChild(pickerSwitch); + + button.className = 'cheditor-pulldown-color-submit'; + button.src = this.config.iconPath + 'button/input_color.gif'; + button.onclick = onSubmitEventHandler; + cellWrapper.appendChild(button); + container.appendChild(cellWrapper); + + self.toolbar[menu].colorNode.selectedValue = selectedValue; + self.toolbar[menu].colorNode.colorPicker = colorPicker; + + pulldown.appendChild(container); + return pulldown; + }, + + onKeyPressToolbarUpdate : function () { + var self = this; + if (this.tempTimer) { + clearTimeout(this.tempTimer); + } + this.tempTimer = setTimeout(function () { + if (self.config.showTagPath) { + self.doEditorEvent(); + } else { + self.toolbarUpdate(); + } + self.tempTimer = null; + }, 50); + }, + + doOnKeyDown : function (evt) { + switch (evt.keyCode) { + case 37: case 38: case 39: case 40: case 46: case 8: + this.onKeyPressToolbarUpdate(evt); + } + }, + + doOnKeyUp : function (evt) { + var caretRange, css, enterNode, i, keyCode = evt.keyCode, node, self = this, storedNode, storedRange, + clearBackgroundColor = function (cNode) { + if (cNode.nodeType !== GB.node.element || cNode.hasChildNodes() || !cNode.getAttribute('style')) { + return cNode; + } + if (GB.textFormatTags[cNode.nodeName.toLowerCase()]) { + css = self.checkCssValue(cNode, 'background-color'); + if (css) { + css = self.clearCss(cNode, 'background-color'); + if (cNode.nodeName.toLowerCase() === 'span' && !css) { + node = cNode.parentNode; + node.removeChild(cNode); + return node; + } + } + } + return cNode; + }; + + if (keyCode !== 13 || this.cheditor.mode !== 'rich') { + return; + } + + if (typeof GB.browser.msie_c !== 'undefined') { + node = this.storedSelections[0]; + if (!node) { + return; + } + if (node.className === this.cheditor.bogusSpacerName) { + node.className = ''; + } + while (node.firstChild) { + node = node.firstChild; + } + if (node.nodeType === GB.node.element && node.canHaveChildren) { + node.className = this.cheditor.bogusSpacerName; + } + return; + } + + caretRange = this.getRange(); + enterNode = caretRange.commonAncestorContainer; + + if (GB.browser.msie || GB.browser.edge) { + this.backupRange(caretRange); + if (enterNode.nodeType === GB.node.element) { + enterNode = clearBackgroundColor(enterNode); + enterNode.className = this.cheditor.bogusSpacerName; + } + for (i = 0; i < this.keyPressStoredSelections.length; i++) { + storedRange = this.keyPressStoredSelections[i]; + storedNode = storedRange.commonAncestorContainer; + if (storedNode && storedNode.nodeType === GB.node.element) { + node = storedNode.childNodes[storedRange.startOffset]; + if (!node) { + break; + } + while (node.firstChild) { + node = node.firstChild; + } + node = clearBackgroundColor(node); + node.className = this.cheditor.bogusSpacerName; + } + } + this.restoreRange(); + this.keyPressStoredSelections = []; + } else { + this.applyBogusClassName(caretRange); + } + }, + + doOnKeyPress : function (evt) { + var keyCode = evt.keyCode, caretRange; + if (keyCode && keyCode === 13 && this.cheditor.mode === 'rich') { + caretRange = this.getRange(); + if (typeof this.browser.msie_c !== 'undefined') { + try { + this.storedSelections[0] = caretRange.parentElement(); + } catch (e) { + this.keyPressBackupRange(); + } + } else if (GB.browser.msie || GB.browser.edge) { + this.keyPressBackupRange(); + } else { + this.applyBogusClassName(caretRange); + } + } + }, + + applyBogusClassName : function (range) { + var node = range.commonAncestorContainer; + if (range.startOffset < 1 && (!node.lastChild || node.lastChild.nodeName.toLowerCase() !== 'br')) { + do { + if (node.parentNode.nodeName.toLowerCase() === 'body') { + break; + } + node = node.parentNode; + } while (GB.textFormatTags[node.nodeName.toLowerCase()]); + + node = node.previousSibling; + if (node) { + while (node.firstChild) { + node = node.firstChild; + } + if (node.nodeType === GB.node.element && node.nodeName.toLowerCase() === 'br') { + node.className = this.cheditor.bogusSpacerName; + } + } + } else { + if (!node || node.nodeType !== GB.node.element) { + return; + } + if (node.lastChild + && node.lastChild.nodeName.toLowerCase() === 'br' + && node.lastChild.className !== this.cheditor.bogusSpacerName) + { + node.lastChild.className = this.cheditor.bogusSpacerName; + } + } + }, + + setWinPosition : function (oWin, popupAttr, windowSize) { + oWin.style.width = popupAttr.width + 'px'; + oWin.style.left = Math.round(((this.cheditor.editArea.clientWidth - popupAttr.width) / 2) + + windowSize.offsetLeft) + 'px'; + oWin.style.top = Math.round(windowSize.offsetTop) + 'px'; + }, + + getWindowSize : function (doc) { + var mydoc = doc || document, + docMode = mydoc.compatMode === 'CSS1Compat', + docBody = mydoc.body, + docElem = mydoc.documentElement, + factor, rect, physicalWidth, logicalWidth, + editAreaRect, + rData = { + width: docMode ? docElem.clientWidth : docBody.clientWidth, + height: docMode ? docElem.clientHeight : docBody.clientHeight, + scrollHeight: docMode ? docElem.scrollHeight : docBody.scrollHeight, + scrollWidth: docMode ? docElem.scrollWidth : docBody.scrollWidth + }; + + if (this.undefined(window.pageXOffset)) { + factor = 1; + if (docBody.getBoundingClientRect) { + rect = docBody.getBoundingClientRect(); + physicalWidth = rect.right - rect.left; + logicalWidth = mydoc.body.offsetWidth; + factor = Math.round ((physicalWidth / logicalWidth) * 100) / 100; + } + rData.scrollY = Math.round(docElem.scrollTop / factor); + rData.scrollX = Math.round(docElem.scrollLeft / factor); + } else { + rData.scrollY = window.pageYOffset; + rData.scrollX = window.pageXOffset; + } + + editAreaRect = this.cheditor.editArea.getBoundingClientRect(); + rData.clientTop = docElem.clientTop || docBody.clientTop || 0; + rData.clientLeft = docElem.clientLeft || docBody.clientLeft || 0; + rData.offsetTop = rData.scrollY + (rData.height / 2); + rData.offsetLeft = editAreaRect.left + rData.scrollX - rData.clientLeft; + return rData; + }, + + popupWinLoad : function (popupAttr) { + var self = this, + windowSize = self.getWindowSize(), + iframe = document.createElement('iframe'), + body = document.getElementsByTagName('body')[0], + done = false, + + popWinResizeHeight = function (evt) { + iframe.contentWindow.focus(); + iframe.contentWindow.init.call(self, iframe, popupAttr.argv || null); + + if (self.cheditor.popupElem.style.visibility !== 'visible') { + self.cheditor.popupElem.style.top = Math.ceil(parseInt(self.cheditor.popupElem.style.top, 10) - + Math.ceil(self.cheditor.popupElem.clientHeight / 2)) + 'px'; + self.cheditor.popupElem.style.visibility = 'visible'; + } + + self.stopEvent(evt); + }, + modalResize = function () { + self.cheditor.modalBackground.style.height = (windowSize.scrollHeight > windowSize.height) ? + windowSize.scrollHeight : windowSize.height + 'px'; + + if (window.scrollWidth > window.width) { + self.cheditor.modalBackground.style.width = windowSize.width + + (windowSize.scrollWidth - windowSize.width) + 'px'; + } else { + self.cheditor.modalBackground.style.width = windowSize.width + 'px'; + } + self.cheditor.modalBackground.style.left = windowSize.scrollX + 'px'; + }, + onReadyStateChangeEventHandler = function (evt) { + if (!done && (!this.readyState || this.readyState === 'complete' || this.readyState === 'loaded')) { + popWinResizeHeight(evt); + done = true; + } + }; + + if (self.cheditor.popupTitle.hasChildNodes()) { + self.cheditor.popupTitle.removeChild(self.cheditor.popupTitle.firstChild); + } + + if (self.cheditor.popupFrameWrapper.hasChildNodes()) { + self.cheditor.popupFrameWrapper.removeChild(self.cheditor.popupFrameWrapper.firstChild); + } + + self.cheditor.popupTitle.appendChild(document.createTextNode(popupAttr.title)); + self.cheditor.popupElem.style.zIndex = self.modalElementZIndex + 1; + self.setWinPosition(self.cheditor.popupElem, popupAttr, windowSize); + + iframe.setAttribute('frameBorder', '0'); + iframe.setAttribute('height', '0'); + iframe.setAttribute('width', String(popupAttr.width - 22)); + iframe.setAttribute('name', popupAttr.tmpl); + iframe.setAttribute('src', self.config.popupPath + popupAttr.tmpl); + iframe.id = popupAttr.tmpl; + + self.cheditor.modalBackground.style.zIndex = self.modalElementZIndex; + body.insertBefore(self.cheditor.modalBackground, body.firstChild); + body.insertBefore(self.cheditor.popupElem, body.firstChild); + + self.cheditor.popupFrameWrapper.appendChild(iframe); + self.cheditor.popupElem.style.visibility = 'hidden'; + self.cheditor.popupElem.style.display = 'block'; + self.cheditor.modalBackground.style.display = 'block'; + GB.dragWindow.init(self.cheditor.dragHandle, self.cheditor.popupElem); + + (function () { + if (GB.browser.msie && !(self.undefined(iframe.onreadystatechange))) { + iframe.onreadystatechange = onReadyStateChangeEventHandler; + } else { + iframe.onload = popWinResizeHeight; + } + + if (GB.browser.msie && GB.browser.version < 9) { + window.onresize = function () { + windowSize = self.getWindowSize(); + modalResize(); + }; + modalResize(); + self.cheditor.modalBackground.style.filter = 'alpha(opacity=50)'; + self.cheditor.modalBackground.style.opacity = 0.5; + } else { + self.cheditor.modalBackground.style.opacity = 0.5; + } + self.cheditor.modalBackground.focus(); + })(); + }, + + popupWinCancel : function () { + this.restoreRange(); + this.popupWinClose(); + }, + + popupWinClose : function () { + if (!this.cheditor.popupElem) { + return; + } + this.cheditor.popupElem.style.display = 'none'; + this.cheditor.popupElem.style.zIndex = -1; + this.cheditor.popupFrameWrapper.src = ''; + + if (this.cheditor.popupFrameWrapper.hasChildNodes()) { + this.cheditor.popupFrameWrapper.removeChild(this.cheditor.popupFrameWrapper.firstChild); + } + + this.cheditor.modalBackground.style.display = 'none'; + this.cheditor.modalBackground.style.zIndex = -1; + + if (this.modalReSize !== null) { + if (GB.browser.opera) { + window.removeEventListener('resize', this.modaReSize, false); + } + this.modalReSize = null; + } + this.editAreaFocus(); + }, + + clearStoredSelections : function () { + this.storedSelections.splice(0, this.storedSelections.length); + }, + + restoreRange : function () { + var range = null, selection = null; + if (this.storedSelections[0]) { + if (this.W3CRange) { + selection = this.getSelection(); + if (selection.rangeCount > 0) { + selection.removeAllRanges(); + } + selection.addRange(this.storedSelections[0]); + range = selection.getRangeAt(0); + } else { + range = this.createRange(); + if (this.storedSelections[0]) { + if (typeof this.storedSelections[0] === 'string') { + range.moveToBookmark(this.storedSelections[0]); + } else { + range = this.storedSelections[0]; + } + } + range.select(); + } + } + return range; + }, + + keyPressBackupRange : function (range) { + var selection = null, i; + if (this.W3CRange) { + selection = this.getSelection(); + if (selection) { + for (i = 0; i < selection.rangeCount; i++) { + this.keyPressStoredSelections.push(selection.getRangeAt(i)); + } + } + } else { + range = range || this.getRange(); + switch (this.getSelectionType()) { + case GB.selection.none: + case GB.selection.text: + this.storedSelections[0] = range.getBookmark(); + break; + case GB.selection.element: + this.storedSelections[0] = range; + break; + default: + this.storedSelections[0] = null; + } + } + }, + + backupRange : function (range) { + var selection = null; + if (this.W3CRange) { + selection = this.getSelection(); + if (selection && selection.rangeCount > 0) { + this.storedSelections[0] = selection.getRangeAt(0); + } + } else { + range = range || this.getRange(); + switch (this.getSelectionType()) { + case GB.selection.none: + case GB.selection.text: + this.storedSelections[0] = range.getBookmark(); + break; + case GB.selection.element: + this.storedSelections[0] = range; + break; + default: + this.storedSelections[0] = null; + } + } + }, + + getSelection : function () { + return this.W3CRange ? this.editArea.getSelection() : this.doc.selection; + }, + + clearSelection : function () { + var sel = this.getSelection(); + if (!sel) { + return; + } + if (this.W3CRange) { + sel.removeAllRanges(); + } else { + sel.empty(); + } + return sel; + }, + + getRange : function () { + var selection = this.getSelection(), range = null; + if (this.W3CRange) { + if (selection.getRangeAt) { + range = selection.rangeCount ? selection.getRangeAt(0) : this.doc.createRange(); + } else { + range = this.doc.createRange(); + range.setStart(selection.anchorNode, selection.anchorOffset); + range.setEnd(selection.focusNode, selection.focusOffset); + if (range.collapsed !== selection.isCollapsed) { + range.setStart(selection.focusNode, selection.focusOffset); + range.setEnd(selection.anchorNode, selection.anchorOffset); + } + } + } else { + range = selection.createRange ? selection.createRange() : this.doc.createRange(); + if (!range) { + range = this.doc.body.createTextRange(); + } + } + this.range = range; + return range; + }, + + createRange : function () { + return this.W3CRange ? this.doc.createRange() : this.doc.body.createTextRange(); + }, + + rangeCollapsed : function (range) { + return this.W3CRange ? + range.collapsed : + (!this.undefined(range.text) && range.text.length === 0 && range.boundingWidth === 0); + }, + + getRangeElement : function (range) { + return this.W3CRange ? this.getW3CRangeElement(range) : this.getIeRangeElement(range); + }, + + getIeRangeElement : function (range) { + var sType = this.getSelectionType(), + node; + + if (!range) { + range = this.createRange(); + } + + switch (sType) { + case GB.selection.text : + node = range.parentElement(); + break; + case GB.selection.element : + node = range.item(0); + break; + case GB.selection.none : + if (!this.undefined(range.parentElement)) { + node = range.parentElement(); + } else { + node = range.item(0); + } + } + return node; + }, + + getW3CRangeElement : function (range) { + var ancestorContainer = range.commonAncestorContainer, + startContainer = range.startContainer, + startOffset = range.startOffset, + endContainer = range.endContainer, + endOffset = range.endOffset, + docFragment = null, node = startContainer; + + if (GB.browser.msie || GB.browser.edge) { + if (!range.collapsed && ancestorContainer.nodeType === GB.node.element) { + if (ancestorContainer === endContainer) { + node = ancestorContainer.childNodes[endOffset - 1]; + } else if (ancestorContainer === startContainer) { + node = ancestorContainer.childNodes[startOffset]; + } else { + docFragment = range.cloneContents(); + node = (docFragment.childNodes.length === 1) ? startContainer.nextSibling : ancestorContainer; + } + } + } else { + if (!range.collapsed + && startContainer.nodeType === GB.node.element + && startContainer === endContainer + && endOffset - startOffset === 1 + && startContainer.hasChildNodes()) + { + node = startContainer.childNodes[startOffset]; + } + } + + if (node.nodeType === GB.node.text) { + node = node.parentNode; + } + return node; + }, + + getSelectionType : function () { + var selection = this.getSelection(), type; + + if (this.W3CRange) { + if (!selection) { + type = GB.selection.none; + } else if (selection.rangeCount && !selection.isCollapsed && !selection.toString()) { + type = GB.selection.element; + } else { + type = GB.selection.text; + } + } else { + switch (selection.type) { + case 'Text' : type = GB.selection.text; break; + case 'Control' : type = GB.selection.element; break; + default : type = GB.selection.none; + } + if (selection.createRange().parentElement) { + type = GB.selection.text; + } + } + return type; + }, + + windowOpen : function (popupName) { + this.editAreaFocus(); + this.boxHideAll(); + this.backupRange(); + 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'; + } + this.popupWinLoad(popup); + } else { + alert('사용할 수 없는 명령입니다.'); + } + }, + + doCmd : function (cmd, opt) { + var self = this, range = this.range, + i, keyboard = '', command = '', pNode, node, tmpframe, tmpdoc, html, content, + hr, newHr, para, next = null, nNode, tagName, style, id, hRule, nodeType, css, found = false, + isEmpty = false, selectionType, selection, nodeRange, + cleanPaste = function () { + self.editAreaFocus(); + var tmpDoc = self.cheditor.tmpdoc; + tmpDoc.execCommand('SelectAll'); + tmpDoc.execCommand('Paste'); + return self.cleanFromWord(tmpDoc); + }, + isTextVisible = function (elem) { + return (!(elem.firstChild.nodeType === GB.node.text && elem.firstChild === elem.lastChild && + elem.firstChild.nodeValue === '')); + }; + + this.editAreaFocus(); + this.boxHideAll(); + + if (!range) { + return; + } + + if (cmd === 'NewDocument') { + if (confirm('글 내용이 모두 사라집니다. 계속하시겠습니까?')) { + this.doc.body.innerHTML = ''; + } + this.images = []; + this.editImages = {}; + this.editAreaFocus(); + this.toolbarUpdate(); + this.initDefaultParagraphSeparator(); + return; + } + + if (cmd === 'ClearTag') { + if (confirm('모든 HTML 태그를 삭제합니다. 계속하시겠습니까?\n(P, DIV, BR 태그와 텍스트는 삭제하지 않습니다.)')) { + content = this.doc.body.innerHTML; + this.doc.body.innerHTML = content.replace(/<(\/?)([^>]*)>/g, + function (a, b, c) { + var el = c.toLowerCase().split(/ /)[0]; + if (el !== 'p' && el !== 'div' && el !== 'br') { + return ''; + } + return '<' + b + el + '>'; + }); + } + this.editAreaFocus(); + this.toolbarUpdate(); + return; + } + + if (cmd === 'Print') { + this.editArea.print(); + return; + } + + if (cmd === 'PageBreak') { + this.printPageBreak(); + this.editAreaFocus(); + return; + } + + selectionType = this.getSelectionType(); + if (this.W3CRange || selectionType === GB.selection.none) { + range = this.doc; + } + + if (!GB.browser.msie && (cmd === 'Cut' || cmd === 'Copy' || cmd === 'Paste')) { + if ((range.execCommand(cmd, false, opt)) !== true) { + switch (cmd) { + case 'Cut' : keyboard = 'x'; command = '자르기'; break; + case 'Copy' : keyboard = 'c'; command = '복사'; break; + case 'Paste': keyboard = 'v'; command = '붙이기'; break; + } + alert('사용하고 계신 브라우저는 보안 상의 이유로 \'' + command + '\' 명령을 사용하실 수 없습니다. \n\n' + + '키보드 단축키를 이용하여 주십시오.\n단축키: Windows: Ctrl+' + keyboard + ', Mac OS X: Command+' + keyboard); + this.editAreaFocus(); + + } + return; + } + + try { + if (cmd === 'PasteFromWord') { + if (this.undefined(this.cheditor.tmpdoc)) { + tmpframe = this.doc.createElement('iframe'); + tmpframe.setAttribute('contentEditable', 'true'); + tmpframe.style.visibility = 'hidden'; + tmpframe.style.height = tmpframe.style.width = '0px'; + tmpframe.setAttribute('frameBorder', '0'); + this.cheditor.editWrapper.appendChild(tmpframe); + + tmpdoc = tmpframe.contentWindow.document; + tmpdoc.designMode = 'On'; + tmpdoc.open(); + tmpdoc.close(); + this.cheditor.tmpdoc = tmpdoc; + } + + if (this.W3CRange) { + html = cleanPaste(); + // range = this.restoreRange(); + this.insertNodeAtSelection(html); + } else { + range = this.getRange(); + range.pasteHTML(cleanPaste()); + range.select(); + } + } else if (cmd === 'Paste') { + this.cheditor.paste = 'text'; + this.handlePaste(null); + this.cheditor.paste = 'html'; + } else if (cmd === 'InsertHorizontalRule') { + hr = this.doc.createElement('hr'); + hr.style.height = '1px'; + hr.style.backgroundColor = '#999'; + hr.style.border = 'none'; + + this.unselectionElement(hr); + range = this.getRange(); + + if (this.W3CRange) { + range.insertNode(hr); + } else { + nodeType = this.getSelectionType(); + id = this.makeRandomString(); + range.execCommand('InsertHorizontalRule', false, id); + switch (nodeType) { + case GB.selection.none : + case GB.selection.text : + node = range.parentElement(); + break; + case GB.selection.element : + node = range.item(0); + break; + default : + return; + } + newHr = this.$(id); + newHr.parentNode.replaceChild(hr, newHr); + } + + hRule = hr; + pNode = hRule.parentNode; + para = this.makeSpacerElement(); + + while (pNode && GB.textFormatTags[pNode.nodeName.toLowerCase()]) { + pNode = pNode.parentNode; + } + + tagName = pNode.tagName.toLowerCase(); + if (GB.textFormatBlockTags[tagName]) { + if (hr.nextSibling) { + next = this.doc.createElement(tagName); + pNode.parentNode.insertBefore(next, pNode.nextSibling); + while (hr.nextSibling) { + if (hr.nextSibling.nodeType === GB.node.text && hr.nextSibling.nodeValue === '') { + hr = hr.nextSibling; + continue; + } + if (hr.nextSibling.parentNode !== pNode) { + node = hr.nextSibling.parentNode; + while (node !== pNode && GB.textFormatTags[node.nodeName.toLowerCase()]) { + nNode = this.doc.createElement(node.nodeName); + style = this.getCssValue(node); + if (style) { + for (i = 0; i < style.length; i++) { + nNode.style[style[i].name] = style[i].value; + } + } + if (next.hasChildNodes() === false) { + next.appendChild(nNode); + while (hr.nextSibling) { + nNode.appendChild(hr.nextSibling); + } + } else { + next.appendChild(nNode); + nNode.appendChild(next.firstChild); + } + node = node.parentNode; + } + } else { + next.appendChild(hr.nextSibling); + } + } + } + node = hr.parentNode; + pNode.parentNode.insertBefore(hRule, pNode.nextSibling); + + while (node && node !== pNode) { + if (node.hasChildNodes() === false || (isTextVisible(node)) === false) { + nNode = node.parentNode; + node.parentNode.removeChild(node); + node = nNode; + continue; + } + node = node.parentNode; + } + + if (pNode.hasChildNodes() === false || (isTextVisible(pNode)) === false) { + pNode.parentNode.replaceChild(para.cloneNode(true), pNode); + } + if (next === null || next.hasChildNodes() === false) { + hRule.parentNode.insertBefore(para.cloneNode(true), hRule.nextSibling); + } + + node = hRule.nextSibling; + while (node.firstChild) { + node = node.firstChild; + } + if (node && node.nodeType !== GB.node.text) { + node = node.parentNode; + } + this.placeCaretAt(this.W3CRange ? node : hRule.nextSibling, true); + } else { + if (!hRule.previousSibling) { + hRule.parentNode.insertBefore(para.cloneNode(true), hRule); + } + if (!hRule.nextSibling) { + hRule.parentNode.insertBefore(para.cloneNode(true), hRule.nextSibling); + } + this.placeCaretAt(hRule.nextSibling, hRule.nextSibling.nodeType === GB.node.text); + } + } else { + switch (cmd) { + case 'JustifyLeft' : + case 'JustifyCenter' : + case 'JustifyRight' : + case 'JustifyFull' : + pNode = this.getRangeElement(this.range); + node = null; + + if (GB.offElementTags[pNode.nodeName.toLowerCase()]) { + nodeRange = this.createRange(); + selection = this.clearSelection(); + if (this.W3CRange) { + nodeRange.selectNode(pNode); + selection.addRange(nodeRange); + } else { + nodeRange.moveToElementText(pNode); + nodeRange.select(); + range = nodeRange; + } + } + // Caption + if (pNode.nodeName.toLowerCase() === 'img') { + if (pNode.parentNode.nodeName.toLowerCase() === 'figure') { + node = pNode.parentNode; + if (node.parentNode.nodeName.toLowerCase() === 'div') { + node = node.parentNode; + node.style.textAlign = GB.textAlign[cmd]; + break; + } + } + } else if (pNode.nodeName.toLowerCase() === 'figure') { + node = pNode.parentNode; + if (node.nodeName.toLowerCase() === 'div') { + node.style.textAlign = GB.textAlign[cmd]; + break; + } + } + + do { + if (pNode.nodeName.toLowerCase() === 'li') { + node = pNode; + break; + } + pNode = pNode.parentNode; + } while (pNode && pNode.nodeName.toLowerCase() !== 'body'); + + + if (node) { + node.style.textAlign = GB.textAlign[cmd]; + break; + } + + range.execCommand(cmd, false, opt); + pNode = this.getRangeElement(this.W3CRange ? this.getRange() : range); + + while (pNode && pNode.nodeName.toLowerCase() !== 'body') { + if (typeof pNode.getAttribute !== 'undefined' && pNode.getAttribute('align')) { + node = pNode; + break; + } else { + css = this.getCssValue(pNode); + if (css) { + for (i = 0; i < css.length; i++) { + if (css[i].name === 'text-align') { + node = pNode; + break; + } + } + } + } + pNode = pNode.parentNode; + } + + if (node) { + pNode.style.textAlign = GB.textAlign[cmd]; + pNode.removeAttribute('align'); + break; + } + break; + case 'InsertOrderedList' : + case 'InsertUnOrderedList' : + range.execCommand(cmd, false, opt); + if (this.W3CRange) { + range = this.getRange(); + node = range.commonAncestorContainer; + if (node.nodeType === GB.node.element && node.lastChild && + node.lastChild.nodeName.toLowerCase() === 'br') { + node.lastChild.className = this.cheditor.bogusSpacerName; + isEmpty = true; + } + found = false; + while (node) { + if (node.nodeName.toLowerCase() === 'ul' || node.nodeName.toLowerCase() === 'ol') { + found = true; + break; + } + node = node.parentNode; + } + if (found) { + node.style.listStyleType = ''; + if (!GB.browser.msie) { + if (node.parentNode.nodeName.toLowerCase() === 'p' || + node.parentNode.nodeName.toLowerCase() === 'div') { + pNode = node.parentNode; + if (pNode.lastChild && pNode.lastChild.nodeName.toLowerCase() === 'br') { + pNode.removeChild(pNode.lastChild); + } + if (pNode.firstChild === node && pNode.lastChild === node) { + pNode.parentNode.insertBefore(node, pNode); + pNode.parentNode.removeChild(pNode); + this.placeCaretAt(node.lastChild, isEmpty); + } + } + } + } + } + break; + default : + if (range.queryCommandSupported(cmd)) { + range.execCommand(cmd, false, opt); + } + } + } + } catch (e) { + alert(cmd + ': 지원되지 않는 명령입니다. ' + e.toString()); + } + + this.toolbarUpdate(); + }, + + cleanFromWord : function (tmpDoc) { + var doc = tmpDoc.body.innerHTML; + doc = doc.replace(/MsoNormal/g, ''); doc = doc.replace(/<\\?\?xml[^>]*>/g, ''); doc = doc.replace(/<\/?o:p[^>]*>/g, ''); + doc = doc.replace(/<\/?v:[^>]*>/g, ''); doc = doc.replace(/<\/?o:[^>]*>/g, ''); doc = doc.replace(/<\/?st1:[^>]*>/g, ''); + doc = doc.replace(//g, ''); doc = doc.replace(//g, ''); + doc = doc.replace(/<\\?\?xml[^>]*>/g, ''); doc = doc.replace(/<\/?o:p[^>]*>/g, ''); doc = doc.replace(/<\/?v:[^>]*>/g, ''); + doc = doc.replace(/<\/?o:[^>]*>/g, ''); doc = doc.replace(/<\/?st1:[^>]*>/g, ''); //doc = doc.replace(/lang=.?[^' >]*/ig, ''); + doc = doc.replace(/type=.?[^' >]*/g, ''); doc = doc.replace(/href='#[^']*'/g, ''); doc = doc.replace(/href='#[^']*'/g, ''); + doc = doc.replace(/name=.?[^' >]*/g, ''); doc = doc.replace(/ clear='all'/g, ''); doc = doc.replace(/id='[^']*'/g, ''); + doc = doc.replace(/title='[^']*'/g, ''); doc = doc.replace(/\n/g, ''); doc = doc.replace(/\r/g, ''); + doc = doc.replace(/mso\-[^'>;]*/g, ''); doc = doc.replace(/]*/ig, ']*<\/span>/ig, ''); + return doc; + }, + + printPageBreak : function () { + var hr = document.createElement('hr'), + div = this.doc.createElement('div'); + hr.style.pageBreakAfter = 'always'; + hr.style.border = '1px #999 dotted'; + this.insertHTML(hr); + div.appendChild(this.doc.createTextNode('\u00a0')); + this.insertHTML(div); + }, + + doCmdPaste : function (html) { + var range = null; + this.editAreaFocus(); + if (!this.W3CRange) { + if (this.range.item) { + range = this.doc.body.createTextRange(); + if (range) { + range.moveToElementText(this.range.item(0)); + range.select(); + this.range.item(0).outerHTML = html; + } + this.toolbarUpdate(); + } else { + this.range.pasteHTML(html); + this.range.select(); + } + } else { + this.insertNodeAtSelection(html); + } + }, + + getPreviousLeaf : function (node) { + var leaf; + while (!node.previousSibling) { + node = node.parentNode; + if (!node) { + return node; + } + } + leaf = node.previousSibling; + while (leaf.lastChild) { + leaf = leaf.lastChild; + } + return leaf; + }, + + getNextLeaf : function (node, breakNode) { + var leaf; + while (!node.nextSibling) { + node = node.parentNode; + if ((breakNode && breakNode === node) || !node) { + return node; + } + } + leaf = node.nextSibling; + if (breakNode && leaf === breakNode) { + return node; + } + while (leaf.firstChild) { + leaf = leaf.firstChild; + } + return leaf; + }, + + isTextVisible : function (text) { + var i, found = false, len = text.length; + for (i = 0; i < len; i++) { + if (text.charAt(i) !== ' ' && text.charAt(i) !== '\t' && text.charAt(i) !== '\r' && text.charAt(i) !== '\n') { + found = true; + break; + } + } + return found; + }, + + checkCssValue : function (elem, prop) { + var css = this.getCssValue(elem), i; + if (!css) { + return null; + } + for (i = 0; i < css.length; i++) { + if (css[i].name === prop) { + return css[i]; + } + } + return null; + }, + + getCssValue : function (elem) { + var i, q, style = [], len, css; + + css = elem.getAttribute('style'); + if (!css) { + return null; + } + if (typeof css === 'object') { + css = css.cssText; + } + if (this.trimSpace(css) === '') { + return null; + } + + css = css.replace(/;$/, '').split(';'); + len = css.length; + + for (i = 0; i < len; i++) { + q = css[i].split(':'); + style.push({'name': this.trimSpace(q[0]).toLowerCase(), 'value': this.trimSpace(q[1]).toLowerCase()}); + } + return style; + }, + + makeFontCss : function (cmd, opt, elem) { + switch (cmd) { + case 'font-size' : elem.style.fontSize = opt; break; + case 'font-family' : elem.style.fontFamily = opt; break; + case 'color': elem.style.color = opt; break; + case 'background-color': elem.style.backgroundColor = opt; break; + } + }, + + insertStartEndNode : function (range) { + var startNode = this.doc.createElement('span'), + startRange, endRange, endNode, collapsed, node = null; + + startNode.id = 'startNode'; + + if (!this.W3CRange) { + startNode.appendChild(this.doc.createTextNode('\u200b')); + try { + endRange = range.duplicate(); + startRange = range.duplicate(); + endRange.collapse(false); + startRange.collapse(true); + } catch (e) { + node = this.getRangeElement(range); + if (node.nodeType === GB.node.element) { + + } else { + return null; + } + } + + endNode = startNode.cloneNode(true); + endNode.id = 'endNode'; + + if (node) { + node.parentNode.insertBefore(startNode, node); + node.parentNode.insertBefore(endNode, node.nextSibling); + collapsed = false; + } else { + collapsed = startRange.isEqual(endRange); + endRange.pasteHTML(endNode.outerHTML); + endRange.moveStart('character', -1); + endNode = endRange.parentElement(); + + if (collapsed || range.text.length === 0) { + endNode.parentNode.insertBefore(startNode, endNode); + } else { + startNode = endNode.cloneNode(true); + startNode.id = 'startNode'; + startRange.pasteHTML(startNode.outerHTML); + startRange.moveStart('character', -1); + startNode = startRange.parentElement(); + } + } + endRange = null; + startRange = null; + } else { + endRange = range.cloneRange(); + startRange = range.cloneRange(); + startRange.collapse(true); + + endRange.collapse(false); + endNode = startNode.cloneNode(false); + endNode.id = 'endNode'; + + collapsed = range.collapsed; + if (collapsed) { + endRange.insertNode(endNode); + endNode.parentNode.insertBefore(startNode, endNode); + } else { + endRange.insertNode(endNode); + startRange.insertNode(startNode); + } + + if (startNode.previousSibling && startNode.previousSibling.nodeType === GB.node.text && + startNode.previousSibling.nodeValue === '') { + startNode.previousSibling.parentNode.removeChild(startNode.previousSibling); + } + if (endNode.nextSibling && endNode.nextSibling.nodeType === GB.node.text && + endNode.nextSibling.nodeValue === '') { + endNode.nextSibling.parentNode.removeChild(endNode.nextSibling); + } + startRange.detach(); endRange.detach(); + endRange = null; startRange = null; + } + return {startNode: startNode, endNode: endNode, collapsed: collapsed}; + }, + + removeStartEndNode : function (nodes) { + if (nodes.startNode) { + nodes.startNode.parentNode.removeChild(nodes.startNode); + } + if (nodes.endNode) { + nodes.endNode.parentNode.removeChild(nodes.endNode); + } + }, + + clearCss : function (node, name) { + var i, css, styles = []; + + if (!node || node.nodeType !== GB.node.element) { + return null; + } + + css = this.getCssValue(node); + if (!css) { + return null; + } + + node.removeAttribute('style'); + for (i = 0; i < css.length; i++) { + if (css[i].name !== name) { + node.style[css[i].name] = css[i].value; + styles.push(css[i]); + } + } + + return styles.length ? styles : null; + }, + + doCmdPopup : function (cmd, opt, checked) { + var self = this, + range, cursor, selectionType, pNode, node, found, isEmpty, span, endNode, startNode, i, endNodeAncestorRange, + startNodeRange, endNodeRange, compare, tNode, len, selection, child, css, tempNodes, endNodeAncestor, + backupRange, removeNodes = [], spanNodes = [], applyTextNodes = [], tailNodes = [], headNodes = [], rootNode = null, + zeroWidth = this.doc.createTextNode('\u200b'), inRange, + + makeSpanText = function (elem, ancestor) { + if (self.undefined(ancestor)) { + ancestor = elem.parentNode; + } + span = self.doc.createElement('span'); + self.makeFontCss(cmd, opt, span); + ancestor.insertBefore(span, elem); + span.appendChild(elem); + spanNodes.push(span); + return span; + }, + searchTextNode = function (node, match) { + var i = 0, len = node.childNodes.length; + for (; i < len; i++) { + child = node.childNodes[i]; + match = searchTextNode(child, match); + if (child === startNode) { + break; + } + if (child.nodeType === GB.node.text) { + match = true; + break; + } + if (child.nodeType === GB.node.element && child.hasChildNodes() === false && + GB.textFormatTags[child.nodeName.toLowerCase()]) { + removeNodes.push(child); + } + } + return match; + }, + compareBoundaryPoints = function (range, type, source) { + var values = { + 'StartToStart': 0, //Range.START_TO_START, + 'StartToEnd': 1, //Range.START_TO_END, + 'EndToEnd': 2, //Range.END_TO_END, + 'EndToStart': 3 //Range.END_TO_START + }; + + if (self.W3CRange) { + return range.compareBoundaryPoints(values[type], source); + } + + type = type === 'StartToEnd' ? 'EndToStart' : (type === 'EndToStart' ? 'StartToEnd' : type); + return range.compareEndPoints(type, source); + }, + rangeSelectNode = function (range, node) { + if (self.W3CRange) { + range.selectNode(node); + } else { + if (node.nodeType === GB.node.text) { + node = node.parentNode; + } + range.moveToElementText(node); + } + }, + clearPreviousLeaf = function (node) { + var leaf, css = []; + while (!node.previousSibling) { + node = node.parentNode; + if (!node || node.nodeName.toLowerCase() === 'body') { + return null; + } + } + + leaf = node.previousSibling; + + while (leaf.lastChild && leaf.nodeType === GB.node.element && leaf !== startNode) { + rangeSelectNode(cursor, leaf); + compare = compareBoundaryPoints(cursor, 'StartToStart', startNodeRange); + if (compare === 1) { + css = self.clearCss(leaf, cmd); + if (!css && (leaf.nodeName.toLowerCase() === 'span' || leaf.nodeName.toLowerCase() === 'font')) { + while (leaf.firstChild) { + leaf.parentNode.insertBefore(leaf.firstChild, leaf); + } + removeNodes.push(leaf); + break; + } + } else if (compare === 0) { + self.clearCss(leaf, cmd); + if (!rootNode && leaf.nodeName.toLowerCase() === 'span') { + rootNode = leaf; + } + } else { // -1 + node = startNode; + found = false; + while (node) { + if (node.nodeType === GB.node.text) { + found = true; + break; + } + node = checkPreviousLeaf(node, leaf); + } + if (!found) { + self.clearCss(leaf, cmd); + if (!rootNode && leaf.nodeName.toLowerCase() === 'span') { + rootNode = leaf; + } + } + } + + leaf = leaf.lastChild; + } + + if (leaf.nodeType === GB.node.text && self.isTextVisible(leaf.nodeValue)) { + applyTextNodes.push(leaf); + } + + return leaf; + }, + checkPreviousLeaf = function (node, breakNode) { + var leaf; + while (!node.previousSibling) { + node = node.parentNode; + if (node === breakNode || node.nodeName.toLowerCase() === 'body') { + return null; + } + } + leaf = node.previousSibling; + while (leaf.lastChild) { + leaf = leaf.lastChild; + } + return leaf; + }, + checkInRange = function (range, source) { + return (typeof range.inRange !== 'undefined') ? range.inRange(source) : + (compareBoundaryPoints(range, 'StartToStart', source) < 1 + && compareBoundaryPoints(range, 'EndToEnd', source) > -1); + }, + checkNextLeaf = function (node) { + var leaf, inRange; + while (!node.nextSibling) { + node = node.parentNode; + + if (!node || node.nodeName.toLowerCase() === 'body') { + return null; + } + + rangeSelectNode(cursor, node); + inRange = checkInRange(cursor, endNodeRange); + if (inRange) { + inRange = checkInRange(cursor, startNodeRange); + if (!inRange) { + tailNodes.push(node); + } else { + headNodes.push(node); + } + } + + if (node === endNodeAncestor) { + return null; + } + } + + leaf = node.nextSibling; + if (leaf.nodeType === GB.node.text || !endNodeAncestor) { + return null; + } + + rangeSelectNode(cursor, leaf); + inRange = checkInRange(endNodeAncestorRange, cursor); + if (!inRange) { + return null; + } + + while (leaf.firstChild) { + leaf = leaf.firstChild; + } + + if (leaf.nodeType === GB.node.text) { + tailNodes = []; + return null; + } + return leaf; + }, + checkParentSpan = function (node) { + var len = spanNodes.length, i = 0; + for (; i < len; i++) { + if (spanNodes[i] === node) { + return true; + } + } + return false; + }; + + this.editAreaFocus(); + + backupRange = this.restoreRange(); + selectionType = this.getSelectionType(); + + if (this.W3CRange) { + range = this.doc; + } else { + range = (selectionType === GB.selection.none) ? this.doc : backupRange; + } + + try { + if (cmd === 'LineHeight') { + this.applyLineHeight(opt); + } else { + if (cmd === 'InsertOrderedList' || cmd === 'InsertUnOrderedList') { + if (checked !== true) { + range.execCommand(cmd, false, opt); + if (!GB.browser.msie) { + range = this.getRange(); + node = range.commonAncestorContainer; + found = isEmpty = false; + + if (node.nodeType === GB.node.element && node.lastChild && + node.lastChild.nodeName.toLowerCase() === 'br') { + node.lastChild.className = this.cheditor.bogusSpacerName; + isEmpty = true; + } + while (node) { + if (node.nodeName.toLowerCase() === 'ul' || node.nodeName.toLowerCase() === 'ol') { + found = true; + break; + } + node = node.parentNode; + } + + if (found) { + if (node.parentNode.nodeName.toLowerCase() === 'p' || + node.parentNode.nodeName.toLowerCase() === 'div') { + pNode = node.parentNode; + if (pNode.lastChild && pNode.lastChild.nodeName.toLowerCase() === 'br') { + pNode.removeChild(pNode.lastChild); + } + if (pNode.firstChild === node && pNode.lastChild === node) { + pNode.parentNode.insertBefore(node, pNode); + pNode.parentNode.removeChild(pNode); + this.placeCaretAt(node.lastChild, isEmpty); + } + } + } + } + } + cursor = this.getRange(); + pNode = this.W3CRange ? cursor.commonAncestorContainer : cursor.parentElement(); + if (pNode.nodeType === GB.node.text) { + pNode = pNode.parentNode; + } + while (pNode) { + if (pNode.nodeName.toLowerCase() === 'ol' || pNode.nodeName.toLowerCase() === 'ul') { + if (opt === 'desc' || opt === 'decimal') { + opt = ''; + } + pNode.style.listStyleType = opt; + break; + } + pNode = pNode.parentNode; + } + } else if (cmd === 'FontSize' || cmd === 'FontName' || cmd === 'ForeColor' || cmd === 'BackColor') { + if (cmd === 'ForeColor' || cmd === 'BackColor') { + opt = this.colorConvert(opt, 'hex'); + } else if (cmd === 'FontName' && opt === '맑은 고딕') { + opt += ', "Malgun Gothic"'; + } + + cmd = GB.fontStyle[cmd]; + + range = this.getRange(); + tempNodes = this.insertStartEndNode(range); + startNode = tempNodes.startNode; + endNode = tempNodes.endNode; + + cursor = this.createRange(); + startNodeRange = this.createRange(); + rangeSelectNode(startNodeRange, startNode); + + endNodeRange = this.createRange(); + endNodeAncestorRange = this.createRange(); + + if (!tempNodes.collapsed) { + tailNodes = []; + endNodeAncestor = null; + rangeSelectNode(endNodeRange, endNode); + node = endNode.parentNode; + + while (node && node.nodeName.toLowerCase() !== 'body') { + endNodeAncestor = node; + node = node.parentNode; + } + + if (endNodeAncestor) { + rangeSelectNode(endNodeAncestorRange, endNodeAncestor); + } + + node = endNode; + while (node) { + node = checkNextLeaf(node); + } + + for (i = 0; i < tailNodes.length; i++) { + this.clearCss(tailNodes[i], cmd); + } + + node = endNode; + while (node && node !== startNode) { + node = clearPreviousLeaf(node); + } + + if (headNodes.length) { + found = false; + node = startNode; + while (node) { + if (node.nodeType === GB.node.text) { + found = true; + break; + } + node = checkPreviousLeaf(node, endNodeAncestor); + } + if (!found) { + for (i = 0; i < headNodes.length; i++) { + self.clearCss(headNodes[i], cmd); + css = self.getCssValue(headNodes[i]); + if (!css && headNodes[i].nodeName.toLowerCase() === 'span') { + child = headNodes[i]; + while (child.firstChild) { + child.parentNode.insertBefore(child.firstChild, child); + } + child.parentNode.removeChild(child); + headNodes.splice(i); + } + } + } + } + + for (i = 0; i < removeNodes.length; i++) { + removeNodes[i].parentNode.removeChild(removeNodes[i]); + } + removeNodes = []; + + len = applyTextNodes.length; + if (rootNode) { + rangeSelectNode(startNodeRange, rootNode); + } + + for (i = 0; i < len; i++) { + tNode = applyTextNodes[i]; + + if (tNode.previousSibling && tNode.previousSibling.nodeType === GB.node.text) { + if (applyTextNodes[i + 1] && tNode.previousSibling === applyTextNodes[i + 1]) { + applyTextNodes[i + 1].nodeValue += tNode.nodeValue; + tNode.parentNode.removeChild(tNode); + } else { + tNode.nodeValue = tNode.previousSibling.nodeValue + tNode.nodeValue; + tNode.previousSibling.parentNode.removeChild(tNode.previousSibling); + i--; + } + continue; + } + + pNode = tNode.parentNode; + + if (rootNode) { + rangeSelectNode(cursor, pNode); + inRange = checkInRange(startNodeRange, cursor); + if (inRange) { + self.makeFontCss(cmd, '', pNode); + self.makeFontCss(cmd, opt, rootNode); + continue; + } + } + if (pNode.nodeName.toLowerCase() === 'span' + && (pNode.firstChild === tNode || pNode.firstChild === startNode) + && (pNode.lastChild === tNode || pNode.lastChild === endNode)) { + self.makeFontCss(cmd, opt, pNode); + spanNodes.push(pNode); + continue; + } + makeSpanText(tNode); + } + + len = spanNodes.length; + for (i = 0; i < len; i++) { + child = spanNodes[i]; + pNode = child.parentNode; + if (pNode.nodeName.toLowerCase() === 'span') { + if (checkParentSpan(pNode)) { + self.makeFontCss(cmd, '', child); + css = self.getCssValue(child); + if (!css) { + while (child.firstChild) { + pNode.insertBefore(child.firstChild, child); + } + pNode.removeChild(child); + continue; + } + } + while (pNode && pNode.nodeName.toLowerCase() === 'span') { + if (pNode.firstChild === child && pNode.lastChild === child) { + css = self.getCssValue(pNode); + if (css) { + self.makeFontCss(cmd, '', pNode); + css = self.getCssValue(pNode); + if (!css) { + pNode.parentNode.insertBefore(child, pNode); + pNode.parentNode.removeChild(pNode); + pNode = child; + continue; + } + } + } + pNode = pNode.parentNode; + } + } + } + + if (this.W3CRange) { + selection = this.getSelection(); + if (selection.rangeCount > 0) { + selection.removeAllRanges(); + } + range = this.createRange(); + range.setStartAfter(startNode); + range.setEndBefore(endNode); + selection.addRange(range); + } else { + startNodeRange = this.createRange(); + endNodeRange = startNodeRange.duplicate(); + startNodeRange.moveToElementText(startNode); + endNodeRange.moveToElementText(endNode); + startNodeRange.setEndPoint('StartToEnd', startNodeRange); + startNodeRange.setEndPoint('EndToStart', endNodeRange); + startNodeRange.select(); + } + } else { + pNode = startNode.parentNode; + found = false; + while (pNode && pNode.nodeName.toLowerCase() === 'span' && !found) { + css = self.getCssValue(pNode); + if (css) { + len = css.length; + for (i = 0; i < len; i++) { + if (css[i].name === cmd && css[i].value === opt) { + found = true; + break; + } + } + } + pNode = pNode.parentNode; + } + + if (!found) { + span = this.doc.createElement('span'); + this.makeFontCss(cmd, opt, span); + span.appendChild(zeroWidth); + endNode.parentNode.insertBefore(span, endNode); + + if (this.W3CRange) { + selection = this.getSelection(); + selection.collapse(zeroWidth, 1); + } else { + range = this.getRange(); + range.moveToElementText(span); + range.collapse(false); + range.select(); + } + } + } + this.removeStartEndNode(tempNodes); + } else { + range.execCommand(cmd, false, opt); + } + } + } catch (e) { + alert(e.toString()); + } + + this.toolbarUpdate(); + this.boxHideAll(); + }, + + modifyImage : function (img) { + var self = this, + idx, div, ico, inputCaption, wrapTextSpan, wrapTextCheckBox, wrapTextIcon, wrapTextChecked, + width = 0, height = 0, wrapElem, currentCaption = '', caption = null, inputAlt, inputTitle, cssFloat, + wrapperClassName = 'cheditor-caption-wrapper', + figureClassName = 'cheditor-caption', + figCaptionClassName = 'cheditor-caption-text', + imageWidthOpt = { + orig : { size: 'normal', desc: '원본 크기' }, + fitpage : { size: '100%', desc: '페이지 크기에 맞춤' }, + px160 : { size: 160, desc: '썸네일, 160 픽셀' }, + px320 : { size: 320, desc: '작은 크기, 320 픽셀' }, + px640 : { size: 640, desc: '중간 크기, 640 픽셀' }, + px1024 : { size: 1024, desc: '크게, 1024 픽셀' }, + px1600 : { size: 1600, desc: '아주 크게, 1600 픽셀' } + }, + captionAlignOpt = { left: '왼쪽', center: '가운데', right: '오른쪽' }, + imageFloatOpt = { + left : { + value : '왼쪽', + input : null + }, + right : { + value : '오른쪽', + input : null + } + }, + fmSelectWidth = document.createElement('select'), + fmSelectCaptionAlign = document.createElement('select'), + + onChangeEventHandler = function () { + if (self.editImages[img.src] && self.editImages[img.src].width) { + width = self.editImages[img.src].width; + if (self.editImages[img.src] && self.editImages[img.src].height) { + height = self.editImages[img.src].height; + } else { + height = img.height; + } + } else if (img.width) { + width = img.width; + } else { + return; + } + + switch (this.value) { + case 'orig' : + width = width + 'px'; + height = (height || img.height) + 'px'; + break; + case 'fitpage' : + width = '100%'; + height = 'auto'; + break; + default : + width = imageWidthOpt[this.value].size; + if (img.height) { + height = Math.round((img.height * width) / img.width) + 'px'; + } + width += 'px'; + } + + if (width) { + img.style.width = width; + if (caption && caption.figure) { + caption.figure.style.width = width; + } + } + if (height) { + img.style.height = height; + } + }, + setCssFloat = function (elem, css) { + if (typeof elem.style.styleFloat === 'undefined') { + elem.style.cssFloat = css; + } else { + elem.style.styleFloat = css; + } + }, + getCssFloat = function (elem) { + return (typeof elem.style.styleFloat === 'undefined') ? elem.style.cssFloat : elem.style.styleFloat; + }, + clearCssFloat = function (elem) { + setCssFloat(elem, ''); + elem.style.marginLeft = ''; + elem.style.marginRight = ''; + }, + createInputForm = function (type, name, value, classname) { + var input = document.createElement('input'); + input.setAttribute('type', type); + input.setAttribute('name', name); + input.setAttribute('value', value); + input.className = classname; + return input; + }, + applyWrapText = function (elem) { + if (!elem) { + return; + } + wrapElem = (caption && caption.wrapper) ? caption.wrapper : img; + if (elem.checked) { + imageFloatOpt[(elem.name === 'left' ? 'right' : 'left')].input.checked = false; + setCssFloat(wrapElem, elem.name); + if (elem.name === 'left') { + wrapElem.style.marginRight = '1em'; + wrapElem.style.marginLeft = ''; + } else { + wrapElem.style.marginLeft = '1em'; + wrapElem.style.marginRight = ''; + } + if (caption && caption.wrapper) { + clearCssFloat(img); + } + } else { + clearCssFloat(wrapElem); + } + }, + getCaptionNodes = function (img) { + var nodes = { figure: null, figCaption: [], captionText: '', img: null, wrapper: null}, + pNode, node; + pNode = img.parentNode; + if (!pNode || pNode.nodeName.toLowerCase() !== 'figure') { + return null; + } + nodes.figure = pNode; + nodes.figCaption = pNode.getElementsByTagName('figcaption'); + for (idx = 0; idx < nodes.figCaption.length; idx++) { + node = nodes.figCaption[idx].firstChild; + while (node) { + if (node.nodeType === GB.node.text) { + nodes.captionText += self.trimSpace(node.nodeValue); + } + node = node.nextSibling; + } + } + if (pNode.parentNode.nodeName.toLowerCase() === 'div' && pNode.parentNode.className === wrapperClassName) { + nodes.wrapper = pNode.parentNode; + } + nodes.img = img; + return nodes; + }, + applyAlt = function () { + var alt = self.trimSpace(inputAlt.value); + if (alt !== '') { + img.setAttribute('alt', alt); + } + self.removeEvent(inputAlt, 'blur', applyAlt); + self.cheditor.modifyState = false; + }, + applyTitle = function () { + var title = self.trimSpace(inputTitle.value); + if (title !== '') { + img.setAttribute('title', title); + } + self.removeEvent(inputTitle, 'blur', applyTitle); + self.cheditor.modifyState = false; + }, + applyCaption = function () { + var figure = self.doc.createElement('figure'), + figCaption = self.doc.createElement('figcaption'), + wrapper = self.doc.createElement('div'), + pNode = img.parentNode, i, para = self.doc.createElement('p'); + + self.removeEvent(inputCaption, 'blur', applyCaption); + + wrapper.className = wrapperClassName; + figure.className = figureClassName; + figCaption.className = figCaptionClassName; + + this.value = self.trimSpace(inputCaption.value); + if (!self.isTextVisible(this.value) && caption) { + caption.wrapper.parentNode.insertBefore(para, caption.wrapper); + para.appendChild(caption.img); + cssFloat = getCssFloat(caption.wrapper); + caption.wrapper.parentNode.removeChild(caption.wrapper); + caption = getCaptionNodes(img); + if (cssFloat && (cssFloat === 'left' || cssFloat === 'right')) { + applyWrapText(imageFloatOpt[cssFloat].input); + } + self.cheditor.modifyState = false; + return; + } + if (currentCaption === this.value) { + self.cheditor.modifyState = false; + return; + } + + if (caption && caption.figure) { + for (i = 0; i < caption.figCaption.length; i++) { + caption.figure.removeChild(caption.figCaption[i]); + } + figure = caption.figure; + } else { + if (pNode.nodeName.toLowerCase() !== 'body') { + pNode.parentNode.insertBefore(wrapper, pNode.nextSibling); + } else { + pNode.insertBefore(wrapper, img); + } + + if (self.config.imgCaptionWrapper !== '') { + wrapper.setAttribute('style', self.config.imgCaptionWrapper); + } + + wrapper.appendChild(figure); + figure.setAttribute('style', self.config.imgCaptionFigure); + figure.style.display = 'inline-block'; + figure.style.width = img.width; + figure.appendChild(img); + para.appendChild(self.createNbspTextNode()); + wrapper.parentNode.insertBefore(para, wrapper.nextSibling); + } + + figure.appendChild(figCaption); + figCaption.setAttribute('style', self.config.imgCaptionText); + figCaption.appendChild(self.doc.createTextNode(this.value)); + + if (!pNode.hasChildNodes()) { + pNode.parentNode.removeChild(pNode); + } + + caption = getCaptionNodes(img); + cssFloat = getCssFloat(img); + if (cssFloat && (cssFloat === 'left' || cssFloat === 'right')) { + applyWrapText(imageFloatOpt[cssFloat].input); + } + self.cheditor.modifyState = false; + }; + + for (idx in imageWidthOpt) { + if (imageWidthOpt.hasOwnProperty(idx)) { + fmSelectWidth.options[fmSelectWidth.options.length] = new Option(imageWidthOpt[idx].desc, idx); + } + } + + fmSelectWidth.onchange = onChangeEventHandler; + caption = getCaptionNodes(img); + + div = document.createElement('div'); + div.style.textAlign = 'left'; + ico = new Image(); + ico.src = this.config.iconPath + 'image_resize.png'; + ico.className = 'cheditor-ico'; + div.appendChild(ico); + div.appendChild(fmSelectWidth); + + wrapTextChecked = getCssFloat((caption && caption.wrapper) ? caption.wrapper : img); + + for (idx in imageFloatOpt) { + if (imageFloatOpt.hasOwnProperty(idx)) { + wrapTextCheckBox = createInputForm('checkbox', idx, '1', 'wrap-checked'); + wrapTextCheckBox.setAttribute('id', 'idWrapText-' + idx); + wrapTextCheckBox.onclick = function () { + applyWrapText(this); + }; + imageFloatOpt[idx].input = wrapTextCheckBox; + wrapTextSpan = document.createElement('span'); + wrapTextIcon = new Image(); + wrapTextSpan.className = 'wrap-text-desc'; + + if (idx === 'left') { + wrapTextSpan.style.marginLeft = '20px'; + } + if (wrapTextChecked === idx) { + wrapTextCheckBox.checked = 'checked'; + } + wrapTextSpan.appendChild(wrapTextCheckBox); + wrapTextIcon.className = 'cheditor-ico'; + wrapTextIcon.src = this.config.iconPath + 'image_align_' + idx + '_wt.png'; + wrapTextSpan.appendChild(wrapTextIcon); + div.appendChild(wrapTextSpan); + } + } + + if (self.undefined(self.editImages[img.src])) { + self.editImages[img.src] = { width: img.width, height: img.height }; + } + + div.appendChild(document.createTextNode('\u00a0\u00a0Alt:')); + inputAlt = createInputForm('text', 'inputAlt', '', 'user-input-alt'); + inputAlt.onfocus = function () { + self.cheditor.modifyState = true; + self.addEvent(inputAlt, 'blur', applyAlt); + }; + div.appendChild(inputAlt); + if (img.getAttribute('alt')) { + inputAlt.value = img.getAttribute('alt'); + } + + div.appendChild(document.createTextNode('타이틀:')); + inputTitle = createInputForm('text', 'inputTitle', '', 'user-input-alt'); + inputTitle.onfocus = function () { + self.cheditor.modifyState = true; + self.addEvent(inputTitle, 'blur', applyTitle); + }; + div.appendChild(inputTitle); + if (img.getAttribute('title')) { + inputTitle.value = img.getAttribute('title'); + } + + div.appendChild(document.createElement('br')); + div.appendChild(document.createTextNode('사진 캡션:')); + + inputCaption = createInputForm('text', 'inputCaption', '', 'user-input-caption'); + inputCaption.onfocus = function () { + caption = getCaptionNodes(img); + self.cheditor.modifyState = true; + self.addEvent(inputCaption, 'blur', applyCaption); + + }; + div.appendChild(inputCaption); + + div.appendChild(document.createTextNode('캡션 텍스트 정렬:')); + for (idx in captionAlignOpt) { + if (captionAlignOpt.hasOwnProperty(idx)) { + fmSelectCaptionAlign.options[fmSelectCaptionAlign.options.length] = new Option(captionAlignOpt[idx], idx); + if (caption && caption.figCaption[0] && caption.figCaption[0].style.textAlign) { + if (idx === caption.figCaption[0].style.textAlign) { + fmSelectCaptionAlign.options[fmSelectCaptionAlign.options.length - 1].selected = true; + } + } + } + } + + fmSelectCaptionAlign.className = 'caption-align'; + fmSelectCaptionAlign.onchange = function () { + caption = getCaptionNodes(img); + if (!caption) { + return; + } + for (idx = 0; idx < caption.figCaption.length; idx++) { + caption.figCaption[idx].style.textAlign = this.value; + } + }; + div.appendChild(fmSelectCaptionAlign); + + if (caption && caption.captionText) { + currentCaption = self.trimSpace(caption.captionText); + inputCaption.value = currentCaption; + } + + while (self.cheditor.editBlock.firstChild) { + self.cheditor.editBlock.removeChild(self.cheditor.editBlock.firstChild); + } + self.cheditor.editBlock.appendChild(div); + }, + + modifyCell : function (ctd) { + var self = this, + ctb = ctd, + ctr = ctb, + tm = [], i, jr, j, jh, jv, rowIndex = 0, realIndex = 0, newc, newr, nc, tempr, rows, span, icon, + div = document.createElement('div'), + + getCellMatrix = function () { + rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('tr'); + for (i = 0; i < rows.length; i++) { + tm[i] = []; + } + for (i = 0; i < rows.length; i++) { + jr = 0; + for (j = 0; j < rows[i].cells.length; j++) { + while (!(self.undefined(tm[i][jr]))) { + jr++; + } + for (jh = jr; jh < jr + (rows[i].cells[j].colSpan || 1); jh++) { + for (jv = i; jv < i + (rows[i].cells[j].rowSpan || 1); jv++) { + tm[jv][jh] = (jv === i) ? rows[i].cells[j].cellIndex : -1; + } + } + } + } + return tm; + }, + insertColumn = function () { + tm = getCellMatrix(); + rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('tr'); + + if (ctr.rowIndex >= 0) { + rowIndex = ctr.rowIndex; + } else { + for (i = 0; i < rows.length; i++) { + if (rows[i] === ctr) { + rowIndex = i; + break; + } + } + } + + for (j = 0; j < tm[rowIndex].length; j++) { + if (tm[rowIndex][j] === ctd.cellIndex) { + realIndex = j; + break; + } + } + + for (i = 0; i < rows.length; i++) { + if (tm[i][realIndex] !== -1) { + if (rows[i].cells[tm[i][realIndex]].colSpan > 1) { + rows[i].cells[tm[i][realIndex]].colSpan++; + } else { + newc = rows[i].insertCell(tm[i][realIndex] + 1); + nc = rows[i].cells[tm[i][realIndex]].cloneNode(false); + nc.innerHTML = ' '; + rows[i].replaceChild(nc, newc); + } + } + } + }, + insertRow = function (idx) { + newr = ctb.insertRow(ctr.rowIndex + 1); + for (i = 0; i < ctr.cells.length; i++) { + if (ctr.cells[i].rowSpan > 1) { + ctr.cells[i].rowSpan++; + } else { + newc = ctr.cells[i].cloneNode(false); + newc.innerHTML = ' '; + newr.appendChild(newc); + } + } + + for (i = 0; i < ctr.rowIndex; i++) { + if (ctb.rows && ctb.rows.length > 0) { + tempr = ctb.rows[i]; + } else { + tempr = ctb.getElementsByTagName('tr')[i]; + } + for (j = 0; j < tempr.cells.length; j++) { + if (tempr.cells[j].rowSpan > (ctr.rowIndex - i)) { + tempr.cells[j].rowSpan++; + } + } + } + }, + deleteColumn = function () { + tm = getCellMatrix(ctb); + rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('tr'); + rowIndex = 0; realIndex = 0; + + if (ctr.rowIndex >= 0) { + rowIndex = ctr.rowIndex; + } else { + for (i = 0; i < rows.length; i++) { + if (rows[i] === ctr) { + rowIndex = i; + break; + } + } + } + + if (tm[0].length <= 1) { + ctb.parentNode.removeChild(ctb); + } else { + for (j = 0; j < tm[rowIndex].length; j++) { + if (tm[rowIndex][j] === ctd.cellIndex) { + realIndex = j; + break; + } + } + + for (i = 0; i < rows.length; i++) { + if (tm[i][realIndex] !== -1) { + if (rows[i].cells[tm[i][realIndex]].colSpan > 1) { + rows[i].cells[tm[i][realIndex]].colSpan--; + } else { + rows[i].deleteCell(tm[i][realIndex]); + } + } + } + } + }, + deleteRow = function () { + var curCI = -1, prevCI, ni, nrCI, cs, nj; + + tm = getCellMatrix(ctb); + rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('TR'); + rowIndex = 0; + + if (ctr.rowIndex >= 0) { + rowIndex = ctr.rowIndex; + } else { + for (i = 0; i < rows.length; i++) { + if (rows[i] === ctr) { + rowIndex = i; + break; + } + } + } + + if (rows.length <= 1) { + ctb.parentNode.removeChild(ctb); + } else { + for (i = 0; i < rowIndex; i++) { + tempr = rows[i]; + for (j = 0; j < tempr.cells.length; j++) { + if (tempr.cells[j].rowSpan > (rowIndex - i)) { + tempr.cells[j].rowSpan--; + } + } + } + + for (i = 0; i < tm[rowIndex].length; i++) { + prevCI = curCI; + curCI = tm[rowIndex][i]; + + if (curCI !== -1 && curCI !== prevCI && ctr.cells[curCI].rowSpan > 1 && (rowIndex + 1) < rows.length) { + ni = i; + nrCI = tm[rowIndex + 1][ni]; + while (nrCI === -1) { + ni++; + nrCI = (ni < rows[rowIndex + 1].cells.length) ? tm[rowIndex + 1][ni] : rows[rowIndex + 1].cells.length; + } + + newc = rows[rowIndex + 1].insertCell(nrCI); + rows[rowIndex].cells[curCI].rowSpan--; + nc = rows[rowIndex].cells[curCI].cloneNode(false); + rows[rowIndex + 1].replaceChild(nc, newc); + + cs = (ctr.cells[curCI].colSpan > 1) ? ctr.cells[curCI].colSpan : 1; + nj = 0; + + for (j = i; j < (i + cs); j++) { + tm[rowIndex + 1][j] = nrCI; + nj = j; + } + for (j = nj; j < tm[rowIndex + 1].length; j++) { + if (tm[rowIndex + 1][j] !== -1) { + tm[rowIndex + 1][j]++; + } + } + } + } + + if (ctb.rows && ctb.rows.length > 0) { + ctb.deleteRow(rowIndex); + } else { + ctb.removeChild(rows[rowIndex]); + } + } + }, + mergeCellRight = function () { + tm = getCellMatrix(ctb); + rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('tr'); + rowIndex = 0; realIndex = 0; + + if (ctr.rowIndex >= 0) { + rowIndex = ctr.rowIndex; + } else { + for (i = 0; i < rows.length; i++) { + if (rows[i] === ctr) { + rowIndex = i; + break; + } + } + } + + for (j = 0; j < tm[rowIndex].length; j++) { + if (tm[rowIndex][j] === ctd.cellIndex) { + realIndex = j; + break; + } + } + + if (ctd.cellIndex + 1 < ctr.cells.length) { + var ccrs = ctd.rowSpan || 1, + cccs = ctd.colSpan || 1, + ncrs = ctr.cells[ctd.cellIndex + 1].rowSpan || 1, + nccs = ctr.cells[ctd.cellIndex + 1].colSpan || 1, + html; + + j = realIndex; + + while (tm[rowIndex][j] === ctd.cellIndex) { + j++; + } + + if (tm[rowIndex][j] === ctd.cellIndex + 1) { + if (ccrs === ncrs) { + if (rows.length > 1) { + ctd.colSpan = cccs + nccs; + } + html = self.trimSpace(ctr.cells[ctd.cellIndex + 1].innerHTML); + html = html.replace(/^ /, ''); + ctd.innerHTML += html; + ctr.deleteCell(ctd.cellIndex + 1); + } + } + } + }, + mergeCellDown = function () { + var crealIndex = 0, + ccrs = ctd.rowSpan || 1, + cccs = ctd.colSpan || 1, + ncellIndex, html, ncrs, nccs; + + tm = getCellMatrix(ctb); + rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('tr'); + rowIndex = 0; + + if (ctr.rowIndex >= 0) { + rowIndex = ctr.rowIndex; + } else { + for (i = 0; i < rows.length; i++) { + if (rows[i] === ctr) { + rowIndex = i; + break; + } + } + } + + for (i = 0; i < tm[rowIndex].length; i++) { + if (tm[rowIndex][i] === ctd.cellIndex) { + crealIndex = i; + break; + } + } + + if (rowIndex + ccrs < rows.length) { + ncellIndex = tm[rowIndex + ccrs][crealIndex]; + if (ncellIndex !== -1 && + (crealIndex === 0 || (crealIndex > 0 && + (tm[rowIndex + ccrs][crealIndex - 1] !== tm[rowIndex + ccrs][crealIndex])))) + { + ncrs = rows[rowIndex + ccrs].cells[ncellIndex].rowSpan || 1; + nccs = rows[rowIndex + ccrs].cells[ncellIndex].colSpan || 1; + if (cccs === nccs) { + html = self.trimSpace(rows[rowIndex + ccrs].cells[ncellIndex].innerHTML); + html = html.replace(/^ /, ''); + ctd.innerHTML += html; + rows[rowIndex + ccrs].deleteCell(ncellIndex); + ctd.rowSpan = ccrs + ncrs; + } + } + } + }, + splitCellVertical = function () { + var ri, cs; + tm = getCellMatrix(); + rowIndex = 0; realIndex = 0; + + rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('TR'); + + if (ctr.rowIndex >= 0) { + rowIndex = ctr.rowIndex; + } else { + for (ri = 0; ri < rows.length; ri++) { + if (rows[ri] === ctr) { + rowIndex = ri; + break; + } + } + } + + for (j = 0; j < tm[rowIndex].length; j++) { + if (tm[rowIndex][j] === ctd.cellIndex) { + realIndex = j; + break; + } + } + + if (ctd.colSpan > 1) { + newc = rows[rowIndex].insertCell(ctd.cellIndex + 1); + ctd.colSpan--; + nc = ctd.cloneNode(false); + nc.innerHTML = ' '; + rows[rowIndex].replaceChild(nc, newc); + ctd.colSpan = 1; + ctd.removeAttribute('colSpan'); + } else { + newc = rows[rowIndex].insertCell(ctd.cellIndex + 1); + nc = ctd.cloneNode(false); + nc.innerHTML = ' '; + rows[rowIndex].replaceChild(nc, newc); + for (i = 0; i < tm.length; i++) { + if (i !== rowIndex && tm[i][realIndex] !== -1) { + cs = (rows[i].cells[tm[i][realIndex]].colSpan > 1) ? rows[i].cells[tm[i][realIndex]].colSpan : 1; + rows[i].cells[tm[i][realIndex]].colSpan = cs + 1; + } + } + } + }, + splitCellHorizontal = function () { + var ni, rs; + tm = getCellMatrix(); + rowIndex = 0; realIndex = 0; + rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('TR'); + + if (ctr.rowIndex >= 0) { + rowIndex = ctr.rowIndex; + } else { + for (i = 0; i < rows.length; i++) { + if (rows[i] === ctr) { + rowIndex = i; + break; + } + } + } + + for (j = 0; j < tm[rowIndex].length; j++) { + if (tm[rowIndex][j] === ctd.cellIndex) { + realIndex = j; + break; + } + } + + if (ctd.rowSpan > 1) { + i = realIndex; + while (tm[rowIndex + 1][i] === -1) { + i++; + } + + ni = (i === tm[rowIndex + 1].length) ? rows[rowIndex + 1].cells.length : tm[rowIndex + 1][i]; + + newc = rows[rowIndex + 1].insertCell(ni); + ctd.rowSpan--; + + nc = ctd.cloneNode(false); + nc.innerHTML = ' '; + rows[rowIndex + 1].replaceChild(nc, newc); + ctd.rowSpan = 1; + } else { + if (ctb.rows && ctb.rows.length > 0) { + ctb.insertRow(rowIndex + 1); + } else { + if (rowIndex < (rows.length - 1)) { + ctb.insertBefore(document.createElement('TR'), rows[rowIndex + 1]); + } else { + ctb.appendChild(document.createElement('TR')); + } + } + for (i = 0; i < ctr.cells.length; i++) { + if (i !== ctd.cellIndex) { + rs = ctr.cells[i].rowSpan > 1 ? ctr.cells[i].rowSpan : 1; + ctr.cells[i].rowSpan = rs + 1; + } + } + + for (i = 0; i < rowIndex; i++) { + tempr = rows[i]; + for (j = 0; j < tempr.cells.length; j++) { + if (tempr.cells[j].rowSpan > (rowIndex - i)) { + tempr.cells[j].rowSpan++; + } + } + } + + newc = rows[rowIndex + 1].insertCell(0); + nc = ctd.cloneNode(false); + nc.innerHTML = ' '; + rows[rowIndex + 1].replaceChild(nc, newc); + } + }, + tblReflash = function () { + self.editAreaFocus(); self.doEditorEvent(); + }, + colorPickerEventHandler = function () { + GB.popupWindow.ColorPicker.argv = { + func: function (color) { + ctd.setAttribute('bgColor', color); + document.getElementById('fm_cell_bgcolor').value = color; + }, + selectedCell : ctd + }; + self.windowOpen('ColorPicker'); + }, + editSubmitEventHandler = function () { + var width = self.trimSpace(document.getElementById('fm_cell_width').value), + height = self.trimSpace(document.getElementById('fm_cell_height').value), + bgcolor = self.trimSpace(document.getElementById('fm_cell_bgcolor').value); + if (width) { + ctd.setAttribute('width', width); + } + if (height) { + ctd.setAttribute('height', height); + } + if (bgcolor) { + ctd.setAttribute('bgcolor', bgcolor); + } + }, + deleteSubmitEventHandler = function () { + ctb.parentNode.removeChild(ctb); + self.doEditorEvent(); + }, + funcs = { + add_cols_after: { icon: 'table_insert_column.png', title: '열 삽입', + func: function () { + insertColumn(ctd.cellIndex); tblReflash(); + }}, + add_rows_after: { icon: 'table_insert_row.png', title: '행 삽입', + func: function () { + insertRow(ctr.rowIndex); tblReflash(); + }}, + remove_cols: { icon: 'table_delete_column.png', title: '열 삭제', + func: function () { + deleteColumn(ctd.cellIndex); tblReflash(); + }}, + remove_rows: { icon: 'table_delete_row.png', title: '행 삭제', + func: function () { + deleteRow(); tblReflash(); + }}, + sp1: { icon: 'dot.gif' }, + merge_cell_right: { icon: 'table_join_row.png', title: '오른쪽 셀과 병합', + func: function () { + mergeCellRight(); tblReflash(); + }}, + merge_cell_down: { icon: 'table_join_column.png', title: '아래 셀과 병합', + func: function () { + mergeCellDown(); tblReflash(); + }}, + split_cell_v: { icon: 'table_split_row.png', title: '셀 열로 나누기', + func: function () { + splitCellVertical(); tblReflash(); + }}, + split_cell_h: { icon: 'table_split_column.png', title: '셀 행으로 나누기', + func: function () { + splitCellHorizontal(); tblReflash(); + }} + }, + attrFuncs = { + setWidth: { + txt: '가로폭', + id: 'fm_cell_width', + marginRight: '10px', + value: ctd.getAttribute('width') + }, + setHeight: { + txt: '세로폭', + id: 'fm_cell_height', + marginRight: '10px', + value: ctd.getAttribute('height') + }, + setBgcolor: { + txt: '배경색', + id: 'fm_cell_bgcolor', + marginRight: '2px', + value: ctd.getAttribute('bgcolor') + } + }, + deleteSubmit = new Image(), + spliter = document.createElement('div'), txt, input, + colorPicker = new Image(), + editSubmit = new Image(); + + + while (ctb && ctb.tagName.toLowerCase() !== 'table') { + ctb = ctb.parentNode; + } + while (ctr && ctr.tagName.toLowerCase() !== 'tr') { + ctr = ctr.parentNode; + } + + self.cheditor.editBlock.innerHTML = ''; + div.style.padding = '6px'; + + for (i in funcs) { + if (!funcs.hasOwnProperty(i)) { + continue; + } + span = document.createElement('span'); + icon = document.createElement('img'); + icon.src = self.config.iconPath + funcs[i].icon; + + if (i === 'sp1' || i === 'sp2') { + icon.className = 'edit-table-ico'; + } else { + icon.setAttribute('title', funcs[i].title); + icon.className = 'edit-table-ico'; + icon.setAttribute('alt', ''); + icon.onclick = funcs[i].func; + } + div.appendChild(span.appendChild(icon)); + } + + deleteSubmit.src = this.config.iconPath + 'delete_table.png'; + deleteSubmit.style.marginLeft = '22px'; + deleteSubmit.className = 'edit-table-ico'; + deleteSubmit.setAttribute('title', '테이블 삭제'); + deleteSubmit.onclick = deleteSubmitEventHandler; + div.appendChild(deleteSubmit); + + spliter.style.padding = '10px 0px 0px 0px'; + spliter.style.marginTop = '5px'; + spliter.style.borderTop = '1px solid #ccc'; + spliter.style.textAlign = 'center'; + + for (i in attrFuncs) { + if (!attrFuncs.hasOwnProperty(i)) { + continue; + } + txt = document.createTextNode(attrFuncs[i].txt + ' '); + spliter.appendChild(txt); + input = document.createElement('input'); + input.style.marginRight = attrFuncs[i].marginRight; + input.setAttribute('type', 'text'); + input.setAttribute('name', i); + input.setAttribute('id', attrFuncs[i].id); + input.setAttribute('size', 7); + input.setAttribute('value', attrFuncs[i].value || ''); + spliter.appendChild(input); + } + + colorPicker.src = this.config.iconPath + 'button/color_picker.gif'; + colorPicker.className = 'color-picker'; + colorPicker.onclick = colorPickerEventHandler; + spliter.appendChild(colorPicker); + + editSubmit.src = this.config.iconPath + 'button/edit_cell.gif'; + editSubmit.className = 'input-submit'; + editSubmit.style.verticalAlign = 'top'; + editSubmit.onclick = editSubmitEventHandler; + + spliter.appendChild(editSubmit); + div.appendChild(spliter); + self.cheditor.editBlock.appendChild(div); + }, + + doEditorEvent : function (evt) { + var self = this, + cmd = null, ancestors = [], node, el, pNode, range, sType, links, span, tag, remove, bText, + srcElement = evt.target || evt.srcElement, + block = self.cheditor.editBlock, + status = self.cheditor.tagPath, + linkOnClickEventHandler = function () { + if (bText) { + document.getElementById('removeSelected').style.display = 'inline'; + self.tagSelector(this.el); + } + }, + removeOnClickEventHandler = function () { + self.doc.execCommand('RemoveFormat', false, null); + remove.style.display = 'none'; + self.editAreaFocus(); + self.doEditorEvent(); + }; + + if (!this.undefined(srcElement) && srcElement.nodeType === GB.node.element) { + pNode = srcElement; + } else { + range = self.getRange(); + sType = self.getSelectionType(); + bText = sType === GB.selection.text; + + if (!self.W3CRange) { + switch (sType) { + case GB.selection.none : + case GB.selection.text : + pNode = range.parentElement(); + break; + case GB.selection.element : + pNode = range.item(0); + break; + default : + pNode = self.editArea.document.body; + } + } else { + pNode = range.commonAncestorContainer; + if (!range.collapsed && + range.startContainer === range.endContainer && + range.startOffset - range.endOffset < 2 && + range.startContainer.hasChildNodes()) + { + pNode = range.startContainer.childNodes[range.startOffset]; + } + while (pNode.nodeType === GB.node.text) { + pNode = pNode.parentNode; + } + } + } + + node = pNode; + while (pNode && pNode.nodeType === GB.node.element) { + if (pNode.tagName.toLowerCase() === 'body') { + break; + } + if (pNode.tagName.toLowerCase() === 'img') { + cmd = 'img'; break; + } + if (pNode.tagName.toLowerCase() === 'td' || pNode.tagName.toLowerCase() === 'th') { + cmd = 'cell'; break; + } + pNode = pNode.parentNode; + } + + if (!cmd) { + block.style.display = 'none'; + block.innerHTML = ''; + } else { + if (cmd === 'cell') { + block.style.display = 'block'; + self.modifyCell(pNode); + } + } + + if (self.config.showTagPath) { + while (node && node.nodeType === GB.node.element) { + ancestors.push(node); + if (node.tagName.toLowerCase() === 'body') { + break; + } + node = node.parentNode; + } + + status.innerHTML = ''; + status.appendChild(document.createTextNode(' ')); + el = ancestors.pop(); + + while (el) { + status.appendChild(document.createTextNode('<')); + tag = el.nodeName.toLowerCase(); + + links = document.createElement('a'); + links.el = el; + links.href = 'javascript:void%200'; + links.className = 'cheditor-tag-path-elem'; + links.title = el.style.cssText; + (function () { + links.onclick = linkOnClickEventHandler; + })(); + links.appendChild(document.createTextNode(tag)); + status.appendChild(links); + status.appendChild(document.createTextNode('> ')); + el = ancestors.pop(); + } + + if (bText) { + remove = document.createElement('a'); + remove.href = 'javascript:void%200'; + remove.id = 'removeSelected'; + remove.style.display = 'none'; + remove.className = 'cheditor-tag-path-elem'; + remove.style.color = '#cc3300'; + remove.appendChild(document.createTextNode('')); + (function () { + remove.onclick = removeOnClickEventHandler; + })(); + span = document.createElement('span'); + span.style.marginTop = '2px'; + span.appendChild(remove); + self.cheditor.tagPath.appendChild(span); + } + } + + self.toolbarUpdate(srcElement); + }, + + tagSelector : function (node) { + var rng, selection; + this.editAreaFocus(); + + if (this.W3CRange) { + selection = this.editArea.getSelection(); + if (this.undefined(selection)) { + return; + } + try { + rng = selection.getRangeAt(0); + } catch (e) { + return; + } + rng.selectNodeContents(node); + selection.removeAllRanges(); + selection.addRange(rng); + } else { + rng = this.doc.body.createTextRange(); + if (rng) { + rng.moveToElementText(node); + rng.select(); + } + } + }, + + getBrowser : function () { + return GB.browser; + }, + $ : function (id) { + return this.doc.getElementById(id); + } +}; + +(function () { + var dragWindow = { + obj: null, + init: function (o, oRoot, minX, maxX, minY, maxY) { + o.style.curser = 'default'; + o.onmousedown = dragWindow.start; + o.onmouseover = function () { + this.style.cursor = 'move'; + }; + o.hmode = true; + o.vmode = true; + o.root = (oRoot && oRoot !== null) ? oRoot : o; + o.transId = oRoot.id + '_Trans'; + + if (o.hmode && isNaN(parseInt(o.root.style.left, 10))) { + o.root.style.left = '0px'; + } + if (o.vmode && isNaN(parseInt(o.root.style.top, 10))) { + o.root.style.top = '0px'; + } + if (!o.hmode && isNaN(parseInt(o.root.style.right, 10))) { + o.root.style.right = '0px'; + } + if (!o.vmode && isNaN(parseInt(o.root.style.bottom, 10))) { + o.root.style.bottom = '0px'; + } + + o.minX = minX !== undefined ? minX : null; + o.minY = minY !== undefined ? minY : null; + o.maxX = maxX !== undefined ? maxX : null; + o.maxY = maxY !== undefined ? maxY : null; + o.root.onDragStart = new Function(); + o.root.onDragEnd = new Function(); + o.root.onDrag = new Function(); + }, + start: function (e) { + var o = dragWindow.obj = this, + dragTransBg = document.createElement('div'), + y = parseInt(o.vmode ? o.root.style.top : o.root.style.bottom, 10), + x = parseInt(o.hmode ? o.root.style.left : o.root.style.right, 10); + + e = dragWindow.fixEv(e); + o.root.onDragStart(x, y); + o.lastMouseX = e.clientX; + o.lastMouseY = e.clientY; + + document.onmousemove = dragWindow.drag; + document.onmouseup = dragWindow.end; + + if (o.root.lastChild.id === o.transId) { + return false; + } + + dragTransBg.className = 'cheditor-dragWindowTransparent'; + if (GB.browser.msie && GB.browser.version < 10) { + dragTransBg.style.filter = 'alpha(opacity=0)'; + } else { + dragTransBg.style.opacity = 0; + } + dragTransBg.id = o.transId; + dragTransBg.style.width = o.root.lastChild.firstChild.style.width; + dragTransBg.style.height = o.root.lastChild.firstChild.style.height; + o.root.appendChild(dragTransBg); + return false; + }, + drag: function (e) { + e = dragWindow.fixEv(e); + var o = dragWindow.obj, + ey = e.clientY, + ex = e.clientX, + y = parseInt(o.vmode ? o.root.style.top : o.root.style.bottom, 10), + x = parseInt(o.hmode ? o.root.style.left : o.root.style.right, 10), + nx, ny; + + nx = x + ((ex - o.lastMouseX) * (o.hmode ? 1 : -1)); + ny = y + ((ey - o.lastMouseY) * (o.vmode ? 1 : -1)); + + dragWindow.obj.root.style.left = nx + 'px'; + dragWindow.obj.root.style.top = ny + 'px'; + dragWindow.obj.lastMouseX = ex; + dragWindow.obj.lastMouseY = ey; + dragWindow.obj.root.onDrag(nx, ny); + return false; + }, + end: function () { + document.onmousemove = null; + document.onmouseup = null; + dragWindow.obj.root.onDragEnd(parseInt(dragWindow.obj.root.style[dragWindow.obj.hmode ? 'left' : 'right'], 10), + parseInt(dragWindow.obj.root.style[dragWindow.obj.vmode ? 'top' : 'bottom'], 10)); + + if (dragWindow.obj.root.lastChild.id === dragWindow.obj.transId) { + dragWindow.obj.root.removeChild(dragWindow.obj.root.lastChild); + } + dragWindow.obj = null; + }, + fixEv: function (e) { + if (e === undefined) { + e = window.event; + } + if (e.layerX === undefined) { + e.layerX = e.offsetX; + } + if (e.layerY === undefined) { + e.layerY = e.offsetY; + } + return e; + } + }; + GB.dragWindow = dragWindow; +})(); + +// -------------------------------------------------------------------------- +// W3C DOM Range +// + +// -------------------------------------------------------------------------- +// Table +// + +// -------------------------------------------------------------------------- +// Color Picker +// +(function () { + var colorDropper = { + images: {pad: [181, 101], sld: [16, 101], cross: [15, 15], arrow: [7, 11]}, + fetchElement: function (mixed) { + return typeof mixed === 'string' ? document.getElementById(mixed) : mixed; + }, + + addEvent: function (el, evnt, func) { + if (el.addEventListener) { + el.addEventListener(evnt, func, false); + } else if (el.attachEvent) { + el.attachEvent('on' + evnt, func); + } + }, + + fireEvent: function (el, evnt) { + if (!el) { + return; + } + var ev; + if (document.createEvent) { + ev = document.createEvent('HTMLEvents'); + ev.initEvent(evnt, true, true); + el.dispatchEvent(ev); + } else if (document.createEventObject) { + ev = document.createEventObject(); + el.fireEvent('on' + evnt, ev); + } else if (el['on' + evnt]) { + el['on' + evnt](); + } + }, + + getElementPos: function (e) { + var e1 = e, e2 = e, x = 0, y = 0; + if (e1.offsetParent) { + do { + x += e1.offsetLeft; + y += e1.offsetTop; + e1 = e1.offsetParent; + } while (e1); + } + + while (e2 && e2.nodeName.toLowerCase() !== 'body') { + x -= e2.scrollLeft; + y -= e2.scrollTop; + e2 = e2.parentNode; + } + return [x, y]; + }, + + getElementSize: function (e) { + return [e.offsetWidth, e.offsetHeight]; + }, + + getRelMousePos: function (e) { + var x = 0, y = 0; + if (!e) { + e = window.event; + } + if (typeof e.offsetX === 'number') { + x = e.offsetX; + y = e.offsetY; + } else if (typeof e.layerX === 'number') { + x = e.layerX; + y = e.layerY; + } + return {x: x, y: y}; + }, + + color: function (target, prop) { + this.required = true; + this.adjust = true; + this.hash = true; + this.caps = false; + this.valueElement = target; + this.styleElement = target; + this.onImmediateChange = null; + this.hsv = [0, 0, 1]; + this.rgb = [1, 1, 1]; + this.minH = 0; + this.maxH = 6; + this.minS = 0; + this.maxS = 1; + this.minV = 0; + this.maxV = 1; + + this.pickerOnfocus = true; + this.pickerMode = 'HSV'; + this.pickerFace = 3; + this.pickerFaceColor = '#fff'; + this.pickerInset = 1; + this.pickerInsetColor = '#999'; + this.pickerZIndex = 10003; + + var p, + self = this, + modeID = this.pickerMode.toLowerCase() === 'hvs' ? 1 : 0, + abortBlur = false, + valueElement = colorDropper.fetchElement(this.valueElement), styleElement = colorDropper.fetchElement(this.styleElement), + holdPad = false, holdSld = false, touchOffset = {}, + leaveValue = 1 << 0, leaveStyle = 1 << 1, leavePad = 1 << 2, leaveSld = 1 << 3, + updateFieldEventHandler = function () { + self.fromString(valueElement.value, leaveValue); + dispatchImmediateChange(); + }; + + colorDropper.addEvent(target, 'blur', function () { + if (!abortBlur) { + window.setTimeout(function () { + abortBlur || blurTarget(); + abortBlur = false; + }, 0); + } else { + abortBlur = false; + } + }); + + for (p in prop) { + if (prop.hasOwnProperty(p)) { + this[p] = prop[p]; + } + } + + this.hidePicker = function () { + if (isPickerOwner()) { + removePicker(); + } + }; + + this.showPicker = function () { + if (!isPickerOwner()) { + drawPicker(); + } + }; + + this.importColor = function () { + if (!valueElement) { + this.exportColor(); + } else { + if (!this.adjust) { + if (!this.fromString(valueElement.value, leaveValue)) { + styleElement.style.backgroundImage = styleElement.jscStyle.backgroundImage; + styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor; + styleElement.style.color = styleElement.jscStyle.color; + this.exportColor(leaveValue | leaveStyle); + } + } else if (!this.required && /^\s*$/.test(valueElement.value)) { + valueElement.value = ''; + styleElement.style.backgroundImage = styleElement.jscStyle.backgroundImage; + styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor; + styleElement.style.color = styleElement.jscStyle.color; + this.exportColor(leaveValue | leaveStyle); + } else if (this.fromString(valueElement.value)) { + // ignore + } else { + this.exportColor(); + } + } + }; + + this.exportColor = function (flags) { + if (!(flags & leaveValue) && valueElement) { + var value = this.toString(); + if (this.caps) { + value = value.toUpperCase(); + } + if (this.hash) { + value = '#' + value; + } + valueElement.value = value; + } + if (!(flags & leaveStyle) && styleElement) { + styleElement.style.backgroundImage = 'none'; + styleElement.style.backgroundColor = '#' + this.toString(); + styleElement.style.color = 0.213 * this.rgb[0] + 0.715 * this.rgb[1] + 0.072 * this.rgb[2] < 0.5 ? '#FFF' : '#000'; + } + if (!(flags & leavePad) && isPickerOwner()) { + redrawPad(); + } + if (!(flags & leaveSld) && isPickerOwner()) { + redrawSld(); + } + }; + + this.fromHSV = function (h, s, v, flags) { + if (h) { + h = Math.max(0.0, this.minH, Math.min(6.0, this.maxH, h)); + } + if (s) { + s = Math.max(0.0, this.minS, Math.min(1.0, this.maxS, s)); + } + if (v) { + v = Math.max(0.0, this.minV, Math.min(1.0, this.maxV, v)); + } + + this.rgb = this.HSV_RGB( + h === null ? this.hsv[0] : (this.hsv[0] = h), + s === null ? this.hsv[1] : (this.hsv[1] = s), + v === null ? this.hsv[2] : (this.hsv[2] = v) + ); + this.exportColor(flags); + }; + + this.fromRGB = function (r, g, b, flags) { + if (r) { + r = Math.max(0.0, Math.min(1.0, r)); + } + if (g) { + g = Math.max(0.0, Math.min(1.0, g)); + } + if (b) { + b = Math.max(0.0, Math.min(1.0, b)); + } + + var hsv = this.RGB_HSV( + r === null ? this.rgb[0] : r, + g === null ? this.rgb[1] : g, + b === null ? this.rgb[2] : b + ); + if (hsv[0] !== null) { + this.hsv[0] = Math.max(0.0, this.minH, Math.min(6.0, this.maxH, hsv[0])); + } + if (hsv[2] !== 0) { + this.hsv[1] = hsv[1] === null ? null : Math.max(0.0, this.minS, Math.min(1.0, this.maxS, hsv[1])); + } + this.hsv[2] = hsv[2] === null ? null : Math.max(0.0, this.minV, Math.min(1.0, this.maxV, hsv[2])); + + var rgb = this.HSV_RGB(this.hsv[0], this.hsv[1], this.hsv[2]); + this.rgb[0] = rgb[0]; + this.rgb[1] = rgb[1]; + this.rgb[2] = rgb[2]; + + this.exportColor(flags); + }; + + this.fromString = function (hex, flags) { + var m = hex.match(/^\W*([0-9A-F]{3}([0-9A-F]{3})?)\W*$/i); + if (!m) { + return false; + } + if (m[1].length === 6) { + this.fromRGB( + parseInt(m[1].substr(0, 2), 16) / 255, + parseInt(m[1].substr(2, 2), 16) / 255, + parseInt(m[1].substr(4, 2), 16) / 255, + flags + ); + } else { + this.fromRGB( + parseInt(m[1].charAt(0) + m[1].charAt(0), 16) / 255, + parseInt(m[1].charAt(1) + m[1].charAt(1), 16) / 255, + parseInt(m[1].charAt(2) + m[1].charAt(2), 16) / 255, + flags + ); + } + return true; + }; + + this.toString = function () { + return ( + (0x100 | Math.round(255 * this.rgb[0])).toString(16).substr(1) + + (0x100 | Math.round(255 * this.rgb[1])).toString(16).substr(1) + + (0x100 | Math.round(255 * this.rgb[2])).toString(16).substr(1) + ); + }; + + this.RGB_HSV = function (r, g, b) { + var n = Math.min(Math.min(r, g), b), + v = Math.max(Math.max(r, g), b), + m = v - n, h; + + if (m === 0) { + return [null, 0, v]; + } + h = r === n ? 3 + (b - g) / m : (g === n ? 5 + (r - b) / m : 1 + (g - r) / m); + return [h === 6 ? 0 : h, m / v, v]; + }; + + this.HSV_RGB = function (h, s, v) { + if (h === null) { + return [v, v, v]; + } + var i = Math.floor(h), + f = i % 2 ? h - i : 1 - (h - i), + m = v * (1 - s), + n = v * (1 - s * f); + switch (i) { + case 6: + case 0: + return [v, n, m]; + case 1: + return [n, v, m]; + case 2: + return [m, v, n]; + case 3: + return [m, n, v]; + case 4: + return [n, m, v]; + case 5: + return [v, m, n]; + } + }; + + function removePicker() { + delete colorDropper.picker.owner; + colorDropper.picker.boxB.parentNode.removeChild(colorDropper.picker.boxB); + } + + function drawPicker() { + var touchMoveEventHandler = function (e) { + var event = { + 'offsetX': e.touches[0].pageX - touchOffset.X, + 'offsetY': e.touches[0].pageY - touchOffset.Y + }; + if (holdPad || holdSld) { + holdPad && setPad(event); + holdSld && setSld(event); + dispatchImmediateChange(); + } + e.stopPropagation(); + e.preventDefault(); + }, + dims = getPickerDims(self), + padImg = modeID ? 'color_picker_hv.png' : 'color_picker_hs.png', + i, seg, segSize; + + if (!colorDropper.picker) { + colorDropper.picker = { + box: document.createElement('div'), + boxB: document.createElement('div'), + pad: document.createElement('div'), + padB: document.createElement('div'), + padM: document.createElement('div'), + sld: document.createElement('div'), + sldB: document.createElement('div'), + sldM: document.createElement('div') + }; + for (i = 0, segSize = 2; i < colorDropper.images.sld[1]; i += segSize) { + seg = document.createElement('div'); + seg.style.height = segSize + 'px'; + seg.style.fontSize = '1px'; + seg.style.lineHeight = '0px'; + colorDropper.picker.sld.appendChild(seg); + } + colorDropper.picker.sldB.appendChild(colorDropper.picker.sld); + colorDropper.picker.box.appendChild(colorDropper.picker.sldB); + colorDropper.picker.box.appendChild(colorDropper.picker.sldM); + colorDropper.picker.padB.appendChild(colorDropper.picker.pad); + colorDropper.picker.box.appendChild(colorDropper.picker.padB); + colorDropper.picker.box.appendChild(colorDropper.picker.padM); + colorDropper.picker.boxB.appendChild(colorDropper.picker.box); + } + + p = colorDropper.picker; + p.box.onmouseup = p.box.onmouseout = function () { + target.focus(); + }; + p.box.onmousedown = function () { + abortBlur = true; + }; + p.box.onmousemove = function (e) { + if (holdPad || holdSld) { + holdPad && setPad(e); + holdSld && setSld(e); + if (document.selection) { + document.selection.empty(); + } else if (window.getSelection) { + window.getSelection().removeAllRanges(); + } + dispatchImmediateChange(); + } + }; + + if ('ontouchstart' in window) { + p.box.removeEventListener('touchmove', touchMoveEventHandler, false); + p.box.addEventListener('touchmove', touchMoveEventHandler, false); + } + p.padM.onmouseup = p.padM.onmouseout = function () { + if (holdPad) { + holdPad = false; + colorDropper.fireEvent(valueElement, 'change'); + } + }; + p.padM.onmousedown = function (e) { + switch (modeID) { + case 0: + if (self.hsv[2] === 0) { + self.fromHSV(null, null, 1.0); + } + break; + case 1: + if (self.hsv[1] === 0) { + self.fromHSV(null, 1.0, null); + } + break; + } + holdSld = false; + holdPad = true; + setPad(e); + dispatchImmediateChange(); + }; + + if ('ontouchstart' in window) { + p.padM.addEventListener('touchstart', function (e) { + touchOffset = {'X': getOffsetParent(e.target).Left, 'Y': getOffsetParent(e.target).Top}; + this.onmousedown({ + 'offsetX': e.touches[0].pageX - touchOffset.X, + 'offsetY': e.touches[0].pageY - touchOffset.Y + }); + }); + } + p.sldM.onmouseup = p.sldM.onmouseout = function () { + if (holdSld) { + holdSld = false; + colorDropper.fireEvent(valueElement, 'change'); + } + }; + p.sldM.onmousedown = function (e) { + holdPad = false; + holdSld = true; + setSld(e); + dispatchImmediateChange(); + }; + if ('ontouchstart' in window) { + p.sldM.addEventListener('touchstart', function (e) { + touchOffset = {'X': getOffsetParent(e.target).Left, 'Y': getOffsetParent(e.target).Top}; + this.onmousedown({ + 'offsetX': e.touches[0].pageX - touchOffset.X, + 'offsetY': e.touches[0].pageY - touchOffset.Y + }); + }); + } + + p.box.style.width = dims[0] + 'px'; + p.box.style.height = dims[1] + 'px'; + + p.boxB.style.position = 'relative'; + p.boxB.style.clear = 'both'; + p.boxB.style.border = 'none'; + p.boxB.style.background = self.pickerFaceColor; + + p.pad.style.width = colorDropper.images.pad[0] + 'px'; + p.pad.style.height = colorDropper.images.pad[1] + 'px'; + + p.padB.style.position = 'absolute'; + p.padB.style.left = self.pickerFace + 'px'; + p.padB.style.top = self.pickerFace + 'px'; + p.padB.style.border = self.pickerInset + 'px solid'; + p.padB.style.borderColor = self.pickerInsetColor; + + p.padM.style.position = 'absolute'; + p.padM.style.left = '0'; + p.padM.style.top = '0'; + p.padM.style.width = self.pickerFace + 2 * self.pickerInset + colorDropper.images.pad[0] + colorDropper.images.arrow[0] + 'px'; + p.padM.style.height = p.box.style.height; + p.padM.style.cursor = 'crosshair'; + + p.sld.style.overflow = 'hidden'; + p.sld.style.width = '13px'; + p.sld.style.height = colorDropper.images.sld[1] + 'px'; + + p.sldB.style.position = 'absolute'; + p.sldB.style.right = self.pickerFace + 'px'; + p.sldB.style.top = self.pickerFace + 'px'; + p.sldB.style.border = self.pickerInset + 'px solid'; + p.sldB.style.borderColor = self.pickerInsetColor; + + p.sldM.style.position = 'absolute'; + p.sldM.style.right = '0'; + p.sldM.style.top = '0'; + p.sldM.style.width = 14 + colorDropper.images.arrow[0] + self.pickerFace + 2 * self.pickerInset + 'px'; + p.sldM.style.height = p.box.style.height; + + try { + p.sldM.style.cursor = 'pointer'; + } catch (e) { + p.sldM.style.cursor = 'hand'; + } + + p.padM.style.backgroundImage = 'url("' + self.iconDir + '/color_picker_cross.gif")'; + p.padM.style.backgroundRepeat = 'no-repeat'; + p.sldM.style.backgroundImage = 'url("' + self.iconDir + '/color_picker_arrow.gif")'; + p.sldM.style.backgroundRepeat = 'no-repeat'; + p.pad.style.backgroundImage = 'url("' + self.iconDir + '/' + padImg + '")'; + p.pad.style.backgroundRepeat = 'no-repeat'; + p.pad.style.backgroundPosition = '0 0'; + redrawPad(); + redrawSld(); + colorDropper.picker.owner = self; + target.parentNode.parentNode.appendChild(p.boxB); + } + + function getPickerDims(o) { + return [2 * o.pickerInset + 2 * o.pickerFace + colorDropper.images.pad[0] + + 2 * o.pickerInset + 2 * colorDropper.images.arrow[0] + colorDropper.images.sld[0], + 2 * o.pickerInset + 2 * o.pickerFace + colorDropper.images.pad[1]]; + } + + function redrawPad() { + var yComponent, x, y, i = 0, rgb, s, c, f, + seg = colorDropper.picker.sld.childNodes; + + switch (modeID) { + case 0: + yComponent = 1; + break; + case 1: + yComponent = 2; + break; + } + x = Math.round((self.hsv[0] / 6) * (colorDropper.images.pad[0] - 1)); + y = Math.round((1 - self.hsv[yComponent]) * (colorDropper.images.pad[1] - 1)); + colorDropper.picker.padM.style.backgroundPosition = + (self.pickerFace + self.pickerInset + x - Math.floor(colorDropper.images.cross[0] / 2)) + 'px ' + + (self.pickerFace + self.pickerInset + y - Math.floor(colorDropper.images.cross[1] / 2)) + 'px'; + + switch (modeID) { + case 0: + rgb = self.HSV_RGB(self.hsv[0], self.hsv[1], 1); + if (window.File && window.FileReader) { + colorDropper.picker.sld.style.background = 'linear-gradient(rgb(' + + (rgb[0] * (1 - i / seg.length) * 100) + '%,' + + (rgb[1] * (1 - i / seg.length) * 100) + '%,' + + (rgb[2] * (1 - i / seg.length) * 100) + '%), black)'; + } else { + for (i = 0; i < seg.length; i += 1) { + seg[i].style.backgroundColor = 'rgb(' + + (rgb[0] * (1 - i / seg.length) * 100) + '%,' + + (rgb[1] * (1 - i / seg.length) * 100) + '%,' + + (rgb[2] * (1 - i / seg.length) * 100) + '%)'; + } + } + break; + case 1: + c = [self.hsv[2], 0, 0]; + i = Math.floor(self.hsv[0]); + f = i % 2 ? self.hsv[0] - i : 1 - (self.hsv[0] - i); + switch (i) { + case 6: + case 0: + rgb = [0, 1, 2]; + break; + case 1: + rgb = [1, 0, 2]; + break; + case 2: + rgb = [2, 0, 1]; + break; + case 3: + rgb = [2, 1, 0]; + break; + case 4: + rgb = [1, 2, 0]; + break; + case 5: + rgb = [0, 2, 1]; + break; + } + + for (i = 0; i < seg.length; i += 1) { + s = 1 - 1 / (seg.length - 1) * i; + c[1] = c[0] * (1 - s * f); + c[2] = c[0] * (1 - s); + seg[i].style.backgroundColor = 'rgb(' + + (c[rgb[0]] * 100) + '%,' + + (c[rgb[1]] * 100) + '%,' + + (c[rgb[2]] * 100) + '%)'; + } + break; + } + } + + function getOffsetParent(el) { + var parent = el.offsetParent, top = 0, left = 0; + while (parent) { + top += parent.offsetTop; + left += parent.offsetLeft; + parent = parent.offsetParent; + } + return {Left: left, Top: top}; + } + + function redrawSld() { + var yComponent, y; + switch (modeID) { + case 0: + yComponent = 2; + break; + case 1: + yComponent = 1; + break; + } + y = Math.round((1 - self.hsv[yComponent]) * (colorDropper.images.sld[1] - 1)); + colorDropper.picker.sldM.style.backgroundPosition = + '0 ' + (self.pickerFace + self.pickerInset + y - Math.floor(colorDropper.images.arrow[1] / 2)) + 'px'; + } + + function isPickerOwner() { + return colorDropper.picker && colorDropper.picker.owner === self; + } + + function blurTarget() { + if (valueElement === target) { + self.importColor(); + } + } + + function blurValue() { + if (valueElement !== target) { + self.importColor(); + } + } + + function setPad(e) { + var mpos = colorDropper.getRelMousePos(e), + x = mpos.x - self.pickerFace - self.pickerInset, + y = mpos.y - self.pickerFace - self.pickerInset; + switch (modeID) { + case 0: + self.fromHSV(x * (6 / (colorDropper.images.pad[0] - 1)), 1 - y / (colorDropper.images.pad[1] - 1), null, leaveSld); + break; + case 1: + self.fromHSV(x * (6 / (colorDropper.images.pad[0] - 1)), null, 1 - y / (colorDropper.images.pad[1] - 1), leaveSld); + break; + } + } + + function setSld(e) { + var mpos = colorDropper.getRelMousePos(e), + y = mpos.y - self.pickerFace - self.pickerInset; + switch (modeID) { + case 0: + self.fromHSV(null, null, 1 - y / (colorDropper.images.sld[1] - 1), leavePad); + break; + case 1: + self.fromHSV(null, 1 - y / (colorDropper.images.sld[1] - 1), null, leavePad); + break; + } + } + + function dispatchImmediateChange() { + if (self.onImmediateChange) { + var callback; + if (typeof self.onImmediateChange === 'string') { + callback = new Function(self.onImmediateChange); + } else { + callback = self.onImmediateChange; + } + callback.call(self); + } + } + + if (valueElement) { + colorDropper.addEvent(valueElement, 'keyup', updateFieldEventHandler); + colorDropper.addEvent(valueElement, 'input', updateFieldEventHandler); + colorDropper.addEvent(valueElement, 'blur', blurValue); + valueElement.setAttribute('autocomplete', 'off'); + } + + this.importColor(); + } + }; + GB.colorDropper = colorDropper.color; +})(); diff --git a/plugin/editor/cheditor5/css/SourceCodePro.eot b/plugin/editor/cheditor5/css/SourceCodePro.eot new file mode 100644 index 000000000..2388fa2d7 Binary files /dev/null and b/plugin/editor/cheditor5/css/SourceCodePro.eot differ diff --git a/plugin/editor/cheditor5/css/SourceCodePro.woff b/plugin/editor/cheditor5/css/SourceCodePro.woff new file mode 100644 index 000000000..395436eb8 Binary files /dev/null and b/plugin/editor/cheditor5/css/SourceCodePro.woff differ diff --git a/plugin/editor/cheditor5/css/dialog.css b/plugin/editor/cheditor5/css/dialog.css new file mode 100644 index 000000000..3c87b0e2c --- /dev/null +++ b/plugin/editor/cheditor5/css/dialog.css @@ -0,0 +1,185 @@ +body { + background-color: #fff; + margin: 0; + border: 0; + padding: 0; + font-size: 9pt; + font-family: "Malgun Gothic", "Apple SD Gothic Neo", gulim, monospace; + line-height: 1em; + overflow: hidden; +} +td, input { + font-size: 9pt; + vertical-align: middle; + margin: 0; + line-height: 15px; + height: 15px; +} +select { + font-size: 9pt; + vertical-align: middle; + margin: 0; +} +.handCursor { + cursor: pointer; +} +td.hover +{ + background-color : Fuchsia; +} +table.dlg { + border: 0; +} +fieldset { + border: 1px solid #ccc; + padding: 2px; + margin: 0; +} +.content-outline { + border: 1px solid #ccc; + border-radius: 4px; + padding: 5px; + margin: 0; +} +.dlg td { + text-align: left; + height: 20px; +} +form { + display: inline; +} +.dlg input { + border: 2px; +} +.img { + border: 0; + vertical-align: middle; +} +.font-normal { + font-size: 9pt; +} +legend { + font-size: 9pt; + font-weight: bold; +} +.bottom-status { + background-color: #fff; + margin-top: 10px; + padding: 0; + text-align: center; + height: 24px; + vertical-align: middle; +} +.button { + width: 64px; + height: 22px; + margin: 1px 2px; + cursor: pointer; + vertical-align: middle; +} +.button8em { + font-size: 9pt; + padding-top: 2px !important; + height: 21px; + width: 8em; +} +.button10em { + font-size: 9pt; + padding-top: 1px !important; + height: 21px; + width: 10em; +} +.emIcon { + width: 19px; + height: 19px; + cursor: pointer; +} +.schar { + border: 1px solid #ccc; + background-color: #fff; + width: 18px; + height: 17px; + text-align: center; + cursor: pointer; + font-size: 12px; + line-height: 1.2em; +} +.spacer { + margin: 10px 0 0 0; +} +.spacer5 { + margin: 5px 0 0 0; + clear: both; +} +.wrapper { + text-align: center; +} +.clear { + clear: both; +} +.flash-movie-source { + margin: 0 auto; +} +.flash-player-wrapper { + width: 560px; + height: 315px; + border: 1px #a0a0a0 solid; + text-align: center; + overflow: auto; + margin: 0 auto; + background-color: #fff; + display: block; +} +.media-player-wrapper { + height: 200px; + margin-top: 5px; + text-align: center; + overflow-x: auto; + overflow-y: hidden; +} +.hr { + border: 0; + background: #e0e0e0; + height: 1px; +} +.colorCellMouseOver { + line-height: 0; + font-size: 0; + height: 8px; + width: 8px; + border: 1px solid #fff; +} +.colorCellMouseOut { + line-height: 8px; + font-size: 0; + height: 8px; + width: 8px; + border: 1px solid #000; +} +.colorInputBox { + background-color: #000; + text-align: center; + border: 1px solid #000; + height: 16px; +} +.colorWrapper { + border: 1px solid #000; + background-color: #fff; + position: absolute; + padding: 2px; + display: none; +} +.colorPickerButton { + background: url("../icons/button/color_picker.png") no-repeat center center; + width: 24px; + height: 20px; + cursor: pointer; + float: left; +} +.colorPickerButtonGray { + background: url("../icons/button/color_picker_disable.png") no-repeat center center; + width: 24px; + height: 20px; + cursor: pointer; + float: left; +} \ No newline at end of file diff --git a/plugin/editor/cheditor5/css/editarea.css b/plugin/editor/cheditor5/css/editarea.css new file mode 100644 index 000000000..5350c82a6 --- /dev/null +++ b/plugin/editor/cheditor5/css/editarea.css @@ -0,0 +1,23 @@ +html, body { +} + +p { + margin: 0; +} +table, td, th { border:1px dotted #ccc; } +table { border-collapse: collapse } + +/*-------------------------------------------------------------------------------*/ +.ch_bogus_spacer {} +.cheditor-zero-width { font-family: monospace; } +.cheditor-insertpara-pointer { + height: 1px; + display: none; + overflow: hidden; + background-color: red; + position: absolute; +} +.cheditor-add-paragraph { + border: #999 dotted 1px; + margin: 1px 0px; +} \ No newline at end of file diff --git a/plugin/editor/cheditor5/css/imageupload.css b/plugin/editor/cheditor5/css/imageupload.css new file mode 100644 index 000000000..0589dd629 --- /dev/null +++ b/plugin/editor/cheditor5/css/imageupload.css @@ -0,0 +1,136 @@ +#uploadWindow { + display: none; +} + +.clear { clear: both; } + +#container { + padding: 0; +} + +.imageListWrapperHtml5, .imageListWrapper, .dragOver { + background-color: #fff; + position: absolute; + height: 295px; + width: 522px; + overflow-y: scroll; + border-radius: 4px; + border: 1px red 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: 548px; +} +.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; +} \ No newline at end of file diff --git a/plugin/editor/cheditor5/css/imageurl.css b/plugin/editor/cheditor5/css/imageurl.css new file mode 100644 index 000000000..7332065a7 --- /dev/null +++ b/plugin/editor/cheditor5/css/imageurl.css @@ -0,0 +1,5 @@ +/* CSS file */ + +Application +{ +} diff --git a/plugin/editor/cheditor5/css/lightbox.css b/plugin/editor/cheditor5/css/lightbox.css new file mode 100644 index 000000000..a45cdfc60 --- /dev/null +++ b/plugin/editor/cheditor5/css/lightbox.css @@ -0,0 +1,95 @@ +/************************************************ + + CHEditor Image Caption Util + +************************************************/ +img.chimg_photo +{ + border: 1px darkgray solid; + padding:10px; +} +div.imgblock +{ +} +div.leftjust +{ +} +div.rightjust +{ +} +div.caption +{ + margin-top: 5px; + margin-left: 0.2em; + color: darkgray; + font-size: 9pt; +} +div.caption-marker +{ + float: left; + margin-right: 0.2em; +} +div.caption-text +{ + float: left; + clear: right; + text-align: left; +} +.imageUtil { + cursor: url(icons/imageutil/zoomin.cur), pointer; + outline: none; +} +.imageUtil img { + border: 2px solid gray; +} +.imageUtil:hover img { + border: 2px solid silver; +} + +.imageUtil-image { + border-bottom: 1px solid white; +} +.imageUtil-image-blur { +} +.imageUtil-caption { + display: none; + border-bottom: 1px solid white; + font-family: gulim, Verdana, Helvetica; + font-size: 9pt; + padding: 5px; + background-color: #fff; +} +.imageUtil-loading { + display: block; + color: white; + font-size: 9px; + font-weight: normal; + text-decoration: none; + padding: 3px; + border-top: 1px solid white; + border-bottom: 1px solid white; + background-color: black; + padding-left: 22px; + background-image: url(icons/imageutil/loader.gif); + background-repeat: no-repeat; + background-position: 3px 1px; +} + +a.imageUtil-credits, +a.imageUtil-credits i { + padding: 2px; + color: silver; + text-decoration: none; + font-size: 10px; +} +a.imageUtil-credits:hover, +a.imageUtil-credits:hover i { + color: white; + background-color: gray; +} +.imageUtil-display-block { + display: block; +} +.imageUtil-display-none { + display: none; +} diff --git a/plugin/editor/cheditor5/css/ui.css b/plugin/editor/cheditor5/css/ui.css new file mode 100644 index 000000000..2273f4034 --- /dev/null +++ b/plugin/editor/cheditor5/css/ui.css @@ -0,0 +1,653 @@ +a.cheditor-tag-path-elem { + text-decoration: none; + color: #0033cc; + font-size: 8pt; + font-family: "Malgun Gothic", "Apple SD Gothic Neo", dotum, monospace; + cursor: pointer; +} +a.cheditor-tag-path-elem:hover { + color: #0033cc; + text-decoration: underline; + cursor: pointer; +} +.cheditor-container { + border-top: 1px #ccc solid; + position: relative; + text-align: left; +} +.cheditor-tb-wrapper { + border-right: 1px #ccc solid; + border-left: 1px #ccc solid; + border-bottom: 1px #ccc solid; + position: relative; + display: block; + 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; + border-bottom: 1px #ccc solid; + position: relative; + display: block; + background: #f0f0f0 url(../icons/readonlymode.png) no-repeat 10px center; +} +.cheditor-tb-wrapper-code { + border-right: 1px #ccc solid; + border-left: 1px #ccc solid; + border-bottom: 1px #ccc solid; + position: relative; + display: block; + background: #f0f0f0 url(../icons/viewmode_code.png) no-repeat 10px center; +} +.cheditor-tb-wrapper-preview { + border-right: 1px #ccc solid; + border-left: 1px #ccc solid; + border-bottom: 1px #ccc solid; + position: relative; + display: block; + background: #f0f0f0 url(../icons/viewmode_preview.png) no-repeat 10px center; +} +.cheditor-tb-wrapper-readonly div, .cheditor-tb-wrapper-code div, .cheditor-tb-wrapper-preview div { + display: none; +} +.cheditor-tb-fullscreen { + width: 16px; + height: 16px; + float: right; + margin-top: 3px; + cursor: pointer; + background: transparent url(../icons/fullscreen.png) no-repeat center center; +} +.cheditor-tb-fullscreen-disable { + display: none; +} +.cheditor-tb-fullscreen-actual { + width: 16px; + height: 16px; + float: right; + margin-top: 3px; + cursor: pointer; + background: transparent url(../icons/fullscreen_actual.png) no-repeat center center; +} +.cheditor-editarea-wrapper { + border-right: 1px #ccc solid; + border-bottom: 1px #ccc solid; + border-left: 1px #ccc solid; + width: auto; + overflow: hidden; +} +.cheditor-editarea { + width: 100%; + overflow-x: hidden; + overflow-y: auto; + margin: 0; + padding: 0; + display: block; +} +@font-face { + font-family: 'SourceCodePro'; + src: url('SourceCodePro.eot'); + src: url('SourceCodePro.woff') format('woff'); +} +.cheditor-editarea-text-content { + overflow-x: hidden; + overflow-y: scroll; + margin: 0; + border: 1px solid transparent; + padding: 7px 10px; + display: none; + resize: none; + outline: none; + font-family: SourceCodePro, monospace; + font-size: 12px; +} +.cheditor-modify-block .cheditor-ico { + width: 16px; + height: 16px; + vertical-align: middle; + margin-right: 5px; +} +.cheditor-modify-block select { + font-family: "Malgun Gothic", "Apple SD Gothic Neo", gulim, monospace; + font-size: 9pt; + color: #000; +} +.cheditor-modify-block div { + padding: 5px 10px 5px 10px; + color: #000; + display: block; +} +.cheditor-modify-block div .wrap-text-desc { + line-height: 1em; + color: #000; +} +.cheditor-modify-block div .user-input-alt { + width: 120px; + margin: 3px 10px 0 5px; + height: 15px; + line-height: 15px; + padding-top: 1px; + font-size: 9pt; + font-family: "Malgun Gothic", "Apple SD Gothic Neo", gulim, monospace; + color: #000; +} +.cheditor-modify-block div .user-input-caption { + width: 350px; + margin: 7px 10px 0 5px; + height: 15px; + line-height: 15px; + padding-top: 1px; + font-size: 9pt; + font-family: "Malgun Gothic", "Apple SD Gothic Neo", gulim, monospace; + color: #000; +} +.cheditor-modify-block div .caption-align { + margin: 7px 0 0 4px; + font-size: 9pt; + vertical-align: top; + font-family: "Malgun Gothic", "Apple SD Gothic Neo", gulim, monospace; + color: #000; +} +.cheditor-modify-block div .wrap-checked { + vertical-align: middle; + padding: 0; + margin-right: 2px; +} +.cheditor-modify-block div .input-submit { + cursor: pointer; + vertical-align: middle; + margin-top: -2px; + margin-left: 10px; + height: 20px; + width: 64px; +} +.cheditor-modify-block div .color-picker { + cursor: pointer; + vertical-align: middle; + height: 20px; + width: 20px; +} +.cheditor-modify-block div .delete-submit { + cursor: pointer; + vertical-align: middle; + margin-top: -2px; + margin-left: 3px; + height: 20px; + width: 64px; +} +.cheditor-modify-block div .edit-table-ico { + cursor: pointer; + vertical-align: middle; + width: 16px; + height: 16px; + margin: 0 3px; +} +.cheditor-modify-block { + display: none; + border-right: 1px #ccc solid; + border-bottom: 1px #ccc solid; + border-left: 1px #ccc solid; + padding: 2px; + background-color: #eee; + font-size: 9pt; + font-family: "Malgun Gothic", "Apple SD Gothic Neo", gulim, monospace; + text-align: center; +} +.cheditor-status-bar { + font-size: 8pt; + font-family: "Malgun Gothic", "Apple SD Gothic Neo", dotum, monospace; + color: #333; +} +.cheditor-tag-path { + border-right: 1px #ccc solid; + border-bottom: 1px #ccc solid; + border-left: 1px #ccc solid; + padding: 0 2px 0 2px; + display: none; + height: 18px; + line-height: 18px; + overflow: hidden; +} +.cheditor-viewmode { + padding: 0 4px 0 4px; + height: 16px; + background: transparent url(../icons/statusbar_bgline.gif) repeat-x 0 0; +} +.cheditor-viewmode div { + width: 24px; + height: 16px; + cursor: pointer; +} +.cheditor-tab-rich { + background: transparent url(../icons/edit_mode_rich_a.png) no-repeat 0 0; + float: left; +} +.cheditor-tab-rich-off { + background: transparent url(../icons/edit_mode_rich_b.png) no-repeat 0 0; + float: left; +} +.cheditor-tab-code { + background: transparent url(../icons/edit_mode_code_a.png) no-repeat 0 0; + float: left; +} +.cheditor-tab-code-off { + background: transparent url(../icons/edit_mode_code_b.png) no-repeat 0 0; + float: left; +} +.cheditor-tab-preview { + background: transparent url(../icons/edit_mode_view_a.png) no-repeat 0 0; + float: left; +} +.cheditor-tab-preview-off { + background: transparent url(../icons/edit_mode_view_b.png) no-repeat 0 0; + float: left; +} +.cheditor-resizebar { + height: 11px; + overflow: hidden; + border-left: 1px #ccc solid; + border-right: 1px #ccc solid; + cursor: s-resize; + background: #eee url(../icons/splitter.gif) no-repeat center top; +} +.cheditor-resizebar-off { + height: 11px; + overflow: hidden; + border-left: 1px #ccc solid; + border-right: 1px #ccc solid; + cursor: default; + background-color: #eee; +} +.cheditor_mode_icon { width: 24px; height: 16px; cursor: pointer; vertical-align: top } +.cheditor-pulldown-container { + border: #7d8db0 1px solid; + background-color: #fff; + padding: 1px; + position: relative; + -moz-box-shadow: 0 0 5px #aaa; + -webkit-box-shadow: 0 0 5px #aaa; + box-shadow: 1px 1px 10px #bbb; +} +.cheditor-pulldown-container div { + padding: 2px 2px 2px 15px; + font-size: 9pt; + font-family: "Malgun Gothic", "Apple SD Gothic Neo", gulim, monospace; + color: #222; + position: relative; + display: block; + line-height: 1.2; + margin: 2px 2px; +} +.cheditor-pulldown-color-container { + border: #7d8db0 1px solid; + -moz-box-shadow: 0 0 5px #aaa; + -webkit-box-shadow: 0 0 5px #aaa; + box-shadow: 1px 1px 10px #bbb; + background-color: #fff; + padding: 2px; +} +.cheditor-pulldown-container div label, .cheditor-pulldown-textblock-container div label { + display: block; +} +.cheditor-pulldown-textblock-container div div { + text-align: center; + padding: 2px; + font-size: 9pt; + color: #000; + line-height: 1.2; +} +.cheditor-pulldown-textblock-container div { + padding: 1px; +} +.cheditor-pulldown-textblock-out { + border: #fff 1px solid; +} +.cheditor-pulldown-textblock-over { + border: #ccc 1px solid; +} +.cheditor-pulldown-textblock-container { + border: #7d8db0 1px solid; + -moz-box-shadow: 0 0 5px #aaa; + -webkit-box-shadow: 0 0 5px #aaa; + box-shadow: 1px 1px 10px #bbb; + background-color: #fff; + padding: 2px; +} +.cheditor-pulldown-mouseout { + border: #fff 1px solid; +} +.cheditor-pulldown-mouseover { + background-color: #f0f0f0; + border: #e0e0e0 1px solid; +} +.cheditor-pulldown-frame { + position: absolute; + visibility: hidden; + z-index: -1; + width: 1px; + height: 1px; + line-height: 12px; +} +.cheditor-pulldown-color-cell-over, .cheditor-pulldown-color-cell { + float: left; + width: 14px; + height: 14px; + margin: 1px; + cursor: pointer; +} +.cheditor-pulldown-color-cell-over { + border: 1px #000 solid; +} +.cheditor-pulldown-color-cell-over span { + width: 12px; + height: 12px; + border: 1px #fff solid; + display: block; +} +.cheditor-pulldown-color-cell { + border: 1px #999 solid; +} +.cheditor-pulldown-color-cell span { + width: 14px; + height: 14px; + display: block; + border: none; +} +.cheditor-pulldown-color-selected { + border: 1px solid #999; + text-align: left; + margin: 4px 0 0 1px; + padding-left: 5px; + height: 15px; + line-height: 15px; + font-size: 11px; + font-family: verdana, monospace; + width: 55px; + vertical-align: -10%; +} +.cheditor-pulldown-color-reset, .cheditor-pulldown-color-show-picker { + height: 19px; + width: 16px; + cursor: pointer; + display: inline-block; + vertical-align: middle; + margin-left: 3px; +} +.cheditor-pulldown-color-reset { + background: #fff url(../icons/color_picker_reset.png) no-repeat center center; +} +.cheditor-pulldown-color-show-picker { + background: #fff url(../icons/color_picker.png) no-repeat center center; +} +.cheditor-pulldown-color-submit { + vertical-align: middle; + margin: 4px 1px 0 0; + height: 19px; + width: 40px; + cursor: pointer; + right: 0; + position: absolute; +} +.cheditor-container-fullscreen { + position: fixed; + left: 0; + top: 0; + _position: absolute; + z-index: 1000; + text-align: left; + background-color: #fff; +} +.cheditor-popupModalBackground { + background-color: #fff; + position: fixed; + _position: absolute; + display: none; + top: 0; + left: 0; + width: 100%; + height: 100%; +} +.cheditor-popup-window { + border: 1px solid #0078D7; + border-radius: 5px; + background-color: #0078D7; + display: none; + position: absolute; + top: 0; + left: 0; + -moz-box-shadow: 0 0 5px #aaa; + -webkit-box-shadow: 0 0 5px #aaa; + box-shadow: 0 0 10px #bbb; + padding: 0; + overflow: hidden; +} +.cheditor-popup-cmd-button { + width: 64px; + height: 22px; + margin: 5px 2px; + cursor: pointer; + vertical-align: middle; +} +.cheditor-popup-cframe { + background-color: #fff; + margin: 0; + padding: 10px; + border: none; + text-align: center; +} + +.cheditor-popup-cframe iframe { + margin: 0; + padding: 0; + overflow: hidden; +} +.cheditor-popup-drag-handle { + height: 31px; +} +.cheditor-popup-titlebar { + padding-left: 10px; + line-height: 30px; +} +.cheditor-popup-title { + font-size: 12px; + font-family: "Malgun Gothic", "Apple SD Gothic Neo", gulim, monospace; + font-weight: bold; + color: #fff; +} +.cheditor-dragWindowTransparent { + background-color: #fff; + position: absolute; + display: block; + left: 0px; + top: 27px; +} +.cheditor-pulldown-wrapper { + line-height: 1; +} +.cheditor-toolbar-icon-wrapper { + margin: 0 2px 0 0; + float: left; + height: 24px; + overflow: hidden; +} +.cheditor-tb-icon { + height: 22px; + width: 16px; + overflow: hidden; +} +.cheditor-tb-icon-disable { + height: 22px; + width: 16px; + overflow: hidden; + filter: alpha(opacity=40) gray; + opacity: 0.4; +} +.cheditor-tb-text { + padding: 0; + margin: 0; + color: #333; + height: 20px; + line-height: 20px; +} +.cheditor-tb-text-disable { + padding: 0; + margin: 0; + height: 20px; + line-height: 20px; + color: #333; + overflow: hidden; + filter: alpha(opacity=40) gray; + -webkit-filter: grayscale(100%); + opacity: 0.4; +} +.cheditor-tb-text span, .cheditor-tb-text-disable span { + font-family: "Malgun Gothic", "Apple SD Gothic Neo", gulim, monospace; + margin: 0 0 0 1px; + padding: 0; + width: 41px; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + display: block; + font-size: 12px; +} +.cheditor-tb-icon23 { + height: 22px; + width: 23px; + margin-left: 3px; + overflow: hidden; +} +.cheditor-tb-icon23-disable { + height: 22px; + width: 23px; + margin-left: 3px; + overflow: hidden; + filter: alpha(opacity=40) gray; + opacity: 0.4; +} +.cheditor-tb-icon36 { + height: 22px; + width: 36px; + overflow: hidden; +} +.cheditor-tb-icon36-disable { + height: 22px; + width: 36px; + overflow: hidden; + filter: alpha(opacity=40) gray; + opacity: 0.4; +} +.cheditor-tb-combo { + height: 22px; + width: 10px; + overflow: hidden; +} +.cheditor-tb-combo-disable { + height: 22px; + width: 10px; + overflow: hidden; + filter: alpha(opacity=40) gray; + opacity: 0.4; +} +.cheditor-tb-bg55 { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left -483px; + position: relative; +} +.cheditor-tb-bg40 { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left -552px; + position: relative; +} +.cheditor-tb-bg44 { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left -621px; + position: relative; +} +.cheditor-tb-bg30-first { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left -276px; + position: relative; +} +.cheditor-tb-bg30 { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left -345px; + position: relative; +} +.cheditor-tb-bg30-last { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left -414px; + position: relative; +} +.cheditor-tb-bgcombo { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left -690px; + position: relative; +} +.cheditor-tb-bgcombo-first { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left top; + position: relative; +} +.cheditor-tb-bgcombo-last { + float: left; + overflow: hidden; + background: url(../icons/toolbar-background.png) no-repeat left -759px; + position: relative; +} +.cheditor-tb-bg { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left -69px; + position: relative; +} +.cheditor-tb-bg-first { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left top; + position: relative; +} +.cheditor-tb-bg-last { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left -138px; + position: relative; + background-clip: border-box; +} +.cheditor-tb-bg-single { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left -207px; + position: relative; +} +.cheditor-tb-color-btn { + width: 16px; + height: 3px; + overflow: hidden; + position: absolute; + top: 16px; + left: 3px; +} +.cheditor-tb-button-spacer { + overflow: hidden; + width: 4px; + height: 4px; + float: left; +} +.cheditor-tb-split { + overflow: hidden; + height: 2px; + width: 3px; + clear: both; +} \ No newline at end of file diff --git a/plugin/editor/cheditor5/editor.lib.php b/plugin/editor/cheditor5/editor.lib.php new file mode 100644 index 000000000..6c0c578d2 --- /dev/null +++ b/plugin/editor/cheditor5/editor.lib.php @@ -0,0 +1,158 @@ +') ) { //textarea로 작성되고, html 내용이 없다면 + $content = nl2br($content); + } + } + + $width = isset($editor_width) ? $editor_width : "100%"; + $height = isset($editor_height) ? $editor_height : "250px"; + if (defined(G5_PUNYCODE)) + $editor_url = G5_PUNYCODE.'/'.G5_EDITOR_DIR.'/'.$config['cf_editor']; + else + $editor_url = G5_EDITOR_URL.'/'.$config['cf_editor']; + + $html = ""; + + if ($is_dhtml_editor) { + if ($js) { + $html .= ""; + } + $html .= "\n"; + $html .= "웹에디터 시작"; + $html .= "\n"; + $html .= "\n웹 에디터 끝"; + $html .= "\n"; + } else { + $html .= "\n"; + } + return $html; +} + + +// textarea 로 값을 넘긴다. javascript 반드시 필요 +function get_editor_js($id, $is_dhtml_editor=true) +{ + if ($is_dhtml_editor) { + return "document.getElementById('tx_{$id}').value = ed_{$id}.outputBodyHTML();\n"; + } else { + return "var {$id}_editor = document.getElementById('{$id}');\n"; + } +} + + +// textarea 의 값이 비어 있는지 검사 +function chk_editor_js($id, $is_dhtml_editor=true) +{ + if ($is_dhtml_editor) { + return "if (document.getElementById('tx_{$id}') && jQuery.inArray(ed_{$id}.outputBodyHTML().toLowerCase().replace(/^\s*|\s*$/g, ''), [' ','

 

','


','

','

','
','']) != -1) { alert(\"내용을 입력해 주십시오.\"); ed_{$id}.returnFalse(); return false; }\n"; + } else { + return "if (!{$id}_editor.value) { alert(\"내용을 입력해 주십시오.\"); {$id}_editor.focus(); return false; }\n"; + } +} + +/* +https://github.com/timostamm/NonceUtil-PHP +*/ + +if (!defined('FT_NONCE_UNIQUE_KEY')) + define( 'FT_NONCE_UNIQUE_KEY' , sha1($_SERVER['SERVER_SOFTWARE'].G5_MYSQL_USER.session_id().G5_TABLE_PREFIX) ); + +if (!defined('FT_NONCE_SESSION_KEY')) + define( 'FT_NONCE_SESSION_KEY' , substr(md5(FT_NONCE_UNIQUE_KEY), 5) ); + +if (!defined('FT_NONCE_DURATION')) + define( 'FT_NONCE_DURATION' , 60 * 30 ); // 300 makes link or form good for 5 minutes from time of generation, 300은 5분간 유효, 60 * 60 은 1시간 + +if (!defined('FT_NONCE_KEY')) + define( 'FT_NONCE_KEY' , '_nonce' ); + +// This method creates a key / value pair for a url string +if(!function_exists('ft_nonce_create_query_string')){ + function ft_nonce_create_query_string( $action = '' , $user = '' ){ + return FT_NONCE_KEY."=".ft_nonce_create( $action , $user ); + } +} + +if(!function_exists('ft_get_secret_key')){ + function ft_get_secret_key($secret){ + return md5(FT_NONCE_UNIQUE_KEY.$secret); + } +} + +// This method creates an nonce. It should be called by one of the previous two functions. +if(!function_exists('ft_nonce_create')){ + function ft_nonce_create( $action = '',$user='', $timeoutSeconds=FT_NONCE_DURATION ){ + + $secret = ft_get_secret_key($action.$user); + + $salt = ft_nonce_generate_hash(); + $time = time(); + $maxTime = $time + $timeoutSeconds; + $nonce = $salt . "|" . $maxTime . "|" . sha1( $salt . $secret . $maxTime ); + + set_session('nonce_'.FT_NONCE_SESSION_KEY, $nonce); + + return $nonce; + + } +} + +// This method validates an nonce +if(!function_exists('ft_nonce_is_valid')){ + function ft_nonce_is_valid( $nonce, $action = '', $user='' ){ + + $secret = ft_get_secret_key($action.$user); + + if (is_string($nonce) == false) { + return false; + } + $a = explode('|', $nonce); + if (count($a) != 3) { + return false; + } + $salt = $a[0]; + $maxTime = intval($a[1]); + $hash = $a[2]; + $back = sha1( $salt . $secret . $maxTime ); + if ($back != $hash) { + return false; + } + if (time() > $maxTime) { + return false; + } + return true; + } +} + +// This method generates the nonce timestamp +if(!function_exists('ft_nonce_generate_hash')){ + function ft_nonce_generate_hash(){ + $length = 10; + $chars='1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'; + $ll = strlen($chars)-1; + $o = ''; + while (strlen($o) < $length) { + $o .= $chars[ rand(0, $ll) ]; + } + return $o; + } +} +?> \ No newline at end of file diff --git a/plugin/editor/cheditor5/icons/add_col_after.png b/plugin/editor/cheditor5/icons/add_col_after.png new file mode 100644 index 000000000..8a3931455 Binary files /dev/null and b/plugin/editor/cheditor5/icons/add_col_after.png differ diff --git a/plugin/editor/cheditor5/icons/add_col_before.png b/plugin/editor/cheditor5/icons/add_col_before.png new file mode 100644 index 000000000..d8f3a56cc Binary files /dev/null and b/plugin/editor/cheditor5/icons/add_col_before.png differ diff --git a/plugin/editor/cheditor5/icons/add_cols_after.png b/plugin/editor/cheditor5/icons/add_cols_after.png new file mode 100644 index 000000000..d177a0418 Binary files /dev/null and b/plugin/editor/cheditor5/icons/add_cols_after.png differ diff --git a/plugin/editor/cheditor5/icons/add_cols_before.png b/plugin/editor/cheditor5/icons/add_cols_before.png new file mode 100644 index 000000000..b03cbda4f Binary files /dev/null and b/plugin/editor/cheditor5/icons/add_cols_before.png differ diff --git a/plugin/editor/cheditor5/icons/add_row_after.png b/plugin/editor/cheditor5/icons/add_row_after.png new file mode 100644 index 000000000..80c449098 Binary files /dev/null and b/plugin/editor/cheditor5/icons/add_row_after.png differ diff --git a/plugin/editor/cheditor5/icons/add_row_before.png b/plugin/editor/cheditor5/icons/add_row_before.png new file mode 100644 index 000000000..9cff358ae Binary files /dev/null and b/plugin/editor/cheditor5/icons/add_row_before.png differ diff --git a/plugin/editor/cheditor5/icons/add_rows_after.png b/plugin/editor/cheditor5/icons/add_rows_after.png new file mode 100644 index 000000000..579a2db0a Binary files /dev/null and b/plugin/editor/cheditor5/icons/add_rows_after.png differ diff --git a/plugin/editor/cheditor5/icons/add_rows_before.png b/plugin/editor/cheditor5/icons/add_rows_before.png new file mode 100644 index 000000000..45d46b4b0 Binary files /dev/null and b/plugin/editor/cheditor5/icons/add_rows_before.png differ diff --git a/plugin/editor/cheditor5/icons/button/cancel.gif b/plugin/editor/cheditor5/icons/button/cancel.gif new file mode 100644 index 000000000..434323b08 Binary files /dev/null and b/plugin/editor/cheditor5/icons/button/cancel.gif differ diff --git a/plugin/editor/cheditor5/icons/button/color_picker.gif b/plugin/editor/cheditor5/icons/button/color_picker.gif new file mode 100644 index 000000000..16826bfb7 Binary files /dev/null and b/plugin/editor/cheditor5/icons/button/color_picker.gif differ diff --git a/plugin/editor/cheditor5/icons/button/color_picker.png b/plugin/editor/cheditor5/icons/button/color_picker.png new file mode 100644 index 000000000..3b8cf1da0 Binary files /dev/null and b/plugin/editor/cheditor5/icons/button/color_picker.png differ diff --git a/plugin/editor/cheditor5/icons/button/color_picker_disable.png b/plugin/editor/cheditor5/icons/button/color_picker_disable.png new file mode 100644 index 000000000..34d8a2292 Binary files /dev/null and b/plugin/editor/cheditor5/icons/button/color_picker_disable.png differ diff --git a/plugin/editor/cheditor5/icons/button/delete.gif b/plugin/editor/cheditor5/icons/button/delete.gif new file mode 100644 index 000000000..5a03749f6 Binary files /dev/null and b/plugin/editor/cheditor5/icons/button/delete.gif differ diff --git a/plugin/editor/cheditor5/icons/button/delete_cross.gif b/plugin/editor/cheditor5/icons/button/delete_cross.gif new file mode 100644 index 000000000..449d63a27 Binary files /dev/null and b/plugin/editor/cheditor5/icons/button/delete_cross.gif differ diff --git a/plugin/editor/cheditor5/icons/button/edit_cell.gif b/plugin/editor/cheditor5/icons/button/edit_cell.gif new file mode 100644 index 000000000..6022fc400 Binary files /dev/null and b/plugin/editor/cheditor5/icons/button/edit_cell.gif differ diff --git a/plugin/editor/cheditor5/icons/button/edit_image.gif b/plugin/editor/cheditor5/icons/button/edit_image.gif new file mode 100644 index 000000000..7bf05a0e8 Binary files /dev/null and b/plugin/editor/cheditor5/icons/button/edit_image.gif differ diff --git a/plugin/editor/cheditor5/icons/button/input.gif b/plugin/editor/cheditor5/icons/button/input.gif new file mode 100644 index 000000000..ef9316e54 Binary files /dev/null and b/plugin/editor/cheditor5/icons/button/input.gif differ diff --git a/plugin/editor/cheditor5/icons/button/input_color.gif b/plugin/editor/cheditor5/icons/button/input_color.gif new file mode 100644 index 000000000..3f7188068 Binary files /dev/null and b/plugin/editor/cheditor5/icons/button/input_color.gif differ diff --git a/plugin/editor/cheditor5/icons/button/map_address.gif b/plugin/editor/cheditor5/icons/button/map_address.gif new file mode 100644 index 000000000..18feee9da Binary files /dev/null and b/plugin/editor/cheditor5/icons/button/map_address.gif differ diff --git a/plugin/editor/cheditor5/icons/button/paste.gif b/plugin/editor/cheditor5/icons/button/paste.gif new file mode 100644 index 000000000..debe8505e Binary files /dev/null and b/plugin/editor/cheditor5/icons/button/paste.gif differ diff --git a/plugin/editor/cheditor5/icons/button/play.gif b/plugin/editor/cheditor5/icons/button/play.gif new file mode 100644 index 000000000..d7da13820 Binary files /dev/null and b/plugin/editor/cheditor5/icons/button/play.gif differ diff --git a/plugin/editor/cheditor5/icons/button/preview.gif b/plugin/editor/cheditor5/icons/button/preview.gif new file mode 100644 index 000000000..9ec331fe8 Binary files /dev/null and b/plugin/editor/cheditor5/icons/button/preview.gif differ diff --git a/plugin/editor/cheditor5/icons/button/process.gif b/plugin/editor/cheditor5/icons/button/process.gif new file mode 100644 index 000000000..8c33eb269 Binary files /dev/null and b/plugin/editor/cheditor5/icons/button/process.gif differ diff --git a/plugin/editor/cheditor5/icons/button/reset.gif b/plugin/editor/cheditor5/icons/button/reset.gif new file mode 100644 index 000000000..9cce769de Binary files /dev/null and b/plugin/editor/cheditor5/icons/button/reset.gif differ diff --git a/plugin/editor/cheditor5/icons/button/submit.gif b/plugin/editor/cheditor5/icons/button/submit.gif new file mode 100644 index 000000000..3e5af8d64 Binary files /dev/null and b/plugin/editor/cheditor5/icons/button/submit.gif differ diff --git a/plugin/editor/cheditor5/icons/button/upload.gif b/plugin/editor/cheditor5/icons/button/upload.gif new file mode 100644 index 000000000..1accaba05 Binary files /dev/null and b/plugin/editor/cheditor5/icons/button/upload.gif differ diff --git a/plugin/editor/cheditor5/icons/checked.png b/plugin/editor/cheditor5/icons/checked.png new file mode 100644 index 000000000..029325ef6 Binary files /dev/null and b/plugin/editor/cheditor5/icons/checked.png differ diff --git a/plugin/editor/cheditor5/icons/color_picker.png b/plugin/editor/cheditor5/icons/color_picker.png new file mode 100644 index 000000000..3ed7f5589 Binary files /dev/null and b/plugin/editor/cheditor5/icons/color_picker.png differ diff --git a/plugin/editor/cheditor5/icons/color_picker_arrow.gif b/plugin/editor/cheditor5/icons/color_picker_arrow.gif new file mode 100644 index 000000000..246478a86 Binary files /dev/null and b/plugin/editor/cheditor5/icons/color_picker_arrow.gif differ diff --git a/plugin/editor/cheditor5/icons/color_picker_cross.gif b/plugin/editor/cheditor5/icons/color_picker_cross.gif new file mode 100644 index 000000000..089b6d159 Binary files /dev/null and b/plugin/editor/cheditor5/icons/color_picker_cross.gif differ diff --git a/plugin/editor/cheditor5/icons/color_picker_hs.png b/plugin/editor/cheditor5/icons/color_picker_hs.png new file mode 100644 index 000000000..3d94486ce Binary files /dev/null and b/plugin/editor/cheditor5/icons/color_picker_hs.png differ diff --git a/plugin/editor/cheditor5/icons/color_picker_hv.png b/plugin/editor/cheditor5/icons/color_picker_hv.png new file mode 100644 index 000000000..1c5e01f8b Binary files /dev/null and b/plugin/editor/cheditor5/icons/color_picker_hv.png differ diff --git a/plugin/editor/cheditor5/icons/color_picker_reset.png b/plugin/editor/cheditor5/icons/color_picker_reset.png new file mode 100644 index 000000000..ba719a746 Binary files /dev/null and b/plugin/editor/cheditor5/icons/color_picker_reset.png differ diff --git a/plugin/editor/cheditor5/icons/color_picker_tick.png b/plugin/editor/cheditor5/icons/color_picker_tick.png new file mode 100644 index 000000000..a48d9da7d Binary files /dev/null and b/plugin/editor/cheditor5/icons/color_picker_tick.png differ diff --git a/plugin/editor/cheditor5/icons/delete_element.png b/plugin/editor/cheditor5/icons/delete_element.png new file mode 100644 index 000000000..80e1db21f Binary files /dev/null and b/plugin/editor/cheditor5/icons/delete_element.png differ diff --git a/plugin/editor/cheditor5/icons/delete_table.png b/plugin/editor/cheditor5/icons/delete_table.png new file mode 100644 index 000000000..87805c966 Binary files /dev/null and b/plugin/editor/cheditor5/icons/delete_table.png differ diff --git a/plugin/editor/cheditor5/icons/dot.gif b/plugin/editor/cheditor5/icons/dot.gif new file mode 100644 index 000000000..1d11fa9ad Binary files /dev/null and b/plugin/editor/cheditor5/icons/dot.gif differ diff --git a/plugin/editor/cheditor5/icons/edit_mode_code_a.png b/plugin/editor/cheditor5/icons/edit_mode_code_a.png new file mode 100644 index 000000000..31f00d9db Binary files /dev/null and b/plugin/editor/cheditor5/icons/edit_mode_code_a.png differ diff --git a/plugin/editor/cheditor5/icons/edit_mode_code_b.png b/plugin/editor/cheditor5/icons/edit_mode_code_b.png new file mode 100644 index 000000000..2ced606d5 Binary files /dev/null and b/plugin/editor/cheditor5/icons/edit_mode_code_b.png differ diff --git a/plugin/editor/cheditor5/icons/edit_mode_rich_a.png b/plugin/editor/cheditor5/icons/edit_mode_rich_a.png new file mode 100644 index 000000000..497b4e859 Binary files /dev/null and b/plugin/editor/cheditor5/icons/edit_mode_rich_a.png differ diff --git a/plugin/editor/cheditor5/icons/edit_mode_rich_b.png b/plugin/editor/cheditor5/icons/edit_mode_rich_b.png new file mode 100644 index 000000000..732f8253d Binary files /dev/null and b/plugin/editor/cheditor5/icons/edit_mode_rich_b.png differ diff --git a/plugin/editor/cheditor5/icons/edit_mode_view_a.png b/plugin/editor/cheditor5/icons/edit_mode_view_a.png new file mode 100644 index 000000000..e14add229 Binary files /dev/null and b/plugin/editor/cheditor5/icons/edit_mode_view_a.png differ diff --git a/plugin/editor/cheditor5/icons/edit_mode_view_b.png b/plugin/editor/cheditor5/icons/edit_mode_view_b.png new file mode 100644 index 000000000..29fe9077a Binary files /dev/null and b/plugin/editor/cheditor5/icons/edit_mode_view_b.png differ diff --git a/plugin/editor/cheditor5/icons/em/1.gif b/plugin/editor/cheditor5/icons/em/1.gif new file mode 100644 index 000000000..192f26f6a Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/1.gif differ diff --git a/plugin/editor/cheditor5/icons/em/10.gif b/plugin/editor/cheditor5/icons/em/10.gif new file mode 100644 index 000000000..67dabd59f Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/10.gif differ diff --git a/plugin/editor/cheditor5/icons/em/11.gif b/plugin/editor/cheditor5/icons/em/11.gif new file mode 100644 index 000000000..aab89b103 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/11.gif differ diff --git a/plugin/editor/cheditor5/icons/em/12.gif b/plugin/editor/cheditor5/icons/em/12.gif new file mode 100644 index 000000000..dcc1c8f64 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/12.gif differ diff --git a/plugin/editor/cheditor5/icons/em/13.gif b/plugin/editor/cheditor5/icons/em/13.gif new file mode 100644 index 000000000..221e0f2e2 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/13.gif differ diff --git a/plugin/editor/cheditor5/icons/em/14.gif b/plugin/editor/cheditor5/icons/em/14.gif new file mode 100644 index 000000000..c2184a3d7 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/14.gif differ diff --git a/plugin/editor/cheditor5/icons/em/15.gif b/plugin/editor/cheditor5/icons/em/15.gif new file mode 100644 index 000000000..adb78d17a Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/15.gif differ diff --git a/plugin/editor/cheditor5/icons/em/16.gif b/plugin/editor/cheditor5/icons/em/16.gif new file mode 100644 index 000000000..164bcce0f Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/16.gif differ diff --git a/plugin/editor/cheditor5/icons/em/17.gif b/plugin/editor/cheditor5/icons/em/17.gif new file mode 100644 index 000000000..79382ce8a Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/17.gif differ diff --git a/plugin/editor/cheditor5/icons/em/18.gif b/plugin/editor/cheditor5/icons/em/18.gif new file mode 100644 index 000000000..ff0eb9652 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/18.gif differ diff --git a/plugin/editor/cheditor5/icons/em/19.gif b/plugin/editor/cheditor5/icons/em/19.gif new file mode 100644 index 000000000..1097e0087 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/19.gif differ diff --git a/plugin/editor/cheditor5/icons/em/2.gif b/plugin/editor/cheditor5/icons/em/2.gif new file mode 100644 index 000000000..9c83e50cc Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/2.gif differ diff --git a/plugin/editor/cheditor5/icons/em/20.gif b/plugin/editor/cheditor5/icons/em/20.gif new file mode 100644 index 000000000..e55ec3081 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/20.gif differ diff --git a/plugin/editor/cheditor5/icons/em/21.gif b/plugin/editor/cheditor5/icons/em/21.gif new file mode 100644 index 000000000..0186a11a7 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/21.gif differ diff --git a/plugin/editor/cheditor5/icons/em/22.gif b/plugin/editor/cheditor5/icons/em/22.gif new file mode 100644 index 000000000..c46dec6cc Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/22.gif differ diff --git a/plugin/editor/cheditor5/icons/em/23.gif b/plugin/editor/cheditor5/icons/em/23.gif new file mode 100644 index 000000000..aacda1a15 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/23.gif differ diff --git a/plugin/editor/cheditor5/icons/em/24.gif b/plugin/editor/cheditor5/icons/em/24.gif new file mode 100644 index 000000000..3afc89869 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/24.gif differ diff --git a/plugin/editor/cheditor5/icons/em/25.gif b/plugin/editor/cheditor5/icons/em/25.gif new file mode 100644 index 000000000..0e26fe05c Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/25.gif differ diff --git a/plugin/editor/cheditor5/icons/em/26.gif b/plugin/editor/cheditor5/icons/em/26.gif new file mode 100644 index 000000000..4dfcdab22 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/26.gif differ diff --git a/plugin/editor/cheditor5/icons/em/27.gif b/plugin/editor/cheditor5/icons/em/27.gif new file mode 100644 index 000000000..8aae5c516 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/27.gif differ diff --git a/plugin/editor/cheditor5/icons/em/28.gif b/plugin/editor/cheditor5/icons/em/28.gif new file mode 100644 index 000000000..c3aee8660 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/28.gif differ diff --git a/plugin/editor/cheditor5/icons/em/29.gif b/plugin/editor/cheditor5/icons/em/29.gif new file mode 100644 index 000000000..39cc0c286 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/29.gif differ diff --git a/plugin/editor/cheditor5/icons/em/3.gif b/plugin/editor/cheditor5/icons/em/3.gif new file mode 100644 index 000000000..b68cfb128 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/3.gif differ diff --git a/plugin/editor/cheditor5/icons/em/30.gif b/plugin/editor/cheditor5/icons/em/30.gif new file mode 100644 index 000000000..51054ede6 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/30.gif differ diff --git a/plugin/editor/cheditor5/icons/em/31.gif b/plugin/editor/cheditor5/icons/em/31.gif new file mode 100644 index 000000000..51e9ab344 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/31.gif differ diff --git a/plugin/editor/cheditor5/icons/em/32.gif b/plugin/editor/cheditor5/icons/em/32.gif new file mode 100644 index 000000000..3d084cc8b Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/32.gif differ diff --git a/plugin/editor/cheditor5/icons/em/33.gif b/plugin/editor/cheditor5/icons/em/33.gif new file mode 100644 index 000000000..465a86764 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/33.gif differ diff --git a/plugin/editor/cheditor5/icons/em/34.gif b/plugin/editor/cheditor5/icons/em/34.gif new file mode 100644 index 000000000..b7c2bb619 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/34.gif differ diff --git a/plugin/editor/cheditor5/icons/em/35.gif b/plugin/editor/cheditor5/icons/em/35.gif new file mode 100644 index 000000000..9e006337c Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/35.gif differ diff --git a/plugin/editor/cheditor5/icons/em/36.gif b/plugin/editor/cheditor5/icons/em/36.gif new file mode 100644 index 000000000..779454291 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/36.gif differ diff --git a/plugin/editor/cheditor5/icons/em/37.gif b/plugin/editor/cheditor5/icons/em/37.gif new file mode 100644 index 000000000..e21691762 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/37.gif differ diff --git a/plugin/editor/cheditor5/icons/em/38.gif b/plugin/editor/cheditor5/icons/em/38.gif new file mode 100644 index 000000000..76a9e13b2 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/38.gif differ diff --git a/plugin/editor/cheditor5/icons/em/39.gif b/plugin/editor/cheditor5/icons/em/39.gif new file mode 100644 index 000000000..f3fd4e7b4 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/39.gif differ diff --git a/plugin/editor/cheditor5/icons/em/4.gif b/plugin/editor/cheditor5/icons/em/4.gif new file mode 100644 index 000000000..99851b3f5 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/4.gif differ diff --git a/plugin/editor/cheditor5/icons/em/40.gif b/plugin/editor/cheditor5/icons/em/40.gif new file mode 100644 index 000000000..40f2ac17b Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/40.gif differ diff --git a/plugin/editor/cheditor5/icons/em/41.gif b/plugin/editor/cheditor5/icons/em/41.gif new file mode 100644 index 000000000..5af0bb1f4 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/41.gif differ diff --git a/plugin/editor/cheditor5/icons/em/42.gif b/plugin/editor/cheditor5/icons/em/42.gif new file mode 100644 index 000000000..e5dfb8dc7 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/42.gif differ diff --git a/plugin/editor/cheditor5/icons/em/43.gif b/plugin/editor/cheditor5/icons/em/43.gif new file mode 100644 index 000000000..c54a84c50 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/43.gif differ diff --git a/plugin/editor/cheditor5/icons/em/44.gif b/plugin/editor/cheditor5/icons/em/44.gif new file mode 100644 index 000000000..ca4abf9e2 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/44.gif differ diff --git a/plugin/editor/cheditor5/icons/em/45.gif b/plugin/editor/cheditor5/icons/em/45.gif new file mode 100644 index 000000000..9efbf4752 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/45.gif differ diff --git a/plugin/editor/cheditor5/icons/em/46.gif b/plugin/editor/cheditor5/icons/em/46.gif new file mode 100644 index 000000000..687b4f41f Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/46.gif differ diff --git a/plugin/editor/cheditor5/icons/em/47.gif b/plugin/editor/cheditor5/icons/em/47.gif new file mode 100644 index 000000000..8fc0b3563 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/47.gif differ diff --git a/plugin/editor/cheditor5/icons/em/48.gif b/plugin/editor/cheditor5/icons/em/48.gif new file mode 100644 index 000000000..7467a5a12 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/48.gif differ diff --git a/plugin/editor/cheditor5/icons/em/49.gif b/plugin/editor/cheditor5/icons/em/49.gif new file mode 100644 index 000000000..3baf57d92 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/49.gif differ diff --git a/plugin/editor/cheditor5/icons/em/5.gif b/plugin/editor/cheditor5/icons/em/5.gif new file mode 100644 index 000000000..50e09671f Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/5.gif differ diff --git a/plugin/editor/cheditor5/icons/em/50.gif b/plugin/editor/cheditor5/icons/em/50.gif new file mode 100644 index 000000000..f9e49d644 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/50.gif differ diff --git a/plugin/editor/cheditor5/icons/em/51.gif b/plugin/editor/cheditor5/icons/em/51.gif new file mode 100644 index 000000000..2bcbccde9 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/51.gif differ diff --git a/plugin/editor/cheditor5/icons/em/52.gif b/plugin/editor/cheditor5/icons/em/52.gif new file mode 100644 index 000000000..72e7ecdfc Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/52.gif differ diff --git a/plugin/editor/cheditor5/icons/em/53.gif b/plugin/editor/cheditor5/icons/em/53.gif new file mode 100644 index 000000000..91f1e96bf Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/53.gif differ diff --git a/plugin/editor/cheditor5/icons/em/54.gif b/plugin/editor/cheditor5/icons/em/54.gif new file mode 100644 index 000000000..3b0b8d3d2 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/54.gif differ diff --git a/plugin/editor/cheditor5/icons/em/55.gif b/plugin/editor/cheditor5/icons/em/55.gif new file mode 100644 index 000000000..28679aae5 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/55.gif differ diff --git a/plugin/editor/cheditor5/icons/em/56.gif b/plugin/editor/cheditor5/icons/em/56.gif new file mode 100644 index 000000000..9d46e2964 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/56.gif differ diff --git a/plugin/editor/cheditor5/icons/em/57.gif b/plugin/editor/cheditor5/icons/em/57.gif new file mode 100644 index 000000000..94540e86b Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/57.gif differ diff --git a/plugin/editor/cheditor5/icons/em/58.gif b/plugin/editor/cheditor5/icons/em/58.gif new file mode 100644 index 000000000..4f7cefdad Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/58.gif differ diff --git a/plugin/editor/cheditor5/icons/em/59.gif b/plugin/editor/cheditor5/icons/em/59.gif new file mode 100644 index 000000000..6324cf14d Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/59.gif differ diff --git a/plugin/editor/cheditor5/icons/em/6.gif b/plugin/editor/cheditor5/icons/em/6.gif new file mode 100644 index 000000000..e39f4cf22 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/6.gif differ diff --git a/plugin/editor/cheditor5/icons/em/60.gif b/plugin/editor/cheditor5/icons/em/60.gif new file mode 100644 index 000000000..83f401007 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/60.gif differ diff --git a/plugin/editor/cheditor5/icons/em/61.gif b/plugin/editor/cheditor5/icons/em/61.gif new file mode 100644 index 000000000..5c297e388 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/61.gif differ diff --git a/plugin/editor/cheditor5/icons/em/62.gif b/plugin/editor/cheditor5/icons/em/62.gif new file mode 100644 index 000000000..71c0c8979 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/62.gif differ diff --git a/plugin/editor/cheditor5/icons/em/63.gif b/plugin/editor/cheditor5/icons/em/63.gif new file mode 100644 index 000000000..a66a51b03 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/63.gif differ diff --git a/plugin/editor/cheditor5/icons/em/64.gif b/plugin/editor/cheditor5/icons/em/64.gif new file mode 100644 index 000000000..e5cb6ca06 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/64.gif differ diff --git a/plugin/editor/cheditor5/icons/em/65.gif b/plugin/editor/cheditor5/icons/em/65.gif new file mode 100644 index 000000000..027f28edf Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/65.gif differ diff --git a/plugin/editor/cheditor5/icons/em/66.gif b/plugin/editor/cheditor5/icons/em/66.gif new file mode 100644 index 000000000..faca98013 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/66.gif differ diff --git a/plugin/editor/cheditor5/icons/em/67.gif b/plugin/editor/cheditor5/icons/em/67.gif new file mode 100644 index 000000000..42bd45300 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/67.gif differ diff --git a/plugin/editor/cheditor5/icons/em/68.gif b/plugin/editor/cheditor5/icons/em/68.gif new file mode 100644 index 000000000..214345180 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/68.gif differ diff --git a/plugin/editor/cheditor5/icons/em/69.gif b/plugin/editor/cheditor5/icons/em/69.gif new file mode 100644 index 000000000..0f9a4de5c Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/69.gif differ diff --git a/plugin/editor/cheditor5/icons/em/7.gif b/plugin/editor/cheditor5/icons/em/7.gif new file mode 100644 index 000000000..330fc953c Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/7.gif differ diff --git a/plugin/editor/cheditor5/icons/em/70.gif b/plugin/editor/cheditor5/icons/em/70.gif new file mode 100644 index 000000000..c107a14af Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/70.gif differ diff --git a/plugin/editor/cheditor5/icons/em/71.gif b/plugin/editor/cheditor5/icons/em/71.gif new file mode 100644 index 000000000..62618d659 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/71.gif differ diff --git a/plugin/editor/cheditor5/icons/em/72.gif b/plugin/editor/cheditor5/icons/em/72.gif new file mode 100644 index 000000000..6764e3228 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/72.gif differ diff --git a/plugin/editor/cheditor5/icons/em/73.gif b/plugin/editor/cheditor5/icons/em/73.gif new file mode 100644 index 000000000..29ecc580e Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/73.gif differ diff --git a/plugin/editor/cheditor5/icons/em/74.gif b/plugin/editor/cheditor5/icons/em/74.gif new file mode 100644 index 000000000..18d684e76 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/74.gif differ diff --git a/plugin/editor/cheditor5/icons/em/75.gif b/plugin/editor/cheditor5/icons/em/75.gif new file mode 100644 index 000000000..18a7b9220 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/75.gif differ diff --git a/plugin/editor/cheditor5/icons/em/76.gif b/plugin/editor/cheditor5/icons/em/76.gif new file mode 100644 index 000000000..ebdb2c942 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/76.gif differ diff --git a/plugin/editor/cheditor5/icons/em/77.gif b/plugin/editor/cheditor5/icons/em/77.gif new file mode 100644 index 000000000..0a996d59e Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/77.gif differ diff --git a/plugin/editor/cheditor5/icons/em/78.gif b/plugin/editor/cheditor5/icons/em/78.gif new file mode 100644 index 000000000..972a21d83 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/78.gif differ diff --git a/plugin/editor/cheditor5/icons/em/79.gif b/plugin/editor/cheditor5/icons/em/79.gif new file mode 100644 index 000000000..3fa89d82e Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/79.gif differ diff --git a/plugin/editor/cheditor5/icons/em/8.gif b/plugin/editor/cheditor5/icons/em/8.gif new file mode 100644 index 000000000..b573e9b3e Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/8.gif differ diff --git a/plugin/editor/cheditor5/icons/em/80.gif b/plugin/editor/cheditor5/icons/em/80.gif new file mode 100644 index 000000000..84e3ca417 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/80.gif differ diff --git a/plugin/editor/cheditor5/icons/em/9.gif b/plugin/editor/cheditor5/icons/em/9.gif new file mode 100644 index 000000000..1521dd484 Binary files /dev/null and b/plugin/editor/cheditor5/icons/em/9.gif differ diff --git a/plugin/editor/cheditor5/icons/fullscreen.png b/plugin/editor/cheditor5/icons/fullscreen.png new file mode 100644 index 000000000..4111243ac Binary files /dev/null and b/plugin/editor/cheditor5/icons/fullscreen.png differ diff --git a/plugin/editor/cheditor5/icons/fullscreen_actual.png b/plugin/editor/cheditor5/icons/fullscreen_actual.png new file mode 100644 index 000000000..60de27e99 Binary files /dev/null and b/plugin/editor/cheditor5/icons/fullscreen_actual.png differ diff --git a/plugin/editor/cheditor5/icons/imageUpload/add.gif b/plugin/editor/cheditor5/icons/imageUpload/add.gif new file mode 100644 index 000000000..5db2a6688 Binary files /dev/null and b/plugin/editor/cheditor5/icons/imageUpload/add.gif differ diff --git a/plugin/editor/cheditor5/icons/imageUpload/cross-small.png b/plugin/editor/cheditor5/icons/imageUpload/cross-small.png new file mode 100644 index 000000000..2de4c1203 Binary files /dev/null and b/plugin/editor/cheditor5/icons/imageUpload/cross-small.png differ diff --git a/plugin/editor/cheditor5/icons/imageUpload/delete.png b/plugin/editor/cheditor5/icons/imageUpload/delete.png new file mode 100644 index 000000000..8f11cfc75 Binary files /dev/null and b/plugin/editor/cheditor5/icons/imageUpload/delete.png differ diff --git a/plugin/editor/cheditor5/icons/imageUpload/dot.gif b/plugin/editor/cheditor5/icons/imageUpload/dot.gif new file mode 100644 index 000000000..1d11fa9ad Binary files /dev/null and b/plugin/editor/cheditor5/icons/imageUpload/dot.gif differ diff --git a/plugin/editor/cheditor5/icons/imageUpload/loader.gif b/plugin/editor/cheditor5/icons/imageUpload/loader.gif new file mode 100644 index 000000000..d42f72c72 Binary files /dev/null and b/plugin/editor/cheditor5/icons/imageUpload/loader.gif differ diff --git a/plugin/editor/cheditor5/icons/imageUpload/marker_bottom.gif b/plugin/editor/cheditor5/icons/imageUpload/marker_bottom.gif new file mode 100644 index 000000000..daa101c00 Binary files /dev/null and b/plugin/editor/cheditor5/icons/imageUpload/marker_bottom.gif differ diff --git a/plugin/editor/cheditor5/icons/imageUpload/marker_middle.gif b/plugin/editor/cheditor5/icons/imageUpload/marker_middle.gif new file mode 100644 index 000000000..a854393c4 Binary files /dev/null and b/plugin/editor/cheditor5/icons/imageUpload/marker_middle.gif differ diff --git a/plugin/editor/cheditor5/icons/imageUpload/marker_top.gif b/plugin/editor/cheditor5/icons/imageUpload/marker_top.gif new file mode 100644 index 000000000..daa101c00 Binary files /dev/null and b/plugin/editor/cheditor5/icons/imageUpload/marker_top.gif differ diff --git a/plugin/editor/cheditor5/icons/imageUpload/mouse_drag_img.gif b/plugin/editor/cheditor5/icons/imageUpload/mouse_drag_img.gif new file mode 100644 index 000000000..4cd7fe127 Binary files /dev/null and b/plugin/editor/cheditor5/icons/imageUpload/mouse_drag_img.gif differ diff --git a/plugin/editor/cheditor5/icons/imageUpload/remove_all.gif b/plugin/editor/cheditor5/icons/imageUpload/remove_all.gif new file mode 100644 index 000000000..fcda632fd Binary files /dev/null and b/plugin/editor/cheditor5/icons/imageUpload/remove_all.gif differ diff --git a/plugin/editor/cheditor5/icons/image_align_center.png b/plugin/editor/cheditor5/icons/image_align_center.png new file mode 100644 index 000000000..d2ee3baad Binary files /dev/null and b/plugin/editor/cheditor5/icons/image_align_center.png differ diff --git a/plugin/editor/cheditor5/icons/image_align_left.png b/plugin/editor/cheditor5/icons/image_align_left.png new file mode 100644 index 000000000..7195ef77b Binary files /dev/null and b/plugin/editor/cheditor5/icons/image_align_left.png differ diff --git a/plugin/editor/cheditor5/icons/image_align_left_wt.png b/plugin/editor/cheditor5/icons/image_align_left_wt.png new file mode 100644 index 000000000..7cc2f5a4b Binary files /dev/null and b/plugin/editor/cheditor5/icons/image_align_left_wt.png differ diff --git a/plugin/editor/cheditor5/icons/image_align_right.png b/plugin/editor/cheditor5/icons/image_align_right.png new file mode 100644 index 000000000..2705dcb82 Binary files /dev/null and b/plugin/editor/cheditor5/icons/image_align_right.png differ diff --git a/plugin/editor/cheditor5/icons/image_align_right_wt.png b/plugin/editor/cheditor5/icons/image_align_right_wt.png new file mode 100644 index 000000000..16b0cf6d2 Binary files /dev/null and b/plugin/editor/cheditor5/icons/image_align_right_wt.png differ diff --git a/plugin/editor/cheditor5/icons/image_resize.png b/plugin/editor/cheditor5/icons/image_resize.png new file mode 100644 index 000000000..a1eb71979 Binary files /dev/null and b/plugin/editor/cheditor5/icons/image_resize.png differ diff --git a/plugin/editor/cheditor5/icons/image_wrap_text.png b/plugin/editor/cheditor5/icons/image_wrap_text.png new file mode 100644 index 000000000..7cc2f5a4b Binary files /dev/null and b/plugin/editor/cheditor5/icons/image_wrap_text.png differ diff --git a/plugin/editor/cheditor5/icons/magnifier-zoom.png b/plugin/editor/cheditor5/icons/magnifier-zoom.png new file mode 100644 index 000000000..77e03059a Binary files /dev/null and b/plugin/editor/cheditor5/icons/magnifier-zoom.png differ diff --git a/plugin/editor/cheditor5/icons/readonlymode.png b/plugin/editor/cheditor5/icons/readonlymode.png new file mode 100644 index 000000000..f1c5c2420 Binary files /dev/null and b/plugin/editor/cheditor5/icons/readonlymode.png differ diff --git a/plugin/editor/cheditor5/icons/remove_col.png b/plugin/editor/cheditor5/icons/remove_col.png new file mode 100644 index 000000000..2193adef8 Binary files /dev/null and b/plugin/editor/cheditor5/icons/remove_col.png differ diff --git a/plugin/editor/cheditor5/icons/remove_cols.png b/plugin/editor/cheditor5/icons/remove_cols.png new file mode 100644 index 000000000..fdbfcd914 Binary files /dev/null and b/plugin/editor/cheditor5/icons/remove_cols.png differ diff --git a/plugin/editor/cheditor5/icons/remove_row.png b/plugin/editor/cheditor5/icons/remove_row.png new file mode 100644 index 000000000..8a82c6b33 Binary files /dev/null and b/plugin/editor/cheditor5/icons/remove_row.png differ diff --git a/plugin/editor/cheditor5/icons/remove_rows.png b/plugin/editor/cheditor5/icons/remove_rows.png new file mode 100644 index 000000000..e2d9588f2 Binary files /dev/null and b/plugin/editor/cheditor5/icons/remove_rows.png differ diff --git a/plugin/editor/cheditor5/icons/splitter.gif b/plugin/editor/cheditor5/icons/splitter.gif new file mode 100644 index 000000000..660bb40df Binary files /dev/null and b/plugin/editor/cheditor5/icons/splitter.gif differ diff --git a/plugin/editor/cheditor5/icons/statusbar_bgline.gif b/plugin/editor/cheditor5/icons/statusbar_bgline.gif new file mode 100644 index 000000000..850fdecf5 Binary files /dev/null and b/plugin/editor/cheditor5/icons/statusbar_bgline.gif differ diff --git a/plugin/editor/cheditor5/icons/table_delete_cell.png b/plugin/editor/cheditor5/icons/table_delete_cell.png new file mode 100644 index 000000000..38dfcec15 Binary files /dev/null and b/plugin/editor/cheditor5/icons/table_delete_cell.png differ diff --git a/plugin/editor/cheditor5/icons/table_delete_column.png b/plugin/editor/cheditor5/icons/table_delete_column.png new file mode 100644 index 000000000..ea515ca89 Binary files /dev/null and b/plugin/editor/cheditor5/icons/table_delete_column.png differ diff --git a/plugin/editor/cheditor5/icons/table_delete_row.png b/plugin/editor/cheditor5/icons/table_delete_row.png new file mode 100644 index 000000000..cb4083c66 Binary files /dev/null and b/plugin/editor/cheditor5/icons/table_delete_row.png differ diff --git a/plugin/editor/cheditor5/icons/table_insert_cell.png b/plugin/editor/cheditor5/icons/table_insert_cell.png new file mode 100644 index 000000000..bc70ca07d Binary files /dev/null and b/plugin/editor/cheditor5/icons/table_insert_cell.png differ diff --git a/plugin/editor/cheditor5/icons/table_insert_column.png b/plugin/editor/cheditor5/icons/table_insert_column.png new file mode 100644 index 000000000..a2f7f5a85 Binary files /dev/null and b/plugin/editor/cheditor5/icons/table_insert_column.png differ diff --git a/plugin/editor/cheditor5/icons/table_insert_row.png b/plugin/editor/cheditor5/icons/table_insert_row.png new file mode 100644 index 000000000..dda90a344 Binary files /dev/null and b/plugin/editor/cheditor5/icons/table_insert_row.png differ diff --git a/plugin/editor/cheditor5/icons/table_join.png b/plugin/editor/cheditor5/icons/table_join.png new file mode 100644 index 000000000..a5c0f9db9 Binary files /dev/null and b/plugin/editor/cheditor5/icons/table_join.png differ diff --git a/plugin/editor/cheditor5/icons/table_join_column.png b/plugin/editor/cheditor5/icons/table_join_column.png new file mode 100644 index 000000000..830afd95e Binary files /dev/null and b/plugin/editor/cheditor5/icons/table_join_column.png differ diff --git a/plugin/editor/cheditor5/icons/table_join_row.png b/plugin/editor/cheditor5/icons/table_join_row.png new file mode 100644 index 000000000..c77e75c10 Binary files /dev/null and b/plugin/editor/cheditor5/icons/table_join_row.png differ diff --git a/plugin/editor/cheditor5/icons/table_split_column.png b/plugin/editor/cheditor5/icons/table_split_column.png new file mode 100644 index 000000000..f7dc6c154 Binary files /dev/null and b/plugin/editor/cheditor5/icons/table_split_column.png differ diff --git a/plugin/editor/cheditor5/icons/table_split_row.png b/plugin/editor/cheditor5/icons/table_split_row.png new file mode 100644 index 000000000..55b822e2f Binary files /dev/null and b/plugin/editor/cheditor5/icons/table_split_row.png differ diff --git a/plugin/editor/cheditor5/icons/title_bar_bg.gif b/plugin/editor/cheditor5/icons/title_bar_bg.gif new file mode 100644 index 000000000..13e78660f Binary files /dev/null and b/plugin/editor/cheditor5/icons/title_bar_bg.gif differ diff --git a/plugin/editor/cheditor5/icons/title_bar_bg2.gif b/plugin/editor/cheditor5/icons/title_bar_bg2.gif new file mode 100644 index 000000000..86617c6c5 Binary files /dev/null and b/plugin/editor/cheditor5/icons/title_bar_bg2.gif differ diff --git a/plugin/editor/cheditor5/icons/toolbar-background.png b/plugin/editor/cheditor5/icons/toolbar-background.png new file mode 100644 index 000000000..22de6225b Binary files /dev/null and b/plugin/editor/cheditor5/icons/toolbar-background.png differ diff --git a/plugin/editor/cheditor5/icons/toolbar-wrapper-bg.png b/plugin/editor/cheditor5/icons/toolbar-wrapper-bg.png new file mode 100644 index 000000000..f3c1f7530 Binary files /dev/null and b/plugin/editor/cheditor5/icons/toolbar-wrapper-bg.png differ diff --git a/plugin/editor/cheditor5/icons/toolbar.png b/plugin/editor/cheditor5/icons/toolbar.png new file mode 100644 index 000000000..6c81e8825 Binary files /dev/null and b/plugin/editor/cheditor5/icons/toolbar.png differ diff --git a/plugin/editor/cheditor5/icons/viewmode_code.png b/plugin/editor/cheditor5/icons/viewmode_code.png new file mode 100644 index 000000000..b046f1689 Binary files /dev/null and b/plugin/editor/cheditor5/icons/viewmode_code.png differ diff --git a/plugin/editor/cheditor5/icons/viewmode_preview.png b/plugin/editor/cheditor5/icons/viewmode_preview.png new file mode 100644 index 000000000..bd6df170c Binary files /dev/null and b/plugin/editor/cheditor5/icons/viewmode_preview.png differ diff --git a/plugin/editor/cheditor5/icons/watermark.png b/plugin/editor/cheditor5/icons/watermark.png new file mode 100644 index 000000000..071fb3fcc Binary files /dev/null and b/plugin/editor/cheditor5/icons/watermark.png differ diff --git a/plugin/editor/cheditor5/imageUpload/_common.php b/plugin/editor/cheditor5/imageUpload/_common.php new file mode 100644 index 000000000..6d489dacb --- /dev/null +++ b/plugin/editor/cheditor5/imageUpload/_common.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/plugin/editor/cheditor5/imageUpload/config.php b/plugin/editor/cheditor5/imageUpload/config.php new file mode 100644 index 000000000..ac4e4956c --- /dev/null +++ b/plugin/editor/cheditor5/imageUpload/config.php @@ -0,0 +1,71 @@ + \ No newline at end of file diff --git a/plugin/editor/cheditor5/imageUpload/delete.php b/plugin/editor/cheditor5/imageUpload/delete.php new file mode 100644 index 000000000..0da4fc8f3 --- /dev/null +++ b/plugin/editor/cheditor5/imageUpload/delete.php @@ -0,0 +1,49 @@ + \ No newline at end of file diff --git a/plugin/editor/cheditor5/imageUpload/upload.php b/plugin/editor/cheditor5/imageUpload/upload.php new file mode 100644 index 000000000..73e3700a2 --- /dev/null +++ b/plugin/editor/cheditor5/imageUpload/upload.php @@ -0,0 +1,128 @@ + array("imagecreatefromgif", "imagegif"), + "image/jpg" => array("imagecreatefromjpeg", "imagejpeg"), + "image/jpeg" => array("imagecreatefromjpeg", "imagejpeg"), + "image/png" => array("imagecreatefrompng", "imagepng"), + "image/bmp" => array("imagecreatefromwbmp", "imagewbmp") + ); + + // Extracting mime type using getimagesize + try { + $image_info = getimagesize($file_path); + if ($image_info === null) { + //throw new Exception("Invalid image type"); + return false; + } + + $mime_type = $image_info["mime"]; + + if (!array_key_exists($mime_type, $MIME_TYPES_PROCESSORS)) { + //throw new Exception("Invalid image MIME type"); + return false; + } + + $image_from_file = $MIME_TYPES_PROCESSORS[$mime_type][0]; + $image_to_file = $MIME_TYPES_PROCESSORS[$mime_type][1]; + + $reprocessed_image = @$image_from_file($file_path); + + if (!$reprocessed_image) { + //throw new Exception("Unable to create reprocessed image from file"); + return false; + } + + // Calling callback(if set) with path of image as a parameter + if ($callback !== null) { + $callback($reprocessed_image); + } + + // Freeing up memory + imagedestroy($reprocessed_image); + } catch (Exception $e) { + unlink($file_path); + return false; + } + + return true; + } +} + +$is_editor_upload = false; + +$get_nonce = get_session('nonce_'.FT_NONCE_SESSION_KEY); + +if( $get_nonce && ft_nonce_is_valid( $get_nonce, 'cheditor' ) ){ + $is_editor_upload = true; +} + +if( !$is_editor_upload ){ + exit; +} + +//---------------------------------------------------------------------------- +// +// +$tempfile = $_FILES['file']['tmp_name']; +$filename = $_FILES['file']['name']; + +$type = substr($filename, strrpos($filename, ".")+1); +$found = false; +switch ($type) { + case "jpg": + case "jpeg": + case "gif": + case "png": + $found = true; +} + +if ($found != true) { + exit; +} + +// ̸: Ͻú_8 +// 20140327125959_abcdefghi.jpg +// ̸: $_POST["origname"] + +$filename = che_replace_filename($filename); +$savefile = SAVE_DIR . '/' . $filename; + +move_uploaded_file($tempfile, $savefile); +$imgsize = getimagesize($savefile); +$filesize = filesize($savefile); + +if (!$imgsize) { + $filesize = 0; + $random_name = '-ERR'; + unlink($savefile); +}; + +if ( CHE_UPLOAD_IMG_CHECK && ! che_reprocessImage($savefile, null) ){ + $filesize = 0; + $random_name = '-ERR'; + unlink($savefile); +} + +try { + if(defined('G5_FILE_PERMISSION')) chmod($savefile, G5_FILE_PERMISSION); +} catch (Exception $e) { +} + +$rdata = sprintf('{"fileUrl": "%s/%s", "filePath": "%s", "fileName": "%s", "fileSize": "%d" }', + SAVE_URL, + $filename, + $savefile, + $filename, + $filesize ); + +echo $rdata; +?> \ No newline at end of file diff --git a/plugin/editor/cheditor5/popup/color_picker.html b/plugin/editor/cheditor5/popup/color_picker.html new file mode 100644 index 000000000..dc972df57 --- /dev/null +++ b/plugin/editor/cheditor5/popup/color_picker.html @@ -0,0 +1,19 @@ + + + +CHEditor + + + + + + + +
+
현재 셀 색상:
+
+ +
+
+ + \ No newline at end of file diff --git a/plugin/editor/cheditor5/popup/flash.html b/plugin/editor/cheditor5/popup/flash.html new file mode 100644 index 000000000..f0e82b894 --- /dev/null +++ b/plugin/editor/cheditor5/popup/flash.html @@ -0,0 +1,22 @@ + + + +CHEditor + + + + + + + +
+
+ <동영상 소스 코드> iframe 또는 object 태그를 입력하세요. +
+ +
+
+
+
+ + \ No newline at end of file diff --git a/plugin/editor/cheditor5/popup/flash/ImagePreview.swf b/plugin/editor/cheditor5/popup/flash/ImagePreview.swf new file mode 100644 index 000000000..87e4f7558 Binary files /dev/null and b/plugin/editor/cheditor5/popup/flash/ImagePreview.swf differ diff --git a/plugin/editor/cheditor5/popup/flash/chximage.swf b/plugin/editor/cheditor5/popup/flash/chximage.swf new file mode 100644 index 000000000..f4e11c21c Binary files /dev/null and b/plugin/editor/cheditor5/popup/flash/chximage.swf differ diff --git a/plugin/editor/cheditor5/popup/google_map.html b/plugin/editor/cheditor5/popup/google_map.html new file mode 100644 index 000000000..5f7ed0955 --- /dev/null +++ b/plugin/editor/cheditor5/popup/google_map.html @@ -0,0 +1,23 @@ + + + + CHEditor + + + + + + + + +
+ 찾을 주소: + + +
찾으실 도로명 주소, 지번 또는 건물명을 입력하세요.
+
+
+
+
+ + diff --git a/plugin/editor/cheditor5/popup/icon.html b/plugin/editor/cheditor5/popup/icon.html new file mode 100644 index 000000000..5f54f1f8f --- /dev/null +++ b/plugin/editor/cheditor5/popup/icon.html @@ -0,0 +1,15 @@ + + + + CHEditor + + + + + + + +
+
+ + \ No newline at end of file diff --git a/plugin/editor/cheditor5/popup/image.html b/plugin/editor/cheditor5/popup/image.html new file mode 100644 index 000000000..a09bbf75f --- /dev/null +++ b/plugin/editor/cheditor5/popup/image.html @@ -0,0 +1,76 @@ + + + + CHEditor + + + + + + + + +
+
+ + + + + +
+ + +
+  (사진을 드래그하여 순서를 바꿀 수 있습니다.) + 0장 / 최대 장 사진 +
+
+
+
+
사진 정보
+
+
가로: 0
+
세로: 0
+
이름: 없음
+
+
+
+
정렬
+
+ + + + + + +
+
+ +
+
+ +
+
+ +
+
+ 한줄에 한 장씩 넣기 +
+
+ 사진 여백 넣기 +
+
+ (전체 사진에 적용됨) +
+
+
+
+
+
+
+
+
+
+
+ + \ No newline at end of file diff --git a/plugin/editor/cheditor5/popup/image.html5.html b/plugin/editor/cheditor5/popup/image.html5.html new file mode 100644 index 000000000..c5f0f9b85 --- /dev/null +++ b/plugin/editor/cheditor5/popup/image.html5.html @@ -0,0 +1,82 @@ + + + + CHEditor + + + + + + + +
+
+
+ + + image button + (사진을 점선 안으로 끌어 놓을 수 있습니다.) + 0장 / 최대 장 사진 +
+
+
+
+
크기 줄이기
+
+
+ 가로: + + 픽셀 + +
+
사진 높이는 자동으로 설정됩니다.
+
+
+
+
정렬
+
+ + + + + + +
+
+ +
+
+ +
+
+ +
+
+ 한줄에 한 장씩 넣기 +
+
+ 사진 여백 넣기 +
+
+ (전체 사진에 적용됨) +
+
+
+
+
+
+
+
+
+
+
+ + \ No newline at end of file diff --git a/plugin/editor/cheditor5/popup/image_url.html b/plugin/editor/cheditor5/popup/image_url.html new file mode 100644 index 000000000..18b76d3db --- /dev/null +++ b/plugin/editor/cheditor5/popup/image_url.html @@ -0,0 +1,34 @@ + + + + CHEditor + + + + + + + + +
+
0 X 0
+
+
사진 URL +
+ +
+
+
+
레이아웃 +
+
+ + + +
+
+
+
+
+ + diff --git a/plugin/editor/cheditor5/popup/js/AC_OETags.js b/plugin/editor/cheditor5/popup/js/AC_OETags.js new file mode 100644 index 000000000..00d0e4405 --- /dev/null +++ b/plugin/editor/cheditor5/popup/js/AC_OETags.js @@ -0,0 +1,247 @@ +// Flash Player Version Detection - Rev 1.5 +// Detect Client Browser type +// Copyright(c) 2005-2006 Adobe Macromedia Software, LLC. All rights reserved. +// Modified: chna@chcode.com + +var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false; +var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false; +var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false; + +function errMaxFileSize (MaxFileSize) { + alert("선택하신 파일 크기가 너무 큽니다. 최대 전송 크기는 "+MaxFileSize+" MB 입니다."); +} + +function ControlVersion() +{ + var version = 0; + var axo; +// var e; + try { + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); + version = axo.GetVariable("$version"); + } catch (e) {} + + if (!version) + { + try { + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); + version = "WIN 6,0,21,0"; + axo.AllowScriptAccess = "always"; + version = axo.GetVariable("$version"); + + } catch (e) {} + } + + if (!version) + { + try { + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); + version = axo.GetVariable("$version"); + } catch (e) {} + } + + if (!version) + { + try { + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); + version = "WIN 3,0,18,0"; + } catch (e) {} + } + + if (!version) + { + try { + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); + version = "WIN 2,0,0,11"; + } catch (e) { + version = -1; + } + } + + return version; +} + +function GetSwfVer(){ + var flashVer = -1; + if (navigator.plugins != null && navigator.plugins.length > 0) { + if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) { + var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : ""; + var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description; + var descArray = flashDescription.split(" "); + var tempArrayMajor = descArray[2].split("."); + var versionMajor = tempArrayMajor[0]; + var versionMinor = tempArrayMajor[1]; + if ( descArray[3] != "" ) { + tempArrayMinor = descArray[3].split("r"); + } else { + tempArrayMinor = descArray[4].split("r"); + } + var versionRevision = tempArrayMinor[1] > 0 ? tempArrayMinor[1] : 0; + flashVer = versionMajor + "." + versionMinor + "." + versionRevision; + } + } + else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4; + else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3; + else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2; + else if ( isIE && isWin && !isOpera ) { + flashVer = ControlVersion(); + } + return flashVer; +} + +function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) +{ + versionStr = GetSwfVer(); + if (versionStr == -1 ) { + return false; + } else if (versionStr != 0) { + if(isIE && isWin && !isOpera) { + tempArray = versionStr.split(" "); // ["WIN", "2,0,0,11"] + tempString = tempArray[1]; // "2,0,0,11" + versionArray = tempString.split(","); // ['2', '0', '0', '11'] + } else { + versionArray = versionStr.split("."); + } + var versionMajor = versionArray[0]; + var versionMinor = versionArray[1]; + var versionRevision = versionArray[2]; + + if (versionMajor > parseFloat(reqMajorVer)) { + return true; + } + else if (versionMajor == parseFloat(reqMajorVer)) { + if (versionMinor > parseFloat(reqMinorVer)) + return true; + else if (versionMinor == parseFloat(reqMinorVer)) { + if (versionRevision >= parseFloat(reqRevision)) + return true; + } + } + return false; + } +} + +function AC_AddExtension(src, ext) +{ + if (src.indexOf('?') != -1) + return src.replace(/\?/, ext+'?'); + else + return src + ext; +} + +function AC_Generateobj(objAttrs, params, embedAttrs) +{ + var str = ''; + if (isIE && isWin && !isOpera) + { + str += ''; + breakpoint = false; + } + str += ''; + } else { + str += '"); + div.innerHTML = "<" + str.substr(0, pos) + ">"; + embed = div.firstChild; + } else { + div.innerHTML = elem; + object = div.getElementsByTagName('OBJECT')[0]; + if (object && object.hasChildNodes()) { + child = object.firstChild; + movieWidth = (isNaN(object.width) !== true) ? object.width : 320; + movieHeight = (isNaN(object.height) !== true) ? object.height : 240; + + do { + if ((child.nodeName === 'PARAM') && (typeof child.name !== 'undefined') && (typeof child.value !== 'undefined')) { + params.push({key: (child.name == 'movie') ? 'src' : child.name, val: child.value}); + } + child = child.nextSibling; + } while (child); + + if (params.length > 0) { + embed = document.createElement('embed'); + embed.setAttribute("width", movieWidth); + embed.setAttribute("height", movieHeight); + for (i = 0; i < params.length; i++) { + embed.setAttribute(params[i].key, params[i].val); + } + embed.setAttribute("type", "application/x-shockwave-flash"); + } + } + } + + if (embed !== null) { + document.getElementById('fm_player').appendChild(embed); + } +} + +function popupClose() { + document.getElementById('fm_player').innerHTML = ''; + oEditor.popupWinCancel(); +} + +function doSubmit() +{ + var source = String(oEditor.trimSpace(document.getElementById("fm_embed").value)); + if (source === '') { + popupClose(); + } + + if (iframeSource || source.indexOf("iframe") !== -1) { + oEditor.insertHtmlPopup(source); + } else { + oEditor.insertFlash(source); + } + + document.getElementById('fm_player').innerHTML = ''; + oEditor.popupWinClose(); +} diff --git a/plugin/editor/cheditor5/popup/js/google_map.js b/plugin/editor/cheditor5/popup/js/google_map.js new file mode 100644 index 000000000..cf6109076 --- /dev/null +++ b/plugin/editor/cheditor5/popup/js/google_map.js @@ -0,0 +1,143 @@ +// ================================================================ +// CHEditor 5 +// ---------------------------------------------------------------- +var oEditor = null, + centerLat = 0, + centerLng = 0, + latlng = 0, + setZoom = 14, + marker_lat = 0, + marker_lng = 0, + mapType = "roadmap", + map, + mapWidth = 512, + mapHeight = 320, + panorama, + panoramaVisible = false; + +function doSubmit() { + var mapImg = document.createElement("img"), + panoramaPitch, panoramaHeading, panoramaZoom, panoramaPosition; + + if (marker_lat === 0) { + marker_lat = centerLat; + } + if (marker_lng === 0) { + marker_lng = centerLng; + } + + mapImg.style.width = mapWidth + 'px'; + mapImg.style.height = mapHeight + 'px'; + mapImg.style.border = '1px #000 solid'; + mapImg.setAttribute("alt", "Google Map"); + mapImg.onload = function () { + oEditor.insertHtmlPopup(mapImg); + oEditor.setImageEvent(true); + oEditor.popupWinClose(); + }; + + if (panoramaVisible) { + panoramaPitch = panorama.getPov().pitch; + panoramaHeading = panorama.getPov().heading; + panoramaZoom = panorama.getPov().zoom; + panoramaPosition = panorama.getPosition(); + + mapImg.src = "http://maps.googleapis.com/maps/api/streetview?location=" + panoramaPosition + + "&pitch=" + panoramaPitch + + "&heading=" + panoramaHeading + + "&size=" + mapWidth + 'x' + mapHeight + + "&zoom=" + panoramaZoom + + "&sensor=false" + + "®ion=KR"; + } else { + mapImg.src = "http://maps.google.com/maps/api/staticmap?center=" + centerLat + ',' + centerLng + + "&zoom=" + setZoom + + "&size=" + mapWidth + 'x' + mapHeight + + "&maptype=" + mapType + + //"&markers=" + marker_lat + ',' + marker_lng + + "&sensor=false" + + "&language=ko" + + "®ion=KR"; + } +} + +function searchAddress() { + var address = document.getElementById('fm_address').value, + geocoder = new google.maps.Geocoder(); + //var results, status; + //var marker = new google.maps.Marker({ 'map': map, 'draggable': true }); + + geocoder.geocode({'address' : address}, + function (results, status) { + if (status === google.maps.GeocoderStatus.OK) { + centerLat = results[0].geometry.location.lat(); + centerLng = results[0].geometry.location.lng(); + latlng = new google.maps.LatLng(centerLat, centerLng); + map.setCenter(latlng); + map.setZoom(setZoom); + } + }); +} + +function initMap(zoom) { + var mapOptions = { + zoom: zoom || setZoom, + panControl: true, + zoomControl: true, + scaleControl: true, + center: new google.maps.LatLng(37.566, 126.977), + disableDefaultUI: false, + streetViewControl: true, + mapTypeId: google.maps.MapTypeId.ROADMAP + }; + + map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions); + centerLat = map.getCenter().lat(); + centerLng = map.getCenter().lng(); + + google.maps.event.addListener(map, 'dragend', function () { + centerLat = map.getCenter().lat(); + centerLng = map.getCenter().lng(); + }); + + google.maps.event.addListener(map, 'maptypeid_changed', function () { + mapType = map.getMapTypeId(); + }); + + google.maps.event.addListener(map, 'zoom_changed', function () { + centerLat = map.getCenter().lat(); + centerLng = map.getCenter().lng(); + }); + + panorama = map.getStreetView(); + google.maps.event.addListener(panorama, 'visible_changed', function () { + panoramaVisible = panorama.getVisible(); + }); +} + +function popupClose() { + oEditor.popupWinCancel(); +} + +function init(dialog) { + oEditor = this; + oEditor.dialog = dialog; + + var dlg = new Dialog(oEditor), + button = [ + { alt : "", img : 'submit.gif', cmd : doSubmit }, + { alt : "", img : 'cancel.gif', cmd : popupClose } + ], + buttonUrl = oEditor.config.iconPath + 'button/map_address.gif', + search = new Image(); + + dlg.showButton(button); + + search.src = buttonUrl; + search.onclick = function () { + searchAddress(); + }; + search.className = 'button'; + document.getElementById('map_search').appendChild(search); + dlg.setDialogHeight(); +} diff --git a/plugin/editor/cheditor5/popup/js/icon.js b/plugin/editor/cheditor5/popup/js/icon.js new file mode 100644 index 000000000..2ce50fae8 --- /dev/null +++ b/plugin/editor/cheditor5/popup/js/icon.js @@ -0,0 +1,54 @@ +// ================================================================ +// CHEditor 5 +// ================================================================ +var oEditor = null; + +function popupClose() { + oEditor.popupWinCancel(); +} + +function insertIcon() { + this.removeAttribute("className"); + this.removeAttribute("class"); + this.style.margin = '1px 4px'; + oEditor.insertHtmlPopup(this.cloneNode(false)); + oEditor.popupWinClose(); +} + +function showContents() { + var block = document.getElementById('iconBlock'), + path = oEditor.config.iconPath + 'em/', + num = 80, i, br, img; + + for (i = 40; i < num; i++) { + if (i > 40 && (i % 10) === 0) { + br = document.createElement('br'); + block.appendChild(br); + } + + img = new Image(); + img.src = path + (i + 1) + ".gif"; + img.style.width = '16px'; + img.style.height = '16px'; + img.style.margin = '5px 4px'; + img.style.verticalAlign = 'middle'; + img.setAttribute('alt', 'Emotion Icon'); + img.setAttribute('border', "0"); + img.className = 'handCursor'; + img.onclick = insertIcon; + block.appendChild(img); + } +} + +function init(dialog) { + var button, dlg; + + oEditor = this; + oEditor.dialog = dialog; + button = [{ alt : "", img : 'cancel.gif', cmd : popupClose }]; + + dlg = new Dialog(oEditor); + showContents(); + dlg.showButton(button); + dlg.setDialogHeight(); +} diff --git a/plugin/editor/cheditor5/popup/js/image.html5.js b/plugin/editor/cheditor5/popup/js/image.html5.js new file mode 100644 index 000000000..b4ed00b0e --- /dev/null +++ b/plugin/editor/cheditor5/popup/js/image.html5.js @@ -0,0 +1,1344 @@ +// ================================================================ +// CHEditor 5 +// ================================================================ +var activeImage = null, + browser = null, + button, + debug = false, + destinationObject = null, + divHeight = [], + divWidth = [], + divXPositions = [], + divYPositions = [], + dragDropDiv, + eventDiff_x = 0, + eventDiff_y = 0, + fileTypeRe = /^image\/(png|jpeg|gif)$/i, + geckoOffsetX_marker = -3, + geckoOffsetY_marker = -1, + imageCompleted = 0, + imageCompletedList = [], + imageListWrapper, + imageResizeInput, + imageResizeWidth = 0, + insertionMarker, + inputFileName = 'file', + modifyImages = [], + moveTimer = -1, + oEditor = 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; + +function createInsertionMaker() { + var wrapper = document.getElementById('insertionMarker'), + topIco = new Image(), + middleIco = new Image(), + bottomIco = new Image(); + + topIco.src = uploadImagePath + '/marker_top.gif'; + topIco.style.width = '6px'; + topIco.style.height = '1px'; + wrapper.appendChild(topIco); + + middleIco.src = uploadImagePath + '/marker_middle.gif'; + middleIco.style.height = '96px'; + middleIco.style.width = '6px'; + wrapper.appendChild(middleIco); + + bottomIco.src = uploadImagePath + '/marker_bottom.gif'; + bottomIco.style.width = '6px'; + bottomIco.style.height = '1px'; + wrapper.appendChild(bottomIco); +} + +function popupClose() { + oEditor.popupWinCancel(); +} + +function showContents() { + var spacer = function (id) { + var clear = document.createElement('div'); + clear.style.height = '0px'; + clear.style.width = '0px'; + clear.className = 'clear'; + clear.id = 'spacer' + id; + return clear; + }, + spacerNo = 1, i, imgBox, theImg, lastSpacer; + + for (i = 0; i < uploadMaxNumber; i++) { + if (i > 0 && ((i % 4) === 0)) { + imageListWrapper.appendChild(spacer(spacerNo++)); + } + + imgBox = document.createElement('div'); + imgBox.id = 'imgBox' + i; + imgBox.className = 'imageBox'; + theImg = document.createElement('div'); + theImg.id = 'img_' + i; + theImg.className = 'imageBox_theImage'; + imgBox.appendChild(theImg); + + imageListWrapper.appendChild(imgBox); + if (i === (uploadMaxNumber - 1)) { + lastSpacer = spacer(spacerNo); + lastSpacer.style.height = "7px"; + imageListWrapper.appendChild(lastSpacer); + } + } + + imageListWrapper.style.padding = '5px 7px 0px 5px'; + document.getElementById('imageInfoBox').style.height = '298px'; + document.getElementById('imageInfoBox').style.width = '130px'; +} + +function setImageCount() { + imageCompleted++; + document.getElementById('imageCount').innerHTML = imageCompleted.toString(); +} + +function getImageCount() { + return imageCompleted; +} + +function allowedMaxImage() { + return uploadMaxNumber - getImageCount(); +} + +function getUploadedCount() { + return imageListWrapper.getElementsByTagName('img').length; +} + +function uploadedImageCount() { + imageCompleted = getUploadedCount(); + document.getElementById('imageCount').innerHTML = imageCompleted.toString(); +} + +function getTopPos(inputObj) { + // ---------------------------------------------------------------------------------- + var returnValue = inputObj.offsetTop; + + inputObj = inputObj.offsetParent; + while (inputObj) { + if (inputObj.tagName.toLowerCase() !== 'html') { + returnValue += (inputObj.offsetTop - inputObj.scrollTop); + if (browser.msie) { + returnValue += inputObj.clientTop; + } + } + inputObj = inputObj.offsetParent; + } + return returnValue; +} + +function getLeftPos(inputObj) { + // ---------------------------------------------------------------------------------- + var returnValue = inputObj.offsetLeft; + + inputObj = inputObj.offsetParent; + while (inputObj) { + if (inputObj.id !== 'imageListWrapper') { + returnValue += inputObj.offsetLeft; + } + inputObj = inputObj.offsetParent; + } + return returnValue; +} + +function getDivCoordinates() { + // ---------------------------------------------------------------------------------- + var imgBox = imageListWrapper.getElementsByTagName('DIV'), + i = 0; + + for (; i < imgBox.length; i++) { + if ((imgBox[i].className === 'imageBox' || imgBox[i].className === 'imageBoxHighlighted') && imgBox[i].id) { + divXPositions[imgBox[i].id] = getLeftPos(imgBox[i]); + divYPositions[imgBox[i].id] = getTopPos(imgBox[i]); + divWidth[imgBox[i].id] = imgBox[i].offsetWidth; + divHeight[imgBox[i].id] = imgBox[i].offsetHeight; + } + } +} + +function reOrder() { + // ---------------------------------------------------------------------------------- + var imgBox = imageListWrapper.getElementsByTagName('div'), + imgNum = 0, i, spacer, breakline = []; + + for (i = 0; i < imgBox.length; i++) { + if (imgBox[i].id.indexOf('imgBox') === -1) { + continue; + } + + imgBox[i].className = 'imageBox'; + imgBox[i].firstChild.className = 'imageBox_theImage'; + + if (imgNum > 0 && (imgNum % 4) === 0) { + breakline.push(imgBox[i].id); + } + + imgNum++; + } + + for (i = 0; i < breakline.length; i++) { + spacer = document.getElementById('spacer' + (i + 1)); + if (i + 1 === breakline.length) { + imageListWrapper.appendChild(spacer); + } else { + imageListWrapper.insertBefore(spacer, document.getElementById(breakline[i])); + } + } +} + +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; + + if (readyToMove) { + return; + } + + getDivCoordinates(); + self.className = 'imageBox_theImage_over'; + btn = document.getElementById('removeImageButton'); + btn.style.left = (showThumbnailSize.width - parseInt(btn.style.width, 10) - 1) + 'px'; + btn.style.top = '-1px'; + + self.appendChild(btn); + btn.style.display = 'block'; + + btn.onmouseover = function (ev) { + oEditor.stopEvent(ev); + this.style.display = 'block'; + this.className = 'removeButton_over'; + self.className = 'imageBox_theImage_over'; + }; + btn.onmouseout = function () { + this.className = 'removeButton'; + }; + btn.onmousedown = function (ev) { + var images = self.getElementsByTagName('img'), i, moveobj, target; + + for (i = 0; i < images.length; i++) { + img_delete_post(self); + self.removeChild(images[i]); + } + + self.removeChild(self.firstChild); + self.className = 'imageBox_theImage'; + + if (self.parentNode.nextSibling && self.parentNode.nextSibling.id) { + moveobj = self.parentNode.nextSibling; + target = self.parentNode; + + while (moveobj !== null) { + if (moveobj.firstChild && !moveobj.firstChild.firstChild) { + break; + } + if (/^spacer/.test(moveobj.id)) { + moveobj = moveobj.nextSibling; + continue; + } + imageListWrapper.insertBefore(moveobj, target); + moveobj = target.nextSibling; + } + } + + reOrder(); + uploadedImageCount(); + this.style.display = 'none'; + document.body.appendChild(ev.target); + oEditor.removeEvent(self, 'mouseover', showDelete); + }; +} + +function hideDelete() { + // ---------------------------------------------------------------------------------- + document.getElementById('removeImageButton').style.display = 'none'; +} + +function startUpload(list) { + // ---------------------------------------------------------------------------------- + var el = imageListWrapper.getElementsByTagName('div'), i, imgBox, + count = 0, len = list.length; + + for (i = 0; i < el.length; i++) { + imgBox = el[i]; + if (imgBox.className !== 'imageBox_theImage') { + continue; + } + if (count === len) { + break; + } + if (!imgBox.firstChild || imgBox.firstChild.tagName.toLowerCase() !== 'img') { + imgBox.style.backgroundImage = "url('" + uploadImagePath + "/loader.gif')"; + list[count++].boxElem = imgBox; + } + } +} + +function fileFilterError(file) { + alert("선택하신 '" + file + "' 파일은 전송할 수 없습니다.\n" + + "gif, png, jpg 사진 파일만 전송할 수 있습니다."); +} + +function imgComplete(img, imgSize, boxId) { + var resizeW, resizeH, M, elem; + img.setAttribute("border", '0'); + + 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); + } else { + 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); + } + + } else { + resizeW = imgSize.width; + resizeH = imgSize.height; + } + + img.style.width = resizeW - 2 + 'px'; + img.style.height = resizeH - 2 + 'px'; + img.style.margin = "1px"; + + if (resizeW < showThumbnailSize.width) { + M = showThumbnailSize.width - resizeW; + img.style.marginLeft = Math.round(M / 2) + 'px'; + } + + if (resizeH < showThumbnailSize.height) { + M = showThumbnailSize.height - resizeH; + img.style.marginTop = Math.round(M / 2) + 'px'; + } + + elem = document.getElementById(boxId); + boxId = boxId.replace(/img_/, ''); + + if (boxId % 12 === 0) { + imageListWrapper.scrollTop = elem.offsetTop - 6; + } + + elem.style.backgroundImage = "url('" + uploadImagePath + "/dot.gif')"; + oEditor.addEvent(elem, 'mouseover', showDelete); + elem.onmouseout = function () { + this.className = 'imageBox_theImage'; + hideDelete(); + }; + + setImageCount(); +} + +function showUploadWindow() { + // ---------------------------------------------------------------------------------- + var uploadWindow = document.getElementById("uploadWindow"), + uploadWindowWidth = 700, + winWidth, el, i, j, imgBox, img; + + if (!(oEditor.undefined(window.innerWidth))) { + winWidth = window.innerWidth; + } else if (document.documentElement && + (!(oEditor.undefined(document.documentElement.clientWidth))) && + document.documentElement.clientWidth !== 0) { + winWidth = document.documentElement.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.display = "block"; + uploadWindow.style.width = uploadWindowWidth + 'px'; + + if (modifyImages.length > 0) { + el = imageListWrapper.getElementsByTagName('div'); + for (i = 0; i < modifyImages.length; i++) { + if (i > 7) { + break; + } + + for (j = 0; j < el.length; j++) { + imgBox = el[j]; + if (imgBox.className !== 'imageBox_theImage') { + continue; + } + + if (imgBox.firstChild && (imgBox.firstChild.src === modifyImages[i])) { + break; + } + + if (imgBox.firstChild === null) { + img = new Image(); + img.src = modifyImages[i]; + img.border = 0; + img.alt = ''; + img.style.width = '120px'; + img.style.height = '90px'; + imgBox.appendChild(img); + break; + } + } + } + } +} + +function removeImages() { + var images = [], i, j, theImage, img, remove; + document.body.appendChild(document.getElementById('removeImageButton')); + + for (i = 0; i < uploadMaxNumber; i++) { + theImage = document.getElementById('img_' + i); + if (theImage.hasChildNodes() && theImage.firstChild.tagName.toLowerCase() === 'img') { + images.push(theImage); + } + } + + for (i = 0; i < images.length; i++) { + img = images[i]; + if (img.firstChild !== null) { + oEditor.removeEvent(img, 'mouseover', showDelete); + remove = img.getElementsByTagName('img'); + + for (j = 0; j < remove.length; j++) { + img_delete_post(img); + img.removeChild(remove[j]); + } + + img.parentNode.className = 'imageBox'; + oEditor.removeEvent(img, 'mouseover', showDelete); + } + } + uploadedImageCount(); + imageCompletedList = []; +} + +function removeImage() { + // ---------------------------------------------------------------------------------- + var i, theImage, found = false; + + for (i = 0; i < uploadMaxNumber; i++) { + theImage = document.getElementById('img_' + i); + if (theImage.hasChildNodes() && theImage.firstChild.tagName.toLowerCase() === 'img') { + found = true; + break; + } + } + + if (found) { + if (!confirm('추가하신 사진이 있습니다. 사진 넣기를 취소하시겠습니까?')) { + return false; + } + removeImages(); + } + + return true; +} + +function closeWindow() { + // ---------------------------------------------------------------------------------- + if (removeImage()) { + popupClose(); + } +} + +function cancelEvent() { + // ---------------------------------------------------------------------------------- + return false; +} + +function startMoveTimer() { + // ---------------------------------------------------------------------------------- + var subElements, newDiv; + + if (moveTimer >= 0 && moveTimer < 10) { + moveTimer++; + setTimeout('startMoveTimer()', 8); + } + + if (moveTimer === 5) { + getDivCoordinates(); + subElements = dragDropDiv.getElementsByTagName('div'); + if (subElements.length > 0) { + dragDropDiv.removeChild(subElements[0]); + } + + dragDropDiv.style.display = 'block'; + newDiv = activeImage.cloneNode(true); + newDiv.className = 'imageBox'; + newDiv.style.opacity = 0.5; + + newDiv.id = ''; + newDiv.style.padding = '2px'; + dragDropDiv.appendChild(newDiv); + + dragDropDiv.style.top = tmpTop + 'px'; + dragDropDiv.style.left = tmpLeft + 'px'; + } + + return false; +} + +function getMouseButtn(e) { + var code; + e = e || window.event; + code = e.button; + + if (code) { + if (browser.msie && browser.version < 9) { + code = code === 1 ? 0 : (code === 4 ? 1 : code); + } + } + + return code; +} + +function selectImage(e) { + // ---------------------------------------------------------------------------------- + var el = this.parentNode.firstChild.firstChild, obj; + + if (!el) { + return; + } + + e = e || window.event; + if (getMouseButtn(e) === 2) { + return; + } + + obj = this.parentNode; + hideDelete(); + + obj.className = 'imageBoxHighlighted'; + activeImage = obj; + readyToMove = true; + moveTimer = 0; + + tmpLeft = e.clientX + Math.max(document.body.scrollLeft, document.documentElement.scrollLeft); + tmpTop = e.clientY + Math.max(document.body.scrollTop, document.documentElement.scrollTop); + + startMoveTimer(); + return false; +} + +function dragDropEnd() { + // ---------------------------------------------------------------------------------- + var parentObj, chkObj, turn = false; + + readyToMove = false; + moveTimer = -1; + dragDropDiv.style.display = 'none'; + insertionMarker.style.display = 'none'; + + if (!activeImage) { + return; + } + + if (destinationObject && destinationObject !== activeImage) { + parentObj = destinationObject.parentNode; + chkObj = destinationObject.previousSibling; + turn = false; + + if (chkObj === null) { + chkObj = imageListWrapper.firstChild; + turn = true; + } + + if (chkObj.id.indexOf('spacer') !== -1) { + chkObj = chkObj.previousSibling; + } + + if (chkObj.firstChild.firstChild === null) { + reOrder(); + return; + } + + if (chkObj && chkObj.id !== null) { + while (chkObj) { + if (chkObj.firstChild.firstChild !== null) { + break; + } + chkObj = chkObj.previousSibling; + } + destinationObject = turn ? chkObj : chkObj.nextSibling; + } + + parentObj.insertBefore(activeImage, destinationObject); + reOrder(); + + activeImage = null; + destinationObject = null; + getDivCoordinates(); + + return false; + } + + activeImage.className = "imageBox"; + return true; +} + +function dragDropMove(e) { + // ---------------------------------------------------------------------------------- + var elementFound = false, prop, offsetX, offsetY, leftPos, topPos; + + if (moveTimer === -1 || !readyToMove) { + return; + } + + e = e || window.event; + + leftPos = e.clientX + document.documentElement.scrollLeft - eventDiff_x; + topPos = e.clientY + document.documentElement.scrollTop - eventDiff_y; + + dragDropDiv.style.top = topPos + 'px'; + dragDropDiv.style.left = leftPos + 'px'; + + leftPos = leftPos + eventDiff_x; + topPos = topPos + eventDiff_y; + + if (getMouseButtn(e) !== 0) { + dragDropEnd(); + } + + for (prop in divXPositions) { + if (!divXPositions.hasOwnProperty(prop) || divXPositions[prop].className === 'clear') { + continue; + } + + if (divXPositions[prop] < leftPos && + (divXPositions[prop] + divWidth[prop] * 0.7) > leftPos && + divYPositions[prop] < topPos && + (divYPositions[prop] + divWidth[prop]) > topPos) { + if (browser.msie) { + offsetX = offsetX_marker; + offsetY = offsetY_marker; + } else { + offsetX = geckoOffsetX_marker; + offsetY = geckoOffsetY_marker; + } + + insertionMarker.style.top = divYPositions[prop] + offsetY + 'px'; + insertionMarker.style.left = divXPositions[prop] + offsetX + 'px'; + insertionMarker.style.display = 'block'; + destinationObject = document.getElementById(prop); + elementFound = true; + break; + } + } + + if (!elementFound) { + insertionMarker.style.display = 'none'; + destinationObject = false; + } + + return false; +} + +function initGallery() { + // ---------------------------------------------------------------------------------- + var imgBox = imageListWrapper.getElementsByTagName('div'), + i; + + for (i = 0; i < imgBox.length; i++) { + if (imgBox[i].className === 'imageBox_theImage') { + imgBox[i].onmousedown = selectImage; + } + } + + document.body.onselectstart = cancelEvent; + document.body.ondragstart = cancelEvent; + document.body.onmouseup = dragDropEnd; + document.body.onmousemove = dragDropMove; + + dragDropDiv = document.getElementById('dragDropContent'); + insertionMarker = document.getElementById('insertionMarker'); + getDivCoordinates(); +} + +function doSubmit() { + // ---------------------------------------------------------------------------------- + var el = imageListWrapper.getElementsByTagName('div'), + imageArray = [], + num = 0, + elem = document.getElementById('id_alignment').elements, + imgParagraph = false, + useSpacer = false, + imgAlign = 'top', i, imgBox, input; + + for (i = 0; i < elem.length; i++) { + input = elem[i]; + switch (input.name) { + case "alignment" : + if (input.checked) { + imgAlign = input.value; + } + break; + case "para" : + imgParagraph = input.checked; + break; + case "use_spacer" : + useSpacer = input.checked; + break; + } + } + + for (i = 0; i < el.length; i++) { + imgBox = el[i]; + if (imgBox.className !== "imageBox_theImage") { + continue; + } + + if (imgBox.firstChild !== null) { + imageArray[num] = imageCompletedList[imgBox.id]; + + if (imgAlign === "break") { + imageArray[num].alt = "break"; + } else { + imageArray[num].alt = ''; + imageArray[num].align = imgAlign; + } + + num++; + } + } + + if (imageArray.length > 0) { + oEditor.doInsertImage(imageArray, imgParagraph, useSpacer); + } + oEditor.popupWinClose(); +} + +function selectedFiles(evt) { + var upload = new DoUpload(), + files = evt.target.files || []; + + oEditor.stopEvent(evt); + if (files) { + upload.select(files); + } +} + +function DoUpload() { + this.list = []; + this.reader = new FileReader(); + this.URL = window.URL || window.webkitURL; + + this.reader.onprogress = null; + this.reader.onloadstart = null; + this.reader.onabort = null; + this.reader.onerror = null; + + this.MyBlob = (function () { + var key, blob, self = this; + function MYBLOB(blob) { + var url = null; + this.blob = blob; + blob = null; + + this.getURL = function () { + if (url) { + return url; + } + url = self.URL.createObjectURL(this.blob); + return url; + }; + this.dispose = function () { + if (url) { + url = self.URL.revokeObjectURL(url); + } + if (typeof this.blob.msClose !== 'undefined') { + this.blob.msClose(); + } + this.blob = null; + if (debug) { + console.log("Blob Data Clear"); + } + }; + } + + blob = new Blob(); + for (key in blob) { + if (blob.hasOwnProperty(key)) { + (function (key) { + Object.defineProperty(MYBLOB.prototype, + key, + { + enumerable: true, + configurable: true, + get: function () { + return this.blob[key]; + } + } + ); + }(key)); + } + } + + key = undefined; + return MYBLOB; + }()); + + return this; +} + +DoUpload.prototype = { + select: function (files) { + var self = this, + num = files.length, + i = 0, + file = null; + + if (num > allowedMaxImage()) { + num = allowedMaxImage(); + } + + for (; i < num; i++) { + file = files[i]; + + if (!file.type.match(fileTypeRe)) { + fileFilterError(file.name); + continue; + } + this.list.push(file); + } + + if (this.list.length < 1) { + return; + } + + this.reader.addEventListener("error", function (evt) { + self.onReadDataErrorHandler(evt); + }, false); + + this.reader.onloadend = function (evt) { + self.dataLoadHandler(evt); + }; + + setResizeWidth(); + startUpload(this.list); + + this.load(); + }, + + getDateTime : function () { + var date = new Date(), + year = date.getFullYear(), + month = date.getMonth() + 1, + day = date.getDate(), + hours = date.getHours(), + minutes = date.getMinutes(), + seconds = date.getSeconds(); + + return String(10000 * year + 100 * month + day + + ('0' + hours).slice(-2) + ('0' + minutes).slice(-2) + ('0' + seconds).slice(-2)); + }, + + makeFilename : function (type) { + var chars = "abcdefghiklmnopqrstuvwxyz", + len = 8, clen = chars.length, rData = '', i, rnum; + + for (i = 0; i < len; i++) { + rnum = Math.floor(Math.random() * clen); + rData += chars.substring(rnum, rnum + 1); + } + + if (type !== '') { + rData += type.toLowerCase(); + } + + return this.getDateTime() + '_' + rData; + }, + + getOrientation : function (data) { + var view = new DataView(data), + length = view.byteLength, + offset = 2, + marker, little, tags, i; + + if (view.getUint16(0, false) !== 0xffd8) { + return -2; + } + + while (offset < length) { + marker = view.getUint16(offset, false); + offset += 2; + + if (marker === 0xffe1) { + if (view.getUint32(offset += 2, false) !== 0x45786966) { + return -1; + } + + little = view.getUint16(offset += 6, false) === 0x4949; + offset += view.getUint32(offset + 4, little); + tags = view.getUint16(offset, little); + offset += 2; + + for (i = 0; i < tags; i++) { + if (view.getUint16(offset + (i * 12), little) === 0x0112) { + return view.getUint16(offset + (i * 12) + 8, little); + } + } + } else if ((marker & 0xff00) !== 0xff00) { + break; + } else { + offset += view.getUint16(offset, false); + } + } + + return -1; + }, + + NewBlob : function (data, datatype) { + var blob = null, blobb; + try { + blob = new Blob([data], {type: datatype}); + } catch (e) { + window.BlobBuilder = window.BlobBuilder + || window.WebKitBlobBuilder + || window.MozBlobBuilder + || window.MSBlobBuilder; + + if (e.name === 'TypeError' && window.BlobBuilder) { + blobb = new BlobBuilder(); + blobb.append(data); + blob = blobb.getBlob(datatype); + console.log("TypeError"); + } else if (e.name === "InvalidStateError") { + console.log("InvalidStateError"); + } else { + console.log("Error"); + } + } + return blob; + }, + + 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; + + 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); + ctx.restore(); + } + + if (this.reader.watermark && addWaterMark) { + ctx.globalAlpha = oEditor.config.imgWaterMarkAlpha; + 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]), + intArray = [], + len = bitmapData.length, + i = 0; + + for (; i < len; i++) { + intArray.push(raw.charCodeAt(i)); + } + return new Blob([new Uint8Array(intArray)], {type: mimetype}); + }, + + makeThumbnail : function (image, type, name, orientation) { + var canvas = document.createElement("canvas"), + width, + xhr = new XMLHttpRequest(), + data = new FormData(), + bitmapData, file; + + xhr.open('POST', uploadScript, true); + width = oEditor.config.thumbnailWidth; + + 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 () { + + }, false); + + xhr.addEventListener("error", function () { + alert("Thumbnail 파일 전송 중 오류:"); + }, false); + + xhr.send(data); + }, + + dataLoadHandler: function (evt) { + var self = this, + filename = evt.target.file.name, + filetype = evt.target.file.type, + file = evt.target.file, + blob, image, orientation = 1; + + if (evt.target.readyState === FileReader.DONE) { + blob = new self.MyBlob(self.NewBlob(evt.target.result, filetype)); + orientation = self.getOrientation(evt.target.result.slice(0, 64 * 1024)); + image = new Image(); + + image.onload = function () { + var bitmapData = null, + canvas = document.createElement("canvas"), + data = new FormData(), + fileFormat, + imgBox = file.boxElem, + imgInfo = {}, + randomName, + xhr = new XMLHttpRequest(); + + xhr.open('POST', uploadScript, true); + + if (imageResizeWidth > 0 && this.width > imageResizeWidth) { + bitmapData = self.imageResize(this, filetype, imageResizeWidth, orientation, true); + file = self.canvasToBlob(bitmapData, filetype); + } + + fileFormat = filename.substring(filename.lastIndexOf('.')); + randomName = self.makeFilename(fileFormat); + + data.append('origname', filename); + data.append(inputFileName, file, randomName); // RFC Level 2 + + if (debug) { + console.log('Successed: ' + filename); + } + + xhr.addEventListener("error", function (evt) { + alert("파일 전송 중 오류: " + evt.target.error.code); + }, false); + + xhr.addEventListener("loadend", function onLoadendImageHandler(xhrevt) { + if (xhrevt.target.readyState === xhrevt.target.DONE) { + if (oEditor.config.makeThumbnail) { + self.makeThumbnail(image, filetype, randomName, orientation, false); + } + } + image.src = ''; + image = null; + }, false); + + xhr.addEventListener("load", function (xhrevt) { + var jsonText, jsonData, img, onLoadHandler; + data = null; + + if (xhrevt.target.status === 200) { + jsonText = decodeURI(oEditor.trimSpace(this.responseText)); + jsonText = jsonText.replace(/\+/g, ' ').replace(/\\/g, '\\\\'); + jsonData = JSON.parse(jsonText); + + onLoadHandler = function () { + imgInfo = { + fileName: jsonData.fileName, + filePath: jsonData.filePath, + fileSize: jsonData.fileSize, + fileUrl: jsonData.fileUrl, + origName: filename, + origSize: file.size, + height: img.height, + width: img.width + }; + + imageCompletedList[imgBox.id] = imgInfo; + imgComplete(this, imgInfo, imgBox.id); + imgBox.appendChild(img); + + if (debug) { + console.log('Image URL: ' + img.src + ', size:' + file.size); + } + + setTimeout(function () { + self.load(); + }, 100); + + if (debug) { + console.log('Uploaded'); + } + }; + img = new Image(); + img.onload = onLoadHandler; + img.src = decodeURIComponent(jsonData.fileUrl); + } else { + alert("HTTP 오류: " + xhr.status); + } + }, false); + + blob.dispose(); + blob = null; + xhr.send(data); + }; + + image.src = blob.getURL(); + } + }, + + onReadDataErrorHandler: function (evt) { + var status = ''; + switch (evt.target.error.code) { + case evt.target.error.NOT_FOUND_ERR: + status = "파일을 찾을 수 없습니다."; + break; + case evt.target.error.NOT_READABLE_ERR: + status = "파일을 읽을 수 없습니다."; + break; + case evt.target.error.ABORT_ERR: + status = "파일 읽기가 중지되었습니다."; + break; + case evt.target.error.SECURITY_ERR: + status = "파일이 잠겨 있습니다."; + break; + case evt.target.error.ENCODING_ERR: + status = "data:// URL의 파일 인코딩 길이가 너무 깁니다."; + break; + default: + status = "파일 읽기 오류: " + evt.target.error.code; + } + this.removeEventListener('error', this.onReadDataErrorHandler); + alert("'" + evt.target.filename + "' " + status); + }, + + load: function () { + var file = this.list.shift(), self = this, watermark = null; + + if (file) { + if (debug) { + console.log('File ' + this.index + ', Name: ' + file.name + ', Size: ' + file.size); + } + this.reader.file = file; + this.reader.watermark = null; + + if (oEditor.config.imgWaterMarkUrl !== '' && oEditor.config.imgWaterMarkUrl !== null) { + watermark = new Image(); + watermark.onerror = function () { + alert('워터마크 이미지를 읽을 수 없습니다. (' + oEditor.config.imgWaterMarkUrl + ')'); + self.reader.readAsArrayBuffer(file); + }; + watermark.onload = function () { + self.reader.watermark = this; + self.reader.readAsArrayBuffer(file); + }; + watermark.src = oEditor.config.imgWaterMarkUrl; + } else { + this.reader.readAsArrayBuffer(file); + } + } else { + this.clear(); + } + }, + + clear: function () { + var inputFile = document.getElementById('inputImageUpload'), + theForm = document.createElement('form'), + fileSelectButton = document.getElementById('fileSelectButton'); + + this.list = []; + + theForm.appendChild(inputFile); + theForm.reset(); + fileSelectButton.parentNode.insertBefore(inputFile, fileSelectButton); + fileSelectButton.style.marginLeft = '-1px'; + } +}; + +function fileSelectDrop(evt) { + var files, + upload = new DoUpload(); + + oEditor.stopEvent(evt); + this.className = "imageListWrapperHtml5"; + + files = evt.dataTransfer.files; + upload.select(files); +} + +function dragOver(ev) { + oEditor.stopEvent(ev); + this.className = "dragOver"; +} + +function dragOut(ev) { + oEditor.stopEvent(ev); + this.className = "imageListWrapperHtml5"; +} + +function setResizeWidth() { + var value = oEditor.trimSpace(imageResizeInput.value); + if (value) { + value = Math.ceil(parseInt(value, 10)); + if (!isNaN(value) && value < oEditor.config.imgMaxWidth) { + imageResizeWidth = value; + } else { + imageResizeInput.value = ''; + imageResizeInput.setAttribute('placeholder', oEditor.config.imgMaxWidth.toString()); + } + } +} + +function init(dialog) { + var dlg, i, elem, input, select, value, name; + + oEditor = this; + oEditor.dialog = dialog; + dlg = new Dialog(oEditor); + browser = oEditor.getBrowser(); + + 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) { + for (i = 0; i < oEditor.config.imgResizeValue.length; i++) { + name = value = oEditor.config.imgResizeValue[i]; + if (value > oEditor.config.imgMaxWidth) { + continue; + } + if (value === -1) { + name = '<입력>'; + } + select.options[select.options.length] = new Option(name, value, false, value === oEditor.config.imgResizeSelected); + } + select.onchange = function () { + if (this.value < 0) { + document.getElementById('idUserInputWrapper').style.display = ''; + } else { + document.getElementById('idUserInputWrapper').style.display = 'none'; + imageResizeWidth = this.value; + } + }; + imageResizeInput.setAttribute('placeholder', imageResizeWidth.toString()); + imageResizeWidth = select.value; + } else { + select.options[0] = new Option('원본', 0); + select.setAttribute('disabled', 'disabled'); + imageResizeWidth = 0; + } + + document.getElementById("maxImageNum").appendChild(document.createTextNode(uploadMaxNumber.toString())); + + button = [ + { alt: "", img: 'submit.gif', cmd: doSubmit, hspace: 2 }, + { alt: "", img: 'cancel.gif', cmd: closeWindow, hspace: 2 } + ]; + + dlg.setDialogHeight(370); + dlg.showButton(button); + showContents(); + initGallery(); + showUploadWindow(); + createInsertionMaker(); + selectedFilesNum = 0; + + oEditor.addEvent(imageListWrapper, 'dragover', dragOver); + oEditor.addEvent(imageListWrapper, 'dragleave', dragOut); + oEditor.addEvent(imageListWrapper, 'drop', fileSelectDrop); + + elem = document.getElementById('id_alignment').elements; + + for (i = 0; i < elem.length; i++) { + if (elem[i].name === "alignment" && elem[i].value === oEditor.config.imgDefaultAlign) { + elem[i].checked = "checked"; + break; + } + } + + if (browser.mobile) { + input = document.getElementById('inputImageUpload'); + input.setAttribute('capture', 'gallery'); + } +} diff --git a/plugin/editor/cheditor5/popup/js/image.js b/plugin/editor/cheditor5/popup/js/image.js new file mode 100644 index 000000000..7fc7c642f --- /dev/null +++ b/plugin/editor/cheditor5/popup/js/image.js @@ -0,0 +1,890 @@ +// ================================================================ +// CHEditor 5 +// ================================================================ +var uploadScript = '', + deleteScript = '', + AppID = 'chximage', + AppSRC = '', + activeImage = null, + destinationObject = null, + readyToMove = false, + moveTimer = -1, + dragDropDiv, + insertionMarker, + offsetX_marker = -4, + offsetY_marker = -3, + geckoOffsetX_marker = 4, + geckoOffsetY_marker = -2, + divXPositions = [], + divYPositions = [], + divWidth = [], + divHeight = [], + tmpLeft = 0, + tmpTop = 0, + eventDiff_x = 0, + eventDiff_y = 0, + modifyImages = [], + uploadMaxNumber = 12, + imageCompleted = 0, + imageCompletedList = [], + uploadButton = '', + uploadImagePath = '', + showThumbnailSize = { width: 120, height: 90 }, + oEditor = null, + button, + imageResizeWidth = 0, + makeThumbnail = true, + makeThumbnailWidth = 120, + makeThumbnailHeight = 90, + sortOnName = false, + browser = null; + +function createInsertionMaker() { + var wrapper = document.getElementById('insertionMarker'), + topIco = new Image(), + middleIco = new Image(), + bottomIco = new Image(); + + topIco.src = uploadImagePath + '/marker_top.gif'; + topIco.style.width = '6px'; + topIco.style.height = '1px'; + wrapper.appendChild(topIco); + + middleIco.src = uploadImagePath + '/marker_middle.gif'; + middleIco.style.height = '96px'; + middleIco.style.width = '6px'; + wrapper.appendChild(middleIco); + + bottomIco.src = uploadImagePath + '/marker_bottom.gif'; + bottomIco.style.width = '6px'; + bottomIco.style.height = '1px'; + wrapper.appendChild(bottomIco); +} + +function popupClose() { + // ---------------------------------------------------------------------------------- + swfobject.removeSWF(AppID); + oEditor.popupWinCancel(); +} + +function showContents() { + var spacer = function (id) { + var clear = document.createElement('span'); + clear.style.height = '0'; + clear.style.width = '0'; + clear.className = 'clear'; + clear.id = 'spacer' + id; + return clear; + }, spacerNo = 1, i, imgBox, theImg, lastSpacer; + + for (i = 0; i < uploadMaxNumber; i++) { + if (i > 0 && ((i % 4) === 0)) { + document.getElementById('imageListWrapper').appendChild(spacer(spacerNo++)); + } + + imgBox = document.createElement('div'); + imgBox.id = 'imgBox' + i; + imgBox.className = 'imageBox'; + theImg = document.createElement('div'); + theImg.id = 'img_' + i; + theImg.className = 'imageBox_theImage'; + imgBox.appendChild(theImg); + + document.getElementById('imageListWrapper').appendChild(imgBox); + if (i === (uploadMaxNumber - 1)) { + lastSpacer = spacer(spacerNo); + lastSpacer.style.height = "7px"; + document.getElementById('imageListWrapper').appendChild(lastSpacer); + } + } + + if (browser.msie && browser.ver < 7) { + document.getElementById('imageListWrapper').style.padding = '5px 2px 5px 2px'; + document.getElementById('imageInfoBox').style.height = '302px'; + document.getElementById('imageInfoBox').style.width = '124px'; + } else { + document.getElementById('imageListWrapper').style.padding = '5px 7px 0 5px'; + document.getElementById('imageInfoBox').style.height = '298px'; + document.getElementById('imageInfoBox').style.width = '130px'; + } +} + +function openFiles() { + // ---------------------------------------------------------------------------------- + var elem = browser.msie ? document.getElementById(AppID) : document[AppID]; + elem.AddFiles(); +} + +function setImageCount() { + imageCompleted++; + document.getElementById('imageCount').innerHTML = imageCompleted; +} + +function getImageCount() { + return imageCompleted; +} + +function allowedMaxImage() { + return uploadMaxNumber - getImageCount(); +} + +function getUploadedCount() { + return document.getElementById('imageListWrapper').getElementsByTagName('img').length; +} + +function uploadedImageCount() { + imageCompleted = getUploadedCount(); + document.getElementById('imageCount').innerHTML = imageCompleted; +} + +function uploadError(msg) { + alert(msg); +} + +function imageDelete(filePath) { + var chximage = document.getElementById(AppID); + chximage.ImageDelete(encodeURI(filePath)); +} + +function getTopPos(inputObj) { + // ---------------------------------------------------------------------------------- + var returnValue = inputObj.offsetTop; + + inputObj = inputObj.offsetParent; + while (inputObj) { + if (inputObj.tagName.toLowerCase() !== 'html') { + returnValue += (inputObj.offsetTop - inputObj.scrollTop); + if (browser.msie) { + returnValue += inputObj.clientTop; + } + } + inputObj = inputObj.offsetParent; + } + return returnValue; +} + +function getLeftPos(inputObj) { + // ---------------------------------------------------------------------------------- + var returnValue = inputObj.offsetLeft; + + inputObj = inputObj.offsetParent; + while (inputObj) { + if (inputObj.id !== 'imageListWrapper') { + returnValue += inputObj.offsetLeft; + if (browser.msie) { + returnValue += inputObj.clientLeft; + } + } + inputObj = inputObj.offsetParent; + } + return returnValue; +} + +function getDivCoordinates() { + // ---------------------------------------------------------------------------------- + var imgBox = document.getElementById('imageListWrapper').getElementsByTagName('DIV'), + i = 0; + + for (; i < imgBox.length; i++) { + if ((imgBox[i].className === 'imageBox' || imgBox[i].className === 'imageBoxHighlighted') && imgBox[i].id) { + divXPositions[imgBox[i].id] = getLeftPos(imgBox[i]); + divYPositions[imgBox[i].id] = getTopPos(imgBox[i]); + divWidth[imgBox[i].id] = imgBox[i].offsetWidth; + divHeight[imgBox[i].id] = imgBox[i].offsetHeight; + } + } +} + +function reOrder() { + // ---------------------------------------------------------------------------------- + var wrapper = document.getElementById('imageListWrapper'), + imgBox = wrapper.getElementsByTagName('div'), + imgNum = 0, i, spacer, breakline = []; + + for (i = 0; i < imgBox.length; i++) { + if (imgBox[i].id.indexOf('imgBox') === -1) { + continue; + } + + imgBox[i].className = 'imageBox'; + imgBox[i].firstChild.className = 'imageBox_theImage'; + + if (imgNum > 0 && (imgNum % 4) === 0) { + breakline.push(imgBox[i].id); + } + + imgNum++; + } + + for (i = 0; i < breakline.length; i++) { + spacer = document.getElementById('spacer' + (i + 1)); + if (i + 1 === breakline.length) { + wrapper.appendChild(spacer); + } else { + wrapper.insertBefore(spacer, document.getElementById(breakline[i])); + } + } +} + +function setImageInfo(id) { + var elem; + if (!id) { + document.getElementById('selectedImageWidth').innerHTML = '0'; + document.getElementById('selectedImageHeight').innerHTML = '0'; + document.getElementById('selectedImageName').innerHTML = "없음"; + } else { + elem = imageCompletedList[id]; + document.getElementById('selectedImageWidth').innerHTML = elem.width; + document.getElementById('selectedImageHeight').innerHTML = elem.height; + document.getElementById('selectedImageName').innerHTML = elem.origName; + } +} + +function showDelete() { + // ---------------------------------------------------------------------------------- + var self = this, btn; + + if (readyToMove) { + return; + } + + getDivCoordinates(); + self.className = 'imageBox_theImage_over'; + btn = document.getElementById('removeImageButton'); + btn.style.left = (showThumbnailSize.width - parseInt(btn.style.width, 10) - 1) + 'px'; + btn.style.top = '-1px'; + + self.appendChild(btn); + btn.style.display = 'block'; + + btn.onmouseover = function (ev) { + ev = ev || window.event; + ev.cancelBubble = true; + this.style.display = 'block'; + setImageInfo(self.id); + this.className = 'removeButton_over'; + self.className = 'imageBox_theImage_over'; + }; + btn.onmouseout = function () { + this.className = 'removeButton'; + }; + btn.onmousedown = function () { + var images = self.getElementsByTagName('img'), i, wrapper, moveobj, target; + + for (i = 0; i < images.length; i++) { + self.removeChild(images[i]); + } + + self.removeChild(self.firstChild); + self.className = 'imageBox_theImage'; + + if (self.parentNode.nextSibling && self.parentNode.nextSibling.id) { + wrapper = document.getElementById('imageListWrapper'); + moveobj = self.parentNode.nextSibling; + target = self.parentNode; + + while (moveobj !== null) { + if (moveobj.firstChild && !moveobj.firstChild.firstChild) { + break; + } + if (/^spacer/.test(moveobj.id)) { + moveobj = moveobj.nextSibling; + continue; + } + wrapper.insertBefore(moveobj, target); + moveobj = target.nextSibling; + } + } + + reOrder(); + uploadedImageCount(); + setImageInfo(0); + this.style.display = 'none'; + document.body.appendChild(this); + self.onmouseout = self.onmouseover = null; + }; + + setImageInfo(self.id); +} + +function hideDelete() { + // ---------------------------------------------------------------------------------- + document.getElementById('removeImageButton').style.display = 'none'; +} + +function startUpload(count) { + // ---------------------------------------------------------------------------------- + var el = document.getElementById('imageListWrapper').getElementsByTagName('div'), i, imgBox; + + for (i = 0; i < el.length; i++) { + imgBox = el[i]; + if (imgBox.className !== 'imageBox_theImage') { + continue; + } + + if (count === 0) { + break; + } + + if (!imgBox.firstChild || imgBox.firstChild.tagName.toLowerCase() !== 'img') { + imgBox.style.backgroundImage = "url('" + uploadImagePath + "/loader.gif')"; + count--; + } + } +} + +function fileFilterError(file) { + alert("선택하신 '" + file + "' 파일은 전송할 수 없습니다.\n" + + "gif, png, jpg, 그림 파일만 전송할 수 있습니다."); +} + +function imgComplete(img, imgSize, boxId) { + var resizeW, resizeH, M, elem; + img.setAttribute("border", '0'); + + 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); + } else { + 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); + } + + } else { + resizeW = imgSize.width; + resizeH = imgSize.height; + } + + img.style.width = resizeW - 2 + 'px'; + img.style.height = resizeH - 2 + 'px'; + img.style.margin = "1px"; + + if (resizeW < showThumbnailSize.width) { + M = showThumbnailSize.width - resizeW; + img.style.marginLeft = Math.round(M / 2) + 'px'; + } + + if (resizeH < showThumbnailSize.height) { + M = showThumbnailSize.height - resizeH; + img.style.marginTop = Math.round(M / 2) + 'px'; + } + + elem = document.getElementById(boxId); + elem.style.backgroundImage = "url('" + uploadImagePath + "/dot.gif')"; + elem.onmouseover = showDelete; + elem.onmouseout = function() { + this.className = 'imageBox_theImage'; + setImageInfo(0); + hideDelete(); + }; + + setImageCount(); +} + +function uploadComplete(image) { + // ---------------------------------------------------------------------------------- + var el = document.getElementById('imageListWrapper').getElementsByTagName('div'), + imgBox = null, tmpImg, i, imgInfo, + imgOnLoad = function () { + imgInfo = { "width": image.width, "height": image.height, "fileSize": image.fileSize, + "fileUrl": image.fileUrl, "fileName": image.fileName, "filePath": image.filePath, "origName": image.origName }; + + imageCompletedList[imgBox.id] = imgInfo; + imgComplete(this, imgInfo, imgBox.id); + }; + + image.filePath = decodeURI(image.filePath); + image.origName = decodeURI(image.origName); + + for (i = 0; i < el.length; i++) { + imgBox = el[i]; + if (imgBox.className !== 'imageBox_theImage') { + continue; + } + + if (!imgBox.firstChild || imgBox.firstChild.tagName.toLowerCase() !== 'img') { + tmpImg = new Image(); + tmpImg.style.width = "0px"; + tmpImg.style.height = "0px"; + tmpImg.setAttribute("alt", image.origName); + tmpImg.onload = imgOnLoad; + tmpImg.src = image.fileUrl; + imgBox.appendChild(tmpImg); + break; + } + } +} + +function showUploadWindow() { + // ---------------------------------------------------------------------------------- + var uploadWindow = document.getElementById("uploadWindow"), + uploadWindowWidth = 700, + winWidth, el, i, j, imgBox, img; + + if (!(oEditor.undefined(window.innerWidth))) { + winWidth = window.innerWidth; + } else if (document.documentElement && + (!(oEditor.undefined(document.documentElement.clientWidth))) && + document.documentElement.clientWidth !== 0) { + winWidth = document.documentElement.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.display = "block"; + uploadWindow.style.width = uploadWindowWidth + 'px'; + + if (modifyImages.length > 0) { + el = document.getElementById('imageListWrapper').getElementsByTagName('div'); + for (i = 0; i < modifyImages.length; i++) { + if (i > 7) { + break; + } + + for (j = 0; j < el.length; j++) { + imgBox = el[j]; + if (imgBox.className !== 'imageBox_theImage') { + continue; + } + + if (imgBox.firstChild && (imgBox.firstChild.src === modifyImages[i])) { + break; + } + + if (imgBox.firstChild === null) { + img = new Image(); + img.src = modifyImages[i]; + img.border = 0; + img.alt = ''; + img.style.width = '120px'; + img.style.height = '90px'; + imgBox.appendChild(img); + break; + } + } + } + } +} + +function removeImages() { + var images = [], i, j, theImage, img, remove; + document.body.appendChild(document.getElementById('removeImageButton')); + + for (i = 0; i < uploadMaxNumber; i++) { + theImage = document.getElementById('img_' + i); + if (theImage.hasChildNodes() && theImage.firstChild.tagName.toLowerCase() === 'img') { + images.push(theImage); + } + } + + for (i = 0; i < images.length; i++) { + img = images[i]; + if (img.firstChild !== null) { + oEditor.removeEvent(img, 'mouseover', showDelete); + remove = img.getElementsByTagName('img'); + + for (j = 0; j < remove.length; j++) { + img.removeChild(remove[j]); + } + + img.parentNode.className = 'imageBox'; + oEditor.removeEvent(img, 'mouseover', showDelete); + } + } + uploadedImageCount(); + imageCompletedList = []; +} + +function removeImage() { + // ---------------------------------------------------------------------------------- + var i, theImage, found = false; + + for (i = 0; i < uploadMaxNumber; i++) { + theImage = document.getElementById('img_' + i); + if (theImage.hasChildNodes() && theImage.firstChild.tagName.toLowerCase() === 'img') { + found = true; + break; + } + } + + if (found) { + if (!confirm('추가하신 사진이 있습니다. 사진 넣기를 취소하시겠습니까?')) { + return false; + } + removeImages(); + } + + return true; +} + +function closeWindow() { + // ---------------------------------------------------------------------------------- + if (removeImage()) { + popupClose(); + } +} + +function cancelEvent() { + // ---------------------------------------------------------------------------------- + return false; +} + +function startMoveTimer() { + // ---------------------------------------------------------------------------------- + var subElements, newDiv; + + if (moveTimer >= 0 && moveTimer < 10) { + moveTimer++; + setTimeout('startMoveTimer()', 8); + } + + if (moveTimer === 5) { + getDivCoordinates(); + subElements = dragDropDiv.getElementsByTagName('div'); + if (subElements.length > 0) { + dragDropDiv.removeChild(subElements[0]); + } + + dragDropDiv.style.display = 'block'; + newDiv = activeImage.cloneNode(true); + newDiv.className = 'imageBox'; + newDiv.style.opacity = 0.5; + + newDiv.id = ''; + newDiv.style.padding = '2px'; + dragDropDiv.appendChild(newDiv); + + dragDropDiv.style.top = tmpTop + 'px'; + dragDropDiv.style.left = tmpLeft + 'px'; + } + + return false; +} + +function getMouseButtn(e) { + var code; + e = e || window.event; + code = e.button; + + if (code) { + if (browser.msie && browser.version < 9) { + code = code === 1 ? 0 : (code === 4 ? 1 : code); + } + } + + return code; +} + +function selectImage(e) { + // ---------------------------------------------------------------------------------- + var el = this.parentNode.firstChild.firstChild, obj; + + if (!el) { + return; + } + + e = e || window.event; + if (getMouseButtn(e) === 2) { + return; + } + + obj = this.parentNode; + hideDelete(); + + obj.className = 'imageBoxHighlighted'; + activeImage = obj; + readyToMove = true; + moveTimer = 0; + + tmpLeft = e.clientX + Math.max(document.body.scrollLeft, document.documentElement.scrollLeft); + tmpTop = e.clientY + Math.max(document.body.scrollTop, document.documentElement.scrollTop); + + startMoveTimer(); + return false; +} + +function dragDropEnd() { + // ---------------------------------------------------------------------------------- + var parentObj, chkObj, turn = false; + + readyToMove = false; + moveTimer = -1; + dragDropDiv.style.display = 'none'; + insertionMarker.style.display = 'none'; + + if (!activeImage) { + return; + } + + if (destinationObject && destinationObject !== activeImage) { + parentObj = destinationObject.parentNode; + chkObj = destinationObject.previousSibling; + turn = false; + + if (chkObj === null) { + chkObj = document.getElementById('imageListWrapper').firstChild; + turn = true; + } + + if (chkObj.id.indexOf('spacer') !== -1) { + chkObj = chkObj.previousSibling; + } + + if (chkObj.firstChild.firstChild === null) { + reOrder(); + return; + } + + if (chkObj && chkObj.id !== null) { + while (chkObj) { + if (chkObj.firstChild.firstChild !== null) { + break; + } + chkObj = chkObj.previousSibling; + } + destinationObject = turn ? chkObj : chkObj.nextSibling; + } + + parentObj.insertBefore(activeImage, destinationObject); + reOrder(); + + activeImage = null; + destinationObject = null; + getDivCoordinates(); + + return false; + } + + activeImage.className = 'imageBox'; + return true; +} + +function dragDropMove(e) { + // ---------------------------------------------------------------------------------- + var elementFound = false, prop, offsetX, offsetY, leftPos, topPos, btnCode; + + if (moveTimer === -1 || !readyToMove) { + return; + } + + e = e || window.event; + + leftPos = e.clientX + document.documentElement.scrollLeft - eventDiff_x; + topPos = e.clientY + document.documentElement.scrollTop - eventDiff_y; + + dragDropDiv.style.top = topPos + 'px'; + dragDropDiv.style.left = leftPos + 'px'; + + leftPos = leftPos + eventDiff_x; + topPos = topPos + eventDiff_y; + + if (getMouseButtn(e) !== 0) { + dragDropEnd(); + } + + for (prop in divXPositions) { + if (!divXPositions.hasOwnProperty(prop) || divXPositions[prop].className === 'clear') { + continue; + } + + if (divXPositions[prop] < leftPos && + (divXPositions[prop] + divWidth[prop] * 0.7) > leftPos && + divYPositions[prop] < topPos && + (divYPositions[prop] + divWidth[prop]) > topPos) { + if (browser.msie) { + offsetX = offsetX_marker; + offsetY = offsetY_marker; + } else { + offsetX = geckoOffsetX_marker; + offsetY = geckoOffsetY_marker; + } + + insertionMarker.style.top = divYPositions[prop] + offsetY + 'px'; + insertionMarker.style.left = divXPositions[prop] + offsetX + 'px'; + insertionMarker.style.display = 'block'; + destinationObject = document.getElementById(prop); + elementFound = true; + break; + } + } + + if (!elementFound) { + insertionMarker.style.display = 'none'; + destinationObject = null; + } + + return false; +} + +function saveImageOrder() { + // ---------------------------------------------------------------------------------- + var rData = [], + objects = document.getElementById('imageListWrapper').getElementsByTagName('div'), + i; + + for (i = 0; i < objects.length; i++) { + if (objects[i].className === 'imageBox' || + objects[i].className === 'imageBoxHighlighted') { + rData.push(objects[i].id); + } + } + + return rData; +} + +function initGallery() { + // ---------------------------------------------------------------------------------- + var imgBox = document.getElementById('imageListWrapper').getElementsByTagName('div'), + i; + + for (i = 0; i < imgBox.length; i++) { + if (imgBox[i].className === 'imageBox_theImage') { + imgBox[i].onmousedown = selectImage; + } + } + + document.body.onselectstart = cancelEvent; + document.body.ondragstart = cancelEvent; + document.body.onmouseup = dragDropEnd; + document.body.onmousemove = dragDropMove; + + dragDropDiv = document.getElementById('dragDropContent'); + insertionMarker = document.getElementById('insertionMarker'); + getDivCoordinates(); +} + +function doSubmit() { + // ---------------------------------------------------------------------------------- + var el = document.getElementById('imageListWrapper').getElementsByTagName('div'), + imageArray = [], + num = 0, + elem = document.getElementById('id_alignment').elements, + imgParagraph = false, + useSpacer = false, + imgAlign = 'top', i, imgBox, input; + + for (i = 0; i < elem.length; i++) { + input = elem[i]; + switch (input.name) { + case "alignment" : + if (input.checked) { + imgAlign = input.value; + } + break; + case "para" : + imgParagraph = input.checked; + break; + case "use_spacer" : + useSpacer = input.checked; + break; + } + } + + for (i = 0; i < el.length; i++) { + imgBox = el[i]; + if (imgBox.className !== "imageBox_theImage") { + continue; + } + + if (imgBox.firstChild !== null) { + imageArray[num] = imageCompletedList[imgBox.id]; + + if (imgAlign === "break") { + imageArray[num].alt = "break"; + } else { + imageArray[num].alt = ''; + imageArray[num].align = imgAlign; + } + + num++; + } + } + + if (imageArray.length > 0) { + oEditor.doInsertImage(imageArray, imgParagraph, useSpacer); + } + oEditor.popupWinClose(); +} + +function initEvent() { + var swfVersionStr = "11.1.0", + xiSwfUrlStr = "http://get.adobe.com/kr/flashplayer/", + flashvars = { + UploadScript: uploadScript, + DeleteScript: deleteScript, + UploadButton: uploadButton, + MakeThumbnail: makeThumbnail, + ThumbnailWidth: makeThumbnailWidth, + ThumbnailHeight: makeThumbnailHeight, + ImageResizeWidth: imageResizeWidth, + loadPolicyFile: true, + SortOnName: sortOnName + }, + params = { + quality: "high", + bgcolor: "#ffffff", + allowscriptaccess: "Always", + allowfullscreen: "false", + //allowNetworking: "all", + wmode: "transparent" + }, + attributes = { id: AppID, name: AppID, align: "middle" }; + + swfobject.embedSWF(AppSRC, "oFlashButton", "93", "22", swfVersionStr, xiSwfUrlStr, flashvars, params, attributes); +} + +function init(dialog) { + var dlg = new Dialog(this), + elem = document.getElementById('id_alignment').elements, + i; + + oEditor = this; + oEditor.dialog = dialog; + + browser = oEditor.getBrowser(); + + uploadImagePath = oEditor.config.iconPath + 'imageUpload'; + uploadButton = '../icons/imageUpload/add.gif'; + AppSRC = oEditor.config.popupPath + 'flash/chximage.swf'; + uploadMaxNumber = oEditor.config.imgUploadNumber; + uploadScript = oEditor.config.editorPath + 'imageUpload/upload.php'; + deleteScript = oEditor.config.editorPath + 'imageUpload/delete.php'; + + imageResizeWidth = oEditor.config.imgMaxWidth; + makeThumbnail = oEditor.config.makeThumbnail; + sortOnName = oEditor.config.imgUploadSortName; + makeThumbnailWidth = oEditor.config.thumbnailWidth; + makeThumbnailHeight = oEditor.config.thumbnailHeight; + + document.getElementById("maxImageNum").appendChild(document.createTextNode(uploadMaxNumber)); + + button = [ + { alt: "", img: 'submit.gif', cmd: doSubmit, hspace: 2 }, + { alt: "", img: 'cancel.gif', cmd: closeWindow, hspace: 2 } + ]; + + dlg.setDialogHeight(370); + dlg.showButton(button); + showContents(); + initGallery(); + showUploadWindow(); + initEvent(); + createInsertionMaker(); + + for (i = 0; i < elem.length; i++) { + if (elem[i].name === "alignment" && elem[i].value === oEditor.config.imgDefaultAlign) { + elem[i].checked = "checked"; + break; + } + } +} diff --git a/plugin/editor/cheditor5/popup/js/image_upload_flash.js b/plugin/editor/cheditor5/popup/js/image_upload_flash.js new file mode 100644 index 000000000..fb70ba021 --- /dev/null +++ b/plugin/editor/cheditor5/popup/js/image_upload_flash.js @@ -0,0 +1,279 @@ +// Flash Player Version Detection - Rev 1.6 +// Detect Client Browser type +// Copyright(c) 2005-2006 Adobe Macromedia Software, LLC. All rights reserved. +var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false; +var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false; +var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false; + +function ControlVersion() +{ + var version = 0; + var axo; +// var e; + + // NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry + + try { + // version will be set for 7.X or greater players + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); + version = axo.GetVariable("$version"); + } catch (e) { + } + + if (!version) + { + try { + // version will be set for 6.X players only + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); + + // installed player is some revision of 6.0 + // GetVariable("$version") crashes for versions 6.0.22 through 6.0.29, + // so we have to be careful. + + // default to the first public version + version = "WIN 6,0,21,0"; + + // throws if AllowScripAccess does not exist (introduced in 6.0r47) + axo.AllowScriptAccess = "always"; + + // safe to call for 6.0r47 or greater + version = axo.GetVariable("$version"); + + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 4.X or 5.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); + version = axo.GetVariable("$version"); + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 3.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); + version = "WIN 3,0,18,0"; + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 2.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); + version = "WIN 2,0,0,11"; + } catch (e) { + version = -1; + } + } + + return version; +} + +// JavaScript helper required to detect Flash Player PlugIn version information +function GetSwfVer(){ + // NS/Opera version >= 3 check for Flash plugin in plugin array + var flashVer = -1; + + if (navigator.plugins != null && navigator.plugins.length > 0) { + if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) { + var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : ""; + var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description; + var descArray = flashDescription.split(" "); + var tempArrayMajor = descArray[2].split("."); + var versionMajor = tempArrayMajor[0]; + var versionMinor = tempArrayMajor[1]; + var versionRevision = descArray[3]; + if (versionRevision == "") { + versionRevision = descArray[4]; + } + if (versionRevision[0] == "d") { + versionRevision = versionRevision.substring(1); + } else if (versionRevision[0] == "r") { + versionRevision = versionRevision.substring(1); + if (versionRevision.indexOf("d") > 0) { + versionRevision = versionRevision.substring(0, versionRevision.indexOf("d")); + } + } else if (versionRevision[0] == "b") { + versionRevision = versionRevision.substring(1); + } + flashVer = versionMajor + "." + versionMinor + "." + versionRevision; + } + } + // MSN/WebTV 2.6 supports Flash 4 + else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4; + // WebTV 2.5 supports Flash 3 + else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3; + // older WebTV supports Flash 2 + else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2; + else if ( isIE && isWin && !isOpera ) { + flashVer = ControlVersion(); + } + return flashVer; +} + +// When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available +function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) +{ + versionStr = GetSwfVer(); + if (versionStr == -1 ) { + return false; + } else if (versionStr != 0) { + if(isIE && isWin && !isOpera) { + // Given "WIN 2,0,0,11" + tempArray = versionStr.split(" "); // ["WIN", "2,0,0,11"] + tempString = tempArray[1]; // "2,0,0,11" + versionArray = tempString.split(","); // ['2', '0', '0', '11'] + } else { + versionArray = versionStr.split("."); + } + var versionMajor = versionArray[0]; + var versionMinor = versionArray[1]; + var versionRevision = versionArray[2]; + + // is the major.revision >= requested major.revision AND the minor version >= requested minor + if (versionMajor > parseFloat(reqMajorVer)) { + return true; + } else if (versionMajor == parseFloat(reqMajorVer)) { + if (versionMinor > parseFloat(reqMinorVer)) + return true; + else if (versionMinor == parseFloat(reqMinorVer)) { + if (versionRevision >= parseFloat(reqRevision)) + return true; + } + } + return false; + } +} + +function AC_AddExtension(src, ext) +{ + if (src.indexOf('?') != -1) + return src.replace(/\?/, ext+'?'); + else + return src + ext; +} + +function AC_Generateobj(objAttrs, params, embedAttrs) +{ + if (isIE && isWin && !isOpera) + { + var str = ' '; + str += ''; + document.getElementById("oFlash").innerHTML = str; + } + else { + var oFlash = document.getElementById("oFlash"); + var embed = document.createElement('embed'); + for (var i in embedAttrs) { + embed.setAttribute(i, embedAttrs[i]); + } + oFlash.appendChild(embed); + } +} + +function CHXImageRUN(){ + var ret = + AC_GetArgs + ( arguments, ".swf", "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" + , "application/x-shockwave-flash" + ); + AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs); +} + +function AC_GetArgs(args, ext, srcParamName, classid, mimeType){ + var ret = new Object(); + ret.embedAttrs = new Object(); + ret.params = new Object(); + ret.objAttrs = new Object(); + for (var i=0; i < args.length; i=i+2){ + var currArg = args[i].toLowerCase(); + + switch (currArg){ + case "classid": + break; + case "pluginspage": + ret.embedAttrs[args[i]] = args[i+1]; + break; + case "src": + case "movie": + args[i+1] = AC_AddExtension(args[i+1], ext); + ret.embedAttrs["src"] = args[i+1]; + ret.params[srcParamName] = args[i+1]; + break; + case "onafterupdate": + case "onbeforeupdate": + case "onblur": + case "oncellchange": + case "onclick": + case "ondblClick": + case "ondrag": + case "ondragend": + case "ondragenter": + case "ondragleave": + case "ondragover": + case "ondrop": + case "onfinish": + case "onfocus": + case "onhelp": + case "onmousedown": + case "onmouseup": + case "onmouseover": + case "onmousemove": + case "onmouseout": + case "onkeypress": + case "onkeydown": + case "onkeyup": + case "onload": + case "onlosecapture": + case "onpropertychange": + case "onreadystatechange": + case "onrowsdelete": + case "onrowenter": + case "onrowexit": + case "onrowsinserted": + case "onstart": + case "onscroll": + case "onbeforeeditfocus": + case "onactivate": + case "onbeforedeactivate": + case "ondeactivate": + case "type": + case "codebase": + ret.objAttrs[args[i]] = args[i+1]; + break; + case "id": + case "width": + case "height": + case "align": + case "vspace": + case "hspace": + case "class": + case "title": + case "accesskey": + case "name": + case "tabindex": + ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i+1]; + break; + default: + ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i+1]; + } + } + ret.objAttrs["classid"] = classid; + if (mimeType) ret.embedAttrs["type"] = mimeType; + return ret; +} + + diff --git a/plugin/editor/cheditor5/popup/js/image_url.js b/plugin/editor/cheditor5/popup/js/image_url.js new file mode 100644 index 000000000..fa5b85d7d --- /dev/null +++ b/plugin/editor/cheditor5/popup/js/image_url.js @@ -0,0 +1,244 @@ +// ================================================================ +// CHEditor 5 +// ---------------------------------------------------------------- +// Homepage: http://www.chcode.com +// Copyright (c) 1997-2014 CHSOFT +// ================================================================ +var AppWidth = "250"; +var AppHeight = "175"; +var AppID = "cheditorPreview"; +var oEditor = null; +var button = [ { alt : "", img : 'submit.gif', cmd : doSubmit }, + { alt : "", img : 'cancel.gif', cmd : popupClose } ]; +var newImage = null; + +function CHEditorImagePreview () { +// ---------------------------------------------------------------------------------- +// callBack function + + document.getElementById(AppID).CHEditorImagePreview("1", "1"); +} + +function CHXUploadRUN(src) { +// ---------------------------------------------------------------------------------- +// Preview +// + chxupload_RUN("src", src, + "width", AppWidth, + "height", AppHeight, + "align", "middle", + "id", AppID, + "classid", AppID, + "quality", "high", + "bgcolor", "#ebe9ed", + "name", AppID, + "wmode", "transparent", + "allowScriptAccess","Always", + "type", "application/x-shockwave-flash", + "pluginspage", "http://www.adobe.com/go/getflashplayer"); +} + +function getFilename (file) { + while (file.indexOf("/") != -1) { + file = file.slice(file.indexOf("/") + 1); + } + return file; +} + +function popupClose() +{ + oEditor.popupWinCancel(); +} + +function chkImgFormat (url) +{ + var imageName = getFilename(url); + var allowSubmit = false; + var extArray = [".gif", ".jpg", ".jpeg", ".png"]; + + extArray.join(" "); + if (imageName === "") { + return false; + } + + var ext = imageName.slice(imageName.lastIndexOf(".")).toLowerCase(); + var i; + + for (i = 0; i < extArray.length; i++) { + if (extArray[i] == ext) { + allowSubmit = true; + break; + } + } + + if (!allowSubmit) { + alert("사진은 GIF, JPG, PNG 형식만 넣을 수 있습니다."); + return false; + } + + return imageName; +} + +function previewImage (source) { + if (navigator.appName.indexOf("microsoft") != -1) { + window[AppID].CHEditorImagePreview(source, 0, 0); + } + else { + document[AppID].CHEditorImagePreview(source, 0, 0); + } +} + +function checkImageComplete (img) { + if (img.complete != true) { + setTimeout("checkImageComplete(document.getElementById('"+img.id+"'))", 250); + } + else { + document.getElementById('imageSize').innerHTML = ''; + + newImage = new Image(); + newImage.style.width = img.width + 'px'; + newImage.style.height = img.height + 'px'; + newImage.setAttribute("src", img.src); + newImage.setAttribute("alt", getFilename(img.src)); + } +} + +function doPreview () { + var imgurl = document.getElementById('fm_imageUrl').value; + var fileName = chkImgFormat(imgurl); + if (!fileName) { + return; + } + + var img = new Image(); + img.src = imgurl; + img.id = fileName; + + document.getElementById('tmpImage').appendChild(img); + checkImageComplete(img); + previewImage(img.src); +} + +function getElementById(id) { + var el = null; + try { + el = document.getElementById(id); + } + catch (ignore) {} + return el; +} + +function removeObjectInIE(id) { + var obj = getElementById(id); + if (obj) { + var i; + for (i in obj) { + if (typeof obj[i] == "function") { + obj[i] = null; + } + } + obj.parentNode.removeChild(obj); + } +} + +function removeSWF(id) { + var obj = getElementById(id); + if (obj && obj.nodeName == "OBJECT") { + if (oEditor.getBrowser().msie) { + obj.style.display = "none"; + (function(){ + if (obj.readyState == 4) { + removeObjectInIE(id); + } + })(); + } + else { + obj.parentNode.removeChild(obj); + } + } +} + +function doSubmit () +{ + if (newImage == null) { + alert("미리 보기 버튼을 클릭하여 이미지를 확인해 주십시오."); + return; + } + + if (navigator.userAgent.toLowerCase().indexOf("msie") != -1) { + document.getElementById(AppID).style.display = 'none'; + } + + var fm_align = document.getElementById('fm_align').alignment; + var align = 'center'; + var i; + + for (i=0; i 0) { + datum = ""; + } else { + datum = protocol[0].replace(/^\/\/\//, "//"); + } + } + + document.getElementById("fm_link_value").value = selectedItemValue + datum; + document.getElementById("fm_link_value").focus(); +} + +function returnSelected() { + var text, target = '', title = ''; + + if (document.getElementById("fm_link_value").value !== "") { + text = document.getElementById("fm_link_value").value; + } else { + alert("링크 URL을 입력하여 주십시오."); + return false; + } + + if (document.getElementById("fm_target").value !== "") { + target = document.getElementById("fm_target").value; + } + + if (document.getElementById("fm_title").value !== "") { + title = document.getElementById("fm_title").value; + } + + if ((/^(http|https|file|ftp|mailto|gopher|news|telnet|):\/\//i.test(text)) === false && + (/^(wias|javascript):/i.test(text) === false)) + { + text = "http://" + text; + } + + oEditor.hyperLink(text, target, title); + oEditor.popupWinClose(); +} + +function getSelected() { + var rng = oEditor.range, link = null, protocol, protocolSel, i, oldTarget, targetSel, j; + + if (window.getSelection) { + link = oEditor.getElement(rng.startContainer, "A"); + } else { + link = rng.parentElement ? oEditor.getElement(rng.parentElement(), "A") : oEditor.getElement(rng.item(0), "A"); + } + + if (link === null || link.nodeName.toLowerCase() !== 'a') { + return; + } + + protocol = link.href.split(":"); + + if (protocol[0]) { + protocolSel = document.getElementById("fm_protocol"); + for (i = 0; i < protocolSel.length; i++) { + if (protocolSel[i].value.indexOf(protocol[0].toLowerCase()) !== -1) { + oldTarget = link.target; + targetSel = document.getElementById("fm_target"); + + if (oldTarget) { + for (j = 0; j < targetSel.length; j++) { + if (targetSel[j].value === oldTarget.toLowerCase()) { + targetSel[j].selected = true; + break; + } + } + } else { + targetSel[0].selected = true; + } + + protocolSel[i].selected = true; + + if (link.title) { + document.getElementById("fm_title").value = link.title; + } + break; + } + } + } + document.getElementById("fm_link_value").value = link.href; +} + +function init(dialog) { + oEditor = this; + oEditor.dialog = dialog; + + resetValues(); + getSelected(); + + var dlg = new Dialog(oEditor); + dlg.showButton(button); + dlg.setDialogHeight(); +} diff --git a/plugin/editor/cheditor5/popup/js/media.js b/plugin/editor/cheditor5/popup/js/media.js new file mode 100644 index 000000000..e808ee320 --- /dev/null +++ b/plugin/editor/cheditor5/popup/js/media.js @@ -0,0 +1,46 @@ +// ================================================================ +// CHEditor 5 +// ---------------------------------------------------------------- +// Homepage: http://www.chcode.com +// Copyright (c) 1997-2014 CHSOFT +// ================================================================ +var button = [ + { alt : "", img : 'play.gif', cmd : play }, + { alt : "", img : 'submit.gif', cmd : doSubmit }, + { alt : "", img : 'cancel.gif', cmd : popupClose } +]; + +var oEditor = null; + +function init(dialog) { + oEditor = this; + oEditor.dialog = dialog; + + var dlg = new Dialog(oEditor); + dlg.showButton(button); + + dlg.setDialogHeight(); +} + +function play() +{ + var file = document.getElementById("fm_linkurl"); + if (!file.value) + return; + + var mediaobj = ""; + var obj = document.getElementById("play"); + obj.innerHTML = mediaobj; +} + +function doSubmit() +{ + var file = document.getElementById("fm_linkurl"); + var media = ""; + oEditor.insertHtmlPopup(media); + oEditor.popupWinClose(); +} + +function popupClose() { + oEditor.popupWinCancel(); +} \ No newline at end of file diff --git a/plugin/editor/cheditor5/popup/js/swfobject.js b/plugin/editor/cheditor5/popup/js/swfobject.js new file mode 100644 index 000000000..c8aa31ce3 --- /dev/null +++ b/plugin/editor/cheditor5/popup/js/swfobject.js @@ -0,0 +1,779 @@ +/*! SWFObject v2.2 + is released under the MIT License +*/ + +var swfobject = function() { + + var UNDEF = "undefined", + OBJECT = "object", + SHOCKWAVE_FLASH = "Shockwave Flash", + SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash", + FLASH_MIME_TYPE = "application/x-shockwave-flash", + EXPRESS_INSTALL_ID = "SWFObjectExprInst", + ON_READY_STATE_CHANGE = "onreadystatechange", + + win = window, + doc = document, + nav = navigator, + + plugin = false, + domLoadFnArr = [main], + regObjArr = [], + objIdArr = [], + listenersArr = [], + storedAltContent, + storedAltContentId, + storedCallbackFn, + storedCallbackObj, + isDomLoaded = false, + isExpressInstallActive = false, + dynamicStylesheet, + dynamicStylesheetMedia, + autoHideShow = true, + + /* Centralized function for browser feature detection + - User agent string detection is only used when no good alternative is possible + - Is executed directly for optimal performance + */ + ua = function() { + var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF, + u = nav.userAgent.toLowerCase(), + p = nav.platform.toLowerCase(), + windows = p ? /win/.test(p) : /win/.test(u), + mac = p ? /mac/.test(p) : /mac/.test(u), + webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, // returns either the webkit version or false if not webkit + ie = !+"\v1", // feature detection based on Andrea Giammarchi's solution: http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html + playerVersion = [0,0,0], + d = null; + if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) { + d = nav.plugins[SHOCKWAVE_FLASH].description; + if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) { // navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin indicates whether plug-ins are enabled or disabled in Safari 3+ + plugin = true; + ie = false; // cascaded feature detection for Internet Explorer + d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1"); + playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10); + playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10); + playerVersion[2] = /[a-zA-Z]/.test(d) ? parseInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0; + } + } + else if (typeof win.ActiveXObject != UNDEF) { + try { + var a = new ActiveXObject(SHOCKWAVE_FLASH_AX); + if (a) { // a will return null when ActiveX is disabled + d = a.GetVariable("$version"); + if (d) { + ie = true; // cascaded feature detection for Internet Explorer + d = d.split(" ")[1].split(","); + playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)]; + } + } + } + catch(e) {} + } + return { w3:w3cdom, pv:playerVersion, wk:webkit, ie:ie, win:windows, mac:mac }; + }(), + + /* Cross-browser onDomLoad + - Will fire an event as soon as the DOM of a web page is loaded + - Internet Explorer workaround based on Diego Perini's solution: http://javascript.nwbox.com/IEContentLoaded/ + - Regular onload serves as fallback + */ + onDomLoad = function() { + if (!ua.w3) { return; } + if ((typeof doc.readyState != UNDEF && doc.readyState == "complete") || (typeof doc.readyState == UNDEF && (doc.getElementsByTagName("body")[0] || doc.body))) { // function is fired after onload, e.g. when script is inserted dynamically + callDomLoadFunctions(); + } + if (!isDomLoaded) { + if (typeof doc.addEventListener != UNDEF) { + doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false); + } + if (ua.ie && ua.win) { + doc.attachEvent(ON_READY_STATE_CHANGE, function() { + if (doc.readyState == "complete") { + doc.detachEvent(ON_READY_STATE_CHANGE, arguments.callee); + callDomLoadFunctions(); + } + }); + if (win == top) { // if not inside an iframe + (function(){ + if (isDomLoaded) { return; } + try { + doc.documentElement.doScroll("left"); + } + catch(e) { + setTimeout(arguments.callee, 0); + return; + } + callDomLoadFunctions(); + })(); + } + } + if (ua.wk) { + (function(){ + if (isDomLoaded) { return; } + if (!/loaded|complete/.test(doc.readyState)) { + setTimeout(arguments.callee, 0); + return; + } + callDomLoadFunctions(); + })(); + } + addLoadEvent(callDomLoadFunctions); + } + }(); + + function callDomLoadFunctions() { + if (isDomLoaded) { return; } + try { // test if we can really add/remove elements to/from the DOM; we don't want to fire it too early + var t = doc.getElementsByTagName("body")[0].appendChild(createElement("span")); + t.parentNode.removeChild(t); + } + catch (e) { return; } + isDomLoaded = true; + var dl = domLoadFnArr.length; + for (var i = 0; i < dl; i++) { + domLoadFnArr[i](); + } + } + + function addDomLoadEvent(fn) { + if (isDomLoaded) { + fn(); + } + else { + domLoadFnArr[domLoadFnArr.length] = fn; // Array.push() is only available in IE5.5+ + } + } + + /* Cross-browser onload + - Based on James Edwards' solution: http://brothercake.com/site/resources/scripts/onload/ + - Will fire an event as soon as a web page including all of its assets are loaded + */ + function addLoadEvent(fn) { + if (typeof win.addEventListener != UNDEF) { + win.addEventListener("load", fn, false); + } + else if (typeof doc.addEventListener != UNDEF) { + doc.addEventListener("load", fn, false); + } + else if (typeof win.attachEvent != UNDEF) { + addListener(win, "onload", fn); + } + else if (typeof win.onload == "function") { + var fnOld = win.onload; + win.onload = function() { + fnOld(); + fn(); + }; + } + else { + win.onload = fn; + } + } + + /* Main function + - Will preferably execute onDomLoad, otherwise onload (as a fallback) + */ + function main() { + if (plugin) { + testPlayerVersion(); + } + else { + matchVersions(); + } + } + + /* Detect the Flash Player version for non-Internet Explorer browsers + - Detecting the plug-in version via the object element is more precise than using the plugins collection item's description: + a. Both release and build numbers can be detected + b. Avoid wrong descriptions by corrupt installers provided by Adobe + c. Avoid wrong descriptions by multiple Flash Player entries in the plugin Array, caused by incorrect browser imports + - Disadvantage of this method is that it depends on the availability of the DOM, while the plugins collection is immediately available + */ + function testPlayerVersion() { + var b = doc.getElementsByTagName("body")[0]; + var o = createElement(OBJECT); + o.setAttribute("type", FLASH_MIME_TYPE); + var t = b.appendChild(o); + if (t) { + var counter = 0; + (function(){ + if (typeof t.GetVariable != UNDEF) { + var d = t.GetVariable("$version"); + if (d) { + d = d.split(" ")[1].split(","); + ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)]; + } + } + else if (counter < 10) { + counter++; + setTimeout(arguments.callee, 10); + return; + } + b.removeChild(o); + t = null; + matchVersions(); + })(); + } + else { + matchVersions(); + } + } + + /* Perform Flash Player and SWF version matching; static publishing only + */ + function matchVersions() { + var rl = regObjArr.length; + if (rl > 0) { + for (var i = 0; i < rl; i++) { // for each registered object element + var id = regObjArr[i].id; + var cb = regObjArr[i].callbackFn; + var cbObj = {success:false, id:id}; + if (ua.pv[0] > 0) { + var obj = getElementById(id); + if (obj) { + if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) { // Flash Player version >= published SWF version: Houston, we have a match! + setVisibility(id, true); + if (cb) { + cbObj.success = true; + cbObj.ref = getObjectById(id); + cb(cbObj); + } + } + else if (regObjArr[i].expressInstall && canExpressInstall()) { // show the Adobe Express Install dialog if set by the web page author and if supported + var att = {}; + att.data = regObjArr[i].expressInstall; + att.width = obj.getAttribute("width") || "0"; + att.height = obj.getAttribute("height") || "0"; + if (obj.getAttribute("class")) { att.styleclass = obj.getAttribute("class"); } + if (obj.getAttribute("align")) { att.align = obj.getAttribute("align"); } + // parse HTML object param element's name-value pairs + var par = {}; + var p = obj.getElementsByTagName("param"); + var pl = p.length; + for (var j = 0; j < pl; j++) { + if (p[j].getAttribute("name").toLowerCase() != "movie") { + par[p[j].getAttribute("name")] = p[j].getAttribute("value"); + } + } + showExpressInstall(att, par, id, cb); + } + else { // Flash Player and SWF version mismatch or an older Webkit engine that ignores the HTML object element's nested param elements: display alternative content instead of SWF + displayAltContent(obj); + if (cb) { cb(cbObj); } + } + } + } + else { // if no Flash Player is installed or the fp version cannot be detected we let the HTML object element do its job (either show a SWF or alternative content) + setVisibility(id, true); + if (cb) { + var o = getObjectById(id); // test whether there is an HTML object element or not + if (o && typeof o.SetVariable != UNDEF) { + cbObj.success = true; + cbObj.ref = o; + } + cb(cbObj); + } + } + } + } + } + + function getObjectById(objectIdStr) { + var r = null; + var o = getElementById(objectIdStr); + if (o && o.nodeName == "OBJECT") { + if (typeof o.SetVariable != UNDEF) { + r = o; + } + else { + var n = o.getElementsByTagName(OBJECT)[0]; + if (n) { + r = n; + } + } + } + return r; + } + + /* Requirements for Adobe Express Install + - only one instance can be active at a time + - fp 6.0.65 or higher + - Win/Mac OS only + - no Webkit engines older than version 312 + */ + function canExpressInstall() { + return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312); + } + + /* Show the Adobe Express Install dialog + - Reference: http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=6a253b75 + */ + function showExpressInstall(att, par, replaceElemIdStr, callbackFn) { + isExpressInstallActive = true; + storedCallbackFn = callbackFn || null; + storedCallbackObj = {success:false, id:replaceElemIdStr}; + var obj = getElementById(replaceElemIdStr); + if (obj) { + if (obj.nodeName == "OBJECT") { // static publishing + storedAltContent = abstractAltContent(obj); + storedAltContentId = null; + } + else { // dynamic publishing + storedAltContent = obj; + storedAltContentId = replaceElemIdStr; + } + att.id = EXPRESS_INSTALL_ID; + if (typeof att.width == UNDEF || (!/%$/.test(att.width) && parseInt(att.width, 10) < 310)) { att.width = "310"; } + if (typeof att.height == UNDEF || (!/%$/.test(att.height) && parseInt(att.height, 10) < 137)) { att.height = "137"; } + doc.title = doc.title.slice(0, 47) + " - Flash Player Installation"; + var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn", + fv = "MMredirectURL=" + encodeURI(window.location).toString().replace(/&/g,"%26") + "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title; + if (typeof par.flashvars != UNDEF) { + par.flashvars += "&" + fv; + } + else { + par.flashvars = fv; + } + // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it, + // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work + if (ua.ie && ua.win && obj.readyState != 4) { + var newObj = createElement("div"); + replaceElemIdStr += "SWFObjectNew"; + newObj.setAttribute("id", replaceElemIdStr); + obj.parentNode.insertBefore(newObj, obj); // insert placeholder div that will be replaced by the object element that loads expressinstall.swf + obj.style.display = "none"; + (function(){ + if (obj.readyState == 4) { + obj.parentNode.removeChild(obj); + } + else { + setTimeout(arguments.callee, 10); + } + })(); + } + createSWF(att, par, replaceElemIdStr); + } + } + + /* Functions to abstract and display alternative content + */ + function displayAltContent(obj) { + if (ua.ie && ua.win && obj.readyState != 4) { + // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it, + // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work + var el = createElement("div"); + obj.parentNode.insertBefore(el, obj); // insert placeholder div that will be replaced by the alternative content + el.parentNode.replaceChild(abstractAltContent(obj), el); + obj.style.display = "none"; + (function(){ + if (obj.readyState == 4) { + obj.parentNode.removeChild(obj); + } + else { + setTimeout(arguments.callee, 10); + } + })(); + } + else { + obj.parentNode.replaceChild(abstractAltContent(obj), obj); + } + } + + function abstractAltContent(obj) { + var ac = createElement("div"); + if (ua.win && ua.ie) { + ac.innerHTML = obj.innerHTML; + } + else { + var nestedObj = obj.getElementsByTagName(OBJECT)[0]; + if (nestedObj) { + var c = nestedObj.childNodes; + if (c) { + var cl = c.length; + for (var i = 0; i < cl; i++) { + if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType == 8)) { + ac.appendChild(c[i].cloneNode(true)); + } + } + } + } + } + return ac; + } + + /* Cross-browser dynamic SWF creation + */ + function createSWF(attObj, parObj, id) { + var r, el = getElementById(id); + if (ua.wk && ua.wk < 312) { return r; } + if (el) { + if (typeof attObj.id == UNDEF) { // if no 'id' is defined for the object element, it will inherit the 'id' from the alternative content + attObj.id = id; + } + if (ua.ie && ua.win) { // Internet Explorer + the HTML object element + W3C DOM methods do not combine: fall back to outerHTML + var att = ""; + for (var i in attObj) { + if (attObj[i] != Object.prototype[i]) { // filter out prototype additions from other potential libraries + if (i.toLowerCase() == "data") { + parObj.movie = attObj[i]; + } + else if (i.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved keyword + att += ' class="' + attObj[i] + '"'; + } + else if (i.toLowerCase() != "classid") { + att += ' ' + i + '="' + attObj[i] + '"'; + } + } + } + var par = ""; + for (var j in parObj) { + if (parObj[j] != Object.prototype[j]) { // filter out prototype additions from other potential libraries + par += ''; + } + } + el.outerHTML = '' + par + ''; + objIdArr[objIdArr.length] = attObj.id; // stored to fix object 'leaks' on unload (dynamic publishing only) + r = getElementById(attObj.id); + } + else { // well-behaving browsers + var o = createElement(OBJECT); + o.setAttribute("type", FLASH_MIME_TYPE); + for (var m in attObj) { + if (attObj[m] != Object.prototype[m]) { // filter out prototype additions from other potential libraries + if (m.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved keyword + o.setAttribute("class", attObj[m]); + } + else if (m.toLowerCase() != "classid") { // filter out IE specific attribute + o.setAttribute(m, attObj[m]); + } + } + } + for (var n in parObj) { + if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") { // filter out prototype additions from other potential libraries and IE specific param element + createObjParam(o, n, parObj[n]); + } + } + el.parentNode.replaceChild(o, el); + r = o; + } + } + return r; + } + + function createObjParam(el, pName, pValue) { + var p = createElement("param"); + p.setAttribute("name", pName); + p.setAttribute("value", pValue); + el.appendChild(p); + } + + /* Cross-browser SWF removal + - Especially needed to safely and completely remove a SWF in Internet Explorer + */ + function removeSWF(id) { + var obj = getElementById(id); + if (obj && obj.nodeName == "OBJECT") { + if (ua.ie && ua.win) { + obj.style.display = "none"; + (function(){ + if (obj.readyState == 4) { + removeObjectInIE(id); + } + else { + setTimeout(arguments.callee, 10); + } + })(); + } + else { + obj.parentNode.removeChild(obj); + } + } + } + + function removeObjectInIE(id) { + var obj = getElementById(id); + if (obj) { + for (var i in obj) { + if (typeof obj[i] == "function") { + obj[i] = null; + } + } + obj.parentNode.removeChild(obj); + } + } + + /* Functions to optimize JavaScript compression + */ + function getElementById(id) { + var el = null; + try { + el = doc.getElementById(id); + } + catch (e) {} + return el; + } + + function createElement(el) { + return doc.createElement(el); + } + + /* Updated attachEvent function for Internet Explorer + - Stores attachEvent information in an Array, so on unload the detachEvent functions can be called to avoid memory leaks + */ + function addListener(target, eventType, fn) { + target.attachEvent(eventType, fn); + listenersArr[listenersArr.length] = [target, eventType, fn]; + } + + /* Flash Player and SWF content version matching + */ + function hasPlayerVersion(rv) { + var pv = ua.pv, v = rv.split("."); + v[0] = parseInt(v[0], 10); + v[1] = parseInt(v[1], 10) || 0; // supports short notation, e.g. "9" instead of "9.0.0" + v[2] = parseInt(v[2], 10) || 0; + return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false; + } + + /* Cross-browser dynamic CSS creation + - Based on Bobby van der Sluis' solution: http://www.bobbyvandersluis.com/articles/dynamicCSS.php + */ + function createCSS(sel, decl, media, newStyle) { + if (ua.ie && ua.mac) { return; } + var h = doc.getElementsByTagName("head")[0]; + if (!h) { return; } // to also support badly authored HTML pages that lack a head element + var m = (media && typeof media == "string") ? media : "screen"; + if (newStyle) { + dynamicStylesheet = null; + dynamicStylesheetMedia = null; + } + if (!dynamicStylesheet || dynamicStylesheetMedia != m) { + // create dynamic stylesheet + get a global reference to it + var s = createElement("style"); + s.setAttribute("type", "text/css"); + s.setAttribute("media", m); + dynamicStylesheet = h.appendChild(s); + if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) { + dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1]; + } + dynamicStylesheetMedia = m; + } + // add style rule + if (ua.ie && ua.win) { + if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) { + dynamicStylesheet.addRule(sel, decl); + } + } + else { + if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) { + dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}")); + } + } + } + + function setVisibility(id, isVisible) { + if (!autoHideShow) { return; } + var v = isVisible ? "visible" : "hidden"; + if (isDomLoaded && getElementById(id)) { + getElementById(id).style.visibility = v; + } + else { + createCSS("#" + id, "visibility:" + v); + } + } + + /* Filter to avoid XSS attacks + */ + function urlEncodeIfNecessary(s) { + var regex = /[\\\"<>\.;]/; + var hasBadChars = regex.exec(s) != null; + return hasBadChars && typeof encodeURIComponent != UNDEF ? encodeURIComponent(s) : s; + } + + /* Release memory to avoid memory leaks caused by closures, fix hanging audio/video threads and force open sockets/NetConnections to disconnect (Internet Explorer only) + */ + var cleanup = function() { + if (ua.ie && ua.win) { + window.attachEvent("onunload", function() { + // remove listeners to avoid memory leaks + var ll = listenersArr.length; + for (var i = 0; i < ll; i++) { + listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]); + } + // cleanup dynamically embedded objects to fix audio/video threads and force open sockets and NetConnections to disconnect + var il = objIdArr.length; + for (var j = 0; j < il; j++) { + removeSWF(objIdArr[j]); + } + // cleanup library's main closures to avoid memory leaks + for (var k in ua) { + ua[k] = null; + } + ua = null; + for (var l in swfobject) { + swfobject[l] = null; + } + swfobject = null; + }); + } + }(); + + return { + /* Public API + - Reference: http://code.google.com/p/swfobject/wiki/documentation + */ + registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) { + if (ua.w3 && objectIdStr && swfVersionStr) { + var regObj = {}; + regObj.id = objectIdStr; + regObj.swfVersion = swfVersionStr; + regObj.expressInstall = xiSwfUrlStr; + regObj.callbackFn = callbackFn; + regObjArr[regObjArr.length] = regObj; + setVisibility(objectIdStr, false); + } + else if (callbackFn) { + callbackFn({success:false, id:objectIdStr}); + } + }, + + getObjectById: function(objectIdStr) { + if (ua.w3) { + return getObjectById(objectIdStr); + } + }, + + embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) { + var callbackObj = {success:false, id:replaceElemIdStr}; + if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) { + setVisibility(replaceElemIdStr, false); + addDomLoadEvent(function() { + widthStr += ""; // auto-convert to string + heightStr += ""; + var att = {}; + if (attObj && typeof attObj === OBJECT) { + for (var i in attObj) { // copy object to avoid the use of references, because web authors often reuse attObj for multiple SWFs + att[i] = attObj[i]; + } + } + att.data = swfUrlStr; + att.width = widthStr; + att.height = heightStr; + var par = {}; + if (parObj && typeof parObj === OBJECT) { + for (var j in parObj) { // copy object to avoid the use of references, because web authors often reuse parObj for multiple SWFs + par[j] = parObj[j]; + } + } + if (flashvarsObj && typeof flashvarsObj === OBJECT) { + for (var k in flashvarsObj) { // copy object to avoid the use of references, because web authors often reuse flashvarsObj for multiple SWFs + if (typeof par.flashvars != UNDEF) { + par.flashvars += "&" + k + "=" + flashvarsObj[k]; + } + else { + par.flashvars = k + "=" + flashvarsObj[k]; + } + } + } + if (hasPlayerVersion(swfVersionStr)) { // create SWF + var obj = createSWF(att, par, replaceElemIdStr); + if (att.id == replaceElemIdStr) { + setVisibility(replaceElemIdStr, true); + } + callbackObj.success = true; + callbackObj.ref = obj; + } + else if (xiSwfUrlStr) { // show Adobe Express Install + if (confirm("Adobe Flash Player "+swfVersionStr+" 이상 버전이 필요합니다.\nCHEditor는 자동으로 Flash Player를 설치하지 않습니다.\n" + + "Adobe Flash Player 다운로드 웹사이트를 방문하시겠습니까?")) { + window.open(xiSwfUrlStr); + } + return; + } + else { // show alternative content + setVisibility(replaceElemIdStr, true); + } + if (callbackFn) { callbackFn(callbackObj); } + }); + } + else if (callbackFn) { callbackFn(callbackObj); } + }, + + switchOffAutoHideShow: function() { + autoHideShow = false; + }, + + ua: ua, + + getFlashPlayerVersion: function() { + return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] }; + }, + + hasFlashPlayerVersion: hasPlayerVersion, + + createSWF: function(attObj, parObj, replaceElemIdStr) { + if (ua.w3) { + return createSWF(attObj, parObj, replaceElemIdStr); + } + else { + return undefined; + } + }, + + showExpressInstall: function(att, par, replaceElemIdStr, callbackFn) { + if (ua.w3 && canExpressInstall()) { + showExpressInstall(att, par, replaceElemIdStr, callbackFn); + } + }, + + removeSWF: function(objElemIdStr) { + if (ua.w3) { + removeSWF(objElemIdStr); + } + }, + + createCSS: function(selStr, declStr, mediaStr, newStyleBoolean) { + if (ua.w3) { + createCSS(selStr, declStr, mediaStr, newStyleBoolean); + } + }, + + addDomLoadEvent: addDomLoadEvent, + + addLoadEvent: addLoadEvent, + + getQueryParamValue: function(param) { + var q = doc.location.search || doc.location.hash; + if (q) { + if (/\?/.test(q)) { q = q.split("?")[1]; } // strip question mark + if (param == null) { + return urlEncodeIfNecessary(q); + } + var pairs = q.split("&"); + for (var i = 0; i < pairs.length; i++) { + if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) { + return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1))); + } + } + } + return ""; + }, + + // For internal usage only + expressInstallCallback: function() { + if (isExpressInstallActive) { + var obj = getElementById(EXPRESS_INSTALL_ID); + if (obj && storedAltContent) { + obj.parentNode.replaceChild(storedAltContent, obj); + if (storedAltContentId) { + setVisibility(storedAltContentId, true); + if (ua.ie && ua.win) { storedAltContent.style.display = "block"; } + } + if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); } + } + isExpressInstallActive = false; + } + } + }; +}(); diff --git a/plugin/editor/cheditor5/popup/js/symbol.js b/plugin/editor/cheditor5/popup/js/symbol.js new file mode 100644 index 000000000..e5e510819 --- /dev/null +++ b/plugin/editor/cheditor5/popup/js/symbol.js @@ -0,0 +1,167 @@ +// ================================================================ +// CHEditor 5 +// ---------------------------------------------------------------- +// Homepage: http://www.chcode.com +// Copyright (c) 1997-2014 CHSOFT +// ================================================================ +var c = null; +var curView = null; +var S1 = '" ( ) [ ] { } ‘ ’ “ ” 〔 〕 〈 〉 《 》 「 」 『 』 【 】 § ※ ☆ ★ ○ ● ■ △ ▲ ▽ ▼ → 〓 ◁ ◀ ▷ ▶ ♤ ♣ ⊙ ◈ ▣ ◐ ◑ ▧ ▦ ▩ ♨ ☏ ☎ ‡ ㉿ ↕ ↗ ↙ ↖ ↘ ㈜ № ㏇ ™ ㏂ + - < = > ± × ÷ ≠ ≤ ≥ ∞ ∴ ♂ ♀ ∠ ⊥ ⌒ ∂ ∇ ≡ ≒ ≪ ≫ √ ∽ ∝ ∵ ∫ ∬ ∈ ∋ ⊆ ⊇ ⊂ ⊃ ∮ ∪ ∩ ∑ ∏ ∧ ∨ ¬ ⇒ ⇔ ∀ ∃'; +var S2 = '─ │ ┌ ┐ ┘ └ ├ ┬ ┤ ┴ ┼ ━ ┃ ┏ ┓ ┛ ┗ ┣ ┳ ┫ ┻ ╋ ┠ ┯ ┨ ┷ ┿ ┝ ┰ ┥ ┸ ╂ ┒ ┑ ┚ ┙ ┖ ┕ ┎ ┍ ┞ ┟ ┡ ┢ ┦ ┧ ┩ ┪ ┭ ┮ ┱ ┲ ┵ ┶ ┹ ┺ ┽ ┾ ╀ ╁ ╃ ╄ ╅ ╆ ╇ ╈ ╉ ╊'; +var S3 = '½ ⅓ ⅔ ¼ ¾ ⅛ ⅜ ⅝ ⅞ ¹ ² ³ ⁴ ⁿ ₁ ₂ ₃ ₄ 0 1 2 3 4 5 6 7 8 9 ⅰ ⅱ ⅲ ⅳ ⅴ ⅵ ⅶ ⅷ ⅸ ⅹ Ⅰ Ⅱ Ⅲ Ⅳ Ⅴ Ⅵ Ⅶ Ⅷ Ⅸ Ⅹ $ % ₩ ° ′ ″ ℃ Å ¢ £ ¥ ¤ ℉ ‰ ㎕ ㎖ ㎗ ℓ ㎘ ㏄ ㎣ ㎤ ㎥ ㎦ ㎙ ㎚ ㎛ ㎜ ㎝ ㎞ ㎟ ㎠ ㎡ ㎢ ㏊ ㎍ ㎎ ㎏ ㏏ ㎈ ㎉ ㏈ ㎧ ㎨ ㎰ ㎱ ㎲ ㎳ ㎴ ㎵ ㎶ ㎷ ㎸ ㎹ ㎀ ㎁ ㎂ ㎃ ㎄ ㎺ ㎻ ㎼ ㎽ ㎾ ㎿ ㎐ ㎑ ㎒ ㎓ ㎔ Ω ㏀ ㏁ ㎊ ㎋ ㎌ ㏖ ㏅ ㎭ ㎮ ㎯ ㏛ ㎩ ㎪ ㎫ ㎬ ㏝ ㏐ ㏓ ㏉ ㏜ ㏆'; +var S4 = 'ㅥ ㅦ ㅧ ㅨ ㅩ ㅪ ㅫ ㅬ ㅭ ㅮ ㅰ ㅯ ㅱ ㅲ ㅳ ㅴ ㅵ ㅶ ㅷ ㅸ ㅹ ㅺ ㅻ ㅼ ㅽ ㅾ ㅿ ㆀ ㆁ ㆂ ㆃ ㆄ ㆅ ㆆ ㆇ ㆈ ㆉ ㆊ ㆋ ㆌ ㆍ ㆎ'; +var S5 = '㉠ ㉡ ㉢ ㉣ ㉤ ㉥ ㉦ ㉧ ㉨ ㉩ ㉪ ㉫ ㉬ ㉭ ㉮ ㉯ ㉰ ㉱ ㉲ ㉳ ㉴ ㉶ ㉶ ㉷ ㉸ ㉹ ㉺ ㉻ ㈀ ㈁ ㈂ ㈃ ㈄ ㈅ ㈆ ㈇ ㈈ ㈉ ㈊ ㈋ ㈌ ㈍ ㈎ ㈏ ㈐ ㈑ ㈒ ㈓ ㈔ ㈕ ㈖ ㈗ ㈘ ㈙ ㈚ ㈛ ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰ ⒱ ⒲ ⒳ ⒴ ⒵ ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ ⒀ ⒁ ⒂'; +var japan1 = 'ぁ か さ た ど び ぽ ょ ゑ あ が ざ だ な ぴ ま よ を ぃ き し ち に ふ み ら ん い ぎ じ ぢ ぬ ぶ む り ぅ く す っ ね ぷ め る う ぐ ず つ の へ も れ ぇ け せ づ は べ ゃ ろ え げ ぜ て ば ぺ や ゎ ぉ こ そ で ぱ ほ ゅ わ お ご ぞ と ひ ぼ ゆ ゐ'; +var japan2 = 'ァ カ サ タ ド ビ ポ ョ ヱ ア ガ ザ ダ ナ ピ マ ヨ ヲ ィ キ シ チ ニ フ ミ ラ ン イ ギ ジ ヂ ヌ ブ ム リ ヴ ゥ ク ス ッ ネ プ メ ル ヵ ウ グ ズ ツ ノ ヘ モ レ ヶ ェ ケ セ ヅ ハ ベ ャ ロ エ ゲ ゼ テ バ ペ ヤ ヮ ォ コ ソ デ パ ホ ュ ワ オ ゴ ゾ ト ヒ ボ ユ ヰ'; + +c = S1.split(' '); +var button = [ { alt : "", img : 'input.gif', cmd : inputChar }, + { alt : "", img : 'cancel.gif', cmd : popupClose } ]; + +var oEditor = null; + +function init(dialog) { + oEditor = this; + oEditor.dialog = dialog; + + var dlg = new Dialog(oEditor); + dlg.showButton(button); + + setupEvent(); + dlg.setDialogHeight(); +} + +function hover(obj, val) { + obj.style.backgroundColor = val ? "#5579aa" : "#fff"; + obj.style.color = val ? "#fff" : "#000"; +} + +function showTable() { + var k = 0; + var len = c.length; + var w = 9; + var h = 20; + var span, i, j, tr, td; + + var table = document.createElement('table'); + table.border = 0; + table.cellSpacing = 1; + table.cellPadding = 0; + table.align = 'center'; + + var getChar = function() { + document.getElementById('fm_input').value = document.getElementById('fm_input').value + c[this.id]; + }; + var mouseOver = function() { + hover(this, true); + }; + var mouseOut = function() { + hover(this, false); + }; + for (i=0; i < w; i++) { + tr = table.insertRow(i); + for (j = 0; j < h; j++) { + td = tr.insertCell(j); + td.className = 'schar'; + + if ( len < k+1) { + td.appendChild(document.createTextNode('\u00a0')); + } + else { + td.style.cursor = 'pointer'; + td.id = k; + td.onclick = getChar; + td.onmouseover = mouseOver; + td.onmouseout = mouseOut; + span = document.createElement("span"); + span.style.fontSize = "13px"; + span.appendChild(document.createTextNode(c[k])); + td.appendChild(span); + } + k++; + } + } + + var output = document.getElementById('output'); + if (output.hasChildNodes()) { + for (i=0; i 0) { + cell = createHeadCell('col'); + } + else { + cell = document.createElement('td'); + } + } + else if (header === 'row' && j === 0) { + cell = createHeadCell('row'); + } + else { + cell = document.createElement('td'); + } + + if (border) { + cell.style.borderStyle = 'solid'; + cell.style.borderWidth = table.style.borderWidth; + cell.style.borderColor = table.style.borderColor; + } +// cell.setAttribute("width", cellWidth); + cell.appendChild(document.createTextNode('\u00a0')); + row.appendChild(cell); + } + } + + if (oHead.hasChildNodes()) { + table.appendChild(oHead); + } + + table.appendChild(oBody); + + if (summaryValue !== '') { + table.setAttribute('summary', summaryValue); + } + if (width) { + table.style.width = width; + } + if (height) { + table.style.height = height; + } + if (align) { + table.setAttribute("align", align); + } + if (bgcolor) { + table.setAttribute("bgcolor", bgcolor); + } + + table.setAttribute("cellpadding", cellpd); + table.setAttribute("cellspacing", cellsp); + + if (captionValue !== '') { + var hideCaption, tableCaption; + tableCaption = table.createCaption(); + tableCaption.appendChild(document.createTextNode(captionValue)); + + hideCaption = document.getElementById('hideCaption'); + if (hideCaption.checked === true) { + tableCaption.style.visibility = 'hidden'; + tableCaption.style.overFlow = 'hidden'; + tableCaption.style.lineHeight = '0px'; + tableCaption.style.position = 'absolute'; + tableCaption.style.display = 'none'; + } + } + + table.id = oEditor.makeRandomString(); + oEditor.insertHtmlPopup(table.cloneNode(true)); + var newTable = oEditor.$(table.id); + newTable.removeAttribute('id'); + + if (cssclass) { + newTable.className = cssclass; + } + if (cssid) { + newTable.id = cssid; + } + + var focusCell = newTable.getElementsByTagName('th')[0]; + if (oEditor.undefined(focusCell)) { + focusCell = newTable.getElementsByTagName('td')[0]; + } + + if (oEditor.getBrowser().msie) { + var cursor = oEditor.doc.body.createTextRange(); + cursor.moveToElementText(focusCell); + cursor.collapse(false); + cursor.select(); + oEditor.backupRange(oEditor.getRange()); + } + else { + var selection = oEditor.getSelection(); + var range = oEditor.getRange(); + range.selectNodeContents(focusCell); + range.collapse(false); + selection.removeAllRanges(); + selection.addRange(range); + } + + oEditor.popupWinClose(); +} + +function init(dialog) { + oEditor = this; + oEditor.dialog = dialog; + + var button = [ { alt : "", img : 'submit.gif', cmd : doSubmit }, + { alt : "", img : 'cancel.gif', cmd : popupClose } ]; + + var dlg = new Dialog(oEditor); + dlg.showButton(button); + dlg.setDialogHeight(); +} diff --git a/plugin/editor/cheditor5/popup/js/table_modify.js b/plugin/editor/cheditor5/popup/js/table_modify.js new file mode 100644 index 000000000..30ff2c575 --- /dev/null +++ b/plugin/editor/cheditor5/popup/js/table_modify.js @@ -0,0 +1,640 @@ +// ================================================================ +// CHEditor 5 +// ---------------------------------------------------------------- +// Homepage: http://www.chcode.com +// Copyright (c) 1997-2014 CHSOFT +// ================================================================ +var oEditor = null; +var button = [ { alt : "", img : 'submit.gif', cmd : doSubmit }, + { alt : "", img : 'cancel.gif', cmd : popupClose } ]; + +var colour = ["ffffcc","ffcc66","ff9900","ffcc99","ff6633","ffcccc","cc9999","ff6699","ff99cc","ff66cc","ffccff","cc99cc","cc66ff","cc99ff","9966cc","ccccff","9999cc","3333ff","6699ff","0066ff","99ccff","66ccff","99cccc","ccffff","99ffcc","66cc99","66ff99","99ff99","ccffcc","33ff33","66ff00","ccff99","99ff00","ccff66","cccc66","ffffff", + "ffff99","ffcc00","ff9933","ff9966","cc3300","ff9999","cc6666","ff3366","ff3399","ff00cc","ff99ff","cc66cc","cc33ff","9933cc","9966ff","9999ff","6666ff","3300ff","3366ff","0066cc","3399ff","33ccff","66cccc","99ffff","66ffcc","33cc99","33ff99","66ff66","99cc99","00ff33","66ff33","99ff66","99ff33","ccff00","cccc33","cccccc", + "ffff66","ffcc33","cc9966","ff6600","ff3300","ff6666","cc3333","ff0066","ff0099","ff33cc","ff66ff","cc00cc","cc00ff","9933ff","6600cc","6633ff","6666cc","3300cc","0000ff","3366cc","0099ff","00ccff","339999","66ffff","33ffcc","00cc99","00ff99","33ff66","66cc66","00ff00","33ff00","66cc00","99cc66","ccff33","999966","999999", + "ffff33","cc9900","cc6600","cc6633","ff0000","ff3333","993333","cc3366","cc0066","cc6699","ff33ff","cc33cc","9900cc","9900ff","6633cc","6600ff","666699","3333cc","0000cc","0033ff","6699cc","3399cc","669999","33ffff","00ffcc","339966","33cc66","00ff66","669966","00cc00","33cc00","66cc33","99cc00","cccc99","999933","666666", + "ffff00","cc9933","996633","993300","cc0000","ff0033","990033","996666","993366","cc0099","ff00ff","990099","996699","660099","663399","330099","333399","000099","0033cc","003399","336699","0099cc","006666","00ffff","33cccc","009966","00cc66","339933","336633","33cc33","339900","669933","99cc33","666633","999900","333333", + "cccc00","996600","663300","660000","990000","cc0033","330000","663333","660033","990066","cc3399","993399","660066","663366","330033","330066","333366","000066","000033","003366","006699","003333","336666","00cccc","009999","006633","009933","006600","003300","00cc33","009900","336600","669900","333300","666600","000000"]; + +var none = '없음'; +var modifyTable; +var beforeHeaderType; +var whichColor = null; + +function popupClose() { + oEditor.popupWinCancel(); +} + +function isError() { + alert('표 정보를 얻을 수 없습니다. 수정하실 표을 다시 한 번 선택해 주십시오.'); + popupClose(); +} + +function init(dialog) { + oEditor = this; + oEditor.dialog = dialog; + + var dlg = new Dialog(oEditor); + dlg.showButton(button); + dlg.setDialogHeight(); + + var rng = oEditor.range, pNode; + + if (oEditor.W3CRange) { + pNode = rng.commonAncestorContainer; + if (!rng.collapsed && + rng.startContainer === rng.endContainer && + rng.startOffset - rng.endOffset < 2 && + rng.startContainer.hasChildNodes()) + { + pNode = rng.startContainer.childNodes[rng.startOffset]; + } + + while (pNode.nodeType === 3) { + pNode = pNode.parentNode; + } + + if (pNode.nodeName !== 'TD' && pNode.nodeName !== 'TH' && pNode.nodeName !== 'CAPTION' && pNode.nodeName !== 'TABLE') + { + isError(); + return; + } + } + else { + if (rng.item) { + pNode = rng.item(0); + if (pNode.nodeName.toLowerCase() !== 'table') { + isError(); + return; + } + } + else { + pNode = rng.parentElement(); + } + } + + while (pNode && pNode.nodeName.toLowerCase() !== 'table') { + pNode = pNode.parentNode; + } + + if (pNode.nodeName.toLowerCase() !== 'table') { + isError(); + return; + } + + modifyTable = pNode; + var border, el_size, fm_size, el_type, fm_type, cellpd, cellsp, bgcolor, idbgcolor, + bordercolor, idbordercolor, captionValue, summaryValue, caption, captionInput, summary; + + border = modifyTable.getAttribute('border'); + if (!border || isNaN(border)) { + border = parseInt(modifyTable.style.borderWidth, 10); + if (!border) { + border = 0; + } + } + document.getElementById("bordersize").value = border; + + if (modifyTable.className !== '') { + document.getElementById('cssClass').value = modifyTable.className; + } + if (modifyTable.id !== '') { + document.getElementById('cssId').value = modifyTable.id; + } + + el_size = modifyTable.getAttribute('width'); + if (!el_size) { + el_size = modifyTable.style.width; + } + + fm_size = document.getElementById("width"); + el_type = 'px'; + fm_type = document.getElementById("widthtype"); + + if (el_size) { + el_type = (/%$/.test(el_size)) ? '%' : 'px'; + el_size = parseInt(el_size, 10); + if (isNaN(el_size)) { + el_size = ''; + } + } + else { + el_size = ''; + } + + fm_size.value = el_size; + fm_type.value = el_type; + + el_size = modifyTable.getAttribute('height'); + if (!el_size) { + el_size = modifyTable.style.height; + } + fm_size = document.getElementById("height"); + el_type = 'px'; + fm_type = document.getElementById("heighttype"); + + if (el_size) { + el_type = (/\%$/.test(el_size)) ? '%' : 'px'; + el_size = parseInt(el_size, 10); + if (isNaN(el_size)) { + el_size = ''; + } + } + else { + el_size = ''; + } + + fm_size.value = el_size; + fm_type.value = el_type; + + fm_type = modifyTable.getAttribute('align'); + if (!fm_type) { + fm_type = 'none'; + } + document.getElementById("talign").value = fm_type; + + cellpd = modifyTable.getAttribute('cellpadding'); + if (isNaN(cellpd)) { + cellpd = 0; + } + document.getElementById("cellpd").value = cellpd || 0; + + cellsp = modifyTable.getAttribute('cellspacing'); + if (isNaN(cellsp)) { + cellsp = 0; + } + document.getElementById("cellsp").value = cellsp || 0; + + bgcolor = modifyTable.getAttribute('bgcolor'); + idbgcolor = document.getElementById("idbgcolor"); + if (bgcolor) { + if (/rgb/.test(bgcolor)) { + bgcolor = oEditor.colorConvert(bgcolor, 'hex'); + } + idbgcolor.value = bgcolor.toLowerCase(); + idbgcolor.style.backgroundColor = idbgcolor.value; + } + else { + idbgcolor.value = none; + } + + bordercolor = modifyTable.getAttribute('bordercolor'); + if (!bordercolor) { + bordercolor = modifyTable.style.borderColor; + if (bordercolor) { + bordercolor = oEditor.colorConvert(bordercolor, 'hex'); + } + else { + bordercolor = null; + } + } + + idbordercolor = document.getElementById("idbordercolor"); + if (bordercolor) { + if (/rgb/.test(bordercolor)) { + bordercolor = oEditor.colorConvert(bordercolor, 'hex'); + } + idbordercolor.value = bordercolor.toLowerCase(); + idbordercolor.style.backgroundColor = idbordercolor.value; + } + else { + idbordercolor.value = none; + } + + caption = modifyTable.getElementsByTagName('caption')[0]; + if (caption) { + captionValue = oEditor.trimSpace(caption.innerHTML); + if (captionValue !== '') { + captionInput = document.getElementById('tableCaption'); + captionInput.value = captionValue; + + if (caption.style.visibility === 'hidden') { + document.getElementById('hideCaption').checked = 'checked'; + } + } + } + + summaryValue = modifyTable.getAttribute('summary'); + if (summaryValue) { + summaryValue = oEditor.trimSpace(summaryValue); + if (summaryValue !== '') { + summary = document.getElementById('tableSummary'); + summary.value = summaryValue; + } + } + + var tableHeader, rows, i, j, cells, headCol, headRow, rowLength, rowCellLength, cellLength, header, headTagName; + headCol = headRow = null; + headTagName = 'th'; + + tableHeader = document.getElementById('tableHeader'); + rows = (modifyTable.rows && modifyTable.rows.length > 0) ? modifyTable.rows : modifyTable.getElementsByTagName('tr'); + rowLength = rows.length; + + document.getElementById('numrows').appendChild(document.createTextNode(rowLength)); + + if (rowLength > 0) { + cells = rows[0].cells; + cellLength = cells.length; + if (cellLength > 0) { + for (j=0; j < cellLength; j++) { + if (cells[j].tagName.toLowerCase() === headTagName) { + headCol = 'col'; + } + else { + headCol = null; + break; + } + } + } + + rowCellLength = 0; + for (i=0; i < rowLength; i++) { + headRow = (rows[i].cells[0] && rows[i].cells[0].tagName.toLowerCase() === headTagName) ? 'row' : null; + if (rowCellLength < rows[i].cells.length) { + rowCellLength = rows[i].cells.length; + } + } + + if (headRow && headCol && cellLength === 1) { + headCol = null; + } + document.getElementById('numcols').appendChild(document.createTextNode(rowCellLength)); + } + + header = (headCol && headRow) ? 'all' : headCol || headRow || 'none'; + tableHeader.value = beforeHeaderType = header; +} + +function getColor() +{ + var color = this.bgColor; + var input = document.getElementById("id"+whichColor); + input.style.backgroundColor = input.value = color; +} + +function drawColor() { + var table, tr, td, insideTable, k = 0, i, j, tr2, td2; + + table = document.createElement('table'); + table.cellPadding = 0; + table.cellSpacing = 0; + table.border = 0; + table.align = 'center'; + tr = table.insertRow(0); + td = tr.insertCell(0); + td.style.backgroundColor = '#fff'; + + insideTable = document.createElement('table'); + insideTable.border = 0; + insideTable.cellSpacing = 1; + insideTable.cellPadding = 0; + insideTable.align = 'center'; + + var onMouseOver = function() { this.className = 'colorCellMouseOver'; }; + var onMouseOut = function() { this.className = 'colorCellMouseOut'; }; + + for (i = 0; i < 6; i++) { + tr2 = insideTable.insertRow(i); + for (j = 0; j < 36; j++) { + td2 = tr2.insertCell(j); + td2.setAttribute('bgColor', '#' + colour[k]); + td2.className = 'colorCellMouseOut'; + td2.onclick = getColor; + td2.appendChild(document.createTextNode('\u00a0')); + td2.onmouseover = onMouseOver; + td2.onmouseout = onMouseOut; + k++; + } + } + + td.appendChild(insideTable); + document.getElementById('colorWrapper').appendChild(table); +} + +function setColor(which) { + whichColor = which; +} + +function doSubmit() +{ + var width, widthType, widthValue, cellWidth, i, j, row, rows, cell; + width = document.getElementById("width"); + widthType = document.getElementById("widthtype").value; + if (width) { + widthValue = parseInt(oEditor.trimSpace(width.value), 10); + if (isNaN(widthValue)) { + cellWidth = widthValue = null; + } + else { + modifyTable.removeAttribute('width'); + modifyTable.style.width = widthValue + widthType; + rows = modifyTable.rows; + if (rows.length > 0) { + for (i=0; i < rows.length; i++) { + row = rows[i]; + for (j=0; j < row.cells.length; j++) { + cellWidth = parseInt(widthValue/row.cells.length, 10) + widthType; + cell = row.cells[j]; + cell.setAttribute("width", cellWidth); + } + } + } + } + } + + var height, heightValue; + height = document.getElementById("height"); + if (height) { + heightValue = parseInt(oEditor.trimSpace(height.value), 10); + if (isNaN(heightValue)) { + heightValue = null; + } + else { + heightValue += document.getElementById("heighttype").value; + modifyTable.removeAttribute('height'); + modifyTable.style.height = heightValue; + } + } + + var cellpadding, cellpaddingValue; + cellpadding = document.getElementById("cellpd"); + if (cellpadding) { + cellpaddingValue = oEditor.trimSpace(cellpadding.value); + if (!cellpaddingValue || isNaN(cellpaddingValue)) { + cellpaddingValue = 0; + } + else { + cellpaddingValue = parseInt(cellpaddingValue, 10); + } + modifyTable.setAttribute('cellpadding', cellpaddingValue); + } + + var cellspacing, cellspacingValue; + cellspacing = document.getElementById("cellsp"); + if (cellspacing) { + cellspacingValue = oEditor.trimSpace(cellspacing.value); + if (!cellspacingValue || isNaN(cellspacingValue)) { + cellspacingValue = 0; + } + else { + cellspacingValue = parseInt(cellspacingValue, 10); + } + modifyTable.setAttribute('cellspacing', cellspacingValue); + } + + var bgcolor, bgcolorValue; + bgcolor = document.getElementById("idbgcolor"); + if (bgcolor) { + bgcolorValue = oEditor.trimSpace(bgcolor.value); + if (bgcolorValue !== '' && bgcolorValue !== none) { + modifyTable.removeAttribute('bgcolor'); + modifyTable.bgColor = bgcolorValue; + } + } + + var align, alignValue; + align = document.getElementById("talign"); + if (align) { + alignValue = align.value; + if (alignValue !== 'none') { + modifyTable.removeAttribute('align'); + modifyTable.setAttribute('align', alignValue); + } + } + + var cssclass, cssclassValue, cssid, cssidValue; + cssclass = document.getElementById('cssClass'); + cssclassValue = oEditor.trimSpace(cssclass.value); + if (cssclassValue !== '') { + modifyTable.className = cssclassValue; + } + else { + modifyTable.removeAttribute('class'); + } + + cssid = document.getElementById('cssId'); + cssidValue = oEditor.trimSpace(cssid.value); + if (cssidValue !== '') { + modifyTable.id = cssidValue; + } + else { + modifyTable.removeAttribute('id'); + } + + var caption = document.getElementById('tableCaption'); + var captionValue = oEditor.trimSpace(caption.value); + var summary = document.getElementById('tableSummary'); + var summaryValue = oEditor.trimSpace(summary.value); + var oCaption; + + if (summaryValue !== '') { + modifyTable.setAttribute('summary', summaryValue); + } + if (captionValue !== '') { + var hideCaption, tableCaption; + tableCaption = modifyTable.createCaption(); + tableCaption.innerHTML = captionValue; + + hideCaption = document.getElementById('hideCaption'); + if (hideCaption.checked === true) { + tableCaption.style.visibility = 'hidden'; + tableCaption.style.overFlow = 'hidden'; + tableCaption.style.lineHeight = '0px'; + tableCaption.style.position = 'absolute'; + tableCaption.style.display = 'none'; + } + else { + tableCaption.removeAttribute('style'); + } + } + else { + oCaption = modifyTable.getElementsByTagName('caption')[0]; + if (oCaption) { + modifyTable.removeChild(oCaption); + } + } + + var copyAttribute = function(target, source) { + var attr, attrValue, nodeName; + attr = source.attributes; + for (i=0; i= 0; j--) { + row.deleteCell(j); + } + + for (j=0; j < newCells.length; j++) { + row.appendChild(newCells[j]); + } + + if (newTagName === 'th') { + oHead = modifyTable.getElementsByTagName('thead')[0]; + if (!oHead) { + oHead = document.createElement('thead'); + modifyTable.insertBefore(oHead, modifyTable.firstChild); + oHead.appendChild(row); + } + } + else if (row.parentNode.nodeName.toLowerCase() === 'thead') { + oHead = row.parentNode; + if (rows[1]) { + rows[1].parentNode.insertBefore(row, rows[1]); + } + else { + modifyTable.insertBefore(row, oHead); + } + modifyTable.removeChild(oHead); + } + }; + + var replaceRow = function (rows, newTagName) { + var len, newCell, sourceCell; + len = rows.length; + for (i=0; i < len; i++) { + row = rows[i]; + sourceCell = row.cells[0]; + newCell = document.createElement(newTagName); + + if (newTagName === 'th') { + newCell.setAttribute('scope', 'row'); + } + else { + sourceCell.removeAttribute('scope'); + } + + row.insertBefore(newCell, sourceCell); + copyAttribute(newCell, sourceCell); + copyChildNodes(newCell, sourceCell); + row.deleteCell(1); + } + }; + + var border, borderValue; + if (beforeHeaderType !== tableHeader) { + rows = (modifyTable.rows && modifyTable.rows.length > 0) ? + modifyTable.rows : + modifyTable.getElementsByTagName('tr'); + + if (tableHeader === 'col') { + replaceRow(rows, 'td'); + replaceCol(rows, 'th'); + } + else if (tableHeader === 'row') { + replaceCol(rows, 'td'); + replaceRow(rows, 'th'); + } + else if (tableHeader === 'all') { + replaceCol(rows, 'th'); + replaceRow(rows, 'th'); + } + else if (tableHeader === 'none') { + replaceCol(rows, 'td'); + replaceRow(rows, 'td'); + } + + oCaption = modifyTable.getElementsByTagName('caption')[0]; + if (oCaption && oCaption !== modifyTable.firstChild) { + modifyTable.insertBefore(oCaption, modifyTable.firstChild); + } + } + + + border = document.getElementById("bordersize"); + if (border) { + borderValue = oEditor.trimSpace(border.value); + if (isNaN(borderValue) === false) { + var borderColor, borderColorValue; + borderValue = parseInt(borderValue, 10); + rows = (modifyTable.rows && modifyTable.rows.length > 0) ? + modifyTable.rows : + modifyTable.getElementsByTagName('tr'); + + if (borderValue) { + borderColor = document.getElementById("idbordercolor"); + if (borderColor) { + borderColorValue = oEditor.trimSpace(borderColor.value); + } + if (!borderColorValue || borderColorValue === none) { + borderColorValue = '#000000'; + } + + borderColorValue = oEditor.colorConvert(borderColorValue, 'rgb'); + + modifyTable.style.border = borderValue + 'px solid ' + borderColorValue; + modifyTable.style.borderCollapse = "collapse"; + modifyTable.removeAttribute('border'); + + for (i=0; i < rows.length; i++) { + row = rows[i]; + for (j=0; j < row.cells.length; j++) { + cell = row.cells[j]; + cell.style.border = borderValue + 'px solid ' + borderColorValue; + } + } + } + else if (borderValue === 0) { + modifyTable.removeAttribute('border'); + modifyTable.style.border = ''; + modifyTable.style.borderCollapse = ''; + for (i=0; i < rows.length; i++) { + row = rows[i]; + for (j=0; j < row.cells.length; j++) { + cell = row.cells[j]; + cell.style.border = ''; + } + } + } + } + } + + oEditor.editArea.focus(); + oEditor.backupRange(oEditor.restoreRange()); + oEditor.clearStoredSelections(); + oEditor.popupWinClose(); +} \ No newline at end of file diff --git a/plugin/editor/cheditor5/popup/link.html b/plugin/editor/cheditor5/popup/link.html new file mode 100644 index 000000000..62b45d6b0 --- /dev/null +++ b/plugin/editor/cheditor5/popup/link.html @@ -0,0 +1,70 @@ + + + + CHEditor + + + + + + + +
+
+ + + + + +
+ + + + + + + + + + + + + + + +
유형: + + + 타겟: + + +
URL: + + +
타이틀: + + +
+
+
+
+
+ + diff --git a/plugin/editor/cheditor5/popup/media.html b/plugin/editor/cheditor5/popup/media.html new file mode 100644 index 000000000..a2addd74b --- /dev/null +++ b/plugin/editor/cheditor5/popup/media.html @@ -0,0 +1,40 @@ + + + + CHEditor + + + + + + + +
+
미디어 재생 + + + + +
+
+
+
+
+
미디어 파일 URL + + + + + + + +
+ URL 입력: +
+ +
+
+
+
+ + diff --git a/plugin/editor/cheditor5/popup/symbol.html b/plugin/editor/cheditor5/popup/symbol.html new file mode 100644 index 000000000..039564fe9 --- /dev/null +++ b/plugin/editor/cheditor5/popup/symbol.html @@ -0,0 +1,26 @@ + + + + CHEditor + + + + + + + + | + | + | + | + | + +
+ +
+
+ 선택한 문자: +
+
+ + diff --git a/plugin/editor/cheditor5/popup/table.html b/plugin/editor/cheditor5/popup/table.html new file mode 100644 index 000000000..a35b2584a --- /dev/null +++ b/plugin/editor/cheditor5/popup/table.html @@ -0,0 +1,178 @@ + + + + CHEditor + + + + + + + +
표 속성 +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
줄 수: + + 칸 수: + +

너비: + + + + 높이: + + + +
셀 안 여백: + + 셀 간격: + +
테두리 굵기: +  픽셀 + 정렬: + +

표 제목: + + 표 제목 숨김: +
표 요약: + + 표 헤더: + +

CSS class: + + CSS id: + +
+
+
+
+
색 지정 +
+ + + + + + + +
테두리 색: + +
+ +
+
 
+
표 배경색: + +
+ +
+
 
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/plugin/editor/cheditor5/popup/table_modify.html b/plugin/editor/cheditor5/popup/table_modify.html new file mode 100644 index 000000000..4a84260f2 --- /dev/null +++ b/plugin/editor/cheditor5/popup/table_modify.html @@ -0,0 +1,180 @@ + + + + CHEditor + + + + + + + +
표 속성 +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
줄 수: + + 칸 수: + +

너비: + + + + 높이: + + + +
셀 안 여백: + + 셀 간격: + +
테두리 굵기: + + 정렬: + +

표 제목: + + 표 제목 숨김: + +
표 요약: + + 표 헤더: + +

CSS class: + + CSS id: + +
+
+
+
+
색 지정 +
+ + + + + + + +
테두리 색: + +
+ +
+
 
+
표 배경색: + +
+ +
+
 
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/plugin/editor/cheditor5/template.xml b/plugin/editor/cheditor5/template.xml new file mode 100644 index 000000000..8aef7b6f0 --- /dev/null +++ b/plugin/editor/cheditor5/template.xml @@ -0,0 +1,368 @@ + + + \ No newline at end of file diff --git a/plugin/editor/cheditor5/utils/crossdomain.xml b/plugin/editor/cheditor5/utils/crossdomain.xml new file mode 100644 index 000000000..786354ea5 --- /dev/null +++ b/plugin/editor/cheditor5/utils/crossdomain.xml @@ -0,0 +1,6 @@ + + + + + +