+ HTML
+ end
+
+ def render_files
+ html = ''
+ count = @pages.size
+ folder_start = -1
+
+ # Process all pages until folders start
+ count.times do | index |
+ page = @pages[ index ]
+ path = page.path
+
+ unless path.include? '/'
+ # Page processed (not contained in a folder)
+ html += new_page page
+ else
+ # Folders start at the next index
+ folder_start = index
+ break # Pages finished, move on to folders
+ end
+ end
+
+ # If there are no folders, then we're done.
+ return enclose_tree(html) if folder_start <= -1
+
+ # Handle special case of only one folder.
+ if (count - folder_start == 1)
+ path = @pages[ folder_start ]
+ name = page.name
+ html += <<-HTML
+
+ HTML
+
+ return enclose_tree html
+ end
+
+ sorted_folders = []
+ (folder_start).upto count - 1 do | index |
+ sorted_folders += [[ @pages[ index ].path, index ]]
+ end
+
+ # http://stackoverflow.com/questions/3482814/sorting-list-of-string-paths-in-vb-net
+ sorted_folders.sort! do |first,second|
+ a = first[0]
+ b = second[0]
+
+ # use :: operator because gollum defines its own conflicting File class
+ dir_compare = ::File.dirname(a) <=> ::File.dirname(b)
+
+ # Sort based on directory name unless they're equal (0) in
+ # which case sort based on file name.
+ if dir_compare == 0
+ ::File.basename(a) <=> ::File.basename(b)
+ else
+ dir_compare
+ end
+ end
+
+ # Process first folder
+ page = @pages[ sorted_folders[ 0 ][1] ]
+ html += new_folder page
+
+ last_folder = ::File.dirname page.path # define last_folder
+
+ # keep track of folder depth, 0 = at root.
+ depth = 0
+
+ # process rest of folders
+ 1.upto(sorted_folders.size - 1) do | index |
+ page = @pages[ sorted_folders[ index ][1] ]
+ path = page.path
+ folder = ::File.dirname path
+
+ if last_folder == folder
+ # same folder
+ html += new_page page
+ elsif folder.include?('/')
+ # check if we're going up or down a depth level
+ if last_folder.scan('/').size > folder.scan('/').size
+ # end tag for 1 subfolder & 1 parent folder
+ # so emit 2 end tags
+ 2.times { html += end_folder; }
+ depth -= 1
+ else
+ depth += 1
+ end
+
+ # subfolder
+ html += new_sub_folder ::File.dirname(page.path).split('/').last, page.name
+ else
+ # depth+1 because we need an additional end_folder
+ (depth+1).times { html += end_folder; }
+ depth = 0
+ # New root folder
+ html += new_folder page
+ end
+
+ last_folder = folder
+ end
+
+ # Process last folder's ending tags.
+ (depth+1).times {
+ depth.times { html += end_folder; }
+ depth = 0
+ }
+
+ # return the completed html
+ enclose_tree html
+ end # end render_files
+ end # end FileView class
+end # end Gollum module
diff --git a/lib/gollum/frontend/app.rb b/lib/gollum/frontend/app.rb
index 07bcb474..ebd4d999 100644
--- a/lib/gollum/frontend/app.rb
+++ b/lib/gollum/frontend/app.rb
@@ -212,6 +212,17 @@ module Precious
mustache :pages
end
+ get '/fileview' do
+ wiki = Gollum::Wiki.new(settings.gollum_path, settings.wiki_options)
+ @results = Gollum::FileView.new(wiki.pages).render_files
+ File.open('/tmp/log.txt', 'w') {|f|
+ f.puts "log!"
+ f.puts @results
+ }
+ @ref = wiki.ref
+ mustache :file_view
+ end
+
get '/*' do
show_page_or_file(params[:splat].first)
end
diff --git a/lib/gollum/frontend/public/gollum/css/_styles.css b/lib/gollum/frontend/public/gollum/css/_styles.css
new file mode 100644
index 00000000..d70f29ed
--- /dev/null
+++ b/lib/gollum/frontend/public/gollum/css/_styles.css
@@ -0,0 +1,110 @@
+/* Just some base styles not needed for example to function */
+*, html { font-family: Verdana, Arial, Helvetica, sans-serif; }
+
+
+#results a:hover {
+ background-color: #4c4c4c;
+}
+
+#home_button {
+ position: absolute;
+ top: 10px;
+ left: 50%;
+}
+
+#home_button .minibutton {
+/* controls size of home btn */
+font-size: 1em;
+text-align: center;
+}
+
+#results {
+ position: absolute;
+ top: 60px;
+ left: 10px;
+}
+
+
+body, form, ul, li, p, h1, h2, h3, h4, h5
+{
+ margin: 0;
+ padding: 0;
+}
+body { background-color: #606061; color: #ffffff; margin: 0; }
+img { border: none; }
+p
+{
+ font-size: 1em;
+ margin: 0 0 1em 0;
+}
+
+html { font-size: 100%; /* IE hack */ }
+body { font-size: 1em; /* Sets base font size to 16px */ }
+table { font-size: 100%; /* IE hack */ }
+input, select, textarea, th, td { font-size: 1em; }
+
+/* CSS Tree menu styles */
+ol.tree
+{
+ padding: 0 0 0 30px;
+ width: 300px;
+}
+ li
+ {
+ position: relative;
+ margin-left: -15px;
+ list-style: none;
+ }
+ li.file
+ {
+ margin-left: -1px !important;
+ height: 1.5em;
+ }
+ li.file a
+ {
+ background: url(/images/fileview/document.png) 0 0 no-repeat;
+ color: #fff;
+ padding-left: 21px;
+ text-decoration: none;
+ display: block;
+ }
+ li.file a[href *= '.pdf'] { background: url(/images/fileview/document.png) 0 0 no-repeat; }
+ li.file a[href *= '.html'] { background: url(/images/fileview/document.png) 0 0 no-repeat; }
+ li.file a[href $= '.css'] { background: url(/images/fileview/document.png) 0 0 no-repeat; }
+ li.file a[href $= '.js'] { background: url(/images/fileview/document.png) 0 0 no-repeat; }
+ li input
+ {
+ position: absolute;
+ left: 0;
+ margin-left: 0;
+ opacity: 0;
+ z-index: 2;
+ cursor: pointer;
+ height: 1em;
+ width: 1em;
+ top: 0;
+ }
+ li input + ol
+ {
+ background: url(/images/fileview/toggle-small-expand.png) 40px 0 no-repeat;
+ margin: -1.188em 0 0 -44px; /* 15px */
+ height: 1.5em;
+ }
+ li input + ol > li { display: none; margin-left: -14px !important; padding-left: 1px; }
+ li label
+ {
+ background: url(/images/fileview/folder-horizontal.png) 15px 1px no-repeat;
+ cursor: pointer;
+ display: block;
+ padding-left: 37px;
+ }
+
+ li input:checked + ol
+ {
+ background: url(/images/fileview/toggle-small.png) 40px 5px no-repeat;
+ margin: -1.5em 0 0 -44px; /* 20px */
+ padding: 1.563em 0 0 80px;
+ height: auto;
+ }
+ li input:checked + ol > li { display: block; margin: 0 0 0.125em; /* 2px */}
+ li input:checked + ol > li:last-child { margin: 0 0 0.063em; /* 1px */ }
diff --git a/lib/gollum/frontend/public/gollum/images/fileview/document.png b/lib/gollum/frontend/public/gollum/images/fileview/document.png
new file mode 100644
index 00000000..f125928c
Binary files /dev/null and b/lib/gollum/frontend/public/gollum/images/fileview/document.png differ
diff --git a/lib/gollum/frontend/public/gollum/images/fileview/folder-horizontal.png b/lib/gollum/frontend/public/gollum/images/fileview/folder-horizontal.png
new file mode 100644
index 00000000..58e5cf7a
Binary files /dev/null and b/lib/gollum/frontend/public/gollum/images/fileview/folder-horizontal.png differ
diff --git a/lib/gollum/frontend/public/gollum/images/fileview/toggle-small-expand.png b/lib/gollum/frontend/public/gollum/images/fileview/toggle-small-expand.png
new file mode 100644
index 00000000..969f5e8a
Binary files /dev/null and b/lib/gollum/frontend/public/gollum/images/fileview/toggle-small-expand.png differ
diff --git a/lib/gollum/frontend/public/gollum/images/fileview/toggle-small.png b/lib/gollum/frontend/public/gollum/images/fileview/toggle-small.png
new file mode 100644
index 00000000..700af04c
Binary files /dev/null and b/lib/gollum/frontend/public/gollum/images/fileview/toggle-small.png differ
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/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 00000000..98fd3024
Binary files /dev/null and b/lib/gollum/frontend/public/gollum/livepreview/images/cancel_24.png differ
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 00000000..38d7d41a
Binary files /dev/null and b/lib/gollum/frontend/public/gollum/livepreview/images/savecomment_24.png differ
diff --git a/lib/gollum/frontend/public/gollum/livepreview/index.html b/lib/gollum/frontend/public/gollum/livepreview/index.html
index f002a2c1..f2bfbbbc 100644
--- a/lib/gollum/frontend/public/gollum/livepreview/index.html
+++ b/lib/gollum/frontend/public/gollum/livepreview/index.html
@@ -1,10 +1,28 @@
-JavaScript Markdown Editor
-
+Live Preview
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -13,249 +31,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
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/js/livepreview/livepreview.js b/lib/gollum/frontend/public/gollum/livepreview/js/livepreview/livepreview.js
new file mode 100644
index 00000000..c8926ab3
--- /dev/null
+++ b/lib/gollum/frontend/public/gollum/livepreview/js/livepreview/livepreview.js
@@ -0,0 +1,361 @@
+(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();
+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 ) {
+ window.onbeforeunload = null;
+
+ var POST = "POST";
+ var markdown = "markdown";
+ var txt = editorSession.getValue();
+ var msg = defaultCommitMessage();
+ var newLocation = window.location.protocol + "//" + window.location.host + "/" + 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();
+})();
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..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
@@ -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);
@@ -1021,16 +1024,17 @@ else
function _DoCodeSpansGollum(text) {
//
// Gollum wraps code in one pre. Use ` to mark code pre.
- // All regex set to use 'm' multiline option.
+ // Gollum requires exactly three starting and ending `.
//
- 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
- 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 + "
`" + c + "
";
+ return m1 + hashBlock("
`" + c + "
");
}
);
@@ -1146,8 +1150,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 +1158,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, "
{{#editable}}
diff --git a/lib/gollum/frontend/views/file_view.rb b/lib/gollum/frontend/views/file_view.rb
new file mode 100644
index 00000000..383fcad2
--- /dev/null
+++ b/lib/gollum/frontend/views/file_view.rb
@@ -0,0 +1,19 @@
+module Precious
+ module Views
+ class FileView < Layout
+ attr_reader :results, :ref
+
+ def title
+ "All pages in #{@ref}"
+ end
+
+ def has_results
+ !@results.empty?
+ end
+
+ def no_results
+ @results.empty?
+ end
+ end
+ end
+end
diff --git a/licenses/css_tree_menu_thecssninja/license.txt b/licenses/css_tree_menu_thecssninja/license.txt
new file mode 100644
index 00000000..55a2604a
--- /dev/null
+++ b/licenses/css_tree_menu_thecssninja/license.txt
@@ -0,0 +1,50 @@
+The MIT License
+
+Copyright (c) 2010 Ryan Seddon
+
+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.
+
+=============================================================================
+
+BSD License
+
+Copyright (c) 2010, Ryan Seddon
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. Neither the name of the organization nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDER "AS IS" AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/licenses/licenses.txt b/licenses/licenses.txt
new file mode 100644
index 00000000..1253cc18
--- /dev/null
+++ b/licenses/licenses.txt
@@ -0,0 +1,23 @@
+The following PNGs are based on Ubuntu 11.10 SVG files located in /usr/share/icons/unity-icon-theme/places/svg/
+- group-folders.svg
+- group-files.svg
+- group-downloads.svg
+
+ lib/gollum/frontend/public/css/document.png
+ lib/gollum/frontend/public/css/folder-horizontal.png
+ lib/gollum/frontend/public/css/toggle-small-expand.png
+ lib/gollum/frontend/public/css/toggle-small.png
+
+Creative Commons - Attribution Share Alike
+https://launchpad.net/unity-asset-pool
+http://packages.ubuntu.com/oneiric/all/unity-asset-pool/filelist
+https://bazaar.launchpad.net/~unity-team/unity-asset-pool/trunk/view/head:/COPYRIGHT
+
+---
+
+The css-tree-menu code is used under the MIT license.
+
+http://www.thecssninja.com/css/css-tree-menu
+http://www.thecssninja.com/demo/license.txt
+
+ lib/gollum/frontend/public/css/_styles.css
diff --git a/licenses/unity_asset_pool/COPYRIGHT b/licenses/unity_asset_pool/COPYRIGHT
new file mode 100644
index 00000000..96c0ac1b
--- /dev/null
+++ b/licenses/unity_asset_pool/COPYRIGHT
@@ -0,0 +1,286 @@
+This package was debianized by Kenneth Wimer on
+Fri, 12 Dec 2010 9:08:32 +0200.
+
+Upstream Author:
+ Michael Forrest
+ Otto Greenslade
+
+Copyright:
+
+(c) Canonical Ltd 2004- 2009
+
+Unless otherwise indicated, artwork is available under the Creative
+Commons Attribution Share-alike license v3.0 or any later version. To
+view a copy of this license, visit
+http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to
+Creative Commons, 171 Second Street, Suite 300, San Francisco,
+California, 94105, USA. See below for the full text of the license.
+
+Some Rights Reserved:
+
+The rights in the trademarks, logos, service marks of Canonical Ltd,
+as well as the look and feel of Ubuntu, are not licensed under the
+Creative Commons license and are subject to the Canonical Trademark
+Policy at http://www.ubuntu.com/ubuntu/TrademarkPolicy
+
+License:
+
+CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN
+ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
+INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
+REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR
+DAMAGES RESULTING FROM ITS USE.
+
+License
+
+THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS
+CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS
+PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE
+WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW
+IS PROHIBITED.
+
+BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND
+AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU
+THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH
+TERMS AND CONDITIONS.
+
+1. Definitions
+
+ 1. "Collective Work" means a work, such as a periodical issue,
+ anthology or encyclopedia, in which the Work in its entirety in
+ unmodified form, along with a number of other contributions,
+ constituting separate and independent works in themselves, are
+ assembled into a collective whole. A work that constitutes a
+ Collective Work will not be considered a Derivative Work
+ (as defined below) for the purposes of this License.
+ 2. "Derivative Work" means a work based upon the Work or upon the
+ Work and other pre-existing works, such as a translation, musical
+ arrangement, dramatization, fictionalization, motion picture
+ version, sound recording, art reproduction, abridgment,
+ condensation, or any other form in which the Work may be recast,
+ transformed, or adapted, except that a work that constitutes a
+ Collective Work will not be considered a Derivative Work for the
+ purpose of this License. For the avoidance of doubt, where the Work
+ is a musical composition or sound recording, the synchronization of
+ the Work in timed-relation with a moving image ("synching") will be
+ considered a Derivative Work for the purpose of this License.
+ 3. "Licensor" means the individual or entity that offers the Work
+ under the terms of this License.
+ 4. "Original Author" means the individual or entity who created the
+ Work.
+ 5. "Work" means the copyrightable work of authorship offered under
+ the terms of this License.
+ 6. "You" means an individual or entity exercising rights under this
+ License who has not previously violated the terms of this License
+ with respect to the Work, or who has received express permission
+ from the Licensor to exercise rights under this License despite a
+ previous violation.
+ 7. "License Elements" means the following high-level license
+ attributes as selected by Licensor and indicated in the title of
+ this License: Attribution, ShareAlike.
+
+2. Fair Use Rights. Nothing in this license is intended to reduce,
+limit, or restrict any rights arising from fair use, first sale or
+other limitations on the exclusive rights of the copyright owner under
+copyright law or other applicable laws.
+
+3. License Grant. Subject to the terms and conditions of this License,
+Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
+perpetual (for the duration of the applicable copyright) license to
+exercise the rights in the Work as stated below:
+
+ 1. to reproduce the Work, to incorporate the Work into one or more
+ Collective Works, and to reproduce the Work as incorporated in the
+ Collective Works;
+ 2. to create and reproduce Derivative Works;
+ 3. to distribute copies or phonorecords of, display publicly,
+ perform publicly, and perform publicly by means of a digital audio
+ transmission the Work including as incorporated in Collective Works;
+ 4. to distribute copies or phonorecords of, display publicly,
+ perform publicly, and perform publicly by means of a digital audio
+ transmission Derivative Works.
+ 5.
+
+ For the avoidance of doubt, where the work is a musical
+ composition:
+ 1. Performance Royalties Under Blanket Licenses. Licensor
+ waives the exclusive right to collect, whether individually
+ or via a performance rights society (e.g. ASCAP, BMI, SESAC),
+ royalties for the public performance or public digital
+ performance (e.g. webcast) of the Work.
+ 2. Mechanical Rights and Statutory Royalties. Licensor waives
+ the exclusive right to collect, whether individually or via a
+ music rights society or designated agent (e.g. Harry Fox
+ Agency), royalties for any phonorecord You create from the
+ Work ("cover version") and distribute, subject to the
+ compulsory license created by 17 USC Section 115 of the US
+ Copyright Act (or the equivalent in other jurisdictions).
+ 6. Webcasting Rights and Statutory Royalties. For the avoidance of
+ doubt, where the Work is a sound recording, Licensor waives the
+ exclusive right to collect, whether individually or via a
+ performance-rights society (e.g. SoundExchange), royalties for the
+ public digital performance (e.g. webcast) of the Work, subject to
+ the compulsory license created by 17 USC Section 114 of the US
+ Copyright Act (or the equivalent in other jurisdictions).
+
+The above rights may be exercised in all media and formats whether now
+known or hereafter devised. The above rights include the right to make
+such modifications as are technically necessary to exercise the rights
+in other media and formats. All rights not expressly granted by
+Licensor are hereby reserved.
+
+4. Restrictions.The license granted in Section 3 above is expressly
+made subject to and limited by the following restrictions:
+
+ 1. You may distribute, publicly display, publicly perform, or
+ publicly digitally perform the Work only under the terms of this
+ License, and You must include a copy of, or the Uniform Resource
+ Identifier for, this License with every copy or phonorecord of the
+ Work You distribute, publicly display, publicly perform, or publicly
+ digitally perform. You may not offer or impose any terms on the Work
+ that alter or restrict the terms of this License or the recipients'
+ exercise of the rights granted hereunder. You may not sublicense the
+ Work. You must keep intact all notices that refer to this License
+ and to the disclaimer of warranties. You may not distribute,
+ publicly display, publicly perform, or publicly digitally perform
+ the Work with any technological measures that control access or use
+ of the Work in a manner inconsistent with the terms of this License
+ Agreement. The above applies to the Work as incorporated in a
+ Collective Work, but this does not require the Collective Work apart
+ from the Work itself to be made subject to the terms of this
+ License. If You create a Collective Work, upon notice from any
+ Licensor You must, to the extent practicable, remove from the
+ Collective Work any credit as required by clause 4(c), as requested.
+ If You create a Derivative Work, upon notice from any Licensor You
+ must, to the extent practicable, remove from the Derivative Work
+ any credit as required by clause 4(c), as requested.
+ 2. You may distribute, publicly display, publicly perform, or
+ publicly digitally perform a Derivative Work only under the terms
+ of this License, a later version of this License with the same
+ License Elements as this License, or a Creative Commons iCommons
+ license that contains the same License Elements as this License
+ (e.g. Attribution-ShareAlike 2.5 Japan). You must include a copy of,
+ or the Uniform Resource Identifier for, this License or other
+ license specified in the previous sentence with every copy or
+ phonorecord of each Derivative Work You distribute, publicly
+ display, publicly perform, or publicly digitally perform. You may
+ not offer or impose any terms on the Derivative Works that alter or
+ restrict the terms of this License or the recipients' exercise of
+ the rights granted hereunder, and You must keep intact all notices
+ that refer to this License and to the disclaimer of warranties.
+ You may not distribute, publicly display, publicly perform, or
+ publicly digitally perform the Derivative Work with any
+ technological measures that control access or use of the Work in a
+ manner inconsistent with the terms of this License Agreement.
+ The above applies to the Derivative Work as incorporated in a
+ Collective Work, but this does not require the Collective Work
+ apart from the Derivative Work itself to be made subject to the
+ terms of this License.
+ 3. If you distribute, publicly display, publicly perform, or
+ publicly digitally perform the Work or any Derivative Works or
+ Collective Works, You must keep intact all copyright notices for
+ the Work and provide, reasonable to the medium or means You are
+ utilizing: (i) the name of the Original Author (or pseudonym, if
+ applicable) if supplied, and/or (ii) if the Original Author and/or
+ Licensor designate another party or parties (e.g. a sponsor
+ institute, publishing entity, journal) for attribution in Licensor's
+ copyright notice, terms of service or by other reasonable means, the
+ name of such party or parties; the title of the Work if supplied; to
+ the extent reasonably practicable, the Uniform Resource Identifier,
+ if any, that Licensor specifies to be associated with the Work,
+ unless such URI does not refer to the copyright notice or licensing
+ information for the Work; and in the case of a Derivative Work, a
+ credit identifying the use of the Work in the Derivative Work (e.g.,
+ "French translation of the Work by Original Author," or "Screenplay
+ based on original Work by Original Author"). Such credit may be
+ implemented in any reasonable manner; provided, however, that in the
+ case of a Derivative Work or Collective Work, at a minimum such
+ credit will appear where any other comparable authorship credit
+ appears and in a manner at least as prominent as such other
+ comparable authorship credit.
+
+5. Representations, Warranties and Disclaimer
+
+UNLESS OTHERWISE AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS
+THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND
+CONCERNING THE MATERIALS, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
+INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
+FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
+LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF
+ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW
+THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY
+TO YOU.
+
+6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE
+LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR
+ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES
+ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR
+HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. Termination
+
+ 1. This License and the rights granted hereunder will terminate
+ automatically upon any breach by You of the terms of this License.
+ Individuals or entities who have received Derivative Works or
+ Collective Works from You under this License, however, will not have
+ their licenses terminated provided such individuals or entities
+ remain in full compliance with those licenses. Sections 1, 2, 5, 6,
+ 7, and 8 will survive any termination of this License.
+ 2. Subject to the above terms and conditions, the license granted
+ here is perpetual (for the duration of the applicable copyright in
+ the Work). Notwithstanding the above, Licensor reserves the right to
+ release the Work under different license terms or to stop
+ distributing the Work at any time; provided, however that any such
+ election will not serve to withdraw this License (or any other
+ license that has been, or is required to be, granted under the terms
+ of this License), and this License will continue in full force and
+ effect unless terminated as stated above.
+
+8. Miscellaneous
+
+ 1. Each time You distribute or publicly digitally perform the Work
+ or a Collective Work, the Licensor offers to the recipient a license
+ to the Work on the same terms and conditions as the license granted
+ to You under this License.
+ 2. Each time You distribute or publicly digitally perform a
+ Derivative Work, Licensor offers to the recipient a license to the
+ original Work on the same terms and conditions as the license
+ granted to You under this License.
+ 3. If any provision of this License is invalid or unenforceable under
+ applicable law, it shall not affect the validity or enforceability of
+ the remainder of the terms of this License, and without further
+ action by the parties to this agreement, such provision shall be
+ reformed to the minimum extent necessary to make such provision
+ valid and enforceable.
+ 4. No term or provision of this License shall be deemed waived and
+ no breach consented to unless such waiver or consent shall be in
+ writing and signed by the party to be charged with such waiver or
+ consent.
+ 5. This License constitutes the entire agreement between the parties
+ with respect to the Work licensed here. There are no understandings,
+ agreements or representations with respect to the Work not specified
+ here. Licensor shall not be bound by any additional provisions that
+ may appear in any communication from You. This License may not be
+ modified without the mutual written agreement of the Licensor and
+ You.
+
+Creative Commons is not a party to this License, and makes no warranty
+whatsoever in connection with the Work. Creative Commons will not be
+liable to You or any party on any legal theory for any damages
+whatsoever, including without limitation any general, special,
+incidental or consequential damages arising in connection to this
+license. Notwithstanding the foregoing two (2) sentences, if Creative
+Commons has expressly identified itself as the Licensor hereunder,
+it shall have all rights and obligations of Licensor.
+
+Except for the limited purpose of indicating to the public that the
+Work is licensed under the CCPL, neither party will use the trademark
+"Creative Commons" or any related trademark or logo of Creative Commons
+without the prior written consent of Creative Commons. Any permitted
+use will be in compliance with Creative Commons' then-current trademark
+usage guidelines, as may be published on its website or otherwise made
+available upon request from time to time.
+
+Creative Commons may be contacted at http://creativecommons.org/
+