From 2ecec3b59aabe2fd6156338cd4cbab7672d4f9b1 Mon Sep 17 00:00:00 2001 From: Wu Cheng-Han Date: Tue, 12 Jan 2016 08:01:42 -0600 Subject: Support show last change user with profile and support YAML config inside the note with robots, lang, dir, breaks options --- public/js/extra.js | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++-- public/js/index.js | 23 ++++++---- public/js/pretty.js | 8 +++- 3 files changed, 139 insertions(+), 14 deletions(-) (limited to 'public/js') diff --git a/public/js/extra.js b/public/js/extra.js index 07e85acc..e624bfaf 100644 --- a/public/js/extra.js +++ b/public/js/extra.js @@ -1,15 +1,32 @@ //auto update last change var lastchangetime = null; -var lastchangeui = null; +var lastchangeui = { + time: $(".ui-lastchange"), + user: $(".ui-lastchangeuser"), + nouser: $(".ui-no-lastchangeuser") +} function updateLastChange() { if (lastchangetime && lastchangeui) { - lastchangeui.html('  change ' + moment(lastchangetime).fromNow()); - lastchangeui.attr('title', moment(lastchangetime).format('llll')); + lastchangeui.time.html(moment(lastchangetime).fromNow()); + lastchangeui.time.attr('title', moment(lastchangetime).format('llll')); } } setInterval(updateLastChange, 60000); +function updateLastChangeUser(data) { + if (data.lastchangeuserprofile) { + var icon = lastchangeui.user.children('i'); + icon.attr('title', data.lastchangeuserprofile.name).tooltip('fixTitle'); + icon.attr('style', 'background-image:url(' + data.lastchangeuserprofile.photo + ')'); + lastchangeui.user.show(); + lastchangeui.nouser.hide(); + } else { + lastchangeui.user.hide(); + lastchangeui.nouser.show(); + } +} + //get title function getTitle(view) { var h1s = view.find("h1"); @@ -48,6 +65,57 @@ function slugifyWithUTF8(text) { return newText; } +//parse meta +function parseMeta(md, view, toc, tocAffix) { + var robots = null; + var lang = null; + var dir = null; + var breaks = true; + if (md && md.meta) { + var meta = md.meta; + robots = meta.robots; + lang = meta.lang; + dir = meta.dir; + breaks = meta.breaks; + } + //robots meta + var robotsMeta = $('meta[name=robots]'); + if (robots) { + if (robotsMeta.length > 0) + robotsMeta.attr('content', robots); + else + $('head').prepend('') + } + else + robotsMeta.remove(); + //text language + if (lang) { + view.attr('lang', lang); + toc.attr('lang', lang); + tocAffix.attr('lang', lang); + } else { + view.removeAttr('lang'); + toc.removeAttr('lang'); + tocAffix.removeAttr('lang'); + } + //text direction + if (dir) { + view.attr('dir', dir); + toc.attr('dir', dir); + tocAffix.attr('dir', dir); + } else { + view.removeAttr('dir'); + toc.removeAttr('dir'); + tocAffix.removeAttr('dir'); + } + //breaks + if (typeof breaks === 'boolean' && !breaks) { + md.options.breaks = false; + } else { + md.options.breaks = true; + } +} + var viewAjaxCallback = null; //regex for extra tags @@ -329,7 +397,10 @@ function exportToHTML(view) { css: css, html: src[0].outerHTML, toc: toc.html(), - 'toc-affix': tocAffix.html() + 'toc-affix': tocAffix.html(), + robots: (md && md.meta && md.meta.robots) ? '' : null, + lang: (md && md.meta && md.meta.lang) ? 'lang="' + md.meta.lang + '"' : null, + dir: (md && md.meta && md.meta.dir) ? 'dir="' + md.meta.dir + '"' : null }; var html = template(context); // console.log(html); @@ -737,6 +808,49 @@ var speakerdeckPlugin = new Plugin( return div[0].outerHTML; } ); + +//yaml meta, from https://github.com/eugeneware/remarkable-meta +function get(state, line) { + var pos = state.bMarks[line]; + var max = state.eMarks[line]; + return state.src.substr(pos, max - pos); +} + +function meta(state, start, end, silent) { + if (start !== 0 || state.blkIndent !== 0) return false; + if (state.tShift[start] < 0) return false; + if (!get(state, start).match(/^---$/)) return false; + + var data = []; + for (var line = start + 1; line < end; line++) { + var str = get(state, line); + if (str.match(/^(\.{3}|-{3})$/)) break; + if (state.tShift[line] < 0) break; + data.push(str); + } + + if (line >= end) return false; + + try { + md.meta = jsyaml.safeLoad(data.join('\n')) || {}; + } catch(err) { + console.error(err); + return false; + } + + state.line = line + 1; + + return true; +} + +function metaPlugin(md) { + md.meta = md.meta || {}; + md.block.ruler.before('code', 'meta', meta, { + alt: [] + }); +} + +md.use(metaPlugin); md.use(youtubePlugin); md.use(vimeoPlugin); md.use(gistPlugin); diff --git a/public/js/index.js b/public/js/index.js index e9be3de0..34cca1f8 100644 --- a/public/js/index.js +++ b/public/js/index.js @@ -320,6 +320,8 @@ var ui = { }, infobar: { lastchange: $(".ui-lastchange"), + lastchangeuser: $(".ui-lastchangeuser"), + nolastchangeuser: $(".ui-no-lastchangeuser"), permission: { permission: $(".ui-permission"), label: $(".ui-permission-label"), @@ -387,9 +389,9 @@ function setHaveUnreadChanges(bool) { function updateTitleReminder() { if (!loaded) return; if (haveUnreadChanges) { - document.title = '• ' + renderTitle(ui.area.view); + document.title = '• ' + renderTitle(ui.area.markdown); } else { - document.title = renderTitle(ui.area.view); + document.title = renderTitle(ui.area.markdown); } } @@ -465,6 +467,8 @@ $(document).ready(function () { upClass: 'navbar-hide', downClass: 'navbar-show' }); + //tooltip + $('[data-toggle="tooltip"]').tooltip(); }); //when page resize $(window).resize(function () { @@ -1165,8 +1169,8 @@ socket.on('version', function (data) { }); socket.on('check', function (data) { lastchangetime = data.updatetime; - lastchangeui = ui.infobar.lastchange; updateLastChange(); + updateLastChangeUser(data); }); socket.on('permission', function (data) { updatePermission(data.permission); @@ -1182,8 +1186,8 @@ socket.on('refresh', function (data) { owner = data.owner; updatePermission(data.permission); lastchangetime = data.updatetime; - lastchangeui = ui.infobar.lastchange; updateLastChange(); + updateLastChangeUser(data); if (!loaded) { changeMode(currentMode); loaded = true; @@ -1884,15 +1888,18 @@ var lastResult = null; function updateViewInner() { if (currentMode == modeType.edit || !isDirty) return; var value = editor.getValue(); + md.meta = {}; + md.render(value); //only for get meta + parseMeta(md, ui.area.markdown, $('#toc'), $('#toc-affix')); var result = postProcess(md.render(value)).children().toArray(); partialUpdate(result, lastResult, ui.area.markdown.children().toArray()); if (result && lastResult && result.length != lastResult.length) updateDataAttrs(result, ui.area.markdown.children().toArray()); lastResult = $(result).clone(); - finishView(ui.area.view); - autoLinkify(ui.area.view); - deduplicatedHeaderId(ui.area.view); - renderTOC(ui.area.view); + finishView(ui.area.markdown); + autoLinkify(ui.area.markdown); + deduplicatedHeaderId(ui.area.markdown); + renderTOC(ui.area.markdown); generateToc('toc'); generateToc('toc-affix'); generateScrollspy(); diff --git a/public/js/pretty.js b/public/js/pretty.js index ff393cac..43e833c2 100644 --- a/public/js/pretty.js +++ b/public/js/pretty.js @@ -1,5 +1,8 @@ var markdown = $(".markdown-body"); var text = $('