summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWu Cheng-Han2016-08-15 11:25:27 +0800
committerWu Cheng-Han2016-08-15 11:25:27 +0800
commita013c9d3bc0eb98c935e80bdb694c1a1cf7bd4c4 (patch)
tree5078a64286601b5b476f9613ecaee39e6837aa1d
parente12fae699981762a69a72f6f164c0ec0254ddcf2 (diff)
Update slide mode to show extra info and support url actions and support disqus via yaml-metadata
-rw-r--r--app.js2
-rw-r--r--lib/models/note.js2
-rwxr-xr-x[-rw-r--r--]lib/response.js39
-rw-r--r--public/css/slide.css26
-rw-r--r--public/docs/yaml-metadata.md11
-rw-r--r--public/js/slide.js11
-rwxr-xr-xpublic/vendor/bootstrap/tooltip.min.css14
-rwxr-xr-xpublic/vendor/bootstrap/tooltip.min.js11
-rw-r--r--public/views/disqus.ejs14
-rw-r--r--public/views/pretty.ejs5
-rw-r--r--public/views/slide.ejs24
11 files changed, 155 insertions, 4 deletions
diff --git a/app.js b/app.js
index 98b2b983..54a6baac 100644
--- a/app.js
+++ b/app.js
@@ -464,6 +464,8 @@ app.get("/s/:shortid", response.showPublishNote);
app.get("/s/:shortid/:action", response.publishNoteActions);
//get publish slide
app.get("/p/:shortid", response.showPublishSlide);
+//publish slide actions
+app.get("/p/:shortid/:action", response.publishSlideActions);
//get note by id
app.get("/:noteId", response.showNote);
//note actions
diff --git a/lib/models/note.js b/lib/models/note.js
index 81013047..d1c073e9 100644
--- a/lib/models/note.js
+++ b/lib/models/note.js
@@ -241,6 +241,8 @@ module.exports = function (sequelize, DataTypes) {
_meta.robots = meta.robots;
if (meta.GA && (typeof meta.GA == "string" || typeof meta.GA == "number"))
_meta.GA = meta.GA;
+ if (meta.disqus && (typeof meta.disqus == "string" || typeof meta.disqus == "number"))
+ _meta.disqus = meta.disqus;
if (meta.slideOptions && (typeof meta.slideOptions == "object"))
_meta.slideOptions = meta.slideOptions;
}
diff --git a/lib/response.js b/lib/response.js
index 23818da8..39d83ca2 100644..100755
--- a/lib/response.js
+++ b/lib/response.js
@@ -47,6 +47,7 @@ var response = {
showIndex: showIndex,
noteActions: noteActions,
publishNoteActions: publishNoteActions,
+ publishSlideActions: publishSlideActions,
githubActions: githubActions,
gitlabActions: gitlabActions
};
@@ -241,7 +242,8 @@ function showPublishNote(req, res, next) {
useCDN: config.usecdn,
lastchangeuserprofile: note.lastchangeuser ? models.User.parseProfile(note.lastchangeuser.profile) : null,
robots: meta.robots || false, //default allow robots
- GA: meta.GA
+ GA: meta.GA,
+ disqus: meta.disqus
};
return renderPublish(data, res);
}).catch(function (err) {
@@ -410,6 +412,20 @@ function publishNoteActions(req, res, next) {
});
}
+function publishSlideActions(req, res, next) {
+ findNote(req, res, function (note) {
+ var action = req.params.action;
+ switch (action) {
+ case "edit":
+ res.redirect(config.serverurl + '/' + (note.alias ? note.alias : LZString.compressToBase64(note.id)));
+ break;
+ default:
+ res.redirect(config.serverurl + '/p/' + note.shortid);
+ break;
+ }
+ });
+}
+
function githubActions(req, res, next) {
var noteId = req.params.noteId;
findNote(req, res, function (note) {
@@ -530,6 +546,13 @@ function gitlabActionProjects(req, res, note) {
}
function showPublishSlide(req, res, next) {
+ var include = [{
+ model: models.User,
+ as: "owner"
+ }, {
+ model: models.User,
+ as: "lastchangeuser"
+ }];
findNote(req, res, function (note) {
// force to use short id
var shortid = req.params.shortid;
@@ -549,26 +572,34 @@ function showPublishSlide(req, res, next) {
//na
}
if (!meta) meta = {};
+ var createtime = note.createdAt;
+ var updatetime = note.lastchangeAt;
var text = S(body).escapeHTML().s;
var title = models.Note.decodeTitle(note.title);
title = models.Note.generateWebTitle(meta.title || title);
var slides = md.slidify(text, slideOptions);
var origin = config.serverurl;
var data = {
- url: origin,
title: title,
description: meta.description,
+ viewcount: note.viewcount,
+ createtime: createtime,
+ updatetime: updatetime,
+ url: origin,
slides: slides,
meta: JSON.stringify(obj.meta || {}),
+ useCDN: config.usecdn,
+ lastchangeuserprofile: note.lastchangeuser ? models.User.parseProfile(note.lastchangeuser.profile) : null,
+ robots: meta.robots || false, //default allow robots
GA: meta.GA,
- useCDN: config.usecdn
+ disqus: meta.disqus
};
return renderPublishSlide(data, res);
}).catch(function (err) {
logger.error(err);
return response.errorInternalError(res);
});
- });
+ }, include);
}
function renderPublishSlide(data, res) {
diff --git a/public/css/slide.css b/public/css/slide.css
index df04fae1..bccb7e42 100644
--- a/public/css/slide.css
+++ b/public/css/slide.css
@@ -264,3 +264,29 @@ pre.mermaid > svg {
direction: rtl;
font-family: inherit;
}
+
+.text-uppercase {
+ text-transform: uppercase;
+}
+
+.footer {
+ background-color: white;
+ padding: 25px 15px;
+}
+
+.footer > * {
+ margin-left: auto;
+ margin-right: auto;
+ max-width: 758px;
+}
+
+.reveal {
+ height: 100vh;
+}
+
+.reveal .progress,
+.reveal .slide-number,
+.reveal .playback,
+.reveal .controls {
+ position: absolute;
+}
diff --git a/public/docs/yaml-metadata.md b/public/docs/yaml-metadata.md
index d22fccda..7158104b 100644
--- a/public/docs/yaml-metadata.md
+++ b/public/docs/yaml-metadata.md
@@ -117,6 +117,17 @@ This option allow you to enable Google Analytics with your ID.
GA: UA-12345667-8
```
+disqus
+---
+This option allow you to enable Disqus with your shortname.
+
+> default: not set (which won't enable)
+
+**Example**
+```xml
+disqus: hackmd
+```
+
slideOptions
---
This option allow you provide custom options to slide mode.
diff --git a/public/js/slide.js b/public/js/slide.js
index fe3cb1e8..e45f78a6 100644
--- a/public/js/slide.js
+++ b/public/js/slide.js
@@ -1,6 +1,17 @@
var body = $(".slides").html();
$(".slides").html(S(body).unescapeHTML().s);
+createtime = lastchangeui.time.attr('data-createtime');
+lastchangetime = lastchangeui.time.attr('data-updatetime');
+updateLastChange();
+var url = window.location.pathname;
+$('.ui-edit').attr('href', url + '/edit');
+
+$(document).ready(function () {
+ //tooltip
+ $('[data-toggle="tooltip"]').tooltip();
+});
+
function extend() {
var target = {};
for (var i = 0; i < arguments.length; i++) {
diff --git a/public/vendor/bootstrap/tooltip.min.css b/public/vendor/bootstrap/tooltip.min.css
new file mode 100755
index 00000000..4c1c1caa
--- /dev/null
+++ b/public/vendor/bootstrap/tooltip.min.css
@@ -0,0 +1,14 @@
+/*!
+ * Bootstrap v3.3.7 (http://getbootstrap.com)
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+/*!
+ * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=f461126998f11cadc491b2b443db2a1b)
+ * Config saved to config.json and https://gist.github.com/f461126998f11cadc491b2b443db2a1b
+ *//*!
+ * Bootstrap v3.3.7 (http://getbootstrap.com)
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:hover,a:focus{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role="button"]{cursor:pointer}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height, visibility;-o-transition-property:height, visibility;transition-property:height, visibility;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:12px;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{bottom:0;right:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.clearfix:before,.clearfix:after{content:" ";display:table}.clearfix:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important}.affix{position:fixed} \ No newline at end of file
diff --git a/public/vendor/bootstrap/tooltip.min.js b/public/vendor/bootstrap/tooltip.min.js
new file mode 100755
index 00000000..6968d747
--- /dev/null
+++ b/public/vendor/bootstrap/tooltip.min.js
@@ -0,0 +1,11 @@
+/*!
+ * Bootstrap v3.3.7 (http://getbootstrap.com)
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+/*!
+ * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=9ca9e711ecf93a5859df188c8b394683)
+ * Config saved to config.json and https://gist.github.com/9ca9e711ecf93a5859df188c8b394683
+ */
+if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(t){"use strict";var e=t.fn.jquery.split(" ")[0].split(".");if(e[0]<2&&e[1]<9||1==e[0]&&9==e[1]&&e[2]<1||e[0]>3)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var o=t(this),n=o.data("bs.tooltip"),s="object"==typeof e&&e;!n&&/destroy|hide/.test(e)||(n||o.data("bs.tooltip",n=new i(this,s)),"string"==typeof e&&n[e]())})}var i=function(t,e){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.inState=null,this.init("tooltip",t,e)};i.VERSION="3.3.7",i.TRANSITION_DURATION=150,i.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},i.prototype.init=function(e,i,o){if(this.enabled=!0,this.type=e,this.$element=t(i),this.options=this.getOptions(o),this.$viewport=this.options.viewport&&t(t.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var n=this.options.trigger.split(" "),s=n.length;s--;){var r=n[s];if("click"==r)this.$element.on("click."+this.type,this.options.selector,t.proxy(this.toggle,this));else if("manual"!=r){var a="hover"==r?"mouseenter":"focusin",p="hover"==r?"mouseleave":"focusout";this.$element.on(a+"."+this.type,this.options.selector,t.proxy(this.enter,this)),this.$element.on(p+"."+this.type,this.options.selector,t.proxy(this.leave,this))}}this.options.selector?this._options=t.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},i.prototype.getDefaults=function(){return i.DEFAULTS},i.prototype.getOptions=function(e){return e=t.extend({},this.getDefaults(),this.$element.data(),e),e.delay&&"number"==typeof e.delay&&(e.delay={show:e.delay,hide:e.delay}),e},i.prototype.getDelegateOptions=function(){var e={},i=this.getDefaults();return this._options&&t.each(this._options,function(t,o){i[t]!=o&&(e[t]=o)}),e},i.prototype.enter=function(e){var i=e instanceof this.constructor?e:t(e.currentTarget).data("bs."+this.type);return i||(i=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,i)),e instanceof t.Event&&(i.inState["focusin"==e.type?"focus":"hover"]=!0),i.tip().hasClass("in")||"in"==i.hoverState?void(i.hoverState="in"):(clearTimeout(i.timeout),i.hoverState="in",i.options.delay&&i.options.delay.show?void(i.timeout=setTimeout(function(){"in"==i.hoverState&&i.show()},i.options.delay.show)):i.show())},i.prototype.isInStateTrue=function(){for(var t in this.inState)if(this.inState[t])return!0;return!1},i.prototype.leave=function(e){var i=e instanceof this.constructor?e:t(e.currentTarget).data("bs."+this.type);return i||(i=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,i)),e instanceof t.Event&&(i.inState["focusout"==e.type?"focus":"hover"]=!1),i.isInStateTrue()?void 0:(clearTimeout(i.timeout),i.hoverState="out",i.options.delay&&i.options.delay.hide?void(i.timeout=setTimeout(function(){"out"==i.hoverState&&i.hide()},i.options.delay.hide)):i.hide())},i.prototype.show=function(){var e=t.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(e);var o=t.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(e.isDefaultPrevented()||!o)return;var n=this,s=this.tip(),r=this.getUID(this.type);this.setContent(),s.attr("id",r),this.$element.attr("aria-describedby",r),this.options.animation&&s.addClass("fade");var a="function"==typeof this.options.placement?this.options.placement.call(this,s[0],this.$element[0]):this.options.placement,p=/\s?auto?\s?/i,l=p.test(a);l&&(a=a.replace(p,"")||"top"),s.detach().css({top:0,left:0,display:"block"}).addClass(a).data("bs."+this.type,this),this.options.container?s.appendTo(this.options.container):s.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var h=this.getPosition(),u=s[0].offsetWidth,f=s[0].offsetHeight;if(l){var c=a,d=this.getPosition(this.$viewport);a="bottom"==a&&h.bottom+f>d.bottom?"top":"top"==a&&h.top-f<d.top?"bottom":"right"==a&&h.right+u>d.width?"left":"left"==a&&h.left-u<d.left?"right":a,s.removeClass(c).addClass(a)}var v=this.getCalculatedOffset(a,h,u,f);this.applyPlacement(v,a);var y=function(){var t=n.hoverState;n.$element.trigger("shown.bs."+n.type),n.hoverState=null,"out"==t&&n.leave(n)};t.support.transition&&this.$tip.hasClass("fade")?s.one("bsTransitionEnd",y).emulateTransitionEnd(i.TRANSITION_DURATION):y()}},i.prototype.applyPlacement=function(e,i){var o=this.tip(),n=o[0].offsetWidth,s=o[0].offsetHeight,r=parseInt(o.css("margin-top"),10),a=parseInt(o.css("margin-left"),10);isNaN(r)&&(r=0),isNaN(a)&&(a=0),e.top+=r,e.left+=a,t.offset.setOffset(o[0],t.extend({using:function(t){o.css({top:Math.round(t.top),left:Math.round(t.left)})}},e),0),o.addClass("in");var p=o[0].offsetWidth,l=o[0].offsetHeight;"top"==i&&l!=s&&(e.top=e.top+s-l);var h=this.getViewportAdjustedDelta(i,e,p,l);h.left?e.left+=h.left:e.top+=h.top;var u=/top|bottom/.test(i),f=u?2*h.left-n+p:2*h.top-s+l,c=u?"offsetWidth":"offsetHeight";o.offset(e),this.replaceArrow(f,o[0][c],u)},i.prototype.replaceArrow=function(t,e,i){this.arrow().css(i?"left":"top",50*(1-t/e)+"%").css(i?"top":"left","")},i.prototype.setContent=function(){var t=this.tip(),e=this.getTitle();t.find(".tooltip-inner")[this.options.html?"html":"text"](e),t.removeClass("fade in top bottom left right")},i.prototype.hide=function(e){function o(){"in"!=n.hoverState&&s.detach(),n.$element&&n.$element.removeAttr("aria-describedby").trigger("hidden.bs."+n.type),e&&e()}var n=this,s=t(this.$tip),r=t.Event("hide.bs."+this.type);return this.$element.trigger(r),r.isDefaultPrevented()?void 0:(s.removeClass("in"),t.support.transition&&s.hasClass("fade")?s.one("bsTransitionEnd",o).emulateTransitionEnd(i.TRANSITION_DURATION):o(),this.hoverState=null,this)},i.prototype.fixTitle=function(){var t=this.$element;(t.attr("title")||"string"!=typeof t.attr("data-original-title"))&&t.attr("data-original-title",t.attr("title")||"").attr("title","")},i.prototype.hasContent=function(){return this.getTitle()},i.prototype.getPosition=function(e){e=e||this.$element;var i=e[0],o="BODY"==i.tagName,n=i.getBoundingClientRect();null==n.width&&(n=t.extend({},n,{width:n.right-n.left,height:n.bottom-n.top}));var s=window.SVGElement&&i instanceof window.SVGElement,r=o?{top:0,left:0}:s?null:e.offset(),a={scroll:o?document.documentElement.scrollTop||document.body.scrollTop:e.scrollTop()},p=o?{width:t(window).width(),height:t(window).height()}:null;return t.extend({},n,a,p,r)},i.prototype.getCalculatedOffset=function(t,e,i,o){return"bottom"==t?{top:e.top+e.height,left:e.left+e.width/2-i/2}:"top"==t?{top:e.top-o,left:e.left+e.width/2-i/2}:"left"==t?{top:e.top+e.height/2-o/2,left:e.left-i}:{top:e.top+e.height/2-o/2,left:e.left+e.width}},i.prototype.getViewportAdjustedDelta=function(t,e,i,o){var n={top:0,left:0};if(!this.$viewport)return n;var s=this.options.viewport&&this.options.viewport.padding||0,r=this.getPosition(this.$viewport);if(/right|left/.test(t)){var a=e.top-s-r.scroll,p=e.top+s-r.scroll+o;a<r.top?n.top=r.top-a:p>r.top+r.height&&(n.top=r.top+r.height-p)}else{var l=e.left-s,h=e.left+s+i;l<r.left?n.left=r.left-l:h>r.right&&(n.left=r.left+r.width-h)}return n},i.prototype.getTitle=function(){var t,e=this.$element,i=this.options;return t=e.attr("data-original-title")||("function"==typeof i.title?i.title.call(e[0]):i.title)},i.prototype.getUID=function(t){do t+=~~(1e6*Math.random());while(document.getElementById(t));return t},i.prototype.tip=function(){if(!this.$tip&&(this.$tip=t(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},i.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},i.prototype.enable=function(){this.enabled=!0},i.prototype.disable=function(){this.enabled=!1},i.prototype.toggleEnabled=function(){this.enabled=!this.enabled},i.prototype.toggle=function(e){var i=this;e&&(i=t(e.currentTarget).data("bs."+this.type),i||(i=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,i))),e?(i.inState.click=!i.inState.click,i.isInStateTrue()?i.enter(i):i.leave(i)):i.tip().hasClass("in")?i.leave(i):i.enter(i)},i.prototype.destroy=function(){var t=this;clearTimeout(this.timeout),this.hide(function(){t.$element.off("."+t.type).removeData("bs."+t.type),t.$tip&&t.$tip.detach(),t.$tip=null,t.$arrow=null,t.$viewport=null,t.$element=null})};var o=t.fn.tooltip;t.fn.tooltip=e,t.fn.tooltip.Constructor=i,t.fn.tooltip.noConflict=function(){return t.fn.tooltip=o,this}}(jQuery),+function(t){"use strict";function e(){var t=document.createElement("bootstrap"),e={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var i in e)if(void 0!==t.style[i])return{end:e[i]};return!1}t.fn.emulateTransitionEnd=function(e){var i=!1,o=this;t(this).one("bsTransitionEnd",function(){i=!0});var n=function(){i||t(o).trigger(t.support.transition.end)};return setTimeout(n,e),this},t(function(){t.support.transition=e(),t.support.transition&&(t.event.special.bsTransitionEnd={bindType:t.support.transition.end,delegateType:t.support.transition.end,handle:function(e){return t(e.target).is(this)?e.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery); \ No newline at end of file
diff --git a/public/views/disqus.ejs b/public/views/disqus.ejs
new file mode 100644
index 00000000..ed991a41
--- /dev/null
+++ b/public/views/disqus.ejs
@@ -0,0 +1,14 @@
+<div id="disqus_thread"></div>
+<script>
+var disqus_config = function () {
+ this.page.identifier = window.location.pathname.split('/').slice(-1)[0];
+};
+(function() {
+ var d = document, s = d.createElement('script');
+ s.src = '//<%- disqus %>.disqus.com/embed.js';
+ s.setAttribute('data-timestamp', +new Date());
+ (d.head || d.body).appendChild(s);
+})();
+</script>
+<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
+ \ No newline at end of file
diff --git a/public/views/pretty.ejs b/public/views/pretty.ejs
index 779e7da1..3afb2a1a 100644
--- a/public/views/pretty.ejs
+++ b/public/views/pretty.ejs
@@ -72,6 +72,11 @@
</div>
</div>
<div id="toc-affix" class="ui-affix-toc ui-toc-dropdown unselectable hidden-print" data-spy="affix" style="display:none;"></div>
+ <% if(typeof disqus !== 'undefined' && disqus) { %>
+ <div class="container-fluid" style="max-width: 758px; margin-bottom: 40px;">
+ <%- include disqus %>
+ </div>
+ <% } %>
</body>
</html>
diff --git a/public/views/slide.ejs b/public/views/slide.ejs
index 8a8fbae0..5b728b21 100644
--- a/public/views/slide.ejs
+++ b/public/views/slide.ejs
@@ -23,6 +23,7 @@
<link rel="stylesheet" href="<%- url %>/vendor/Ionicons/css/ionicons.min.css">
<link rel="stylesheet" href="<%- url %>/vendor/octicons/octicons/octicons.css">
<% } %>
+ <link rel="stylesheet" href='<%- url %>/vendor/bootstrap/tooltip.min.css'>
<link rel="stylesheet" href="<%- url %>/vendor/reveal.js/css/reveal.css">
<link rel="stylesheet" href="<%- url %>/vendor/reveal.js/css/theme/black.css" id="theme">
@@ -52,6 +53,28 @@
<div id="meta" style="display: none;"><%- meta %></div>
+ <div class="footer">
+ <div class="unselectable hidden-print" style="color: #777;">
+ <small>
+ <span>
+ <% if(lastchangeuserprofile) { %>
+ <span class="ui-lastchangeuser">&thinsp;<i class="ui-user-icon small" style="background-image: url(<%- lastchangeuserprofile.photo %>);" data-toggle="tooltip" data-placement="right" title="<%- lastchangeuserprofile.name %>"></i></span>
+ <% } else { %>
+ <span class="ui-no-lastchangeuser">&thinsp;<i class="fa fa-clock-o"></i></span>
+ <% } %>
+ &nbsp;<span class="text-uppercase ui-status-lastchange"></span>
+ <span class="ui-lastchange text-uppercase" data-createtime="<%- createtime %>" data-updatetime="<%- updatetime %>"></span>
+ </span>
+ <span class="pull-right"><%- viewcount %> views <a href="#" class="ui-edit" title="Edit this note"><i class="fa fa-fw fa-pencil"></i></a></span>
+ </small>
+ </div>
+ <% if(typeof disqus !== 'undefined' && disqus) { %>
+ <div style="margin-top: 25px; margin-bottom: 15px;">
+ <%- include disqus %>
+ </div>
+ <% } %>
+ </div>
+
<script type="text/x-mathjax-config">
MathJax.Hub.Config({ messageStyle: "none", skipStartupTypeset: true ,tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']], processEscapes: true }});
</script>
@@ -70,6 +93,7 @@
<script src="<%- url %>/vendor/moment/min/moment-with-locales.js" defer></script>
<script src="<%- url %>/vendor/mermaid/dist/mermaid.min.js" defer></script>
<% } %>
+ <script src="<%- url %>/vendor/bootstrap/tooltip.min.js"></script>
<script src="<%- url %>/vendor/reveal.js/lib/js/head.min.js"></script>
<script src="<%- url %>/vendor/reveal.js/js/reveal.js"></script>
<script src="<%- url %>/vendor/xss/dist/xss.min.js" defer></script>