diff --git a/modules/editor/components/code_highlighter/code.png b/modules/editor/components/code_highlighter/code.png new file mode 100755 index 000000000..b2b401363 Binary files /dev/null and b/modules/editor/components/code_highlighter/code.png differ diff --git a/modules/editor/components/code_highlighter/code_highlighter.class.php b/modules/editor/components/code_highlighter/code_highlighter.class.php new file mode 100755 index 000000000..704713c10 --- /dev/null +++ b/modules/editor/components/code_highlighter/code_highlighter.class.php @@ -0,0 +1,66 @@ + + * @brief Code Highlighter + **/ + +class code_highlighter extends EditorHandler { + + // editor_sequence 는 에디터에서 필수로 달고 다녀야 함 + var $editor_sequence = 0; + var $component_path = ''; + + /** + * @brief editor_sequence과 컴포넌트의 경로를 받음 + **/ + function code_highlighter($editor_sequence, $component_path) { + $this->editor_sequence = $editor_sequence; + $this->component_path = $component_path; + } + + /** + * @brief popup window요청시 popup window에 출력할 내용을 추가하면 된다 + **/ + function getPopupContent() { + // 템플릿을 미리 컴파일해서 컴파일된 소스를 return + $tpl_path = $this->component_path.'tpl'; + $tpl_file = 'popup.html'; + + Context::set("tpl_path", $tpl_path); + + $oTemplate = &TemplateHandler::getInstance(); + return $oTemplate->compile($tpl_path, $tpl_file); + } + + /** + * @brief 에디터 컴포넌트가 별도의 고유 코드를 이용한다면 그 코드를 html로 변경하여 주는 method + * + * 이미지나 멀티미디어, 설문등 고유 코드가 필요한 에디터 컴포넌트는 고유코드를 내용에 추가하고 나서 + * DocumentModule::transContent() 에서 해당 컴포넌트의 transHtml() method를 호출하여 고유코드를 html로 변경 + **/ + function transHTML($xml_obj) { + $code_type = $xml_obj->attrs->code_type; + $body = $xml_obj->body; + $body = preg_replace('@@Ui' , "\r\n", $body); + $body = preg_replace('@@Ui' , "", $body); + + if(!$GLOBALS['_called_code_highlighter_']) { + $GLOBALS['_called_code_highlighter_'] = true; + $js_code = <<dp.SyntaxHighlighter.HighlightAll('CodeHighLighterArea'); +EndOfCss; + + Context::addHtmlFooter($js_code); + } + + Context::addCSSFile($this->component_path.'css/SyntaxHighlighter.css'); + + Context::addJsFile($this->component_path.'script/shCore.js'); + Context::addJsFile($this->component_path.'script/shBrush'.$code_type.'.js'); + + $output = sprintf('', $code_type, $body); + return $output; + } +} +?> diff --git a/modules/editor/components/code_highlighter/css/SyntaxHighlighter.css b/modules/editor/components/code_highlighter/css/SyntaxHighlighter.css new file mode 100755 index 000000000..d26efbf6b --- /dev/null +++ b/modules/editor/components/code_highlighter/css/SyntaxHighlighter.css @@ -0,0 +1,223 @@ +/* Main style for the table */ + +.dp-highlighter +{ + font-family: "Courier New" , Courier, mono; + font-size: 12px; + border: 1px solid #eee; + background-color: #fff; + width: 99%; + overflow: auto; + margin: 18px 0px 18px 0px; +} + +.dp-highlighter .bar +{ + padding-left: 45px; +} + +.dp-highlighter.collapsed .bar, .dp-highlighter.nogutter .bar +{ + padding-left: 0px; +} + +.dp-highlighter ol +{ + margin: 0px 0px 1px 45px; /* 1px bottom margin seems to fix occasional Firefox scrolling */ + padding: 0px; + color: #666; +} + +.dp-highlighter.nogutter ol +{ + list-style-type: none; + margin-left: 0px; +} + +.dp-highlighter ol li, .dp-highlighter .columns div +{ + border-left: 1px solid #999; + background-color: #fff; + padding-left: 10px; + line-height: 14px; +} + +.dp-highlighter.nogutter ol li, .dp-highlighter.nogutter .columns div +{ + border: 0; +} + +.dp-highlighter .columns +{ + color: gray; + overflow: hidden; + width: 100%; +} + +.dp-highlighter .columns div +{ + padding-bottom: 5px; +} + +.dp-highlighter ol li.alt +{ + background-color: #f8f8f8; +} + +.dp-highlighter ol li span +{ + color: Black; +} + +/* Adjust some properties when collapsed */ + +.dp-highlighter.collapsed ol +{ + margin: 0px; +} + +.dp-highlighter.collapsed ol li +{ + display: none; +} + +/* Additional modifications when in print-view */ + +.dp-highlighter.printing +{ + border: none; +} + +.dp-highlighter.printing .tools +{ + display: none !important; +} + +.dp-highlighter.printing li +{ + display: list-item !important; +} + +/* Styles for the tools */ + +.dp-highlighter .tools +{ + padding: 3px 8px 3px 10px; + border-bottom: 1px solid #999; + font: 9px Verdana, Geneva, Arial, Helvetica, sans-serif; + color: silver; +} + +.dp-highlighter.collapsed .tools +{ + border-bottom: 0; +} + +.dp-highlighter .tools a +{ + font-size: 9px; + color: gray; + text-decoration: none; + margin-right: 10px; +} + +.dp-highlighter .tools a:hover +{ + color: red; + text-decoration: underline; +} + +/* About dialog styles */ + +.dp-about { background-color: #fff; margin: 0px; padding: 0px; } +.dp-about table { width: 100%; height: 100%; font-size: 11px; font-family: Tahoma, Verdana, Arial, sans-serif !important; } +.dp-about td { padding: 10px; vertical-align: top; } +.dp-about .dp-copy { border-bottom: 1px solid #ACA899; height: 95%; } +.dp-about .dp-title { color: red; font-weight: bold; } +.dp-about .dp-para { margin: 0 0 4px 0; } +.dp-about .dp-footer { background-color: #ECEADB; border-top: 1px solid #fff; text-align: right; } +.dp-about .dp-close { font-size: 11px; font-family: Tahoma, Verdana, Arial, sans-serif !important; background-color: #ECEADB; width: 60px; height: 22px; } + +/* Language specific styles */ + +.dp-c {} +.dp-c .dp-comment { color: green; } +.dp-c .dp-string { color: blue; } +.dp-c .dp-preprocessor { color: gray; } +.dp-c .dp-keyword { color: blue; } +.dp-c .dp-vars { color: #d00; } + +.dp-vb {} +.dp-vb .dp-comment { color: green; } +.dp-vb .dp-string { color: blue; } +.dp-vb .dp-preprocessor { color: gray; } +.dp-vb .dp-keyword { color: blue; } + +.dp-sql {} +.dp-sql .dp-comment { color: green; } +.dp-sql .dp-string { color: red; } +.dp-sql .dp-keyword { color: blue; } +.dp-sql .dp-func { color: #ff1493; } +.dp-sql .dp-op { color: #808080; } + +.dp-xml {} +.dp-xml .dp-cdata { color: #ff1493; } +.dp-xml .dp-comments { color: green; } +.dp-xml .dp-tag { font-weight: bold; color: blue; } +.dp-xml .dp-tag-name { color: black; font-weight: bold; } +.dp-xml .dp-attribute { color: red; } +.dp-xml .dp-attribute-value { color: blue; } + +.dp-delphi {} +.dp-delphi .dp-comment { color: #008200; font-style: italic; } +.dp-delphi .dp-string { color: blue; } +.dp-delphi .dp-number { color: blue; } +.dp-delphi .dp-directive { color: #008284; } +.dp-delphi .dp-keyword { font-weight: bold; color: navy; } +.dp-delphi .dp-vars { color: #000; } + +.dp-py {} +.dp-py .dp-comment { color: green; } +.dp-py .dp-string { color: red; } +.dp-py .dp-docstring { color: green; } +.dp-py .dp-keyword { color: blue; font-weight: bold;} +.dp-py .dp-builtins { color: #ff1493; } +.dp-py .dp-magicmethods { color: #808080; } +.dp-py .dp-exceptions { color: brown; } +.dp-py .dp-types { color: brown; font-style: italic; } +.dp-py .dp-commonlibs { color: #8A2BE2; font-style: italic; } + +.dp-rb {} +.dp-rb .dp-comment { color: #c00; } +.dp-rb .dp-string { color: #f0c; } +.dp-rb .dp-symbol { color: #02b902; } +.dp-rb .dp-keyword { color: #069; } +.dp-rb .dp-variable { color: #6cf; } + +.dp-css {} +.dp-css .dp-comment { color: green; } +.dp-css .dp-string { color: red; } +.dp-css .dp-keyword { color: blue; } +.dp-css .dp-colors { color: darkred; } +.dp-css .dp-vars { color: #d00; } + +.dp-j {} +.dp-j .dp-comment { color: rgb(63,127,95); } +.dp-j .dp-string { color: rgb(42,0,255); } +.dp-j .dp-keyword { color: rgb(127,0,85); font-weight: bold } +.dp-j .dp-annotation { color: #646464; } +.dp-j .dp-number { color: #C00000; } + +.dp-cpp {} +.dp-cpp .dp-comment { color: #e00; } +.dp-cpp .dp-string { color: red; } +.dp-cpp .dp-preprocessor { color: #CD00CD; font-weight: bold; } +.dp-cpp .dp-keyword { color: #5697D9; font-weight: bold; } +.dp-cpp .dp-datatypes { color: #2E8B57; font-weight: bold; } + +.dp-php { color: #800000; } +.dp-php .dp-comment { color: #008000; } +.dp-php .dp-keyword { color: #4B00FB; } +.dp-php .dp-string { color: #FB00FB; } +.dp-php .dp-func { color: #FF0000; } +.dp-php .dp-vars { color: #008080; } \ No newline at end of file diff --git a/modules/editor/components/code_highlighter/icon.gif b/modules/editor/components/code_highlighter/icon.gif new file mode 100755 index 000000000..4b542c04e Binary files /dev/null and b/modules/editor/components/code_highlighter/icon.gif differ diff --git a/modules/editor/components/code_highlighter/info.xml b/modules/editor/components/code_highlighter/info.xml new file mode 100755 index 000000000..80840727e --- /dev/null +++ b/modules/editor/components/code_highlighter/info.xml @@ -0,0 +1,8 @@ + + + Code Highlighter + + BNU + 코드를 보기 좋게 출력합니다. + + \ No newline at end of file diff --git a/modules/editor/components/code_highlighter/lang/ko.lang.php b/modules/editor/components/code_highlighter/lang/ko.lang.php new file mode 100755 index 000000000..781b18280 --- /dev/null +++ b/modules/editor/components/code_highlighter/lang/ko.lang.php @@ -0,0 +1,8 @@ + + * @brief 위지윅에디터(editor) 모듈 > 인용구 (quotation) 컴포넌트의 언어팩 + **/ + $lang->code_type = '언어 종류'; +?> diff --git a/modules/editor/components/code_highlighter/script/shBrushCSharp.js b/modules/editor/components/code_highlighter/script/shBrushCSharp.js new file mode 100755 index 000000000..1d12b78d6 --- /dev/null +++ b/modules/editor/components/code_highlighter/script/shBrushCSharp.js @@ -0,0 +1,31 @@ +dp.sh.Brushes.CSharp = function() +{ + var keywords = 'abstract as base bool break byte case catch char checked class const ' + + 'continue decimal default delegate do double else enum event explicit ' + + 'extern false finally fixed float for foreach get goto if implicit in int ' + + 'interface internal is lock long namespace new null object operator out ' + + 'override params private protected public readonly ref return sbyte sealed set ' + + 'short sizeof stackalloc static string struct switch this throw true try ' + + 'typeof uint ulong unchecked unsafe ushort using virtual void while'; + + this.regexList = [ + // There's a slight problem with matching single line comments and figuring out + // a difference between // and ///. Using lookahead and lookbehind solves the + // problem, unfortunately JavaScript doesn't support lookbehind. So I'm at a + // loss how to translate that regular expression to JavaScript compatible one. +// { regex: new RegExp('(?) + | () + | (<)*(\w+)*\s*(\w+)\s*=\s*(".*?"|'.*?'|\w+)(/*>)* + | () + */ + var index = 0; + var match = null; + var regex = null; + + // Match CDATA in the following format + // <\!\[[\w\s]*?\[(.|\s)*?\]\]> + this.GetMatches(new RegExp('<\\!\\[[\\w\\s]*?\\[(.|\\s)*?\\]\\]>', 'gm'), 'dp-cdata'); + + // Match comments + // + this.GetMatches(new RegExp('', 'gm'), 'dp-comments'); + + // Match attributes and their values + // (:|\w+)\s*=\s*(".*?"|\'.*?\'|\w+)* + regex = new RegExp('([:\\w-\.]+)\\s*=\\s*(".*?"|\'.*?\'|\\w+)*', 'gm'); // Thanks to Tomi Blinnikka of Yahoo! for fixing namespaces in attributes + while((match = regex.exec(this.code)) != null) + { + push(this.matches, new dp.sh.Match(match[1], match.index, 'dp-attribute')); + + // if xml is invalid and attribute has no property value, ignore it + if(match[2] != undefined) + { + push(this.matches, new dp.sh.Match(match[2], match.index + match[0].indexOf(match[2]), 'dp-attribute-value')); + } + } + + // Match opening and closing tag brackets + // + this.GetMatches(new RegExp('', 'gm'), 'dp-tag'); + + // Match tag names + // About...

dp.SyntaxHighlighter

Version: {V}

http://www.dreamprojections.com/SyntaxHighlighter

©2004-2005 Alex Gorbatchev. All right reserved.
"};dp.SyntaxHighlighter=dp.sh;dp.sh.Toolbar.Commands={ExpandSource:{label:"+ expand source",check:function(_1){return _1.collapse;},func:function(_2,_3){_2.parentNode.removeChild(_2);_3.div.className=_3.div.className.replace("collapsed","");}},ViewSource:{label:"view plain",func:function(_4,_5){var _6=_5.originalCode.replace(/"+_6+"");_7.document.close();}},CopyToClipboard:{label:"copy to clipboard",check:function(){return window.clipboardData!=null;},func:function(_8,_9){window.clipboardData.setData("text",_9.originalCode);alert("The code is in your clipboard now");}},PrintSource:{label:"print",func:function(_a,_b){var _c=document.createElement("IFRAME");var _d=null;_c.style.cssText="position:absolute;width:0px;height:0px;left:-500px;top:-500px;";document.body.appendChild(_c);_d=_c.contentWindow.document;dp.sh.Utils.CopyStyles(_d,window.document);_d.write("
"+_b.div.innerHTML+"
");_d.close();_c.contentWindow.focus();_c.contentWindow.print();document.body.removeChild(_c);}},About:{label:"?",func:function(_e){var _f=window.open("","_blank","dialog,width=300,height=150,scrollbars=0");var doc=_f.document;dp.sh.Utils.CopyStyles(doc,window.document);doc.write(dp.sh.Strings.AboutDialog.replace("{V}",dp.sh.Version));doc.close();_f.focus();}}};dp.sh.Toolbar.Create=function(_11){var div=document.createElement("DIV");div.className="tools";for(var _13 in dp.sh.Toolbar.Commands){var cmd=dp.sh.Toolbar.Commands[_13];if(cmd.check!=null&&!cmd.check(_11)){continue;}div.innerHTML+=""+cmd.label+"";}return div;};dp.sh.Toolbar.Command=function(_15,_16){var n=_16;while(n!=null&&n.className.indexOf("dp-highlighter")==-1){n=n.parentNode;}if(n!=null){dp.sh.Toolbar.Commands[_15].func(_16,n.highlighter);}};dp.sh.Utils.CopyStyles=function(_18,_19){var _1a=_19.getElementsByTagName("link");for(var i=0;i<_1a.length;i++){if(_1a[i].rel.toLowerCase()=="stylesheet"){_18.write("");}}};dp.sh.RegexLib={MultiLineCComments:new RegExp("/\\*[\\s\\S]*?\\*/","gm"),SingleLineCComments:new RegExp("//.*$","gm"),SingleLinePerlComments:new RegExp("#.*$","gm"),DoubleQuotedString:new RegExp("\"(?:\\.|(\\\\\\\")|[^\\\"\"])*\"","g"),SingleQuotedString:new RegExp("'(?:\\.|(\\\\\\')|[^\\''])*'","g")};dp.sh.Match=function(_1c,_1d,css){this.value=_1c;this.index=_1d;this.length=_1c.length;this.css=css;};dp.sh.Highlighter=function(){this.noGutter=false;this.addControls=true;this.collapse=false;this.tabsToSpaces=true;this.wrapColumn=80;this.showColumns=true;};dp.sh.Highlighter.SortCallback=function(m1,m2){if(m1.indexm2.index){return 1;}else{if(m1.lengthm2.length){return 1;}}}}return 0;};dp.sh.Highlighter.prototype.CreateElement=function(_21){var _22=document.createElement(_21);_22.highlighter=this;return _22;};dp.sh.Highlighter.prototype.GetMatches=function(_23,css){var _25=0;var _26=null;while((_26=_23.exec(this.code))!=null){this.matches[this.matches.length]=new dp.sh.Match(_26[0],_26.index,css);}};dp.sh.Highlighter.prototype.AddBit=function(str,css){if(str==null||str.length==0){return;}var _29=this.CreateElement("SPAN");str=str.replace(/&/g,"&");str=str.replace(/ /g," ");str=str.replace(/");if(css!=null){var _2a=new RegExp("
","gi");if(_2a.test(str)){var _2b=str.split(" 
");str="";for(var i=0;i<_2b.length;i++){_29=this.CreateElement("SPAN");_29.className=css;_29.innerHTML=_2b[i];this.div.appendChild(_29);if(i+1<_2b.length){this.div.appendChild(this.CreateElement("BR"));}}}else{_29.className=css;_29.innerHTML=str;this.div.appendChild(_29);}}else{_29.innerHTML=str;this.div.appendChild(_29);}};dp.sh.Highlighter.prototype.IsInside=function(_2d){if(_2d==null||_2d.length==0){return false;}for(var i=0;ic.index)&&(_2d.index/gi,"\n");var _43=_42.split("\n");if(this.addControls==true){this.bar.appendChild(dp.sh.Toolbar.Create(this));}if(this.showColumns){var div=this.CreateElement("div");var _45=this.CreateElement("div");var _46=10;var i=1;while(i<=150){if(i%_46==0){div.innerHTML+=i;i+=(i+"").length;}else{div.innerHTML+="·";i++;}}_45.className="columns";_45.appendChild(div);this.bar.appendChild(_45);}for(var i=0,lineIndex=this.firstLine;i<_43.length-1;i++,lineIndex++){var li=this.CreateElement("LI");var _4a=this.CreateElement("SPAN");li.className=(i%2==0)?"alt":"";_4a.innerHTML=_43[i]+" ";li.appendChild(_4a);this.ol.appendChild(li);}this.div.innerHTML="";};dp.sh.Highlighter.prototype.Highlight=function(_4b){function Trim(str){return str.replace(/^\s*(.*?)[\s\n]*$/g,"$1");}function Chop(str){return str.replace(/\n*$/,"").replace(/^\n*/,"");}function Unindent(str){var _4f=str.split("\n");var _50=new Array();var _51=new RegExp("^\\s*","g");var min=1000;for(var i=0;i<_4f.length&&min>0;i++){if(Trim(_4f[i]).length==0){continue;}var _54=_51.exec(_4f[i]);if(_54!=null&&_54.length>0){min=Math.min(_54[0].length,min);}}if(min>0){for(var i=0;i<_4f.length;i++){_4f[i]=_4f[i].substr(min);}}return _4f.join("\n");}function Copy(_56,_57,_58){return _56.substr(_57,_58-_57);}var pos=0;this.originalCode=_4b;this.code=Chop(Unindent(_4b));this.div=this.CreateElement("DIV");this.bar=this.CreateElement("DIV");this.ol=this.CreateElement("OL");this.matches=new Array();this.div.className="dp-highlighter";this.div.highlighter=this;this.bar.className="bar";this.ol.start=this.firstLine;if(this.CssClass!=null){this.ol.className=this.CssClass;}if(this.collapse){this.div.className+=" collapsed";}if(this.noGutter){this.div.className+=" nogutter";}if(this.tabsToSpaces==true){this.code=this.ProcessSmartTabs(this.code);}this.ProcessRegexList();if(this.matches.length==0){this.AddBit(this.code,null);this.SwitchToList();this.div.appendChild(this.ol);return;}this.matches=this.matches.sort(dp.sh.Highlighter.SortCallback);for(var i=0;i + + + +
+

{$component_info->title} ver. {$component_info->version}

+
+ +
+
+ + + + + + + +
{$lang->code_type} +
    +
  • + +
  • +
+
+
+ + + +
diff --git a/modules/editor/components/code_highlighter/tpl/popup.js b/modules/editor/components/code_highlighter/tpl/popup.js new file mode 100755 index 000000000..696b3ea86 --- /dev/null +++ b/modules/editor/components/code_highlighter/tpl/popup.js @@ -0,0 +1,52 @@ +/** + * popup으로 열렸을 경우 부모창의 위지윅에디터에 select된 멀티미디어 컴포넌트 코드를 체크하여 + * 있으면 가져와서 원하는 곳에 삽입 + **/ +var selected_node = null; +function getCode() { + // 부모 위지윅 에디터에서 선택된 영역이 있는지 확인 + if(typeof(opener)=="undefined") return; + + var node = opener.editorPrevNode; + if(!node || node.nodeName != "DIV") return; + + selected_node = node; + + var code_type = node.getAttribute("code_type"); + + xGetElementById("code_type").value = code_type; +} + +/* 추가 버튼 클릭시 부모창의 위지윅 에디터에 인용구 추가 */ +function insertCode() { + if(typeof(opener)=="undefined") return; + + var code_type = xGetElementById("code_type").value; + + var content = ""; + if(selected_node) content = xInnerHtml(selected_node); + else content = opener.editorGetSelectedHtml(opener.editorPrevSrl); + + var style = "border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;"; + + if(!content) content = " "; + + var text = "\n
"+content+"
\n
"; + + if(selected_node) { + selected_node.setAttribute("code_type", code_type); + selected_node.setAttribute("style", style); + opener.editorFocus(opener.editorPrevSrl); + + } else { + + opener.editorFocus(opener.editorPrevSrl); + var iframe_obj = opener.editorGetIFrame(opener.editorPrevSrl) + opener.editorReplaceHTML(iframe_obj, text); + opener.editorFocus(opener.editorPrevSrl); + } + + window.close(); +} + +xAddEventListener(window, "load", getCode);