From 695293145193ed84b7ef193b538bb144ecb2832e Mon Sep 17 00:00:00 2001 From: Riceball LEE Date: Tue, 10 Nov 2015 21:40:46 +0000 Subject: [PATCH 01/69] * update marked.js version to 0.3.5 --- plugin/markdown/marked.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/markdown/marked.js b/plugin/markdown/marked.js index 70af29b..555c1dc 100644 --- a/plugin/markdown/marked.js +++ b/plugin/markdown/marked.js @@ -3,4 +3,4 @@ * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed) * https://github.com/chjj/marked */ -(function(){function e(e){this.tokens=[],this.tokens.links={},this.options=e||a.defaults,this.rules=p.normal,this.options.gfm&&(this.rules=this.options.tables?p.tables:p.gfm)}function t(e,t){if(this.options=t||a.defaults,this.links=e,this.rules=u.normal,this.renderer=this.options.renderer||new n,this.renderer.options=this.options,!this.links)throw new Error("Tokens array requires a `links` property.");this.options.gfm?this.rules=this.options.breaks?u.breaks:u.gfm:this.options.pedantic&&(this.rules=u.pedantic)}function n(e){this.options=e||{}}function r(e){this.tokens=[],this.token=null,this.options=e||a.defaults,this.options.renderer=this.options.renderer||new n,this.renderer=this.options.renderer,this.renderer.options=this.options}function s(e,t){return e.replace(t?/&/g:/&(?!#?\w+;)/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}function i(e){return e.replace(/&([#\w]+);/g,function(e,t){return t=t.toLowerCase(),"colon"===t?":":"#"===t.charAt(0)?String.fromCharCode("x"===t.charAt(1)?parseInt(t.substring(2),16):+t.substring(1)):""})}function l(e,t){return e=e.source,t=t||"",function n(r,s){return r?(s=s.source||s,s=s.replace(/(^|[^\[])\^/g,"$1"),e=e.replace(r,s),n):new RegExp(e,t)}}function o(){}function h(e){for(var t,n,r=1;rAn error occured:

"+s(c.message+"",!0)+"
";throw c}}var p={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:o,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,nptable:o,lheading:/^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,blockquote:/^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,def:/^ *\[([^\]]+)\]: *]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:o,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,text:/^[^\n]+/};p.bullet=/(?:[*+-]|\d+\.)/,p.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/,p.item=l(p.item,"gm")(/bull/g,p.bullet)(),p.list=l(p.list)(/bull/g,p.bullet)("hr","\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))")("def","\\n+(?="+p.def.source+")")(),p.blockquote=l(p.blockquote)("def",p.def)(),p._tag="(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b",p.html=l(p.html)("comment",//)("closed",/<(tag)[\s\S]+?<\/\1>/)("closing",/])*?>/)(/tag/g,p._tag)(),p.paragraph=l(p.paragraph)("hr",p.hr)("heading",p.heading)("lheading",p.lheading)("blockquote",p.blockquote)("tag","<"+p._tag)("def",p.def)(),p.normal=h({},p),p.gfm=h({},p.normal,{fences:/^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/,paragraph:/^/}),p.gfm.paragraph=l(p.paragraph)("(?!","(?!"+p.gfm.fences.source.replace("\\1","\\2")+"|"+p.list.source.replace("\\1","\\3")+"|")(),p.tables=h({},p.gfm,{nptable:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/}),e.rules=p,e.lex=function(t,n){var r=new e(n);return r.lex(t)},e.prototype.lex=function(e){return e=e.replace(/\r\n|\r/g,"\n").replace(/\t/g," ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n"),this.token(e,!0)},e.prototype.token=function(e,t,n){for(var r,s,i,l,o,h,a,u,c,e=e.replace(/^ +$/gm,"");e;)if((i=this.rules.newline.exec(e))&&(e=e.substring(i[0].length),i[0].length>1&&this.tokens.push({type:"space"})),i=this.rules.code.exec(e))e=e.substring(i[0].length),i=i[0].replace(/^ {4}/gm,""),this.tokens.push({type:"code",text:this.options.pedantic?i:i.replace(/\n+$/,"")});else if(i=this.rules.fences.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"code",lang:i[2],text:i[3]});else if(i=this.rules.heading.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"heading",depth:i[1].length,text:i[2]});else if(t&&(i=this.rules.nptable.exec(e))){for(e=e.substring(i[0].length),h={type:"table",header:i[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:i[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:i[3].replace(/\n$/,"").split("\n")},u=0;u ?/gm,""),this.token(i,t,!0),this.tokens.push({type:"blockquote_end"});else if(i=this.rules.list.exec(e)){for(e=e.substring(i[0].length),l=i[2],this.tokens.push({type:"list_start",ordered:l.length>1}),i=i[0].match(this.rules.item),r=!1,c=i.length,u=0;c>u;u++)h=i[u],a=h.length,h=h.replace(/^ *([*+-]|\d+\.) +/,""),~h.indexOf("\n ")&&(a-=h.length,h=this.options.pedantic?h.replace(/^ {1,4}/gm,""):h.replace(new RegExp("^ {1,"+a+"}","gm"),"")),this.options.smartLists&&u!==c-1&&(o=p.bullet.exec(i[u+1])[0],l===o||l.length>1&&o.length>1||(e=i.slice(u+1).join("\n")+e,u=c-1)),s=r||/\n\n(?!\s*$)/.test(h),u!==c-1&&(r="\n"===h.charAt(h.length-1),s||(s=r)),this.tokens.push({type:s?"loose_item_start":"list_item_start"}),this.token(h,!1,n),this.tokens.push({type:"list_item_end"});this.tokens.push({type:"list_end"})}else if(i=this.rules.html.exec(e))e=e.substring(i[0].length),this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:"pre"===i[1]||"script"===i[1]||"style"===i[1],text:i[0]});else if(!n&&t&&(i=this.rules.def.exec(e)))e=e.substring(i[0].length),this.tokens.links[i[1].toLowerCase()]={href:i[2],title:i[3]};else if(t&&(i=this.rules.table.exec(e))){for(e=e.substring(i[0].length),h={type:"table",header:i[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:i[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:i[3].replace(/(?: *\| *)?\n$/,"").split("\n")},u=0;u])/,autolink:/^<([^ >]+(@|:\/)[^ >]+)>/,url:o,tag:/^|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,em:/^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,code:/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:o,text:/^[\s\S]+?(?=[\\?(?:\s+['"]([\s\S]*?)['"])?\s*/,u.link=l(u.link)("inside",u._inside)("href",u._href)(),u.reflink=l(u.reflink)("inside",u._inside)(),u.normal=h({},u),u.pedantic=h({},u.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/}),u.gfm=h({},u.normal,{escape:l(u.escape)("])","~|])")(),url:/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:l(u.text)("]|","~]|")("|","|https?://|")()}),u.breaks=h({},u.gfm,{br:l(u.br)("{2,}","*")(),text:l(u.gfm.text)("{2,}","*")()}),t.rules=u,t.output=function(e,n,r){var s=new t(n,r);return s.output(e)},t.prototype.output=function(e){for(var t,n,r,i,l="";e;)if(i=this.rules.escape.exec(e))e=e.substring(i[0].length),l+=i[1];else if(i=this.rules.autolink.exec(e))e=e.substring(i[0].length),"@"===i[2]?(n=this.mangle(":"===i[1].charAt(6)?i[1].substring(7):i[1]),r=this.mangle("mailto:")+n):(n=s(i[1]),r=n),l+=this.renderer.link(r,null,n);else if(this.inLink||!(i=this.rules.url.exec(e))){if(i=this.rules.tag.exec(e))!this.inLink&&/^/i.test(i[0])&&(this.inLink=!1),e=e.substring(i[0].length),l+=this.options.sanitize?s(i[0]):i[0];else if(i=this.rules.link.exec(e))e=e.substring(i[0].length),this.inLink=!0,l+=this.outputLink(i,{href:i[2],title:i[3]}),this.inLink=!1;else if((i=this.rules.reflink.exec(e))||(i=this.rules.nolink.exec(e))){if(e=e.substring(i[0].length),t=(i[2]||i[1]).replace(/\s+/g," "),t=this.links[t.toLowerCase()],!t||!t.href){l+=i[0].charAt(0),e=i[0].substring(1)+e;continue}this.inLink=!0,l+=this.outputLink(i,t),this.inLink=!1}else if(i=this.rules.strong.exec(e))e=e.substring(i[0].length),l+=this.renderer.strong(this.output(i[2]||i[1]));else if(i=this.rules.em.exec(e))e=e.substring(i[0].length),l+=this.renderer.em(this.output(i[2]||i[1]));else if(i=this.rules.code.exec(e))e=e.substring(i[0].length),l+=this.renderer.codespan(s(i[2],!0));else if(i=this.rules.br.exec(e))e=e.substring(i[0].length),l+=this.renderer.br();else if(i=this.rules.del.exec(e))e=e.substring(i[0].length),l+=this.renderer.del(this.output(i[1]));else if(i=this.rules.text.exec(e))e=e.substring(i[0].length),l+=s(this.smartypants(i[0]));else if(e)throw new Error("Infinite loop on byte: "+e.charCodeAt(0))}else e=e.substring(i[0].length),n=s(i[1]),r=n,l+=this.renderer.link(r,null,n);return l},t.prototype.outputLink=function(e,t){var n=s(t.href),r=t.title?s(t.title):null;return"!"!==e[0].charAt(0)?this.renderer.link(n,r,this.output(e[1])):this.renderer.image(n,r,s(e[1]))},t.prototype.smartypants=function(e){return this.options.smartypants?e.replace(/--/g,"—").replace(/(^|[-\u2014/(\[{"\s])'/g,"$1‘").replace(/'/g,"’").replace(/(^|[-\u2014/(\[{\u2018\s])"/g,"$1“").replace(/"/g,"”").replace(/\.{3}/g,"…"):e},t.prototype.mangle=function(e){for(var t,n="",r=e.length,s=0;r>s;s++)t=e.charCodeAt(s),Math.random()>.5&&(t="x"+t.toString(16)),n+="&#"+t+";";return n},n.prototype.code=function(e,t,n){if(this.options.highlight){var r=this.options.highlight(e,t);null!=r&&r!==e&&(n=!0,e=r)}return t?'
'+(n?e:s(e,!0))+"\n
\n":"
"+(n?e:s(e,!0))+"\n
"},n.prototype.blockquote=function(e){return"
\n"+e+"
\n"},n.prototype.html=function(e){return e},n.prototype.heading=function(e,t,n){return"'+e+"\n"},n.prototype.hr=function(){return this.options.xhtml?"
\n":"
\n"},n.prototype.list=function(e,t){var n=t?"ol":"ul";return"<"+n+">\n"+e+"\n"},n.prototype.listitem=function(e){return"
  • "+e+"
  • \n"},n.prototype.paragraph=function(e){return"

    "+e+"

    \n"},n.prototype.table=function(e,t){return"\n\n"+e+"\n\n"+t+"\n
    \n"},n.prototype.tablerow=function(e){return"\n"+e+"\n"},n.prototype.tablecell=function(e,t){var n=t.header?"th":"td",r=t.align?"<"+n+' style="text-align:'+t.align+'">':"<"+n+">";return r+e+"\n"},n.prototype.strong=function(e){return""+e+""},n.prototype.em=function(e){return""+e+""},n.prototype.codespan=function(e){return""+e+""},n.prototype.br=function(){return this.options.xhtml?"
    ":"
    "},n.prototype.del=function(e){return""+e+""},n.prototype.link=function(e,t,n){if(this.options.sanitize){try{var r=decodeURIComponent(i(e)).replace(/[^\w:]/g,"").toLowerCase()}catch(s){return""}if(0===r.indexOf("javascript:")||0===r.indexOf("vbscript:"))return""}var l='
    "},n.prototype.image=function(e,t,n){var r=''+n+'":">"},r.parse=function(e,t,n){var s=new r(t,n);return s.parse(e)},r.prototype.parse=function(e){this.inline=new t(e.links,this.options,this.renderer),this.tokens=e.reverse();for(var n="";this.next();)n+=this.tok();return n},r.prototype.next=function(){return this.token=this.tokens.pop()},r.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0},r.prototype.parseText=function(){for(var e=this.token.text;"text"===this.peek().type;)e+="\n"+this.next().text;return this.inline.output(e)},r.prototype.tok=function(){switch(this.token.type){case"space":return"";case"hr":return this.renderer.hr();case"heading":return this.renderer.heading(this.inline.output(this.token.text),this.token.depth,this.token.text);case"code":return this.renderer.code(this.token.text,this.token.lang,this.token.escaped);case"table":var e,t,n,r,s,i="",l="";for(n="",e=0;e[^\n]+(\n(?!def)[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,def:/^ *\[([^\]]+)\]: *]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:noop,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,text:/^[^\n]+/};block.bullet=/(?:[*+-]|\d+\.)/;block.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;block.item=replace(block.item,"gm")(/bull/g,block.bullet)();block.list=replace(block.list)(/bull/g,block.bullet)("hr","\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))")("def","\\n+(?="+block.def.source+")")();block.blockquote=replace(block.blockquote)("def",block.def)();block._tag="(?!(?:"+"a|em|strong|small|s|cite|q|dfn|abbr|data|time|code"+"|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo"+"|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b";block.html=replace(block.html)("comment",//)("closed",/<(tag)[\s\S]+?<\/\1>/)("closing",/])*?>/)(/tag/g,block._tag)();block.paragraph=replace(block.paragraph)("hr",block.hr)("heading",block.heading)("lheading",block.lheading)("blockquote",block.blockquote)("tag","<"+block._tag)("def",block.def)();block.normal=merge({},block);block.gfm=merge({},block.normal,{fences:/^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,paragraph:/^/,heading:/^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/});block.gfm.paragraph=replace(block.paragraph)("(?!","(?!"+block.gfm.fences.source.replace("\\1","\\2")+"|"+block.list.source.replace("\\1","\\3")+"|")();block.tables=merge({},block.gfm,{nptable:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/});function Lexer(options){this.tokens=[];this.tokens.links={};this.options=options||marked.defaults;this.rules=block.normal;if(this.options.gfm){if(this.options.tables){this.rules=block.tables}else{this.rules=block.gfm}}}Lexer.rules=block;Lexer.lex=function(src,options){var lexer=new Lexer(options);return lexer.lex(src)};Lexer.prototype.lex=function(src){src=src.replace(/\r\n|\r/g,"\n").replace(/\t/g," ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n");return this.token(src,true)};Lexer.prototype.token=function(src,top,bq){var src=src.replace(/^ +$/gm,""),next,loose,cap,bull,b,item,space,i,l;while(src){if(cap=this.rules.newline.exec(src)){src=src.substring(cap[0].length);if(cap[0].length>1){this.tokens.push({type:"space"})}}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);cap=cap[0].replace(/^ {4}/gm,"");this.tokens.push({type:"code",text:!this.options.pedantic?cap.replace(/\n+$/,""):cap});continue}if(cap=this.rules.fences.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"code",lang:cap[2],text:cap[3]||""});continue}if(cap=this.rules.heading.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[1].length,text:cap[2]});continue}if(top&&(cap=this.rules.nptable.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/\n$/,"").split("\n")};for(i=0;i ?/gm,"");this.token(cap,top,true);this.tokens.push({type:"blockquote_end"});continue}if(cap=this.rules.list.exec(src)){src=src.substring(cap[0].length);bull=cap[2];this.tokens.push({type:"list_start",ordered:bull.length>1});cap=cap[0].match(this.rules.item);next=false;l=cap.length;i=0;for(;i1&&b.length>1)){src=cap.slice(i+1).join("\n")+src;i=l-1}}loose=next||/\n\n(?!\s*$)/.test(item);if(i!==l-1){next=item.charAt(item.length-1)==="\n";if(!loose)loose=next}this.tokens.push({type:loose?"loose_item_start":"list_item_start"});this.token(item,false,bq);this.tokens.push({type:"list_item_end"})}this.tokens.push({type:"list_end"});continue}if(cap=this.rules.html.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:!this.options.sanitizer&&(cap[1]==="pre"||cap[1]==="script"||cap[1]==="style"),text:cap[0]});continue}if(!bq&&top&&(cap=this.rules.def.exec(src))){src=src.substring(cap[0].length);this.tokens.links[cap[1].toLowerCase()]={href:cap[2],title:cap[3]};continue}if(top&&(cap=this.rules.table.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/(?: *\| *)?\n$/,"").split("\n")};for(i=0;i])/,autolink:/^<([^ >]+(@|:\/)[^ >]+)>/,url:noop,tag:/^|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,em:/^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,code:/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:noop,text:/^[\s\S]+?(?=[\\?(?:\s+['"]([\s\S]*?)['"])?\s*/;inline.link=replace(inline.link)("inside",inline._inside)("href",inline._href)();inline.reflink=replace(inline.reflink)("inside",inline._inside)();inline.normal=merge({},inline);inline.pedantic=merge({},inline.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/});inline.gfm=merge({},inline.normal,{escape:replace(inline.escape)("])","~|])")(),url:/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:replace(inline.text)("]|","~]|")("|","|https?://|")()});inline.breaks=merge({},inline.gfm,{br:replace(inline.br)("{2,}","*")(),text:replace(inline.gfm.text)("{2,}","*")()});function InlineLexer(links,options){this.options=options||marked.defaults;this.links=links;this.rules=inline.normal;this.renderer=this.options.renderer||new Renderer;this.renderer.options=this.options;if(!this.links){throw new Error("Tokens array requires a `links` property.")}if(this.options.gfm){if(this.options.breaks){this.rules=inline.breaks}else{this.rules=inline.gfm}}else if(this.options.pedantic){this.rules=inline.pedantic}}InlineLexer.rules=inline;InlineLexer.output=function(src,links,options){var inline=new InlineLexer(links,options);return inline.output(src)};InlineLexer.prototype.output=function(src){var out="",link,text,href,cap;while(src){if(cap=this.rules.escape.exec(src)){src=src.substring(cap[0].length);out+=cap[1];continue}if(cap=this.rules.autolink.exec(src)){src=src.substring(cap[0].length);if(cap[2]==="@"){text=cap[1].charAt(6)===":"?this.mangle(cap[1].substring(7)):this.mangle(cap[1]);href=this.mangle("mailto:")+text}else{text=escape(cap[1]);href=text}out+=this.renderer.link(href,null,text);continue}if(!this.inLink&&(cap=this.rules.url.exec(src))){src=src.substring(cap[0].length);text=escape(cap[1]);href=text;out+=this.renderer.link(href,null,text);continue}if(cap=this.rules.tag.exec(src)){if(!this.inLink&&/^/i.test(cap[0])){this.inLink=false}src=src.substring(cap[0].length);out+=this.options.sanitize?this.options.sanitizer?this.options.sanitizer(cap[0]):escape(cap[0]):cap[0];continue}if(cap=this.rules.link.exec(src)){src=src.substring(cap[0].length);this.inLink=true;out+=this.outputLink(cap,{href:cap[2],title:cap[3]});this.inLink=false;continue}if((cap=this.rules.reflink.exec(src))||(cap=this.rules.nolink.exec(src))){src=src.substring(cap[0].length);link=(cap[2]||cap[1]).replace(/\s+/g," ");link=this.links[link.toLowerCase()];if(!link||!link.href){out+=cap[0].charAt(0);src=cap[0].substring(1)+src;continue}this.inLink=true;out+=this.outputLink(cap,link);this.inLink=false;continue}if(cap=this.rules.strong.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.strong(this.output(cap[2]||cap[1]));continue}if(cap=this.rules.em.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.em(this.output(cap[2]||cap[1]));continue}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.codespan(escape(cap[2],true));continue}if(cap=this.rules.br.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.br();continue}if(cap=this.rules.del.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.del(this.output(cap[1]));continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.text(escape(this.smartypants(cap[0])));continue}if(src){throw new Error("Infinite loop on byte: "+src.charCodeAt(0))}}return out};InlineLexer.prototype.outputLink=function(cap,link){var href=escape(link.href),title=link.title?escape(link.title):null;return cap[0].charAt(0)!=="!"?this.renderer.link(href,title,this.output(cap[1])):this.renderer.image(href,title,escape(cap[1]))};InlineLexer.prototype.smartypants=function(text){if(!this.options.smartypants)return text;return text.replace(/---/g,"—").replace(/--/g,"–").replace(/(^|[-\u2014/(\[{"\s])'/g,"$1‘").replace(/'/g,"’").replace(/(^|[-\u2014/(\[{\u2018\s])"/g,"$1“").replace(/"/g,"”").replace(/\.{3}/g,"…")};InlineLexer.prototype.mangle=function(text){if(!this.options.mangle)return text;var out="",l=text.length,i=0,ch;for(;i.5){ch="x"+ch.toString(16)}out+="&#"+ch+";"}return out};function Renderer(options){this.options=options||{}}Renderer.prototype.code=function(code,lang,escaped){if(this.options.highlight){var out=this.options.highlight(code,lang);if(out!=null&&out!==code){escaped=true;code=out}}if(!lang){return"
    "+(escaped?code:escape(code,true))+"\n
    "}return'
    '+(escaped?code:escape(code,true))+"\n
    \n"};Renderer.prototype.blockquote=function(quote){return"
    \n"+quote+"
    \n"};Renderer.prototype.html=function(html){return html};Renderer.prototype.heading=function(text,level,raw){return"'+text+"\n"};Renderer.prototype.hr=function(){return this.options.xhtml?"
    \n":"
    \n"};Renderer.prototype.list=function(body,ordered){var type=ordered?"ol":"ul";return"<"+type+">\n"+body+"\n"};Renderer.prototype.listitem=function(text){return"
  • "+text+"
  • \n"};Renderer.prototype.paragraph=function(text){return"

    "+text+"

    \n"};Renderer.prototype.table=function(header,body){return"\n"+"\n"+header+"\n"+"\n"+body+"\n"+"
    \n"};Renderer.prototype.tablerow=function(content){return"\n"+content+"\n"};Renderer.prototype.tablecell=function(content,flags){var type=flags.header?"th":"td";var tag=flags.align?"<"+type+' style="text-align:'+flags.align+'">':"<"+type+">";return tag+content+"\n"};Renderer.prototype.strong=function(text){return""+text+""};Renderer.prototype.em=function(text){return""+text+""};Renderer.prototype.codespan=function(text){return""+text+""};Renderer.prototype.br=function(){return this.options.xhtml?"
    ":"
    "};Renderer.prototype.del=function(text){return""+text+""};Renderer.prototype.link=function(href,title,text){if(this.options.sanitize){try{var prot=decodeURIComponent(unescape(href)).replace(/[^\w:]/g,"").toLowerCase()}catch(e){return""}if(prot.indexOf("javascript:")===0||prot.indexOf("vbscript:")===0){return""}}var out='
    ";return out};Renderer.prototype.image=function(href,title,text){var out=''+text+'":">";return out};Renderer.prototype.text=function(text){return text};function Parser(options){this.tokens=[];this.token=null;this.options=options||marked.defaults;this.options.renderer=this.options.renderer||new Renderer;this.renderer=this.options.renderer;this.renderer.options=this.options}Parser.parse=function(src,options,renderer){var parser=new Parser(options,renderer);return parser.parse(src)};Parser.prototype.parse=function(src){this.inline=new InlineLexer(src.links,this.options,this.renderer);this.tokens=src.reverse();var out="";while(this.next()){out+=this.tok()}return out};Parser.prototype.next=function(){return this.token=this.tokens.pop()};Parser.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0};Parser.prototype.parseText=function(){var body=this.token.text;while(this.peek().type==="text"){body+="\n"+this.next().text}return this.inline.output(body)};Parser.prototype.tok=function(){switch(this.token.type){case"space":{return""}case"hr":{return this.renderer.hr()}case"heading":{return this.renderer.heading(this.inline.output(this.token.text),this.token.depth,this.token.text)}case"code":{return this.renderer.code(this.token.text,this.token.lang,this.token.escaped)}case"table":{var header="",body="",i,row,cell,flags,j;cell="";for(i=0;i/g,">").replace(/"/g,""").replace(/'/g,"'")}function unescape(html){return html.replace(/&([#\w]+);/g,function(_,n){n=n.toLowerCase();if(n==="colon")return":";if(n.charAt(0)==="#"){return n.charAt(1)==="x"?String.fromCharCode(parseInt(n.substring(2),16)):String.fromCharCode(+n.substring(1))}return""})}function replace(regex,opt){regex=regex.source;opt=opt||"";return function self(name,val){if(!name)return new RegExp(regex,opt);val=val.source||val;val=val.replace(/(^|[^\[])\^/g,"$1");regex=regex.replace(name,val);return self}}function noop(){}noop.exec=noop;function merge(obj){var i=1,target,key;for(;iAn error occured:

    "+escape(e.message+"",true)+"
    "}throw e}}marked.options=marked.setOptions=function(opt){merge(marked.defaults,opt);return marked};marked.defaults={gfm:true,tables:true,breaks:false,pedantic:false,sanitize:false,sanitizer:null,mangle:true,smartLists:false,silent:false,highlight:null,langPrefix:"lang-",smartypants:false,headerPrefix:"",renderer:new Renderer,xhtml:false};marked.Parser=Parser;marked.parser=Parser.parse;marked.Renderer=Renderer;marked.Lexer=Lexer;marked.lexer=Lexer.lex;marked.InlineLexer=InlineLexer;marked.inlineLexer=InlineLexer.output;marked.parse=marked;if(typeof module!=="undefined"&&typeof exports==="object"){module.exports=marked}else if(typeof define==="function"&&define.amd){define(function(){return marked})}else{this.marked=marked}}).call(function(){return this||(typeof window!=="undefined"?window:global)}()); \ No newline at end of file From 16ebf2a783724527faac2036bc2f971df8dea0a5 Mon Sep 17 00:00:00 2001 From: Riceball LEE Date: Wed, 11 Nov 2015 07:37:08 +0000 Subject: [PATCH 02/69] * [bug] the markdown plugin can not render highlight codes for marked.setOptions(highlight) --- plugin/markdown/markdown.js | 4 ++-- test/simple.md | 10 +++++++++ test/test-markdown-external.html | 36 ++++++++++++++++++++++++++++++++ test/test-markdown-external.js | 19 +++++++++++++++++ 4 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 test/simple.md create mode 100644 test/test-markdown-external.html create mode 100644 test/test-markdown-external.js diff --git a/plugin/markdown/markdown.js b/plugin/markdown/markdown.js index f4035e2..5544599 100755 --- a/plugin/markdown/markdown.js +++ b/plugin/markdown/markdown.js @@ -20,8 +20,8 @@ if( typeof hljs !== 'undefined' ) { marked.setOptions({ - highlight: function( lang, code ) { - return hljs.highlightAuto( lang, code ).value; + highlight: function( code, lang ) { + return hljs.highlightAuto( code, [lang] ).value; } }); } diff --git a/test/simple.md b/test/simple.md new file mode 100644 index 0000000..cd57d70 --- /dev/null +++ b/test/simple.md @@ -0,0 +1,10 @@ +## Slide 1.1 + +```js +var a = 1; +``` + +## Slide 1.2 + + +## Slide 2 diff --git a/test/test-markdown-external.html b/test/test-markdown-external.html new file mode 100644 index 0000000..859d0a1 --- /dev/null +++ b/test/test-markdown-external.html @@ -0,0 +1,36 @@ + + + + + + + reveal.js - Test Markdown + + + + + + + +
    +
    + + + + + + + + + + + + + + diff --git a/test/test-markdown-external.js b/test/test-markdown-external.js new file mode 100644 index 0000000..a9ea034 --- /dev/null +++ b/test/test-markdown-external.js @@ -0,0 +1,19 @@ + + +Reveal.addEventListener( 'ready', function() { + + QUnit.module( 'Markdown' ); + + test( 'Vertical separator', function() { + strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 2, 'found two slides' ); + }); + test( 'language highlighter', function() { + strictEqual( document.querySelectorAll( '.hljs-keyword' ).length, 1, 'got rendered highlight tag.' ); + strictEqual( document.querySelector( '.hljs-keyword' ).innerHTML, 'var', 'the same keyword: var.' ); + }); + + +} ); + +Reveal.initialize(); + From 7621e1085d6389b214f244ac3e3ddb78c381d1c8 Mon Sep 17 00:00:00 2001 From: Bjoern Kimminich Date: Fri, 8 Jan 2016 10:46:28 +0100 Subject: [PATCH 03/69] added retire.js to build process -allows security vulnerability check in used npm-dependencies and own scripts -execute with ```grunt retire``` --- Gruntfile.js | 10 +++++++++- package.json | 3 ++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index f6c71e2..11bd42b 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -134,7 +134,14 @@ module.exports = function(grunt) { markdown: { files: [ './*.md' ] } - } + }, + + retire: { + js: ['js/reveal.js', 'lib/js/*.js', 'plugin/**/*.js'], + node: ['.'], + options: { + } + } }); @@ -148,6 +155,7 @@ module.exports = function(grunt) { grunt.loadNpmTasks( 'grunt-contrib-connect' ); grunt.loadNpmTasks( 'grunt-autoprefixer' ); grunt.loadNpmTasks( 'grunt-zip' ); + grunt.loadNpmTasks('grunt-retire'); // Default task grunt.registerTask( 'default', [ 'css', 'js' ] ); diff --git a/package.json b/package.json index f7035aa..b75bb90 100644 --- a/package.json +++ b/package.json @@ -36,10 +36,11 @@ "grunt-sass": "~1.1.0-beta", "grunt-contrib-connect": "~0.11.2", "grunt-autoprefixer": "~3.0.3", + "grunt-retire": "~0.3.10", "grunt-zip": "~0.17.1", "grunt": "~0.4.5", "node-sass": "~3.3.3" }, - + "license": "MIT" } From 587d16ceef9e8f11230d6f183b483388075d3609 Mon Sep 17 00:00:00 2001 From: Dhyego Fernando Date: Thu, 10 Mar 2016 13:50:35 -0400 Subject: [PATCH 04/69] fix(PDF Export): Mark as important `width`, `height` and add `zoom` properties to fix CSS rules which were overrided by inline styles --- css/print/pdf.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/css/print/pdf.css b/css/print/pdf.css index 9ed90d6..e4a1b7d 100644 --- a/css/print/pdf.css +++ b/css/print/pdf.css @@ -60,8 +60,9 @@ ul, ol, div, p { } .reveal .slides { position: static; - width: 100%; - height: auto; + width: 100% !important; + height: auto !important; + zoom: 1 !important; left: auto; top: auto; @@ -157,4 +158,3 @@ ul, ol, div, p { position: absolute; font-size: 14px; } - From a9566dfbd48741b4566b4bdbe07c1222dd48771f Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Thu, 24 Mar 2016 16:23:12 +0100 Subject: [PATCH 05/69] make theme "simple" use white titles on dark backgrounds This is similar to what is done in the "white" theme. --- css/theme/simple.css | 3 +++ css/theme/source/simple.scss | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/css/theme/simple.css b/css/theme/simple.css index b17fa5c..8b48be1 100644 --- a/css/theme/simple.css +++ b/css/theme/simple.css @@ -7,6 +7,9 @@ */ @import url(https://fonts.googleapis.com/css?family=News+Cycle:400,700); @import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); +section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 { + color: #fff; } + /********************************************* * GLOBAL STYLES *********************************************/ diff --git a/css/theme/source/simple.scss b/css/theme/source/simple.scss index 84c7d9b..394c9cd 100644 --- a/css/theme/source/simple.scss +++ b/css/theme/source/simple.scss @@ -31,6 +31,11 @@ $linkColor: #00008B; $linkColorHover: lighten( $linkColor, 20% ); $selectionBackgroundColor: rgba(0, 0, 0, 0.99); +section.has-dark-background { + &, h1, h2, h3, h4, h5, h6 { + color: #fff; + } +} // Theme template ------------------------------ From a0e6da6a9cf4372c20230e1c7e076375539bd8d5 Mon Sep 17 00:00:00 2001 From: Jess Telford Date: Fri, 22 Apr 2016 08:18:20 +1000 Subject: [PATCH 06/69] More natural zooming on block level elements Switching a `display: block` element to `display: inline-block` allows calculating the bounds based on the contents of the div rather than the entire container (which is often `width: 100%`). This provides a much more natural zoom, especially for paragraphs and code examples. --- plugin/zoom-js/zoom.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/plugin/zoom-js/zoom.js b/plugin/zoom-js/zoom.js index 95093e0..efccad6 100644 --- a/plugin/zoom-js/zoom.js +++ b/plugin/zoom-js/zoom.js @@ -11,7 +11,17 @@ if( event[ modifier ] && isEnabled ) { event.preventDefault(); - var bounds = event.target.getBoundingClientRect(); + var bounds; + var originalDisplay = event.target.style.display; + + // Get the bounding rect of the contents, not the containing box + if (window.getComputedStyle(event.target).display === 'block') { + event.target.style.display = 'inline-block'; + bounds = event.target.getBoundingClientRect(); + event.target.style.display = originalDisplay; + } else { + bounds = event.target.getBoundingClientRect(); + } zoom.to({ x: ( bounds.left * revealScale ) - zoomPadding, From 66c4e6a77fed49cf970ac306b50320f409abbc6b Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Wed, 27 Apr 2016 11:12:16 +0200 Subject: [PATCH 07/69] use scrollHeight instead of custom measurement --- js/reveal.js | 45 ++++----------------------------------------- 1 file changed, 4 insertions(+), 41 deletions(-) diff --git a/js/reveal.js b/js/reveal.js index 10c609e..8975504 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -589,7 +589,7 @@ var left = ( pageWidth - slideWidth ) / 2, top = ( pageHeight - slideHeight ) / 2; - var contentHeight = getAbsoluteHeight( slide ); + var contentHeight = slide.scrollHeight; var numberOfPages = Math.max( Math.ceil( contentHeight / pageHeight ), 1 ); // Center slides vertically @@ -1290,41 +1290,6 @@ } - /** - * Retrieves the height of the given element by looking - * at the position and height of its immediate children. - */ - function getAbsoluteHeight( element ) { - - var height = 0; - - if( element ) { - var absoluteChildren = 0; - - toArray( element.childNodes ).forEach( function( child ) { - - if( typeof child.offsetTop === 'number' && child.style ) { - // Count # of abs children - if( window.getComputedStyle( child ).position === 'absolute' ) { - absoluteChildren += 1; - } - - height = Math.max( height, child.offsetTop + child.offsetHeight ); - } - - } ); - - // If there are no absolute children, use offsetHeight - if( absoluteChildren === 0 ) { - height = element.offsetHeight; - } - - } - - return height; - - } - /** * Returns the remaining height within the parent of the * target element. @@ -1589,10 +1554,8 @@ var size = getComputedSlideSize(); - var slidePadding = 20; // TODO Dig this out of DOM - // Layout the contents of the slides - layoutSlideContents( config.width, config.height, slidePadding ); + layoutSlideContents( config.width, config.height ); dom.slides.style.width = size.width + 'px'; dom.slides.style.height = size.height + 'px'; @@ -1654,7 +1617,7 @@ slide.style.top = 0; } else { - slide.style.top = Math.max( ( ( size.height - getAbsoluteHeight( slide ) ) / 2 ) - slidePadding, 0 ) + 'px'; + slide.style.top = Math.max( ( size.height - slide.scrollHeight ) / 2, 0 ) + 'px'; } } else { @@ -1674,7 +1637,7 @@ * Applies layout logic to the contents of all slides in * the presentation. */ - function layoutSlideContents( width, height, padding ) { + function layoutSlideContents( width, height ) { // Handle sizing of elements with the 'stretch' class toArray( dom.slides.querySelectorAll( 'section > .stretch' ) ).forEach( function( element ) { From d1a3656108ef0872f2a1179bcb87aa035d60b378 Mon Sep 17 00:00:00 2001 From: Aniqah Mair Date: Wed, 27 Apr 2016 14:50:03 -0400 Subject: [PATCH 08/69] Add selection colour for Mozilla Firefox Defines the highlight colour when selecting slide content using Mozilla Firefox to match other browsers, instead of being the default colour. --- css/theme/beige.css | 5 +++++ css/theme/black.css | 5 +++++ css/theme/blood.css | 5 +++++ css/theme/league.css | 5 +++++ css/theme/moon.css | 5 +++++ css/theme/night.css | 5 +++++ css/theme/serif.css | 5 +++++ css/theme/simple.css | 5 +++++ css/theme/sky.css | 5 +++++ css/theme/solarized.css | 5 +++++ css/theme/white.css | 5 +++++ 11 files changed, 55 insertions(+) diff --git a/css/theme/beige.css b/css/theme/beige.css index 5bbda4b..7f71dd9 100644 --- a/css/theme/beige.css +++ b/css/theme/beige.css @@ -29,6 +29,11 @@ body { background: rgba(79, 64, 28, 0.99); text-shadow: none; } +::-moz-selection { + color: #fff; + background: rgba(79, 64, 28, 0.99); + text-shadow: none; } + .reveal .slides > section, .reveal .slides > section > section { line-height: 1.3; diff --git a/css/theme/black.css b/css/theme/black.css index 511fa79..9228c46 100644 --- a/css/theme/black.css +++ b/css/theme/black.css @@ -25,6 +25,11 @@ body { background: #bee4fd; text-shadow: none; } +::-moz-selection { + color: #fff; + background: #bee4fd; + text-shadow: none; } + .reveal .slides > section, .reveal .slides > section > section { line-height: 1.3; diff --git a/css/theme/blood.css b/css/theme/blood.css index 6fe3d67..2da8d68 100644 --- a/css/theme/blood.css +++ b/css/theme/blood.css @@ -28,6 +28,11 @@ body { background: #a23; text-shadow: none; } +::-moz-selection { + color: #fff; + background: #a23; + text-shadow: none; } + .reveal .slides > section, .reveal .slides > section > section { line-height: 1.3; diff --git a/css/theme/league.css b/css/theme/league.css index 03c44ce..aa5bee5 100644 --- a/css/theme/league.css +++ b/css/theme/league.css @@ -31,6 +31,11 @@ body { background: #FF5E99; text-shadow: none; } +::-moz-selection { + color: #fff; + background: #FF5E99; + text-shadow: none; } + .reveal .slides > section, .reveal .slides > section > section { line-height: 1.3; diff --git a/css/theme/moon.css b/css/theme/moon.css index 5e5d6e4..5cb1176 100644 --- a/css/theme/moon.css +++ b/css/theme/moon.css @@ -29,6 +29,11 @@ body { background: #d33682; text-shadow: none; } +::-moz-selection { + color: #fff; + background: #d33682; + text-shadow: none; } + .reveal .slides > section, .reveal .slides > section > section { line-height: 1.3; diff --git a/css/theme/night.css b/css/theme/night.css index a439cdc..cf2c7a7 100644 --- a/css/theme/night.css +++ b/css/theme/night.css @@ -23,6 +23,11 @@ body { background: #e7ad52; text-shadow: none; } +::-moz-selection { + color: #fff; + background: #e7ad52; + text-shadow: none; } + .reveal .slides > section, .reveal .slides > section > section { line-height: 1.3; diff --git a/css/theme/serif.css b/css/theme/serif.css index 40ccb39..bbb9f7e 100644 --- a/css/theme/serif.css +++ b/css/theme/serif.css @@ -25,6 +25,11 @@ body { background: #26351C; text-shadow: none; } +::-moz-selection { + color: #fff; + background: #26351C; + text-shadow: none; } + .reveal .slides > section, .reveal .slides > section > section { line-height: 1.3; diff --git a/css/theme/simple.css b/css/theme/simple.css index b17fa5c..33809ec 100644 --- a/css/theme/simple.css +++ b/css/theme/simple.css @@ -25,6 +25,11 @@ body { background: rgba(0, 0, 0, 0.99); text-shadow: none; } +::-moz-selection { + color: #fff; + background: rgba(0, 0, 0, 0.99); + text-shadow: none; } + .reveal .slides > section, .reveal .slides > section > section { line-height: 1.3; diff --git a/css/theme/sky.css b/css/theme/sky.css index 99f1cfd..202ade8 100644 --- a/css/theme/sky.css +++ b/css/theme/sky.css @@ -32,6 +32,11 @@ body { background: #134674; text-shadow: none; } +::-moz-selection { + color: #fff; + background: #134674; + text-shadow: none; } + .reveal .slides > section, .reveal .slides > section > section { line-height: 1.3; diff --git a/css/theme/solarized.css b/css/theme/solarized.css index b4d4d4b..44771dc 100644 --- a/css/theme/solarized.css +++ b/css/theme/solarized.css @@ -29,6 +29,11 @@ body { background: #d33682; text-shadow: none; } +::-moz-selection { + color: #fff; + background: #d33682; + text-shadow: none; } + .reveal .slides > section, .reveal .slides > section > section { line-height: 1.3; diff --git a/css/theme/white.css b/css/theme/white.css index b10dd0e..16a1d23 100644 --- a/css/theme/white.css +++ b/css/theme/white.css @@ -25,6 +25,11 @@ body { background: #98bdef; text-shadow: none; } +::-moz-selection { + color: #fff; + background: #98bdef; + text-shadow: none; } + .reveal .slides > section, .reveal .slides > section > section { line-height: 1.3; From fcb6ea8385487194f257b9d556f9c98d0ec73301 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 28 Apr 2016 11:16:36 +0200 Subject: [PATCH 09/69] prevent pages from overflowing when printing to pdf --- js/reveal.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/js/reveal.js b/js/reveal.js index 8975504..bbe2ca4 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -597,6 +597,15 @@ top = Math.max( ( pageHeight - contentHeight ) / 2, 0 ); } + // Wrap the slide in a page element and hide its overflow + // so that no page ever flows onto another + var page = document.createElement( 'div' ); + page.className = 'page'; + page.style.overflow = 'hidden'; + page.style.height = ( pageHeight * numberOfPages ) + 'px'; + slide.parentNode.insertBefore( page, slide ); + page.appendChild( slide ); + // Position the slide inside of the page slide.style.left = left + 'px'; slide.style.top = top + 'px'; From 55581035228aba9a0d061a6969797327c626b0bf Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 28 Apr 2016 11:31:11 +0200 Subject: [PATCH 10/69] make max pages per slide limit configurable --- README.md | 2 ++ js/reveal.js | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/README.md b/README.md index 13bf457..e858216 100644 --- a/README.md +++ b/README.md @@ -783,6 +783,8 @@ Reveal.initialize({ Presentations can be exported to PDF via a special print stylesheet. This feature requires that you use [Google Chrome](http://google.com/chrome) or [Chromium](https://www.chromium.org/Home). Here's an example of an exported presentation that's been uploaded to SlideShare: http://www.slideshare.net/hakimel/revealjs-300. +Export dimensions are inferred from the configured [presentation size](#presentation-size). Slides that are too tall to fit within a single page will expand onto multiple pages. You can limit how many pages a slide may expand onto using the `pdfMaxPagesPerSlide` config option, for example: `Reveal.configure({ pdfMaxPagesPerSlide: 1 })`. + 1. Open your presentation with `print-pdf` included anywhere in the query string. This triggers the default index HTML to load the PDF print stylesheet ([css/print/pdf.css](https://github.com/hakimel/reveal.js/blob/master/css/print/pdf.css)). You can test this with [lab.hakim.se/reveal-js?print-pdf](http://lab.hakim.se/reveal-js?print-pdf). 2. Open the in-browser print dialog (CTRL/CMD+P). 3. Change the **Destination** setting to **Save as PDF**. diff --git a/js/reveal.js b/js/reveal.js index bbe2ca4..628c0b9 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -153,6 +153,10 @@ parallaxBackgroundHorizontal: null, parallaxBackgroundVertical: null, + // The maximum number of pages a single slide can expand onto when printing + // to PDF, unlimited by default + pdfMaxPagesPerSlide: Number.POSITIVE_INFINITY, + // Number of slides away from the current that are visible viewDistance: 3, @@ -592,6 +596,9 @@ var contentHeight = slide.scrollHeight; var numberOfPages = Math.max( Math.ceil( contentHeight / pageHeight ), 1 ); + // Adhere to configured pages per slide limit + numberOfPages = Math.min( numberOfPages, config.pdfMaxPagesPerSlide ); + // Center slides vertically if( numberOfPages === 1 && config.center || slide.classList.contains( 'center' ) ) { top = Math.max( ( pageHeight - contentHeight ) / 2, 0 ); From 9b11915c3a409aa456c64e9d386ac15598a4fa6b Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 28 Apr 2016 17:07:26 +0200 Subject: [PATCH 11/69] fix pdf bg layering, simplify code --- css/print/pdf.css | 14 +++++++------- js/reveal.js | 38 +++++++++----------------------------- 2 files changed, 16 insertions(+), 36 deletions(-) diff --git a/css/print/pdf.css b/css/print/pdf.css index 9ed90d6..9ae0dfe 100644 --- a/css/print/pdf.css +++ b/css/print/pdf.css @@ -82,6 +82,12 @@ ul, ol, div, p { perspective-origin: 50% 50%; } +.reveal .slides .pdf-page { + position: relative; + overflow: hidden; + z-index: 1; +} + .reveal .slides section { page-break-after: always !important; @@ -132,13 +138,7 @@ ul, ol, div, p { top: 0; left: 0; width: 100%; - z-index: -1; -} - -/* All elements should be above the slide-background */ -.reveal section>* { - position: relative; - z-index: 1; + height: 100%; } /* Display slide speaker notes when 'showNotes' is enabled */ diff --git a/js/reveal.js b/js/reveal.js index 628c0b9..47b4f01 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -607,8 +607,7 @@ // Wrap the slide in a page element and hide its overflow // so that no page ever flows onto another var page = document.createElement( 'div' ); - page.className = 'page'; - page.style.overflow = 'hidden'; + page.className = 'pdf-page'; page.style.height = ( pageHeight * numberOfPages ) + 'px'; slide.parentNode.insertBefore( page, slide ); page.appendChild( slide ); @@ -618,14 +617,8 @@ slide.style.top = top + 'px'; slide.style.width = slideWidth + 'px'; - // TODO Backgrounds need to be multiplied when the slide - // stretches over multiple pages - var background = slide.querySelector( '.slide-background' ); - if( background ) { - background.style.width = pageWidth + 'px'; - background.style.height = ( pageHeight * numberOfPages ) + 'px'; - background.style.top = -top + 'px'; - background.style.left = -left + 'px'; + if( slide.slideBackgroundElement ) { + page.insertBefore( slide.slideBackgroundElement, slide ); } // Inject notes if `showNotes` is enabled @@ -653,7 +646,7 @@ numberElement.classList.add( 'slide-number' ); numberElement.classList.add( 'slide-number-pdf' ); numberElement.innerHTML = formatSlideNumber( slideNumberH, '.', slideNumberV ); - background.appendChild( numberElement ); + page.appendChild( numberElement ); } } @@ -733,24 +726,12 @@ // Iterate over all horizontal slides toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ).forEach( function( slideh ) { - var backgroundStack; - - if( printMode ) { - backgroundStack = createBackground( slideh, slideh ); - } - else { - backgroundStack = createBackground( slideh, dom.background ); - } + var backgroundStack = createBackground( slideh, dom.background ); // Iterate over all vertical slides toArray( slideh.querySelectorAll( 'section' ) ).forEach( function( slidev ) { - if( printMode ) { - createBackground( slidev, slidev ); - } - else { - createBackground( slidev, backgroundStack ); - } + createBackground( slidev, backgroundStack ); backgroundStack.classList.add( 'stack' ); @@ -846,6 +827,8 @@ slide.classList.remove( 'has-dark-background' ); slide.classList.remove( 'has-light-background' ); + slide.slideBackgroundElement = element; + // If this slide has a background color, add a class that // signals if it is light or dark. If the slide has no background // color, no class will be set @@ -3406,10 +3389,7 @@ if( isPrintingPDF() ) { var slide = getSlide( x, y ); if( slide ) { - var background = slide.querySelector( '.slide-background' ); - if( background && background.parentNode === slide ) { - return background; - } + return slide.slideBackgroundElement; } return undefined; From ce7d494ae9f6516af82d597ed00e3cabd1a1ad55 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Fri, 29 Apr 2016 09:25:05 +0200 Subject: [PATCH 12/69] tweak formatting to match rest of slide --- plugin/zoom-js/zoom.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/zoom-js/zoom.js b/plugin/zoom-js/zoom.js index efccad6..8738083 100644 --- a/plugin/zoom-js/zoom.js +++ b/plugin/zoom-js/zoom.js @@ -15,7 +15,7 @@ var originalDisplay = event.target.style.display; // Get the bounding rect of the contents, not the containing box - if (window.getComputedStyle(event.target).display === 'block') { + if( window.getComputedStyle( event.target ).display === 'block' ) { event.target.style.display = 'inline-block'; bounds = event.target.getBoundingClientRect(); event.target.style.display = originalDisplay; From e2a863405782709e8cd30227f8b1157acc30fa19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E7=8E=84?= Date: Mon, 2 May 2016 01:42:11 +0800 Subject: [PATCH 13/69] add refused-to-display tips in link-preview-overlay --- css/reveal.scss | 10 ++++++++++ js/reveal.js | 3 +++ 2 files changed, 13 insertions(+) diff --git a/css/reveal.scss b/css/reveal.scss index f8d6904..c360fe6 100644 --- a/css/reveal.scss +++ b/css/reveal.scss @@ -1229,6 +1229,16 @@ html:-moz-full-screen-ancestor { visibility: visible; } + .reveal .overlay.overlay-preview.loaded .viewport-inner { + position: absolute; + z-index: -1; + left: 0; + top: 60px; + width: 100%; + text-align: center; + letter-spacing: normal; + } + .reveal .overlay.overlay-preview.loaded .spinner { opacity: 0; visibility: hidden; diff --git a/js/reveal.js b/js/reveal.js index 10c609e..e772516 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -1500,6 +1500,9 @@ '
    ', '
    ', '', + '', + 'This link is refused to display in a frame due to its policy', + '', '
    ' ].join(''); From fb8bbaac00e1fa7e9259acfc2b88a14e83a59707 Mon Sep 17 00:00:00 2001 From: Jason Kiss Date: Tue, 10 May 2016 10:03:05 +1200 Subject: [PATCH 14/69] set/remove @disabled on navigation buttons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keeps disabled buttons out of kbd tab order and indicates to assistive tech like screen readers that button is disabled. Otherwise buttons that aren’t enabled remain in kbd Tab order and screen readers announce them as buttons, but they don’t work. --- js/reveal.js | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/js/reveal.js b/js/reveal.js index 10c609e..b3a91b3 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -2652,34 +2652,36 @@ .concat( dom.controlsNext ).forEach( function( node ) { node.classList.remove( 'enabled' ); node.classList.remove( 'fragmented' ); + // Set 'disabled' attribute on all directions + node.setAttribute('disabled', 'disabled'); } ); - // Add the 'enabled' class to the available routes - if( routes.left ) dom.controlsLeft.forEach( function( el ) { el.classList.add( 'enabled' ); } ); - if( routes.right ) dom.controlsRight.forEach( function( el ) { el.classList.add( 'enabled' ); } ); - if( routes.up ) dom.controlsUp.forEach( function( el ) { el.classList.add( 'enabled' ); } ); - if( routes.down ) dom.controlsDown.forEach( function( el ) { el.classList.add( 'enabled' ); } ); + // Add the 'enabled' class to the available routes; remove 'disabled' attribute to enable buttons + if( routes.left ) dom.controlsLeft.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute('disabled'); } ); + if( routes.right ) dom.controlsRight.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute('disabled'); } ); + if( routes.up ) dom.controlsUp.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute('disabled'); } ); + if( routes.down ) dom.controlsDown.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute('disabled'); } ); // Prev/next buttons - if( routes.left || routes.up ) dom.controlsPrev.forEach( function( el ) { el.classList.add( 'enabled' ); } ); - if( routes.right || routes.down ) dom.controlsNext.forEach( function( el ) { el.classList.add( 'enabled' ); } ); + if( routes.left || routes.up ) dom.controlsPrev.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute('disabled'); } ); + if( routes.right || routes.down ) dom.controlsNext.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute('disabled'); } ); // Highlight fragment directions if( currentSlide ) { // Always apply fragment decorator to prev/next buttons - if( fragments.prev ) dom.controlsPrev.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } ); - if( fragments.next ) dom.controlsNext.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } ); + if( fragments.prev ) dom.controlsPrev.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute('disabled'); } ); + if( fragments.next ) dom.controlsNext.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute('disabled'); } ); // Apply fragment decorators to directional buttons based on // what slide axis they are in if( isVerticalSlide( currentSlide ) ) { - if( fragments.prev ) dom.controlsUp.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } ); - if( fragments.next ) dom.controlsDown.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } ); + if( fragments.prev ) dom.controlsUp.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute('disabled'); } ); + if( fragments.next ) dom.controlsDown.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute('disabled'); } ); } else { - if( fragments.prev ) dom.controlsLeft.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } ); - if( fragments.next ) dom.controlsRight.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } ); + if( fragments.prev ) dom.controlsLeft.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute('disabled'); } ); + if( fragments.next ) dom.controlsRight.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute('disabled'); } ); } } From dec6d1745b780e67960afe20a5a0d86f23ba0733 Mon Sep 17 00:00:00 2001 From: Jason Kiss Date: Tue, 10 May 2016 11:02:45 +1200 Subject: [PATCH 15/69] make speaker notes keyboard accessible Places div.speaker-notes in default kbd Tab order, and when focused, prevent slide navigation with up/down arrows, allowing up/down arrow keys to scroll div.speaker-notes. --- js/reveal.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/js/reveal.js b/js/reveal.js index 10c609e..3ff1f85 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -495,6 +495,7 @@ // Element containing notes that are visible to the audience dom.speakerNotes = createSingletonNode( dom.wrapper, 'div', 'speaker-notes', null ); dom.speakerNotes.setAttribute( 'data-prevent-swipe', '' ); + dom.speakerNotes.setAttribute( 'tabindex', '0'); // Overlay graphic which is displayed during the paused mode createSingletonNode( dom.wrapper, 'div', 'pause-overlay', null ); @@ -3963,10 +3964,11 @@ // the keyboard var activeElementIsCE = document.activeElement && document.activeElement.contentEditable !== 'inherit'; var activeElementIsInput = document.activeElement && document.activeElement.tagName && /input|textarea/i.test( document.activeElement.tagName ); + var activeElementIsNotes = document.activeElement && document.activeElement.className && /speaker-notes/i.test( document.activeElement.className); // Disregard the event if there's a focused element or a // keyboard modifier key is present - if( activeElementIsCE || activeElementIsInput || (event.shiftKey && event.keyCode !== 32) || event.altKey || event.ctrlKey || event.metaKey ) return; + if( activeElementIsCE || activeElementIsInput || activeElementIsNotes || (event.shiftKey && event.keyCode !== 32) || event.altKey || event.ctrlKey || event.metaKey ) return; // While paused only allow resume keyboard events; 'b', '.'' var resumeKeyCodes = [66,190,191]; From b79f1fac132569158ceec752eb21c6ac4a00b656 Mon Sep 17 00:00:00 2001 From: Tristan Sokol Date: Thu, 19 May 2016 16:47:25 -0700 Subject: [PATCH 16/69] Add minor imporovements to the PDF export instructions --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e229f1e..c10a465 100644 --- a/README.md +++ b/README.md @@ -780,10 +780,10 @@ Reveal.initialize({ ## PDF Export -Presentations can be exported to PDF via a special print stylesheet. This feature requires that you use [Google Chrome](http://google.com/chrome) or [Chromium](https://www.chromium.org/Home). +Presentations can be exported to PDF via a special print stylesheet. This feature requires that you use [Google Chrome](http://google.com/chrome) or [Chromium](https://www.chromium.org/Home) and to be serving the presention from a webserver. Here's an example of an exported presentation that's been uploaded to SlideShare: http://www.slideshare.net/hakimel/revealjs-300. -1. Open your presentation with `print-pdf` included anywhere in the query string. This triggers the default index HTML to load the PDF print stylesheet ([css/print/pdf.css](https://github.com/hakimel/reveal.js/blob/master/css/print/pdf.css)). You can test this with [lab.hakim.se/reveal-js?print-pdf](http://lab.hakim.se/reveal-js?print-pdf). +1. Open your presentation with `print-pdf` included in the query string i.e. http://localhost:8000/?print-pdf#/. This triggers the default index HTML to load the PDF print stylesheet ([css/print/pdf.css](https://github.com/hakimel/reveal.js/blob/master/css/print/pdf.css)). You can test this with [lab.hakim.se/reveal-js?print-pdf](http://lab.hakim.se/reveal-js?print-pdf). 2. Open the in-browser print dialog (CTRL/CMD+P). 3. Change the **Destination** setting to **Save as PDF**. 4. Change the **Layout** to **Landscape**. From 187114f47224b4628350a6046c6f758bce83f6c1 Mon Sep 17 00:00:00 2001 From: Tiago Garcia Date: Sat, 21 May 2016 11:36:49 -0700 Subject: [PATCH 17/69] Removing duplicated "position" property at pdf.css Found that by running css-lint on the code --- css/print/pdf.css | 1 - 1 file changed, 1 deletion(-) diff --git a/css/print/pdf.css b/css/print/pdf.css index 9ed90d6..3dc577d 100644 --- a/css/print/pdf.css +++ b/css/print/pdf.css @@ -86,7 +86,6 @@ ul, ol, div, p { page-break-after: always !important; visibility: visible !important; - position: relative !important; display: block !important; position: relative !important; From 6593ac3d5f83ec49b168d49d7963146e67fd0e79 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Mon, 23 May 2016 10:38:46 +0200 Subject: [PATCH 18/69] moz selection color in theme template #1575 --- css/theme/template/theme.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/css/theme/template/theme.scss b/css/theme/template/theme.scss index 101a567..bcbaf0c 100644 --- a/css/theme/template/theme.scss +++ b/css/theme/template/theme.scss @@ -22,6 +22,12 @@ body { text-shadow: none; } +::-moz-selection { + color: $selectionColor; + background: $selectionBackgroundColor; + text-shadow: none; +} + .reveal .slides>section, .reveal .slides>section>section { line-height: 1.3; From e2fa1d966c66098d69f5212636d4d620977521db Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Mon, 23 May 2016 10:50:39 +0200 Subject: [PATCH 19/69] ocd --- js/reveal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/reveal.js b/js/reveal.js index d2b93bb..708bef5 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -499,7 +499,7 @@ // Element containing notes that are visible to the audience dom.speakerNotes = createSingletonNode( dom.wrapper, 'div', 'speaker-notes', null ); dom.speakerNotes.setAttribute( 'data-prevent-swipe', '' ); - dom.speakerNotes.setAttribute( 'tabindex', '0'); + dom.speakerNotes.setAttribute( 'tabindex', '0' ); // Overlay graphic which is displayed during the paused mode createSingletonNode( dom.wrapper, 'div', 'pause-overlay', null ); From 9cd7f3f37b564808a77e8a2448f9c92f8aae0aaf Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Mon, 23 May 2016 10:54:40 +0200 Subject: [PATCH 20/69] code format --- js/reveal.js | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/js/reveal.js b/js/reveal.js index d5cba0e..656ed10 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -2615,36 +2615,37 @@ .concat( dom.controlsNext ).forEach( function( node ) { node.classList.remove( 'enabled' ); node.classList.remove( 'fragmented' ); + // Set 'disabled' attribute on all directions - node.setAttribute('disabled', 'disabled'); + node.setAttribute( 'disabled', 'disabled' ); } ); // Add the 'enabled' class to the available routes; remove 'disabled' attribute to enable buttons - if( routes.left ) dom.controlsLeft.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute('disabled'); } ); - if( routes.right ) dom.controlsRight.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute('disabled'); } ); - if( routes.up ) dom.controlsUp.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute('disabled'); } ); - if( routes.down ) dom.controlsDown.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute('disabled'); } ); + if( routes.left ) dom.controlsLeft.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } ); + if( routes.right ) dom.controlsRight.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } ); + if( routes.up ) dom.controlsUp.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } ); + if( routes.down ) dom.controlsDown.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } ); // Prev/next buttons - if( routes.left || routes.up ) dom.controlsPrev.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute('disabled'); } ); - if( routes.right || routes.down ) dom.controlsNext.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute('disabled'); } ); + if( routes.left || routes.up ) dom.controlsPrev.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } ); + if( routes.right || routes.down ) dom.controlsNext.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } ); // Highlight fragment directions if( currentSlide ) { // Always apply fragment decorator to prev/next buttons - if( fragments.prev ) dom.controlsPrev.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute('disabled'); } ); - if( fragments.next ) dom.controlsNext.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute('disabled'); } ); + if( fragments.prev ) dom.controlsPrev.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); + if( fragments.next ) dom.controlsNext.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); // Apply fragment decorators to directional buttons based on // what slide axis they are in if( isVerticalSlide( currentSlide ) ) { - if( fragments.prev ) dom.controlsUp.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute('disabled'); } ); - if( fragments.next ) dom.controlsDown.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute('disabled'); } ); + if( fragments.prev ) dom.controlsUp.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); + if( fragments.next ) dom.controlsDown.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); } else { - if( fragments.prev ) dom.controlsLeft.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute('disabled'); } ); - if( fragments.next ) dom.controlsRight.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute('disabled'); } ); + if( fragments.prev ) dom.controlsLeft.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); + if( fragments.next ) dom.controlsRight.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); } } From 3111d3b1ae12af2580cb45a18da208146701a6fd Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 26 May 2016 09:57:19 +0200 Subject: [PATCH 21/69] support for 'separate-page' layout for notes in PDF exports #1518 --- README.md | 2 +- css/print/pdf.css | 13 ++++++++++++- js/reveal.js | 21 +++++++++++++++++---- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 56dad41..b275846 100644 --- a/README.md +++ b/README.md @@ -890,7 +890,7 @@ This will only display in the notes window. Notes are only visible to the speaker inside of the speaker view. If you wish to share your notes with others you can initialize reveal.js with the `showNotes` config value set to `true`. Notes will appear along the bottom of the presentations. -When `showNotes` is enabled notes are also included when you [export to PDF](https://github.com/hakimel/reveal.js#pdf-export). +When `showNotes` is enabled notes are also included when you [export to PDF](https://github.com/hakimel/reveal.js#pdf-export). By default, notes are printed in a semi-transparent box on top of slide. If you'd rather print them on a separate page after the slide, set `showNotes: "separate-page"`. ## Server Side Speaker Notes diff --git a/css/print/pdf.css b/css/print/pdf.css index 406f125..fb56129 100644 --- a/css/print/pdf.css +++ b/css/print/pdf.css @@ -145,11 +145,22 @@ ul, ol, div, p { display: block; width: 100%; max-height: none; - left: auto; top: auto; + right: auto; + bottom: auto; + left: auto; z-index: 100; } +/* Layout option which makes notes appear on a separate page */ +.reveal .speaker-notes-pdf[data-layout="separate-page"] { + position: relative; + color: inherit; + background-color: transparent; + padding: 20px; + page-break-after: always; +} + /* Display slide numbers when 'slideNumber' is enabled */ .reveal .slide-number-pdf { display: block; diff --git a/js/reveal.js b/js/reveal.js index 656ed10..f43e0aa 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -624,18 +624,31 @@ // Inject notes if `showNotes` is enabled if( config.showNotes ) { + + // Are there notes for this slide? var notes = getSlideNotes( slide ); if( notes ) { + var notesSpacing = 8; + var notesLayout = typeof config.showNotes === 'string' ? config.showNotes : 'inline'; var notesElement = document.createElement( 'div' ); notesElement.classList.add( 'speaker-notes' ); notesElement.classList.add( 'speaker-notes-pdf' ); + notesElement.setAttribute( 'data-layout', notesLayout ); notesElement.innerHTML = notes; - notesElement.style.left = ( notesSpacing - left ) + 'px'; - notesElement.style.bottom = ( notesSpacing - top ) + 'px'; - notesElement.style.width = ( pageWidth - notesSpacing*2 ) + 'px'; - slide.appendChild( notesElement ); + + if( notesLayout === 'separate-page' ) { + page.parentNode.insertBefore( notesElement, page.nextSibling ); + } + else { + notesElement.style.left = ( notesSpacing - left ) + 'px'; + notesElement.style.bottom = ( notesSpacing - top ) + 'px'; + notesElement.style.width = ( pageWidth - notesSpacing*2 ) + 'px'; + slide.appendChild( notesElement ); + } + } + } // Inject slide numbers if `slideNumbers` are enabled From 43212662767129f85973b82f8d1799fa446b3267 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 26 May 2016 10:09:09 +0200 Subject: [PATCH 22/69] include layout for notes outside of pdf exports --- js/reveal.js | 1 + 1 file changed, 1 insertion(+) diff --git a/js/reveal.js b/js/reveal.js index f43e0aa..3c750af 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -948,6 +948,7 @@ if( config.showNotes ) { dom.speakerNotes.classList.add( 'visible' ); + dom.speakerNotes.setAttribute( 'data-layout', typeof config.showNotes === 'string' ? config.showNotes : 'inline' ); } else { dom.speakerNotes.classList.remove( 'visible' ); From ca92d22adcf2a5a6c960b2d4a6bdadd13b12385b Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Fri, 10 Jun 2016 10:04:54 +0200 Subject: [PATCH 23/69] add showHelp to api #1611 --- README.md | 3 +++ js/reveal.js | 3 +++ 2 files changed, 6 insertions(+) diff --git a/README.md b/README.md index 211ee98..48311ab 100644 --- a/README.md +++ b/README.md @@ -434,6 +434,9 @@ Reveal.nextFragment(); // Randomize the order of slides Reveal.shuffle(); +// Shows a help overlay with keyboard shortcuts +Reveal.showHelp(); + // Toggle presentation states, optionally pass true/false to force on/off Reveal.toggleOverview(); Reveal.togglePause(); diff --git a/js/reveal.js b/js/reveal.js index 3c750af..ed4d769 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -4580,6 +4580,9 @@ navigatePrev: navigatePrev, navigateNext: navigateNext, + // Shows a help overlay with keyboard shortcuts + showHelp: showHelp, + // Forces an update in slide layout layout: layout, From 02123205a0995b41580c357f4b20c1473af69e63 Mon Sep 17 00:00:00 2001 From: Timothep Date: Wed, 9 Mar 2016 11:38:29 +0100 Subject: [PATCH 24/69] Added a description of the undocumented timer-reset feature --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 13bf457..41bf077 100644 --- a/README.md +++ b/README.md @@ -822,6 +822,8 @@ If you want to add a theme of your own see the instructions here: [/css/theme/RE reveal.js comes with a speaker notes plugin which can be used to present per-slide notes in a separate browser window. The notes window also gives you a preview of the next upcoming slide so it may be helpful even if you haven't written any notes. Press the 's' key on your keyboard to open the notes window. +A speaker timer starts as soon as the speaker view is opened. You can reset it to 00:00:00 at any time by simply clicking/tapping on it. + Notes are defined by appending an ```