| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496 |
- // jQuery not really required, it's here to overcome an inability to pass configuration options to the fiddle remotely
- // Custom example logic
- /**
- * TinyMCE Load
- */
- if (typeof (tinyMCE) == "undefined") {
- console.log('Requires TinyMCE.');
- }
- let isMobile = !tinymce.Env.desktop; // (tinymce.Env.phone || tinymce.Env.tablet || false);
- let pluploadHandler,
- menubar,
- plugins,
- toolbar,
- cssText;
- cssText = "div.emoticon-group {margin:0; padding:0;}";
- cssText += "div.emoticon-group > A.emoticon-group-item {margin:0;padding:0 9px 0 11px; float:left;width:60px;height:60px; list-style:none;cursor:pointer;}";
- cssText += "div.emoticon-group > A.emoticon-group-item > IMG.emoticon-group-item-icon {max-width:100%;max-height:100%;}";
- cssText += "div.mce-path > .mce-path-item {display:none !important;}";
- cssText += "@media all and (max-width: 480px;) {";
- cssText += "ul.emoticon-group > li.emoticon-group-item {width:32px;}";
- cssText += "}";
- if(isMobile) {
- cssText += "@media all and (max-width: 480px;){";
- cssText += ".tinycme-full .mce-edit-area {display:flex;flex-flow:column;}";
- cssText += ".tinycme-full .mce-edit-area iframe {flex:1 1 auto;}";
- cssText += ".tinycme-full {height:100%;}";
- cssText += ".tinycme-full .mce-tinymce.mce-container {width:100%;height:100%;/*border:0;*/}";
- cssText += ".tinycme-full .mce-panel{/*border:0;*/}";
- cssText += ".tinycme-full .mce-container-body.mce-stack-layout {display: flex; flex-flow: column;height: 100%;}";
- cssText += ".tinycme-full .mce-stack-layout-item{ flex: 0 0 auto;}";
- cssText += ".tinycme-full .mce-edit-area{flex:1 1 auto;}";
- cssText += ".tinycme-full .mce-window .mce-btn.mce-colorbutton {display:none}";
- cssText += ".tinycme-full .mce-window-head .mce-dragh {cursor:default !important;} }";
- }
- // Viewport Add HTML5기반 (IE 10, Chrome 9, Opera 12.1, Safari 5.1, Firefox 6.0
- if (!$('head > meta[name="viewport"]:last').length) {
- $('<meta name="viewport" content="width=device-width, initial-scale=1.0" />').append('head:last');
- }
- $('<style>').prop("type", "text/css").attr({'id': 'tinymce-css-responsive'}).html(cssText).appendTo('head:last');
- $.ajaxSetup({'async': false});
- // 허용 iframe 주소 기본값
- if(typeof whiteIframe == "undefined" || whiteIframe == null || whiteIframe == "") {
- var whiteIframe = ['www.youtube.com', 'www.youtube-nocookie.com', 'maps.google.co.kr',
- 'maps.google.com', 'flvs.daum.net', 'player.vimeo.com', 'sbsplayer.sbs.co.kr',
- 'serviceapi.rmcnmv.naver.com', 'serviceapi.nmv.naver.com', 'www.mgoon.com',
- 'videofarm.daum.net', 'player.sbs.co.kr', 'sbsplayer.sbs.co.kr', 'www.tagstory.com',
- 'play.tagstory.com', 'flvr.pandora.tv', 'youtu.be', 'vimeo.com', 'dailymotion.com', 'tvpot.daum.net'];
- }
- // 이모티콘 사용여부
- if(typeof useEmoticon == "undefined" || useEmoticon == null || useEmoticon === "") {
- var useEmoticon = 'N';
- }
- // 관리자와 사용자 구분하여 기능 구분
- if(window.location.href.indexOf('admin') <= -1) // 사용자
- {
- // autoresize라는 플러그인도 있음.
- menubar = false;
- plugins = 'advlist autolink link image lists charmap print preview hr anchor pagebreak spellchecker searchreplace visualblocks visualchars code fullscreen insertdatetime media nonbreaking save table contextmenu directionality emoticons template paste textcolor codesample';
- toolbar = 'fontselect | fontStyle | fontsizeselect | bold underline strikethrough forecolor backcolor alignleft aligncenter alignright alignjustify | link imageUpload media | code | codesample';
- } else { // 관리자
- // wordcount 제외시킴
- menubar = true;
- plugins = 'print preview searchreplace autolink directionality visualblocks visualchars fullscreen link media template codesample table charmap hr pagebreak nonbreaking anchor toc insertdatetime advlist lists textcolor imagetools contextmenu colorpicker textpattern help codesample';
- toolbar = 'formatselect | bold italic strikethrough forecolor backcolor | alignleft aligncenter alignright alignjustify | numlist bullist outdent indent | removeformat | link imageUpload media | code | codesample';
- }
- // Placeholder 기능 추가
- let label = {
- init: function(e) {
- let placeholderText = (e.getElement().getAttribute("placeholoer") || e.settings.placeholder);
- let placeholderAttrs = (e.settings.placeholderAttrs || {
- style: {
- position: 'absolute',
- top: '2px',
- left: 0,
- color: '#959595',
- padding: '.25%',
- margin: '5px',
- width: 'auto',
- 'font-size': '17px !important;',
- overflow: 'hidden',
- 'line-height': '24px',
- 'white-space': 'pre-wrap'
- }
- });
- let contentAreaContainer = e.getContentAreaContainer();
- tinymce.DOM.setStyle(contentAreaContainer, 'position', 'relative');
- this.el = tinymce.DOM.add(contentAreaContainer, "label", placeholderAttrs, placeholderText);
- },
- focus: function(e) {
- if (!e.settings.readonly === true) {
- this.hide();
- }
- e.execCommand('mceFocus', false);
- },
- blur: function(e) {
- if (e.getContent() == '') {
- this.show();
- } else {
- this.hide();
- }
- },
- hide: function() {
- tinymce.DOM.setStyle(this.el, 'display', 'none');
- },
- show: function() {
- tinymce.DOM.setStyle(this.el, 'display', '');
- }
- };
- let setting = {
- selector: '.tinymce-editor',
- language: 'ko_KR',
- menubar: menubar,
- theme: 'modern',
- skin: 'default',
- plugins: plugins,
- width: 'auto',
- inline: false, // <br data-mce-bogus="1"> 삭제
- forced_root_block: "", // p tag 비 활성화
- min_height: 400, // 에디터 세로크기
- // autoresize_min_height: 400, // 에디터 최소 세로크기
- // autoresize_bottom_margin: 0,
- // autoresize_on_init: true,
- content_style:
- "body {font-family: Nanum-Square-Neo-Regular;}",
- font_formats: "Default='나눔스퀘어'" +
- ";나눔스퀘어=Nanum-Square-Neo-Regular, 나눔스퀘어" +
- ";돋움=dotum, 돋움" +
- ";굴림=gulim, 굴림" +
- ";바탕=batang, 바탕" +
- ";궁서=gungsuh, 궁서" +
- ";맑은 고딕=malgun gothic, 맑은 고딕" +
- ";Arial=arial,helvetica, verdana, sans-serif" +
- ";Andale Mono=andale mono, monospace" +
- ";Tahoma=tahoma,arial, helvetica, sans-serif" +
- ";Verdana=verdana, geneva, sans-serif",
- codesample_languages: [
- {text: "HTML/XML", value: "markup"},
- {text: "JavaScript", value: "javascript"},
- {text: "CSS", value: "css"},
- {text: "PHP", value: "php"},
- {text: "Ruby", value: "ruby"},
- {text: "Python", value: "python"},
- {text: "Java", value: "java"},
- {text: "C", value: "c"},
- {text: "C#", value: "csharp"},
- {text: "C++", value: "cpp"},
- {text: "scss", value: "scss"},
- {text: "SQL", value: "sql"},
- {text: "YAML", value: "yaml"},
- {text: "nginx", value: "nginx"},
- {text: "JSON", value: "json"},
- {text: "go", value: "go"},
- {text: "Bash", value: "bash"},
- {text: "Shell", value: "shell-session"}
- ],
- branding: false, // 아래 `POWERED BY TINYMCE` 표시 삭제
- toolbar: toolbar,
- fontsize_formats: '8pt 10pt 12pt 14pt 18pt 24pt 36pt',
- statusbar: true, // 하단 단어 개수, p 태그 지정 상태창 숨김
- directionality: 'ltr',
- visualblocks_default_state: false, // 선택 영역 지정
- // 링크 설정
- link_title: false,
- target_list: false,
- default_link_target: "_blank",
- // 이미지 설정
- image_dimensions: false, // 이미지 크기
- file_browser_url: "/editor/uploader", // 라우터에 의한 이동
- image_advtab: true,
- paste_data_images: true,
- paste_postprocess: (editor, args) => {
- let images = args.node.getElementsByTagName("img");
- if(images.length > 0) {
- for(let img of images) {
- img.dataset.target = "thumb";
- }
- }
- },
- // 이미지 크기 조정
- elementpath: false,
- relative_urls: true,
- remove_script_host: true,
- // 비디오 설정
- media_poster: false, // 포스터 파일
- media_alt_source: false, // 대체 소스
- media_dimensions: false,
- media_filter_html: true,
- media_allow_host: whiteIframe
- , 'media_url_patterns' : [
- {regex : /videofarm\.daum\.net\/controller\/video\/viewer\/Video\.html\?vid=([^&]+)/, type: 'iframe', w: 640, h: 360, url: '//videofarm.daum.net/controller/video/viewer/Video.html?vid=$1&play_loc=undefined&alert=true', allowFullscreen: true}
- ]
- , 'media_pattern_types' : [
- {'regex' : /^(http[s]?:)?\/\/videofarm\.daum\.net/, 'type' : 'iframe' , 'allowFullscreen' : true, 'width': 640, 'height': 360}
- ],
- extended_valid_elements : "iframe[src|title|width|height|allowfullscreen|frameborder]",
- init_instance_callback: function (editor) {
- label.init(editor);
- label.blur(editor);
- tinymce.DOM.bind(label.el, 'click', label.focus(editor));
- },
- setup: function (editor) {
- editor.on('submit', function (e) {
- console.log("Editor submited !!");
- });
- editor.addButton('imageUpload', {
- type: 'button',
- title: 'Insert/edit image',
- icon: 'image',
- id: 'imageUpload',
- stateSelector: 'img:not([data-mce-object],[data-mce-placeholder],[data-smileys]),figure.image',
- onclick: function () {
- let dialog = editor.windowManager.open({
- title: "사진 첨부하기",
- width: 800,
- height: 415,
- scrollbars: false,
- labelby: "imageUpload",
- resizable: true,
- file: editor.settings.file_browser_url,
- close_previous: true,
- maximizable: true,
- inline: true,
- buttons: [{
- text: "확인",
- subtype: "primary",
- onclick: function (e) {
- // pluploadHandler.startUploader(this);
- pluploadHandler.insertContent();
- }
- }, {
- text: "닫기",
- onclick: function (e) {
- pluploadHandler.stopUploader();
- }
- }]
- });
- pluploadSetting(dialog);
- }
- });
- // 초기 설정
- editor.on('init', function(e) {
- if(useEmoticon === 'Y') {
- let div = $('<div class="mce-container mce-panel mce-stack-layout-item">');
- $(e.getContentAreaContainer()).after(div); // 에디터 하단에 새로운 영역 생성
- setEmoticons(e, div);
- selfAutoResize();
- (typeof (selfAutoResize) == 'function' && e.on("nodechange setcontent keyup FullscreenStateChanged", selfAutoResize));
- console.log("editor emoticon loaded");
- }
- });
- // 팝업 창 오픈
- editor.on("OpenWindow", function(arg) {
- let hWin = arg.win;
- hWin.settings.maxWidth = (hWin.settings.maxWidth || hWin.settings.width || hWin._layoutRect.w);
- hWin.settings.maxHeight = (hWin.settings.maxHeight || hWin.settings.height || hWin._layoutRect.h);
- $(window).off('resize', windowDialogResize).on('resize', windowDialogResize);
- setTimeout(windowDialogResize, 100);
- });
- // 팝업창 닫기
- editor.on("CloseWindow", function() {
- $(".wrap-loading").hide();
- $(window).off('resize', windowDialogResize);
- });
- // 에디터 자동저장
- editor.on('change', function(e) {
- e.target.save();
- label.blur(editor);
- });
- editor.on('focus', function(e) {
- label.focus(editor);
- });
- editor.on('blur', function(e) {
- label.blur(editor);
- });
- editor.on('setContent', function(e) {
- // iframe에 입력되는 주소는 hidden으로 저장한다.
- let iframeRows = e.target.contentDocument.body.getElementsByTagName("iframe");
- if(iframeRows > 0) {
- $(e.content).filter("iframe").attr("src", ""); // iframe src 주소
- }
- label.blur(editor);
- });
- }
- };
- tinymce.init(setting);
- // 파일 업로드 환경설정
- function pluploadSetting(dialog)
- {
- let iframe = $(dialog.$el).find(".mce-window-body iframe").get(0);
- $(iframe).on("load", function () {
- let window = this.contentWindow || this;
- let document = this.contentDocument || win.document;
- pluploadHandler = window;
- // 전체삭제 버튼 클릭
- $(document).on("click", "div#remove-all", function () {
- pluploadHandler.removeThumb();
- });
- // 개별 삭제 버튼 클릭
- $(document).on("click", ".picker-image-remove", function () {
- pluploadHandler.removeThumb($(this));
- });
- // 제대로 로딩이 안되면 팝업 닫기
- if(document.firstElementChild.querySelectorAll(".picker-container").length <= 0) {
- parent.tinyMCE.activeEditor.windowManager.close(window);
- }
- console.log('Upload View Loaded.');
- });
- }
- // 에디터 팝업창 크기 자동조절
- function windowDialogResize()
- {
- let editor = tinyMCE.activeEditor;
- let hWin = editor.windowManager.getWindows()[0];
- if(typeof hWin == 'undefined') {
- return;
- }
- let dialog = $(hWin.$el);
- let currentWidth = dialog.width();
- let innerWidth = $(window).innerWidth();
- let innerHeight = $(window).innerHeight();
- let maxWidth = hWin.settings.maxWidth;
- let maxHeight = hWin.settings.maxHeight;
- let resizeWidth = Math.max(Math.min(innerWidth, maxWidth), 240);
- let resizeHeight = Math.max(Math.min(innerHeight, maxHeight), 200);
- hWin.resizeTo(resizeWidth, resizeHeight);
- let posX = Math.floor((innerWidth / 2) - (dialog.width() / 2)) - 1;
- let posY = Math.floor((innerHeight / 2) - (dialog.height() / 2));
- if(isMobile) {
- posY = innerHeight - (dialog.height() + 2);
- }
- hWin.moveTo(posX, posY);
- setTimeout(function () {
- var dw = (currentWidth - 40) - (dialog.width() - 40);
- dialog.find('.' + hWin.bodyClasses.prefix + 'textbox').each(function () {
- var el = $(this);
- el.width(el.width() - dw);
- });
- }, 0);
- }
- // 에디터 알림 메시지
- function message(message, severity, args)
- {
- let setting = $.extend({'timeout': 3000, 'closeButton': true, 'icon': (severity || 'notice').replace('error', 'notice')}, args, {'text': message, 'type': severity || 'info'});
- tinymce.activeEditor.notificationManager.open(setting);
- }
- // 팝업 알림 메시지
- function popMessage(message)
- {
- tinymce.activeEditor.windowManager.alert(message);
- }
- let selfResizeObj;
- let selfIframe;
- let wrapper = $("div#wrapper");
- let oldHeight = wrapper.height();
- // 크기 자동조정 기능정의
- function resizeDone(wait)
- {
- clearTimeout(selfResizeObj);
- selfResizeObj = null;
- if (!selfIframe) {
- $(parent.document).find("iframe").each(function () {
- return ((this.contentWindow == window) ? (selfIframe = $(this), false) : void 0);
- });
- if (!selfIframe) {
- return true;
- }
- }
- try {
- let curHeight;
- (curHeight = wrapper.height()) != oldHeight && (selfIframe.height(curHeight), oldHeight = curHeight);
- } catch (err) {
- alert(err);
- }
- if (wait > 0) {
- selfResizeObj = setTimeout(function () {
- resizeDone(--wait);
- }, 10);
- }
- }
- // 현재 에디터 크기 자동조정
- function selfAutoResize(wait)
- {
- if(!window.parent) {
- return true;
- }
- // tinymce.activeEditor.execCommand('mceAutoResize', false);
- wait = (wait || 1);
- selfResizeObj = setTimeout(function() {
- resizeDone(--wait);
- }, 10);
- }
- // 이모티콘 설정
- function setEmoticons(editor, container)
- {
- // 현재 창이 관리자 모드 라면 취소
- let adminUrl = document.location.href;
- if(adminUrl.indexOf("admin") != -1) {
- return false;
- }
- // 이모티콘 로드
- let emoticons= new Array();
- $.get(tinyMCE.baseURL + '/emoticon.xml', function(data) {
- if(typeof data == 'string'){
- data = $.parseXML(data);
- }
- emoticons = $.map(data.documentElement.getElementsByTagName('emoticon'), function(emoticon) {
- let s = {};
- $.each(emoticon.attributes, function() {
- if($.trim(this.nodeValue))
- s[this.nodeName] = this.nodeValue;
- });
- return s;
- });
- });
- container.css({'background-color': '#FFFFFF', 'border-width': '1px 0 0 0'});
- let group = $('<DIV />').addClass('emoticon-group').appendTo(container);
- $.each(emoticons, function(index) {
- $('<img />').attr(this).addClass('emoticon-group-item-icon').appendTo($('<a href="#" onclick="return false;" class="emoticon-group-item"></a>').appendTo(group)).on('click', function(event) {
- event.preventDefault();
- editor.insertContent('<img src="' + $(this).attr('src') + '" align="middle" data-mce-resize="false" alt="이모티콘_' + index + ' "/>');
- });
- });
- group.append($('<div />').css({'display': 'block', 'width': '100%', 'height': '1px', 'clear': 'both', 'float': 'none'}));
- }
- // 업로드 이미지 번호 저장
- function setImageID(imageID) {
- let editor = tinyMCE.activeEditor;
- if (typeof imageID == "undefined" || imageID == null) {
- message("해당 사진을 올릴 수 없습니다.");
- return false;
- } else {
- let div = $('<input type="hidden" name="imageID" value="' + imageID + '"/>');
- $(editor.getContentAreaContainer()).after(div); // 에디터 하단에 새로운 영역 생성
- }
- }
|