diff --git a/app.js b/app.js index 98b2b9834..54a6baac2 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 81013047b..d1c073e9b 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 old mode 100644 new mode 100755 index 23818da85..39d83ca29 --- 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 df04fae11..bccb7e42e 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 d22fccda7..7158104b5 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 fe3cb1e8b..e45f78a65 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 000000000..4c1c1caab --- /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 000000000..6968d747d --- /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:'