diff --git a/.gitmodules b/.gitmodules
index 255017267..6794840bd 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,3 @@
[submodule "libgit2"]
- path = libgit2
- url = git://github.com/pieter/libgit2.git
+ path = libgit2
+ url = git://repo.or.cz/libgit2.git
\ No newline at end of file
diff --git a/BMDefines.h b/BMDefines.h
new file mode 100644
index 000000000..02a874fab
--- /dev/null
+++ b/BMDefines.h
@@ -0,0 +1,298 @@
+//
+// BMDefines.h
+// BMScriptTest
+//
+// Created by Andre Berg on 27.09.09.
+// Copyright 2009 Berg Media. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/*!
+ * @file BMDefines.h
+ *
+ * Provides defines mostly for debugging.
+ * This file may be included by any project as it does not really contain project-specific symbols.
+ * Consists mainly of stuff I have gathered from multiple sources or defined in my own work to help
+ * ease debugging and/or cross-platform development.
+ */
+
+#import
clipboardSwf
is configured.
+ */
+ copyToClipboard : function(highlighter)
+ {
+ var flashDiv, flashSwf,
+ highlighterId = highlighter.id
+ ;
+
+ this.create = function()
+ {
+ var config = sh.config;
+
+ // disable functionality if running locally
+ if (config.clipboardSwf == null)
+ return null;
+
+ function params(list)
+ {
+ var result = '';
+
+ for (var name in list)
+ result += "";
+
+ return result;
+ };
+
+ function attributes(list)
+ {
+ var result = '';
+
+ for (var name in list)
+ result += " " + name + "='" + list[name] + "'";
+
+ return result;
+ };
+
+ var args1 = {
+ width : config.toolbarItemWidth,
+ height : config.toolbarItemHeight,
+ id : highlighterId + '_clipboard',
+ type : 'application/x-shockwave-flash',
+ title : sh.config.strings.copyToClipboard
+ },
+
+ // these arguments are used in IE's collection
+ args2 = {
+ allowScriptAccess : 'always',
+ wmode : 'transparent',
+ flashVars : 'highlighterId=' + highlighterId,
+ menu : 'false'
+ },
+ swf = config.clipboardSwf,
+ html
+ ;
+
+ if (/msie/i.test(navigator.userAgent))
+ {
+ html = ''
+ ;
+ }
+ else
+ {
+ html = ''
+ ;
+ }
+
+ flashDiv = document.createElement('div');
+ flashDiv.innerHTML = html;
+
+ return flashDiv;
+ };
+
+ this.execute = function(sender, event, args)
+ {
+ var command = args.command;
+
+ switch (command)
+ {
+ case 'get':
+ var code = sh.utils.unindent(
+ sh.utils.fixInputString(highlighter.originalCode)
+ .replace(/</g, '<')
+ .replace(/>/g, '>')
+ .replace(/&/g, '&')
+ );
+
+ if(window.clipboardData)
+ // will fall through to the confirmation because there isn't a break
+ window.clipboardData.setData('text', code);
+ else
+ return sh.utils.unindent(code);
+
+ case 'ok':
+ sh.utils.alert(sh.config.strings.copyToClipboardConfirmation);
+ break;
+
+ case 'error':
+ sh.utils.alert(args.message);
+ break;
+ }
+ };
+ },
+
+ /** Command to print the colored source code. */
+ printSource : function(highlighter)
+ {
+ this.create = function()
+ {
+ return sh.config.strings.print;
+ };
+
+ this.execute = function(sender, event, args)
+ {
+ var iframe = document.createElement('IFRAME'),
+ doc = null
+ ;
+
+ // make sure there is never more than one hidden iframe created by SH
+ if (sh.vars.printFrame != null)
+ document.body.removeChild(sh.vars.printFrame);
+
+ sh.vars.printFrame = iframe;
+
+ // this hides the iframe
+ iframe.style.cssText = 'position:absolute;width:0px;height:0px;left:-500px;top:-500px;';
+
+ document.body.appendChild(iframe);
+ doc = iframe.contentWindow.document;
+
+ copyStyles(doc, window.document);
+ doc.write('
tag with given style applied to it.
+ *
+ * @param {String} str Input string.
+ * @param {String} css Style name to apply to the string.
+ * @return {String} Returns input string with each line surrounded by tag.
+ */
+ decorate: function(str, css)
+ {
+ if (str == null || str.length == 0 || str == '\n')
+ return str;
+
+ str = str.replace(/...' + line + '
';
+ });
+
+ return str;
+ },
+
+ /**
+ * Pads number with zeros until it's length is the same as given length.
+ *
+ * @param {Number} number Number to pad.
+ * @param {Number} length Max string length with.
+ * @return {String} Returns a string padded with proper amount of '0'.
+ */
+ padNumber : function(number, length)
+ {
+ var result = number.toString();
+
+ while (result.length < length)
+ result = '0' + result;
+
+ return result;
+ },
+
+ /**
+ * Measures width of a single space character.
+ * @return {Number} Returns width of a single space character.
+ */
+ measureSpace : function()
+ {
+ var container = document.createElement('div'),
+ span,
+ result = 0,
+ body = document.body,
+ id = sh.utils.guid('measureSpace'),
+
+ // variable names will be compressed, so it's better than a plain string
+ divOpen = 'regexList
collection.
+ * @return {Array} Returns a list of Match objects.
+ */
+ getMatches: function(code, regexInfo)
+ {
+ function defaultAdd(match, regexInfo)
+ {
+ return [new sh.Match(match[0], match.index, regexInfo.css)];
+ };
+
+ var index = 0,
+ match = null,
+ result = [],
+ func = regexInfo.func ? regexInfo.func : defaultAdd
+ ;
+
+ while((match = regexInfo.regex.exec(code)) != null)
+ result = result.concat(func(match, regexInfo));
+
+ return result;
+ },
+
+ processUrls: function(code)
+ {
+ var lt = '<',
+ gt = '>'
+ ;
+
+ return code.replace(sh.regexLib.url, function(m)
+ {
+ var suffix = '', prefix = '';
+
+ // We include < and > in the URL for the common cases like ' + lineNumber + ' | ' : '')
+ + ''
+ + (spaces != null ? '' + spaces.replace(' ', ' ') + ' ' : '')
+ + line
+ + ' | '
+ + '
.*?)" +
+ "(?" + regexGroup.right.source + ")",
+ "sgi"
+ )
+ };
+ }
+}; // end of Highlighter
+
+return sh;
+}(); // end of anonymous function
+
+
+/**
+ * XRegExp 0.6.1
+ * (c) 2007-2008 Steven Levithan
+ *
+ * MIT License
+ *
+ * provides an augmented, cross-browser implementation of regular expressions
+ * including support for additional modifiers and syntax. several convenience
+ * methods and a recursive-construct parser are also included.
+ */
+
+// prevent running twice, which would break references to native globals
+if (!window.XRegExp) {
+// anonymous function to avoid global variables
+(function () {
+// copy various native globals for reference. can't use the name ``native``
+// because it's a reserved JavaScript keyword.
+var real = {
+ exec: RegExp.prototype.exec,
+ match: String.prototype.match,
+ replace: String.prototype.replace,
+ split: String.prototype.split
+ },
+ /* regex syntax parsing with support for all the necessary cross-
+ browser and context issues (escapings, character classes, etc.) */
+ lib = {
+ part: /(?:[^\\([#\s.]+|\\(?!k<[\w$]+>|[pP]{[^}]+})[\S\s]?|\((?=\?(?!#|<[\w$]+>)))+|(\()(?:\?(?:(#)[^)]*\)|<([$\w]+)>))?|\\(?:k<([\w$]+)>|[pP]{([^}]+)})|(\[\^?)|([\S\s])/g,
+ replaceVar: /(?:[^$]+|\$(?![1-9$&`']|{[$\w]+}))+|\$(?:([1-9]\d*|[$&`'])|{([$\w]+)})/g,
+ extended: /^(?:\s+|#.*)+/,
+ quantifier: /^(?:[?*+]|{\d+(?:,\d*)?})/,
+ classLeft: /&&\[\^?/g,
+ classRight: /]/g
+ },
+ indexOf = function (array, item, from) {
+ for (var i = from || 0; i < array.length; i++)
+ if (array[i] === item) return i;
+ return -1;
+ },
+ brokenExecUndef = /()??/.exec("")[1] !== undefined,
+ plugins = {};
+
+/**
+ * Accepts a pattern and flags, returns a new, extended RegExp object.
+ * differs from a native regex in that additional flags and syntax are
+ * supported and browser inconsistencies are ameliorated.
+ * @ignore
+ */
+XRegExp = function (pattern, flags) {
+ if (pattern instanceof RegExp) {
+ if (flags !== undefined)
+ throw TypeError("can't supply flags when constructing one RegExp from another");
+ return pattern.addFlags(); // new copy
+ }
+
+ var flags = flags || "",
+ singleline = flags.indexOf("s") > -1,
+ extended = flags.indexOf("x") > -1,
+ hasNamedCapture = false,
+ captureNames = [],
+ output = [],
+ part = lib.part,
+ match, cc, len, index, regex;
+
+ part.lastIndex = 0; // in case the last XRegExp compilation threw an error (unbalanced character class)
+
+ while (match = real.exec.call(part, pattern)) {
+ // comment pattern. this check must come before the capturing group check,
+ // because both match[1] and match[2] will be non-empty.
+ if (match[2]) {
+ // keep tokens separated unless the following token is a quantifier
+ if (!lib.quantifier.test(pattern.slice(part.lastIndex)))
+ output.push("(?:)");
+ // capturing group
+ } else if (match[1]) {
+ captureNames.push(match[3] || null);
+ if (match[3])
+ hasNamedCapture = true;
+ output.push("(");
+ // named backreference
+ } else if (match[4]) {
+ index = indexOf(captureNames, match[4]);
+ // keep backreferences separate from subsequent literal numbers
+ // preserve backreferences to named groups that are undefined at this point as literal strings
+ output.push(index > -1 ?
+ "\\" + (index + 1) + (isNaN(pattern.charAt(part.lastIndex)) ? "" : "(?:)") :
+ match[0]
+ );
+ // unicode element (requires plugin)
+ } else if (match[5]) {
+ output.push(plugins.unicode ?
+ plugins.unicode.get(match[5], match[0].charAt(1) === "P") :
+ match[0]
+ );
+ // character class opening delimiter ("[" or "[^")
+ // (non-native unicode elements are not supported within character classes)
+ } else if (match[6]) {
+ if (pattern.charAt(part.lastIndex) === "]") {
+ // for cross-browser compatibility with ECMA-262 v3 behavior,
+ // convert [] to (?!) and [^] to [\S\s].
+ output.push(match[6] === "[" ? "(?!)" : "[\\S\\s]");
+ part.lastIndex++;
+ } else {
+ // parse the character class with support for inner escapes and
+ // ES4's infinitely nesting intersection syntax ([&&[^&&[]]]).
+ cc = XRegExp.matchRecursive("&&" + pattern.slice(match.index), lib.classLeft, lib.classRight, "", {escapeChar: "\\"})[0];
+ output.push(match[6] + cc + "]");
+ part.lastIndex += cc.length + 1;
+ }
+ // dot ("."), pound sign ("#"), or whitespace character
+ } else if (match[7]) {
+ if (singleline && match[7] === ".") {
+ output.push("[\\S\\s]");
+ } else if (extended && lib.extended.test(match[7])) {
+ len = real.exec.call(lib.extended, pattern.slice(part.lastIndex - 1))[0].length;
+ // keep tokens separated unless the following token is a quantifier
+ if (!lib.quantifier.test(pattern.slice(part.lastIndex - 1 + len)))
+ output.push("(?:)");
+ part.lastIndex += len - 1;
+ } else {
+ output.push(match[7]);
+ }
+ } else {
+ output.push(match[0]);
+ }
+ }
+
+ regex = RegExp(output.join(""), real.replace.call(flags, /[sx]+/g, ""));
+ regex._x = {
+ source: pattern,
+ captureNames: hasNamedCapture ? captureNames : null
+ };
+ return regex;
+};
+
+/**
+ * Barebones plugin support for now (intentionally undocumented)
+ * @ignore
+ * @param {Object} name
+ * @param {Object} o
+ */
+XRegExp.addPlugin = function (name, o) {
+ plugins[name] = o;
+};
+
+/**
+ * Adds named capture support, with values returned as ``result.name``.
+ *
+ * Also fixes two cross-browser issues, following the ECMA-262 v3 spec:
+ * - captured values for non-participating capturing groups should be returned
+ * as ``undefined``, rather than the empty string.
+ * - the regex's ``lastIndex`` should not be incremented after zero-length
+ * matches.
+ * @ignore
+ */
+RegExp.prototype.exec = function (str) {
+ var match = real.exec.call(this, str),
+ name, i, r2;
+ if (match) {
+ // fix browsers whose exec methods don't consistently return
+ // undefined for non-participating capturing groups
+ if (brokenExecUndef && match.length > 1) {
+ // r2 doesn't need /g or /y, but they shouldn't hurt
+ r2 = new RegExp("^" + this.source + "$(?!\\s)", this.getNativeFlags());
+ real.replace.call(match[0], r2, function () {
+ for (i = 1; i < arguments.length - 2; i++) {
+ if (arguments[i] === undefined) match[i] = undefined;
+ }
+ });
+ }
+ // attach named capture properties
+ if (this._x && this._x.captureNames) {
+ for (i = 1; i < match.length; i++) {
+ name = this._x.captureNames[i - 1];
+ if (name) match[name] = match[i];
+ }
+ }
+ // fix browsers that increment lastIndex after zero-length matches
+ if (this.global && this.lastIndex > (match.index + match[0].length))
+ this.lastIndex--;
+ }
+ return match;
+};
+})(); // end anonymous function
+} // end if(!window.XRegExp)
+
+/**
+ * intentionally undocumented
+ * @ignore
+ */
+RegExp.prototype.getNativeFlags = function () {
+ return (this.global ? "g" : "") +
+ (this.ignoreCase ? "i" : "") +
+ (this.multiline ? "m" : "") +
+ (this.extended ? "x" : "") +
+ (this.sticky ? "y" : "");
+};
+
+/**
+ * Accepts flags; returns a new XRegExp object generated by recompiling
+ * the regex with the additional flags (may include non-native flags).
+ * The original regex object is not altered.
+ * @ignore
+ */
+RegExp.prototype.addFlags = function (flags) {
+ var regex = new XRegExp(this.source, (flags || "") + this.getNativeFlags());
+ if (this._x) {
+ regex._x = {
+ source: this._x.source,
+ captureNames: this._x.captureNames ? this._x.captureNames.slice(0) : null
+ };
+ }
+ return regex;
+};
+
+/**
+ * Accepts a context object and string; returns the result of calling
+ * ``exec`` with the provided string. the context is ignored but is
+ * accepted for congruity with ``Function.prototype.call``.
+ * @ignore
+ */
+RegExp.prototype.call = function (context, str) {
+ return this.exec(str);
+};
+
+/**
+ * Accepts a context object and arguments array; returns the result of
+ * calling ``exec`` with the first value in the arguments array. the context
+ * is ignored but is accepted for congruity with ``Function.prototype.apply``.
+ * @ignore
+ */
+RegExp.prototype.apply = function (context, args) {
+ return this.exec(args[0]);
+};
+
+/**
+ * Accepts a pattern and flags; returns an XRegExp object. if the pattern
+ * and flag combination has previously been cached, the cached copy is
+ * returned, otherwise the new object is cached.
+ * @ignore
+ */
+XRegExp.cache = function (pattern, flags) {
+ var key = "/" + pattern + "/" + (flags || "");
+ return XRegExp.cache[key] || (XRegExp.cache[key] = new XRegExp(pattern, flags));
+};
+
+/**
+ * Accepts a string; returns the string with regex metacharacters escaped.
+ * the returned string can safely be used within a regex to match a literal
+ * string. escaped characters are [, ], {, }, (, ), -, *, +, ?, ., \, ^, $,
+ * |, #, [comma], and whitespace.
+ * @ignore
+ */
+XRegExp.escape = function (str) {
+ return str.replace(/[-[\]{}()*+?.\\^$|,#\s]/g, "\\$&");
+};
+
+/**
+ * Accepts a string to search, left and right delimiters as regex pattern
+ * strings, optional regex flags (may include non-native s, x, and y flags),
+ * and an options object which allows setting an escape character and changing
+ * the return format from an array of matches to a two-dimensional array of
+ * string parts with extended position data. returns an array of matches
+ * (optionally with extended data), allowing nested instances of left and right
+ * delimiters. use the g flag to return all matches, otherwise only the first
+ * is returned. if delimiters are unbalanced within the subject data, an error
+ * is thrown.
+ *
+ * This function admittedly pushes the boundaries of what can be accomplished
+ * sensibly without a "real" parser. however, by doing so it provides flexible
+ * and powerful recursive parsing capabilities with minimal code weight.
+ *
+ * Warning: the ``escapeChar`` option is considered experimental and might be
+ * changed or removed in future versions of XRegExp.
+ *
+ * unsupported features:
+ * - backreferences within delimiter patterns when using ``escapeChar``.
+ * - although providing delimiters as regex objects adds the minor feature of
+ * independent delimiter flags, it introduces other limitations and is only
+ * intended to be done by the ``XRegExp`` constructor (which can't call
+ * itself while building a regex).
+ *
+ * @ignore
+ */
+XRegExp.matchRecursive = function (str, left, right, flags, options) {
+ var options = options || {},
+ escapeChar = options.escapeChar,
+ vN = options.valueNames,
+ flags = flags || "",
+ global = flags.indexOf("g") > -1,
+ ignoreCase = flags.indexOf("i") > -1,
+ multiline = flags.indexOf("m") > -1,
+ sticky = flags.indexOf("y") > -1,
+ /* sticky mode has its own handling in this function, which means you
+ can use flag "y" even in browsers which don't support it natively */
+ flags = flags.replace(/y/g, ""),
+ left = left instanceof RegExp ? (left.global ? left : left.addFlags("g")) : new XRegExp(left, "g" + flags),
+ right = right instanceof RegExp ? (right.global ? right : right.addFlags("g")) : new XRegExp(right, "g" + flags),
+ output = [],
+ openTokens = 0,
+ delimStart = 0,
+ delimEnd = 0,
+ lastOuterEnd = 0,
+ outerStart, innerStart, leftMatch, rightMatch, escaped, esc;
+
+ if (escapeChar) {
+ if (escapeChar.length > 1) throw SyntaxError("can't supply more than one escape character");
+ if (multiline) throw TypeError("can't supply escape character when using the multiline flag");
+ escaped = XRegExp.escape(escapeChar);
+ /* Escape pattern modifiers:
+ /g - not needed here
+ /i - included
+ /m - **unsupported**, throws error
+ /s - handled by XRegExp when delimiters are provided as strings
+ /x - handled by XRegExp when delimiters are provided as strings
+ /y - not needed here; supported by other handling in this function
+ */
+ esc = new RegExp(
+ "^(?:" + escaped + "[\\S\\s]|(?:(?!" + left.source + "|" + right.source + ")[^" + escaped + "])+)+",
+ ignoreCase ? "i" : ""
+ );
+ }
+
+ while (true) {
+ /* advance the starting search position to the end of the last delimiter match.
+ a couple special cases are also covered:
+ - if using an escape character, advance to the next delimiter's starting position,
+ skipping any escaped characters
+ - first time through, reset lastIndex in case delimiters were provided as regexes
+ */
+ left.lastIndex = right.lastIndex = delimEnd +
+ (escapeChar ? (esc.exec(str.slice(delimEnd)) || [""])[0].length : 0);
+
+ leftMatch = left.exec(str);
+ rightMatch = right.exec(str);
+
+ // only keep the result which matched earlier in the string
+ if (leftMatch && rightMatch) {
+ if (leftMatch.index <= rightMatch.index)
+ rightMatch = null;
+ else leftMatch = null;
+ }
+
+ /* paths*:
+ leftMatch | rightMatch | openTokens | result
+ 1 | 0 | 1 | ...
+ 1 | 0 | 0 | ...
+ 0 | 1 | 1 | ...
+ 0 | 1 | 0 | throw
+ 0 | 0 | 1 | throw
+ 0 | 0 | 0 | break
+ * - does not include the sticky mode special case
+ - the loop ends after the first completed match if not in global mode
+ */
+
+ if (leftMatch || rightMatch) {
+ delimStart = (leftMatch || rightMatch).index;
+ delimEnd = (leftMatch ? left : right).lastIndex;
+ } else if (!openTokens) {
+ break;
+ }
+
+ if (sticky && !openTokens && delimStart > lastOuterEnd)
+ break;
+
+ if (leftMatch) {
+ if (!openTokens++) {
+ outerStart = delimStart;
+ innerStart = delimEnd;
+ }
+ } else if (rightMatch && openTokens) {
+ if (!--openTokens) {
+ if (vN) {
+ if (vN[0] && outerStart > lastOuterEnd)
+ output.push([vN[0], str.slice(lastOuterEnd, outerStart), lastOuterEnd, outerStart]);
+ if (vN[1]) output.push([vN[1], str.slice(outerStart, innerStart), outerStart, innerStart]);
+ if (vN[2]) output.push([vN[2], str.slice(innerStart, delimStart), innerStart, delimStart]);
+ if (vN[3]) output.push([vN[3], str.slice(delimStart, delimEnd), delimStart, delimEnd]);
+ } else {
+ output.push(str.slice(innerStart, delimStart));
+ }
+ lastOuterEnd = delimEnd;
+ if (!global)
+ break;
+ }
+ } else {
+ // reset lastIndex in case delimiters were provided as regexes
+ left.lastIndex = right.lastIndex = 0;
+ throw Error("subject data contains unbalanced delimiters");
+ }
+
+ // if the delimiter matched an empty string, advance delimEnd to avoid an infinite loop
+ if (delimStart === delimEnd)
+ delimEnd++;
+ }
+
+ if (global && !sticky && vN && vN[0] && str.length > lastOuterEnd)
+ output.push([vN[0], str.slice(lastOuterEnd), lastOuterEnd, str.length]);
+
+ // reset lastIndex in case delimiters were provided as regexes
+ left.lastIndex = right.lastIndex = 0;
+
+ return output;
+};
diff --git a/html/lib/syntaxhighlighter_2.1.364/src/shLegacy.js b/html/lib/syntaxhighlighter_2.1.364/src/shLegacy.js
new file mode 100644
index 000000000..491a79d5c
--- /dev/null
+++ b/html/lib/syntaxhighlighter_2.1.364/src/shLegacy.js
@@ -0,0 +1,172 @@
+/**
+ * SyntaxHighlighter
+ * http://alexgorbatchev.com/
+ *
+ * SyntaxHighlighter is donationware. If you are using it, please donate.
+ * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate
+ *
+ * @version
+ * 2.1.364 (October 15 2009)
+ *
+ * @copyright
+ * Copyright (C) 2004-2009 Alex Gorbatchev.
+ *
+ * @license
+ * This file is part of SyntaxHighlighter.
+ *
+ * SyntaxHighlighter is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SyntaxHighlighter is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SyntaxHighlighter. If not, see .
+ */
+var dp = {
+ SyntaxHighlighter : {}
+};
+
+dp.SyntaxHighlighter = {
+ parseParams: function(
+ input,
+ showGutter,
+ showControls,
+ collapseAll,
+ firstLine,
+ showColumns
+ )
+ {
+ function getValue(list, name)
+ {
+ var regex = new XRegExp('^' + name + '\\[(?\\w+)\\]$', 'gi'),
+ match = null
+ ;
+
+ for (var i = 0; i < list.length; i++)
+ if ((match = regex.exec(list[i])) != null)
+ return match.value;
+
+ return null;
+ };
+
+ function defaultValue(value, def)
+ {
+ return value != null ? value : def;
+ };
+
+ function asString(value)
+ {
+ return value != null ? value.toString() : null;
+ };
+
+ var parts = input.split(':'),
+ brushName = parts[0],
+ options = {},
+ straight = { 'true' : 'true' }
+ reverse = { 'true' : 'false' },
+ result = null,
+ defaults = SyntaxHighlighter.defaults
+ ;
+
+ for (var i in parts)
+ options[parts[i]] = 'true';
+
+ showGutter = asString(defaultValue(showGutter, defaults.gutter));
+ showControls = asString(defaultValue(showControls, defaults.toolbar));
+ collapseAll = asString(defaultValue(collapseAll, defaults.collapse));
+ showColumns = asString(defaultValue(showColumns, defaults.ruler));
+ firstLine = asString(defaultValue(firstLine, defaults['first-line']));
+
+ result = {
+ brush : brushName,
+ gutter : defaultValue(reverse[options.nogutter], showGutter),
+ toolbar : defaultValue(reverse[options.nocontrols], showControls),
+ collapse : defaultValue(straight[options.collapse], collapseAll),
+ ruler : defaultValue(straight[options.showcolumns], showColumns),
+ 'first-line' : defaultValue(getValue(parts, 'firstline'), firstLine)
+ };
+
+ return result;
+ },
+
+ HighlightAll: function(
+ name,
+ showGutter /* optional */,
+ showControls /* optional */,
+ collapseAll /* optional */,
+ firstLine /* optional */,
+ showColumns /* optional */
+ )
+ {
+ function findValue()
+ {
+ var a = arguments;
+
+ for (var i = 0; i < a.length; i++)
+ {
+ if (a[i] === null)
+ continue;
+
+ if (typeof(a[i]) == 'string' && a[i] != '')
+ return a[i] + '';
+
+ if (typeof(a[i]) == 'object' && a[i].value != '')
+ return a[i].value + '';
+ }
+
+ return null;
+ };
+
+ function findTagsByName(list, name, tagName)
+ {
+ var tags = document.getElementsByTagName(tagName);
+
+ for (var i = 0; i < tags.length; i++)
+ if (tags[i].getAttribute('name') == name)
+ list.push(tags[i]);
+ }
+
+ var elements = [],
+ highlighter = null,
+ registered = {},
+ propertyName = 'innerHTML'
+ ;
+
+ // for some reason IE doesn't find by name, however it does see them just fine by tag name...
+ findTagsByName(elements, name, 'pre');
+ findTagsByName(elements, name, 'textarea');
+
+ if (elements.length === 0)
+ return;
+
+ for (var i = 0; i < elements.length; i++)
+ {
+ var element = elements[i],
+ params = findValue(
+ element.attributes['class'], element.className,
+ element.attributes['language'], element.language
+ ),
+ language = ''
+ ;
+
+ if (params === null)
+ continue;
+
+ params = dp.SyntaxHighlighter.parseParams(
+ params,
+ showGutter,
+ showControls,
+ collapseAll,
+ firstLine,
+ showColumns
+ );
+
+ SyntaxHighlighter.highlight(params, element);
+ }
+ }
+};
diff --git a/html/lib/syntaxhighlighter_2.1.364/styles/help.png b/html/lib/syntaxhighlighter_2.1.364/styles/help.png
new file mode 100644
index 000000000..5c870176d
Binary files /dev/null and b/html/lib/syntaxhighlighter_2.1.364/styles/help.png differ
diff --git a/html/lib/syntaxhighlighter_2.1.364/styles/magnifier.png b/html/lib/syntaxhighlighter_2.1.364/styles/magnifier.png
new file mode 100644
index 000000000..cf3d97f75
Binary files /dev/null and b/html/lib/syntaxhighlighter_2.1.364/styles/magnifier.png differ
diff --git a/html/lib/syntaxhighlighter_2.1.364/styles/page_white_code.png b/html/lib/syntaxhighlighter_2.1.364/styles/page_white_code.png
new file mode 100644
index 000000000..0c76bd129
Binary files /dev/null and b/html/lib/syntaxhighlighter_2.1.364/styles/page_white_code.png differ
diff --git a/html/lib/syntaxhighlighter_2.1.364/styles/page_white_copy.png b/html/lib/syntaxhighlighter_2.1.364/styles/page_white_copy.png
new file mode 100644
index 000000000..a9f31a278
Binary files /dev/null and b/html/lib/syntaxhighlighter_2.1.364/styles/page_white_copy.png differ
diff --git a/html/lib/syntaxhighlighter_2.1.364/styles/printer.png b/html/lib/syntaxhighlighter_2.1.364/styles/printer.png
new file mode 100644
index 000000000..a350d1871
Binary files /dev/null and b/html/lib/syntaxhighlighter_2.1.364/styles/printer.png differ
diff --git a/html/lib/syntaxhighlighter_2.1.364/styles/shCore.css b/html/lib/syntaxhighlighter_2.1.364/styles/shCore.css
new file mode 100644
index 000000000..415ab487e
--- /dev/null
+++ b/html/lib/syntaxhighlighter_2.1.364/styles/shCore.css
@@ -0,0 +1,330 @@
+/**
+ * SyntaxHighlighter
+ * http://alexgorbatchev.com/
+ *
+ * SyntaxHighlighter is donationware. If you are using it, please donate.
+ * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate
+ *
+ * @version
+ * 2.1.364 (October 15 2009)
+ *
+ * @copyright
+ * Copyright (C) 2004-2009 Alex Gorbatchev.
+ *
+ * @license
+ * This file is part of SyntaxHighlighter.
+ *
+ * SyntaxHighlighter is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SyntaxHighlighter is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SyntaxHighlighter. If not, see .
+ */
+.syntaxhighlighter,
+.syntaxhighlighter div,
+.syntaxhighlighter code,
+.syntaxhighlighter table,
+.syntaxhighlighter table td,
+.syntaxhighlighter table tr,
+.syntaxhighlighter table tbody
+{
+ margin: 0 !important;
+ padding: 0 !important;
+ border: 0 !important;
+ outline: 0 !important;
+ background: none !important;
+ text-align: left !important;
+ float: none !important;
+ vertical-align: baseline !important;
+ position: static !important;
+ left: auto !important;
+ top: auto !important;
+ right: auto !important;
+ bottom: auto !important;
+ height: auto !important;
+ width: auto !important;
+ line-height: 1.1em !important;
+ -font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important;
+ font-weight: normal !important;
+ font-style: normal !important;
+ -font-size: 1em !important;
+ min-height: inherit !important; /* For IE8, FF & WebKit */
+ min-height: auto !important; /* For IE7 */
+}
+
+.syntaxhighlighter
+{
+ width: 99% !important; /* 99% fixes IE8 horizontal scrollbar */
+ margin: 0 !important;
+ padding: 1px !important; /* adds a little border on top and bottom */
+ position: relative !important;
+}
+
+.syntaxhighlighter .bold
+{
+ font-weight: bold !important;
+}
+
+.syntaxhighlighter .italic
+{
+ font-style: italic !important;
+}
+
+.syntaxhighlighter .line
+{
+}
+
+.syntaxhighlighter .no-wrap .line .content
+{
+ white-space: pre !important;
+}
+
+.syntaxhighlighter .line table
+{
+ border-collapse: collapse !important;
+}
+
+.syntaxhighlighter .line td
+{
+ vertical-align: top !important;
+}
+
+.syntaxhighlighter .line .number
+{
+ width: 3em !important;
+}
+
+.syntaxhighlighter .line .number code
+{
+ width: 2.7em !important;
+ padding-right: .3em !important;
+ text-align: right !important;
+ display: block !important;
+}
+
+.syntaxhighlighter .line .content
+{
+ padding-left: .5em !important;
+}
+
+.syntaxhighlighter .line .spaces
+{
+}
+
+/* Disable border and margin on the lines when no gutter option is set */
+.syntaxhighlighter.nogutter .line .content
+{
+ border-left: none !important;
+}
+
+.syntaxhighlighter .bar
+{
+ display: none !important;
+}
+
+.syntaxhighlighter .bar.show
+{
+ display: block !important;
+}
+
+.syntaxhighlighter.collapsed .bar
+{
+ display: block !important;
+}
+
+/* Adjust some properties when collapsed */
+
+.syntaxhighlighter.collapsed .lines
+{
+ display: none !important;
+}
+
+.syntaxhighlighter .lines.no-wrap
+{
+ overflow: auto !important;
+ overflow-y: hidden !important;
+}
+
+/* Styles for the toolbar */
+
+.syntaxhighlighter .toolbar
+{
+ position: absolute !important;
+ right: 0px !important;
+ top: 0px !important;
+ font-size: 1px !important;
+ padding: 8px 8px 8px 0 !important; /* in px because images don't scale with ems */
+}
+
+.syntaxhighlighter.collapsed .toolbar
+{
+ font-size: 80% !important;
+ padding: .2em 0 .5em .5em !important;
+ position: static !important;
+}
+
+.syntaxhighlighter .toolbar a.item,
+.syntaxhighlighter .toolbar .item
+{
+ display: block !important;
+ float: left !important;
+ margin-left: 8px !important;
+ background-repeat: no-repeat !important;
+ overflow: hidden !important;
+ text-indent: -5000px !important;
+}
+
+.syntaxhighlighter.collapsed .toolbar .item
+{
+ display: none !important;
+}
+
+.syntaxhighlighter.collapsed .toolbar .item.expandSource
+{
+ background-image: url(magnifier.png) !important;
+ display: inline !important;
+ text-indent: 0 !important;
+ width: auto !important;
+ float: none !important;
+ height: 16px !important;
+ padding-left: 20px !important;
+}
+
+.syntaxhighlighter .toolbar .item.viewSource
+{
+ background-image: url(page_white_code.png) !important;
+}
+
+.syntaxhighlighter .toolbar .item.printSource
+{
+ background-image: url(printer.png) !important;
+}
+
+.syntaxhighlighter .toolbar .item.copyToClipboard
+{
+ text-indent: 0 !important;
+ background: none !important;
+ overflow: visible !important;
+}
+
+.syntaxhighlighter .toolbar .item.about
+{
+ background-image: url(help.png) !important;
+}
+
+/**
+ * Print view.
+ * Colors are based on the default theme without background.
+ */
+
+.syntaxhighlighter.printing,
+.syntaxhighlighter.printing .line.alt1 .content,
+.syntaxhighlighter.printing .line.alt2 .content,
+.syntaxhighlighter.printing .line.highlighted .number,
+.syntaxhighlighter.printing .line.highlighted.alt1 .content,
+.syntaxhighlighter.printing .line.highlighted.alt2 .content,
+{
+ background: none !important;
+}
+
+/* Gutter line numbers */
+.syntaxhighlighter.printing .line .number
+{
+ color: #bbb !important;
+}
+
+/* Add border to the lines */
+.syntaxhighlighter.printing .line .content
+{
+ color: #000 !important;
+}
+
+/* Toolbar when visible */
+.syntaxhighlighter.printing .toolbar
+{
+ display: none !important;
+}
+
+.syntaxhighlighter.printing a
+{
+ text-decoration: none !important;
+}
+
+.syntaxhighlighter.printing .plain,
+.syntaxhighlighter.printing .plain a
+{
+ color: #000 !important;
+}
+
+.syntaxhighlighter.printing .comments,
+.syntaxhighlighter.printing .comments a
+{
+ color: #008200 !important;
+}
+
+.syntaxhighlighter.printing .string,
+.syntaxhighlighter.printing .string a
+{
+ color: blue !important;
+}
+
+.syntaxhighlighter.printing .keyword
+{
+ color: #069 !important;
+ font-weight: bold !important;
+}
+
+.syntaxhighlighter.printing .preprocessor
+{
+ color: gray !important;
+}
+
+.syntaxhighlighter.printing .variable
+{
+ color: #a70 !important;
+}
+
+.syntaxhighlighter.printing .value
+{
+ color: #090 !important;
+}
+
+.syntaxhighlighter.printing .functions
+{
+ color: #ff1493 !important;
+}
+
+.syntaxhighlighter.printing .constants
+{
+ color: #0066CC !important;
+}
+
+.syntaxhighlighter.printing .script
+{
+ font-weight: bold !important;
+}
+
+.syntaxhighlighter.printing .color1,
+.syntaxhighlighter.printing .color1 a
+{
+ color: #808080 !important;
+}
+
+.syntaxhighlighter.printing .color2,
+.syntaxhighlighter.printing .color2 a
+{
+ color: #ff1493 !important;
+}
+
+.syntaxhighlighter.printing .color3,
+.syntaxhighlighter.printing .color3 a
+{
+ color: red !important;
+}
diff --git a/html/lib/syntaxhighlighter_2.1.364/styles/shThemeDefault.css b/html/lib/syntaxhighlighter_2.1.364/styles/shThemeDefault.css
new file mode 100644
index 000000000..a57dd054a
--- /dev/null
+++ b/html/lib/syntaxhighlighter_2.1.364/styles/shThemeDefault.css
@@ -0,0 +1,173 @@
+/**
+ * SyntaxHighlighter
+ * http://alexgorbatchev.com/
+ *
+ * SyntaxHighlighter is donationware. If you are using it, please donate.
+ * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate
+ *
+ * @version
+ * 2.1.364 (October 15 2009)
+ *
+ * @copyright
+ * Copyright (C) 2004-2009 Alex Gorbatchev.
+ *
+ * @license
+ * This file is part of SyntaxHighlighter.
+ *
+ * SyntaxHighlighter is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SyntaxHighlighter is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SyntaxHighlighter. If not, see .
+ */
+/************************************
+ * Default Syntax Highlighter theme.
+ *
+ * Interface elements.
+ ************************************/
+
+.syntaxhighlighter
+{
+ background-color: #fff !important;
+}
+
+/* Highlighed line number */
+.syntaxhighlighter .line.highlighted .number
+{
+ color: black !important;
+}
+
+/* Highlighed line */
+.syntaxhighlighter .line.highlighted.alt1,
+.syntaxhighlighter .line.highlighted.alt2
+{
+ background-color: #e0e0e0 !important;
+}
+
+/* Gutter line numbers */
+.syntaxhighlighter .line .number
+{
+ color: #afafaf !important;
+}
+
+/* Add border to the lines */
+.syntaxhighlighter .line .content
+{
+ border-left: 3px solid #6CE26C !important;
+ color: #000 !important;
+}
+
+.syntaxhighlighter.printing .line .content
+{
+ border: 0 !important;
+}
+
+/* First line */
+.syntaxhighlighter .line.alt1
+{
+ background-color: #fff !important;
+}
+
+/* Second line */
+.syntaxhighlighter .line.alt2
+{
+ background-color: #F8F8F8 !important;
+}
+
+.syntaxhighlighter .toolbar
+{
+ background-color: #F8F8F8 !important;
+ border: #E7E5DC solid 1px !important;
+}
+
+.syntaxhighlighter .toolbar a
+{
+ color: #a0a0a0 !important;
+}
+
+.syntaxhighlighter .toolbar a:hover
+{
+ color: red !important;
+}
+
+/************************************
+ * Actual syntax highlighter colors.
+ ************************************/
+.syntaxhighlighter .plain,
+.syntaxhighlighter .plain a
+{
+ color: #000 !important;
+}
+
+.syntaxhighlighter .comments,
+.syntaxhighlighter .comments a
+{
+ color: #008200 !important;
+}
+
+.syntaxhighlighter .string,
+.syntaxhighlighter .string a
+{
+ color: blue !important;
+}
+
+.syntaxhighlighter .keyword
+{
+ color: #069 !important;
+ font-weight: bold !important;
+}
+
+.syntaxhighlighter .preprocessor
+{
+ color: gray !important;
+}
+
+.syntaxhighlighter .variable
+{
+ color: #a70 !important;
+}
+
+.syntaxhighlighter .value
+{
+ color: #090 !important;
+}
+
+.syntaxhighlighter .functions
+{
+ color: #ff1493 !important;
+}
+
+.syntaxhighlighter .constants
+{
+ color: #0066CC !important;
+}
+
+.syntaxhighlighter .script
+{
+ background-color: yellow !important;
+}
+
+.syntaxhighlighter .color1,
+.syntaxhighlighter .color1 a
+{
+ color: #808080 !important;
+}
+
+.syntaxhighlighter .color2,
+.syntaxhighlighter .color2 a
+{
+ color: #ff1493 !important;
+}
+
+.syntaxhighlighter .color3,
+.syntaxhighlighter .color3 a
+{
+ color: red !important;
+}
diff --git a/html/lib/syntaxhighlighter_2.1.364/styles/shThemeDjango.css b/html/lib/syntaxhighlighter_2.1.364/styles/shThemeDjango.css
new file mode 100644
index 000000000..4a6564c73
--- /dev/null
+++ b/html/lib/syntaxhighlighter_2.1.364/styles/shThemeDjango.css
@@ -0,0 +1,176 @@
+/**
+ * SyntaxHighlighter
+ * http://alexgorbatchev.com/
+ *
+ * SyntaxHighlighter is donationware. If you are using it, please donate.
+ * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate
+ *
+ * @version
+ * 2.1.364 (October 15 2009)
+ *
+ * @copyright
+ * Copyright (C) 2004-2009 Alex Gorbatchev.
+ *
+ * @license
+ * This file is part of SyntaxHighlighter.
+ *
+ * SyntaxHighlighter is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SyntaxHighlighter is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SyntaxHighlighter. If not, see .
+ */
+/**
+ * Django SyntaxHighlighter theme
+ */
+
+/************************************
+ * Interface elements.
+ ************************************/
+
+.syntaxhighlighter
+{
+ background-color: #0B2F20 !important;
+}
+
+/* Gutter line numbers */
+.syntaxhighlighter .line .number
+{
+ color: #497958 !important;
+}
+
+/* Add border to the lines */
+.syntaxhighlighter .line .content
+{
+ border-left: 3px solid #41A83E !important;
+ color: #B9BDB6 !important;
+}
+
+.syntaxhighlighter.printing .line .content
+{
+ border: 0 !important;
+}
+
+/* First line */
+.syntaxhighlighter .line.alt1
+{
+}
+
+/* Second line */
+.syntaxhighlighter .line.alt2
+{
+ background-color: #0a2b1d !important;
+}
+
+/* Highlighed line number */
+.syntaxhighlighter .line.highlighted .number
+{
+ background-color: #336442 !important;
+ color: #fff !important;
+}
+
+/* Highlighed line */
+.syntaxhighlighter .line.highlighted.alt1,
+.syntaxhighlighter .line.highlighted.alt2
+{
+ background-color: #336442 !important;
+}
+
+.syntaxhighlighter .toolbar
+{
+ background-color: #245032 !important;
+ border: #0B2F20 solid 1px !important;
+}
+
+.syntaxhighlighter .toolbar a
+{
+ color: #C4B14A !important;
+}
+
+.syntaxhighlighter .toolbar a:hover
+{
+ color: #FFE862 !important;
+}
+
+/************************************
+ * Actual syntax highlighter colors.
+ ************************************/
+.syntaxhighlighter .plain,
+.syntaxhighlighter .plain a
+{
+ color: #F8F8F8 !important;
+}
+
+.syntaxhighlighter .comments,
+.syntaxhighlighter .comments a
+{
+ color: #336442 !important;
+ font-style: italic !important;
+}
+
+.syntaxhighlighter .string,
+.syntaxhighlighter .string a
+{
+ color: #9DF39F !important;
+}
+
+.syntaxhighlighter .keyword
+{
+ color: #96DD3B !important;
+ font-weight: bold !important;
+}
+
+.syntaxhighlighter .preprocessor
+{
+ color: #91BB9E !important;
+}
+
+.syntaxhighlighter .variable
+{
+ color: #FFAA3E !important;
+}
+
+.syntaxhighlighter .value
+{
+ color: #F7E741 !important;
+}
+
+.syntaxhighlighter .functions
+{
+ color: #FFAA3E !important;
+}
+
+.syntaxhighlighter .constants
+{
+ color: #E0E8FF !important;
+}
+
+.syntaxhighlighter .script
+{
+ background-color: #497958 !important;
+}
+
+.syntaxhighlighter .color1,
+.syntaxhighlighter .color1 a
+{
+ color: #EB939A !important;
+}
+
+.syntaxhighlighter .color2,
+.syntaxhighlighter .color2 a
+{
+ color: #91BB9E !important;
+}
+
+.syntaxhighlighter .color3,
+.syntaxhighlighter .color3 a
+{
+ color: #EDEF7D !important;
+}
diff --git a/html/lib/syntaxhighlighter_2.1.364/styles/shThemeEclipse.css b/html/lib/syntaxhighlighter_2.1.364/styles/shThemeEclipse.css
new file mode 100644
index 000000000..e0dc24a5b
--- /dev/null
+++ b/html/lib/syntaxhighlighter_2.1.364/styles/shThemeEclipse.css
@@ -0,0 +1,190 @@
+/**
+ * SyntaxHighlighter
+ * http://alexgorbatchev.com/
+ *
+ * SyntaxHighlighter is donationware. If you are using it, please donate.
+ * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate
+ *
+ * @version
+ * 2.1.364 (October 15 2009)
+ *
+ * @copyright
+ * Copyright (C) 2004-2009 Alex Gorbatchev.
+ *
+ * @license
+ * This file is part of SyntaxHighlighter.
+ *
+ * SyntaxHighlighter is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SyntaxHighlighter is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SyntaxHighlighter. If not, see .
+ */
+/**
+ * Eclipse IDE SyntaxHighlighter color theme
+ * (C) Code-House
+ * http://blog.code-house.org/2009/10/xml-i-adnotacje-kod-ogolnego-przeznaczenia-i-jpa/
+ */
+
+.syntaxhighlighter
+{
+ background-color: #fff !important;
+}
+
+/* Highlighed line number */
+.syntaxhighlighter .line.highlighted .number
+{
+ background-color: #c3defe !important;
+}
+
+/* Highlighed line */
+.syntaxhighlighter .line.highlighted.alt1,
+.syntaxhighlighter .line.highlighted.alt2
+{
+ background-color: #c3defe !important;
+}
+
+/* Gutter line numbers */
+.syntaxhighlighter .line .number
+{
+ color: #787878 !important;
+ background-color: #fff !important;
+}
+
+/* Add border to the lines */
+.syntaxhighlighter .line .content
+{
+ border-left: 1px solid #d4d0c8 !important;
+ color: #000 !important;
+}
+
+.syntaxhighlighter.printing .line .content
+{
+ border: 0 !important;
+}
+
+/* First line */
+.syntaxhighlighter .line.alt1
+{
+ background-color: #fff !important;
+}
+
+/* Second line */
+.syntaxhighlighter .line.alt2
+{
+ background-color: #fff !important;
+}
+
+.syntaxhighlighter .toolbar
+{
+ background-color: #F8F8F8 !important;
+ border: #E7E5DC solid 1px !important;
+}
+
+.syntaxhighlighter .toolbar a
+{
+ color: #a0a0a0 !important;
+}
+
+.syntaxhighlighter .toolbar a:hover
+{
+ color: red !important;
+}
+
+/************************************
+ * Actual syntax highlighter colors.
+ ************************************/
+.syntaxhighlighter .plain,
+.syntaxhighlighter .plain a
+{
+ color: #000 !important;
+}
+
+.syntaxhighlighter .comments,
+.syntaxhighlighter .comments a
+{
+ color: #3f5fbf !important;
+}
+
+.syntaxhighlighter .string,
+.syntaxhighlighter .string a
+{
+ color: #2a00ff !important;
+}
+
+.syntaxhighlighter .keyword
+{
+ color: #7f0055 !important;
+ font-weight: bold !important;
+}
+
+.syntaxhighlighter .preprocessor
+{
+ color: #646464 !important;
+}
+
+.syntaxhighlighter .variable
+{
+ color: #a70 !important;
+}
+
+.syntaxhighlighter .value
+{
+ color: #090 !important;
+}
+
+.syntaxhighlighter .functions
+{
+ color: #ff1493 !important;
+}
+
+.syntaxhighlighter .constants
+{
+ color: #0066CC !important;
+}
+
+.syntaxhighlighter .script
+{
+ background-color: yellow !important;
+}
+
+.syntaxhighlighter .color1,
+.syntaxhighlighter .color1 a
+{
+ color: #808080 !important;
+}
+
+.syntaxhighlighter .color2,
+.syntaxhighlighter .color2 a
+{
+ color: #ff1493 !important;
+}
+
+.syntaxhighlighter .color3,
+.syntaxhighlighter .color3 a
+{
+ color: red !important;
+}
+
+
+.xml .keyword {
+ color: #3f7f7f !important;
+ font-weight: normal !important;
+}
+
+.xml .color1,
+.xml .color1 a{
+ color: #7f007f !important;
+}
+
+.xml .string {
+ font-style: italic !important;
+ color: #2a00ff !important;
+}
\ No newline at end of file
diff --git a/html/lib/syntaxhighlighter_2.1.364/styles/shThemeEmacs.css b/html/lib/syntaxhighlighter_2.1.364/styles/shThemeEmacs.css
new file mode 100644
index 000000000..030fbc318
--- /dev/null
+++ b/html/lib/syntaxhighlighter_2.1.364/styles/shThemeEmacs.css
@@ -0,0 +1,175 @@
+/**
+ * SyntaxHighlighter
+ * http://alexgorbatchev.com/
+ *
+ * SyntaxHighlighter is donationware. If you are using it, please donate.
+ * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate
+ *
+ * @version
+ * 2.1.364 (October 15 2009)
+ *
+ * @copyright
+ * Copyright (C) 2004-2009 Alex Gorbatchev.
+ *
+ * @license
+ * This file is part of SyntaxHighlighter.
+ *
+ * SyntaxHighlighter is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SyntaxHighlighter is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SyntaxHighlighter. If not, see .
+ */
+/**
+ * Emacs SyntaxHighlighter theme based on theme by Joshua Emmons
+ * http://www.skia.net/
+ */
+
+/************************************
+ * Interface elements.
+ ************************************/
+
+.syntaxhighlighter
+{
+ background-color: #000000 !important;
+}
+
+/* Gutter line numbers */
+.syntaxhighlighter .line .number
+{
+ color: #D3D3D3 !important;
+}
+
+/* Add border to the lines */
+.syntaxhighlighter .line .content
+{
+ border-left: 3px solid #990000 !important;
+ color: #B9BDB6 !important;
+}
+
+.syntaxhighlighter.printing .line .content
+{
+ border: 0 !important;
+}
+
+/* First line */
+.syntaxhighlighter .line.alt1
+{
+}
+
+/* Second line */
+.syntaxhighlighter .line.alt2
+{
+ background-color: #0f0f0f !important;
+}
+
+/* Highlighed line number */
+.syntaxhighlighter .line.highlighted .number
+{
+ background-color: #435A5F !important;
+ color: #fff !important;
+}
+
+/* Highlighed line */
+.syntaxhighlighter .line.highlighted.alt1,
+.syntaxhighlighter .line.highlighted.alt2
+{
+ background-color: #435A5F !important;
+}
+
+.syntaxhighlighter .toolbar
+{
+ background-color: #000000 !important;
+ border: #000000 solid 1px !important;
+}
+
+.syntaxhighlighter .toolbar a
+{
+ color: #646763 !important;
+}
+
+.syntaxhighlighter .toolbar a:hover
+{
+ color: #9CCFF4 !important;
+}
+
+/************************************
+ * Actual syntax highlighter colors.
+ ************************************/
+.syntaxhighlighter .plain,
+.syntaxhighlighter .plain a
+{
+ color: #D3D3D3 !important;
+}
+
+.syntaxhighlighter .comments,
+.syntaxhighlighter .comments a
+{
+ color: #FF7D27 !important;
+}
+
+.syntaxhighlighter .string,
+.syntaxhighlighter .string a
+{
+ color: #FF9E7B !important;
+}
+
+.syntaxhighlighter .keyword
+{
+ color: #00FFFF !important;
+}
+
+.syntaxhighlighter .preprocessor
+{
+ color: #AEC4DE !important;
+}
+
+.syntaxhighlighter .variable
+{
+ color: #FFAA3E !important;
+}
+
+.syntaxhighlighter .value
+{
+ color: #090 !important;
+}
+
+.syntaxhighlighter .functions
+{
+ color: #81CEF9 !important;
+}
+
+.syntaxhighlighter .constants
+{
+ color: #FF9E7B !important;
+}
+
+.syntaxhighlighter .script
+{
+ background-color: #990000 !important;
+}
+
+.syntaxhighlighter .color1,
+.syntaxhighlighter .color1 a
+{
+ color: #EBDB8D !important;
+}
+
+.syntaxhighlighter .color2,
+.syntaxhighlighter .color2 a
+{
+ color: #FF7D27 !important;
+}
+
+.syntaxhighlighter .color3,
+.syntaxhighlighter .color3 a
+{
+ color: #AEC4DE !important;
+}
diff --git a/html/lib/syntaxhighlighter_2.1.364/styles/shThemeFadeToGrey.css b/html/lib/syntaxhighlighter_2.1.364/styles/shThemeFadeToGrey.css
new file mode 100644
index 000000000..9c0bb753e
--- /dev/null
+++ b/html/lib/syntaxhighlighter_2.1.364/styles/shThemeFadeToGrey.css
@@ -0,0 +1,177 @@
+/**
+ * SyntaxHighlighter
+ * http://alexgorbatchev.com/
+ *
+ * SyntaxHighlighter is donationware. If you are using it, please donate.
+ * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate
+ *
+ * @version
+ * 2.1.364 (October 15 2009)
+ *
+ * @copyright
+ * Copyright (C) 2004-2009 Alex Gorbatchev.
+ *
+ * @license
+ * This file is part of SyntaxHighlighter.
+ *
+ * SyntaxHighlighter is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SyntaxHighlighter is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SyntaxHighlighter. If not, see .
+ */
+/**
+ * Fade to Grey SyntaxHighlighter theme based on theme by Brasten Sager
+ * http://www.ibrasten.com/
+ */
+
+/************************************
+ * Interface elements.
+ ************************************/
+
+.syntaxhighlighter
+{
+ background-color: #121212 !important;
+}
+
+/* Gutter line numbers */
+.syntaxhighlighter .line .number
+{
+ color: #C3C3C3 !important;
+}
+
+/* Add border to the lines */
+.syntaxhighlighter .line .content
+{
+ border-left: 3px solid #3185B9 !important;
+ color: #B9BDB6 !important;
+}
+
+.syntaxhighlighter.printing .line .content
+{
+ border: 0 !important;
+}
+
+/* First line */
+.syntaxhighlighter .line.alt1
+{
+}
+
+/* Second line */
+.syntaxhighlighter .line.alt2
+{
+ background-color: #000000 !important;
+}
+
+/* Highlighed line number */
+.syntaxhighlighter .line.highlighted .number
+{
+ background-color: #3A3A00 !important;
+ color: #fff !important;
+}
+
+/* Highlighed line */
+.syntaxhighlighter .line.highlighted.alt1,
+.syntaxhighlighter .line.highlighted.alt2
+{
+ background-color: #3A3A00 !important;
+}
+
+.syntaxhighlighter .toolbar
+{
+ background-color: #000000 !important;
+ border: #000000 solid 1px !important;
+}
+
+.syntaxhighlighter .toolbar a
+{
+ color: #808080 !important;
+}
+
+.syntaxhighlighter .toolbar a:hover
+{
+ color: #96DAFF !important;
+}
+
+/************************************
+ * Actual syntax highlighter colors.
+ ************************************/
+.syntaxhighlighter .plain,
+.syntaxhighlighter .plain a
+{
+ color: #FFFFFF !important;
+}
+
+.syntaxhighlighter .comments,
+.syntaxhighlighter .comments a
+{
+ color: #696854 !important;
+}
+
+.syntaxhighlighter .string,
+.syntaxhighlighter .string a
+{
+ color: #E3E658 !important;
+}
+
+.syntaxhighlighter .keyword
+{
+ color: #D01D33 !important;
+}
+
+.syntaxhighlighter .preprocessor
+{
+ color: #435A5F !important;
+}
+
+.syntaxhighlighter .variable
+{
+ color: #898989 !important;
+}
+
+.syntaxhighlighter .value
+{
+ color: #090 !important;
+}
+
+.syntaxhighlighter .functions
+{
+ color: #AAAAAA !important;
+ font-weight: bold !important;
+}
+
+.syntaxhighlighter .constants
+{
+ color: #96DAFF !important;
+}
+
+.syntaxhighlighter .script
+{
+ background-color: #C3C3C3 !important;
+ color: #000 !important;
+}
+
+.syntaxhighlighter .color1,
+.syntaxhighlighter .color1 a
+{
+ color: #FFC074 !important;
+}
+
+.syntaxhighlighter .color2,
+.syntaxhighlighter .color2 a
+{
+ color: #4A8CDB !important;
+}
+
+.syntaxhighlighter .color3,
+.syntaxhighlighter .color3 a
+{
+ color: #96DAFF !important;
+}
diff --git a/html/lib/syntaxhighlighter_2.1.364/styles/shThemeMidnight.css b/html/lib/syntaxhighlighter_2.1.364/styles/shThemeMidnight.css
new file mode 100644
index 000000000..4039464c1
--- /dev/null
+++ b/html/lib/syntaxhighlighter_2.1.364/styles/shThemeMidnight.css
@@ -0,0 +1,175 @@
+/**
+ * SyntaxHighlighter
+ * http://alexgorbatchev.com/
+ *
+ * SyntaxHighlighter is donationware. If you are using it, please donate.
+ * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate
+ *
+ * @version
+ * 2.1.364 (October 15 2009)
+ *
+ * @copyright
+ * Copyright (C) 2004-2009 Alex Gorbatchev.
+ *
+ * @license
+ * This file is part of SyntaxHighlighter.
+ *
+ * SyntaxHighlighter is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SyntaxHighlighter is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SyntaxHighlighter. If not, see .
+ */
+/**
+ * Midnight SyntaxHighlighter theme based on theme by J.D. Myers
+ * http://webdesign.lsnjd.com/
+ */
+
+/************************************
+ * Interface elements.
+ ************************************/
+
+.syntaxhighlighter
+{
+ background-color: #0F192A !important;
+}
+
+/* Gutter line numbers */
+.syntaxhighlighter .line .number
+{
+ color: #38566F !important;
+}
+
+/* Add border to the lines */
+.syntaxhighlighter .line .content
+{
+ border-left: 3px solid #435A5F !important;
+ color: #B9BDB6 !important;
+}
+
+.syntaxhighlighter.printing .line .content
+{
+ border: 0 !important;
+}
+
+/* First line */
+.syntaxhighlighter .line.alt1
+{
+ background-color: #0F192A !important;
+}
+
+/* Second line */
+.syntaxhighlighter .line.alt2
+{
+ background-color: #0F192A !important;
+}
+
+/* Highlighed line number */
+.syntaxhighlighter .line.highlighted .number
+{
+ background-color: #253E5A !important;
+ color: #fff !important;
+}
+
+/* Highlighed line */
+.syntaxhighlighter .line.highlighted.alt1,
+.syntaxhighlighter .line.highlighted.alt2
+{
+ background-color: #253E5A !important;
+}
+
+.syntaxhighlighter .toolbar
+{
+ background-color: #0F192A !important;
+}
+
+.syntaxhighlighter .toolbar a
+{
+ color: #38566F !important;
+}
+
+.syntaxhighlighter .toolbar a:hover
+{
+ color: #8AA6C1 !important;
+}
+
+/************************************
+ * Actual syntax highlighter colors.
+ ************************************/
+.syntaxhighlighter .plain,
+.syntaxhighlighter .plain a
+{
+ color: #D1EDFF !important;
+}
+
+.syntaxhighlighter .comments,
+.syntaxhighlighter .comments a
+{
+ color: #428BDD !important;
+}
+
+.syntaxhighlighter .string,
+.syntaxhighlighter .string a
+{
+ color: #1DC116 !important;
+}
+
+.syntaxhighlighter .keyword
+{
+ color: #B43D3D !important;
+}
+
+.syntaxhighlighter .preprocessor
+{
+ color: #8AA6C1 !important;
+}
+
+.syntaxhighlighter .variable
+{
+ color: #FFAA3E !important;
+}
+
+.syntaxhighlighter .value
+{
+ color: #F7E741 !important;
+}
+
+.syntaxhighlighter .functions
+{
+ color: #FFAA3E !important;
+}
+
+.syntaxhighlighter .constants
+{
+ color: #E0E8FF !important;
+}
+
+.syntaxhighlighter .script
+{
+ background-color: #404040 !important;
+}
+
+.syntaxhighlighter .color1,
+.syntaxhighlighter .color1 a
+{
+ color: #F8BB00 !important;
+}
+
+.syntaxhighlighter .color2,
+.syntaxhighlighter .color2 a
+{
+ color: #FFFFFF !important;
+}
+
+.syntaxhighlighter .color3,
+.syntaxhighlighter .color3 a
+{
+ color: #FFAA3E !important;
+}
diff --git a/html/lib/syntaxhighlighter_2.1.364/styles/shThemeRDark.css b/html/lib/syntaxhighlighter_2.1.364/styles/shThemeRDark.css
new file mode 100644
index 000000000..972aa5eef
--- /dev/null
+++ b/html/lib/syntaxhighlighter_2.1.364/styles/shThemeRDark.css
@@ -0,0 +1,175 @@
+/**
+ * SyntaxHighlighter
+ * http://alexgorbatchev.com/
+ *
+ * SyntaxHighlighter is donationware. If you are using it, please donate.
+ * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate
+ *
+ * @version
+ * 2.1.364 (October 15 2009)
+ *
+ * @copyright
+ * Copyright (C) 2004-2009 Alex Gorbatchev.
+ *
+ * @license
+ * This file is part of SyntaxHighlighter.
+ *
+ * SyntaxHighlighter is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SyntaxHighlighter is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SyntaxHighlighter. If not, see .
+ */
+/**
+ * RDark SyntaxHighlighter theme based on theme by Radu Dineiu
+ * http://www.vim.org/scripts/script.php?script_id=1732
+ */
+
+/************************************
+ * Interface elements.
+ ************************************/
+
+.syntaxhighlighter
+{
+ background-color: #1B2426 !important;
+}
+
+/* Gutter line numbers */
+.syntaxhighlighter .line .number
+{
+ color: #B9BDB6 !important;
+}
+
+/* Add border to the lines */
+.syntaxhighlighter .line .content
+{
+ border-left: 3px solid #435A5F !important;
+ color: #B9BDB6 !important;
+}
+
+.syntaxhighlighter.printing .line .content
+{
+ border: 0 !important;
+}
+
+/* First line */
+.syntaxhighlighter .line.alt1
+{
+ background-color: #1B2426 !important;
+}
+
+/* Second line */
+.syntaxhighlighter .line.alt2
+{
+ background-color: #1B2426 !important;
+}
+
+/* Highlighed line number */
+.syntaxhighlighter .line.highlighted .number
+{
+ background-color: #435A5F !important;
+ color: #fff !important;
+}
+
+/* Highlighed line */
+.syntaxhighlighter .line.highlighted.alt1,
+.syntaxhighlighter .line.highlighted.alt2
+{
+ background-color: #435A5F !important;
+}
+
+.syntaxhighlighter .toolbar
+{
+ background-color: #1B2426 !important;
+}
+
+.syntaxhighlighter .toolbar a
+{
+ color: #646763 !important;
+}
+
+.syntaxhighlighter .toolbar a:hover
+{
+ color: #E0E8FF !important;
+}
+
+/************************************
+ * Actual syntax highlighter colors.
+ ************************************/
+.syntaxhighlighter .plain,
+.syntaxhighlighter .plain a
+{
+ color: #B9BDB6 !important;
+}
+
+.syntaxhighlighter .comments,
+.syntaxhighlighter .comments a
+{
+ color: #878A85 !important;
+}
+
+.syntaxhighlighter .string,
+.syntaxhighlighter .string a
+{
+ color: #5CE638 !important;
+}
+
+.syntaxhighlighter .keyword
+{
+ color: #5BA1CF !important;
+}
+
+.syntaxhighlighter .preprocessor
+{
+ color: #435A5F !important;
+}
+
+.syntaxhighlighter .variable
+{
+ color: #FFAA3E !important;
+}
+
+.syntaxhighlighter .value
+{
+ color: #090 !important;
+}
+
+.syntaxhighlighter .functions
+{
+ color: #FFAA3E !important;
+}
+
+.syntaxhighlighter .constants
+{
+ color: #E0E8FF !important;
+}
+
+.syntaxhighlighter .script
+{
+ background-color: #435A5F !important;
+}
+
+.syntaxhighlighter .color1,
+.syntaxhighlighter .color1 a
+{
+ color: #E0E8FF !important;
+}
+
+.syntaxhighlighter .color2,
+.syntaxhighlighter .color2 a
+{
+ color: #FFFFFF !important;
+}
+
+.syntaxhighlighter .color3,
+.syntaxhighlighter .color3 a
+{
+ color: #FFAA3E !important;
+}
diff --git a/html/lib/syntaxhighlighter_2.1.364/test.html b/html/lib/syntaxhighlighter_2.1.364/test.html
new file mode 100644
index 000000000..5a208aedd
--- /dev/null
+++ b/html/lib/syntaxhighlighter_2.1.364/test.html
@@ -0,0 +1,42 @@
+
+
+
+
+ SyntaxHighlighter Build Test Page
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+SyntaxHihglighter Test
+This is a test file to insure that everything is working well.
+
+
+function test() : String
+{
+ return 10;
+}
+
+
diff --git a/html/views/blame/blame.js b/html/views/blame/blame.js
index a89326bc7..5bcbc627e 100644
--- a/html/views/blame/blame.js
+++ b/html/views/blame/blame.js
@@ -7,3 +7,7 @@ var showFile = function(txt) {
SyntaxHighlighter.highlight();
return;
}
+
+var selectCommit = function(a) {
+ Controller.selectCommit_(a);
+}
\ No newline at end of file
diff --git a/html/views/blame/index copy.html b/html/views/blame/index copy.html
new file mode 100644
index 000000000..af371b686
--- /dev/null
+++ b/html/views/blame/index copy.html
@@ -0,0 +1,726 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+summary Add a Tree displayer
+
+ //
+ // PBGitTree.m
+ // GitTest
+ //
+ // Created by Pieter de Bie on 15-06-08.
+ // Copyright 2008 __MyCompanyName__. All rights reserved.
+ //
+
+ #import "PBGitTree.h"
+ #import "PBGitCommit.h"
+ #import "NSFileHandleExt.h"
+
+
+
+summary Allow double click to open file
+
+ #import "PBEasyPipe.h"
+
+
+
+summary Delete temporary files when they are deallocated
+
+ #import "PBEasyFS.h"
+
+
+
+summary Add a Tree displayer
+
+
+ @implementation PBGitTree
+
+ @synthesize sha, path, repository, leaf, parent;
+
+ + (PBGitTree*) rootForCommit:(id) commit
+ {
+
+
+
+summary Add a Tree displayer
+
+ PBGitCommit* c = commit;
+ PBGitTree* tree = [[self alloc] init];
+ tree.parent = nil;
+ tree.leaf = NO;
+
+
+
+summary Include libgit2 as submodule and use it to store sha's
+
+ tree.sha = [c realSha];
+
+
+
+summary Add a Tree displayer
+
+ tree.repository = c.repository;
+ tree.path = @"";
+ return tree;
+ }
+
+ + (PBGitTree*) treeForTree: (PBGitTree*) prev andPath: (NSString*) path;
+ {
+ PBGitTree* tree = [[self alloc] init];
+ tree.parent = prev;
+ tree.sha = prev.sha;
+ tree.repository = prev.repository;
+ tree.path = path;
+ return tree;
+ }
+
+ - init
+ {
+ children = nil;
+
+
+
+summary Delete temporary files when they are deallocated
+
+ localFileName = nil;
+
+
+
+summary Add a Tree displayer
+
+ leaf = YES;
+ return self;
+ }
+
+
+
+
+summary Use unified interface and display tree contents
+
+ - (NSString*) refSpec
+ {
+ return [NSString stringWithFormat:@"%@:%@", self.sha, self.fullPath];
+ }
+
+
+
+
+summary Delete temporary files when they are deallocated
+
+ - (BOOL) isLocallyCached
+ {
+ NSFileManager* fs = [NSFileManager defaultManager];
+ if (localFileName && [fs fileExistsAtPath:localFileName])
+ {
+ NSDate* mtime = [[fs attributesOfItemAtPath:localFileName error: nil] objectForKey:NSFileModificationDate];
+ if ([mtime compare:localMtime] == 0)
+ return YES;
+ }
+ return NO;
+ }
+
+
+
+
+summary PBGitTree: Improve binary-file decision
+
+ - (BOOL)hasBinaryHeader:(NSString*)contents
+
+
+
+summary PBGitTree: Don't try to print binary-file contents
+
+ {
+
+
+
+summary PBGitTree: Improve binary-file decision
+
+ if(!contents)
+
+
+
+summary PBGitTree: Don't try to print binary-file contents
+
+ return NO;
+
+
+
+
+summary PBGitTree: Improve binary-file decision
+
+ return [contents rangeOfString:@"\0" options:0 range:NSMakeRange(0, ([contents length] >= 8000) ? 7999 : [contents length])].location != NSNotFound;
+
+
+
+summary PBGitTree: Don't try to print binary-file contents
+
+ }
+
+ - (BOOL)hasBinaryAttributes
+ {
+ // First ask git check-attr if the file has a binary attribute custom set
+ NSFileHandle *handle = [repository handleInWorkDirForArguments:[NSArray arrayWithObjects:@"check-attr", @"binary", [self fullPath], nil]];
+ NSData *data = [handle readDataToEndOfFile];
+ NSString *string = [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding];
+
+ if (!string)
+ return NO;
+ string = [string stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
+
+ if ([string hasSuffix:@"binary: set"])
+ return YES;
+
+ if ([string hasSuffix:@"binary: unset"])
+ return NO;
+
+ // Binary state unknown, do a check on common filename-extensions
+ for (NSString *extension in [NSArray arrayWithObjects:@".pdf", @".jpg", @".jpeg", @".png", @".bmp", @".gif", @".o", nil]) {
+ if ([[self fullPath] hasSuffix:extension])
+ return YES;
+ }
+
+ return NO;
+ }
+
+
+
+
+summary Use unified interface and display tree contents
+
+ - (NSString*) contents
+ {
+ if (!leaf)
+
+
+
+summary When selecting a folder in tree-view, display the
+
+ return [NSString stringWithFormat:@"This is a tree with path %@", [self fullPath]];
+
+
+
+summary initial blame functionality on tree view
+
+
+
+
+
+summary PBGitTree: Don't try to print binary-file contents
+
+ if ([self isLocallyCached]) {
+ NSData *data = [NSData dataWithContentsOfFile:localFileName];
+ NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
+ if (!string)
+ string = [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding];
+ return string;
+
+
+
+summary Delete temporary files when they are deallocated
+
+ }
+
+
+
+
+summary initial blame functionality on tree view
+
+ //return [repository outputForArguments:[NSArray arrayWithObjects:@"show", [self refSpec], nil]];
+ return [repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"blame", self.path, nil]];
+ }
+
+
+
+
+summary HTML Blame
+
+ // XXX: create img tag for images.
+
+
+
+summary initial blame functionality on tree view
+
+ - (NSString*) contents:(NSInteger)option
+ {
+
+
+
+summary HTML Blame
+
+ NSString* contents;
+
+
+
+
+summary initial blame functionality on tree view
+
+ if (!leaf)
+ return [NSString stringWithFormat:@"This is a tree with path %@", [self fullPath]];
+
+
+
+
+summary HTML Blame
+
+ if ([self hasBinaryAttributes])
+ return [NSString stringWithFormat:@"%@ appears to be a binary file of %d bytes", [self fullPath], [self fileSize]];
+
+ if ([self fileSize] > 52428800) // ~50MB
+ return [NSString stringWithFormat:@"%@ is too big to be displayed (%d bytes)", [self fullPath], [self fileSize]];
+
+
+
+
+summary initial blame functionality on tree view
+
+ if(option==0)
+
+
+
+summary HTML Blame
+
+ contents= [repository outputForArguments:[NSArray arrayWithObjects:@"show", [self refSpec], nil]];
+
+
+
+summary initial blame functionality on tree view
+
+ else
+
+
+
+summary HTML Blame
+
+ contents=[PBGitTree parseBlame:[repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"blame", @"-p", self.fullPath, nil]]];
+
+ if ([self hasBinaryHeader:contents])
+ return [NSString stringWithFormat:@"%@ appears to be a binary file of %d bytes", [self fullPath], [self fileSize]];
+
+ return contents;
+
+
+
+summary PBGitTree: Don't try to print binary-file contents
+
+ }
+
+ - (long long)fileSize
+ {
+ if (_fileSize)
+ return _fileSize;
+
+ NSFileHandle *handle = [repository handleForArguments:[NSArray arrayWithObjects:@"cat-file", @"-s", [self refSpec], nil]];
+ NSString *sizeString = [[NSString alloc] initWithData:[handle readDataToEndOfFile] encoding:NSISOLatin1StringEncoding];
+
+ if (!sizeString)
+ _fileSize = -1;
+ else
+ _fileSize = [sizeString longLongValue];
+
+ return _fileSize;
+ }
+
+ - (NSString *)textContents
+ {
+ if (!leaf)
+ return [NSString stringWithFormat:@"This is a tree with path %@", [self fullPath]];
+
+ if ([self hasBinaryAttributes])
+ return [NSString stringWithFormat:@"%@ appears to be a binary file of %d bytes", [self fullPath], [self fileSize]];
+
+
+
+
+summary PBGitTree: Improve binary-file decision
+
+ if ([self fileSize] > 52428800) // ~50MB
+ return [NSString stringWithFormat:@"%@ is too big to be displayed (%d bytes)", [self fullPath], [self fileSize]];
+
+
+
+summary PBGitTree: Don't try to print binary-file contents
+
+
+
+
+
+summary PBGitTree: Improve binary-file decision
+
+ NSString* contents = [self contents];
+
+
+
+summary PBGitTree: Don't try to print binary-file contents
+
+
+
+
+
+summary PBGitTree: Improve binary-file decision
+
+ if ([self hasBinaryHeader:contents])
+ return [NSString stringWithFormat:@"%@ appears to be a binary file of %d bytes", [self fullPath], [self fileSize]];
+
+
+
+summary PBGitTree: Don't try to print binary-file contents
+
+
+ return contents;
+
+
+
+summary Use unified interface and display tree contents
+
+ }
+
+
+
+
+summary Delete temporary files when they are deallocated
+
+ - (void) saveToFolder: (NSString *) dir
+ {
+ NSString* newName = [dir stringByAppendingPathComponent:path];
+
+ if (leaf) {
+ NSFileHandle* handle = [repository handleForArguments:[NSArray arrayWithObjects:@"show", [self refSpec], nil]];
+ NSData* data = [handle readDataToEndOfFile];
+ [data writeToFile:newName atomically:YES];
+ } else { // Directory
+ [[NSFileManager defaultManager] createDirectoryAtPath:newName attributes:nil];
+
+
+
+summary Fix saving tree to folder
+
+ for (PBGitTree* child in [self children])
+
+
+
+summary Delete temporary files when they are deallocated
+
+ [child saveToFolder: newName];
+ }
+ }
+
+ - (NSString*) tmpDirWithContents
+ {
+ if (leaf)
+ return nil;
+
+ if (!localFileName)
+ localFileName = [PBEasyFS tmpDirWithPrefix: path];
+
+
+
+
+summary Delete temporary files when they are deallocated
+
+ for (PBGitTree* child in [self children]) {
+
+
+
+summary Delete temporary files when they are deallocated
+
+ [child saveToFolder: localFileName];
+ }
+
+ return localFileName;
+ }
+
+
+
+
+
+
+summary Allow double click to open file
+
+ - (NSString*) tmpFileNameForContents
+ {
+ if (!leaf)
+
+
+
+summary Delete temporary files when they are deallocated
+
+ return [self tmpDirWithContents];
+
+ if ([self isLocallyCached])
+ return localFileName;
+
+ if (!localFileName)
+
+
+
+summary Prevent confusing filenames when quick-looking files.
+
+ localFileName = [[PBEasyFS tmpDirWithPrefix: sha] stringByAppendingPathComponent:path];
+
+
+
+summary Delete temporary files when they are deallocated
+
+
+
+
+
+summary Allow double click to open file
+
+ NSFileHandle* handle = [repository handleForArguments:[NSArray arrayWithObjects:@"show", [self refSpec], nil]];
+ NSData* data = [handle readDataToEndOfFile];
+
+
+
+summary Delete temporary files when they are deallocated
+
+ [data writeToFile:localFileName atomically:YES];
+
+ NSFileManager* fs = [NSFileManager defaultManager];
+ localMtime = [[fs attributesOfItemAtPath:localFileName error: nil] objectForKey:NSFileModificationDate];
+
+ return localFileName;
+
+
+
+summary Allow double click to open file
+
+ }
+
+
+
+
+summary Add a Tree displayer
+
+ - (NSArray*) children
+ {
+
+
+
+summary Use unified interface and display tree contents
+
+ if (children != nil)
+
+
+
+summary Add a Tree displayer
+
+ return children;
+
+
+
+
+summary Use unified interface and display tree contents
+
+ NSString* ref = [self refSpec];
+
+
+
+summary Add a Tree displayer
+
+
+ NSFileHandle* handle = [repository handleForArguments:[NSArray arrayWithObjects:@"show", ref, nil]];
+ [handle readLine];
+ [handle readLine];
+
+ NSMutableArray* c = [NSMutableArray array];
+
+ NSString* p = [handle readLine];
+ while (p.length > 0) {
+
+
+
+summary Bugfix: Avoid looping while parsing the children of a tree
+
+ if ([p isEqualToString:@"\r"])
+ break;
+
+
+
+
+summary Add a Tree displayer
+
+ BOOL isLeaf = ([p characterAtIndex:p.length - 1] != '/');
+ if (!isLeaf)
+ p = [p substringToIndex:p.length -1];
+
+ PBGitTree* child = [PBGitTree treeForTree:self andPath:p];
+ child.leaf = isLeaf;
+ [c addObject: child];
+
+ p = [handle readLine];
+ }
+ children = c;
+ return c;
+ }
+
+ - (NSString*) fullPath
+ {
+ if (!parent)
+ return @"";
+
+ if ([parent.fullPath isEqualToString:@""])
+ return self.path;
+
+ return [parent.fullPath stringByAppendingPathComponent: self.path];
+ }
+
+
+
+
+summary Delete temporary files when they are deallocated
+
+ - (void) finalize
+ {
+ if (localFileName)
+ [[NSFileManager defaultManager] removeFileAtPath:localFileName handler:nil];
+ [super finalize];
+ }
+
+
+
+summary HTML Blame
+
+
+ +(NSString *)parseBlame:(NSString *)string
+ {
+ string=[string stringByReplacingOccurrencesOfString:@"<" withString:@"<"];
+ string=[string stringByReplacingOccurrencesOfString:@">" withString:@">"];
+
+
+
+summary HTML Blame
+
+
+ NSArray *lines = [string componentsSeparatedByString:@"\n"];
+ NSString *line;
+ NSMutableDictionary *headers=[NSMutableDictionary dictionary];
+ NSMutableString *res=[NSMutableString string];
+
+ [res appendString:@"<table class='blocks'>\n"];
+ int i=0;
+ while(i<[lines count]){
+ line=[lines objectAtIndex:i];
+ NSArray *header=[line componentsSeparatedByString:@" "];
+ if([header count]==4){
+ int nLines=[(NSString *)[header objectAtIndex:3] intValue];
+ [res appendFormat:@"<tr class='block l%d'>\n",nLines];
+ line=[lines objectAtIndex:++i];
+ if([[[line componentsSeparatedByString:@" "] objectAtIndex:0] isEqual:@"author"]){
+ NSString *author=line;
+ NSString *summary=nil;
+ while(summary==nil){
+ line=[lines objectAtIndex:i++];
+ if([[[line componentsSeparatedByString:@" "] objectAtIndex:0] isEqual:@"summary"]){
+ summary=line;
+ }
+ }
+ NSString *block=[NSString stringWithFormat:@"<td><p class='author'>%@</p><p class='summary'>%@</p></td>\n<td>\n",author,summary];
+ [headers setObject:block forKey:[header objectAtIndex:0]];
+ }
+ [res appendString:[headers objectForKey:[header objectAtIndex:0]]];
+
+
+
+
+summary Version of PBGitTree.m from PBGitTree.m
+
+ NSMutableString *code=[NSMutableString string];
+
+
+
+summary HTML Blame
+
+ do{
+ line=[lines objectAtIndex:i++];
+ }while([line characterAtIndex:0]!='\t');
+ line=[line stringByReplacingOccurrencesOfString:@"\t" withString:@" "];
+
+
+
+summary Version of PBGitTree.m from PBGitTree.m
+
+ [code appendString:line];
+ [code appendString:@"\n"];
+
+
+
+summary HTML Blame
+
+
+ int n;
+ for(n=1;n<nLines;n++){
+ line=[lines objectAtIndex:i++];
+ NSArray *h=[line componentsSeparatedByString:@" "];
+ do{
+ line=[lines objectAtIndex:i++];
+ }while([line characterAtIndex:0]!='\t');
+ line=[line stringByReplacingOccurrencesOfString:@"\t" withString:@" "];
+
+
+
+summary Version of PBGitTree.m from PBGitTree.m
+
+ [code appendString:line];
+ [code appendString:@"\n"];
+
+
+
+summary HTML Blame
+
+ }
+
+
+
+summary Version of PBGitTree.m from PBGitTree.m
+
+ [res appendFormat:@"<pre class='first-line: %@;brush: js'>%@</pre>",[header objectAtIndex:2],code];
+ [res appendString:@"</td>\n"];
+
+
+
+summary HTML Blame
+
+ }else{
+ break;
+ }
+ [res appendString:@"</tr>\n"];
+ }
+ [res appendString:@"</table>\n"];
+
+
+
+summary Version of PBGitTree.m from PBGitTree.m
+
+ NSLog(@"%@",res);
+
+
+
+summary HTML Blame
+
+
+ return (NSString *)res;
+ }
+
+
+
+summary Add a Tree displayer
+
+ @end
+
+
+
+
+
+
\ No newline at end of file
diff --git a/html/views/commit/test.html b/html/views/commit/test.html
new file mode 100644
index 000000000..4f870000e
--- /dev/null
+++ b/html/views/commit/test.html
@@ -0,0 +1,95 @@
+
+ Diff for file
+
+
+
+
+
+
+
+
+
+
+
+
+ Context:
+ Nothing to commit
+
+
+
+
+
+
+
+ Nothing to commit (working directory clean)
+
+ PBWebChangesController.m...
+12
+13
+14
+
+
+15
+16
+17
+...
+72
+73
+74
+75
+
+
+76
+
+
+77
+78
+79
+...
+85
+86
+87
+88
+
+89
+90
+91
+...
+12
+13
+14
+15
+16
+17
+18
+19
+...
+74
+75
+76
+
+77
+78
+79
+80
+81
+82
+83
+84
+...
+90
+91
+92
+
+93
+94
+95
+96
+ @implementation PBWebChangesController +@synthesize fileViewerController;+ - (void) awakeFromNib { selectedFile = nil; - (void) refresh {- if (!finishedLoading)+ [fileViewerController showFile:[selectedFile path] sha:nil];+ /*if (!finishedLoading) return;+ + [fileViewerController showFile:selectedFile sha:@""]; id script = [view windowScriptObject]; [script callWebScriptMethod:@"showFileBlame" withArguments:[NSArray arrayWithObjects:selectedFile ?: (id)[NSNull null], [NSNumber numberWithBool:selectedFileIsCached], nil]];- }+ }*/ } - (void)stageHunk:(NSString *)hunk reverse:(BOOL)reverse
+
+
\ No newline at end of file
diff --git a/html/views/history/history.css b/html/views/history/history.css
index 7d855aa55..9be98367e 100644
--- a/html/views/history/history.css
+++ b/html/views/history/history.css
@@ -77,32 +77,6 @@ a.servicebutton {
padding-top: 10px;
}
-#files {
- margin-top: 1em;
- margin-left: 0.5em;
-}
-
-#files a {
- color: #666666;
- text-decoration: none;
-}
-
-#files a:hover {
- color: #4444ff;
- border-bottom: 1px solid #4444ff;
-}
-
-#files img {
- float: left;
- margin-right: 0.5em;
- margin-top: 1px;
-}
-
-#files p {
- margin-top: 0.25em;
- margin-bottom: 0.25em;
-}
-
.clear_both {
clear:both;
display:block;
@@ -132,7 +106,19 @@ a {
a.showdiff {
text-decoration: none;
+ text-align: center;
font-size: 1.3em;
+ background-color: #d5d5d5;
+ display: block;
+ padding: 5px 10px;
+ width: 400px;
+ margin: 25px auto 25px auto;
+ -webkit-border-radius: 10px;
+ border: 1px solid #999;
+ -webkit-box-shadow: 1px 1px 2px #DDD;
+}
+a.showdiff:hover {
+ background-color: #c4daff;
}
.refs {
@@ -159,6 +145,117 @@ a.showdiff {
.refs.currentBranch {
background-color: #fca64f;
}
+#message_files {
+ margin: 0;
+ padding: 0;
+}
+#message {
+ padding: 10px;
+}
+#files {
+ margin: 10px;
+ padding: 10px 0;
+ background-color: #f9f9f9;
+ -webkit-border-radius: 10px;
+ border: 1px solid #CCC;
+ -webkit-box-shadow: 1px 1px 2px #DDD;
+}
+#files ul {
+ margin: 0;
+ padding: 0;
+}
+#files li {
+ list-style-type: none;
+ padding: 4px 10px;
+ color: #000;
+ height: 18px;
+}
+#files li.odd {
+ background-color: #f9f9f9;
+}
+#files li.even {
+ background-color: #f0f0f0;
+}
+#files li:hover {
+ background-color: #d4e4ff;
+ cursor: pointer;
+}
+#files img.changetype-icon {
+ float: left;
+ margin: 3px 7px;
+}
+#files li .filename {
+ position: relative;
+ top: 2px;
+ font-size: 12px;
+ text-shadow: white 0 0 4px;
+ z-index: 100;
+}
+
+#files .diffstat-info {
+ padding: 0;
+ position: absolute;
+ right: 30px;
+ display: inline-block;
+}
+#files .changes-bar {
+ height: 6px;
+ display: inline-block;
+ right: 46px;
+ position: absolute;
+ -webkit-border-top-left-radius: 5px;
+ -webkit-border-bottom-left-radius: 5px;
+ -webkit-box-shadow: 0 1px 1px #fff;
+}
+#files .changes-bar.added {
+ background-color: #1a843d;
+ border: 1px solid #164b27;
+}
+#files .changes-bar.removed {
+ top: 10px;
+ background-color: #ce2e2b;
+ border: 1px solid #8c1815;
+}
+
+#files .diffstat-numbers {
+ background-color: rgba(0,0,0,.75);
+ color: #e3e3e3;
+ font-size: 12px;
+ font-weight: bold;
+ text-shadow: #000 0 1px 1px;
+ white-space: nowrap;
+ padding: 1px 5px;
+ position: absolute;
+ height: 14px;
+ border: 1px solid black;
+ -webkit-box-shadow: 0 1px 1px white;
+}
+
+#files .diffstat-numbers.summary {
+ -webkit-border-top-right-radius: 12px;
+ -webkit-border-bottom-right-radius: 12px;
+ right: 0px;
+ width: 35px;
+}
+#files .diffstat-numbers.details {
+ -webkit-border-top-left-radius: 12px;
+ -webkit-border-bottom-left-radius: 12px;
+ right: 46px;
+ text-align: right;
+}
+#files .diffstat-numbers.details .added {
+ color: #5db15d;
+}
+#files .diffstat-numbers.details .removed {
+ color: #f34b4e;
+}
+
+#files .diffstat-numbers.binary {
+ display: inline-block;
+ right: 30px;
+ -webkit-border-radius: 12px;
+ background-color: #a7681f;
+}
/*
div.button
diff --git a/html/views/history/history.js b/html/views/history/history.js
index 225e590fd..d030efec5 100644
--- a/html/views/history/history.js
+++ b/html/views/history/history.js
@@ -1,4 +1,5 @@
-var commit;
+var commit,
+ fileElementPrototype;
// Create a new Commit object
// obj: PBGitCommit object
@@ -16,39 +17,124 @@ var Commit = function(obj) {
// TODO:
// this.author_date instant
- // This can be called later with the output of
- // 'git show' to fill in missing commit details (such as a diff)
- this.parseDetails = function(details) {
- this.raw = details;
+ this.parseSummary = function(summaryString) {
+ this.summaryRaw = summaryString;
+
+ // Get the header info and the full commit message
+ var messageStart = this.summaryRaw.indexOf("\n\n") + 2;
+ this.header = this.summaryRaw.substring(0, messageStart);
+ var afterHeader = this.summaryRaw.substring(messageStart);
+ var numstatStart = afterHeader.indexOf("\n\n") + 2;
+ if (numstatStart > 1) {
+ this.message = afterHeader.substring(0, numstatStart).replace(/^ /gm, "").escapeHTML();;
+ var afterMessage = afterHeader.substring(numstatStart);
+ var filechangeStart = afterMessage.indexOf("\n ") + 1;
+ if (filechangeStart > 1) {
+ this.numstatRaw = afterMessage.substring(0, filechangeStart);
+ this.filechangeRaw = afterMessage.substring(filechangeStart);
+ }
+ else {
+ this.numstatRaw = afterMessage;
+ this.filechangeRaw = "";
+ }
+ }
+ else {
+ this.message = afterHeader;
+ this.numstatRaw = "";
+ this.filechangeRaw = "";
+ }
+
+
+ if (typeof this.header !== 'undefined') {
+ var matches = this.header.match(/\nauthor (.*) <(.*@.*|.*)> ([0-9].*)/);
+ if (matches !== null && matches[2] !== null) {
+ if (!(matches[2].match(/@[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/)))
+ this.author_email = matches[2];
+
+ if (typeof matches[3] !== 'undefined')
+ this.author_date = new Date(parseInt(matches[3]) * 1000);
+
+ matches = this.header.match(/\ncommitter (.*) <(.*@.*|.*)> ([0-9].*)/);
+ if (typeof matches[2] !== 'undefined')
+ this.committer_email = matches[2];
+ if (typeof matches[3] !== 'undefined')
+ this.committer_date = new Date(parseInt(matches[3]) * 1000);
+ }
+ }
+
+ // Parse the --numstat part to get the list of files and lines changed.
+ this.filesInfo = [];
+ var lines = this.numstatRaw.split('\n');
+ for (var lineno=0; lineno < lines.length; lineno++) {
+ var columns = lines[lineno].split('\t');
+ if (columns.length >= 2) {
+ if (columns[0] == "-" && columns[1] == "-") {
+ this.filesInfo.push({"filename": columns[2],
+ "changeType": "modified",
+ "binary": true});
+ }
+ else {
+ this.filesInfo.push({"numLinesAdded": parseInt(columns[0]),
+ "numLinesRemoved": parseInt(columns[1]),
+ "filename": columns[2],
+ "changeType": "modified",
+ "binary": false});
+ }
+ }
+ }
+
+ // Parse the filechange part (from --summary) to get info about files
+ // that were added/deleted/etc.
+ // Sample text:
+ // create mode 100644 GitXTextFieldCell.h
+ // delete mode 100644 someDir/filename with spaces.txt
+ // rename fielname with spaces.txt => filename_without_spaces.txt (98%)
+ var lines = this.filechangeRaw.split('\n');
+ for (var lineno=0; lineno < lines.length; lineno++) {
+ var line = lines[lineno];
+ var filename="", changeType="";
+ if (line.indexOf("delete") == 1) {
+ filename = line.match(/ delete mode \d+ (.*)$/)[0];
+ changeType = "removed";
+ }
+ else if (line.indexOf("create") == 1) {
+ filename = line.match(/ create mode \d+ (.*)/)[0];
+ changeType = "added";
+ }
+ else if (line.indexOf("rename") == 1) {
+ // get the new name of the file (the part after the " => ")
+ filename = line.match(/ rename (.*) \(.+\)$/)[0];
+ changeType = "renamed";
+ }
+
+ if (filename != "") {
+ // Update the appropriate filesInfo with the actual changeType.
+ for (var i=0; i < commit.filesInfo.length; i+=1) {
+ if (commit.filesInfo[i].filename == filename) {
+ commit.filesInfo[i].changeType = changeType;
+ if (changeType == "renamed") {
+ var names = filename.split(" => ");
+ commit.filesInfo[i].oldFilename = names[0];
+ commit.filesInfo[i].newFilename = names[1];
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
- var diffStart = this.raw.indexOf("\ndiff ");
- var messageStart = this.raw.indexOf("\n\n") + 2;
+ // This can be called later with the output of
+ // 'git show' to get the full diff
+ this.parseFullDiff = function(fullDiff) {
+ this.fullDiffRaw = fullDiff;
+ var diffStart = this.fullDiffRaw.indexOf("\ndiff ");
if (diffStart > 0) {
- this.message = this.raw.substring(messageStart, diffStart).replace(/^ /gm, "").escapeHTML();
- this.diff = this.raw.substring(diffStart);
+ this.diff = this.fullDiffRaw.substring(diffStart);
} else {
- this.message = this.raw.substring(messageStart).replace(/^ /gm, "").escapeHTML();
this.diff = "";
}
- this.header = this.raw.substring(0, messageStart);
-
- if (typeof this.header !== 'undefined') {
- var match = this.header.match(/\nauthor (.*) <(.*@.*|.*)> ([0-9].*)/);
- if (typeof match !== 'undefined' && typeof match[2] !== 'undefined') {
- if (!(match[2].match(/@[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/)))
- this.author_email = match[2];
-
- if (typeof match[3] !== 'undefined')
- this.author_date = new Date(parseInt(match[3]) * 1000);
-
- match = this.header.match(/\ncommitter (.*) <(.*@.*|.*)> ([0-9].*)/);
- if (typeof match[2] !== 'undefined')
- this.committer_email = match[2];
- if (typeof match[3] !== 'undefined')
- this.committer_date = new Date(parseInt(match[3]) * 1000);
- }
- }
}
this.reloadRefs = function() {
@@ -57,6 +143,13 @@ var Commit = function(obj) {
};
+var extractPrototypes = function() {
+ // Grab an element from the DOM, save it in a global variable (with its
+ // id removed) so it can be copied later, and remove it from the DOM.
+ fileElementPrototype = $('file_prototype');
+ fileElementPrototype.removeAttribute('id');
+ fileElementPrototype.parentNode.removeChild(fileElementPrototype);
+}
var confirm_gist = function(confirmation_message) {
if (!Controller.isFeatureEnabled_("confirmGist")) {
@@ -169,9 +262,9 @@ var showRefs = function() {
var loadCommit = function(commitObject, currentRef) {
// These are only the things we can do instantly.
- // Other information will be loaded later by loadCommitDetails,
- // Which will be called from the controller once
- // the commit details are in.
+ // Other information will be loaded later by loadCommitSummary
+ // and loadCommitFullDiff, which will be called from the
+ // controller once the commit details are in.
if (commit && commit.notificationID)
clearTimeout(commit.notificationID);
@@ -182,10 +275,13 @@ var loadCommit = function(commitObject, currentRef) {
$("commitID").innerHTML = commit.sha;
$("authorID").innerHTML = commit.author_name;
$("subjectID").innerHTML = commit.subject.escapeHTML();
- $("diff").innerHTML = ""
- $("message").innerHTML = ""
- $("files").innerHTML = ""
- $("date").innerHTML = ""
+ $("diff").innerHTML = "";
+ $("message").innerHTML = "";
+ $("date").innerHTML = "";
+ $("files").style.display = "none";
+ var filelist = $("filelist");
+ while (filelist.hasChildNodes())
+ filelist.removeChild(filelist.lastChild);
showRefs();
for (var i = 0; i < $("commit_header").rows.length; ++i) {
@@ -219,51 +315,7 @@ var loadCommit = function(commitObject, currentRef) {
var showDiff = function() {
- $("files").innerHTML = "";
-
// Callback for the diff highlighter. Used to generate a filelist
- var newfile = function(name1, name2, id, mode_change, old_mode, new_mode) {
- var img = document.createElement("img");
- var p = document.createElement("p");
- var link = document.createElement("a");
- link.setAttribute("href", "#" + id);
- p.appendChild(link);
- var finalFile = "";
- if (name1 == name2) {
- finalFile = name1;
- img.src = "../../images/modified.png";
- img.title = "Modified file";
- p.title = "Modified file";
- if (mode_change)
- p.appendChild(document.createTextNode(" mode " + old_mode + " -> " + new_mode));
- }
- else if (name1 == "/dev/null") {
- img.src = "../../images/added.png";
- img.title = "Added file";
- p.title = "Added file";
- finalFile = name2;
- }
- else if (name2 == "/dev/null") {
- img.src = "../../images/removed.png";
- img.title = "Removed file";
- p.title = "Removed file";
- finalFile = name1;
- }
- else {
- img.src = "../../images/renamed.png";
- img.title = "Renamed file";
- p.title = "Renamed file";
- finalFile = name2;
- p.insertBefore(document.createTextNode(name1 + " -> "), link);
- }
-
- link.appendChild(document.createTextNode(finalFile));
- link.setAttribute("representedFile", finalFile);
-
- p.insertBefore(img, link);
- $("files").appendChild(p);
- }
-
var binaryDiff = function(filename) {
if (filename.match(/\.(png|jpg|icns|psd)$/i))
return 'Display image';
@@ -271,7 +323,7 @@ var showDiff = function() {
return "Binary file differs";
}
- highlightDiff(commit.diff, $("diff"), { "newfile" : newfile, "binaryFile" : binaryDiff });
+ highlightDiff(commit.diff, $("diff"), { "binaryFile" : binaryDiff });
}
var showImage = function(element, filename)
@@ -296,27 +348,27 @@ var enableFeatures = function()
enableFeature("gravatar", $("committer_gravatar").parentNode)
}
-var loadCommitDetails = function(data)
+var loadCommitSummary = function(data)
{
- commit.parseDetails(data);
-
+ commit.parseSummary(data);
+
if (commit.notificationID)
clearTimeout(commit.notificationID)
- else
- $("notification").style.display = "none";
-
+ else
+ $("notification").style.display = "none";
+
var formatEmail = function(name, email) {
return email ? name + " <" + email + ">" : name;
}
-
+
$("authorID").innerHTML = formatEmail(commit.author_name, commit.author_email);
$("date").innerHTML = commit.author_date;
setGravatar(commit.author_email, $("author_gravatar"));
-
+
if (commit.committer_name != commit.author_name) {
$("committerID").parentNode.style.display = "";
$("committerID").innerHTML = formatEmail(commit.committer_name, commit.committer_email);
-
+
$("committerDate").parentNode.style.display = "";
$("committerDate").innerHTML = commit.committer_date;
setGravatar(commit.committer_email, $("committer_gravatar"));
@@ -324,13 +376,111 @@ var loadCommitDetails = function(data)
$("committerID").parentNode.style.display = "none";
$("committerDate").parentNode.style.display = "none";
}
-
+
$("message").innerHTML = commit.message.replace(/\n/g,"
");
+ if (commit.filesInfo.length > 0) {
+ // Create the file list
+ for (var i=0; i < commit.filesInfo.length; i+=1) {
+ var fileInfo = commit.filesInfo[i];
+ var fileElem = fileElementPrototype.cloneNode(true); // this is a
+ fileElem.targetFileId = "file_index_"+i;
+
+ var displayName, representedFile;
+ if (fileInfo.changeType == "renamed") {
+ displayName = fileInfo.filename;
+ representedFile = fileInfo.newFilename;
+ }
+ else {
+ displayName = fileInfo.filename;
+ representedFile = fileInfo.filename;
+ }
+ fileElem.title = fileInfo.changeType + ": " + displayName; // set tooltip
+ fileElem.setAttribute("representedFile", representedFile);
+
+ if (i % 2)
+ fileElem.className += "even";
+ else
+ fileElem.className += "odd";
+ fileElem.onclick = function () {
+ // Show the full diff in case it's not already visisble.
+ showDiff();
+ // Scroll to that file.
+ $(this.targetFileId).scrollIntoView(true);
+ }
+
+ // Start with a modified icon, and update it later when the
+ // `diff --summary` info comes back.
+ var imgElement = fileElem.getElementsByClassName("changetype-icon")[0];
+ imgElement.src = "../../images/"+fileInfo.changeType+".png";
+
+ var filenameElement = fileElem.getElementsByClassName("filename")[0];
+ filenameElement.innerText = displayName;
+
+ var diffstatElem = fileElem.getElementsByClassName("diffstat-info")[0];
+ var binaryElem = fileElem.getElementsByClassName("binary")[0]
+ if (fileInfo.binary) {
+ // remove the diffstat-info element
+ diffstatElem.parentNode.removeChild(diffstatElem);
+ }
+ else {
+ // remove the binary element
+ binaryElem.parentNode.removeChild(binaryElem);
+
+ // Show the num of lines added/removed
+ var addedWidth = 2 * fileInfo.numLinesAdded;
+ var removedWidth = 2 * fileInfo.numLinesRemoved;
+ // Scale them down proportionally if they're too wide.
+ var maxWidth = 350;
+ var minWidth = 5;
+ if (addedWidth+removedWidth > maxWidth) {
+ var scaleBy = maxWidth/(addedWidth+removedWidth);
+ addedWidth *= scaleBy;
+ removedWidth *= scaleBy;
+ }
+ if (addedWidth > 0 && addedWidth < minWidth) addedWidth = minWidth;
+ if (removedWidth > 0 && removedWidth < minWidth) removedWidth = minWidth;
+
+ // show lines changed info
+ var numLinesAdded = fileInfo.numLinesAdded;
+ var numLinesRemoved = fileInfo.numLinesRemoved;
+ var numLinesChanged = numLinesAdded + numLinesRemoved;
+ // summarize large numbers
+ if (numLinesChanged > 999) numLinesChanged = "~" + Math.round(numLinesChanged / 1000) + "k";
+ // fill in numbers
+ var diffstatSummary = diffstatElem.getElementsByClassName("diffstat-numbers")[1];
+ diffstatSummary.innerText = numLinesChanged;
+ var diffstatDetails = diffstatElem.getElementsByClassName("diffstat-numbers")[0];
+ diffstatDetails.getElementsByClassName("added")[0].innerText = "+"+numLinesAdded;
+ diffstatDetails.getElementsByClassName("removed")[0].innerText = "-"+numLinesRemoved;
+
+ // Size the bars
+ var addedBar = diffstatElem.getElementsByClassName("changes-bar")[0];
+ if (addedWidth >= minWidth)
+ addedBar.style.width = addedWidth;
+ else
+ addedBar.style.visibility = "hidden";
+
+ var removedBar = diffstatElem.getElementsByClassName("changes-bar")[1];
+ if (removedWidth >= minWidth)
+ removedBar.style.width = removedWidth;
+ else
+ removedBar.style.visibility = "hidden";
+ }
+ $("filelist").appendChild(fileElem);
+ }
+ $("files").style.display = "";
+ }
+}
+
+var loadCommitFullDiff = function(data)
+{
+ commit.parseFullDiff(data);
+
if (commit.diff.length < 200000)
showDiff();
else
- $("diff").innerHTML = "This is a large commit. Click here or press 'v' to view.";
+ $("diff").innerHTML = "This is a large commit.
Click here or press 'v' to view.";
hideNotification();
enableFeatures();
diff --git a/html/views/history/index.html b/html/views/history/index.html
index cc8d4a286..7b6ac5aca 100644
--- a/html/views/history/index.html
+++ b/html/views/history/index.html
@@ -9,9 +9,38 @@
+
-
+