/*! UIkit 2.5.0 | http://www.getuikit.com | (c) 2014 YOOtheme | MIT License */ (function(addon) { if (typeof define == "function" && define.amd) { // AMD define("uikit-markdownarea", ["uikit"], function(){ return jQuery.UIkit.markdownarea || addon(window, window.jQuery, window.jQuery.UIkit); }); } if(window && window.jQuery && window.jQuery.UIkit) { addon(window, window.jQuery, window.jQuery.UIkit); } })(function(global, $, UI){ var Markdownarea = function(element, options){ var $element = $(element); if($element.data("markdownarea")) return; this.element = $element; this.options = $.extend({}, Markdownarea.defaults, options); this.marked = this.options.marked || marked; this.CodeMirror = this.options.CodeMirror || CodeMirror; this.marked.setOptions({ gfm: true, tables: true, breaks: true, pedantic: false, sanitize: false, smartLists: true, smartypants: false, langPrefix: 'lang-' }); this.init(); this.element.data("markdownarea", this); }; $.extend(Markdownarea.prototype, { init: function(){ var $this = this, tpl = Markdownarea.template; tpl = tpl.replace(/\{\:lblPreview\}/g, this.options.lblPreview); tpl = tpl.replace(/\{\:lblCodeview\}/g, this.options.lblCodeview); this.markdownarea = $(tpl); this.content = this.markdownarea.find(".uk-markdownarea-content"); this.toolbar = this.markdownarea.find(".uk-markdownarea-toolbar"); this.preview = this.markdownarea.find(".uk-markdownarea-preview").children().eq(0); this.code = this.markdownarea.find(".uk-markdownarea-code"); this.element.before(this.markdownarea).appendTo(this.code); this.editor = this.CodeMirror.fromTextArea(this.element[0], this.options.codemirror); this.editor.markdownarea = this; this.editor.on("change", (function(){ var render = function(){ var value = $this.editor.getValue(); $this.currentvalue = String(value); $this.element.trigger("markdownarea-before", [$this]); $this.applyPlugins(); $this.marked($this.currentvalue, function (err, markdown) { if (err) throw err; $this.preview.html(markdown); $this.element.val($this.editor.getValue()).trigger("markdownarea-update", [$this]); }); }; render(); return UI.Utils.debounce(render, 150); })()); this.code.find(".CodeMirror").css("height", this.options.height); this._buildtoolbar(); this.fit(); $(window).on("resize", UI.Utils.debounce(function(){ $this.fit(); }, 200)); var previewContainer = $this.preview.parent(), codeContent = this.code.find('.CodeMirror-sizer'), codeScroll = this.code.find('.CodeMirror-scroll').on('scroll',UI.Utils.debounce(function() { if($this.markdownarea.attr("data-mode")=="tab") return; // calc position var codeHeight = codeContent.height() - codeScroll.height(), previewHeight = previewContainer[0].scrollHeight - previewContainer.height(), ratio = previewHeight / codeHeight, previewPostition = codeScroll.scrollTop() * ratio; // apply new scroll previewContainer.scrollTop(previewPostition); }, 10)); this.markdownarea.on("click", ".uk-markdown-button-markdown, .uk-markdown-button-preview", function(e){ e.preventDefault(); if($this.markdownarea.attr("data-mode")=="tab") { $this.markdownarea.find(".uk-markdown-button-markdown, .uk-markdown-button-preview").removeClass("uk-active").filter(this).addClass("uk-active"); $this.activetab = $(this).hasClass("uk-markdown-button-markdown") ? "code":"preview"; $this.markdownarea.attr("data-active-tab", $this.activetab); } }); this.preview.parent().css("height", this.code.height()); }, applyPlugins: function(){ var $this = this, plugins = Object.keys(Markdownarea.plugins), plgs = Markdownarea.plugins; this.markers = {}; if(plugins.length) { var lines = this.currentvalue.split("\n"); plugins.forEach(function(name){ this.markers[name] = []; }, this); for(var line=0,max=lines.length;line'+Markdownarea.commands[cmd].label+''); if(Markdownarea.commands[cmd].shortcut) { $this.registerShortcut(Markdownarea.commands[cmd].shortcut, Markdownarea.commands[cmd].action); } } }); this.toolbar.html(bar.join("\n")); this.markdownarea.on("click", "a[data-markdownarea-cmd]", function(){ var cmd = $(this).data("markdownareaCmd"); if(cmd && Markdownarea.commands[cmd] && (!$this.activetab || $this.activetab=="code" || cmd=="fullscreen")) { Markdownarea.commands[cmd].action.apply($this, [$this.editor]) } }); }, fit: function() { var mode = this.options.mode; if(mode=="split" && this.markdownarea.width() < this.options.maxsplitsize) { mode = "tab"; } if(mode=="tab") { if(!this.activetab) { this.activetab = "code"; this.markdownarea.attr("data-active-tab", this.activetab); } this.markdownarea.find(".uk-markdown-button-markdown, .uk-markdown-button-preview").removeClass("uk-active") .filter(this.activetab=="code" ? '.uk-markdown-button-markdown':'.uk-markdown-button-preview').addClass("uk-active"); } this.editor.refresh(); this.preview.parent().css("height", this.code.height()); this.markdownarea.attr("data-mode", mode); }, registerShortcut: function(combination, callback){ var $this = this; combination = $.isArray(combination) ? combination : [combination]; for(var i=0,max=combination.length;i < max;i++) { var map = {}; map[combination[i]] = function(){ callback.apply($this, [$this.editor]); }; $this.editor.addKeyMap(map); } } }); //jQuery plugin $.fn.markdownarea = function(options){ return this.each(function(){ var ele = $(this); if(!ele.data("markdownarea")) { var obj = new Markdownarea(ele, options); } }); }; var baseReplacer = function(replace, editor){ var text = editor.getSelection(), markdown = replace.replace('$1', text); editor.replaceSelection(markdown, 'end'); }; Markdownarea.commands = { "fullscreen": { "title" : 'Fullscreen', "label" : '', "action" : function(editor){ editor.markdownarea.markdownarea.toggleClass("uk-markdownarea-fullscreen"); var wrap = editor.getWrapperElement(); if(editor.markdownarea.markdownarea.hasClass("uk-markdownarea-fullscreen")) { editor.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset, width: wrap.style.width, height: wrap.style.height}; wrap.style.width = ""; wrap.style.height = editor.markdownarea.content.height()+"px"; document.documentElement.style.overflow = "hidden"; } else { document.documentElement.style.overflow = ""; var info = editor.state.fullScreenRestore; wrap.style.width = info.width; wrap.style.height = info.height; window.scrollTo(info.scrollLeft, info.scrollTop); } editor.refresh(); editor.markdownarea.preview.parent().css("height", editor.markdownarea.code.height()); } }, "bold" : { "title" : "Bold", "label" : '', "shortcut": ['Ctrl-B', 'Cmd-B'], "action" : function(editor){ baseReplacer("**$1**", editor); } }, "italic" : { "title" : "Italic", "label" : '', "action" : function(editor){ baseReplacer("*$1*", editor); } }, "strike" : { "title" : "Strikethrough", "label" : '', "action" : function(editor){ baseReplacer("~~$1~~", editor); } }, "blockquote" : { "title" : "Blockquote", "label" : '', "action" : function(editor){ baseReplacer("> $1", editor); } }, "link" : { "title" : "Link", "label" : '', "action" : function(editor){ baseReplacer("[$1](http://)", editor); } }, "picture" : { "title" : "Picture", "label" : '', "action" : function(editor){ baseReplacer("![$1](http://)", editor); } }, "listUl" : { "title" : "Unordered List", "label" : '', "action" : function(editor){ baseReplacer("* $1", editor); } }, "listOl" : { "title" : "Ordered List", "label" : '', "action" : function(editor){ baseReplacer("1. $1", editor); } } } Markdownarea.defaults = { "mode" : "split", "height" : 500, "maxsplitsize" : 1000, "codemirror" : { mode: 'gfm', tabMode: 'indent', tabindex: "2", lineWrapping: true, dragDrop: false }, "toolbar" : [ "bold", "italic", "strike", "link", "picture", "blockquote", "listUl", "listOl" ], "lblPreview" : "Preview", "lblCodeview" : "Markdown" }; Markdownarea.template = '
' + '
' + '
    ' + '
    ' + '' + '
    ' + '
    ' + '
    ' + '
    ' + '
    ' + '
    ' + '
    '; Markdownarea.plugins = {}; Markdownarea.addPlugin = function(name, identifier, callback) { Markdownarea.plugins[name] = {"identifier":identifier, "cb":callback}; }; UI["markdownarea"] = Markdownarea; // init code $(function() { $("textarea[data-uk-markdownarea]").each(function() { var area = $(this), obj; if (!area.data("markdownarea")) { obj = new Markdownarea(area, UI.Utils.options(area.attr("data-uk-markdownarea"))); } }); }); return Markdownarea; });