From 68b2de6dd7e62998fb232cc60c0214aaea626f08 Mon Sep 17 00:00:00 2001 From: Jonathan Roes Date: Sat, 12 May 2012 21:05:42 -0400 Subject: [PATCH 01/51] Fit generated SHA1 placeholders to original length. --- lib/gollum/markup.rb | 36 ++++++++++++++++++++++++++++++------ test/test_markup.rb | 30 ++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/lib/gollum/markup.rb b/lib/gollum/markup.rb index 3bac70d1..31e19cd6 100644 --- a/lib/gollum/markup.rb +++ b/lib/gollum/markup.rb @@ -80,17 +80,41 @@ module Gollum def extract_tex(data) data.gsub(/\\\[\s*(.*?)\s*\\\]/m) do tag = CGI.escapeHTML($1) - id = Digest::SHA1.hexdigest(tag) + id = generate_placeholder(tag, $&.length) @texmap[id] = [:block, tag] id end.gsub(/\\\(\s*(.*?)\s*\\\)/m) do tag = CGI.escapeHTML($1) - id = Digest::SHA1.hexdigest(tag) + id = generate_placeholder(tag, $&.length) @texmap[id] = [:inline, tag] id end end + # Fit `id` into `len` by adding trailing spaces or truncating. + # + # id - The String identifier to be fit. + # len - The Integer target length. + # + # Returns the newly-fit String. + def fit_width(id, len) + if id.length < len + id.ljust(len) + else + id[0...len] + end + end + + # Generate a placeholder of a particular length. + # + # tag - The original String tag to be processed later. + # length - The Integer length the placeholder should be. + # + # Returns the new placeholder String. + def generate_placeholder(tag, length) + fit_width(Digest::SHA1.hexdigest(tag), length) + end + # Process all TeX from the texmap and replace the placeholders with the # final markup. # @@ -131,14 +155,14 @@ module Gollum parts = $2.split('][') parts[0][0..4] = "" link = "#{parts[1]}|#{parts[0].sub(/\.org/,'')}" - id = Digest::SHA1.hexdigest(link) + id = generate_placeholder(link, $&.length) @tagmap[id] = link "#{pre}#{id}#{post}" else $& end else - id = Digest::SHA1.hexdigest($2) + id = generate_placeholder($2, $2.length+4) @tagmap[id] = $2 "#{$1}#{id}#{$3}" end @@ -385,7 +409,7 @@ module Gollum # Returns the placeholder'd String data. def extract_code(data) data.gsub!(/^([ \t]*)``` ?([^\r\n]+)?\r?\n(.+?)\r?\n\1```\r?$/m) do - id = Digest::SHA1.hexdigest("#{$2}.#{$3}") + id = generate_placeholder("#{$2}.#{$3}", [$2, $3].join.length) cached = check_cache(:code, id) @codemap[id] = cached ? { :output => cached } : @@ -467,7 +491,7 @@ module Gollum # Returns the placeholder'd String data. def extract_wsd(data) data.gsub(/^\{\{\{ ?(.+?)\r?\n(.+?)\r?\n\}\}\}\r?$/m) do - id = Digest::SHA1.hexdigest($2) + id = generate_placeholder($2, $&.length) @wsdmap[id] = { :style => $1, :code => $2 } id end diff --git a/test/test_markup.rb b/test/test_markup.rb index b14e597e..7be6d915 100644 --- a/test/test_markup.rb +++ b/test/test_markup.rb @@ -195,6 +195,36 @@ context "Markup" do assert_equal "

make a link [[home|sweet home]]

", page.formatted_data end + test "table with links" do + table = < + ++++ + + + + + + +
Proposal | Mentor
+Ray-Bans | technoweenie
+ +EOT + @wiki.write_page("Potato", :rest, table, commit_details) + page = @wiki.page("Potato") + assert_equal expected_table.chomp, page.formatted_data + end + ######################################################################### # # Images From fbcc69ec67269a2ec4dfb42f7824370dfff78afb Mon Sep 17 00:00:00 2001 From: Jonathan Roes Date: Sat, 12 May 2012 21:47:31 -0400 Subject: [PATCH 02/51] Tell Travis that the tests now depend on docutils. --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index fc72739e..ef1b651e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,3 +5,5 @@ notifications: disabled: true before_install: - sudo apt-get install -y asciidoc + - sudo easy_install docutils + \ No newline at end of file From 3ea5b0193c485a1025a550cae7a55d004fdb1491 Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Tue, 15 May 2012 09:59:15 -0600 Subject: [PATCH 03/51] Fix sanitizer to whitelist h1-6. --- .../public/gollum/livepreview/js/pagedown/Markdown.Sanitizer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/gollum/frontend/public/gollum/livepreview/js/pagedown/Markdown.Sanitizer.js b/lib/gollum/frontend/public/gollum/livepreview/js/pagedown/Markdown.Sanitizer.js index eecd069e..b6709b9c 100644 --- a/lib/gollum/frontend/public/gollum/livepreview/js/pagedown/Markdown.Sanitizer.js +++ b/lib/gollum/frontend/public/gollum/livepreview/js/pagedown/Markdown.Sanitizer.js @@ -20,7 +20,7 @@ } // (tags that can be opened/closed) | (tags that stand alone) - var basic_tag_whitelist = /^(<\/?(b|blockquote|code|del|dd|dl|dt|em|h1|h2|h3|i|kbd|li|ol|p|pre|s|sup|sub|strong|strike|ul)>|<(br|hr)\s?\/?>)$/i; + var basic_tag_whitelist = /^(<\/?(b|blockquote|code|del|dd|dl|dt|em|h1|h2|h3|h4|h5|h6|i|kbd|li|ol|p|pre|s|sup|sub|strong|strike|ul)>|<(br|hr)\s?\/?>)$/i; // | // Make https:// ftp:// prefix optional so relative links work. page one var a_white = /^(]+")?\s?>|<\/a>)$/i; From 966ba290843ce124bdab99b5c9b3a81a62ecb33a Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Tue, 15 May 2012 10:12:32 -0600 Subject: [PATCH 04/51] Fix gollum style code blocks. --- .../js/pagedown/Markdown.Converter.js | 29 +++---------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/lib/gollum/frontend/public/gollum/livepreview/js/pagedown/Markdown.Converter.js b/lib/gollum/frontend/public/gollum/livepreview/js/pagedown/Markdown.Converter.js index 1867ff7e..c0a6002e 100644 --- a/lib/gollum/frontend/public/gollum/livepreview/js/pagedown/Markdown.Converter.js +++ b/lib/gollum/frontend/public/gollum/livepreview/js/pagedown/Markdown.Converter.js @@ -175,6 +175,9 @@ else // Strip link definitions, store in hashes. text = _StripLinkDefinitions(text); + // Process gollum style code highlighting. + text = _DoCodeSpansGollum(text); + text = _RunBlockGamut(text); text = _UnescapeSpecialChars(text); @@ -1030,7 +1033,7 @@ else c = c.replace(/[ \t]*$/gm, ""); // trailing whitespace c = _EncodeCode(c); c = c.replace(/:\/\//gm, "~P"); // to prevent auto-linking. Not necessary in code *blocks*, but in code spans. Will be converted back after the auto-linker runs. - return m1 + "
`" + c + "
"; + return m1 + hashBlock("
`" + c + "
"); } ); @@ -1146,8 +1149,6 @@ else // Wrap

tags. // var end = grafs.length; - var extendedString = ""; - var isExtended = false; for (var i = 0; i < end; i++) { var str = grafs[i]; @@ -1156,28 +1157,6 @@ else grafsOut.push(str); } else if (/\S/.test(str)) { - // Detect start of gollum code. - if (str.substring(0,3) === "```") { - isExtended = true; - } - - if (isExtended === true) { - // Detect end of gollum code. - var strLength = str.length; - if (str.substring(strLength-3, strLength) === "```") { - str = extendedString + str; - str = _DoCodeSpansGollum(str); - grafsOut.push(str); - - isExtended = false; - extendedString = ""; - continue; - } - - extendedString += str + "\n\n"; - continue; - } - str = _RunSpanGamut(str); str = str.replace(/^([ \t]*)/g, "

"); str += "

" From 27bd608b53031c6e672f77462f63344d9fee9882 Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Tue, 15 May 2012 10:37:38 -0600 Subject: [PATCH 05/51] Update live preview title. --- lib/gollum/frontend/public/gollum/livepreview/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/gollum/frontend/public/gollum/livepreview/index.html b/lib/gollum/frontend/public/gollum/livepreview/index.html index f002a2c1..415c7599 100644 --- a/lib/gollum/frontend/public/gollum/livepreview/index.html +++ b/lib/gollum/frontend/public/gollum/livepreview/index.html @@ -1,6 +1,6 @@ -JavaScript Markdown Editor +Live Preview From 3a91b076e121175b4a20d50f0499276c40008a4b Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Tue, 15 May 2012 11:06:36 -0600 Subject: [PATCH 06/51] Fix gollum code blocks. --- .../gollum/livepreview/js/pagedown/Markdown.Converter.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/gollum/frontend/public/gollum/livepreview/js/pagedown/Markdown.Converter.js b/lib/gollum/frontend/public/gollum/livepreview/js/pagedown/Markdown.Converter.js index c0a6002e..8bb02cd6 100644 --- a/lib/gollum/frontend/public/gollum/livepreview/js/pagedown/Markdown.Converter.js +++ b/lib/gollum/frontend/public/gollum/livepreview/js/pagedown/Markdown.Converter.js @@ -1024,9 +1024,10 @@ else function _DoCodeSpansGollum(text) { // // Gollum wraps code in one pre. Use ` to mark code pre. + // Gollum requires exactly three starting and ending `. // All regex set to use 'm' multiline option. // - text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm, + text = text.replace(/(^|[^\\])(`{3})([^\r]*?[^`])\2(?!`)/gm, function (wholeMatch, m1, m2, m3, m4) { var c = m3; c = c.replace(/^([ \t]*)/gm, ""); // leading whitespace From f2a2d850080447d9fb8dcfe8ae80124fc89d37aa Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Tue, 15 May 2012 11:20:01 -0600 Subject: [PATCH 07/51] Preserve whitespace in gollum code blocks. --- .../gollum/livepreview/js/pagedown/Markdown.Converter.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/gollum/frontend/public/gollum/livepreview/js/pagedown/Markdown.Converter.js b/lib/gollum/frontend/public/gollum/livepreview/js/pagedown/Markdown.Converter.js index 8bb02cd6..25313cf0 100644 --- a/lib/gollum/frontend/public/gollum/livepreview/js/pagedown/Markdown.Converter.js +++ b/lib/gollum/frontend/public/gollum/livepreview/js/pagedown/Markdown.Converter.js @@ -1025,14 +1025,14 @@ else // // Gollum wraps code in one pre. Use ` to mark code pre. // Gollum requires exactly three starting and ending `. - // All regex set to use 'm' multiline option. // text = text.replace(/(^|[^\\])(`{3})([^\r]*?[^`])\2(?!`)/gm, function (wholeMatch, m1, m2, m3, m4) { var c = m3; - c = c.replace(/^([ \t]*)/gm, ""); // leading whitespace - c = c.replace(/[ \t]*$/gm, ""); // trailing whitespace + c = c.replace(/^([ \t]*)/g, ""); // leading whitespace + c = c.replace(/[ \t]*$/g, ""); // trailing whitespace c = _EncodeCode(c); + // Set to use 'm' multiline option. c = c.replace(/:\/\//gm, "~P"); // to prevent auto-linking. Not necessary in code *blocks*, but in code spans. Will be converted back after the auto-linker runs. return m1 + hashBlock("
`" + c + "
"); } From fde288d9e8dc10a0d68bd534be57b80ad7589dae Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Tue, 15 May 2012 11:48:48 -0600 Subject: [PATCH 08/51] Guess highlight rules for code blocks to match gollum behavior. --- lib/gollum/frontend/public/gollum/livepreview/index.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/gollum/frontend/public/gollum/livepreview/index.html b/lib/gollum/frontend/public/gollum/livepreview/index.html index 415c7599..069d6b9c 100644 --- a/lib/gollum/frontend/public/gollum/livepreview/index.html +++ b/lib/gollum/frontend/public/gollum/livepreview/index.html @@ -209,7 +209,7 @@ var makePreviewHtml = function () { // highlight code blocks. var codeElements = preview.getElementsByTagName("pre"); var codeElementsLength = codeElements.length; - + var hlSpace = " "; if (codeElementsLength > 0) { for (var idx = 0; idx < codeElementsLength; idx++) { var element = codeElements[idx]; @@ -225,17 +225,17 @@ var makePreviewHtml = function () { // txt[0] = "`"; txt[1] = "ruby" if ($.inArray(txt[1], languages) === -1) { element.innerHTML = codeHTML.substring(1).trim(); - element.className = "nohighlight"; + hljs.highlightBlock(element, hlSpace); continue; } element.className = txt[1] + " highlight"; // length + 1 for the marker character. element.innerHTML = codeHTML.substring(txt[1].length+1).trim(); - hljs.highlightBlock(element, " "); + hljs.highlightBlock(element, hlSpace); } else { element.innerHTML = codeHTML.substring(1).trim(); - element.className = "nohighlight"; + hljs.highlightBlock(element, hlSpace); } } } From 423b5205bf4e57ffda7e92fd165ded8958060447 Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Tue, 15 May 2012 11:49:55 -0600 Subject: [PATCH 09/51] Fix language detection. --- lib/gollum/frontend/public/gollum/livepreview/index.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/gollum/frontend/public/gollum/livepreview/index.html b/lib/gollum/frontend/public/gollum/livepreview/index.html index 069d6b9c..637710ab 100644 --- a/lib/gollum/frontend/public/gollum/livepreview/index.html +++ b/lib/gollum/frontend/public/gollum/livepreview/index.html @@ -222,8 +222,9 @@ var makePreviewHtml = function () { var txt = codeHTML.split(/\b/); // the syntax for code highlighting means all code, even one line, contains newlines. if (txt.length > 1 && codeHTML.match(/\n/)) { + // txt[0] must be "`" // txt[0] = "`"; txt[1] = "ruby" - if ($.inArray(txt[1], languages) === -1) { + if (txt[0] !== "`" || $.inArray(txt[1], languages) === -1) { element.innerHTML = codeHTML.substring(1).trim(); hljs.highlightBlock(element, hlSpace); continue; From 1043b4de70653e7cef1f29e93488e1b884b67042 Mon Sep 17 00:00:00 2001 From: Corey Donohoe Date: Wed, 16 May 2012 12:48:16 -0700 Subject: [PATCH 10/51] Revert "Merge pull request #338 from jroes/resize-sha1s" This reverts commit 4bc5e7b8ffc79abfca7b7045c3ab67988341dd1d, reversing changes made to 423b5205bf4e57ffda7e92fd165ded8958060447. --- .travis.yml | 2 -- lib/gollum/markup.rb | 36 ++++++------------------------------ test/test_markup.rb | 30 ------------------------------ 3 files changed, 6 insertions(+), 62 deletions(-) diff --git a/.travis.yml b/.travis.yml index ef1b651e..fc72739e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,5 +5,3 @@ notifications: disabled: true before_install: - sudo apt-get install -y asciidoc - - sudo easy_install docutils - \ No newline at end of file diff --git a/lib/gollum/markup.rb b/lib/gollum/markup.rb index 31e19cd6..3bac70d1 100644 --- a/lib/gollum/markup.rb +++ b/lib/gollum/markup.rb @@ -80,41 +80,17 @@ module Gollum def extract_tex(data) data.gsub(/\\\[\s*(.*?)\s*\\\]/m) do tag = CGI.escapeHTML($1) - id = generate_placeholder(tag, $&.length) + id = Digest::SHA1.hexdigest(tag) @texmap[id] = [:block, tag] id end.gsub(/\\\(\s*(.*?)\s*\\\)/m) do tag = CGI.escapeHTML($1) - id = generate_placeholder(tag, $&.length) + id = Digest::SHA1.hexdigest(tag) @texmap[id] = [:inline, tag] id end end - # Fit `id` into `len` by adding trailing spaces or truncating. - # - # id - The String identifier to be fit. - # len - The Integer target length. - # - # Returns the newly-fit String. - def fit_width(id, len) - if id.length < len - id.ljust(len) - else - id[0...len] - end - end - - # Generate a placeholder of a particular length. - # - # tag - The original String tag to be processed later. - # length - The Integer length the placeholder should be. - # - # Returns the new placeholder String. - def generate_placeholder(tag, length) - fit_width(Digest::SHA1.hexdigest(tag), length) - end - # Process all TeX from the texmap and replace the placeholders with the # final markup. # @@ -155,14 +131,14 @@ module Gollum parts = $2.split('][') parts[0][0..4] = "" link = "#{parts[1]}|#{parts[0].sub(/\.org/,'')}" - id = generate_placeholder(link, $&.length) + id = Digest::SHA1.hexdigest(link) @tagmap[id] = link "#{pre}#{id}#{post}" else $& end else - id = generate_placeholder($2, $2.length+4) + id = Digest::SHA1.hexdigest($2) @tagmap[id] = $2 "#{$1}#{id}#{$3}" end @@ -409,7 +385,7 @@ module Gollum # Returns the placeholder'd String data. def extract_code(data) data.gsub!(/^([ \t]*)``` ?([^\r\n]+)?\r?\n(.+?)\r?\n\1```\r?$/m) do - id = generate_placeholder("#{$2}.#{$3}", [$2, $3].join.length) + id = Digest::SHA1.hexdigest("#{$2}.#{$3}") cached = check_cache(:code, id) @codemap[id] = cached ? { :output => cached } : @@ -491,7 +467,7 @@ module Gollum # Returns the placeholder'd String data. def extract_wsd(data) data.gsub(/^\{\{\{ ?(.+?)\r?\n(.+?)\r?\n\}\}\}\r?$/m) do - id = generate_placeholder($2, $&.length) + id = Digest::SHA1.hexdigest($2) @wsdmap[id] = { :style => $1, :code => $2 } id end diff --git a/test/test_markup.rb b/test/test_markup.rb index 7be6d915..b14e597e 100644 --- a/test/test_markup.rb +++ b/test/test_markup.rb @@ -195,36 +195,6 @@ context "Markup" do assert_equal "

make a link [[home|sweet home]]

", page.formatted_data end - test "table with links" do - table = < - ---- - - - - - - -
Proposal | Mentor
-Ray-Bans | technoweenie
- -EOT - @wiki.write_page("Potato", :rest, table, commit_details) - page = @wiki.page("Potato") - assert_equal expected_table.chomp, page.formatted_data - end - ######################################################################### # # Images From 9b87126f0f1acb9321fbb25fe2ec981c57d63fb7 Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Thu, 17 May 2012 12:40:27 -0600 Subject: [PATCH 11/51] Generate commit messages when using live preview. --- .../public/gollum/livepreview/index.html | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/lib/gollum/frontend/public/gollum/livepreview/index.html b/lib/gollum/frontend/public/gollum/livepreview/index.html index 637710ab..1a38ceef 100644 --- a/lib/gollum/frontend/public/gollum/livepreview/index.html +++ b/lib/gollum/frontend/public/gollum/livepreview/index.html @@ -74,23 +74,29 @@ window.onload = function() { $.save = function() { // if &create=true then handle create instead of edit. var create = $.key("create"); + var POST = "POST"; + var pageName = $.key("page"); + var markdown = "markdown"; + var txt = editorSession.getValue(); + var msg = pageName + " ("+markdown+")" + var newLocation = location + "/" + pageName; if (create) { jQuery.ajax({ - type: "POST", - url: "/create", - data: { page: $.key("page"), format: "markdown", content: editorSession.getValue() }, - success: function() { - window.location = window.location.origin + "/" + $.key("page"); - } + type: POST, + url: "/create", + data: { page: pageName, format: markdown, content: txt, message: "Created " + msg }, + success: function() { + window.location = newLocation; + } }); } else { jQuery.ajax({ - type: "POST", - url: "/edit/" + $.key("page"), - data: { format: "markdown", content: editorSession.getValue() }, - success: function() { - window.location = window.location.origin + "/" + $.key("page"); + type: POST, + url: "/edit/" + pageName, + data: { format: markdown, content: txt, message: "Updated " + msg }, + success: function() { + window.location = newLocation; } }); } // end else From 67d21bcd64bbcfd4c42f086980cfd4c438d5a432 Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Thu, 17 May 2012 12:44:28 -0600 Subject: [PATCH 12/51] Fix location. --- lib/gollum/frontend/public/gollum/livepreview/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/gollum/frontend/public/gollum/livepreview/index.html b/lib/gollum/frontend/public/gollum/livepreview/index.html index 1a38ceef..36564644 100644 --- a/lib/gollum/frontend/public/gollum/livepreview/index.html +++ b/lib/gollum/frontend/public/gollum/livepreview/index.html @@ -79,7 +79,7 @@ window.onload = function() { var markdown = "markdown"; var txt = editorSession.getValue(); var msg = pageName + " ("+markdown+")" - var newLocation = location + "/" + pageName; + var newLocation = window.location.origin + "/" + pageName; if (create) { jQuery.ajax({ From 4b2fb6dd110bf3b477baf9ebf77faa4d3cc5d192 Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Thu, 17 May 2012 15:17:24 -0600 Subject: [PATCH 13/51] Add default commit messages when using gollum editor. --- .../gollum/javascript/editor/gollum.editor.js | 14 ++++++++++++++ lib/gollum/frontend/templates/editor.mustache | 8 ++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/gollum/frontend/public/gollum/javascript/editor/gollum.editor.js b/lib/gollum/frontend/public/gollum/javascript/editor/gollum.editor.js index caf885a2..0ef3d2a5 100755 --- a/lib/gollum/frontend/public/gollum/javascript/editor/gollum.editor.js +++ b/lib/gollum/frontend/public/gollum/javascript/editor/gollum.editor.js @@ -168,6 +168,11 @@ }, setActiveLanguage: function( name ) { + // On first load _ACTIVE_LANG.length is 0 and evtChangeFormat isn't called. + if ( LanguageDefinition._ACTIVE_LANG.length <= 0 ) { + FormatSelector.updateCommitMessage( name ); + } + if(LanguageDefinition.getHookFunctionFor("deactivate")) { LanguageDefinition.getHookFunctionFor("deactivate")(); } @@ -747,9 +752,18 @@ */ evtChangeFormat: function( e ) { var newMarkup = $(this).val(); + FormatSelector.updateCommitMessage( newMarkup ); LanguageDefinition.setActiveLanguage( newMarkup ); }, + updateCommitMessage: function( newMarkup ) { + var msg = document.getElementById( "gollum-editor-message-field" ); + var val = msg.value; + // Must start with created or updated. + if (/^(?:created|updated)/i.test(val)) { + msg.value = val.replace( /\([^\)]*\)$/, "(" + newMarkup + ")" ); + } + }, /** * FormatSelector.init diff --git a/lib/gollum/frontend/templates/editor.mustache b/lib/gollum/frontend/templates/editor.mustache index 1ae57779..34c3c8cb 100644 --- a/lib/gollum/frontend/templates/editor.mustache +++ b/lib/gollum/frontend/templates/editor.mustache @@ -112,10 +112,14 @@
- + {{#is_create_page}} + + {{/is_create_page}} + {{#is_edit_page}} + + {{/is_edit_page}}
-
Preview From 16a618657001cc9ecc7b5c7c3b4c3b794f1c3c42 Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Thu, 17 May 2012 16:00:09 -0600 Subject: [PATCH 14/51] Add icon for save with comment in live preview. --- .../gollum/livepreview/images/savecomment_24.png | Bin 0 -> 278 bytes .../frontend/public/gollum/livepreview/index.html | 9 +++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 lib/gollum/frontend/public/gollum/livepreview/images/savecomment_24.png diff --git a/lib/gollum/frontend/public/gollum/livepreview/images/savecomment_24.png b/lib/gollum/frontend/public/gollum/livepreview/images/savecomment_24.png new file mode 100644 index 0000000000000000000000000000000000000000..38d7d41aa073becfef62ba6727f06c2b4ab5243b GIT binary patch literal 278 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`Gjk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xc6hothE&{2TC-|Z(uVEZzo#c8%wRae#dC#`zhTFN2M3#_ zCClI4;WVmYX3lkB5Wezs3zP7S6%sl(8ko4n9L2eK?>3)FR9w;!bl`|XvVoM#Vn-7x zmkA104u=J*7&a|vXcH4LXw+g2*y)=(zu^oQ!%W^j<`t^aiJJ~cy|Wkd6>qq~xZ<0# z?j+5~HsS1pY(>1sr}|7h$fV%c!Y1wK>TvqxC&oJkP7EoQdh7;?!9HCNBfczRXkcJw YSjTCZ?#5Gp3+M+1Pgg&ebxsLQ01e4t7ytkO literal 0 HcmV?d00001 diff --git a/lib/gollum/frontend/public/gollum/livepreview/index.html b/lib/gollum/frontend/public/gollum/livepreview/index.html index 36564644..916d823a 100644 --- a/lib/gollum/frontend/public/gollum/livepreview/index.html +++ b/lib/gollum/frontend/public/gollum/livepreview/index.html @@ -19,9 +19,10 @@
- +
- save + Save + Save with comment Toggle left to right
@@ -106,6 +107,10 @@ window.onload = function() { $.save(); }); + $('#savecomment').click(function() { + $.save(); + }); + // onChange calls applyTimeout which rate limits the calling of makePreviewHtml based on render time. editor.on('change', applyTimeout); makePreviewHtml(); // preview default text on load From 268a9f18fa6e285cefcb91bdaeb3e8ac362c8eca Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Fri, 18 May 2012 10:24:14 -0600 Subject: [PATCH 15/51] Update readme. --- lib/gollum/frontend/public/gollum/livepreview/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/gollum/frontend/public/gollum/livepreview/readme.md b/lib/gollum/frontend/public/gollum/livepreview/readme.md index 9c7a6276..d1b7575e 100644 --- a/lib/gollum/frontend/public/gollum/livepreview/readme.md +++ b/lib/gollum/frontend/public/gollum/livepreview/readme.md @@ -41,6 +41,6 @@ Using jQuery v1.7.2. - Download latest production version from [jquery.com](http://www.jquery.com). ## Pagedown -The Pagedown code used is from revision `44a4db795617`, Mar 2, 2012 (currently the newest version at the time of writing this document). Markdown.Converter.js has been enhanced to support Gollum style code highlighting. +The Pagedown code used is from revision `44a4db795617`, Mar 2, 2012 (currently the newest version at the time of writing this document). Markdown.Converter.js has been enhanced to support Gollum style code highlighting. Markdown.Sanitizer.js has been fixed to not remove h4-6. `https://code.google.com/p/pagedown/source/detail?r=44a4db795617288ae9817c90735fb497891ede23` From 32e5cc4a5a771b226008f5834ca221177d008848 Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Fri, 18 May 2012 10:27:01 -0600 Subject: [PATCH 16/51] Add debounce. --- .../debounce/jquery.ba-throttle-debounce.js | 252 ++++++++++++++++++ .../licenses/debounce/LICENSE-MIT.txt | 22 ++ .../public/gollum/livepreview/readme.md | 1 + 3 files changed, 275 insertions(+) create mode 100644 lib/gollum/frontend/public/gollum/livepreview/js/debounce/jquery.ba-throttle-debounce.js create mode 100644 lib/gollum/frontend/public/gollum/livepreview/licenses/debounce/LICENSE-MIT.txt diff --git a/lib/gollum/frontend/public/gollum/livepreview/js/debounce/jquery.ba-throttle-debounce.js b/lib/gollum/frontend/public/gollum/livepreview/js/debounce/jquery.ba-throttle-debounce.js new file mode 100644 index 00000000..fa30bdff --- /dev/null +++ b/lib/gollum/frontend/public/gollum/livepreview/js/debounce/jquery.ba-throttle-debounce.js @@ -0,0 +1,252 @@ +/*! + * jQuery throttle / debounce - v1.1 - 3/7/2010 + * http://benalman.com/projects/jquery-throttle-debounce-plugin/ + * + * Copyright (c) 2010 "Cowboy" Ben Alman + * Dual licensed under the MIT and GPL licenses. + * http://benalman.com/about/license/ + */ + +// Script: jQuery throttle / debounce: Sometimes, less is more! +// +// *Version: 1.1, Last updated: 3/7/2010* +// +// Project Home - http://benalman.com/projects/jquery-throttle-debounce-plugin/ +// GitHub - http://github.com/cowboy/jquery-throttle-debounce/ +// Source - http://github.com/cowboy/jquery-throttle-debounce/raw/master/jquery.ba-throttle-debounce.js +// (Minified) - http://github.com/cowboy/jquery-throttle-debounce/raw/master/jquery.ba-throttle-debounce.min.js (0.7kb) +// +// About: License +// +// Copyright (c) 2010 "Cowboy" Ben Alman, +// Dual licensed under the MIT and GPL licenses. +// http://benalman.com/about/license/ +// +// About: Examples +// +// These working examples, complete with fully commented code, illustrate a few +// ways in which this plugin can be used. +// +// Throttle - http://benalman.com/code/projects/jquery-throttle-debounce/examples/throttle/ +// Debounce - http://benalman.com/code/projects/jquery-throttle-debounce/examples/debounce/ +// +// About: Support and Testing +// +// Information about what version or versions of jQuery this plugin has been +// tested with, what browsers it has been tested in, and where the unit tests +// reside (so you can test it yourself). +// +// jQuery Versions - none, 1.3.2, 1.4.2 +// Browsers Tested - Internet Explorer 6-8, Firefox 2-3.6, Safari 3-4, Chrome 4-5, Opera 9.6-10.1. +// Unit Tests - http://benalman.com/code/projects/jquery-throttle-debounce/unit/ +// +// About: Release History +// +// 1.1 - (3/7/2010) Fixed a bug in where trailing callbacks +// executed later than they should. Reworked a fair amount of internal +// logic as well. +// 1.0 - (3/6/2010) Initial release as a stand-alone project. Migrated over +// from jquery-misc repo v0.4 to jquery-throttle repo v1.0, added the +// no_trailing throttle parameter and debounce functionality. +// +// Topic: Note for non-jQuery users +// +// jQuery isn't actually required for this plugin, because nothing internal +// uses any jQuery methods or properties. jQuery is just used as a namespace +// under which these methods can exist. +// +// Since jQuery isn't actually required for this plugin, if jQuery doesn't exist +// when this plugin is loaded, the method described below will be created in +// the `Cowboy` namespace. Usage will be exactly the same, but instead of +// $.method() or jQuery.method(), you'll need to use Cowboy.method(). + +(function(window,undefined){ + '$:nomunge'; // Used by YUI compressor. + + // Since jQuery really isn't required for this plugin, use `jQuery` as the + // namespace only if it already exists, otherwise use the `Cowboy` namespace, + // creating it if necessary. + var $ = window.jQuery || window.Cowboy || ( window.Cowboy = {} ), + + // Internal method reference. + jq_throttle; + + // Method: jQuery.throttle + // + // Throttle execution of a function. Especially useful for rate limiting + // execution of handlers on events like resize and scroll. If you want to + // rate-limit execution of a function to a single time, see the + // method. + // + // In this visualization, | is a throttled-function call and X is the actual + // callback execution: + // + // > Throttled with `no_trailing` specified as false or unspecified: + // > ||||||||||||||||||||||||| (pause) ||||||||||||||||||||||||| + // > X X X X X X X X X X X X + // > + // > Throttled with `no_trailing` specified as true: + // > ||||||||||||||||||||||||| (pause) ||||||||||||||||||||||||| + // > X X X X X X X X X X + // + // Usage: + // + // > var throttled = jQuery.throttle( delay, [ no_trailing, ] callback ); + // > + // > jQuery('selector').bind( 'someevent', throttled ); + // > jQuery('selector').unbind( 'someevent', throttled ); + // + // This also works in jQuery 1.4+: + // + // > jQuery('selector').bind( 'someevent', jQuery.throttle( delay, [ no_trailing, ] callback ) ); + // > jQuery('selector').unbind( 'someevent', callback ); + // + // Arguments: + // + // delay - (Number) A zero-or-greater delay in milliseconds. For event + // callbacks, values around 100 or 250 (or even higher) are most useful. + // no_trailing - (Boolean) Optional, defaults to false. If no_trailing is + // true, callback will only execute every `delay` milliseconds while the + // throttled-function is being called. If no_trailing is false or + // unspecified, callback will be executed one final time after the last + // throttled-function call. (After the throttled-function has not been + // called for `delay` milliseconds, the internal counter is reset) + // callback - (Function) A function to be executed after delay milliseconds. + // The `this` context and all arguments are passed through, as-is, to + // `callback` when the throttled-function is executed. + // + // Returns: + // + // (Function) A new, throttled, function. + + $.throttle = jq_throttle = function( delay, no_trailing, callback, debounce_mode ) { + // After wrapper has stopped being called, this timeout ensures that + // `callback` is executed at the proper times in `throttle` and `end` + // debounce modes. + var timeout_id, + + // Keep track of the last time `callback` was executed. + last_exec = 0; + + // `no_trailing` defaults to falsy. + if ( typeof no_trailing !== 'boolean' ) { + debounce_mode = callback; + callback = no_trailing; + no_trailing = undefined; + } + + // The `wrapper` function encapsulates all of the throttling / debouncing + // functionality and when executed will limit the rate at which `callback` + // is executed. + function wrapper() { + var that = this, + elapsed = +new Date() - last_exec, + args = arguments; + + // Execute `callback` and update the `last_exec` timestamp. + function exec() { + last_exec = +new Date(); + callback.apply( that, args ); + }; + + // If `debounce_mode` is true (at_begin) this is used to clear the flag + // to allow future `callback` executions. + function clear() { + timeout_id = undefined; + }; + + if ( debounce_mode && !timeout_id ) { + // Since `wrapper` is being called for the first time and + // `debounce_mode` is true (at_begin), execute `callback`. + exec(); + } + + // Clear any existing timeout. + timeout_id && clearTimeout( timeout_id ); + + if ( debounce_mode === undefined && elapsed > delay ) { + // In throttle mode, if `delay` time has been exceeded, execute + // `callback`. + exec(); + + } else if ( no_trailing !== true ) { + // In trailing throttle mode, since `delay` time has not been + // exceeded, schedule `callback` to execute `delay` ms after most + // recent execution. + // + // If `debounce_mode` is true (at_begin), schedule `clear` to execute + // after `delay` ms. + // + // If `debounce_mode` is false (at end), schedule `callback` to + // execute after `delay` ms. + timeout_id = setTimeout( debounce_mode ? clear : exec, debounce_mode === undefined ? delay - elapsed : delay ); + } + }; + + // Set the guid of `wrapper` function to the same of original callback, so + // it can be removed in jQuery 1.4+ .unbind or .die by using the original + // callback as a reference. + if ( $.guid ) { + wrapper.guid = callback.guid = callback.guid || $.guid++; + } + + // Return the wrapper function. + return wrapper; + }; + + // Method: jQuery.debounce + // + // Debounce execution of a function. Debouncing, unlike throttling, + // guarantees that a function is only executed a single time, either at the + // very beginning of a series of calls, or at the very end. If you want to + // simply rate-limit execution of a function, see the + // method. + // + // In this visualization, | is a debounced-function call and X is the actual + // callback execution: + // + // > Debounced with `at_begin` specified as false or unspecified: + // > ||||||||||||||||||||||||| (pause) ||||||||||||||||||||||||| + // > X X + // > + // > Debounced with `at_begin` specified as true: + // > ||||||||||||||||||||||||| (pause) ||||||||||||||||||||||||| + // > X X + // + // Usage: + // + // > var debounced = jQuery.debounce( delay, [ at_begin, ] callback ); + // > + // > jQuery('selector').bind( 'someevent', debounced ); + // > jQuery('selector').unbind( 'someevent', debounced ); + // + // This also works in jQuery 1.4+: + // + // > jQuery('selector').bind( 'someevent', jQuery.debounce( delay, [ at_begin, ] callback ) ); + // > jQuery('selector').unbind( 'someevent', callback ); + // + // Arguments: + // + // delay - (Number) A zero-or-greater delay in milliseconds. For event + // callbacks, values around 100 or 250 (or even higher) are most useful. + // at_begin - (Boolean) Optional, defaults to false. If at_begin is false or + // unspecified, callback will only be executed `delay` milliseconds after + // the last debounced-function call. If at_begin is true, callback will be + // executed only at the first debounced-function call. (After the + // throttled-function has not been called for `delay` milliseconds, the + // internal counter is reset) + // callback - (Function) A function to be executed after delay milliseconds. + // The `this` context and all arguments are passed through, as-is, to + // `callback` when the debounced-function is executed. + // + // Returns: + // + // (Function) A new, debounced, function. + + $.debounce = function( delay, at_begin, callback ) { + return callback === undefined + ? jq_throttle( delay, at_begin, false ) + : jq_throttle( delay, callback, at_begin !== false ); + }; + +})(this); diff --git a/lib/gollum/frontend/public/gollum/livepreview/licenses/debounce/LICENSE-MIT.txt b/lib/gollum/frontend/public/gollum/livepreview/licenses/debounce/LICENSE-MIT.txt new file mode 100644 index 00000000..874d2469 --- /dev/null +++ b/lib/gollum/frontend/public/gollum/livepreview/licenses/debounce/LICENSE-MIT.txt @@ -0,0 +1,22 @@ +Copyright (c) 2010 "Cowboy" Ben Alman + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/lib/gollum/frontend/public/gollum/livepreview/readme.md b/lib/gollum/frontend/public/gollum/livepreview/readme.md index d1b7575e..22ba8b17 100644 --- a/lib/gollum/frontend/public/gollum/livepreview/readme.md +++ b/lib/gollum/frontend/public/gollum/livepreview/readme.md @@ -12,6 +12,7 @@ Uses code/assets from: 0. [notepages](https://github.com/fivesixty/notepages) 0. [pagedown](https://code.google.com/p/pagedown/) 0. [retina_display_icon_set](http://blog.twg.ca/2010/11/retina-display-icon-set/) +0. [debounce](https://github.com/cowboy/jquery-throttle-debounce) See licenses folder for details. From 3479dca0d09ff90d03a339311bf3132d0644a4fb Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Fri, 18 May 2012 10:28:59 -0600 Subject: [PATCH 17/51] Add comment window using Ace that allows user entered commit messages. Use darkness div to dim the background when the comment window is active. Set CSS in batch to avoid unnecessary reflows. Use debouncing to efficiently resize the window. Eliminate previewSetter in favor of redefining the previewSet function. --- .../public/gollum/livepreview/css/custom.css | 35 ++- .../gollum/livepreview/images/cancel_24.png | Bin 0 -> 525 bytes .../public/gollum/livepreview/index.html | 201 +++++++++++++----- 3 files changed, 183 insertions(+), 53 deletions(-) create mode 100644 lib/gollum/frontend/public/gollum/livepreview/images/cancel_24.png diff --git a/lib/gollum/frontend/public/gollum/livepreview/css/custom.css b/lib/gollum/frontend/public/gollum/livepreview/css/custom.css index c043bc25..23c412e0 100644 --- a/lib/gollum/frontend/public/gollum/livepreview/css/custom.css +++ b/lib/gollum/frontend/public/gollum/livepreview/css/custom.css @@ -2,7 +2,22 @@ body { overflow: hidden; } -#editor { +#darkness { + visibility: hidden; + position: absolute; + left: 0px; + top: 0px; + background-color: black; + opacity: 0.8; + z-index: 1001; /* must be > 1000 to overlay ace gutter */ +} + +#commenttoolpanel { + visibility: hidden; + z-index: 1002; /* > 1001 to not be hidden by darkness */ +} + +#comment, #editor { margin: 0; padding: 0; position: absolute; @@ -10,6 +25,16 @@ body { bottom: 0; left: 0; right: 0; + /* Set font size of both ace editors. */ + font-size: 16px; +} + +/* Set comment to have a higher z-index +so editor doesn't display in the background. */ + +#comment { + visibility: hidden; + z-index: 1003; /* > 1002 to not be hidden by toolpanel */ } #contentframe { @@ -30,7 +55,7 @@ body { } /* -- Start from notepag.es -- */ -#toolpanel { +.toolpanel { position: fixed; background: #666; top: 0; @@ -43,7 +68,7 @@ body { text-align: center; } -#toolpanel.edit a.edit { +.toolpanel.edit a.edit { opacity: 0.4; /* Make it appear as a link even though save doesn't have a href attribute. */ @@ -51,7 +76,7 @@ body { display: inline-block; } -#toolpanel a { +.toolpanel a { color: white; text-decoration: none; margin: 0 5px; @@ -60,7 +85,7 @@ body { font-family: sans-serif; } -#toolpanel a img { +.toolpanel a img { vertical-align: middle; margin-left: 5px; margin: 0; diff --git a/lib/gollum/frontend/public/gollum/livepreview/images/cancel_24.png b/lib/gollum/frontend/public/gollum/livepreview/images/cancel_24.png new file mode 100644 index 0000000000000000000000000000000000000000..98fd3024f6612d98db089d73e86802374197f2d6 GIT binary patch literal 525 zcmV+o0`mQdP)XD5e|oKwi~#y|pk#+5v?7M4uIa``D4Zq=P=?gjc}d==1dpaEItB+Pfy7m}NU@9-(f5y$4rAsHv>0iG(%D=gj`1>lSWE|Jju zj7P8(3t|pl$j=?Rua$_oT?mhMyIl$?xZW8_aOz-gfyccGkHjlsRs+EcMdrCz%5gJ5 zmIBQt_vT)Nq5IW+M>hT5pK$q7MzV6v^R6SAC+VuOWw14-~nJOu_3#2ecTY@a(Z@&IV3Uf zkgLlYF#q6~V`bq1tV?*(1AK!w Live Preview - + + @@ -13,27 +14,40 @@ +
- -
- Save + +
+ save Save with comment Toggle left to right
+
+ Confirm save with comment + Cancel save with comment +
+
+
+ - - - - - - - @@ -34,367 +24,14 @@
- + + + + + + + + + diff --git a/lib/gollum/frontend/public/gollum/livepreview/js/livepreview/livepreview.js b/lib/gollum/frontend/public/gollum/livepreview/js/livepreview/livepreview.js new file mode 100644 index 00000000..98d15af9 --- /dev/null +++ b/lib/gollum/frontend/public/gollum/livepreview/js/livepreview/livepreview.js @@ -0,0 +1,357 @@ +(function () { +var converter = Markdown.getSanitizingConverter(); +var editor = ace.edit("editor"); +var editorSession = editor.getSession(); +var editorContainer = editor.container; +var preview = document.getElementById("previewframe"); +var content = document.getElementById("contentframe"); +var toolPanel = document.getElementById("toolpanel"); +var comment = document.getElementById("comment"); +var commentToolPanel = document.getElementById("commenttoolpanel"); +// dim the page +var darkness = document.getElementById("darkness"); + +var leftRight = true; +var jsm = {}; // JavaScript Markdown +window.jsm = jsm; +window.jsm.toggleLeftRight = function() { + leftRight = leftRight === false ? true : false; + jsm.resize(); +} + +var MarkdownMode = require("ace/mode/markdown").Mode; + +function initAce(editor, editorSession) { + editor.setTheme("ace/theme/twilight"); + editorSession.setMode(new MarkdownMode()); + // Gutter shows line numbers + editor.renderer.setShowGutter(true); + editor.renderer.setHScrollBarAlwaysVisible(false); + editorSession.setUseSoftTabs(true); + editorSession.setTabSize(2); + editorSession.setUseWrapMode(true); + editor.setShowPrintMargin(false); + editor.setBehavioursEnabled(true); +} + +initAce(editor, editorSession); + +// Setup comment ace. +var commentEditor = ace.edit("comment"); +var commentEditorSession = commentEditor.getSession(); +var commentEditorContainer = commentEditor.container; + +initAce(commentEditor, commentEditorSession); + +// RegExp from http://stackoverflow.com/questions/901115/get-query-string-values-in-javascript +$.key = function(key){ + var value = new RegExp('[\\?&]' + key + '=([^&#]*)').exec(window.location.href); + return (!value) ? 0 : value[1] || 0; +} + +// True if &create=true +var create = $.key("create"); +// The name of the page being edited. +var pageName = $.key("page"); + +defaultCommitMessage = function() { + var msg = pageName + " (markdown)"; + + if (create) { + return "Created " + msg; + } else { + return "Updated " + msg; + } +} + +// Set comment using the default commit message. +commentEditorSession.setValue( defaultCommitMessage() ); + +$.save = function( commitMessage ) { + var POST = "POST"; + var markdown = "markdown"; + var txt = editorSession.getValue(); + var msg = defaultCommitMessage(); + var newLocation = window.location.origin + "/" + pageName; + + // if &create=true then handle create instead of edit. + if (create) { + jQuery.ajax({ + type: POST, + url: "/create", + data: { page: pageName, format: markdown, content: txt, message: commitMessage || msg }, + success: function() { + window.location = newLocation; + } + }); + } else { + jQuery.ajax({ + type: POST, + url: "/edit/" + pageName, + data: { format: markdown, content: txt, message: commitMessage || msg }, + success: function() { + window.location = newLocation; + } + }); + } // end else +} + +var elapsedTime; +var oldInputText = ""; + +// ---- from Markdown.Editor +var timeout; + +var nonSuckyBrowserPreviewSet = function (text) { + content.innerHTML = text; +} + +// IE doesn't let you use innerHTML if the element is contained somewhere in a table +// (which is the case for inline editing) -- in that case, detach the element, set the +// value, and reattach. Yes, that *is* ridiculous. +var ieSafePreviewSet = function (text) { + var parent = content.parentNode; + var sibling = content.nextSibling; + parent.removeChild(content); + content.innerHTML = text; + if (!sibling) + parent.appendChild(content); + else + parent.insertBefore(content, sibling); +} + +var cssTextSet = function( element, css ){ + element.style.cssText = css; +} + +var cssAttrSet = function( element, css ){ + element.setAttribute( 'style', css ); +} + +/* + Redefine the function based on browser support. + element - the element to set the css on + css - a fully formed css string. ex: "top: 0; left: 0;" + + Avoid reflow by batching CSS changes. + http://dev.opera.com/articles/view/efficient-javascript/?page=3#stylechanges +*/ +var cssSet = function( element, css ) { + if( typeof( element.style.cssText ) != 'undefined' ) { + cssTextSet( element, css ); + cssSet = cssTextSet; + } else { + cssAttrSet( element, css ); + cssSet = cssAttrSet; + } +} + +var previewSet = function( text ) { + try { + nonSuckyBrowserPreviewSet( text ); + previewSet = nonSuckyBrowserPreviewSet; + } catch (e) { + ieSafePreviewSet( text ); + previewSet = ieSafePreviewSet; + } +}; + +var languages = [ "1c", "actionscript", "apache", "avrasm", "axapta", +"bash", "cmake", "coffeescript", "cpp", "cs", "css", "delphi", "diff", +"django", "d", "dos", "erlang", "erlang-repl", "go", "haskell", "ini", +"java", "javascript", "languages", "lisp", "lua", "markdown", "matlab", +"mel", "nginx", "objectivec", "parser3", "perl", "php", "profile", +"python", "renderman", "ruby", "rust", "scala", "smalltalk", "sql", +"tex", "vala", "vbscript", "vhdl", "xml" ]; + +var makePreviewHtml = function () { + var text = editorSession.getValue(); + + if (text && text == oldInputText) { + return; // Input text hasn't changed. + } + else { + oldInputText = text; + } + + var prevTime = new Date().getTime(); + + text = converter.makeHtml(text); + + // Calculate the processing time of the HTML creation. + // It's used as the delay time in the event listener. + var currTime = new Date().getTime(); + elapsedTime = currTime - prevTime; + + // Update the text using feature detection to support IE. + // preview.innerHTML = text; // this doesn't work on IE. + previewSet(text); + + // highlight code blocks. + var codeElements = preview.getElementsByTagName("pre"); + var codeElementsLength = codeElements.length; + var hlSpace = " "; + if (codeElementsLength > 0) { + for (var idx = 0; idx < codeElementsLength; idx++) { + var element = codeElements[idx]; + var codeHTML = element.innerHTML; + + // Only use pre tags marked containing code. + if (codeHTML[0] !== "`") + continue; + + var txt = codeHTML.split(/\b/); + // the syntax for code highlighting means all code, even one line, contains newlines. + if (txt.length > 1 && codeHTML.match(/\n/)) { + // txt[0] must be "`" + // txt[0] = "`"; txt[1] = "ruby" + if (txt[0] !== "`" || $.inArray(txt[1], languages) === -1) { + element.innerHTML = codeHTML.substring(1).trim(); + hljs.highlightBlock(element, hlSpace); + continue; + } + + element.className = txt[1] + " highlight"; + // length + 1 for the marker character. + element.innerHTML = codeHTML.substring(txt[1].length+1).trim(); + hljs.highlightBlock(element, hlSpace); + } else { + element.innerHTML = codeHTML.substring(1).trim(); + hljs.highlightBlock(element, hlSpace); + } + } + } +}; + +// setTimeout is already used. Used as an event listener. +var applyTimeout = function () { + if (timeout) { + clearTimeout(timeout); + timeout = undefined; + } + + // 3 second max delay + if (elapsedTime > 3000) { + elapsedTime = 3000; + } + + timeout = setTimeout(makePreviewHtml, elapsedTime); +}; + + /* Load markdown from /data/page into the ace editor. */ + jQuery.ajax({ + type: "GET", + url: "/data/" + $.key("page"), + success: function(data) { + editorSession.setValue(data); + } + }); + + $("#save").click(function() { + $.save(); + }); + + // Hide dimmer, comment tool panel, and comment. + $("#commentcancel").click(function() { + // Restore focus on commentcancel but not on + // savecommentconfirm because the latter loads + // a new page. + hideCommentWindow(); + editor.focus(); + }); + + var isCommentHidden = true; + + function hideCommentWindow() { + isCommentHidden = true; + darkness.style.visibility = "hidden"; + commentToolPanel.style.visibility = "hidden"; + comment.style.visibility = "hidden"; + } + + // Show dimmer, comment tool panel, and comment. + $("#savecomment").click(function() { + isCommentHidden = false; + darkness.style.visibility = "visible"; + commentToolPanel.style.visibility = "visible"; + comment.style.visibility = "visible"; + // Set focus so typing can begin immediately. + commentEditor.focus(); + }); + + $("#savecommentconfirm").click(function() { + $.save(commentEditorSession.getValue()); + hideCommentWindow(); + }); + + // onChange calls applyTimeout which rate limits the calling of makePreviewHtml based on render time. + editor.on('change', applyTimeout); + makePreviewHtml(); // preview default text on load + + function resize() { + var width = $(window).width(); + var widthHalf = width / 2; + var widthFourth = widthHalf / 2; + var height = $(window).height(); + var heightHalf = height / 2; + + // height minus 50 so the end of document text doesn't flow off the page. + var editorContainerStyle = "width:" + widthHalf + "px;" + + "height:" + (height - 50) + "px;" + + "left:" + (leftRight === false ? widthHalf + "px;" : "0px;") + + "top:" + "40px;"; // use 40px for tool menu + cssSet( editorContainer, editorContainerStyle ); + editor.resize(); + + // width -2 for scroll bar & -10 for left offset + var previewStyle = "width:" + (widthHalf - 2 - 10) + "px;" + + "height:" + height + "px;" + + "left:" + (leftRight === false ? "10px;" : widthHalf + "px;") + + "top:" + "0px;"; + cssSet( preview, previewStyle ); + + // Resize tool panel + var toolPanelStyle = "width:" + widthHalf + "px;" + + "left:" + (leftRight === false ? widthHalf + "px;" : "0px;"); + cssSet( toolPanel, toolPanelStyle ); + + // Resize comment related elements. + var commentHidden = "visibility:" + ( isCommentHidden === true ? "hidden;" : "visible;" ); + + // Adjust comment editor + var commentEditorContainerStyle = "height:" + heightHalf + "px;" + + "width:" + widthHalf + "px;" + + "left:" + widthFourth + "px;" + + "top:" + (heightHalf / 2) + "px;" + + commentHidden; + cssSet( commentEditorContainer, commentEditorContainerStyle ); + commentEditor.resize(); + + // In top subtract height (40px) of comment tool panel. + var commentToolPanelStyle = "width:" + widthHalf + "px;" + + "left:" + widthFourth + "px;" + + "top:" + (height / 4 - 40) + "px;" + + commentHidden; + cssSet( commentToolPanel, commentToolPanelStyle ); + + // Resize dimmer. + var darknessStyle = "width:" + width + "px;" + + "height:" + height + "px;" + + commentHidden; + cssSet(darkness, darknessStyle); + } + + window.jsm.resize = resize; + + /* + Resize can be called an absurd amount of times + and will crash the page without debouncing. + http://benalman.com/projects/jquery-throttle-debounce-plugin/ + https://github.com/cowboy/jquery-throttle-debounce + http://unscriptable.com/2009/03/20/debouncing-javascript-methods/ + */ + $(window).resize( $.debounce( 100, resize ) ); + + // resize for the intial page load + resize(); +})(); From 7154220d0b5da4e5b6aeb01362b1999af53b2f0e Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Mon, 21 May 2012 09:44:19 -0600 Subject: [PATCH 35/51] Updated Home (markdown) --- Home.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Home.md b/Home.md index 6edf0edb..722c2524 100644 --- a/Home.md +++ b/Home.md @@ -1,3 +1 @@ -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque vulputate tincidunt sollicitudin. Quisque sit amet leo sed nunc eleifend rhoncus in consectetur leo. Vivamus posuere semper convallis. Duis malesuada lacus sed erat lobortis tincidunt mattis ligula consectetur. Sed aliquam vulputate eros at euismod. Aenean egestas lorem ligula, quis faucibus turpis. Curabitur a eros in ipsum gravida ornare. Sed elementum enim vel mi scelerisque dapibus. Nulla id libero ligula, quis tempus sem. Morbi nec felis tortor, ac cursus risus. Mauris elementum tortor id lacus eleifend non lobortis tellus pharetra. Etiam posuere cursus vestibulum. $x \lt y$ - -Morbi tincidunt dolor vel massa dictum volutpat. Vestibulum quis nibh metus, id tincidunt nisl. Vivamus eget sem ac risus eleifend rhoncus at eu nisl. Nunc elit massa, vulputate ac gravida eget, condimentum quis justo. Integer scelerisque, libero vel consequat ultricies, eros libero sagittis libero, pellentesque bibendum quam massa ut orci. Maecenas sit amet urna eget quam aliquam posuere. Nulla facilisi. Duis imperdiet augue sit amet metus ornare et hendrerit dui feugiat. Aenean a lacus neque. Sed eu enim tincidunt dolor pharetra porttitor. Vestibulum ut felis dui, rutrum iaculis orci. Duis eu bibendum tortor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Suspendisse mollis sagittis purus sit amet sollicitudin. Phasellus vel interdum erat. \ No newline at end of file +# Hello There \ No newline at end of file From d510c74456b3af0654c1c27179b1ff22f9a3acbd Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Mon, 21 May 2012 09:44:27 -0600 Subject: [PATCH 36/51] Updated Home (markdown) --- Home.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Home.md b/Home.md index 722c2524..6edf0edb 100644 --- a/Home.md +++ b/Home.md @@ -1 +1,3 @@ -# Hello There \ No newline at end of file +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque vulputate tincidunt sollicitudin. Quisque sit amet leo sed nunc eleifend rhoncus in consectetur leo. Vivamus posuere semper convallis. Duis malesuada lacus sed erat lobortis tincidunt mattis ligula consectetur. Sed aliquam vulputate eros at euismod. Aenean egestas lorem ligula, quis faucibus turpis. Curabitur a eros in ipsum gravida ornare. Sed elementum enim vel mi scelerisque dapibus. Nulla id libero ligula, quis tempus sem. Morbi nec felis tortor, ac cursus risus. Mauris elementum tortor id lacus eleifend non lobortis tellus pharetra. Etiam posuere cursus vestibulum. $x \lt y$ + +Morbi tincidunt dolor vel massa dictum volutpat. Vestibulum quis nibh metus, id tincidunt nisl. Vivamus eget sem ac risus eleifend rhoncus at eu nisl. Nunc elit massa, vulputate ac gravida eget, condimentum quis justo. Integer scelerisque, libero vel consequat ultricies, eros libero sagittis libero, pellentesque bibendum quam massa ut orci. Maecenas sit amet urna eget quam aliquam posuere. Nulla facilisi. Duis imperdiet augue sit amet metus ornare et hendrerit dui feugiat. Aenean a lacus neque. Sed eu enim tincidunt dolor pharetra porttitor. Vestibulum ut felis dui, rutrum iaculis orci. Duis eu bibendum tortor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Suspendisse mollis sagittis purus sit amet sollicitudin. Phasellus vel interdum erat. \ No newline at end of file From 3d5931c259893a4cfc4976cdc5cdb19e645b5100 Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Mon, 21 May 2012 09:44:52 -0600 Subject: [PATCH 37/51] Updated Home (markdown) --- Home.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Home.md b/Home.md index 6edf0edb..722c2524 100644 --- a/Home.md +++ b/Home.md @@ -1,3 +1 @@ -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque vulputate tincidunt sollicitudin. Quisque sit amet leo sed nunc eleifend rhoncus in consectetur leo. Vivamus posuere semper convallis. Duis malesuada lacus sed erat lobortis tincidunt mattis ligula consectetur. Sed aliquam vulputate eros at euismod. Aenean egestas lorem ligula, quis faucibus turpis. Curabitur a eros in ipsum gravida ornare. Sed elementum enim vel mi scelerisque dapibus. Nulla id libero ligula, quis tempus sem. Morbi nec felis tortor, ac cursus risus. Mauris elementum tortor id lacus eleifend non lobortis tellus pharetra. Etiam posuere cursus vestibulum. $x \lt y$ - -Morbi tincidunt dolor vel massa dictum volutpat. Vestibulum quis nibh metus, id tincidunt nisl. Vivamus eget sem ac risus eleifend rhoncus at eu nisl. Nunc elit massa, vulputate ac gravida eget, condimentum quis justo. Integer scelerisque, libero vel consequat ultricies, eros libero sagittis libero, pellentesque bibendum quam massa ut orci. Maecenas sit amet urna eget quam aliquam posuere. Nulla facilisi. Duis imperdiet augue sit amet metus ornare et hendrerit dui feugiat. Aenean a lacus neque. Sed eu enim tincidunt dolor pharetra porttitor. Vestibulum ut felis dui, rutrum iaculis orci. Duis eu bibendum tortor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Suspendisse mollis sagittis purus sit amet sollicitudin. Phasellus vel interdum erat. \ No newline at end of file +# Hello There \ No newline at end of file From f3e58165472147bf490116adb209f430e7e14ee6 Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Mon, 21 May 2012 09:45:08 -0600 Subject: [PATCH 38/51] Updated Home (markdown) --- Home.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Home.md b/Home.md index 722c2524..9043db5b 100644 --- a/Home.md +++ b/Home.md @@ -1 +1 @@ -# Hello There \ No newline at end of file +# Hi 2 \ No newline at end of file From 66e7f240da72806cb8c75bfe4b05491fae7b5936 Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Mon, 21 May 2012 09:45:14 -0600 Subject: [PATCH 39/51] Updated Home (markdown) --- Home.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Home.md b/Home.md index 9043db5b..1b40b873 100644 --- a/Home.md +++ b/Home.md @@ -1 +1 @@ -# Hi 2 \ No newline at end of file +# Hi 3 \ No newline at end of file From 4380aa980395384c50fdc3ba75677e796b03d95f Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Mon, 21 May 2012 09:45:39 -0600 Subject: [PATCH 40/51] Updated Home (markdown) --- Home.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Home.md b/Home.md index 1b40b873..7e18ee17 100644 --- a/Home.md +++ b/Home.md @@ -1 +1 @@ -# Hi 3 \ No newline at end of file +# Hi 4 \ No newline at end of file From 1d55ed05999f6576b4d19a948f5a0a96a1184c89 Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Mon, 21 May 2012 09:49:12 -0600 Subject: [PATCH 41/51] Updated Home (markdown) --- Home.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Home.md b/Home.md index 7e18ee17..9e3b2f81 100644 --- a/Home.md +++ b/Home.md @@ -1 +1 @@ -# Hi 4 \ No newline at end of file +# Hi 5 \ No newline at end of file From 5be5cd5ba5150266f18ab256a0ad31bed7953d0c Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Mon, 21 May 2012 09:49:22 -0600 Subject: [PATCH 42/51] Updated Home (markdown) --- Home.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Home.md b/Home.md index 9e3b2f81..e69d3e04 100644 --- a/Home.md +++ b/Home.md @@ -1 +1 @@ -# Hi 5 \ No newline at end of file +# Hi 6 \ No newline at end of file From 5c642997fe984ed9e323efba5c39875cdf47b6d6 Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Mon, 21 May 2012 09:50:23 -0600 Subject: [PATCH 43/51] Origin is undefined in Firefox. --- .../public/gollum/livepreview/js/livepreview/livepreview.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/gollum/frontend/public/gollum/livepreview/js/livepreview/livepreview.js b/lib/gollum/frontend/public/gollum/livepreview/js/livepreview/livepreview.js index 98d15af9..b79a73ac 100644 --- a/lib/gollum/frontend/public/gollum/livepreview/js/livepreview/livepreview.js +++ b/lib/gollum/frontend/public/gollum/livepreview/js/livepreview/livepreview.js @@ -72,7 +72,7 @@ $.save = function( commitMessage ) { var markdown = "markdown"; var txt = editorSession.getValue(); var msg = defaultCommitMessage(); - var newLocation = window.location.origin + "/" + pageName; + var newLocation = window.location.protocol + "//" + window.location.host + "/" + pageName; // if &create=true then handle create instead of edit. if (create) { From 7f17102c861f31850122c0ec2868988a6f15b67f Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Mon, 21 May 2012 10:00:06 -0600 Subject: [PATCH 44/51] Remove home.md. --- Home.md | 1 - 1 file changed, 1 deletion(-) delete mode 100644 Home.md diff --git a/Home.md b/Home.md deleted file mode 100644 index e69d3e04..00000000 --- a/Home.md +++ /dev/null @@ -1 +0,0 @@ -# Hi 6 \ No newline at end of file From 444fca22509ecd330c7123ca2d70afcf6b99bd37 Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Mon, 21 May 2012 10:02:55 -0600 Subject: [PATCH 45/51] Revert changes to Home. --- Home.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Home.md diff --git a/Home.md b/Home.md new file mode 100644 index 00000000..6edf0edb --- /dev/null +++ b/Home.md @@ -0,0 +1,3 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque vulputate tincidunt sollicitudin. Quisque sit amet leo sed nunc eleifend rhoncus in consectetur leo. Vivamus posuere semper convallis. Duis malesuada lacus sed erat lobortis tincidunt mattis ligula consectetur. Sed aliquam vulputate eros at euismod. Aenean egestas lorem ligula, quis faucibus turpis. Curabitur a eros in ipsum gravida ornare. Sed elementum enim vel mi scelerisque dapibus. Nulla id libero ligula, quis tempus sem. Morbi nec felis tortor, ac cursus risus. Mauris elementum tortor id lacus eleifend non lobortis tellus pharetra. Etiam posuere cursus vestibulum. $x \lt y$ + +Morbi tincidunt dolor vel massa dictum volutpat. Vestibulum quis nibh metus, id tincidunt nisl. Vivamus eget sem ac risus eleifend rhoncus at eu nisl. Nunc elit massa, vulputate ac gravida eget, condimentum quis justo. Integer scelerisque, libero vel consequat ultricies, eros libero sagittis libero, pellentesque bibendum quam massa ut orci. Maecenas sit amet urna eget quam aliquam posuere. Nulla facilisi. Duis imperdiet augue sit amet metus ornare et hendrerit dui feugiat. Aenean a lacus neque. Sed eu enim tincidunt dolor pharetra porttitor. Vestibulum ut felis dui, rutrum iaculis orci. Duis eu bibendum tortor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Suspendisse mollis sagittis purus sit amet sollicitudin. Phasellus vel interdum erat. \ No newline at end of file From 484629734ea768b68c5b62ac2e1d11d2c45841c9 Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Mon, 21 May 2012 10:17:05 -0600 Subject: [PATCH 46/51] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 909a42c8..dcfbf169 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ utility, you can run it like so: $ gollum --help +Note that the gollum server will not run on Windows because of [an issue](https://github.com/rtomayko/posix-spawn/issues/9) with posix-spawn. ## REPO STRUCTURE From aa7e01a0856cb29f9f60bf60448d2d67ab20d9fd Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Mon, 21 May 2012 10:27:16 -0600 Subject: [PATCH 47/51] Add unload confirmation on live preview, edit, and create. --- .../public/gollum/livepreview/js/livepreview/livepreview.js | 2 ++ lib/gollum/frontend/templates/create.mustache | 3 ++- lib/gollum/frontend/templates/edit.mustache | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/gollum/frontend/public/gollum/livepreview/js/livepreview/livepreview.js b/lib/gollum/frontend/public/gollum/livepreview/js/livepreview/livepreview.js index b79a73ac..2dcff06d 100644 --- a/lib/gollum/frontend/public/gollum/livepreview/js/livepreview/livepreview.js +++ b/lib/gollum/frontend/public/gollum/livepreview/js/livepreview/livepreview.js @@ -1,4 +1,6 @@ (function () { +window.onbeforeunload = function(){ return "Leaving Live Preview will discard all edits!" }; + var converter = Markdown.getSanitizingConverter(); var editor = ace.edit("editor"); var editorSession = editor.getSession(); diff --git a/lib/gollum/frontend/templates/create.mustache b/lib/gollum/frontend/templates/create.mustache index c24c09ae..64dbabde 100644 --- a/lib/gollum/frontend/templates/create.mustache +++ b/lib/gollum/frontend/templates/create.mustache @@ -9,9 +9,10 @@
-{{something}} \ No newline at end of file +{{something}} diff --git a/lib/gollum/frontend/templates/edit.mustache b/lib/gollum/frontend/templates/edit.mustache index 014c719a..527eaa83 100644 --- a/lib/gollum/frontend/templates/edit.mustache +++ b/lib/gollum/frontend/templates/edit.mustache @@ -11,7 +11,8 @@
{{>editor}}
\ No newline at end of file + From 14f16349c09754c5e84d4d2f7b9163ea91dc7efd Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Mon, 21 May 2012 10:35:29 -0600 Subject: [PATCH 48/51] Remove unload on save. --- .../public/gollum/livepreview/js/livepreview/livepreview.js | 2 ++ lib/gollum/frontend/templates/create.mustache | 2 ++ lib/gollum/frontend/templates/edit.mustache | 2 ++ 3 files changed, 6 insertions(+) diff --git a/lib/gollum/frontend/public/gollum/livepreview/js/livepreview/livepreview.js b/lib/gollum/frontend/public/gollum/livepreview/js/livepreview/livepreview.js index 2dcff06d..c8926ab3 100644 --- a/lib/gollum/frontend/public/gollum/livepreview/js/livepreview/livepreview.js +++ b/lib/gollum/frontend/public/gollum/livepreview/js/livepreview/livepreview.js @@ -70,6 +70,8 @@ defaultCommitMessage = function() { commentEditorSession.setValue( defaultCommitMessage() ); $.save = function( commitMessage ) { + window.onbeforeunload = null; + var POST = "POST"; var markdown = "markdown"; var txt = editorSession.getValue(); diff --git a/lib/gollum/frontend/templates/create.mustache b/lib/gollum/frontend/templates/create.mustache index 64dbabde..0fd92af2 100644 --- a/lib/gollum/frontend/templates/create.mustache +++ b/lib/gollum/frontend/templates/create.mustache @@ -10,6 +10,8 @@