|
|
/*! 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<max;line++) {
(function(line){ plugins.forEach(function(name){
var i = 0;
lines[line] = lines[line].replace(plgs[name].identifier, function(){
var replacement = plgs[name].cb({ "area" : $this, "found": arguments, "line" : line, "pos" : i++, "uid" : [name, line, i, (new Date().getTime())+"RAND"+(Math.ceil(Math.random() *100000))].join('-'), "replace": function(strwith){ var src = this.area.editor.getLine(this.line), start = src.indexOf(this.found[0]); end = this.found[0].length;
this.area.editor.replaceRange(strwith, {"line": this.line, "ch":start}, {"line": this.line, "ch":end} ); } });
return replacement; }); }); })(line); }
this.currentvalue = lines.join("\n");
} },
_buildtoolbar: function(){
if(!(this.options.toolbar && this.options.toolbar.length)) return;
var $this = this, bar = [];
this.options.toolbar.forEach(function(cmd){ if(Markdownarea.commands[cmd]) {
var title = Markdownarea.commands[cmd].title ? Markdownarea.commands[cmd].title : cmd;
bar.push('<li><a data-markdownarea-cmd="'+cmd+'" title="'+title+'" data-uk-tooltip>'+Markdownarea.commands[cmd].label+'</a></li>');
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" : '<i class="uk-icon-expand"></i>', "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" : '<i class="uk-icon-bold"></i>', "shortcut": ['Ctrl-B', 'Cmd-B'], "action" : function(editor){
baseReplacer("**$1**", editor); } }, "italic" : { "title" : "Italic", "label" : '<i class="uk-icon-italic"></i>', "action" : function(editor){ baseReplacer("*$1*", editor); } }, "strike" : { "title" : "Strikethrough", "label" : '<i class="uk-icon-strikethrough"></i>', "action" : function(editor){ baseReplacer("~~$1~~", editor); } }, "blockquote" : { "title" : "Blockquote", "label" : '<i class="uk-icon-quote-right"></i>', "action" : function(editor){ baseReplacer("> $1", editor); } }, "link" : { "title" : "Link", "label" : '<i class="uk-icon-link"></i>', "action" : function(editor){ baseReplacer("[$1](http://)", editor); } }, "picture" : { "title" : "Picture", "label" : '<i class="uk-icon-picture-o"></i>', "action" : function(editor){ baseReplacer("![$1](http://)", editor); } }, "listUl" : { "title" : "Unordered List", "label" : '<i class="uk-icon-list-ul"></i>', "action" : function(editor){ baseReplacer("* $1", editor); } }, "listOl" : { "title" : "Ordered List", "label" : '<i class="uk-icon-list-ol"></i>', "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 = '<div class="uk-markdownarea uk-clearfix" data-mode="split">' + '<div class="uk-markdownarea-navbar">' + '<ul class="uk-markdownarea-navbar-nav uk-markdownarea-toolbar"></ul>' + '<div class="uk-markdownarea-navbar-flip">' + '<ul class="uk-markdownarea-navbar-nav">' + '<li class="uk-markdown-button-markdown"><a>{:lblCodeview}</a></li>' + '<li class="uk-markdown-button-preview"><a>{:lblPreview}</a></li>' + '<li><a data-markdownarea-cmd="fullscreen"><i class="uk-icon-expand"></i></a></li>' + '</ul>' + '</div>' + '</div>' + '<div class="uk-markdownarea-content">' + '<div class="uk-markdownarea-code"></div>' + '<div class="uk-markdownarea-preview"><div></div></div>' + '</div>' + '</div>';
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; });
|