initial ungit plugin commit
This commit is contained in:
parent
540bfbab5b
commit
4badb37a72
BIN
plugins/ungit.png
Normal file
BIN
plugins/ungit.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
73
source/ungit/etc/rc.d/rc.ungit
Executable file
73
source/ungit/etc/rc.d/rc.ungit
Executable file
|
@ -0,0 +1,73 @@
|
|||
#!/bin/sh
|
||||
# start/stop/restart ungit daemon:
|
||||
PLG="ungit"
|
||||
EMHTTP="/usr/local/emhttp/plugins/$PLG"
|
||||
PROG="$EMHTTP/node_modules/$PLG/src/server.js"
|
||||
LOCKFILE="/var/lock/$PLG"
|
||||
PIDFILE="/var/run/$PLG.pid"
|
||||
CONFIG="/boot/config/plugins/$PLG/$PLG.cfg"
|
||||
|
||||
# read our configuration
|
||||
[ -e "$CONFIG" ] && source "$CONFIG"
|
||||
|
||||
# Start ungit:
|
||||
ungit_start() {
|
||||
# no-op if already running
|
||||
if [ ! -r "$PIDFILE" ]; then
|
||||
if [ "$DAEMON" == "enable" ]; then
|
||||
echo "starting $PLG..."
|
||||
sleep 1
|
||||
#cd $EMHTTP/node_modules/$PLG
|
||||
nohup /usr/bin/node $PROG --port="$PORT" --logDirectory="/var/log/" --logGitCommands --logGitOutput >/var/log/$PLG 2>&1 | echo $! > $PIDFILE &
|
||||
touch $LOCKFILE
|
||||
TIMER=0
|
||||
while [ ! -e $PIDFILE ]; do
|
||||
sleep 1
|
||||
let TIMER=$TIMER+1
|
||||
if [ $TIMER -gt 5 ]; then
|
||||
echo -n "$PIDFILE not created"
|
||||
break
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo "$PLG is not enabled "
|
||||
fi
|
||||
else
|
||||
echo "$PLG is running "
|
||||
fi
|
||||
}
|
||||
|
||||
# Stop ungit:
|
||||
ungit_stop() {
|
||||
# no-op if not running
|
||||
if [ -r $PIDFILE ]; then
|
||||
#stop ungit
|
||||
echo "stopping $PLG..."
|
||||
sleep 1
|
||||
kill $(cat $PIDFILE)
|
||||
rm -f $LOCKFILE && rm -f $PIDFILE
|
||||
else
|
||||
echo "$PLG is stopped "
|
||||
fi
|
||||
}
|
||||
|
||||
# Restart ungit:
|
||||
ungit_restart() {
|
||||
ungit_stop
|
||||
sleep 1
|
||||
ungit_start
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
'start')
|
||||
ungit_start
|
||||
;;
|
||||
'stop')
|
||||
ungit_stop
|
||||
;;
|
||||
'restart')
|
||||
ungit_restart
|
||||
;;
|
||||
*)
|
||||
echo "usage rc.ungit: start|stop|restart"
|
||||
esac
|
12
source/ungit/install/doinst.sh
Normal file
12
source/ungit/install/doinst.sh
Normal file
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh
|
||||
RC_SCRIPT="/etc/rc.d/rc.ungit"
|
||||
SD_RCFILE="/etc/rc.d/rc.local_shutdown"
|
||||
|
||||
# Update file permissions of scripts
|
||||
chmod +0755 $RC_SCRIPT
|
||||
|
||||
# add stop to shutdown script
|
||||
if ! grep "$RC_SCRIPT" $SD_RCFILE >/dev/null 2>&1
|
||||
then echo -e "\n[ -x $RC_SCRIPT ] && $RC_SCRIPT stop" >> $SD_RCFILE
|
||||
fi
|
||||
[ ! -x $SD_RCFILE ] && chmod u+x $SD_RCFILE
|
19
source/ungit/install/slack-desc
Normal file
19
source/ungit/install/slack-desc
Normal file
|
@ -0,0 +1,19 @@
|
|||
# HOW TO EDIT THIS FILE:
|
||||
# The "handy ruler" below makes it easier to edit a package description.
|
||||
# Line up the first '|' above the ':' following the base package name, and
|
||||
# the '|' on the right side marks the last column you can put a character in.
|
||||
# You must make exactly 11 lines for the formatting to be correct. It's also
|
||||
# customary to leave one space after the ':' except on otherwise blank lines.
|
||||
|
||||
|-----handy-ruler------------------------------------------------------|
|
||||
ungit: unGit unRAID 6.1+ Plugin
|
||||
ungit:
|
||||
ungit: Ungit is to bring user friendliness to git without sacrificing
|
||||
ungit: versatility of git. Clean and intuitive UI that makes it easy to
|
||||
ungit: understand git.
|
||||
ungit:
|
||||
ungit: https://github.com/FredrikNoren/ungit-gerrit
|
||||
ungit:
|
||||
ungit: dmacias72/unRAID
|
||||
ungit: https://github.com/dmacias72/unRAID-plugins
|
||||
ungit:
|
37
source/ungit/pkg_build.sh
Executable file
37
source/ungit/pkg_build.sh
Executable file
|
@ -0,0 +1,37 @@
|
|||
#!/bin/bash
|
||||
DIR="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")"
|
||||
tmpdir=/tmp/tmp.$(( $RANDOM * 19318203981230 + 40 ))
|
||||
plugin=$(basename ${DIR})
|
||||
archive="$(dirname $(dirname ${DIR}))/archive"
|
||||
version=$(date +"%Y.%m.%d")
|
||||
package="${archive}/${plugin}-${version}-x86_64-1.txz"
|
||||
md5="${archive}/${plugin}-${version}-x86_64-1.md5"
|
||||
|
||||
if [[ -f $package ]]; then
|
||||
for x in a b c d e d f g h ; do
|
||||
package="${archive}/${plugin}-${version}${x}-x86_64-1.txz"
|
||||
md5="${archive}/${plugin}-${version}${x}-x86_64-1.md5"
|
||||
if [[ ! -f $package ]]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
mkdir -p $tmpdir
|
||||
cd "$DIR"
|
||||
cp --parents -f $(find . -type f ! \( -iname "pkg_build.sh" -o -iname "sftp-config.json" -o -iname ".DS_Store" \) ) $tmpdir/
|
||||
cd "$tmpdir/"
|
||||
makepkg -l y -c y "${package}"
|
||||
cd "$archive/"
|
||||
md5sum $(basename "$package") > "$md5"
|
||||
rm -rf "$tmpdir"
|
||||
|
||||
# Verify and install plugin package
|
||||
sum1=$(md5sum "${package}")
|
||||
sum2=$(cat "$md5")
|
||||
if [ "${sum1:0:32}" != "${sum2:0:32}" ]; then
|
||||
echo "Checksum mismatched.";
|
||||
rm "$md5" "${package}"
|
||||
else
|
||||
echo "Checksum matched."
|
||||
fi
|
107
source/ungit/usr/local/emhttp/plugins/ungit/UnGit.page
Normal file
107
source/ungit/usr/local/emhttp/plugins/ungit/UnGit.page
Normal file
|
@ -0,0 +1,107 @@
|
|||
Icon="ungit.png"
|
||||
Menu="NetworkServices"
|
||||
Title="unGit"
|
||||
---
|
||||
<? require_once '/usr/local/emhttp/plugins/ungit/include/settings.php';?>
|
||||
|
||||
<form markdown="1" id="gform" name="g_settings" action="/update.php" method="POST" target="progressFrame">
|
||||
<input type="hidden" name="#file" value="ungit/ungit.cfg" />
|
||||
<input type="hidden" id="command" name="#command" value="" />
|
||||
|
||||
Enable unGit Server (<?=$gversion;?>):
|
||||
: <select id="DAEMON" name="DAEMON" size="1" onChange="checkRUNNING(this.form);">
|
||||
<?=mk_option($gdaemon, "disable", "No");?>
|
||||
<?=mk_option($gdaemon, "enable", "Yes");?>
|
||||
</select>
|
||||
|
||||
> Choose to enable unGit Server.
|
||||
>
|
||||
> Select Yes to enable, No to disable.
|
||||
|
||||
Port:
|
||||
: <input id="PORT" name="PORT" type="text" class="g-run" style="width:25px" maxlength="4" value="<?=$gport;?>" title="port must be 0-65535, default is 8888" placeholder="Port" >
|
||||
|
||||
> Enter Port number of your unGit Server
|
||||
|
||||
<input id="DEFAULT" class="g-run" type="submit" value="Default" onClick="resetDATA(this.form)"><input id="BtnConnect" type="button" value="Connect">
|
||||
: <input id="btnApply" type="submit" value="Apply" style="margin-bottom:8px" onClick="verifyDATA(this.form);"><input type="button" value="Done" onClick="done()">
|
||||
</form>
|
||||
|
||||
<div id="title" ><span class="left"><img class="icon" src="/webGui/icons/log.png"> unGit Log </span></div>
|
||||
<table class="tablesorter" style="margin-top: -22px;">
|
||||
<thead>
|
||||
<th>Logfile</th>
|
||||
<th>Size</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?
|
||||
$log = '/var/log/ungit';
|
||||
if(file_exists($log)){
|
||||
echo "<tr><td style='cursor:pointer;'><a title='$log' onclick=\"openWindow('/webGui/scripts/tail_log&arg1=ungit','unGit Log',600,900);\">$log</a></td><td>"
|
||||
.filesize($log).'</td></tr>';
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<script type="text/javascript" src="/plugins/ungit/js/jquery.mask.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
$('.tabs')
|
||||
.append("<span class='status'>Status: <?=$gstatus;?> </span>");
|
||||
|
||||
// dynamix plugin update api
|
||||
<?if (function_exists('plugin_update_available') && $version = plugin_update_available('ungit')):?>
|
||||
showNotice('ungit Notify <?=$version?> available. <a>Update</a>','ungit');
|
||||
$('#user-notice a').on('click', function () {
|
||||
$('#user-notice').empty();
|
||||
});
|
||||
<?endif;?>
|
||||
|
||||
$('#PORT').mask('0000#');
|
||||
|
||||
$('#BtnConnect').click(function () {
|
||||
window.open("<?php echo 'http://',$var['NAME'],':',$gport;?>", '_blank');
|
||||
});
|
||||
|
||||
checkRUNNING(document.g_settings);
|
||||
});
|
||||
|
||||
|
||||
function resetDATA(form) {
|
||||
form.PORT.value = 8888;
|
||||
}
|
||||
|
||||
function checkRUNNING(form) {
|
||||
if ("<?=$grunning;?>" == true){
|
||||
$('.g-run').prop('disabled', true);
|
||||
$('#BtnConnect').prop('disabled', false);
|
||||
form.btnApply.disabled = true;
|
||||
}else{
|
||||
$('.g-run').prop('disabled', false);
|
||||
$('#BtnConnect').prop('disabled', true);
|
||||
}
|
||||
if (form.DAEMON.value == 'enable'){
|
||||
form.command.value = '/usr/local/emhttp/plugins/ungit/scripts/start';
|
||||
} else {
|
||||
form.command.value = '/usr/local/emhttp/plugins/ungit/scripts/stop';
|
||||
form.btnApply.disabled = (form.DAEMON.value == 'enable');
|
||||
}
|
||||
}
|
||||
|
||||
function verifyDATA(form) {
|
||||
if (form.PORT.value < 0 || form.PORT.value > 65535){
|
||||
form.PORT.value = 8888;
|
||||
}
|
||||
form.DAEMON.value = form.DAEMON.value.replace(/ /g,"_");
|
||||
}
|
||||
|
||||
/* empty fan log */
|
||||
function clearFanLOG(){
|
||||
$.get('/plugins/ungit/include/fanlog_clear.php', {},function() {
|
||||
$('#fanlog-size').html('0');
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
BIN
source/ungit/usr/local/emhttp/plugins/ungit/icons/ungit.png
Normal file
BIN
source/ungit/usr/local/emhttp/plugins/ungit/icons/ungit.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 636 B |
BIN
source/ungit/usr/local/emhttp/plugins/ungit/images/ungit.png
Normal file
BIN
source/ungit/usr/local/emhttp/plugins/ungit/images/ungit.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.7 KiB |
|
@ -0,0 +1,18 @@
|
|||
<?
|
||||
$gcfg_file = '/boot/config/plugins/ungit/ungit.cfg';
|
||||
if(file_exists($gcfg_file))
|
||||
$gcfg = parse_ini_file($gcfg_file);
|
||||
|
||||
$gdaemon = isset($gcfg['DAEMON']) ? $gcfg['DAEMON'] : "disable";
|
||||
//$qipaddr = preg_match('/^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:[.](?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$/', $ipmi_cfg['host']) ?
|
||||
// $qcfg['host'] : $var['IPADDR'];
|
||||
$gipaddr = 'localhost';
|
||||
$gport = (isset($gcfg['port']) && is_numeric($gcfg['port']) && $gcfg['port'] > 0 && $gcfg['port'] < 65535 ) ? $gcfg['port'] : 8888;
|
||||
$gversion = shell_exec( '/usr/local/emhttp/plugins/ungit/node_modules/ungit/bin/ungit -v' );
|
||||
|
||||
//check running status
|
||||
$grunning = (trim(shell_exec( "[ -f /proc/`cat /var/run/ungit.pid 2> /dev/null`/exe ] && echo 1 || echo 0 2> /dev/null" )) == 1);
|
||||
$daemon_running = "<span class='green'>Running</span>";
|
||||
$daemon_stopped = "<span class='orange'>Stopped</span>";
|
||||
$gstatus = ($grunning) ? $daemon_running : $daemon_stopped;
|
||||
?>
|
482
source/ungit/usr/local/emhttp/plugins/ungit/js/jquery.mask.js
Normal file
482
source/ungit/usr/local/emhttp/plugins/ungit/js/jquery.mask.js
Normal file
|
@ -0,0 +1,482 @@
|
|||
/**
|
||||
* jquery.mask.js
|
||||
* @version: v1.11.3
|
||||
* @author: Igor Escobar
|
||||
*
|
||||
* Created by Igor Escobar on 2012-03-10. Please report any bug at http://blog.igorescobar.com
|
||||
*
|
||||
* Copyright (c) 2012 Igor Escobar http://blog.igorescobar.com
|
||||
*
|
||||
* The MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
/*jshint laxbreak: true */
|
||||
/* global define */
|
||||
|
||||
// UMD (Universal Module Definition) patterns for JavaScript modules that work everywhere.
|
||||
// https://github.com/umdjs/umd/blob/master/jqueryPluginCommonjs.js
|
||||
(function (factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(["jquery"], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS
|
||||
factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals
|
||||
factory(window.jQuery || window.Zepto);
|
||||
}
|
||||
}(function ($) {
|
||||
"use strict";
|
||||
var Mask = function (el, mask, options) {
|
||||
el = $(el);
|
||||
|
||||
var jMask = this, old_value = el.val(), regexMask;
|
||||
|
||||
mask = typeof mask === "function" ? mask(el.val(), undefined, el, options) : mask;
|
||||
|
||||
var p = {
|
||||
invalid: [],
|
||||
getCaret: function () {
|
||||
try {
|
||||
var sel,
|
||||
pos = 0,
|
||||
ctrl = el.get(0),
|
||||
dSel = document.selection,
|
||||
cSelStart = ctrl.selectionStart;
|
||||
|
||||
// IE Support
|
||||
if (dSel && navigator.appVersion.indexOf("MSIE 10") === -1) {
|
||||
sel = dSel.createRange();
|
||||
sel.moveStart('character', el.is("input") ? -el.val().length : -el.text().length);
|
||||
pos = sel.text.length;
|
||||
}
|
||||
// Firefox support
|
||||
else if (cSelStart || cSelStart === '0') {
|
||||
pos = cSelStart;
|
||||
}
|
||||
|
||||
return pos;
|
||||
} catch (e) {}
|
||||
},
|
||||
setCaret: function(pos) {
|
||||
try {
|
||||
if (el.is(":focus")) {
|
||||
var range, ctrl = el.get(0);
|
||||
|
||||
if (ctrl.setSelectionRange) {
|
||||
ctrl.setSelectionRange(pos,pos);
|
||||
} else if (ctrl.createTextRange) {
|
||||
range = ctrl.createTextRange();
|
||||
range.collapse(true);
|
||||
range.moveEnd('character', pos);
|
||||
range.moveStart('character', pos);
|
||||
range.select();
|
||||
}
|
||||
}
|
||||
} catch (e) {}
|
||||
},
|
||||
events: function() {
|
||||
el
|
||||
.on('keyup.mask', p.behaviour)
|
||||
.on("paste.mask drop.mask", function() {
|
||||
setTimeout(function() {
|
||||
el.keydown().keyup();
|
||||
}, 100);
|
||||
})
|
||||
.on('change.mask', function(){
|
||||
el.data('changed', true);
|
||||
})
|
||||
.on("blur.mask", function(){
|
||||
if (old_value !== el.val() && !el.data('changed')) {
|
||||
el.trigger("change");
|
||||
}
|
||||
el.data('changed', false);
|
||||
})
|
||||
// it's very important that this callback remains in this position
|
||||
// otherwhise old_value it's going to work buggy
|
||||
.on('keydown.mask, blur.mask', function() {
|
||||
old_value = el.val();
|
||||
})
|
||||
// select all text on focus
|
||||
.on('focus.mask', function (e) {
|
||||
if (options.selectOnFocus === true) {
|
||||
$(e.target).select();
|
||||
}
|
||||
})
|
||||
// clear the value if it not complete the mask
|
||||
.on("focusout.mask", function() {
|
||||
if (options.clearIfNotMatch && !regexMask.test(p.val())) {
|
||||
p.val('');
|
||||
}
|
||||
});
|
||||
},
|
||||
getRegexMask: function() {
|
||||
var maskChunks = [], translation, pattern, optional, recursive, oRecursive, r;
|
||||
|
||||
for (var i = 0; i < mask.length; i++) {
|
||||
translation = jMask.translation[mask.charAt(i)];
|
||||
|
||||
if (translation) {
|
||||
|
||||
pattern = translation.pattern.toString().replace(/.{1}$|^.{1}/g, "");
|
||||
optional = translation.optional;
|
||||
recursive = translation.recursive;
|
||||
|
||||
if (recursive) {
|
||||
maskChunks.push(mask.charAt(i));
|
||||
oRecursive = {digit: mask.charAt(i), pattern: pattern};
|
||||
} else {
|
||||
maskChunks.push(!optional && !recursive ? pattern : (pattern + "?"));
|
||||
}
|
||||
|
||||
} else {
|
||||
maskChunks.push(mask.charAt(i).replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'));
|
||||
}
|
||||
}
|
||||
|
||||
r = maskChunks.join("");
|
||||
|
||||
if (oRecursive) {
|
||||
r = r.replace(new RegExp("(" + oRecursive.digit + "(.*" + oRecursive.digit + ")?)"), "($1)?")
|
||||
.replace(new RegExp(oRecursive.digit, "g"), oRecursive.pattern);
|
||||
}
|
||||
|
||||
return new RegExp(r);
|
||||
},
|
||||
destroyEvents: function() {
|
||||
el.off(['keydown', 'keyup', 'paste', 'drop', 'blur', 'focusout', ''].join('.mask '));
|
||||
},
|
||||
val: function(v) {
|
||||
var isInput = el.is('input'),
|
||||
method = isInput ? 'val' : 'text',
|
||||
r;
|
||||
|
||||
if (arguments.length > 0) {
|
||||
if (el[method]() !== v) {
|
||||
el[method](v);
|
||||
}
|
||||
r = el;
|
||||
} else {
|
||||
r = el[method]();
|
||||
}
|
||||
|
||||
return r;
|
||||
},
|
||||
getMCharsBeforeCount: function(index, onCleanVal) {
|
||||
for (var count = 0, i = 0, maskL = mask.length; i < maskL && i < index; i++) {
|
||||
if (!jMask.translation[mask.charAt(i)]) {
|
||||
index = onCleanVal ? index + 1 : index;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
},
|
||||
caretPos: function (originalCaretPos, oldLength, newLength, maskDif) {
|
||||
var translation = jMask.translation[mask.charAt(Math.min(originalCaretPos - 1, mask.length - 1))];
|
||||
|
||||
return !translation ? p.caretPos(originalCaretPos + 1, oldLength, newLength, maskDif)
|
||||
: Math.min(originalCaretPos + newLength - oldLength - maskDif, newLength);
|
||||
},
|
||||
behaviour: function(e) {
|
||||
e = e || window.event;
|
||||
p.invalid = [];
|
||||
var keyCode = e.keyCode || e.which;
|
||||
if ($.inArray(keyCode, jMask.byPassKeys) === -1) {
|
||||
|
||||
var caretPos = p.getCaret(),
|
||||
currVal = p.val(),
|
||||
currValL = currVal.length,
|
||||
changeCaret = caretPos < currValL,
|
||||
newVal = p.getMasked(),
|
||||
newValL = newVal.length,
|
||||
maskDif = p.getMCharsBeforeCount(newValL - 1) - p.getMCharsBeforeCount(currValL - 1);
|
||||
|
||||
p.val(newVal);
|
||||
|
||||
// change caret but avoid CTRL+A
|
||||
if (changeCaret && !(keyCode === 65 && e.ctrlKey)) {
|
||||
// Avoid adjusting caret on backspace or delete
|
||||
if (!(keyCode === 8 || keyCode === 46)) {
|
||||
caretPos = p.caretPos(caretPos, currValL, newValL, maskDif);
|
||||
}
|
||||
p.setCaret(caretPos);
|
||||
}
|
||||
|
||||
return p.callbacks(e);
|
||||
}
|
||||
},
|
||||
getMasked: function (skipMaskChars) {
|
||||
var buf = [],
|
||||
value = p.val(),
|
||||
m = 0, maskLen = mask.length,
|
||||
v = 0, valLen = value.length,
|
||||
offset = 1, addMethod = "push",
|
||||
resetPos = -1,
|
||||
lastMaskChar,
|
||||
check;
|
||||
|
||||
if (options.reverse) {
|
||||
addMethod = "unshift";
|
||||
offset = -1;
|
||||
lastMaskChar = 0;
|
||||
m = maskLen - 1;
|
||||
v = valLen - 1;
|
||||
check = function () {
|
||||
return m > -1 && v > -1;
|
||||
};
|
||||
} else {
|
||||
lastMaskChar = maskLen - 1;
|
||||
check = function () {
|
||||
return m < maskLen && v < valLen;
|
||||
};
|
||||
}
|
||||
|
||||
while (check()) {
|
||||
var maskDigit = mask.charAt(m),
|
||||
valDigit = value.charAt(v),
|
||||
translation = jMask.translation[maskDigit];
|
||||
|
||||
if (translation) {
|
||||
if (valDigit.match(translation.pattern)) {
|
||||
buf[addMethod](valDigit);
|
||||
if (translation.recursive) {
|
||||
if (resetPos === -1) {
|
||||
resetPos = m;
|
||||
} else if (m === lastMaskChar) {
|
||||
m = resetPos - offset;
|
||||
}
|
||||
|
||||
if (lastMaskChar === resetPos) {
|
||||
m -= offset;
|
||||
}
|
||||
}
|
||||
m += offset;
|
||||
} else if (translation.optional) {
|
||||
m += offset;
|
||||
v -= offset;
|
||||
} else if (translation.fallback) {
|
||||
buf[addMethod](translation.fallback);
|
||||
m += offset;
|
||||
v -= offset;
|
||||
} else {
|
||||
p.invalid.push({p: v, v: valDigit, e: translation.pattern});
|
||||
}
|
||||
v += offset;
|
||||
} else {
|
||||
if (!skipMaskChars) {
|
||||
buf[addMethod](maskDigit);
|
||||
}
|
||||
|
||||
if (valDigit === maskDigit) {
|
||||
v += offset;
|
||||
}
|
||||
|
||||
m += offset;
|
||||
}
|
||||
}
|
||||
|
||||
var lastMaskCharDigit = mask.charAt(lastMaskChar);
|
||||
if (maskLen === valLen + 1 && !jMask.translation[lastMaskCharDigit]) {
|
||||
buf.push(lastMaskCharDigit);
|
||||
}
|
||||
|
||||
return buf.join("");
|
||||
},
|
||||
callbacks: function (e) {
|
||||
var val = p.val(),
|
||||
changed = val !== old_value,
|
||||
defaultArgs = [val, e, el, options],
|
||||
callback = function(name, criteria, args) {
|
||||
if (typeof options[name] === "function" && criteria) {
|
||||
options[name].apply(this, args);
|
||||
}
|
||||
};
|
||||
|
||||
callback('onChange', changed === true, defaultArgs);
|
||||
callback('onKeyPress', changed === true, defaultArgs);
|
||||
callback('onComplete', val.length === mask.length, defaultArgs);
|
||||
callback('onInvalid', p.invalid.length > 0, [val, e, el, p.invalid, options]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// public methods
|
||||
jMask.mask = mask;
|
||||
jMask.options = options;
|
||||
jMask.remove = function() {
|
||||
var caret = p.getCaret();
|
||||
p.destroyEvents();
|
||||
p.val(jMask.getCleanVal());
|
||||
p.setCaret(caret - p.getMCharsBeforeCount(caret));
|
||||
return el;
|
||||
};
|
||||
|
||||
// get value without mask
|
||||
jMask.getCleanVal = function() {
|
||||
return p.getMasked(true);
|
||||
};
|
||||
|
||||
jMask.init = function(only_mask) {
|
||||
only_mask = only_mask || false;
|
||||
options = options || {};
|
||||
|
||||
jMask.byPassKeys = $.jMaskGlobals.byPassKeys;
|
||||
jMask.translation = $.jMaskGlobals.translation;
|
||||
|
||||
jMask.translation = $.extend({}, jMask.translation, options.translation);
|
||||
jMask = $.extend(true, {}, jMask, options);
|
||||
|
||||
regexMask = p.getRegexMask();
|
||||
|
||||
if (only_mask === false) {
|
||||
|
||||
if (options.placeholder) {
|
||||
el.attr('placeholder' , options.placeholder);
|
||||
}
|
||||
|
||||
// autocomplete needs to be off. we can't intercept events
|
||||
// the browser doesn't fire any kind of event when something is
|
||||
// selected in a autocomplete list so we can't sanitize it.
|
||||
el.attr('autocomplete', 'off');
|
||||
p.destroyEvents();
|
||||
p.events();
|
||||
|
||||
var caret = p.getCaret();
|
||||
p.val(p.getMasked());
|
||||
p.setCaret(caret + p.getMCharsBeforeCount(caret, true));
|
||||
|
||||
} else {
|
||||
p.events();
|
||||
p.val(p.getMasked());
|
||||
}
|
||||
};
|
||||
|
||||
jMask.init(!el.is("input"));
|
||||
};
|
||||
|
||||
$.maskWatchers = {};
|
||||
var HTMLAttributes = function () {
|
||||
var input = $(this),
|
||||
options = {},
|
||||
prefix = "data-mask-",
|
||||
mask = input.attr('data-mask');
|
||||
|
||||
if (input.attr(prefix + 'reverse')) {
|
||||
options.reverse = true;
|
||||
}
|
||||
|
||||
if (input.attr(prefix + 'clearifnotmatch')) {
|
||||
options.clearIfNotMatch = true;
|
||||
}
|
||||
|
||||
if (input.attr(prefix + 'selectonfocus') === 'true') {
|
||||
options.selectOnFocus = true;
|
||||
}
|
||||
|
||||
if (notSameMaskObject(input, mask, options)) {
|
||||
return input.data('mask', new Mask(this, mask, options));
|
||||
}
|
||||
},
|
||||
notSameMaskObject = function(field, mask, options) {
|
||||
options = options || {};
|
||||
var maskObject = $(field).data('mask'),
|
||||
stringify = JSON.stringify,
|
||||
value = $(field).val() || $(field).text();
|
||||
try {
|
||||
if (typeof mask === "function") {
|
||||
mask = mask(value);
|
||||
}
|
||||
return typeof maskObject !== "object" || stringify(maskObject.options) !== stringify(options) || maskObject.mask !== mask;
|
||||
} catch (e) {}
|
||||
};
|
||||
|
||||
|
||||
$.fn.mask = function(mask, options) {
|
||||
options = options || {};
|
||||
var selector = this.selector,
|
||||
globals = $.jMaskGlobals,
|
||||
interval = $.jMaskGlobals.watchInterval,
|
||||
maskFunction = function() {
|
||||
if (notSameMaskObject(this, mask, options)) {
|
||||
return $(this).data('mask', new Mask(this, mask, options));
|
||||
}
|
||||
};
|
||||
|
||||
$(this).each(maskFunction);
|
||||
|
||||
if (selector && selector !== "" && globals.watchInputs) {
|
||||
clearInterval($.maskWatchers[selector]);
|
||||
$.maskWatchers[selector] = setInterval(function(){
|
||||
$(document).find(selector).each(maskFunction);
|
||||
}, interval);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
$.fn.unmask = function() {
|
||||
clearInterval($.maskWatchers[this.selector]);
|
||||
delete $.maskWatchers[this.selector];
|
||||
return this.each(function() {
|
||||
var dataMask = $(this).data('mask');
|
||||
if (dataMask) {
|
||||
dataMask.remove().removeData('mask');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.cleanVal = function() {
|
||||
return this.data('mask').getCleanVal();
|
||||
};
|
||||
|
||||
$.applyDataMask = function() {
|
||||
$(document).find($.jMaskGlobals.maskElements).filter(globals.dataMaskAttr).each(HTMLAttributes);
|
||||
}
|
||||
|
||||
var globals = {
|
||||
maskElements: 'input,td,span,div',
|
||||
dataMaskAttr: '*[data-mask]',
|
||||
dataMask: true,
|
||||
watchInterval: 300,
|
||||
watchInputs: true,
|
||||
watchDataMask: false,
|
||||
byPassKeys: [9, 16, 17, 18, 36, 37, 38, 39, 40, 91],
|
||||
translation: {
|
||||
'0': {pattern: /\d/},
|
||||
'9': {pattern: /\d/, optional: true},
|
||||
'#': {pattern: /\d/, recursive: true},
|
||||
'A': {pattern: /[a-zA-Z0-9]/},
|
||||
'S': {pattern: /[a-zA-Z]/}
|
||||
}
|
||||
};
|
||||
|
||||
$.jMaskGlobals = $.jMaskGlobals || {};
|
||||
globals = $.jMaskGlobals = $.extend(true, {}, globals, $.jMaskGlobals);
|
||||
|
||||
// looking for inputs with data-mask attribute
|
||||
if (globals.dataMask) { $.applyDataMask(); }
|
||||
|
||||
setInterval(function(){
|
||||
if ($.jMaskGlobals.watchDataMask) { $.applyDataMask(); }
|
||||
}, globals.watchInterval);
|
||||
}));
|
1
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/.bin/0ungit-credentials-helper
generated
vendored
Symbolic link
1
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/.bin/0ungit-credentials-helper
generated
vendored
Symbolic link
|
@ -0,0 +1 @@
|
|||
../ungit/bin/credentials-helper
|
1
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/.bin/ungit
generated
vendored
Symbolic link
1
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/.bin/ungit
generated
vendored
Symbolic link
|
@ -0,0 +1 @@
|
|||
../ungit/bin/ungit
|
3
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/.gitattributes
generated
vendored
Normal file
3
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/.gitattributes
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
* text=auto
|
||||
/bin/credentials-helper eol=lf
|
||||
/bin/ungit eol=lf
|
3
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/.nodemonignore
generated
vendored
Normal file
3
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/.nodemonignore
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
/public/*
|
||||
.git/*
|
||||
.git
|
40
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/.npmignore
generated
vendored
Normal file
40
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/.npmignore
generated
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
lib-cov
|
||||
*.seed
|
||||
*.log
|
||||
*.csv
|
||||
*.dat
|
||||
*.out
|
||||
*.pid
|
||||
*.gz
|
||||
|
||||
pids
|
||||
logs
|
||||
results
|
||||
|
||||
npm-debug.log
|
||||
|
||||
node_modules/
|
||||
|
||||
.ungitrc
|
||||
.travis.yml
|
||||
Gruntfile.js
|
||||
|
||||
assets/
|
||||
test/
|
||||
report/
|
||||
public/source/
|
||||
public/vendor/css/
|
||||
public/vendor/js/
|
||||
public/templates/
|
||||
public/devStyling.html
|
||||
public/js/devStyling.js
|
||||
|
||||
clicktests/
|
||||
clicktestout/
|
||||
|
||||
teststabilitytester.js
|
||||
|
||||
build/
|
||||
*.dll
|
||||
nw.exe
|
||||
nw.pak
|
52
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/CHANGELOG.md
generated
vendored
Normal file
52
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/CHANGELOG.md
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
# Change Log
|
||||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](http://semver.org/) and
|
||||
[Keep a changlelog's changelog standard](http://keepachangelog.com/)
|
||||
|
||||
## [Unreleased](https://github.com/FredrikNoren/ungit/compare/v0.10.3...master)
|
||||
|
||||
## [0.10.3](https://github.com/FredrikNoren/ungit/compare/v0.10.2...v0.10.3)
|
||||
|
||||
### Fixed
|
||||
- Missing npm as a normal dependency [#766] (https://github.com/FredrikNoren/ungit/issues/766)
|
||||
|
||||
## [0.10.2](https://github.com/FredrikNoren/ungit/compare/v0.10.1...v0.10.2)
|
||||
|
||||
### Added
|
||||
- Added bare repo support [#177](https://github.com/FredrikNoren/ungit/issues/177) [#728](https://github.com/FredrikNoren/ungit/issues/728)
|
||||
- Added support for cherry-pick conflict[#701](https://github.com/FredrikNoren/ungit/issues/701)
|
||||
- Added wordwrap support for diffs [#721](https://github.com/FredrikNoren/ungit/issues/721)
|
||||
- Support for Node6 [#745](https://github.com/FredrikNoren/ungit/pull/745/files)
|
||||
- Added "autoCheckoutOnBranchCreate" option [#752](https://github.com/FredrikNoren/ungit/pull/752/files)
|
||||
|
||||
### Fixed
|
||||
- Fix maxConcurrentGitOperations not limiting git processes [#707](https://github.com/FredrikNoren/ungit/issues/707)
|
||||
- Fix ".lock" file conflicts in parallelized git operations [#515](https://github.com/FredrikNoren/ungit/issues/515)
|
||||
- Allow Ungit to function under sub dir of a git dir [#734](https://github.com/FredrikNoren/ungit/issues/734)
|
||||
- Removed deprecated npmconf package [#746](https://github.com/FredrikNoren/ungit/issues/746)
|
||||
- More helpful warning messages [#749](https://github.com/FredrikNoren/ungit/pull/749/files)
|
||||
- Deleting already deleted remote tag [#748](https://github.com/FredrikNoren/ungit/pull/748)
|
||||
- Fix to handle revert merge commit [#757](https://github.com/FredrikNoren/ungit/pull/757)
|
||||
|
||||
### Changed
|
||||
- Cleaner rebase conflict message display [#708](https://github.com/FredrikNoren/ungit/pull/708)
|
||||
- ES6 [#672](https://github.com/FredrikNoren/ungit/pull/672)
|
||||
- Dropped support for Node 0.10 and 0.12 [#745](https://github.com/FredrikNoren/ungit/pull/745/files)
|
||||
|
||||
## [0.10.1](https://github.com/FredrikNoren/ungit/compare/v0.10.0...v0.10.1)
|
||||
|
||||
### Added
|
||||
- Introduced change log! [#687](https://github.com/FredrikNoren/ungit/issues/687)
|
||||
- Improved server and client error logging [#695](https://github.com/FredrikNoren/ungit/pull/695)
|
||||
|
||||
### Fixed
|
||||
- Fix crashes due to submodule parsing [#690](https://github.com/FredrikNoren/ungit/issues/690) [#689](https://github.com/FredrikNoren/ungit/issues/689)
|
||||
- Fix duplicate remote tag issues [#685](https://github.com/FredrikNoren/ungit/issues/685)
|
||||
- Fix scrolling issue in safari [#686](https://github.com/FredrikNoren/ungit/issues/686)
|
||||
- Fix git hooks failing on non-ascii files [#676](https://github.com/FredrikNoren/ungit/issues/676)
|
||||
|
||||
### Removed
|
||||
- Reverted on hover button effects [#688](https://github.com/FredrikNoren/ungit/issues/688)
|
||||
|
||||
### Changed
|
||||
- Upgrade keen.io client code [#679](https://github.com/FredrikNoren/ungit/issues/679)
|
88
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/CONTRIBUTING.md
generated
vendored
Normal file
88
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/CONTRIBUTING.md
generated
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
These are the contributing guidelines as well as some documentation on how the code is structured. Read up before contributing to make everything as smooth as possible.
|
||||
|
||||
Posting issues
|
||||
==============
|
||||
|
||||
Just common sense; do a quick search before posting, someone might already have created an issue (or resolved the problem!). If you're posting a bug; try to include as much relevant information as possible (ungit version, node and npm version, os, any git errors displayed, output from cli console and output from the browser console).
|
||||
|
||||
Pull requests
|
||||
=============
|
||||
Make sure to include a note in CHANGELOG.md about the change as part of the PR.
|
||||
We follow the ["Keep a changelog"](http://keepachangelog.com/) style guide.
|
||||
Make sure to include reference's to issues and PR's when relevant in the change log.
|
||||
|
||||
Writing plugins
|
||||
===============
|
||||
See [PLUGINS.md](PLUGINS.md)
|
||||
|
||||
Developing for Ungit proper
|
||||
===========================
|
||||
|
||||
I do accept pull requests, but I also reserve the right to not do so for things I don't think fit with Ungit. If you are developing anything new you should almost always also provide tests for it, preferably clicktests but it doesn't hurt to write REST-interface tests as well if applicable. Try to post pull requests early, even at a concept stage, to get feedback and increase chances it's merged.
|
||||
|
||||
What you need to get started
|
||||
----------------------------
|
||||
|
||||
You'll need the same as for Ungit; node, npm and git. You will also need grunt (`npm install -g grunt-cli`).
|
||||
|
||||
Getting started
|
||||
---------------
|
||||
|
||||
To get started developing on Ungit:
|
||||
|
||||
1. Make sure you have [node.js](http://nodejs.org), [npm](https://npmjs.org/), [git](http://git-scm.com/) and [grunt](http://gruntjs.com/) installed.
|
||||
2. Clone the repository to a local directory.
|
||||
3. Run `npm install` to install dependencies.
|
||||
4. Run `grunt` to build (compile templates, css and js).
|
||||
5. Type `npm start` to start ungit, or `npm test` to run tests.
|
||||
6. (Optional). Run `grunt watch` to automatically rebuild stuff when you change files.
|
||||
|
||||
Run ungit as standalone application
|
||||
-----------------------------------
|
||||
|
||||
To provide easier access to launch ungit, very early stage of standalone application container using [electron](http://electron.atom.io/) is available.
|
||||
Please note this is not yet ready for public release and being developed having several known & unknown limitations.
|
||||
|
||||
To get started:
|
||||
1. Follow steps in 'Getting started' to get a development environment ready.
|
||||
2. Run `grunt default && grunt package`. This will compile latest ungit and will create a standalone application package under `build/`
|
||||
|
||||
Known limitation:
|
||||
1. Current standalone application does not allow to execute more than one instance.
|
||||
2. There is no installer package neither automatic update mechanism for standalone application in place yet.
|
||||
|
||||
Additional notes:
|
||||
1. To create windows package with proper application description on non-windows platform, [wine](https://www.winehq.org/) is required to be installed. If not, windows package will be created with default resources.
|
||||
|
||||
Architecture overview
|
||||
---------------------
|
||||
|
||||
Ungit has two major parts; the server and the ui. The server exposes a REST interfaces, which enables it to be run on a remote server. The UI is a single-page web-app, built using Knockout.js.
|
||||
|
||||
Folders
|
||||
-------
|
||||
|
||||
* `assets/` Raw assets used for development.
|
||||
* `bin/` "Binary" files, the ungit launcher script and the credentials-helper, which is invoked by git to acquire credentials when using http authentication.
|
||||
* `clicktests/` Phantom.js clicktest; basically tests that run on the rendered DOM. Since these run all the way, from the DOM down to the server, they're also the most powerful of the tests.
|
||||
* `components/` This directory contains all view components for Ungit, each of them exposed as an Ungit plugin.
|
||||
* `public/` The UI web-app.
|
||||
* `public/css/` CSS generated by the grunt script.
|
||||
* `public/fonts/` & `public/images` Assets, some of which are compiled into the CSS by the grunt script, others (for instance those that are too large to compile into the CSS efficiently) are served directly.
|
||||
* `public/js/` An ungit.js file generated by the grunt script, as well as raven files which handle exception logging.
|
||||
* `public/less/` Less files, which are the "source" used to generate the CSS.
|
||||
* `public/source/` Javascript source code, which is turned into the public/js/ungit.js file by the grunt script.
|
||||
* `public/vendor/` Various 3rd-party libs.
|
||||
* `source/` Server and shared (i.e. used by both server and UI) source code.
|
||||
* `test/` Unit tests and REST interface tests.
|
||||
|
||||
Running tests
|
||||
-------------
|
||||
|
||||
`grunt test` will run both unit tests, REST-interface tests, and clicktests. `grunt unittest` only runs the tests in the test/ folder, `grunt clicktest` runs only the tests in the clicktests/ folder. Install mocha (`npm install -g mocha`) to run specific tests in the test folder and get better stack traces: `mocha test/spec.git-api.js`.
|
||||
|
||||
Things to consider when developing
|
||||
----------------------------------
|
||||
|
||||
* Try to make everything as touch friendly as possible, for instance no mouse over tooltips (try to make it clear without that). Everything doesn't adhere 100% to that right now but I'm trying to move it more in that direction.
|
||||
* Write tests. The most important tests to write are usually the clicktests since they will cover the most code (both ui and backend).
|
76
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/PLUGINS.md
generated
vendored
Normal file
76
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/PLUGINS.md
generated
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
Writing Ungit plugins
|
||||
=====================
|
||||
|
||||
It's super easy to write an Ungit plugin. Here's how to write a completely new (though super simple) git log ui:
|
||||
|
||||
### 1. Create a new folder for your plugin.
|
||||
Create a folder at `~/.ungit/plugins/MY_FANCY_PLUGIN`, then add a file called `ungit-plugin.json` with the following content:
|
||||
```JSON
|
||||
{
|
||||
"exports": {
|
||||
"javascript": "example.js"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Add some code
|
||||
Create an `example.js` file and add this:
|
||||
|
||||
```JavaScript
|
||||
var components = require('ungit-components');
|
||||
|
||||
// We're overriding the graph component here
|
||||
components.register('graph', function(args) {
|
||||
return {
|
||||
// This method creates and returns the DOM node that represents this component.
|
||||
updateNode: function() {
|
||||
var node = document.createElement('div');
|
||||
// Request all log entries from the backend
|
||||
args.server.get('/log', { path: args.repoPath, limit: 50 }, function(err, log) {
|
||||
// Add all log entries to the parent node
|
||||
log.forEach(function(entry) {
|
||||
var entryNode = document.createElement('div');
|
||||
entryNode.innerHTML = entry.message;
|
||||
node.appendChild(entryNode);
|
||||
});
|
||||
});
|
||||
return node;
|
||||
}
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
### 3. Done!
|
||||
Just restart Ungit, or if you have `"dev": true` in your `.ungitrc` you can just refresh your browser. A [gerrit plugin example](https://github.com/FredrikNoren/ungit-gerrit) can be found here.
|
||||
|
||||
### Ungit Plugin API version
|
||||
The Ungit Plugin API follows semver, and the current version can be found in the package.json (ungitPluginApiVersion). On the frontend it can be accessed from `ungit.pluginApiVersion` and on the backend `env.pluginApiVersion`.
|
||||
|
||||
### Components
|
||||
|
||||
Each functionalities within ungit is built as components. Each components is an ungit plugin that is checked into main repository. All the components in Ungit is built as plugins, take a look in the [components](https://github.com/FredrikNoren/ungit/tree/master/components) directory for inspiration.
|
||||
|
||||
An [example](https://github.com/FredrikNoren/ungit/tree/master/components/staging) of ungit component with view can be seen below.
|
||||
|
||||
```JSON
|
||||
{
|
||||
"exports": {
|
||||
"knockoutTemplates": {
|
||||
"staging": "staging.html"
|
||||
},
|
||||
"javascript": "staging.bundle.js",
|
||||
"css": "staging.css"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* Views(html) for Component
|
||||
|
||||
Each component can have multiple views as exampled [here](https://github.com/FredrikNoren/ungit/tree/master/components/dialogs).
|
||||
|
||||
* CSS for Component
|
||||
css file can be easily defined per components and in above example we can see that `staging.less` file is compiled into `staging.css` via grunt job. If you are using less file please modify [Gruntfile.js](https://github.com/FredrikNoren/ungit/blob/master/Gruntfile.js) file to include new less file.
|
||||
|
||||
* JS for Component
|
||||
|
||||
Each component gets to have one javascipt files. However each javasciprt file can require other javascript in it's directory or other libraries. If you are doing require by relative pass as exampled in [graph.js](https://github.com/FredrikNoren/ungit/blob/master/components/graph/graph.js), you wouldn't have to include the js in browserify job in [Gruntfile.js](https://github.com/FredrikNoren/ungit/blob/master/Gruntfile.js).
|
103
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/README.md
generated
vendored
Normal file
103
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/README.md
generated
vendored
Normal file
|
@ -0,0 +1,103 @@
|
|||
ungit
|
||||
======
|
||||
[![NPM version](https://badge.fury.io/js/ungit.svg)](http://badge.fury.io/js/ungit)
|
||||
[![Build Status](https://travis-ci.org/FredrikNoren/ungit.svg)](https://travis-ci.org/FredrikNoren/ungit)
|
||||
[![Join the chat at https://gitter.im/FredrikNoren/ungit](https://badges.gitter.im/FredrikNoren/ungit.svg)](https://gitter.im/FredrikNoren/ungit?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
The easiest way to use git. On any platform. Anywhere.
|
||||
|
||||
[![xkcd](xkcd.png)](https://xkcd.com/1597/)
|
||||
|
||||
Git is known for being a versatile distributed source control system that is a staple of many individuals, communities, and even for [the City of Chattanooga to crowd source bicycle parking locations](https://github.com/cityofchattanooga/Bicycle-Parking). However, it is not known for userfriendlyness or easy learning curve.
|
||||
|
||||
Ungit is to bring user friendliness to git without sacrificing versatility of git.
|
||||
|
||||
* Clean and intuitive UI that makes it easy to _understand_ git.
|
||||
* Runs on any platform that node.js & git supports.
|
||||
* Web-based, meaning you can run it on your cloud/pure shell machine and use the ui from your browser (just browse to http://your-cloud-machine.com:8448).
|
||||
* Works well with GitHub.
|
||||
* [Gerrit](https://code.google.com/p/gerrit/) integration through plugin: https://github.com/FredrikNoren/ungit-gerrit
|
||||
|
||||
[Follow @ungitui on twitter](https://twitter.com/ungitui)
|
||||
|
||||
Quick intro to ungit: [http://youtu.be/hkBVAi3oKvo](http://youtu.be/hkBVAi3oKvo)
|
||||
|
||||
[![Screenshot](screenshot.png)](http://youtu.be/hkBVAi3oKvo)
|
||||
|
||||
Installing
|
||||
----------
|
||||
Requires [node.js](http://nodejs.org) (≥ 0.10), [npm](https://www.npmjs.com/) (≥ 1.3.1, comes with node.js) and [git](http://git-scm.com/) (≥ 1.8.x). To install ungit just type:
|
||||
|
||||
npm install -g ungit
|
||||
|
||||
NOTE: If your system requires root access to install global npm packages, make sure you use the -H flag:
|
||||
|
||||
sudo -H npm install -g ungit
|
||||
|
||||
Using
|
||||
-----
|
||||
Anywhere you want to start, just type:
|
||||
|
||||
ungit
|
||||
|
||||
This will launch the server and open up a browser with the ui.
|
||||
|
||||
Configuring
|
||||
---------
|
||||
Put a configuration file called .ungitrc in your home directory (`/home/USERNAME` on *nix, `C:/Users/USERNAME/` on windows). Can be in either json or ini format. See [source/config.js](source/config.js) for available options.
|
||||
|
||||
You can also override configuration variables at launch by specifying them as command line arguments; `ungit --port=8080`. To disable boolean features use --no: `ungit --no-autoFetch`.
|
||||
|
||||
Example of `~/.ungitrc` configuration file to change default port and enable bugtracking:
|
||||
|
||||
```json
|
||||
{
|
||||
"port": 8080,
|
||||
"bugtracking": true
|
||||
}
|
||||
```
|
||||
|
||||
Ungit uses [rc](https://github.com/dominictarr/rc) for configuration, which in turn uses [yargs](https://github.com/yargs/yargs) for command line arguments. See corresponding documentations for more details.
|
||||
|
||||
Plugins
|
||||
-------
|
||||
Plugins are installed by simply placing them in the Ungit plugin directory (`~/.ungit/plugins` by default), and then restarting Ungit.
|
||||
|
||||
[List of available plugins](https://github.com/FredrikNoren/ungit/wiki/List-of-plugins)
|
||||
|
||||
There's a guide in the [PLUGINS.md](PLUGINS.md) file on how to write new plugins.
|
||||
|
||||
Developing
|
||||
----------
|
||||
|
||||
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
||||
|
||||
Maintainers
|
||||
-----------
|
||||
* [FredrikNoren](https://github.com/FredrikNoren)
|
||||
* [codingtwinky](https://github.com/codingtwinky)
|
||||
|
||||
Known issues
|
||||
------------
|
||||
|
||||
* If you're running MacOSX Mavericks and Ungit crashes after a few seconds; try updating npm and node. See [#259](https://github.com/FredrikNoren/ungit/issues/259) and [#249](https://github.com/FredrikNoren/ungit/issues/249) for details.
|
||||
* Ubuntu users may have trouble installing because the node executable is named differently on Ubuntu, see [#401](https://github.com/FredrikNoren/ungit/issues/401) for details.
|
||||
* Debian Wheezy's supported git and nodejs packages are too old, therefore download newest [git](https://github.com/git/git/releases) and [nodejs](https://nodejs.org/download/) tarballs and [build from source](http://www.control-escape.com/linux/lx-swinstall-tar.html).
|
||||
|
||||
Changelog
|
||||
---------
|
||||
See [CHANGELOG.md](CHANGELOG.md).
|
||||
|
||||
License (MIT)
|
||||
-------------
|
||||
|
||||
Copyright (C) 2013-2016 Fredrik Norén
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
[![Dependency Status](https://david-dm.org/FredrikNoren/ungit.png)](https://david-dm.org/FredrikNoren/ungit)
|
||||
[![devDependency Status](https://david-dm.org/FredrikNoren/ungit/dev-status.png)](https://david-dm.org/FredrikNoren/ungit#info=devDependencies)
|
18
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/appveyor.yml
generated
vendored
Normal file
18
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/appveyor.yml
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
environment:
|
||||
matrix:
|
||||
- nodejs_version: "6.0"
|
||||
|
||||
install:
|
||||
- ps: Install-Product node $env:nodejs_version
|
||||
- git config --global user.email "test@testy.com"
|
||||
- git config --global user.name "Test testy"
|
||||
- npm install
|
||||
- npm install -g grunt-cli
|
||||
|
||||
test_script:
|
||||
- node --version
|
||||
- npm --version
|
||||
- grunt
|
||||
- npm test
|
||||
|
||||
build: off
|
46
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/bin/credentials-helper
generated
vendored
Executable file
46
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/bin/credentials-helper
generated
vendored
Executable file
|
@ -0,0 +1,46 @@
|
|||
#!/usr/bin/env node
|
||||
var config = require('../src/config');
|
||||
var winston = require('winston');
|
||||
var path = require('path');
|
||||
var async = require('async');
|
||||
|
||||
winston.remove(winston.transports.Console);
|
||||
|
||||
var BugTracker = require('../src/bugtracker');
|
||||
var bugtracker = new BugTracker('credentials-helper');
|
||||
var usageStatistics = require('../src/usage-statistics');
|
||||
|
||||
process.on('uncaughtException', function(err) {
|
||||
console.error(err.stack.toString());
|
||||
async.parallel([
|
||||
bugtracker.notify.bind(bugtracker, err, 'credentials-helper'),
|
||||
usageStatistics.addEvent.bind(usageStatistics, 'credentials-helper-exception')
|
||||
], function() {
|
||||
process.exit();
|
||||
});
|
||||
});
|
||||
|
||||
if (config.logDirectory)
|
||||
winston.add(winston.transports.File, { filename: path.join(config.logDirectory, 'credentials-helper.log'), maxsize: 100*1024, maxFiles: 2 });
|
||||
|
||||
var socketId = process.argv[2];
|
||||
var port = process.argv[3];
|
||||
winston.info('Credentials helper invoked; port ' + port + ', socketId ' + socketId);
|
||||
|
||||
var http = require('http');
|
||||
|
||||
if (process.argv[4] == 'get') {
|
||||
winston.info('Getting credentials');
|
||||
http.get('http://localhost:' + port + '/api/credentials?socketId=' + socketId, function(res) {
|
||||
winston.info('Got credentials');
|
||||
res.on('data', function(body) {
|
||||
var data = JSON.parse(body);
|
||||
console.log('username=' + data.username);
|
||||
console.log('password=' + (data.password ? data.password : ''));
|
||||
});
|
||||
}).on('error', function(err) {
|
||||
winston.error('Error getting credentials, couldn\'t query server', err);
|
||||
});
|
||||
} else {
|
||||
winston.info('Unhandled param: ' + process.argv[4]);
|
||||
}
|
98
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/bin/ungit
generated
vendored
Executable file
98
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/bin/ungit
generated
vendored
Executable file
|
@ -0,0 +1,98 @@
|
|||
#!/usr/bin/env node
|
||||
var startLaunchTime = Date.now();
|
||||
var forever = require('forever-monitor');
|
||||
var config = require('../src/config');
|
||||
var open = require('open');
|
||||
var path = require('path');
|
||||
var child_process = require('child_process');
|
||||
var async = require('async');
|
||||
|
||||
var BugTracker = require('../src/bugtracker');
|
||||
var bugtracker = new BugTracker('launcher');
|
||||
var usageStatistics = require('../src/usage-statistics');
|
||||
|
||||
process.on('uncaughtException', function(err) {
|
||||
console.error(err.stack.toString());
|
||||
async.parallel([
|
||||
bugtracker.notify.bind(bugtracker, err, 'ungit-launcher'),
|
||||
usageStatistics.addEvent.bind(usageStatistics, 'launcher-exception')
|
||||
], function() {
|
||||
process.exit();
|
||||
});
|
||||
});
|
||||
|
||||
var child = new (forever.Monitor)(path.join(__dirname, '..', 'src', 'server.js'), {
|
||||
silent: false,
|
||||
minUptime: 2000,
|
||||
max: config.maxNAutoRestartOnCrash,
|
||||
cwd: path.join(process.cwd(), '..'),
|
||||
options: process.argv.slice(2),
|
||||
env: { LANG: 'en_US.UTF-8' }
|
||||
});
|
||||
|
||||
child.on('exit', function (res) {
|
||||
console.log('Stopped keeping ungit alive');
|
||||
});
|
||||
|
||||
function launch(callback) {
|
||||
var currentUrl = config.urlBase + ':' + config.port + config.rootPath;
|
||||
if (config.forcedLaunchPath === undefined) currentUrl += '/#/repository?path=' + encodeURIComponent(process.cwd());
|
||||
else if (config.forcedLaunchPath !== null && config.forcedLaunchPath !== '') currentUrl += '/#/repository?path=' + encodeURIComponent(config.forcedLaunchPath);
|
||||
console.log('Browse to ' + currentUrl);
|
||||
if (config.launchBrowser && !config.launchCommand) {
|
||||
open(currentUrl);
|
||||
} else if (config.launchCommand) {
|
||||
var command = config.launchCommand.replace(/%U/g, currentUrl);
|
||||
console.log('Running custom launch command: ' + command);
|
||||
child_process.exec(command, function(err, stdout, stderr) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
if (config.launchBrowser)
|
||||
open(currentUrl);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function startupListener(data) {
|
||||
if (data.toString().indexOf('## Ungit started ##') >= 0) {
|
||||
launch(function(err) {
|
||||
if (err) console.log(err);
|
||||
});
|
||||
child.removeListener('stdout', startupListener);
|
||||
var launchTime = (Date.now() - startLaunchTime);
|
||||
console.log('Took ' + launchTime + 'ms to start server.');
|
||||
usageStatistics.addEvent('server-start', { launchTimeMs: launchTime });
|
||||
}
|
||||
}
|
||||
|
||||
child.on('stdout', startupListener);
|
||||
|
||||
function checkIfUngitIsRunning(callback) {
|
||||
// Fastest way to find out if a port is used or not/i.e. if ungit is running
|
||||
var net = require('net');
|
||||
var server = net.createServer(function(c) { });
|
||||
server.listen(config.port, function(err) {
|
||||
server.close(function() {
|
||||
callback(null, false);
|
||||
});
|
||||
});
|
||||
server.on('error', function (e) {
|
||||
if (e.code == 'EADDRINUSE') {
|
||||
callback(null, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
checkIfUngitIsRunning(function(err1, ungitRunning) {
|
||||
if (ungitRunning) {
|
||||
console.log('Ungit server already running');
|
||||
launch(function(err) {
|
||||
if (err) console.log(err);
|
||||
});
|
||||
}
|
||||
else {
|
||||
child.start();
|
||||
}
|
||||
});
|
170
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/app/app.bundle.js
generated
vendored
Normal file
170
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/app/app.bundle.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
4
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/app/app.css
generated
vendored
Normal file
4
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/app/app.css
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
|
||||
.app-wrapper {
|
||||
padding-top: 21px;
|
||||
}
|
61
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/app/app.html
generated
vendored
Normal file
61
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/app/app.html
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
|
||||
<!-- ko component: header --><!-- /ko -->
|
||||
<div class="app-top-margin"></div>
|
||||
<div class="app-wrapper">
|
||||
|
||||
<div class="container" data-bind="shown: shown" data-ta-container="app">
|
||||
<div class="alert alert-danger" data-bind="visible: gitVersionErrorVisible">
|
||||
<span data-bind="text: gitVersionError"></span>
|
||||
<button type="button" class="close" data-bind="click: dismissGitVersionError">×</button>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info" data-bind="visible: newVersionAvailable">
|
||||
A new version of ungit (<span data-bind="text: latestVersion"></span>) is <a href="https://github.com/FredrikNoren/ungit">available</a>! Run <code data-bind="text: newVersionInstallCommand"></code> to install. (You are currently running version <span data-bind="text: currentVersion"></span>.)
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info clearfix" data-bind="visible: showBugtrackingNagscreen">
|
||||
<button type="button" class="close" data-bind="click: dismissBugtrackingNagscreen">×</button>
|
||||
<p><strong>Help make ungit better with the press of a button!</strong></p>
|
||||
|
||||
<button class="btn btn-primary" data-bind="click: enableBugtrackingAndStatistics">Enable automatic bug reports + anonymous usage statistics</button>
|
||||
<button class="btn btn-primary" data-bind="click: enableBugtracking">Enable automatic bug reports</button>
|
||||
<button class="btn btn-default" data-bind="click: dismissBugtrackingNagscreen">Naah, I'll skip that</button>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info clearfix" data-bind="visible: showNPSSurvey">
|
||||
<button type="button" class="close" data-bind="click: dismissNPSSurvey">×</button>
|
||||
<span class="text-dimmed">Hi! This is a one-question survey to learn more about how people use Ungit. You can dismiss it by clicking the x in the upper right corner.</span>
|
||||
<p><h4>Question: How likely are you to recommend Ungit to your friends and colleagues?</h4></p>
|
||||
<p>
|
||||
<div class="btn-group btn-group-justified">
|
||||
<a class="btn btn-default" role="button" data-bind="click: sendNPS.bind(null, 0)">0</a>
|
||||
<a class="btn btn-default" role="button" data-bind="click: sendNPS.bind(null, 1)">1</a>
|
||||
<a class="btn btn-default" role="button" data-bind="click: sendNPS.bind(null, 2)">2</a>
|
||||
<a class="btn btn-default" role="button" data-bind="click: sendNPS.bind(null, 3)">3</a>
|
||||
<a class="btn btn-default" role="button" data-bind="click: sendNPS.bind(null, 4)">4</a>
|
||||
<a class="btn btn-default" role="button" data-bind="click: sendNPS.bind(null, 5)">5</a>
|
||||
<a class="btn btn-default" role="button" data-bind="click: sendNPS.bind(null, 6)">6</a>
|
||||
<a class="btn btn-default" role="button" data-bind="click: sendNPS.bind(null, 7)">7</a>
|
||||
<a class="btn btn-default" role="button" data-bind="click: sendNPS.bind(null, 8)">8</a>
|
||||
<a class="btn btn-default" role="button" data-bind="click: sendNPS.bind(null, 9)">9</a>
|
||||
<a class="btn btn-default" role="button" data-bind="click: sendNPS.bind(null, 10)">10</a>
|
||||
</div>
|
||||
<div class="clearfix">
|
||||
Not at all likely
|
||||
<div class="pull-right">Extremely likely</div>
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ko if: content -->
|
||||
<div class="container container-wide" data-bind="component: content"></div>
|
||||
<!-- /ko -->
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ko if: dialog -->
|
||||
<!-- ko template: { name: templateChooser, data: dialog } --><!-- /ko -->
|
||||
<!-- /ko -->
|
166
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/app/app.js
generated
vendored
Normal file
166
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/app/app.js
generated
vendored
Normal file
|
@ -0,0 +1,166 @@
|
|||
|
||||
var ko = require('knockout');
|
||||
var components = require('ungit-components');
|
||||
var programEvents = require('ungit-program-events');
|
||||
var navigation = require('ungit-navigation');
|
||||
|
||||
components.register('app', function(args) {
|
||||
return new AppViewModel(args.appContainer, args.server);
|
||||
});
|
||||
|
||||
var AppViewModel = function(appContainer, server) {
|
||||
var self = this;
|
||||
this.appContainer = appContainer;
|
||||
this.server = server;
|
||||
if (window.location.search.indexOf('noheader=true') < 0)
|
||||
this.header = components.create('header', { app: this });
|
||||
this.dialog = ko.observable(null);
|
||||
|
||||
this.repoList = ko.observableArray(JSON.parse(localStorage.getItem('repositories') || localStorage.getItem('visitedRepositories') || '[]')); // visitedRepositories is legacy, remove in the next version
|
||||
this.repoList.subscribe(function(newValue) { localStorage.setItem('repositories', JSON.stringify(newValue)); });
|
||||
|
||||
this.content = ko.observable(components.create('home', { app: this }));
|
||||
this.currentVersion = ko.observable();
|
||||
this.latestVersion = ko.observable();
|
||||
this.newVersionAvailable = ko.observable();
|
||||
this.newVersionInstallCommand = (ungit.platform == 'win32' ? '' : 'sudo -H ') + 'npm update -g ungit';
|
||||
this.bugtrackingEnabled = ko.observable(ungit.config.bugtracking);
|
||||
|
||||
this.bugtrackingNagscreenDismissed = ko.observable(localStorage.getItem('bugtrackingNagscreenDismissed'));
|
||||
this.showBugtrackingNagscreen = ko.computed(function() {
|
||||
return !self.bugtrackingEnabled() && !self.bugtrackingNagscreenDismissed();
|
||||
});
|
||||
|
||||
this.gitVersionErrorDismissed = ko.observable(localStorage.getItem('gitVersionErrorDismissed'));
|
||||
this.gitVersionError = ko.observable();
|
||||
this.gitVersionErrorVisible = ko.computed(function() {
|
||||
return !ungit.config.gitVersionCheckOverride && self.gitVersionError() && !self.gitVersionErrorDismissed();
|
||||
});
|
||||
|
||||
var NPSSurveyLastDismissed = parseInt(localStorage.getItem('NPSSurveyLastDismissed') || '0');
|
||||
var monthsSinceNPSLastDismissed = (Date.now() - NPSSurveyLastDismissed) / (1000 * 60 * 60 * 24 * 30);
|
||||
this.showNPSSurvey = ko.observable(monthsSinceNPSLastDismissed >= 6 && Math.random() < 0.01);
|
||||
this.sendNPS = function(value) {
|
||||
keen.addEvent('survey-nps', {
|
||||
version: ungit.version,
|
||||
userHash: ungit.userHash,
|
||||
rating: value,
|
||||
bugtrackingEnabled: ungit.config.bugtracking,
|
||||
sendUsageStatistics: ungit.config.sendUsageStatistics
|
||||
});
|
||||
self.dismissNPSSurvey();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
AppViewModel.prototype.updateNode = function(parentElement) {
|
||||
ko.renderTemplate('app', this, {}, parentElement);
|
||||
}
|
||||
AppViewModel.prototype.template = 'app';
|
||||
AppViewModel.prototype.shown = function() {
|
||||
var self = this;
|
||||
// The ungit.config variable collections configuration from all different paths and only updates when
|
||||
// ungit is restarted
|
||||
if(!ungit.config.bugtracking) {
|
||||
// Whereas the userconfig only reflects what's in the ~/.ungitrc and updates directly,
|
||||
// but is only used for changing around the configuration. We need to check this here
|
||||
// since ungit may have crashed without the server crashing since we enabled bugtracking,
|
||||
// and we don't want to show the nagscreen twice in that case.
|
||||
this.server.get('/userconfig', undefined, function(err, userConfig) {
|
||||
self.bugtrackingEnabled(userConfig.bugtracking);
|
||||
});
|
||||
}
|
||||
|
||||
this.server.get('/latestversion', undefined, function(err, version) {
|
||||
if (!version) return;
|
||||
self.currentVersion(version.currentVersion);
|
||||
self.latestVersion(version.latestVersion);
|
||||
self.newVersionAvailable(version.outdated);
|
||||
});
|
||||
this.server.get('/gitversion', undefined, function(err, gitversion) {
|
||||
if (!gitversion) return;
|
||||
if (!gitversion.satisfied) {
|
||||
self.gitVersionError(gitversion.error);
|
||||
}
|
||||
});
|
||||
}
|
||||
AppViewModel.prototype.updateAnimationFrame = function(deltaT) {
|
||||
if (this.content() && this.content().updateAnimationFrame) this.content().updateAnimationFrame(deltaT);
|
||||
}
|
||||
AppViewModel.prototype.onProgramEvent = function(event) {
|
||||
if (event.event == 'request-credentials') this._handleCredentialsRequested(event);
|
||||
else if (event.event == 'request-show-dialog') this.showDialog(event.dialog);
|
||||
else if (event.event == 'request-remember-repo') this._handleRequestRememberRepo(event);
|
||||
|
||||
if (this.content() && this.content().onProgramEvent)
|
||||
this.content().onProgramEvent(event);
|
||||
if (this.header && this.header.onProgramEvent) this.header.onProgramEvent(event);
|
||||
}
|
||||
AppViewModel.prototype._handleRequestRememberRepo = function(event) {
|
||||
var repoPath = event.repoPath;
|
||||
if (this.repoList.indexOf(repoPath) != -1) return;
|
||||
this.repoList.push(repoPath);
|
||||
}
|
||||
AppViewModel.prototype._handleCredentialsRequested = function() {
|
||||
var self = this;
|
||||
var diag;
|
||||
// Only show one credentials dialog if we're asked to show another one while the first one is open
|
||||
// This happens for instance when we fetch nodes and remote tags at the same time
|
||||
if (this._isShowingCredentialsDialog)
|
||||
diag = self.dialog();
|
||||
else {
|
||||
diag = components.create('credentialsdialog');
|
||||
self.showDialog(diag);
|
||||
}
|
||||
this._isShowingCredentialsDialog = true;
|
||||
diag.closed.add(function() {
|
||||
self._isShowingCredentialsDialog = false;
|
||||
programEvents.dispatch({ event: 'request-credentials-response', username: diag.username(), password: diag.password() });
|
||||
});
|
||||
}
|
||||
AppViewModel.prototype.showDialog = function(dialog) {
|
||||
var self = this;
|
||||
dialog.closed.add(function() {
|
||||
self.dialog(null);
|
||||
})
|
||||
this.dialog(dialog);
|
||||
}
|
||||
AppViewModel.prototype.enableBugtrackingAndStatistics = function() {
|
||||
var self = this;
|
||||
this.server.get('/userconfig', undefined, function(err, userConfig) {
|
||||
if (err) return;
|
||||
userConfig.bugtracking = true;
|
||||
userConfig.sendUsageStatistics = true;
|
||||
self.server.post('/userconfig', userConfig, function(err) {
|
||||
if (err) return;
|
||||
self.bugtrackingEnabled(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
AppViewModel.prototype.enableBugtracking = function() {
|
||||
var self = this;
|
||||
this.server.get('/userconfig', undefined, function(err, userConfig) {
|
||||
if (err) return;
|
||||
userConfig.bugtracking = true;
|
||||
self.server.post('/userconfig', userConfig, function(err) {
|
||||
if (err) return;
|
||||
self.bugtrackingEnabled(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
AppViewModel.prototype.dismissBugtrackingNagscreen = function() {
|
||||
localStorage.setItem('bugtrackingNagscreenDismissed', true);
|
||||
this.bugtrackingNagscreenDismissed(true);
|
||||
}
|
||||
AppViewModel.prototype.dismissGitVersionError = function() {
|
||||
localStorage.setItem('gitVersionErrorDismissed', true);
|
||||
this.gitVersionErrorDismissed(true);
|
||||
}
|
||||
AppViewModel.prototype.dismissNPSSurvey = function() {
|
||||
this.showNPSSurvey(false);
|
||||
localStorage.setItem('NPSSurveyLastDismissed', Date.now());
|
||||
}
|
||||
AppViewModel.prototype.templateChooser = function(data) {
|
||||
if (!data) return '';
|
||||
return data.template;
|
||||
};
|
8
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/app/ungit-plugin.json
generated
vendored
Normal file
8
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/app/ungit-plugin.json
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"exports": {
|
||||
"knockoutTemplates": {
|
||||
"app": "app.html"
|
||||
},
|
||||
"javascript": "app.bundle.js"
|
||||
}
|
||||
}
|
91
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/branches/branches.bundle.js
generated
vendored
Normal file
91
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/branches/branches.bundle.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
18
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/branches/branches.html
generated
vendored
Normal file
18
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/branches/branches.html
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-default btn-main" data-ta-clickable="branch" data-bind="click: updateBranches">
|
||||
<span class="octicon octicon-git-branch"></span>
|
||||
<span data-bind="text: fetchLabel"></span>
|
||||
<!-- ko component: fetchingProgressBar --><!-- /ko -->
|
||||
</button>
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" data-ta-clickable="branch-menu">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu pull-right" role="menu" data-ta-container="branches">
|
||||
<!-- ko foreach: branches -->
|
||||
<li>
|
||||
<a href="#" data-bind="text: name, click: $parent.checkoutBranch.bind($parent), attr: { 'data-ta-clickable': 'checkout' + name }"></a>
|
||||
<a href="#" class="list-link list-remove" data-bind="click: $parent.branchRemove.bind($parent), attr: { 'data-ta-clickable': name + '-remove' }">X</a>
|
||||
</li>
|
||||
<!-- /ko -->
|
||||
</ul>
|
||||
</div>
|
87
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/branches/branches.js
generated
vendored
Normal file
87
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/branches/branches.js
generated
vendored
Normal file
|
@ -0,0 +1,87 @@
|
|||
|
||||
var ko = require('knockout');
|
||||
var _ = require('lodash');
|
||||
var async = require('async');
|
||||
var components = require('ungit-components');
|
||||
var programEvents = require('ungit-program-events');
|
||||
|
||||
components.register('branches', function(args) {
|
||||
return new BranchesViewModel(args.server, args.repoPath);
|
||||
});
|
||||
|
||||
function BranchesViewModel(server, repoPath) {
|
||||
var self = this;
|
||||
this.repoPath = repoPath;
|
||||
this.server = server;
|
||||
this.branches = ko.observableArray();
|
||||
this.fetchingProgressBar = components.create('progressBar', { predictionMemoryKey: 'fetching-' + this.repoPath(), temporary: true });
|
||||
this.current = ko.observable();
|
||||
this.fetchLabel = ko.computed(function() {
|
||||
if (self.current()) {
|
||||
return self.current();
|
||||
}
|
||||
});
|
||||
this.updateBranches();
|
||||
}
|
||||
BranchesViewModel.prototype.updateNode = function(parentElement) {
|
||||
ko.renderTemplate('branches', this, {}, parentElement);
|
||||
}
|
||||
BranchesViewModel.prototype.clickFetch = function() { this.updateBranches(); }
|
||||
BranchesViewModel.prototype.onProgramEvent = function(event) {
|
||||
if (event.event === 'working-tree-changed' || event.event == 'request-app-content-refresh' || event.event == 'branch-updated') {
|
||||
this.updateBranches();
|
||||
}
|
||||
}
|
||||
BranchesViewModel.prototype.checkoutBranch = function(branch) {
|
||||
var self = this;
|
||||
this.fetchingProgressBar.start();
|
||||
this.server.post('/checkout', { path: this.repoPath(), name: branch.name }, function(err) {
|
||||
if (err) return;
|
||||
self.current(branch.name);
|
||||
self.fetchingProgressBar.stop();
|
||||
});
|
||||
}
|
||||
BranchesViewModel.prototype.updateBranches = function() {
|
||||
var self = this;
|
||||
this.fetchingProgressBar.start();
|
||||
this.server.get('/branches', { path: this.repoPath() }, function(err, branches) {
|
||||
if (err) {
|
||||
self.current("~error");
|
||||
return;
|
||||
}
|
||||
|
||||
if (branches) {
|
||||
var sorted = branches.sort(function(a, b) {
|
||||
if (a.name < b.name)
|
||||
return -1;
|
||||
if (a.name > b.name)
|
||||
return 1;
|
||||
return 0;
|
||||
});
|
||||
self.branches(sorted);
|
||||
self.current(undefined);
|
||||
branches.forEach(function(branch) {
|
||||
if (branch.current) {
|
||||
self.current(branch.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
self.fetchingProgressBar.stop();
|
||||
});
|
||||
}
|
||||
|
||||
BranchesViewModel.prototype.branchRemove = function(branch) {
|
||||
var self = this;
|
||||
var diag = components.create('yesnodialog', { title: 'Are you sure?', details: 'Deleting ' + branch.name + ' branch cannot be undone with ungit.'});
|
||||
diag.closed.add(function() {
|
||||
if (diag.result()) {
|
||||
self.server.del('/branches', { name: branch.name, path: self.repoPath() }, function(err) {
|
||||
if (!err) {
|
||||
programEvents.dispatch({ event: 'working-tree-changed' });
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
programEvents.dispatch({ event: 'request-show-dialog', dialog: diag });
|
||||
}
|
8
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/branches/ungit-plugin.json
generated
vendored
Normal file
8
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/branches/ungit-plugin.json
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"exports": {
|
||||
"knockoutTemplates": {
|
||||
"branches": "branches.html"
|
||||
},
|
||||
"javascript": "branches.bundle.js"
|
||||
}
|
||||
}
|
97
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commit/commit.bundle.js
generated
vendored
Normal file
97
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commit/commit.bundle.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
92
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commit/commit.css
generated
vendored
Normal file
92
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commit/commit.css
generated
vendored
Normal file
|
@ -0,0 +1,92 @@
|
|||
.commit {
|
||||
position: relative;
|
||||
}
|
||||
.commit.highlighted {
|
||||
z-index: 2;
|
||||
}
|
||||
.commit.highlighted .commit-box {
|
||||
box-shadow: 5px 5px 0px rgba(0, 0, 0, 0.2);
|
||||
background: #4B5766;
|
||||
left: -5px;
|
||||
}
|
||||
.commit.highlighted .commit-box .arrowRight .shadow {
|
||||
display: block;
|
||||
}
|
||||
.commit.highlighted .commit-box .arrowRight .arrow {
|
||||
border-left: 15px solid #4A5665;
|
||||
}
|
||||
.commit.hover {
|
||||
z-index: 3;
|
||||
}
|
||||
.commit.selected .details .diff-wrapper {
|
||||
transition: width 0.1s, left 0.05s;
|
||||
box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
.commit.selected .details .diff-wrapper .diff-inner {
|
||||
box-shadow: 5px 5px 0px rgba(0, 0, 0, 0.2);
|
||||
padding: 10px;
|
||||
padding-top: 0px;
|
||||
}
|
||||
.commit.selected .details .diff-wrapper .btn-group {
|
||||
padding: 2px;
|
||||
margin: 10px 0px 0px 10px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
.commit .commit-box .arrowRight {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
top: 5px;
|
||||
}
|
||||
.commit .commit-box .arrowRight .shadow {
|
||||
display: none;
|
||||
height: 0px;
|
||||
width: 0px;
|
||||
margin-left: -1px;
|
||||
border-top: 15px solid transparent;
|
||||
border-bottom: 15px solid transparent;
|
||||
border-left: 15px solid #1E2029;
|
||||
}
|
||||
.commit .commit-box .arrowRight .arrow {
|
||||
height: 0px;
|
||||
width: 0px;
|
||||
border-top: 15px solid transparent;
|
||||
border-bottom: 15px solid transparent;
|
||||
border-left: 15px solid #3b4552;
|
||||
}
|
||||
.commit .commit-box > .panel-body {
|
||||
position: relative;
|
||||
padding: 10px;
|
||||
margin-bottom: 0px;
|
||||
width: 400px;
|
||||
min-height: 85px;
|
||||
}
|
||||
.commit .commit-box > .panel-body .gravatar {
|
||||
display: none;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.commit .commit-box > .panel-body .title {
|
||||
font-size: 1.3em;
|
||||
word-wrap: break-word;
|
||||
display: block;
|
||||
}
|
||||
.commit .commit-box > .panel-body .details .body {
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
color: #8F9FA6;
|
||||
}
|
||||
.commit .commit-box > .panel-body .details .diff-wrapper {
|
||||
position: relative;
|
||||
margin: 0px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
background: #4B5766;
|
||||
border-radius: 3px;
|
||||
}
|
||||
@media (min-width: 992px) {
|
||||
.commit .commit-box > .panel-body {
|
||||
width: 550px;
|
||||
}
|
||||
.commit .commit-box > .panel-body .gravatar {
|
||||
display: block;
|
||||
}
|
||||
}
|
52
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commit/commit.html
generated
vendored
Normal file
52
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commit/commit.html
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
<div class="commit" data-bind="css: { highlighted: highlighted, hover: nodeIsMousehover, selected: selected }">
|
||||
<div class="commit-box panel panel-default" data-bind="element: element, click: stopClickPropagation">
|
||||
<div class="panel-body">
|
||||
<div class="arrowContainer arrowRight">
|
||||
<div class="shadow"></div>
|
||||
<div class="arrow"></div>
|
||||
</div>
|
||||
<div class="clearfix">
|
||||
<img class="pull-left img-circle gravatar"
|
||||
data-bind="attr: { src: 'http://www.gravatar.com/avatar/' + authorGravatar() + '?default=404' }"
|
||||
onerror="this.style.display='none';">
|
||||
<div>
|
||||
<div>
|
||||
<span class="title" data-bind="text: title"></span>
|
||||
<span class="text-muted">by <a data-bind="text: authorName, attr: { href: 'mailto:' + authorEmail() }"></a></span>
|
||||
</div>
|
||||
<div class="text-muted nodeSummaryContainer">
|
||||
<span data-bind="text: authorDateFromNow, attr: { 'data-original-title': authorDate }" class="bootstrap-tooltip" data-toggle="tooltip" data-placement="bottom" data-delay='{"show":"2000", "hide":"0"}'></span> |
|
||||
+<span data-bind="text: numberOfAddedLines"></span>,
|
||||
-<span data-bind="text: numberOfRemovedLines"></span>
|
||||
|
|
||||
<span data-bind="text: sha1.substr(0, 8)"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ko if: selected() || nodeIsMousehover() -->
|
||||
<div class="details">
|
||||
<div class="body" data-bind="text: body"></div>
|
||||
<div class="diff-wrapper" data-bind="visible: showCommitDiff, style: diffStyle, click: stopClickPropagation">
|
||||
<div class="btn-group btn-group-xs" data-bind="visible: selected">
|
||||
<button class="btn btn-default bootstrap-tooltip pull-right" data-ta-clickable="commit-wordwrap" data-bind="click: toggleWordWrap.bind($data, true), css: {active: wordWrap}" data-toggle="tooltip" data-placement="bottom" data-original-title="Wrap words per line" data-delay='{"show":"2000", "hide":"0"}'>
|
||||
<span data-bind="text: 'Word Wrap'"></span>
|
||||
</button>
|
||||
<button class="btn btn-default bootstrap-tooltip pull-right" data-ta-clickable="commit-nowrap" data-bind="click: toggleWordWrap.bind($data, false), css: {active: !wordWrap()}" data-toggle="tooltip" data-placement="bottom" data-original-title="Not wrapping words per line" data-delay='{"show":"2000", "hide":"0"}'>
|
||||
<span data-bind="text: 'Default'"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="btn-group btn-group-xs" data-bind="visible: selected">
|
||||
<button class="btn btn-default bootstrap-tooltip pull-right" data-ta-clickable="commit-sideBySideDiff" data-bind="click: textDiffTypeChange.bind($data, 'sidebysidediff'), css: {active: textDiffType() === 'sidebysidediff'}" data-toggle="tooltip" data-placement="bottom" data-original-title="Show side by side diff view" data-delay='{"show":"2000", "hide":"0"}'>
|
||||
<span data-bind="text: 'Side by Side'"></span>
|
||||
</button>
|
||||
<button class="btn btn-default bootstrap-tooltip pull-right" data-ta-clickable="commit-defaultDiff" data-bind="click: textDiffTypeChange.bind($data, 'textdiff'), css: {active: textDiffType() === 'textdiff'}" data-toggle="tooltip" data-placement="bottom" data-original-title="Show inline diff view" data-delay='{"show":"2000", "hide":"0"}'>
|
||||
<span data-bind="text: 'Default'"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="diff-inner" data-bind="component: commitDiff"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
93
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commit/commit.js
generated
vendored
Normal file
93
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commit/commit.js
generated
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
|
||||
var ko = require('knockout');
|
||||
var components = require('ungit-components');
|
||||
var navigation = require('ungit-navigation');
|
||||
var programEvents = require('ungit-program-events');
|
||||
var md5 = require('blueimp-md5');
|
||||
var moment = require('moment');
|
||||
|
||||
components.register('commit', function(args) {
|
||||
return new CommitViewModel(args);
|
||||
});
|
||||
|
||||
function CommitViewModel(args) {
|
||||
var self = this;
|
||||
this.repoPath = args.repoPath;
|
||||
this.sha1 = args.sha1;
|
||||
this.server = args.server;
|
||||
this.highlighted = args.highlighted;
|
||||
this.nodeIsMousehover = args.nodeIsMousehover;
|
||||
this.selected = args.selected;
|
||||
this.element = ko.observable();
|
||||
this.commitTime = ko.observable();
|
||||
this.authorTime = ko.observable();
|
||||
this.message = ko.observable();
|
||||
this.title = ko.observable();
|
||||
this.body = ko.observable();
|
||||
this.authorDate = ko.observable(0);
|
||||
this.authorDateFromNow = ko.observable();
|
||||
this.authorName = ko.observable();
|
||||
this.authorEmail = ko.observable();
|
||||
this.fileLineDiffs = ko.observable();
|
||||
this.numberOfAddedLines = ko.observable();
|
||||
this.numberOfRemovedLines = ko.observable();
|
||||
this.authorGravatar = ko.computed(function() { return md5(self.authorEmail()); });
|
||||
this.textDiffType = ko.observable('textdiff');
|
||||
this.wordWrap = ko.observable(false);
|
||||
|
||||
this.showCommitDiff = ko.computed(function() {
|
||||
return self.fileLineDiffs() && self.fileLineDiffs().length > 0;
|
||||
});
|
||||
|
||||
this.selectedDiffLeftPosition = ko.observable();
|
||||
this.diffStyle = ko.computed(function() {
|
||||
if (self.selected()) return { left: self.selectedDiffLeftPosition() + 'px', width: (window.innerWidth - 220) + 'px' };
|
||||
else return { left: '0px', width: self.element() ? ((self.element().clientWidth - 20) + 'px') : 'inherit' };
|
||||
});
|
||||
}
|
||||
CommitViewModel.prototype.updateNode = function(parentElement) {
|
||||
ko.renderTemplate('commit', this, {}, parentElement);
|
||||
}
|
||||
CommitViewModel.prototype.setData = function(args) {
|
||||
this.commitTime(moment(new Date(args.commitDate)));
|
||||
this.authorTime(moment(new Date(args.authorDate)));
|
||||
var message = args.message.split('\n');
|
||||
this.message(args.message);
|
||||
this.title(message[0]);
|
||||
this.body(message.slice(2).join('\n'));
|
||||
this.authorDate(moment(new Date(args.authorDate)));
|
||||
this.authorDateFromNow(this.authorDate().fromNow());
|
||||
this.authorName(args.authorName);
|
||||
this.authorEmail(args.authorEmail);
|
||||
this.numberOfAddedLines(args.fileLineDiffs.length > 0 ? args.fileLineDiffs[0][0] : 0);
|
||||
this.numberOfRemovedLines(args.fileLineDiffs.length > 0 ? args.fileLineDiffs[0][1] : 0);
|
||||
this.fileLineDiffs(args.fileLineDiffs);
|
||||
this.isInited = true;
|
||||
this.commitDiff = ko.observable(components.create('commitDiff',
|
||||
{ fileLineDiffs: this.fileLineDiffs(),
|
||||
sha1: this.sha1,
|
||||
repoPath: this.repoPath,
|
||||
server: this.server,
|
||||
textDiffType: this.textDiffType,
|
||||
wordWrap: this.wordWrap }));
|
||||
}
|
||||
CommitViewModel.prototype.updateLastAuthorDateFromNow = function(deltaT) {
|
||||
this.lastUpdatedAuthorDateFromNow = this.lastUpdatedAuthorDateFromNow || 0;
|
||||
this.lastUpdatedAuthorDateFromNow += deltaT;
|
||||
if(this.lastUpdatedAuthorDateFromNow > 60 * 1000) {
|
||||
this.lastUpdatedAuthorDateFromNow = 0;
|
||||
this.authorDateFromNow(this.authorDate().fromNow());
|
||||
}
|
||||
}
|
||||
CommitViewModel.prototype.updateAnimationFrame = function(deltaT) {
|
||||
this.updateLastAuthorDateFromNow(deltaT);
|
||||
}
|
||||
CommitViewModel.prototype.textDiffTypeChange = function(type) {
|
||||
this.textDiffType(type);
|
||||
}
|
||||
CommitViewModel.prototype.stopClickPropagation = function(data, event) {
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
CommitViewModel.prototype.toggleWordWrap = function(state) {
|
||||
this.wordWrap(state);
|
||||
}
|
114
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commit/commit.less
generated
vendored
Normal file
114
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commit/commit.less
generated
vendored
Normal file
|
@ -0,0 +1,114 @@
|
|||
|
||||
@import "public/less/variables.less";
|
||||
|
||||
.commit {
|
||||
position: relative;
|
||||
|
||||
&.highlighted {
|
||||
z-index: 2;
|
||||
.commit-box {
|
||||
box-shadow: 5px 5px 0px rgba(0, 0, 0, 0.2);
|
||||
background: #4B5766;
|
||||
left: -5px;
|
||||
.arrowRight {
|
||||
.shadow {
|
||||
display: block;
|
||||
}
|
||||
.arrow {
|
||||
border-left: 15px solid #4A5665;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&.hover {
|
||||
z-index: 3;
|
||||
}
|
||||
&.selected {
|
||||
.details {
|
||||
.diff-wrapper {
|
||||
transition:width 0.1s, left 0.05s;
|
||||
box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.15);
|
||||
.diff-inner {
|
||||
box-shadow: 5px 5px 0px rgba(0, 0, 0, 0.2);
|
||||
padding: 10px;
|
||||
padding-top: 0px;
|
||||
}
|
||||
.btn-group {
|
||||
padding: 2px;
|
||||
margin: 10px 0px 0px 10px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.commit-box {
|
||||
.arrowRight {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
top: 5px;
|
||||
.shadow {
|
||||
display: none;
|
||||
height: 0px;
|
||||
width: 0px;
|
||||
margin-left: -1px;
|
||||
border-top: 15px solid transparent;
|
||||
border-bottom: 15px solid transparent;
|
||||
border-left: 15px solid #1E2029;
|
||||
}
|
||||
.arrow {
|
||||
height: 0px;
|
||||
width: 0px;
|
||||
border-top: 15px solid transparent;
|
||||
border-bottom: 15px solid transparent;
|
||||
border-left: 15px solid #3b4552;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.commit-box > .panel-body {
|
||||
position: relative;
|
||||
|
||||
padding: 10px;
|
||||
margin-bottom: 0px;
|
||||
width: @log-width-small;
|
||||
min-height: 85px;
|
||||
|
||||
.gravatar {
|
||||
display: none;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 1.3em;
|
||||
word-wrap: break-word;
|
||||
display: block;
|
||||
}
|
||||
.details {
|
||||
.body {
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
color: #8F9FA6;
|
||||
}
|
||||
.diff-wrapper {
|
||||
position: relative;
|
||||
margin: 0px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
background: #4B5766;
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: @screen-md-min) {
|
||||
.commit {
|
||||
.commit-box > .panel-body {
|
||||
width: @log-width-large;
|
||||
.gravatar {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
9
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commit/ungit-plugin.json
generated
vendored
Normal file
9
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commit/ungit-plugin.json
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"exports": {
|
||||
"knockoutTemplates": {
|
||||
"commit": "commit.html"
|
||||
},
|
||||
"javascript": "commit.bundle.js",
|
||||
"css": "commit.css"
|
||||
}
|
||||
}
|
73
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commitdiff/commitdiff.bundle.js
generated
vendored
Normal file
73
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commitdiff/commitdiff.bundle.js
generated
vendored
Normal file
|
@ -0,0 +1,73 @@
|
|||
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
var ko = require('knockout');
|
||||
var CommitLineDiff = require('./commitlinediff.js').CommitLineDiff;
|
||||
var components = require('ungit-components');
|
||||
|
||||
components.register('commitDiff', function(args) {
|
||||
return new CommitDiff(args);
|
||||
});
|
||||
|
||||
var CommitDiff = function(args) {
|
||||
this.commitLineDiffs = ko.observableArray();
|
||||
this.sha1 = args.sha1;
|
||||
args.fileLineDiffs.shift(); // remove first line that has "total"
|
||||
this.loadFileLineDiffs(args);
|
||||
};
|
||||
|
||||
CommitDiff.prototype.updateNode = function(parentElement) {
|
||||
ko.renderTemplate('commitdiff', this, {}, parentElement);
|
||||
};
|
||||
|
||||
CommitDiff.prototype.loadFileLineDiffs = function(args) {
|
||||
var tempCommitLineDiffs = [];
|
||||
var lineDiffLength = this.commitLineDiffs().length;
|
||||
|
||||
args.fileLineDiffs.slice(lineDiffLength === 0 ? 0 : lineDiffLength + 1, this.maxNumberOfFilesShown).forEach(function(fileLineDiff) {
|
||||
tempCommitLineDiffs.push(new CommitLineDiff(args, fileLineDiff));
|
||||
});
|
||||
|
||||
this.commitLineDiffs(this.commitLineDiffs().concat(tempCommitLineDiffs));
|
||||
}
|
||||
|
||||
},{"./commitlinediff.js":2,"knockout":"knockout","ungit-components":"ungit-components"}],2:[function(require,module,exports){
|
||||
var ko = require('knockout');
|
||||
var components = require('ungit-components');
|
||||
var inherits = require('util').inherits;
|
||||
var programEvents = require('ungit-program-events');
|
||||
|
||||
var CommitLineDiff = function(args, fileLineDiff) {
|
||||
this.added = ko.observable(fileLineDiff[0]);
|
||||
this.removed = ko.observable(fileLineDiff[1]);
|
||||
this.fileName = ko.observable(fileLineDiff[2]);
|
||||
this.fileType = fileLineDiff[3];
|
||||
this.isShowingDiffs = ko.observable(false);
|
||||
this.repoPath = args.repoPath;
|
||||
this.server = args.server;
|
||||
this.sha1 = args.sha1;
|
||||
this.textDiffType = args.textDiffType;
|
||||
this.wordWrap = args.wordWrap;
|
||||
this.specificDiff = ko.observable(this.getSpecificDiff());
|
||||
};
|
||||
exports.CommitLineDiff = CommitLineDiff;
|
||||
|
||||
CommitLineDiff.prototype.getSpecificDiff = function() {
|
||||
return components.create(this.fileType + 'diff', {
|
||||
filename: this.fileName(),
|
||||
repoPath: this.repoPath,
|
||||
server: this.server,
|
||||
sha1: this.sha1,
|
||||
textDiffType: this.textDiffType,
|
||||
isShowingDiffs: this.isShowingDiffs,
|
||||
wordWrap: this.wordWrap
|
||||
});
|
||||
}
|
||||
|
||||
CommitLineDiff.prototype.fileNameClick = function() {
|
||||
this.isShowingDiffs(!this.isShowingDiffs());
|
||||
this.specificDiff().invalidateDiff(function() {
|
||||
programEvents.dispatch({ event: 'graph-render' });
|
||||
});
|
||||
};
|
||||
|
||||
},{"knockout":"knockout","ungit-components":"ungit-components","ungit-program-events":"ungit-program-events","util":undefined}]},{},[1])
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJjb21wb25lbnRzL2NvbW1pdGRpZmYvY29tbWl0ZGlmZi5qcyIsImNvbXBvbmVudHMvY29tbWl0ZGlmZi9jb21taXRsaW5lZGlmZi5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsInZhciBrbyA9IHJlcXVpcmUoJ2tub2Nrb3V0Jyk7XG52YXIgQ29tbWl0TGluZURpZmYgPSByZXF1aXJlKCcuL2NvbW1pdGxpbmVkaWZmLmpzJykuQ29tbWl0TGluZURpZmY7XG52YXIgY29tcG9uZW50cyA9IHJlcXVpcmUoJ3VuZ2l0LWNvbXBvbmVudHMnKTtcblxuY29tcG9uZW50cy5yZWdpc3RlcignY29tbWl0RGlmZicsIGZ1bmN0aW9uKGFyZ3MpIHtcbiAgcmV0dXJuIG5ldyBDb21taXREaWZmKGFyZ3MpO1xufSk7XG5cbnZhciBDb21taXREaWZmID0gZnVuY3Rpb24oYXJncykge1xuICB0aGlzLmNvbW1pdExpbmVEaWZmcyA9IGtvLm9ic2VydmFibGVBcnJheSgpO1xuICB0aGlzLnNoYTEgPSBhcmdzLnNoYTE7XG4gIGFyZ3MuZmlsZUxpbmVEaWZmcy5zaGlmdCgpOyAgLy8gcmVtb3ZlIGZpcnN0IGxpbmUgdGhhdCBoYXMgXCJ0b3RhbFwiXG4gIHRoaXMubG9hZEZpbGVMaW5lRGlmZnMoYXJncyk7XG59O1xuXG5Db21taXREaWZmLnByb3RvdHlwZS51cGRhdGVOb2RlID0gZnVuY3Rpb24ocGFyZW50RWxlbWVudCkge1xuICBrby5yZW5kZXJUZW1wbGF0ZSgnY29tbWl0ZGlmZicsIHRoaXMsIHt9LCBwYXJlbnRFbGVtZW50KTtcbn07XG5cbkNvbW1pdERpZmYucHJvdG90eXBlLmxvYWRGaWxlTGluZURpZmZzID0gZnVuY3Rpb24oYXJncykge1xuICB2YXIgdGVtcENvbW1pdExpbmVEaWZmcyA9IFtdO1xuICB2YXIgbGluZURpZmZMZW5ndGggPSB0aGlzLmNvbW1pdExpbmVEaWZmcygpLmxlbmd0aDtcblxuICBhcmdzLmZpbGVMaW5lRGlmZnMuc2xpY2UobGluZURpZmZMZW5ndGggPT09IDAgPyAwIDogbGluZURpZmZMZW5ndGggKyAxLCB0aGlzLm1heE51bWJlck9mRmlsZXNTaG93bikuZm9yRWFjaChmdW5jdGlvbihmaWxlTGluZURpZmYpIHtcbiAgICB0ZW1wQ29tbWl0TGluZURpZmZzLnB1c2gobmV3IENvbW1pdExpbmVEaWZmKGFyZ3MsIGZpbGVMaW5lRGlmZikpO1xuICB9KTtcblxuICB0aGlzLmNvbW1pdExpbmVEaWZmcyh0aGlzLmNvbW1pdExpbmVEaWZmcygpLmNvbmNhdCh0ZW1wQ29tbWl0TGluZURpZmZzKSk7XG59XG4iLCJ2YXIga28gPSByZXF1aXJlKCdrbm9ja291dCcpO1xudmFyIGNvbXBvbmVudHMgPSByZXF1aXJlKCd1bmdpdC1jb21wb25lbnRzJyk7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCd1dGlsJykuaW5oZXJpdHM7XG52YXIgcHJvZ3JhbUV2ZW50cyA9IHJlcXVpcmUoJ3VuZ2l0LXByb2dyYW0tZXZlbnRzJyk7XG5cbnZhciBDb21taXRMaW5lRGlmZiA9IGZ1bmN0aW9uKGFyZ3MsIGZpbGVMaW5lRGlmZikge1xuICB0aGlzLmFkZGVkID0ga28ub2JzZXJ2YWJsZShmaWxlTGluZURpZmZbMF0pO1xuICB0aGlzLnJlbW92ZWQgPSBrby5vYnNlcnZhYmxlKGZpbGVMaW5lRGlmZlsxXSk7XG4gIHRoaXMuZmlsZU5hbWUgPSBrby5vYnNlcnZhYmxlKGZpbGVMaW5lRGlmZlsyXSk7XG4gIHRoaXMuZmlsZVR5cGUgPSBmaWxlTGluZURpZmZbM107XG4gIHRoaXMuaXNTaG93aW5nRGlmZnMgPSBrby5vYnNlcnZhYmxlKGZhbHNlKTtcbiAgdGhpcy5yZXBvUGF0aCA9IGFyZ3MucmVwb1BhdGg7XG4gIHRoaXMuc2VydmVyID0gYXJncy5zZXJ2ZXI7XG4gIHRoaXMuc2hhMSA9IGFyZ3Muc2hhMTtcbiAgdGhpcy50ZXh0RGlmZlR5cGUgPSBhcmdzLnRleHREaWZmVHlwZTtcbiAgdGhpcy53b3JkV3JhcCA9IGFyZ3Mud29yZFdyYXA7XG4gIHRoaXMuc3BlY2lmaWNEaWZmID0ga28ub2JzZXJ2YWJsZSh0aGlzLmdldFNwZWNpZmljRGlmZigpKTtcbn07XG5leHBvcnRzLkNvbW1pdExpbmVEaWZmID0gQ29tbWl0TGluZURpZmY7XG5cbkNvbW1pdExpbmVEaWZmLnByb3RvdHlwZS5nZXRTcGVjaWZpY0RpZmYgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIGNvbXBvbmVudHMuY3JlYXRlKHRoaXMuZmlsZVR5cGUgKyAnZGlmZicsIHtcbiAgICBmaWxlbmFtZTogdGhpcy5maWxlTmFtZSgpLFxuICAgIHJlcG9QYXRoOiB0aGlzLnJlcG9QYXRoLFxuICAgIHNlcnZlcjogdGhpcy5zZXJ2ZXIsXG4gICAgc2hhMTogdGhpcy5zaGExLFxuICAgIHRleHREaWZmVHlwZTogdGhpcy50ZXh0RGlmZlR5cGUsXG4gICAgaXNTaG93aW5nRGlmZnM6IHRoaXMuaXNTaG93aW5nRGlmZnMsXG4gICAgd29yZFdyYXA6IHRoaXMud29yZFdyYXBcbiAgfSk7XG59XG5cbkNvbW1pdExpbmVEaWZmLnByb3RvdHlwZS5maWxlTmFtZUNsaWNrID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuaXNTaG93aW5nRGlmZnMoIXRoaXMuaXNTaG93aW5nRGlmZnMoKSk7XG4gIHRoaXMuc3BlY2lmaWNEaWZmKCkuaW52YWxpZGF0ZURpZmYoZnVuY3Rpb24oKSB7XG4gICAgcHJvZ3JhbUV2ZW50cy5kaXNwYXRjaCh7IGV2ZW50OiAnZ3JhcGgtcmVuZGVyJyB9KTtcbiAgfSk7XG59O1xuIl19
|
39
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commitdiff/commitdiff.css
generated
vendored
Normal file
39
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commitdiff/commitdiff.css
generated
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
.commitdiff {
|
||||
width: 100%;
|
||||
}
|
||||
.commitdiff .file {
|
||||
margin-top: 5px;
|
||||
background: rgba(255, 255, 255, 0.16);
|
||||
border-radius: 3px;
|
||||
}
|
||||
.commitdiff .file .head {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
padding: 3px;
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
color: rgba(255, 255, 255, 0.79);
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.commitdiff .file .head .file-stats span:nth-of-type(1)::Before {
|
||||
content: "+";
|
||||
}
|
||||
.commitdiff .file .head .file-stats span:nth-of-type(1) {
|
||||
color: #9BF3A9;
|
||||
}
|
||||
.commitdiff .file .head .file-stats span:nth-of-type(2)::Before {
|
||||
content: "-";
|
||||
}
|
||||
.commitdiff .file .head .file-stats span:nth-of-type(2) {
|
||||
color: #EC9D93;
|
||||
}
|
||||
.commitdiff .file .diff {
|
||||
background: rgba(0, 0, 0, 0.11);
|
||||
}
|
||||
.commitdiff .file .diff .textDiff {
|
||||
color: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
.loadMore .btn {
|
||||
display: block;
|
||||
margin: 20px 20px 10px 20px;
|
||||
}
|
14
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commitdiff/commitdiff.html
generated
vendored
Normal file
14
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commitdiff/commitdiff.html
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
<div data-bind="foreach: commitLineDiffs" class="commitdiff">
|
||||
<div class="file">
|
||||
<div class="head" data-bind="click: fileNameClick" data-ta-clickable="commitDiffFileName">
|
||||
<span data-bind="text: fileName"></span>
|
||||
<span class="file-stats" data-bind="visible: added() != '-'">
|
||||
(
|
||||
<span data-bind="text: added"></span>
|
||||
<span data-bind="text: removed"></span>
|
||||
)
|
||||
</span>
|
||||
</div>
|
||||
<div class="diffContainer" data-bind="component: specificDiff" data-ta-container="commitLineDiffs"></div>
|
||||
</div>
|
||||
</div>
|
29
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commitdiff/commitdiff.js
generated
vendored
Normal file
29
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commitdiff/commitdiff.js
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
var ko = require('knockout');
|
||||
var CommitLineDiff = require('./commitlinediff.js').CommitLineDiff;
|
||||
var components = require('ungit-components');
|
||||
|
||||
components.register('commitDiff', function(args) {
|
||||
return new CommitDiff(args);
|
||||
});
|
||||
|
||||
var CommitDiff = function(args) {
|
||||
this.commitLineDiffs = ko.observableArray();
|
||||
this.sha1 = args.sha1;
|
||||
args.fileLineDiffs.shift(); // remove first line that has "total"
|
||||
this.loadFileLineDiffs(args);
|
||||
};
|
||||
|
||||
CommitDiff.prototype.updateNode = function(parentElement) {
|
||||
ko.renderTemplate('commitdiff', this, {}, parentElement);
|
||||
};
|
||||
|
||||
CommitDiff.prototype.loadFileLineDiffs = function(args) {
|
||||
var tempCommitLineDiffs = [];
|
||||
var lineDiffLength = this.commitLineDiffs().length;
|
||||
|
||||
args.fileLineDiffs.slice(lineDiffLength === 0 ? 0 : lineDiffLength + 1, this.maxNumberOfFilesShown).forEach(function(fileLineDiff) {
|
||||
tempCommitLineDiffs.push(new CommitLineDiff(args, fileLineDiff));
|
||||
});
|
||||
|
||||
this.commitLineDiffs(this.commitLineDiffs().concat(tempCommitLineDiffs));
|
||||
}
|
40
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commitdiff/commitdiff.less
generated
vendored
Normal file
40
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commitdiff/commitdiff.less
generated
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
|
||||
.commitdiff {
|
||||
width: 100%;
|
||||
.file {
|
||||
margin-top: 5px;
|
||||
background: rgba(255, 255, 255, 0.16);
|
||||
border-radius: 3px;
|
||||
.head {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
padding: 3px;
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
color: rgba(255, 255, 255, 0.79);
|
||||
word-wrap: break-word;
|
||||
.file-stats {
|
||||
span:nth-of-type(1)::Before{ content: "+" }
|
||||
span:nth-of-type(1){
|
||||
color: #9BF3A9;
|
||||
}
|
||||
span:nth-of-type(2)::Before{ content: "-" }
|
||||
span:nth-of-type(2){
|
||||
color: #EC9D93;
|
||||
}
|
||||
}
|
||||
}
|
||||
.diff {
|
||||
background: rgba(0, 0, 0, 0.11);
|
||||
.textDiff {
|
||||
color: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.loadMore {
|
||||
.btn {
|
||||
display: block;
|
||||
margin: 20px 20px 10px 20px;
|
||||
}
|
||||
}
|
38
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commitdiff/commitlinediff.js
generated
vendored
Normal file
38
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commitdiff/commitlinediff.js
generated
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
var ko = require('knockout');
|
||||
var components = require('ungit-components');
|
||||
var inherits = require('util').inherits;
|
||||
var programEvents = require('ungit-program-events');
|
||||
|
||||
var CommitLineDiff = function(args, fileLineDiff) {
|
||||
this.added = ko.observable(fileLineDiff[0]);
|
||||
this.removed = ko.observable(fileLineDiff[1]);
|
||||
this.fileName = ko.observable(fileLineDiff[2]);
|
||||
this.fileType = fileLineDiff[3];
|
||||
this.isShowingDiffs = ko.observable(false);
|
||||
this.repoPath = args.repoPath;
|
||||
this.server = args.server;
|
||||
this.sha1 = args.sha1;
|
||||
this.textDiffType = args.textDiffType;
|
||||
this.wordWrap = args.wordWrap;
|
||||
this.specificDiff = ko.observable(this.getSpecificDiff());
|
||||
};
|
||||
exports.CommitLineDiff = CommitLineDiff;
|
||||
|
||||
CommitLineDiff.prototype.getSpecificDiff = function() {
|
||||
return components.create(this.fileType + 'diff', {
|
||||
filename: this.fileName(),
|
||||
repoPath: this.repoPath,
|
||||
server: this.server,
|
||||
sha1: this.sha1,
|
||||
textDiffType: this.textDiffType,
|
||||
isShowingDiffs: this.isShowingDiffs,
|
||||
wordWrap: this.wordWrap
|
||||
});
|
||||
}
|
||||
|
||||
CommitLineDiff.prototype.fileNameClick = function() {
|
||||
this.isShowingDiffs(!this.isShowingDiffs());
|
||||
this.specificDiff().invalidateDiff(function() {
|
||||
programEvents.dispatch({ event: 'graph-render' });
|
||||
});
|
||||
};
|
9
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commitdiff/ungit-plugin.json
generated
vendored
Normal file
9
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commitdiff/ungit-plugin.json
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"exports": {
|
||||
"knockoutTemplates": {
|
||||
"commitdiff": "commitdiff.html"
|
||||
},
|
||||
"javascript": "commitdiff.bundle.js",
|
||||
"css": "commitdiff.css"
|
||||
}
|
||||
}
|
153
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/dialogs/dialogs.bundle.js
generated
vendored
Normal file
153
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/dialogs/dialogs.bundle.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
149
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/dialogs/dialogs.js
generated
vendored
Normal file
149
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/dialogs/dialogs.js
generated
vendored
Normal file
|
@ -0,0 +1,149 @@
|
|||
|
||||
var ko = require('knockout');
|
||||
var signals = require('signals');
|
||||
var inherits = require('util').inherits;
|
||||
var components = require('ungit-components');
|
||||
|
||||
components.register('formdialog', function(args) {
|
||||
return new FormDialogViewModel(args.title);
|
||||
});
|
||||
|
||||
components.register('credentialsdialog', function(args) {
|
||||
return new CredentialsDialogViewModel();
|
||||
});
|
||||
|
||||
components.register('addremotedialog', function(args) {
|
||||
return new AddRemoteDialogViewModel();
|
||||
});
|
||||
|
||||
components.register('addsubmoduledialog', function(args) {
|
||||
return new AddSubmoduleDialogViewModel();
|
||||
});
|
||||
|
||||
components.register('promptdialog', function(args) {
|
||||
return new PromptDialogViewModel(args.title, args.details);
|
||||
});
|
||||
|
||||
components.register('yesnodialog', function(args) {
|
||||
return new YesNoDialogViewModel(args.title, args.details);
|
||||
});
|
||||
|
||||
components.register('yesnomutedialog', function(args) {
|
||||
return new YesNoMuteDialogViewModel(args.title, args.details);
|
||||
});
|
||||
|
||||
components.register('TooManyFilesDialogViewModel', function(args) {
|
||||
return new TooManyFilesDialogViewModel(args.title, args.details);
|
||||
});
|
||||
|
||||
function DialogViewModel(title) {
|
||||
this.closed = new signals.Signal();
|
||||
this.title = ko.observable(title);
|
||||
this.taDialogName = ko.observable('');
|
||||
}
|
||||
DialogViewModel.prototype.setCloser = function(closer) {
|
||||
this.close = closer;
|
||||
}
|
||||
DialogViewModel.prototype.onclose = function() {
|
||||
this.closed.dispatch();
|
||||
}
|
||||
|
||||
function FormDialogViewModel(title) {
|
||||
DialogViewModel.call(this, title);
|
||||
this.items = ko.observable([]);
|
||||
this.isSubmitted = ko.observable(false);
|
||||
this.showCancel = ko.observable(true);
|
||||
}
|
||||
inherits(FormDialogViewModel, DialogViewModel);
|
||||
FormDialogViewModel.prototype.template = 'formDialog';
|
||||
FormDialogViewModel.prototype.submit = function() {
|
||||
this.isSubmitted(true);
|
||||
this.close();
|
||||
}
|
||||
|
||||
|
||||
function CredentialsDialogViewModel() {
|
||||
FormDialogViewModel.call(this);
|
||||
this.title('Remote requires authentication');
|
||||
this.taDialogName('credentials-dialog');
|
||||
this.showCancel(false);
|
||||
this.username = ko.observable();
|
||||
this.password = ko.observable();
|
||||
this.items([
|
||||
{ name: 'Username', value: this.username, placeholder: 'Username', type: 'text', autofocus: true, taName: 'username' },
|
||||
{ name: 'Password', value: this.password, placeholder: 'Password', type: 'password', autofocus: false, taName: 'password' }
|
||||
]);
|
||||
}
|
||||
inherits(CredentialsDialogViewModel, FormDialogViewModel);
|
||||
|
||||
|
||||
function AddRemoteDialogViewModel() {
|
||||
FormDialogViewModel.call(this);
|
||||
this.title('Add new remote');
|
||||
this.taDialogName('add-remote');
|
||||
this.name = ko.observable();
|
||||
this.url = ko.observable();
|
||||
this.items([
|
||||
{ name: 'Name', value: this.name, placeholder: 'Name', type: 'text', autofocus: true, taName: 'name' },
|
||||
{ name: 'Url', value: this.url, placeholder: 'Url', type: 'text', autofocus: false, taName: 'url' }
|
||||
]);
|
||||
}
|
||||
inherits(AddRemoteDialogViewModel, FormDialogViewModel);
|
||||
|
||||
function AddSubmoduleDialogViewModel() {
|
||||
FormDialogViewModel.call(this);
|
||||
this.title('Add new submodule');
|
||||
this.taDialogName('add-submodule');
|
||||
this.path = ko.observable();
|
||||
this.url = ko.observable();
|
||||
this.items([
|
||||
{ name: 'Path', value: this.path, placeholder: 'Path', type: 'text', autofocus: true, taName: 'path' },
|
||||
{ name: 'Url', value: this.url, placeholder: 'Url', type: 'text', autofocus: false, taName: 'url' }
|
||||
]);
|
||||
}
|
||||
inherits(AddSubmoduleDialogViewModel, FormDialogViewModel);
|
||||
|
||||
function PromptDialogViewModel(title, details) {
|
||||
DialogViewModel.call(this, title);
|
||||
this.alternatives = ko.observable();
|
||||
this.details = ko.observable(details);
|
||||
}
|
||||
inherits(PromptDialogViewModel, DialogViewModel);
|
||||
PromptDialogViewModel.prototype.template = 'prompt';
|
||||
|
||||
function YesNoDialogViewModel(title, details) {
|
||||
PromptDialogViewModel.call(this, title, details);
|
||||
var self = this;
|
||||
this.taDialogName('yes-no-dialog');
|
||||
this.result = ko.observable(false);
|
||||
this.alternatives([
|
||||
{ label: 'Yes', primary: true, taId: 'yes', click: function() { self.result(true); self.close(); } },
|
||||
{ label: 'No', primary: false, taId: 'no', click: function() { self.result(false); self.close(); } },
|
||||
]);
|
||||
}
|
||||
inherits(YesNoDialogViewModel, PromptDialogViewModel);
|
||||
|
||||
function YesNoMuteDialogViewModel(title, details) {
|
||||
PromptDialogViewModel.call(this, title, details);
|
||||
var self = this;
|
||||
this.taDialogName('yes-no-mute-dialog');
|
||||
this.result = ko.observable(false);
|
||||
this.alternatives([
|
||||
{ label: 'Yes', primary: true, taId: 'yes', click: function() { self.result(true); self.close(); } },
|
||||
{ label: 'Yes and mute for awhile', primary: false, taId: 'mute', click: function() { self.result("mute"); self.close(); } },
|
||||
{ label: 'No', primary: false, taId: 'no', click: function() { self.result(false); self.close(); } }
|
||||
]);
|
||||
}
|
||||
inherits(YesNoMuteDialogViewModel, PromptDialogViewModel);
|
||||
|
||||
function TooManyFilesDialogViewModel(title, details) {
|
||||
PromptDialogViewModel.call(this, title, details);
|
||||
var self = this;
|
||||
this.taDialogName('yes-no-dialog');
|
||||
this.result = ko.observable(false);
|
||||
this.alternatives([
|
||||
{ label: "Don't load", primary: true, taId: 'noLoad', click: function() { self.result(false); self.close(); } },
|
||||
{ label: 'Load anyway', primary: false, taId: 'loadAnyway', click: function() { self.result(true); self.close(); } },
|
||||
]);
|
||||
}
|
||||
inherits(TooManyFilesDialogViewModel, PromptDialogViewModel);
|
26
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/dialogs/formDialog.html
generated
vendored
Normal file
26
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/dialogs/formDialog.html
generated
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
|
||||
<div class="modal fade" data-bind="modal: { onclose: onclose, closer: setCloser }, attr: { 'data-ta-container': taDialogName }">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title" data-bind="text: title"></h4>
|
||||
</div>
|
||||
<!-- Autocomplete is off here because of https://github.com/FredrikNoren/ungit/issues/363 -->
|
||||
<form class="form-horizontal" data-bind="submit: submit" autocomplete="off">
|
||||
<div class="modal-body" data-bind="foreach: items">
|
||||
<div class="form-group">
|
||||
<label data-bind="text: name, attr: { for: name }" class="col-lg-2 control-label"></label>
|
||||
<div class="col-lg-10">
|
||||
<input class="form-control" id="inputName"
|
||||
data-bind="value: value, attr: { id: name, placeholder: placeholder, type: type, autofocus: autofocus, 'data-ta-input': taName }">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<input type="submit" class="btn btn-primary" value="Submit" data-ta-clickable="submit">
|
||||
<button class="btn btn-default" data-bind="click: close, visible: showCancel">Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
18
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/dialogs/prompt.html
generated
vendored
Normal file
18
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/dialogs/prompt.html
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
|
||||
<div class="modal fade" data-bind="modal: { onclose: onclose, closer: setCloser }, attr: { 'data-ta-container': taDialogName }">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title" data-bind="text: title"></h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p data-bind="text: details"></p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<!-- ko foreach: alternatives -->
|
||||
<button type="button" class="btn btn-default" data-bind="css: { 'btn-primary': primary }, text: label, click: click, attr: { 'data-ta-clickable': taId }"></button>
|
||||
<!-- /ko -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
9
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/dialogs/ungit-plugin.json
generated
vendored
Normal file
9
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/dialogs/ungit-plugin.json
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"exports": {
|
||||
"knockoutTemplates": {
|
||||
"formDialog": "formDialog.html",
|
||||
"prompt": "prompt.html"
|
||||
},
|
||||
"javascript": "dialogs.bundle.js"
|
||||
}
|
||||
}
|
65
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/gitErrors/gitErrors.bundle.js
generated
vendored
Normal file
65
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/gitErrors/gitErrors.bundle.js
generated
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
|
||||
var ko = require('knockout');
|
||||
var components = require('ungit-components');
|
||||
var programEvents = require('ungit-program-events');
|
||||
var navigation = require('ungit-navigation');
|
||||
|
||||
components.register('gitErrors', function(args) {
|
||||
return new GitErrorsViewModel(args.server, args.repoPath);
|
||||
});
|
||||
|
||||
var GitErrorsViewModel = function(server, repoPath) {
|
||||
var self = this;
|
||||
this.server = server;
|
||||
this.repoPath = repoPath;
|
||||
this.gitErrors = ko.observableArray();
|
||||
}
|
||||
GitErrorsViewModel.prototype.updateNode = function(parentElement) {
|
||||
ko.renderTemplate('gitErrors', this, {}, parentElement);
|
||||
}
|
||||
GitErrorsViewModel.prototype.onProgramEvent = function(event) {
|
||||
if (event.event == 'git-error') this._handleGitError(event);
|
||||
}
|
||||
GitErrorsViewModel.prototype._handleGitError = function(event) {
|
||||
if (event.data.repoPath != this.repoPath()) return;
|
||||
this.gitErrors.push(new GitErrorViewModel(this, this.server, event.data));
|
||||
}
|
||||
|
||||
function GitErrorViewModel(gitErrors, server, data) {
|
||||
var self = this;
|
||||
this.gitErrors = gitErrors;
|
||||
this.server = server;
|
||||
this.tip = data.tip;
|
||||
this.command = data.command;
|
||||
this.error = data.error;
|
||||
this.stdout = data.stdout;
|
||||
this.stderr = data.stderr;
|
||||
this.showEnableBugtracking = ko.observable(false);
|
||||
this.bugReportWasSent = ungit.config.bugtracking;
|
||||
|
||||
if (!data.shouldSkipReport && !ungit.config.bugtracking) {
|
||||
this.server.get('/userconfig', undefined, function(err, userConfig) {
|
||||
if (err) return;
|
||||
self.showEnableBugtracking(!userConfig.bugtracking);
|
||||
});
|
||||
}
|
||||
}
|
||||
GitErrorViewModel.prototype.dismiss = function() {
|
||||
this.gitErrors.gitErrors.remove(this);
|
||||
}
|
||||
GitErrorViewModel.prototype.enableBugtrackingAndStatistics = function() {
|
||||
var self = this;
|
||||
this.server.get('/userconfig', undefined, function(err, userConfig) {
|
||||
if (err) return;
|
||||
userConfig.bugtracking = true;
|
||||
userConfig.sendUsageStatistics = true;
|
||||
self.server.post('/userconfig', userConfig, function(err) {
|
||||
if (err) return;
|
||||
self.showEnableBugtracking(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
},{"knockout":"knockout","ungit-components":"ungit-components","ungit-navigation":"ungit-navigation","ungit-program-events":"ungit-program-events"}]},{},[1])
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJjb21wb25lbnRzL2dpdEVycm9ycy9naXRFcnJvcnMuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIlxudmFyIGtvID0gcmVxdWlyZSgna25vY2tvdXQnKTtcbnZhciBjb21wb25lbnRzID0gcmVxdWlyZSgndW5naXQtY29tcG9uZW50cycpO1xudmFyIHByb2dyYW1FdmVudHMgPSByZXF1aXJlKCd1bmdpdC1wcm9ncmFtLWV2ZW50cycpO1xudmFyIG5hdmlnYXRpb24gPSByZXF1aXJlKCd1bmdpdC1uYXZpZ2F0aW9uJyk7XG5cbmNvbXBvbmVudHMucmVnaXN0ZXIoJ2dpdEVycm9ycycsIGZ1bmN0aW9uKGFyZ3MpIHtcbiAgcmV0dXJuIG5ldyBHaXRFcnJvcnNWaWV3TW9kZWwoYXJncy5zZXJ2ZXIsIGFyZ3MucmVwb1BhdGgpO1xufSk7XG5cbnZhciBHaXRFcnJvcnNWaWV3TW9kZWwgPSBmdW5jdGlvbihzZXJ2ZXIsIHJlcG9QYXRoKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdGhpcy5zZXJ2ZXIgPSBzZXJ2ZXI7XG4gIHRoaXMucmVwb1BhdGggPSByZXBvUGF0aDtcbiAgdGhpcy5naXRFcnJvcnMgPSBrby5vYnNlcnZhYmxlQXJyYXkoKTtcbn1cbkdpdEVycm9yc1ZpZXdNb2RlbC5wcm90b3R5cGUudXBkYXRlTm9kZSA9IGZ1bmN0aW9uKHBhcmVudEVsZW1lbnQpIHtcbiAga28ucmVuZGVyVGVtcGxhdGUoJ2dpdEVycm9ycycsIHRoaXMsIHt9LCBwYXJlbnRFbGVtZW50KTtcbn1cbkdpdEVycm9yc1ZpZXdNb2RlbC5wcm90b3R5cGUub25Qcm9ncmFtRXZlbnQgPSBmdW5jdGlvbihldmVudCkge1xuICBpZiAoZXZlbnQuZXZlbnQgPT0gJ2dpdC1lcnJvcicpIHRoaXMuX2hhbmRsZUdpdEVycm9yKGV2ZW50KTtcbn1cbkdpdEVycm9yc1ZpZXdNb2RlbC5wcm90b3R5cGUuX2hhbmRsZUdpdEVycm9yID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgaWYgKGV2ZW50LmRhdGEucmVwb1BhdGggIT0gdGhpcy5yZXBvUGF0aCgpKSByZXR1cm47XG4gIHRoaXMuZ2l0RXJyb3JzLnB1c2gobmV3IEdpdEVycm9yVmlld01vZGVsKHRoaXMsIHRoaXMuc2VydmVyLCBldmVudC5kYXRhKSk7XG59XG5cbmZ1bmN0aW9uIEdpdEVycm9yVmlld01vZGVsKGdpdEVycm9ycywgc2VydmVyLCBkYXRhKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdGhpcy5naXRFcnJvcnMgPSBnaXRFcnJvcnM7XG4gIHRoaXMuc2VydmVyID0gc2VydmVyO1xuICB0aGlzLnRpcCA9IGRhdGEudGlwO1xuICB0aGlzLmNvbW1hbmQgPSBkYXRhLmNvbW1hbmQ7XG4gIHRoaXMuZXJyb3IgPSBkYXRhLmVycm9yO1xuICB0aGlzLnN0ZG91dCA9IGRhdGEuc3Rkb3V0O1xuICB0aGlzLnN0ZGVyciA9IGRhdGEuc3RkZXJyO1xuICB0aGlzLnNob3dFbmFibGVCdWd0cmFja2luZyA9IGtvLm9ic2VydmFibGUoZmFsc2UpO1xuICB0aGlzLmJ1Z1JlcG9ydFdhc1NlbnQgPSB1bmdpdC5jb25maWcuYnVndHJhY2tpbmc7XG5cbiAgaWYgKCFkYXRhLnNob3VsZFNraXBSZXBvcnQgJiYgIXVuZ2l0LmNvbmZpZy5idWd0cmFja2luZykge1xuICAgIHRoaXMuc2VydmVyLmdldCgnL3VzZXJjb25maWcnLCB1bmRlZmluZWQsIGZ1bmN0aW9uKGVyciwgdXNlckNvbmZpZykge1xuICAgICAgaWYgKGVycikgcmV0dXJuO1xuICAgICAgc2VsZi5zaG93RW5hYmxlQnVndHJhY2tpbmcoIXVzZXJDb25maWcuYnVndHJhY2tpbmcpO1xuICAgIH0pO1xuICB9XG59XG5HaXRFcnJvclZpZXdNb2RlbC5wcm90b3R5cGUuZGlzbWlzcyA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLmdpdEVycm9ycy5naXRFcnJvcnMucmVtb3ZlKHRoaXMpO1xufVxuR2l0RXJyb3JWaWV3TW9kZWwucHJvdG90eXBlLmVuYWJsZUJ1Z3RyYWNraW5nQW5kU3RhdGlzdGljcyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuc2VydmVyLmdldCgnL3VzZXJjb25maWcnLCB1bmRlZmluZWQsIGZ1bmN0aW9uKGVyciwgdXNlckNvbmZpZykge1xuICAgIGlmIChlcnIpIHJldHVybjtcbiAgICB1c2VyQ29uZmlnLmJ1Z3RyYWNraW5nID0gdHJ1ZTtcbiAgICB1c2VyQ29uZmlnLnNlbmRVc2FnZVN0YXRpc3RpY3MgPSB0cnVlO1xuICAgIHNlbGYuc2VydmVyLnBvc3QoJy91c2VyY29uZmlnJywgdXNlckNvbmZpZywgZnVuY3Rpb24oZXJyKSB7XG4gICAgICBpZiAoZXJyKSByZXR1cm47XG4gICAgICBzZWxmLnNob3dFbmFibGVCdWd0cmFja2luZyhmYWxzZSk7XG4gICAgfSk7XG4gIH0pO1xufVxuIl19
|
22
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/gitErrors/gitErrors.html
generated
vendored
Normal file
22
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/gitErrors/gitErrors.html
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
<!-- ko foreach: gitErrors -->
|
||||
<div class="alert alert-danger" data-ta-container="git-error-container">
|
||||
<button type="button" class="close" data-bind="click: dismiss">×</button>
|
||||
<h3><span class="glyphicon glyphicon-warning-sign"></span> Unhandled git error!</h3>
|
||||
<p>
|
||||
Ungit tried to run a git command that resulted in an unhandled error. <span data-bind="visible: bugReportWasSent">An automatic bug report was sent.</span>
|
||||
</p>
|
||||
<p data-bind="visible: tip, text: tip"></p>
|
||||
<p data-bind="visible: showEnableBugtracking">
|
||||
<button class="btn btn-primary" data-bind="click: enableBugtrackingAndStatistics">Enable bugtracking + usage statistics</button> to automatically report bugs, and/or <a href="https://github.com/FredrikNoren/ungit/issues" target="_blank">file an issue on the ungit issue tracker</a>.
|
||||
</p>
|
||||
<h4>Command</h4>
|
||||
<pre data-bind="text: command"></pre>
|
||||
<h4>Error</h4>
|
||||
<pre data-bind="text: error"></pre>
|
||||
<h4>Stderr</h4>
|
||||
<pre data-bind="text: stderr"></pre>
|
||||
<h4>Stdout</h4>
|
||||
<pre data-bind="text: stdout"></pre>
|
||||
</div>
|
||||
<!-- /ko -->
|
61
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/gitErrors/gitErrors.js
generated
vendored
Normal file
61
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/gitErrors/gitErrors.js
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
|
||||
var ko = require('knockout');
|
||||
var components = require('ungit-components');
|
||||
var programEvents = require('ungit-program-events');
|
||||
var navigation = require('ungit-navigation');
|
||||
|
||||
components.register('gitErrors', function(args) {
|
||||
return new GitErrorsViewModel(args.server, args.repoPath);
|
||||
});
|
||||
|
||||
var GitErrorsViewModel = function(server, repoPath) {
|
||||
var self = this;
|
||||
this.server = server;
|
||||
this.repoPath = repoPath;
|
||||
this.gitErrors = ko.observableArray();
|
||||
}
|
||||
GitErrorsViewModel.prototype.updateNode = function(parentElement) {
|
||||
ko.renderTemplate('gitErrors', this, {}, parentElement);
|
||||
}
|
||||
GitErrorsViewModel.prototype.onProgramEvent = function(event) {
|
||||
if (event.event == 'git-error') this._handleGitError(event);
|
||||
}
|
||||
GitErrorsViewModel.prototype._handleGitError = function(event) {
|
||||
if (event.data.repoPath != this.repoPath()) return;
|
||||
this.gitErrors.push(new GitErrorViewModel(this, this.server, event.data));
|
||||
}
|
||||
|
||||
function GitErrorViewModel(gitErrors, server, data) {
|
||||
var self = this;
|
||||
this.gitErrors = gitErrors;
|
||||
this.server = server;
|
||||
this.tip = data.tip;
|
||||
this.command = data.command;
|
||||
this.error = data.error;
|
||||
this.stdout = data.stdout;
|
||||
this.stderr = data.stderr;
|
||||
this.showEnableBugtracking = ko.observable(false);
|
||||
this.bugReportWasSent = ungit.config.bugtracking;
|
||||
|
||||
if (!data.shouldSkipReport && !ungit.config.bugtracking) {
|
||||
this.server.get('/userconfig', undefined, function(err, userConfig) {
|
||||
if (err) return;
|
||||
self.showEnableBugtracking(!userConfig.bugtracking);
|
||||
});
|
||||
}
|
||||
}
|
||||
GitErrorViewModel.prototype.dismiss = function() {
|
||||
this.gitErrors.gitErrors.remove(this);
|
||||
}
|
||||
GitErrorViewModel.prototype.enableBugtrackingAndStatistics = function() {
|
||||
var self = this;
|
||||
this.server.get('/userconfig', undefined, function(err, userConfig) {
|
||||
if (err) return;
|
||||
userConfig.bugtracking = true;
|
||||
userConfig.sendUsageStatistics = true;
|
||||
self.server.post('/userconfig', userConfig, function(err) {
|
||||
if (err) return;
|
||||
self.showEnableBugtracking(false);
|
||||
});
|
||||
});
|
||||
}
|
8
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/gitErrors/ungit-plugin.json
generated
vendored
Normal file
8
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/gitErrors/ungit-plugin.json
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"exports": {
|
||||
"knockoutTemplates": {
|
||||
"gitErrors": "gitErrors.html"
|
||||
},
|
||||
"javascript": "gitErrors.bundle.js"
|
||||
}
|
||||
}
|
22
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/animateable.js
generated
vendored
Normal file
22
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/animateable.js
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
var ko = require('knockout');
|
||||
require('mina');
|
||||
|
||||
module.exports = function(graph) {
|
||||
var self = this;
|
||||
this.element = ko.observable();
|
||||
this.previousGraph = undefined;
|
||||
this.element.subscribe(function(val) {
|
||||
if (val) self.animate(true);
|
||||
});
|
||||
this.animate = function(forceRefresh) {
|
||||
var currentGraph = this.getGraphAttr();
|
||||
// animate only when dom is valid and (attribute changed or force refresh due to dom change)
|
||||
if (this.element() && (forceRefresh || JSON.stringify(currentGraph) !== JSON.stringify(this.previousGraph))) {
|
||||
var now = Date.now();
|
||||
window.mina(this.previousGraph || currentGraph, currentGraph, now, now + 750, window.mina.time, function (val) {
|
||||
self.setGraphAttr(val);
|
||||
}, window.mina.elastic);
|
||||
this.previousGraph = currentGraph;
|
||||
}
|
||||
}
|
||||
};
|
26
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/edge.js
generated
vendored
Normal file
26
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/edge.js
generated
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
var ko = require('knockout');
|
||||
var Animateable = require('./animateable');
|
||||
|
||||
var EdgeViewModel = function(graph, nodeAsha1, nodeBsha1) {
|
||||
var self = this;
|
||||
Animateable.call(this);
|
||||
this.nodeA = graph.getNode(nodeAsha1);
|
||||
this.nodeB = graph.getNode(nodeBsha1);
|
||||
this.getGraphAttr = ko.computed(function() {
|
||||
if (self.nodeB.isInited && self.nodeB.cx() && self.nodeB.cy()) {
|
||||
return [self.nodeA.cx(), self.nodeA.cy(), self.nodeA.cx(), self.nodeA.cy(),
|
||||
self.nodeB.cx(), self.nodeB.cy(), self.nodeB.cx(), self.nodeB.cy()];
|
||||
} else if (graph.graphHeight()) {
|
||||
return [self.nodeA.cx(), self.nodeA.cy(), self.nodeA.cx(), self.nodeA.cy(),
|
||||
self.nodeA.cx(), graph.graphHeight(), self.nodeA.cx(), graph.graphHeight()];
|
||||
} else {
|
||||
return [self.nodeA.cx(), self.nodeA.cy(), self.nodeA.cx(), self.nodeA.cy(),
|
||||
self.nodeA.cx(), self.nodeA.cy(), self.nodeA.cx(), self.nodeA.cy()];
|
||||
}
|
||||
});
|
||||
this.getGraphAttr.subscribe(this.animate.bind(this));
|
||||
}
|
||||
EdgeViewModel.prototype.setGraphAttr = function(val) {
|
||||
this.element().setAttribute('d', 'M' + val.slice(0,4).join(',') + 'L' + val.slice(4,8).join(','));
|
||||
}
|
||||
module.exports = EdgeViewModel;
|
353
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/git-graph-actions.js
generated
vendored
Normal file
353
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/git-graph-actions.js
generated
vendored
Normal file
|
@ -0,0 +1,353 @@
|
|||
|
||||
var ko = require('knockout');
|
||||
var inherits = require('util').inherits;
|
||||
var components = require('ungit-components');
|
||||
var RefViewModel = require('./git-ref.js');
|
||||
var HoverActions = require('./hover-actions');
|
||||
var RebaseViewModel = HoverActions.RebaseViewModel;
|
||||
var MergeViewModel = HoverActions.MergeViewModel;
|
||||
var ResetViewModel = HoverActions.ResetViewModel;
|
||||
var PushViewModel = HoverActions.PushViewModel;
|
||||
var programEvents = require('ungit-program-events');
|
||||
|
||||
var GraphActions = {};
|
||||
module.exports = GraphActions;
|
||||
|
||||
GraphActions.ActionBase = function(graph) {
|
||||
var self = this;
|
||||
this.graph = graph;
|
||||
this.server = graph.server;
|
||||
this.performProgressBar = components.create('progressBar', {
|
||||
predictionMemoryKey: 'action-' + this.style + '-' + graph.repoPath(),
|
||||
fallbackPredictedTimeMs: 1000,
|
||||
temporary: true
|
||||
});
|
||||
|
||||
this.isHighlighted = ko.computed(function() {
|
||||
return !graph.hoverGraphAction() || graph.hoverGraphAction() == self;
|
||||
});
|
||||
this.cssClasses = ko.computed(function() {
|
||||
var c = self.style;
|
||||
if (!self.isHighlighted()) c += ' dimmed';
|
||||
return c;
|
||||
})
|
||||
}
|
||||
GraphActions.ActionBase.prototype.icon = null;
|
||||
GraphActions.ActionBase.prototype.doPerform = function() {
|
||||
var self = this;
|
||||
this.graph.hoverGraphAction(null);
|
||||
self.performProgressBar.start();
|
||||
this.perform(function() {
|
||||
self.performProgressBar.stop();
|
||||
});
|
||||
}
|
||||
GraphActions.ActionBase.prototype.dragEnter = function() {
|
||||
if (!this.visible()) return;
|
||||
this.graph.hoverGraphAction(this);
|
||||
}
|
||||
GraphActions.ActionBase.prototype.dragLeave = function() {
|
||||
if (!this.visible()) return;
|
||||
this.graph.hoverGraphAction(null);
|
||||
}
|
||||
GraphActions.ActionBase.prototype.mouseover = function() {
|
||||
this.graph.hoverGraphAction(this);
|
||||
}
|
||||
GraphActions.ActionBase.prototype.mouseout = function() {
|
||||
this.graph.hoverGraphAction(null);
|
||||
}
|
||||
|
||||
GraphActions.Move = function(graph, node) {
|
||||
var self = this;
|
||||
GraphActions.ActionBase.call(this, graph);
|
||||
this.node = node;
|
||||
this.visible = ko.computed(function() {
|
||||
if (self.performProgressBar.running()) return true;
|
||||
return self.graph.currentActionContext() instanceof RefViewModel &&
|
||||
self.graph.currentActionContext().node() != self.node;
|
||||
});
|
||||
}
|
||||
inherits(GraphActions.Move, GraphActions.ActionBase);
|
||||
GraphActions.Move.prototype.text = 'Move';
|
||||
GraphActions.Move.prototype.style = 'move';
|
||||
GraphActions.Move.prototype.icon = 'glyphicon glyphicon-move';
|
||||
GraphActions.Move.prototype.perform = function(callback) {
|
||||
this.graph.currentActionContext().moveTo(this.node.sha1, callback);
|
||||
}
|
||||
|
||||
GraphActions.Reset = function(graph, node) {
|
||||
var self = this;
|
||||
GraphActions.ActionBase.call(this, graph);
|
||||
this.node = node;
|
||||
this.visible = ko.computed(function() {
|
||||
if (self.performProgressBar.running()) return true;
|
||||
if (!(self.graph.currentActionContext() instanceof RefViewModel)) return false;
|
||||
var context = self.graph.currentActionContext();
|
||||
if (context.node() != self.node) return false;
|
||||
var remoteRef = context.getRemoteRef(self.graph.currentRemote());
|
||||
return remoteRef &&
|
||||
remoteRef.node() != context.node() &&
|
||||
remoteRef.node().date < context.node().date;
|
||||
});
|
||||
}
|
||||
inherits(GraphActions.Reset, GraphActions.ActionBase);
|
||||
GraphActions.Reset.prototype.text = 'Reset';
|
||||
GraphActions.Reset.prototype.style = 'reset';
|
||||
GraphActions.Reset.prototype.icon = 'glyphicon glyphicon-trash';
|
||||
GraphActions.Reset.prototype.createHoverGraphic = function() {
|
||||
var context = this.graph.currentActionContext();
|
||||
if (!context) return null;
|
||||
var remoteRef = context.getRemoteRef(this.graph.currentRemote());
|
||||
var nodes = context.node().getPathToCommonAncestor(remoteRef.node()).slice(0, -1);
|
||||
return new ResetViewModel(nodes);
|
||||
}
|
||||
GraphActions.Reset.prototype.perform = function(callback) {
|
||||
var self = this;
|
||||
var context = this.graph.currentActionContext();
|
||||
var remoteRef = context.getRemoteRef(self.graph.currentRemote());
|
||||
var diag = components.create('yesnodialog', { title: 'Are you sure?', details: 'Resetting to ref: ' + remoteRef.name + ' cannot be undone with ungit.'});
|
||||
diag.closed.add(function() {
|
||||
if (diag.result()) {
|
||||
self.server.post('/reset', { path: self.graph.repoPath(), to: remoteRef.name, mode: 'hard' }, function() {
|
||||
context.node(remoteRef.node());
|
||||
callback();
|
||||
});
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
programEvents.dispatch({ event: 'request-show-dialog', dialog: diag });
|
||||
}
|
||||
|
||||
GraphActions.Rebase = function(graph, node) {
|
||||
var self = this;
|
||||
GraphActions.ActionBase.call(this, graph);
|
||||
this.node = node;
|
||||
this.visible = ko.computed(function() {
|
||||
if (self.performProgressBar.running()) return true;
|
||||
return self.graph.currentActionContext() instanceof RefViewModel &&
|
||||
(!ungit.config.showRebaseAndMergeOnlyOnRefs || self.node.refs().length > 0) &&
|
||||
self.graph.currentActionContext().current() &&
|
||||
self.graph.currentActionContext().node() != self.node;
|
||||
});
|
||||
}
|
||||
inherits(GraphActions.Rebase, GraphActions.ActionBase);
|
||||
GraphActions.Rebase.prototype.text = 'Rebase';
|
||||
GraphActions.Rebase.prototype.style = 'rebase';
|
||||
GraphActions.Rebase.prototype.icon = 'octicon octicon-repo-forked flip';
|
||||
GraphActions.Rebase.prototype.createHoverGraphic = function() {
|
||||
var onto = this.graph.currentActionContext();
|
||||
if (!onto) return;
|
||||
if (onto instanceof RefViewModel) onto = onto.node();
|
||||
var path = onto.getPathToCommonAncestor(this.node);
|
||||
return new RebaseViewModel(this.node, path);
|
||||
}
|
||||
GraphActions.Rebase.prototype.perform = function(callback) {
|
||||
this.server.post('/rebase', { path: this.graph.repoPath(), onto: this.node.sha1 }, function(err) {
|
||||
callback();
|
||||
if (err && err.errorCode == 'merge-failed') return true;
|
||||
});
|
||||
}
|
||||
|
||||
GraphActions.Merge = function(graph, node) {
|
||||
var self = this;
|
||||
GraphActions.ActionBase.call(this, graph);
|
||||
this.node = node;
|
||||
this.visible = ko.computed(function() {
|
||||
if (self.performProgressBar.running()) return true;
|
||||
if (!self.graph.checkedOutRef() || !self.graph.checkedOutRef().node()) return false;
|
||||
return self.graph.currentActionContext() instanceof RefViewModel &&
|
||||
!self.graph.currentActionContext().current() &&
|
||||
self.graph.checkedOutRef().node() == self.node;
|
||||
});
|
||||
}
|
||||
inherits(GraphActions.Merge, GraphActions.ActionBase);
|
||||
GraphActions.Merge.prototype.text = 'Merge';
|
||||
GraphActions.Merge.prototype.style = 'merge';
|
||||
GraphActions.Merge.prototype.icon = 'octicon octicon-git-merge';
|
||||
GraphActions.Merge.prototype.createHoverGraphic = function() {
|
||||
var node = this.graph.currentActionContext();
|
||||
if (!node) return null;
|
||||
if (node instanceof RefViewModel) node = node.node();
|
||||
return new MergeViewModel(this.graph, this.node, node);
|
||||
}
|
||||
GraphActions.Merge.prototype.perform = function(callback) {
|
||||
this.server.post('/merge', { path: this.graph.repoPath(), with: this.graph.currentActionContext().localRefName }, function(err) {
|
||||
callback();
|
||||
if (err && err.errorCode == 'merge-failed') return true;
|
||||
});
|
||||
}
|
||||
|
||||
GraphActions.Push = function(graph, node) {
|
||||
var self = this;
|
||||
GraphActions.ActionBase.call(this, graph);
|
||||
this.node = node;
|
||||
this.visible = ko.computed(function() {
|
||||
if (self.performProgressBar.running()) return true;
|
||||
return self.graph.currentActionContext() instanceof RefViewModel &&
|
||||
self.graph.currentActionContext().node() == self.node &&
|
||||
self.graph.currentActionContext().canBePushed(self.graph.currentRemote());
|
||||
});
|
||||
}
|
||||
inherits(GraphActions.Push, GraphActions.ActionBase);
|
||||
GraphActions.Push.prototype.text = 'Push';
|
||||
GraphActions.Push.prototype.style = 'push';
|
||||
GraphActions.Push.prototype.icon = 'octicon octicon-cloud-upload';
|
||||
GraphActions.Push.prototype.createHoverGraphic = function() {
|
||||
var context = this.graph.currentActionContext();
|
||||
if (!context) return null;
|
||||
var remoteRef = context.getRemoteRef(this.graph.currentRemote());
|
||||
if (!remoteRef) return null;
|
||||
return new PushViewModel(remoteRef.node(), context.node());
|
||||
}
|
||||
GraphActions.Push.prototype.perform = function(callback) {
|
||||
var self = this;
|
||||
var ref = this.graph.currentActionContext();
|
||||
var remoteRef = ref.getRemoteRef(this.graph.currentRemote());
|
||||
|
||||
if (remoteRef) {
|
||||
remoteRef.moveTo(ref.node().sha1, callback);
|
||||
} else ref.createRemoteRef(function(err) {
|
||||
if (!err && self.graph.HEAD().name == ref.name) {
|
||||
self.grah.HEADref().node(ref.node());
|
||||
}
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
GraphActions.Checkout = function(graph, node) {
|
||||
var self = this;
|
||||
GraphActions.ActionBase.call(this, graph);
|
||||
this.node = node;
|
||||
this.visible = ko.computed(function() {
|
||||
if (self.performProgressBar.running()) return true;
|
||||
if (self.graph.currentActionContext() instanceof RefViewModel)
|
||||
return self.graph.currentActionContext().node() == self.node &&
|
||||
!self.graph.currentActionContext().current();
|
||||
return ungit.config.allowCheckoutNodes &&
|
||||
self.graph.currentActionContext() == self.node;
|
||||
});
|
||||
}
|
||||
inherits(GraphActions.Checkout, GraphActions.ActionBase);
|
||||
GraphActions.Checkout.prototype.text = 'Checkout';
|
||||
GraphActions.Checkout.prototype.style = 'checkout';
|
||||
GraphActions.Checkout.prototype.icon = 'octicon octicon-desktop-download';
|
||||
GraphActions.Checkout.prototype.perform = function(callback) {
|
||||
var self = this;
|
||||
var context = this.graph.currentActionContext();
|
||||
var refName = context instanceof RefViewModel ? context.refName : context.sha1;
|
||||
this.server.post('/checkout', { path: this.graph.repoPath(), name: refName }, function(err) {
|
||||
if (err && err.errorCode != 'merge-failed') {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
if (context instanceof RefViewModel && context.isRemoteBranch) {
|
||||
self.server.post('/reset', { path: self.graph.repoPath(), to: context.name, mode: 'hard' }, function(err, res) {
|
||||
self.graph.HEADref().node(context instanceof RefViewModel ? context.node() : context);
|
||||
callback();
|
||||
return err && err.errorCode != 'merge-failed' ? undefined : true;
|
||||
});
|
||||
} else {
|
||||
self.graph.HEADref().node(context instanceof RefViewModel ? context.node() : context);
|
||||
callback();
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
GraphActions.Delete = function(graph, node) {
|
||||
var self = this;
|
||||
GraphActions.ActionBase.call(this, graph);
|
||||
this.node = node;
|
||||
this.visible = ko.computed(function() {
|
||||
if (self.performProgressBar.running()) return true;
|
||||
return self.graph.currentActionContext() instanceof RefViewModel &&
|
||||
self.graph.currentActionContext().node() == self.node &&
|
||||
!self.graph.currentActionContext().current();
|
||||
});
|
||||
}
|
||||
inherits(GraphActions.Delete, GraphActions.ActionBase);
|
||||
GraphActions.Delete.prototype.text = 'Delete';
|
||||
GraphActions.Delete.prototype.style = 'delete';
|
||||
GraphActions.Delete.prototype.icon = 'glyphicon glyphicon-remove';
|
||||
GraphActions.Delete.prototype.perform = function(callback) {
|
||||
var context = this.graph.currentActionContext();
|
||||
var name = context.isRemoteBranch ? "remote " + context.localRefName : context.localRefName;
|
||||
var diag = components.create('yesnodialog', { title: 'Are you sure?', details: 'Deleting ' + name + ' branch or tag cannot be undone with ungit.'});
|
||||
diag.closed.add(function() {
|
||||
if (diag.result()) {
|
||||
context.remove(callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
programEvents.dispatch({ event: 'request-show-dialog', dialog: diag });
|
||||
}
|
||||
|
||||
GraphActions.CherryPick = function(graph, node) {
|
||||
var self = this;
|
||||
GraphActions.ActionBase.call(this, graph);
|
||||
this.node = node;
|
||||
this.visible = ko.computed(function() {
|
||||
if (self.performProgressBar.running()) return true;
|
||||
var context = self.graph.currentActionContext();
|
||||
return context === self.node && self.graph.HEAD() && context.sha1 !== self.graph.HEAD().sha1
|
||||
});
|
||||
}
|
||||
inherits(GraphActions.CherryPick, GraphActions.ActionBase);
|
||||
GraphActions.CherryPick.prototype.text = 'Cherry pick';
|
||||
GraphActions.CherryPick.prototype.style = 'cherry-pick';
|
||||
GraphActions.CherryPick.prototype.icon = 'octicon octicon-circuit-board';
|
||||
GraphActions.CherryPick.prototype.perform = function(callback) {
|
||||
var self = this;
|
||||
this.server.post('/cherrypick', { path: this.graph.repoPath(), name: this.node.sha1 }, function(err) {
|
||||
callback();
|
||||
if (err && err.errorCode == 'merge-failed') return true;
|
||||
});
|
||||
}
|
||||
|
||||
GraphActions.Uncommit = function(graph, node) {
|
||||
var self = this;
|
||||
GraphActions.ActionBase.call(this, graph);
|
||||
this.node = node;
|
||||
this.visible = ko.computed(function() {
|
||||
if (self.performProgressBar.running()) return true;
|
||||
return self.graph.currentActionContext() == self.node &&
|
||||
self.graph.HEAD() == self.node;
|
||||
});
|
||||
}
|
||||
inherits(GraphActions.Uncommit, GraphActions.ActionBase);
|
||||
GraphActions.Uncommit.prototype.text = 'Uncommit';
|
||||
GraphActions.Uncommit.prototype.style = 'uncommit';
|
||||
GraphActions.Uncommit.prototype.icon = 'octicon octicon-zap';
|
||||
GraphActions.Uncommit.prototype.perform = function(callback) {
|
||||
var self = this;
|
||||
this.server.postPromise('/reset', { path: this.graph.repoPath(), to: 'HEAD^', mode: 'mixed' })
|
||||
.then(function() {
|
||||
var targetNode = self.node.belowNode;
|
||||
while (targetNode && !targetNode.ancestorOfHEAD()) {
|
||||
targetNode = targetNode.belowNode;
|
||||
}
|
||||
self.graph.HEADref().node(targetNode ? targetNode : null);
|
||||
self.graph.checkedOutRef().node(targetNode ? targetNode : null);
|
||||
}).finally(callback);
|
||||
}
|
||||
|
||||
GraphActions.Revert = function(graph, node) {
|
||||
var self = this;
|
||||
GraphActions.ActionBase.call(this, graph);
|
||||
this.node = node;
|
||||
this.visible = ko.computed(function() {
|
||||
if (self.performProgressBar.running()) return true;
|
||||
return self.graph.currentActionContext() == self.node;
|
||||
});
|
||||
}
|
||||
inherits(GraphActions.Revert, GraphActions.ActionBase);
|
||||
GraphActions.Revert.prototype.text = 'Revert';
|
||||
GraphActions.Revert.prototype.style = 'revert';
|
||||
GraphActions.Revert.prototype.icon = 'octicon octicon-history';
|
||||
GraphActions.Revert.prototype.perform = function(callback) {
|
||||
var self = this;
|
||||
this.server.postPromise('/revert', { path: this.graph.repoPath(), commit: this.node.sha1 })
|
||||
.finally(callback);
|
||||
}
|
258
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/git-node.js
generated
vendored
Normal file
258
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/git-node.js
generated
vendored
Normal file
|
@ -0,0 +1,258 @@
|
|||
var ko = require('knockout');
|
||||
var components = require('ungit-components');
|
||||
var Selectable = require('./selectable');
|
||||
var Animateable = require('./animateable');
|
||||
var programEvents = require('ungit-program-events');
|
||||
var GraphActions = require('./git-graph-actions');
|
||||
|
||||
var GitNodeViewModel = function(graph, sha1) {
|
||||
var self = this;
|
||||
Selectable.call(this, graph);
|
||||
Animateable.call(this);
|
||||
this.graph = graph;
|
||||
this.sha1 = sha1;
|
||||
this.isInited = false;
|
||||
this.title = undefined;
|
||||
this.parents = ko.observableArray();
|
||||
this.commitTime = undefined; // commit time in string
|
||||
this.date = undefined; // commit time in numeric format for sort
|
||||
this.color = ko.observable();
|
||||
this.ideologicalBranch = ko.observable();
|
||||
this.remoteTags = ko.observableArray();
|
||||
this.branchesAndLocalTags = ko.observableArray();
|
||||
|
||||
this.refs = ko.computed(function() {
|
||||
var rs = self.branchesAndLocalTags().concat(self.remoteTags());
|
||||
rs.sort(function(a, b) {
|
||||
if (a.isLocal && !b.isLocal) return -1;
|
||||
if (!a.isLocal && b.isLocal) return 1;
|
||||
return a.refName < b.refName ? -1 : 1;
|
||||
});
|
||||
return rs;
|
||||
});
|
||||
this.ancestorOfHEAD = ko.observable(false);
|
||||
this.nodeIsMousehover = ko.observable(false);
|
||||
this.commitContainerVisible = ko.computed(function() {
|
||||
return self.ancestorOfHEAD() || self.nodeIsMousehover() || self.selected();
|
||||
});
|
||||
this.highlighted = ko.computed(function() {
|
||||
return self.nodeIsMousehover() || self.selected();
|
||||
});
|
||||
this.selected.subscribe(function() {
|
||||
programEvents.dispatch({ event: 'graph-render' });
|
||||
});
|
||||
this.commitComponent = components.create('commit', {
|
||||
sha1: this.sha1,
|
||||
repoPath: this.graph.repoPath,
|
||||
server: this.graph.server,
|
||||
selected: this.selected,
|
||||
highlighted: this.highlighted,
|
||||
nodeIsMousehover: this.nodeIsMousehover
|
||||
});
|
||||
// These are split up like this because branches and local tags can be found in the git log,
|
||||
// whereas remote tags needs to be fetched with another command (which is much slower)
|
||||
this.branches = ko.computed(function() {
|
||||
return self.refs().filter(function(r) { return r.isBranch; });
|
||||
});
|
||||
this.tags = ko.computed(function() {
|
||||
return self.refs().filter(function(r) { return r.isTag; });
|
||||
});
|
||||
this.showNewRefAction = ko.computed(function() {
|
||||
return !graph.currentActionContext();
|
||||
});
|
||||
this.newBranchName = ko.observable();
|
||||
this.newBranchNameHasFocus = ko.observable(true);
|
||||
this.newBranchNameHasFocus.subscribe(function(newValue) {
|
||||
if (!newValue) {
|
||||
// Small timeout because in ff the form is hidden before the submit click event is registered otherwise
|
||||
setTimeout(function() {
|
||||
self.branchingFormVisible(false);
|
||||
}, 200);
|
||||
}
|
||||
});
|
||||
this.branchingFormVisible = ko.observable(false);
|
||||
this.canCreateRef = ko.computed(function() {
|
||||
return self.newBranchName() && self.newBranchName().trim() && self.newBranchName().indexOf(' ') == -1;
|
||||
});
|
||||
this.branchOrder = ko.observable();
|
||||
this.aboveNode = undefined;
|
||||
this.belowNode = undefined;
|
||||
|
||||
this.r = ko.observable();
|
||||
this.cx = ko.observable();
|
||||
this.cy = ko.observable();
|
||||
|
||||
this.dropareaGraphActions = [
|
||||
new GraphActions.Move(this.graph, this),
|
||||
new GraphActions.Rebase(this.graph, this),
|
||||
new GraphActions.Merge(this.graph, this),
|
||||
new GraphActions.Push(this.graph, this),
|
||||
new GraphActions.Reset(this.graph, this),
|
||||
new GraphActions.Checkout(this.graph, this),
|
||||
new GraphActions.Delete(this.graph, this),
|
||||
new GraphActions.CherryPick(this.graph, this),
|
||||
new GraphActions.Uncommit(this.graph, this),
|
||||
new GraphActions.Revert(this.graph, this)
|
||||
];
|
||||
}
|
||||
module.exports = GitNodeViewModel;
|
||||
|
||||
GitNodeViewModel.prototype.getGraphAttr = function() {
|
||||
return [this.cx(), this.cy()];
|
||||
}
|
||||
GitNodeViewModel.prototype.setGraphAttr = function(val) {
|
||||
this.element().setAttribute('x', val[0] - 30);
|
||||
this.element().setAttribute('y', val[1] - 30);
|
||||
}
|
||||
GitNodeViewModel.prototype.render = function() {
|
||||
if (!this.isInited) return;
|
||||
if (this.ancestorOfHEAD()) {
|
||||
this.r(30);
|
||||
this.cx(610);
|
||||
|
||||
if (!this.aboveNode) {
|
||||
this.cy(120);
|
||||
} else if (this.aboveNode.ancestorOfHEAD()) {
|
||||
this.cy(this.aboveNode.cy() + 120);
|
||||
} else {
|
||||
this.cy(this.aboveNode.cy() + 60);
|
||||
}
|
||||
} else {
|
||||
this.r(15);
|
||||
this.cx(610 + (90 * this.branchOrder()));
|
||||
this.cy(this.aboveNode ? this.aboveNode.cy() + 60 : 120);
|
||||
}
|
||||
|
||||
if (this.aboveNode && this.aboveNode.selected()) {
|
||||
this.cy(this.aboveNode.cy() + this.aboveNode.commitComponent.element().offsetHeight + 30);
|
||||
}
|
||||
|
||||
this.commitComponent.selectedDiffLeftPosition(-(this.cx() - 600));
|
||||
this.color(this.ideologicalBranch() ? this.ideologicalBranch().color : '#666');
|
||||
this.animate();
|
||||
}
|
||||
GitNodeViewModel.prototype.setData = function(logEntry) {
|
||||
var self = this;
|
||||
this.title = logEntry.message.split('\n')[0];
|
||||
this.parents(logEntry.parents || []);
|
||||
this.commitTime = logEntry.commitDate;
|
||||
this.date = Date.parse(this.commitTime);
|
||||
this.commitComponent.setData(logEntry);
|
||||
|
||||
if (logEntry.refs) {
|
||||
logEntry.refs.forEach(function(ref) {
|
||||
self.graph.getRef(ref).node(self);
|
||||
});
|
||||
}
|
||||
this.isInited = true;
|
||||
}
|
||||
GitNodeViewModel.prototype.showBranchingForm = function() {
|
||||
this.branchingFormVisible(true);
|
||||
this.newBranchNameHasFocus(true);
|
||||
}
|
||||
GitNodeViewModel.prototype.createBranch = function() {
|
||||
if (!this.canCreateRef()) return;
|
||||
var self = this;
|
||||
var command = ungit.config.autoCheckoutOnBranchCreate ? "/checkout" : "/branches";
|
||||
|
||||
this.graph.server.postPromise(command, { path: this.graph.repoPath(), name: this.newBranchName(), sha1: this.sha1 })
|
||||
.then(function() {
|
||||
self.graph.getRef('refs/heads/' + self.newBranchName()).node(self);
|
||||
}).finally(function() {
|
||||
self.branchingFormVisible(false);
|
||||
self.newBranchName('');
|
||||
programEvents.dispatch({ event: 'branch-updated' });
|
||||
});
|
||||
}
|
||||
GitNodeViewModel.prototype.createTag = function() {
|
||||
if (!this.canCreateRef()) return;
|
||||
var self = this;
|
||||
this.graph.server.postPromise('/tags', { path: this.graph.repoPath(), name: this.newBranchName(), sha1: this.sha1 })
|
||||
.then(function() {
|
||||
var newRef = self.graph.getRef('tag: refs/tags/' + self.newBranchName());
|
||||
newRef.node(self);
|
||||
}).finally(function() {
|
||||
self.branchingFormVisible(false);
|
||||
self.newBranchName('');
|
||||
});
|
||||
}
|
||||
GitNodeViewModel.prototype.toggleSelected = function() {
|
||||
var self = this;
|
||||
var beforeThisCR = this.commitComponent.element().getBoundingClientRect();
|
||||
var beforeBelowCR = null;
|
||||
if (this.belowNode) {
|
||||
beforeBelowCR = this.belowNode.commitComponent.element().getBoundingClientRect();
|
||||
}
|
||||
|
||||
var prevSelected = this.graph.currentActionContext();
|
||||
if (!(prevSelected instanceof GitNodeViewModel)) prevSelected = null;
|
||||
var prevSelectedCR = prevSelected ? prevSelected.commitComponent.element().getBoundingClientRect() : null;
|
||||
this.selected(!this.selected());
|
||||
|
||||
// If we are deselecting
|
||||
if (!this.selected()) {
|
||||
if (beforeThisCR.top < 0 && beforeBelowCR) {
|
||||
var afterBelowCR = this.belowNode.commitComponent.element().getBoundingClientRect();
|
||||
// If the next node is showing, try to keep it in the screen (no jumping)
|
||||
if (beforeBelowCR.top < window.innerHeight) {
|
||||
window.scrollBy(0, afterBelowCR.top - beforeBelowCR.top);
|
||||
// Otherwise just try to bring them to the middle of the screen
|
||||
} else {
|
||||
window.scrollBy(0, afterBelowCR.top - window.innerHeight / 2);
|
||||
}
|
||||
}
|
||||
// If we are selecting
|
||||
} else {
|
||||
var afterThisCR = this.commitComponent.element().getBoundingClientRect();
|
||||
if ((prevSelectedCR && (prevSelectedCR.top < 0 || prevSelectedCR.top > window.innerHeight)) &&
|
||||
afterThisCR.top != beforeThisCR.top) {
|
||||
window.scrollBy(0, -(beforeThisCR.top - afterThisCR.top));
|
||||
console.log('Fix')
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
GitNodeViewModel.prototype.removeRef = function(ref) {
|
||||
if (ref.isRemoteTag) {
|
||||
this.remoteTags.remove(ref);
|
||||
} else {
|
||||
this.branchesAndLocalTags.remove(ref);
|
||||
}
|
||||
}
|
||||
GitNodeViewModel.prototype.pushRef = function(ref) {
|
||||
if (ref.isRemoteTag && this.remoteTags.indexOf(ref) < 0) {
|
||||
this.remoteTags.push(ref);
|
||||
} else if(this.branchesAndLocalTags.indexOf(ref) < 0) {
|
||||
this.branchesAndLocalTags.push(ref);
|
||||
}
|
||||
}
|
||||
GitNodeViewModel.prototype.getPathToCommonAncestor = function(node) {
|
||||
var path = [];
|
||||
var thisNode = this;
|
||||
while (thisNode && !node.isAncestor(thisNode)) {
|
||||
path.push(thisNode);
|
||||
thisNode = this.graph.nodesById[thisNode.parents()[0]];
|
||||
}
|
||||
if (thisNode) path.push(thisNode);
|
||||
return path;
|
||||
}
|
||||
GitNodeViewModel.prototype.isAncestor = function(node) {
|
||||
if (node == this) return true;
|
||||
for (var v in this.parents()) {
|
||||
var n = this.graph.nodesById[this.parents()[v]];
|
||||
if (n && n.isAncestor(node)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
GitNodeViewModel.prototype.getRightToLeftStrike = function() {
|
||||
return 'M ' + (this.cx() - 30) + ' ' + (this.cy() - 30) + ' L ' + (this.cx() + 30) + ' ' + (this.cy() + 30);
|
||||
}
|
||||
GitNodeViewModel.prototype.getLeftToRightStrike = function() {
|
||||
return 'M ' + (this.cx() + 30) + ' ' + (this.cy() - 30) + ' L ' + (this.cx() - 30) + ' ' + (this.cy() + 30);
|
||||
}
|
||||
GitNodeViewModel.prototype.nodeMouseover = function() {
|
||||
this.nodeIsMousehover(true);
|
||||
}
|
||||
GitNodeViewModel.prototype.nodeMouseout = function() {
|
||||
this.nodeIsMousehover(false);
|
||||
}
|
168
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/git-ref.js
generated
vendored
Normal file
168
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/git-ref.js
generated
vendored
Normal file
|
@ -0,0 +1,168 @@
|
|||
var ko = require('knockout');
|
||||
var md5 = require('blueimp-md5');
|
||||
var Selectable = require('./selectable');
|
||||
var programEvents = require('ungit-program-events');
|
||||
var components = require('ungit-components');
|
||||
|
||||
var RefViewModel = function(fullRefName, graph) {
|
||||
var self = this;
|
||||
Selectable.call(this, graph);
|
||||
this.graph = graph;
|
||||
this.name = fullRefName;
|
||||
this.node = ko.observable();
|
||||
this.localRefName = this.name; // origin/master or master
|
||||
this.refName = this.name; // master
|
||||
this.isRemoteTag = this.name.indexOf('remote-tag: ') == 0;
|
||||
this.isLocalTag = this.name.indexOf('tag: ') == 0;
|
||||
this.isTag = this.isLocalTag || this.isRemoteTag;
|
||||
var isRemoteBranchOrHEAD = this.name.indexOf('refs/remotes/') == 0;
|
||||
this.isLocalHEAD = this.name == 'HEAD';
|
||||
this.isRemoteHEAD = this.name.indexOf('/HEAD') != -1;
|
||||
this.isLocalBranch = this.name.indexOf('refs/heads/') == 0;
|
||||
this.isRemoteBranch = isRemoteBranchOrHEAD && !this.isRemoteHEAD;
|
||||
this.isStash = this.name.indexOf('refs/stash') == 0;
|
||||
this.isHEAD = this.isLocalHEAD || this.isRemoteHEAD;
|
||||
this.isBranch = this.isLocalBranch || this.isRemoteBranch;
|
||||
this.isRemote = isRemoteBranchOrHEAD || this.isRemoteTag;
|
||||
this.isLocal = this.isLocalBranch || this.isLocalTag;
|
||||
if (this.isLocalBranch) {
|
||||
this.localRefName = this.name.slice('refs/heads/'.length);
|
||||
this.refName = this.localRefName;
|
||||
}
|
||||
if (this.isRemoteBranch) {
|
||||
this.localRefName = this.name.slice('refs/remotes/'.length);
|
||||
}
|
||||
if (this.isLocalTag) {
|
||||
this.localRefName = this.name.slice('tag: refs/tags/'.length);
|
||||
this.refName = this.localRefName;
|
||||
}
|
||||
if (this.isRemoteTag) {
|
||||
this.localRefName = this.name.slice('remote-tag: '.length);
|
||||
}
|
||||
if (this.isRemote) {
|
||||
// get rid of the origin/ part of origin/branchname
|
||||
var s = this.localRefName.split('/');
|
||||
this.remote = s[0];
|
||||
this.refName = s.slice(1).join('/');
|
||||
}
|
||||
this.show = true;
|
||||
this.server = this.graph.server;
|
||||
this.isDragging = ko.observable(false);
|
||||
this.current = ko.computed(function() {
|
||||
return self.isLocalBranch && self.graph.checkedOutBranch() == self.refName;
|
||||
});
|
||||
this.color = this._colorFromHashOfString(this.name);
|
||||
|
||||
this.node.subscribe(function(oldNode) {
|
||||
if (oldNode) oldNode.removeRef(self);
|
||||
}, null, "beforeChange");
|
||||
this.node.subscribe(function(newNode) {
|
||||
if (newNode) newNode.pushRef(self);
|
||||
});
|
||||
};
|
||||
module.exports = RefViewModel;
|
||||
|
||||
RefViewModel.prototype._colorFromHashOfString = function(string) {
|
||||
return '#' + md5(string).toString().slice(0, 6);
|
||||
}
|
||||
RefViewModel.prototype.dragStart = function() {
|
||||
this.graph.currentActionContext(this);
|
||||
this.isDragging(true);
|
||||
if (document.activeElement) document.activeElement.blur();
|
||||
}
|
||||
RefViewModel.prototype.dragEnd = function() {
|
||||
this.graph.currentActionContext(null);
|
||||
this.isDragging(false);
|
||||
}
|
||||
RefViewModel.prototype.moveTo = function(target, callback) {
|
||||
var self = this;
|
||||
|
||||
var callbackWithRefSet = function(err, res) {
|
||||
if (err) {
|
||||
callback(err, res);
|
||||
} else {
|
||||
var targetNode = self.graph.getNode(target);
|
||||
if (self.graph.checkedOutBranch() == self.refName) {
|
||||
self.graph.HEADref().node(targetNode);
|
||||
}
|
||||
self.node(targetNode);
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.isLocal) {
|
||||
if (this.current()) {
|
||||
this.server.post('/reset', { path: this.graph.repoPath(), to: target, mode: 'hard' }, callbackWithRefSet);
|
||||
} else if (this.isTag) {
|
||||
this.server.post('/tags', { path: this.graph.repoPath(), name: this.refName, sha1: target, force: true }, callbackWithRefSet);
|
||||
} else {
|
||||
this.server.post('/branches', { path: this.graph.repoPath(), name: this.refName, sha1: target, force: true }, callbackWithRefSet);
|
||||
}
|
||||
} else {
|
||||
var pushReq = { path: this.graph.repoPath(), remote: this.remote, refSpec: target, remoteBranch: this.refName };
|
||||
this.server.post('/push', pushReq, function(err, res) {
|
||||
if (err) {
|
||||
if (err.errorCode == 'non-fast-forward') {
|
||||
var forcePushDialog = components.create('yesnodialog', { title: 'Force push?', details: 'The remote branch can\'t be fast-forwarded.' });
|
||||
forcePushDialog.closed.add(function() {
|
||||
if (!forcePushDialog.result()) return callback();
|
||||
pushReq.force = true;
|
||||
self.server.post('/push', pushReq, callbackWithRefSet);
|
||||
});
|
||||
programEvents.dispatch({ event: 'request-show-dialog', dialog: forcePushDialog });
|
||||
return true;
|
||||
}
|
||||
}
|
||||
callbackWithRefSet(err, res);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
RefViewModel.prototype.remove = function(callback) {
|
||||
var self = this;
|
||||
var url = this.isTag ? '/tags' : '/branches';
|
||||
if (this.isRemote) url = '/remote' + url;
|
||||
this.server.del(url, { path: this.graph.repoPath(), remote: this.isRemote ? this.remote : null, name: this.refName }, function(err) {
|
||||
if (!err) {
|
||||
self.node().removeRef(self);
|
||||
self.graph.refsByRefName[self.name] = undefined;
|
||||
}
|
||||
|
||||
callback();
|
||||
self.graph.loadNodesFromApi();
|
||||
if (url == '/remote/tags') {
|
||||
programEvents.dispatch({ event: 'request-fetch-tags' });
|
||||
} else {
|
||||
programEvents.dispatch({ event: 'branch-updated' });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RefViewModel.prototype.getRemoteRef = function(remote) {
|
||||
return this.graph.getRef(this.getRemoteRefFullName(remote), false);
|
||||
}
|
||||
|
||||
RefViewModel.prototype.getRemoteRefFullName = function(remote) {
|
||||
if (this.isLocalBranch) return 'refs/remotes/' + remote + '/' + this.refName;
|
||||
if (this.isLocalTag) return 'remote-tag: ' + remote + '/' + this.refName;
|
||||
return null;
|
||||
}
|
||||
|
||||
RefViewModel.prototype.canBePushed = function(remote) {
|
||||
if (!this.isLocal) return false;
|
||||
var remoteRef = this.getRemoteRef(remote);
|
||||
if (!remoteRef) return true;
|
||||
return this.node() != remoteRef.node();
|
||||
}
|
||||
|
||||
RefViewModel.prototype.createRemoteRef = function(callback) {
|
||||
var self = this;
|
||||
this.server.post('/push', { path: this.graph.repoPath(), remote: this.graph.currentRemote(),
|
||||
refSpec: this.refName, remoteBranch: this.refName }, function(err) {
|
||||
if (!err) {
|
||||
var newRef = self.graph.getRef("refs/remotes/" + self.graph.currentRemote() + "/" + self.refName);
|
||||
newRef.node(self.node());
|
||||
}
|
||||
callback(err);
|
||||
});
|
||||
}
|
55
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/graph-graphics.html
generated
vendored
Normal file
55
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/graph-graphics.html
generated
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
|
||||
<svg class="graphLog" xmlns="http://www.w3.org/2000/svg" version="1.1" data-bind="attr: { width: graphWidth, height: graphHeight }">
|
||||
<defs>
|
||||
<marker id="rebaseArrowEnd"
|
||||
viewBox="0 0 10 10" refX="0" refY="5"
|
||||
markerUnits="strokeWidth"
|
||||
markerWidth="4" markerHeight="3"
|
||||
orient="auto">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" fill="#22252E" />
|
||||
</marker>
|
||||
<marker id="pushArrowEnd"
|
||||
viewBox="0 0 10 10" refX="0" refY="5"
|
||||
markerUnits="strokeWidth"
|
||||
markerWidth="4" markerHeight="3"
|
||||
orient="auto">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" fill="rgb(61, 139, 255)" />
|
||||
</marker>
|
||||
</defs>
|
||||
<g>
|
||||
<!-- ko if: commitNodeEdge -->
|
||||
<g data-bind="attr: { opacity: commitOpacity }">
|
||||
<path data-bind="attr: { d: commitNodeEdge }", stroke="#4A4A4A" stroke-width="8" stroke-dasharray="10, 5" />
|
||||
<circle data-bind="attr: { stroke: commitNodeColor }" cx="610" cy="35" r="30" data-bind="attr: { stroke: '#4A4A4A' }" stroke-dasharray="10, 7" stroke-width="10" fill="transparent"/>
|
||||
</g>
|
||||
<!-- /ko -->
|
||||
|
||||
<!-- ko with: hoverGraphActionGraphic -->
|
||||
<!-- ko foreach: bgEdges -->
|
||||
<path data-bind="attr: { d: d, stroke: stroke, 'stroke-width': strokeWidth, 'stroke-dasharray': strokeDasharray, 'marker-end': markerEnd }" />
|
||||
<!-- /ko -->
|
||||
<!-- /ko -->
|
||||
|
||||
<!-- ko foreach: edges -->
|
||||
<path data-bind="element: element" stroke="#4A4A4A" stroke-width="8" />
|
||||
<!-- /ko -->
|
||||
|
||||
<!-- ko foreach: nodes -->
|
||||
<svg data-bind="element: element" >
|
||||
<circle data-bind="attr: { r: r, fill: color, 'data-ta-clickable': 'node-clickable-' + $index() }, event: { mouseover: nodeMouseover, mouseout: nodeMouseout }, click: toggleSelected" cx="30" cy="30" />
|
||||
<!-- ko if: selected -->
|
||||
<circle data-bind=" attr: { r: r() - 4 }, click: toggleSelected" stroke="#252833" stroke-width="4" fill="transparent" cx="30" cy="30" />
|
||||
<!-- /ko -->
|
||||
</svg>
|
||||
<!-- /ko -->
|
||||
|
||||
<!-- ko with: hoverGraphActionGraphic -->
|
||||
<!-- ko foreach: nodes -->
|
||||
<circle data-bind="attr: { cx: cx, cy: cy, r: r, fill: fill, stroke: stroke, 'stroke-width': strokeWidth, 'stroke-dasharray': strokeDasharray }" />
|
||||
<!-- /ko -->
|
||||
<!-- ko foreach: fgEdges -->
|
||||
<path data-bind="attr: { d: d, stroke: stroke, 'stroke-width': strokeWidth, 'stroke-dasharray': strokeDasharray, 'marker-end': markerEnd }" />
|
||||
<!-- /ko -->
|
||||
<!-- /ko -->
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
1238
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/graph.bundle.js
generated
vendored
Normal file
1238
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/graph.bundle.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
186
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/graph.css
generated
vendored
Normal file
186
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/graph.css
generated
vendored
Normal file
|
@ -0,0 +1,186 @@
|
|||
.graph {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
.graph .graphLog {
|
||||
left: 575px;
|
||||
}
|
||||
.graph .nodeContainer {
|
||||
position: absolute;
|
||||
left: 30px;
|
||||
top: 120px;
|
||||
width: 100%;
|
||||
}
|
||||
.graph .nodeContainer .commit-container {
|
||||
position: absolute;
|
||||
top: -43px;
|
||||
}
|
||||
.graph .nodeContainer .rightSideContainer {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
margin-left: 440px;
|
||||
top: -22px;
|
||||
white-space: nowrap;
|
||||
height: 40px;
|
||||
}
|
||||
.graph .nodeContainer .droparea {
|
||||
margin: 8px 0px 4px 0px;
|
||||
}
|
||||
.graph .nodeContainer .ref {
|
||||
display: inline-block;
|
||||
opacity: 0.6;
|
||||
cursor: move;
|
||||
margin: 7px 0px 4px 0px;
|
||||
outline: none;
|
||||
padding: 2px 5px 2px 5px;
|
||||
border: 3px solid transparent;
|
||||
border-radius: 10px;
|
||||
transition: border-color 0.5s;
|
||||
-webkit-transition: border-color 0.5s;
|
||||
}
|
||||
.graph .nodeContainer .ref.dragging.focused {
|
||||
border-color: transparent;
|
||||
}
|
||||
.graph .nodeContainer .ref.focused {
|
||||
border-color: #fff;
|
||||
}
|
||||
.graph .nodeContainer .ref.current {
|
||||
font-weight: bold;
|
||||
opacity: 1;
|
||||
font-size: 20px;
|
||||
margin-top: 2px;
|
||||
margin-bottom: -2px;
|
||||
}
|
||||
.graph .nodeContainer .ref.current .octicon {
|
||||
font-size: 20px;
|
||||
}
|
||||
.graph .nodeContainer .ref.remote {
|
||||
color: #5DB4FF;
|
||||
}
|
||||
.graph .nodeContainer .ref.tag {
|
||||
color: #EEF266;
|
||||
}
|
||||
.graph .nodeContainer .graphAction {
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
opacity: 1;
|
||||
transition: all 0.5s ease 0.2s;
|
||||
-webkit-transition: all 0.5s ease 0.2s;
|
||||
transition-property: opacity, max-width;
|
||||
-webkit-transition-property: opacity, max-width;
|
||||
margin-right: 2.5px;
|
||||
margin-left: 2.5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.graph .nodeContainer .graphAction .icon {
|
||||
margin-right: 6px;
|
||||
}
|
||||
.graph .nodeContainer .graphAction .icon.flip {
|
||||
-webkit-transform: rotate(-180deg);
|
||||
-moz-transform: rotate(-180deg);
|
||||
-o-transform: rotate(-180deg);
|
||||
transform: rotate(-180deg);
|
||||
}
|
||||
.graph .nodeContainer .graphAction .icon.octicon-git-merge,
|
||||
.graph .nodeContainer .graphAction .icon.octicon-repo-forked,
|
||||
.graph .nodeContainer .graphAction .icon.octicon-zap {
|
||||
margin-left: 3px;
|
||||
}
|
||||
.graph .nodeContainer .graphAction .icon.octicon-history {
|
||||
margin-left: 2px;
|
||||
}
|
||||
.graph .nodeContainer .graphAction .icon.glyphicon-remove,
|
||||
.graph .nodeContainer .graphAction .icon.octicon-circuit-board {
|
||||
margin-left: 1px;
|
||||
}
|
||||
.graph .nodeContainer .graphAction.droparea {
|
||||
padding-left: 7px;
|
||||
}
|
||||
.graph .nodeContainer .graphAction.dimmed {
|
||||
opacity: 0.5;
|
||||
}
|
||||
.graph .nodeContainer .graphAction.push {
|
||||
background: rgba(61, 139, 255, 0.9);
|
||||
}
|
||||
.graph .nodeContainer .graphAction.pull {
|
||||
background: rgba(38, 189, 189, 0.9);
|
||||
}
|
||||
.graph .nodeContainer .graphAction.reset {
|
||||
background: rgba(255, 129, 31, 0.9);
|
||||
}
|
||||
.graph .nodeContainer .graphAction.rebase {
|
||||
background: rgba(65, 222, 60, 0.9);
|
||||
}
|
||||
.graph .nodeContainer .graphAction.move {
|
||||
width: auto;
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.graph .nodeContainer .graphAction.merge {
|
||||
background: rgba(208, 135, 212, 0.9);
|
||||
}
|
||||
.graph .nodeContainer .graphAction.checkout {
|
||||
background: rgba(205, 219, 55, 0.9);
|
||||
}
|
||||
.graph .nodeContainer .graphAction.delete {
|
||||
background: rgba(214, 77, 56, 0.9);
|
||||
}
|
||||
.graph .nodeContainer .graphAction.cherry-pick {
|
||||
background: rgba(110, 156, 110, 0.9);
|
||||
}
|
||||
.graph .nodeContainer .graphAction.uncommit {
|
||||
background: rgba(158, 53, 20, 0.9);
|
||||
}
|
||||
.graph .nodeContainer .graphAction.revert {
|
||||
background: rgba(179, 135, 43, 0.9);
|
||||
}
|
||||
.graph .nodeContainer .newRef {
|
||||
opacity: 1;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
.graph .nodeContainer .newRef .showBranchingForm {
|
||||
background: transparent;
|
||||
border: 0px;
|
||||
cursor: pointer;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
margin-top: 9px;
|
||||
color: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
.graph .nodeContainer .newRef .showBranchingForm:hover {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
.graph .nodeContainer .newRef .form-inline {
|
||||
display: inline-block;
|
||||
}
|
||||
.graph .nodeContainer .newRef input.name {
|
||||
width: 150px;
|
||||
}
|
||||
.graph .graphFooter {
|
||||
height: 60px;
|
||||
}
|
||||
.graph .graphFooter .progressBar {
|
||||
position: relative;
|
||||
top: -150px;
|
||||
margin-left: 400px;
|
||||
}
|
||||
.graph .remote-icon {
|
||||
background: url('images/remoteIcon.png');
|
||||
width: 12px;
|
||||
height: 10px;
|
||||
display: inline-block;
|
||||
}
|
||||
.graph .branch-icon {
|
||||
background: url('images/branchIcon.png');
|
||||
width: 9px;
|
||||
height: 10px;
|
||||
display: inline-block;
|
||||
}
|
||||
.graph .tag-icon {
|
||||
background: url('images/tagIcon.png');
|
||||
width: 5px;
|
||||
height: 10px;
|
||||
display: inline-block;
|
||||
}
|
65
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/graph.html
generated
vendored
Normal file
65
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/graph.html
generated
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
|
||||
<div class="graph" data-bind="scrolledToEnd: scrolledToEnd, click: handleBubbledClick" data-ta-clickable="graph">
|
||||
|
||||
<!-- ko template: { name: 'graphGraphics' } --><!-- /ko -->
|
||||
|
||||
<div class="nodes" data-bind="foreach: nodes">
|
||||
<div class="nodeContainer animation" data-ta-container="node" data-bind="style: { left: '0px', top: cy() + 'px' }, attr: { 'data-ta-node-title': title }">
|
||||
<div class="commit-container animation" data-bind="visible: commitContainerVisible, style: { left: cx() - 620 + 'px' }">
|
||||
<!-- ko component: commitComponent -->
|
||||
<!-- /ko -->
|
||||
</div>
|
||||
|
||||
<div class="rightSideContainer" data-bind="style: { left: cx() + r() - 433 + 'px' }">
|
||||
<!-- ko foreach: branches -->
|
||||
<span class="ref branch" data-ta-clickable="branch" draggable="true" tabIndex="-1"
|
||||
data-bind="css: { current: current, remote: isRemoteBranch, dragging: isDragging, focused: selected },
|
||||
click: selected,
|
||||
dragStart: dragStart, dragEnd: dragEnd, attr: { 'data-ta-name': localRefName, 'data-ta-current': current, 'data-ta-local': isLocal }" >
|
||||
<span class="octicon octicon-broadcast" data-bind="visible: isRemoteBranch"></span>
|
||||
<span class="octicon octicon-git-branch"></span>
|
||||
<span class="name" data-bind="text: localRefName"></span>
|
||||
</span>
|
||||
<!-- /ko -->
|
||||
|
||||
<!-- ko foreach: tags -->
|
||||
<span class="ref tag" data-ta-clickable="tag" draggable="true" tabIndex="0"
|
||||
data-bind="css: { current: current, remote: isRemoteTag, dragging: isDragging, focused: selected },
|
||||
click: selected,
|
||||
dragStart: dragStart, dragEnd: dragEnd, attr: { 'data-ta-name': localRefName, 'data-ta-current': current }">
|
||||
<span class="octicon octicon-globe" data-bind="visible: isRemote"></span>
|
||||
<span class="octicon octicon-tag"></span>
|
||||
<span class="name" data-bind="text: localRefName"></span>
|
||||
</span>
|
||||
<!-- /ko -->
|
||||
|
||||
<!-- ko foreach: dropareaGraphActions -->
|
||||
<span class="graphAction droparea" data-bind="css: cssClasses, visible: visible, attr: { 'data-ta-action': style, 'data-ta-visible': visible }, event: { mouseover: mouseover, mouseout: mouseout }">
|
||||
<!-- ko if: icon --><span data-bind="css: icon" class="icon"></span><!-- /ko -->
|
||||
<span data-bind="text: text"></span>
|
||||
<div class="dropmask" tabIndex="0" role="button" data-bind="dropOver: visible, drop: doPerform, dragEnter: dragEnter, dragLeave: dragLeave, click: doPerform"></div>
|
||||
<!-- ko component: performProgressBar --><!-- /ko -->
|
||||
</span>
|
||||
<!-- /ko -->
|
||||
|
||||
<!-- ko if: showNewRefAction -->
|
||||
<span class="newRef" data-bind="css: { editing: branchingFormVisible }">
|
||||
<button class="showBranchingForm" data-ta-clickable="show-new-branch-form" data-bind="click: showBranchingForm, visible: !branchingFormVisible()">✚</button>
|
||||
<!-- ko if: branchingFormVisible -->
|
||||
<div class="form-inline">
|
||||
<input class="name form-control" data-ta-input="new-branch-name" type="text" data-bind="value: newBranchName, hasfocus: newBranchNameHasFocus, valueUpdate: 'afterkeydown'"/>
|
||||
<button class="btn btn-primary" data-ta-clickable="create-branch" type="submit" value="Branch" data-bind="click: createBranch, enable: canCreateRef">Branch</button>
|
||||
<button class="btn btn-default" data-ta-clickable="create-tag" data-bind="click: createTag, enable: canCreateRef">Tag</button>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
</span>
|
||||
<!-- /ko -->
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="graphFooter">
|
||||
<!-- ko component: nodesLoader --><!-- /ko -->
|
||||
</div>
|
||||
</div>
|
297
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/graph.js
generated
vendored
Normal file
297
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/graph.js
generated
vendored
Normal file
|
@ -0,0 +1,297 @@
|
|||
var ko = require('knockout');
|
||||
var components = require('ungit-components');
|
||||
var GitNodeViewModel = require('./git-node');
|
||||
var GitRefViewModel = require('./git-ref');
|
||||
var _ = require('lodash');
|
||||
var moment = require('moment');
|
||||
var EdgeViewModel = require('./edge');
|
||||
|
||||
components.register('graph', function(args) {
|
||||
return new GraphViewModel(args.server, args.repoPath);
|
||||
});
|
||||
|
||||
function GraphViewModel(server, repoPath) {
|
||||
var self = this;
|
||||
this.repoPath = repoPath;
|
||||
this.maxNNodes = 25;
|
||||
this.server = server;
|
||||
this.currentRemote = ko.observable();
|
||||
this.nodesLoader = components.create('progressBar', {
|
||||
predictionMemoryKey: 'gitgraph-' + self.repoPath(),
|
||||
fallbackPredictedTimeMs: 1000,
|
||||
temporary: true
|
||||
});
|
||||
this.nodes = ko.observableArray();
|
||||
this.edges = ko.observableArray();
|
||||
this.refs = ko.observableArray();
|
||||
this.nodesById = {};
|
||||
this.refsByRefName = {};
|
||||
this.checkedOutBranch = ko.observable();
|
||||
this.checkedOutRef = ko.computed(function() {
|
||||
return self.checkedOutBranch() ? self.getRef('refs/heads/' + self.checkedOutBranch()) : null;
|
||||
});
|
||||
this.HEADref = ko.observable();
|
||||
this.HEAD = ko.computed(function() {
|
||||
return self.HEADref() ? self.HEADref().node() : undefined;
|
||||
});
|
||||
this.commitNodeColor = ko.computed(function() {
|
||||
return self.HEAD() ? self.HEAD().color() : '#4A4A4A';
|
||||
});
|
||||
this.commitNodeEdge = ko.computed(function() {
|
||||
if (!self.HEAD() || !self.HEAD().cx() || !self.HEAD().cy()) return;
|
||||
return "M 610 68 L " + self.HEAD().cx() + " " + self.HEAD().cy();
|
||||
});
|
||||
this.showCommitNode = ko.observable(false);
|
||||
this.currentActionContext = ko.observable();
|
||||
this.edgesById = {};
|
||||
this.scrolledToEnd = _.debounce(function() {
|
||||
self.maxNNodes = self.maxNNodes + 25;
|
||||
self.loadNodesFromApi();
|
||||
}, 500, true);
|
||||
this.dimCommit = ko.observable(false);
|
||||
this.commitOpacity = ko.computed(function() { return self.dimCommit() ? 0.1 : 1; });
|
||||
this.heighstBranchOrder = 0;
|
||||
this.hoverGraphActionGraphic = ko.observable();
|
||||
this.hoverGraphActionGraphic.subscribe(function(value) {
|
||||
if (value && value.destroy)
|
||||
value.destroy();
|
||||
}, null, 'beforeChange');
|
||||
|
||||
this.hoverGraphAction = ko.observable();
|
||||
this.hoverGraphAction.subscribe(function(value) {
|
||||
if (value && value.createHoverGraphic) {
|
||||
self.hoverGraphActionGraphic(value.createHoverGraphic());
|
||||
} else {
|
||||
self.hoverGraphActionGraphic(null);
|
||||
}
|
||||
});
|
||||
|
||||
this.loadNodesFromApiThrottled = _.throttle(this.loadNodesFromApi.bind(this), 500);
|
||||
this.updateBranchesThrottled = _.throttle(this.updateBranches.bind(this), 500);
|
||||
this.loadNodesFromApiThrottled();
|
||||
this.updateBranchesThrottled();
|
||||
this.graphWidth = ko.observable();
|
||||
this.graphHeight = ko.observable();
|
||||
}
|
||||
|
||||
GraphViewModel.prototype.updateNode = function(parentElement) {
|
||||
ko.renderTemplate('graph', this, {}, parentElement);
|
||||
}
|
||||
|
||||
GraphViewModel.prototype.getNode = function(sha1, logEntry) {
|
||||
var nodeViewModel = this.nodesById[sha1];
|
||||
if (!nodeViewModel) nodeViewModel = this.nodesById[sha1] = new GitNodeViewModel(this, sha1);
|
||||
if (logEntry) nodeViewModel.setData(logEntry);
|
||||
return nodeViewModel;
|
||||
}
|
||||
GraphViewModel.prototype.getRef = function(ref, constructIfUnavailable) {
|
||||
if (constructIfUnavailable === undefined) constructIfUnavailable = true;
|
||||
var refViewModel = this.refsByRefName[ref];
|
||||
if (!refViewModel && constructIfUnavailable) {
|
||||
refViewModel = this.refsByRefName[ref] = new GitRefViewModel(ref, this);
|
||||
this.refs.push(refViewModel);
|
||||
if (refViewModel.name === 'HEAD') {
|
||||
this.HEADref(refViewModel);
|
||||
}
|
||||
}
|
||||
return refViewModel;
|
||||
}
|
||||
|
||||
GraphViewModel.prototype.loadNodesFromApi = function(callback) {
|
||||
var self = this;
|
||||
|
||||
this.nodesLoader.start();
|
||||
this.server.getPromise('/log', { path: this.repoPath(), limit: this.maxNNodes })
|
||||
.then(function(nodes) {
|
||||
nodes = self.computeNode(nodes.map(function(logEntry) {
|
||||
return self.getNode(logEntry.sha1, logEntry);
|
||||
}));
|
||||
|
||||
var edges = [];
|
||||
nodes.forEach(function(node) {
|
||||
node.parents().forEach(function(parentSha1) {
|
||||
edges.push(self.getEdge(node.sha1, parentSha1));
|
||||
});
|
||||
node.render();
|
||||
});
|
||||
|
||||
self.edges(edges);
|
||||
self.nodes(nodes);
|
||||
|
||||
if (nodes.length > 0) {
|
||||
self.graphHeight(nodes[nodes.length - 1].cy() + 80);
|
||||
}
|
||||
self.graphWidth(1000 + (self.heighstBranchOrder * 90));
|
||||
}).finally(function() {
|
||||
self.nodesLoader.stop();
|
||||
if (callback) callback();
|
||||
});
|
||||
}
|
||||
|
||||
GraphViewModel.prototype.traverseNodeLeftParents = function(node, callback) {
|
||||
callback(node);
|
||||
var parent = this.nodesById[node.parents()[0]];
|
||||
if (parent) {
|
||||
this.traverseNodeLeftParents(parent, callback);
|
||||
}
|
||||
}
|
||||
|
||||
GraphViewModel.prototype.computeNode = function(nodes) {
|
||||
var self = this;
|
||||
|
||||
if (!nodes) {
|
||||
nodes = this.nodes();
|
||||
}
|
||||
|
||||
this.markNodesIdeologicalBranches(this.refs(), nodes, this.nodesById);
|
||||
|
||||
var updateTimeStamp = moment().valueOf();
|
||||
if (this.HEAD()) {
|
||||
this.traverseNodeLeftParents(this.HEAD(), function(node) {
|
||||
node.ancestorOfHEADTimeStamp = updateTimeStamp;
|
||||
});
|
||||
}
|
||||
|
||||
// Filter out nodes which doesn't have a branch (staging and orphaned nodes)
|
||||
nodes = nodes.filter(function(node) { return (node.ideologicalBranch() && !node.ideologicalBranch().isStash) || node.ancestorOfHEADTimeStamp == updateTimeStamp; })
|
||||
|
||||
var branchSlots = [];
|
||||
|
||||
// Then iterate from the bottom to fix the orders of the branches
|
||||
for (var i = nodes.length - 1; i >= 0; i--) {
|
||||
var node = nodes[i];
|
||||
if (node.ancestorOfHEADTimeStamp == updateTimeStamp) continue;
|
||||
var ideologicalBranch = node.ideologicalBranch();
|
||||
|
||||
// First occurence of the branch, find an empty slot for the branch
|
||||
if (ideologicalBranch.lastSlottedTimeStamp != updateTimeStamp) {
|
||||
ideologicalBranch.lastSlottedTimeStamp = updateTimeStamp;
|
||||
var slot = branchSlots.indexOf(undefined);
|
||||
if (slot === -1) {
|
||||
branchSlots.push(ideologicalBranch);
|
||||
slot = branchSlots.length - 1;
|
||||
}
|
||||
ideologicalBranch.branchOrder = slot;
|
||||
branchSlots[slot] = slot;
|
||||
}
|
||||
|
||||
node.branchOrder(ideologicalBranch.branchOrder);
|
||||
self.heighstBranchOrder = Math.max(self.heighstBranchOrder, node.branchOrder());
|
||||
}
|
||||
|
||||
var prevNode;
|
||||
nodes.forEach(function(node) {
|
||||
node.branchOrder(branchSlots.length - node.branchOrder());
|
||||
node.ancestorOfHEAD(node.ancestorOfHEADTimeStamp == updateTimeStamp);
|
||||
node.aboveNode = prevNode;
|
||||
if (prevNode) prevNode.belowNode = node;
|
||||
prevNode = node;
|
||||
});
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
GraphViewModel.prototype.getEdge = function(nodeAsha1, nodeBsha1) {
|
||||
var id = nodeAsha1 + '-' + nodeBsha1;
|
||||
var edge = this.edgesById[id];
|
||||
if (!edge) {
|
||||
edge = this.edgesById[id] = new EdgeViewModel(this, nodeAsha1, nodeBsha1);
|
||||
}
|
||||
return edge;
|
||||
}
|
||||
|
||||
GraphViewModel._markIdeologicalStamp = 0;
|
||||
GraphViewModel.prototype.markNodesIdeologicalBranches = function(refs, nodes, nodesById) {
|
||||
var self = this;
|
||||
refs = refs.filter(function(r) { return !!r.node(); });
|
||||
refs = refs.sort(function(a, b) {
|
||||
if (a.isLocal && !b.isLocal) return -1;
|
||||
if (b.isLocal && !a.isLocal) return 1;
|
||||
if (a.isBranch && !b.isBranch) return -1;
|
||||
if (b.isBranch && !a.isBranch) return 1;
|
||||
if (a.isHEAD && !b.isHEAD) return 1;
|
||||
if (!a.isHEAD && b.isHEAD) return -1;
|
||||
if (a.isStash && !b.isStash) return 1;
|
||||
if (b.isStash && !a.isStash) return -1;
|
||||
if (a.node() && a.node().date && b.node() && b.node().date)
|
||||
return b.node().date - a.node().date;
|
||||
return a.refName < b.refName ? -1 : 1;
|
||||
});
|
||||
var stamp = GraphViewModel._markIdeologicalStamp++;
|
||||
refs.forEach(function(ref) {
|
||||
self.traverseNodeParents(ref.node(), function(node) {
|
||||
if (node.stamp == stamp) return false;
|
||||
node.stamp = stamp;
|
||||
node.ideologicalBranch(ref);
|
||||
return true;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
GraphViewModel.prototype.traverseNodeParents = function(node, callback) {
|
||||
if (!callback(node)) return false;
|
||||
for (var i = 0; i < node.parents().length; i++) {
|
||||
// if parent, travers parent
|
||||
var parent = this.nodesById[node.parents()[i]];
|
||||
if (parent) {
|
||||
this.traverseNodeParents(parent, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GraphViewModel.prototype.handleBubbledClick = function(elem, event) {
|
||||
// If the clicked element is bound to the current action context,
|
||||
// then let's not deselect it.
|
||||
if (ko.dataFor(event.target) === this.currentActionContext()) return;
|
||||
if (this.currentActionContext() && this.currentActionContext() instanceof GitNodeViewModel) {
|
||||
this.currentActionContext().toggleSelected();
|
||||
} else {
|
||||
this.currentActionContext(null);
|
||||
}
|
||||
// If the click was on an input element, then let's allow the default action to proceed.
|
||||
// This is especially needed since for some strange reason any submit (ie. enter in a textbox)
|
||||
// will trigger a click event on the submit input of the form, which will end up here,
|
||||
// and if we don't return true, then the submit event is never fired, breaking stuff.
|
||||
if (event.target.nodeName === 'INPUT') return true;
|
||||
}
|
||||
|
||||
GraphViewModel.prototype.onProgramEvent = function(event) {
|
||||
if (event.event == 'git-directory-changed') {
|
||||
this.loadNodesFromApiThrottled();
|
||||
this.updateBranchesThrottled();
|
||||
} else if (event.event == 'request-app-content-refresh') {
|
||||
this.loadNodesFromApiThrottled();
|
||||
} else if (event.event == 'remote-tags-update') {
|
||||
this.setRemoteTags(event.tags);
|
||||
} else if (event.event == 'current-remote-changed') {
|
||||
this.currentRemote(event.newRemote);
|
||||
} else if (event.event == 'graph-render') {
|
||||
this.nodes().forEach(function(node) {
|
||||
node.render();
|
||||
});
|
||||
}
|
||||
}
|
||||
GraphViewModel.prototype.updateBranches = function() {
|
||||
var self = this;
|
||||
this.server.get('/checkout', { path: this.repoPath() }, function(err, branch) {
|
||||
if (err && err.errorCode == 'not-a-repository') return true;
|
||||
if (err) return;
|
||||
self.checkedOutBranch(branch);
|
||||
});
|
||||
}
|
||||
GraphViewModel.prototype.setRemoteTags = function(remoteTags) {
|
||||
var self = this;
|
||||
var nodeIdsToRemoteTags = {};
|
||||
remoteTags.forEach(function(ref) {
|
||||
if (ref.name.indexOf('^{}') != -1) {
|
||||
var tagRef = ref.name.slice(0, ref.name.length - '^{}'.length);
|
||||
var name = 'remote-tag: ' + ref.remote + '/' + tagRef.split('/')[2];
|
||||
self.getRef(name).node(self.getNode(ref.sha1));
|
||||
}
|
||||
});
|
||||
}
|
||||
GraphViewModel.prototype.checkHeadMove = function(toNode) {
|
||||
if (this.HEAD() === toNode) {
|
||||
this.HEADref.node(toNode);
|
||||
}
|
||||
}
|
197
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/graph.less
generated
vendored
Normal file
197
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/graph.less
generated
vendored
Normal file
|
@ -0,0 +1,197 @@
|
|||
|
||||
@import "public/less/variables.less";
|
||||
|
||||
.graph {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
|
||||
.graphLog {
|
||||
left: 575px;
|
||||
}
|
||||
|
||||
.nodeContainer {
|
||||
position: absolute;
|
||||
left: 30px;
|
||||
top: 120px;
|
||||
width: 100%;
|
||||
|
||||
.commit-container {
|
||||
position: absolute;
|
||||
top: -43px;
|
||||
}
|
||||
|
||||
.rightSideContainer {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
margin-left: (@log-width-small + 40px);
|
||||
top: -22px;
|
||||
white-space: nowrap;
|
||||
height: 40px;
|
||||
}
|
||||
.droparea {
|
||||
margin: 8px 0px 4px 0px;
|
||||
}
|
||||
|
||||
.ref {
|
||||
display: inline-block;
|
||||
opacity: 0.6;
|
||||
cursor: move;
|
||||
margin: 7px 0px 4px 0px;
|
||||
outline: none;
|
||||
padding: 2px 5px 2px 5px;
|
||||
border: 3px solid transparent;
|
||||
border-radius: 10px;
|
||||
transition: border-color 0.5s;
|
||||
-webkit-transition: border-color 0.5s;
|
||||
|
||||
&.dragging.focused {
|
||||
border-color: transparent;
|
||||
}
|
||||
&.focused {
|
||||
border-color: #fff;
|
||||
}
|
||||
|
||||
&.current {
|
||||
font-weight: bold;
|
||||
opacity: 1;
|
||||
font-size: 20px;
|
||||
margin-top: 2px;
|
||||
margin-bottom: -2px;
|
||||
.octicon {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
&.remote {
|
||||
color: #5DB4FF;
|
||||
}
|
||||
&.tag {
|
||||
color: #EEF266;
|
||||
}
|
||||
}
|
||||
.graphAction {
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
opacity: 1;
|
||||
transition: all 0.5s ease 0.2s;
|
||||
-webkit-transition: all 0.5s ease 0.2s;
|
||||
transition-property: opacity, max-width;
|
||||
-webkit-transition-property: opacity, max-width;
|
||||
margin-right: 2.5px;
|
||||
margin-left: 2.5px;
|
||||
overflow: hidden;
|
||||
.icon {
|
||||
&.flip {
|
||||
-webkit-transform:rotate(-180deg);
|
||||
-moz-transform:rotate(-180deg);
|
||||
-o-transform:rotate(-180deg);
|
||||
transform:rotate(-180deg);
|
||||
}
|
||||
&.octicon-git-merge,&.octicon-repo-forked, &.octicon-zap {
|
||||
margin-left: 3px;
|
||||
}
|
||||
&.octicon-history {
|
||||
margin-left: 2px;
|
||||
}
|
||||
&.glyphicon-remove,&.octicon-circuit-board {
|
||||
margin-left: 1px;
|
||||
}
|
||||
margin-right: 6px;
|
||||
}
|
||||
&.droparea {
|
||||
padding-left: 7px;
|
||||
}
|
||||
&.dimmed {
|
||||
opacity: 0.5;
|
||||
}
|
||||
&.push {
|
||||
background: rgba(61, 139, 255, 0.9);
|
||||
}
|
||||
&.pull {
|
||||
background: rgba(38, 189, 189, 0.9);
|
||||
}
|
||||
&.reset {
|
||||
background: rgba(255, 129, 31, 0.9);
|
||||
}
|
||||
&.rebase {
|
||||
background: rgba(65, 222, 60, 0.9);
|
||||
}
|
||||
&.move {
|
||||
width: auto;
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
&.merge {
|
||||
background: rgba(208, 135, 212, 0.9);
|
||||
}
|
||||
&.checkout {
|
||||
background: rgba(205, 219, 55, 0.9);
|
||||
}
|
||||
&.delete {
|
||||
background: rgba(214, 77, 56, 0.9);
|
||||
}
|
||||
&.cherry-pick {
|
||||
background: rgba(110, 156, 110, 0.9);
|
||||
}
|
||||
&.uncommit {
|
||||
background: rgba(158, 53, 20, 0.9);
|
||||
}
|
||||
&.revert {
|
||||
background: rgba(179, 135, 43, 0.9);
|
||||
}
|
||||
}
|
||||
.newRef {
|
||||
opacity: 1;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
margin-left: 5px;
|
||||
.showBranchingForm {
|
||||
background: transparent;
|
||||
border: 0px;
|
||||
cursor: pointer;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
margin-top: 9px;
|
||||
color: rgba(255, 255, 255, 0.3);
|
||||
&:hover {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
}
|
||||
.form-inline {
|
||||
display: inline-block;
|
||||
}
|
||||
input.name {
|
||||
width: 150px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.graphFooter {
|
||||
height: 60px;
|
||||
.progressBar {
|
||||
position: relative;
|
||||
top: -150px;
|
||||
margin-left: (@log-width-small);
|
||||
}
|
||||
}
|
||||
|
||||
.remote-icon {
|
||||
background: url('images/remoteIcon.png');
|
||||
width: 12px;
|
||||
height: 10px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.branch-icon {
|
||||
background: url('images/branchIcon.png');
|
||||
width: 9px;
|
||||
height: 10px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.tag-icon {
|
||||
background: url('images/tagIcon.png');
|
||||
width: 5px;
|
||||
height: 10px;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
77
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/hover-actions.js
generated
vendored
Normal file
77
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/hover-actions.js
generated
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
var getEdgeModelWithD = function(d, stroke, strokeWidth, strokeDasharray, markerEnd) {
|
||||
return { d: d,
|
||||
stroke: stroke ? stroke : '#4A4A4A',
|
||||
strokeWidth: strokeWidth ? strokeWidth : '8',
|
||||
strokeDasharray: strokeDasharray ? strokeDasharray : '10, 5',
|
||||
markerEnd: markerEnd ? markerEnd : '' };
|
||||
}
|
||||
|
||||
var getEdgeModel = function(scx, scy, tcx, tcy, stroke, strokeWidth, strokeDasharray, markerEnd) {
|
||||
return getEdgeModelWithD("M " + scx + " " + scy + " L " + tcx + " " + tcy, stroke, strokeWidth, strokeDasharray, markerEnd);
|
||||
}
|
||||
|
||||
var getNodeModel = function(cx, cy, r, fill, stroke, strokeWidth, strokeDasharray) {
|
||||
return { cx: cx,
|
||||
cy: cy,
|
||||
r: r,
|
||||
fill: fill,
|
||||
stroke: stroke ? stroke : '#41DE3C',
|
||||
strokeWidth: strokeWidth ? strokeWidth : '8',
|
||||
strokeDasharray: strokeDasharray ? strokeDasharray : '10, 5' };
|
||||
}
|
||||
|
||||
function HoverViewModel() {
|
||||
this.bgEdges = [];
|
||||
this.nodes = [];
|
||||
this.fgEdges = [];
|
||||
}
|
||||
|
||||
function MergeViewModel(graph, headNode, node) {
|
||||
var self = this;
|
||||
HoverViewModel.call(this);
|
||||
this.graph = graph;
|
||||
this.bgEdges = [ getEdgeModel(headNode.cx(), (headNode.cy() - 110), headNode.cx(), headNode.cy()),
|
||||
getEdgeModel(headNode.cx(), (headNode.cy() - 110), node.cx(), node.cy()) ];
|
||||
this.nodes = [ getNodeModel(headNode.cx(), headNode.cy() - 110, Math.max(headNode.r(), node.r()), '#252833', '#41DE3C', '8', '10, 5') ];
|
||||
|
||||
graph.dimCommit(true);
|
||||
}
|
||||
exports.MergeViewModel = MergeViewModel;
|
||||
MergeViewModel.prototype.destroy = function() {
|
||||
this.graph.dimCommit(false);
|
||||
}
|
||||
|
||||
function RebaseViewModel(onto, nodesThatWillMove) {
|
||||
var self = this;
|
||||
HoverViewModel.call(this);
|
||||
nodesThatWillMove = nodesThatWillMove.slice(0, -1);
|
||||
|
||||
if (nodesThatWillMove.length == 0) return;
|
||||
|
||||
this.bgEdges.push(getEdgeModel(onto.cx(), onto.cy(), onto.cx(), onto.cy() - 60));
|
||||
nodesThatWillMove.forEach(function(node, i) {
|
||||
var cy = onto.cy() + (-90 * (i + 1));
|
||||
self.nodes.push(getNodeModel(onto.cx(), cy, 28, 'transparent'));
|
||||
if (i + 1 < nodesThatWillMove.length) {
|
||||
self.bgEdges.push(getEdgeModel(onto.cx(), (cy - 25), onto.cx(), (cy - 65)));
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.RebaseViewModel = RebaseViewModel;
|
||||
|
||||
function ResetViewModel(nodes) {
|
||||
var self = this;
|
||||
HoverViewModel.call(this);
|
||||
|
||||
nodes.forEach(function(node) {
|
||||
self.fgEdges.push(getEdgeModelWithD(node.getLeftToRightStrike(), 'rgb(255, 129, 31)', '8', '0, 0'))
|
||||
self.fgEdges.push(getEdgeModelWithD(node.getRightToLeftStrike(), 'rgb(255, 129, 31)', '8', '0, 0'));
|
||||
});
|
||||
}
|
||||
exports.ResetViewModel = ResetViewModel;
|
||||
|
||||
function PushViewModel(fromNode, toNode) {
|
||||
HoverViewModel.call(this);
|
||||
this.fgEdges = [getEdgeModel(fromNode.cx(), fromNode.cy(), toNode.cx(), (toNode.cy() + 40), 'rgb(61, 139, 255)', '15', '10, 5', 'url(#pushArrowEnd)' )];
|
||||
}
|
||||
exports.PushViewModel = PushViewModel;
|
19
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/selectable.js
generated
vendored
Normal file
19
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/selectable.js
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
var ko = require('knockout');
|
||||
|
||||
var Selectable = function(graph) {
|
||||
this.selected = ko.computed({
|
||||
read: function() {
|
||||
return graph.currentActionContext() == this;
|
||||
},
|
||||
write: function(val) {
|
||||
// val is this if we're called from a click ko binding
|
||||
if (val === this || val === true) {
|
||||
graph.currentActionContext(this);
|
||||
} else if (graph.currentActionContext() == this) {
|
||||
graph.currentActionContext(null);
|
||||
}
|
||||
},
|
||||
owner: this
|
||||
});
|
||||
};
|
||||
module.exports = Selectable;
|
10
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/ungit-plugin.json
generated
vendored
Normal file
10
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/ungit-plugin.json
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"exports": {
|
||||
"knockoutTemplates": {
|
||||
"graph": "graph.html",
|
||||
"graphGraphics": "graph-graphics.html"
|
||||
},
|
||||
"javascript": "graph.bundle.js",
|
||||
"css": "graph.css"
|
||||
}
|
||||
}
|
43
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/header/header.bundle.js
generated
vendored
Normal file
43
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/header/header.bundle.js
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
|
||||
var ko = require('knockout');
|
||||
var components = require('ungit-components');
|
||||
var navigation = require('ungit-navigation');
|
||||
var programEvents = require('ungit-program-events');
|
||||
|
||||
components.register('header', function(args) {
|
||||
return new HeaderViewModel(args.app);
|
||||
});
|
||||
|
||||
function HeaderViewModel(app) {
|
||||
var self = this;
|
||||
this.app = app;
|
||||
this.showBackButton = ko.observable(false);
|
||||
this.path = ko.observable();
|
||||
this.currentVersion = ungit.version;
|
||||
this.refreshButton = components.create('refreshbutton');
|
||||
this.showAddToRepoListButton = ko.computed(function() {
|
||||
return self.path() && self.app.repoList().indexOf(self.path()) == -1;
|
||||
});
|
||||
}
|
||||
HeaderViewModel.prototype.updateNode = function(parentElement) {
|
||||
ko.renderTemplate('header', this, {}, parentElement);
|
||||
}
|
||||
HeaderViewModel.prototype.submitPath = function() {
|
||||
navigation.browseTo('repository?path=' + encodeURIComponent(this.path()));
|
||||
}
|
||||
HeaderViewModel.prototype.onProgramEvent = function(event) {
|
||||
if (event.event == 'navigation-changed') {
|
||||
this.showBackButton(event.path != '');
|
||||
if (event.path == '') this.path('');
|
||||
} else if (event.event == 'navigated-to-path') {
|
||||
this.path(event.path);
|
||||
}
|
||||
}
|
||||
HeaderViewModel.prototype.addCurrentPathToRepoList = function() {
|
||||
programEvents.dispatch({ event: 'request-remember-repo', repoPath: this.path() });
|
||||
return true;
|
||||
}
|
||||
|
||||
},{"knockout":"knockout","ungit-components":"ungit-components","ungit-navigation":"ungit-navigation","ungit-program-events":"ungit-program-events"}]},{},[1])
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJjb21wb25lbnRzL2hlYWRlci9oZWFkZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCJcbnZhciBrbyA9IHJlcXVpcmUoJ2tub2Nrb3V0Jyk7XG52YXIgY29tcG9uZW50cyA9IHJlcXVpcmUoJ3VuZ2l0LWNvbXBvbmVudHMnKTtcbnZhciBuYXZpZ2F0aW9uID0gcmVxdWlyZSgndW5naXQtbmF2aWdhdGlvbicpO1xudmFyIHByb2dyYW1FdmVudHMgPSByZXF1aXJlKCd1bmdpdC1wcm9ncmFtLWV2ZW50cycpO1xuXG5jb21wb25lbnRzLnJlZ2lzdGVyKCdoZWFkZXInLCBmdW5jdGlvbihhcmdzKSB7XG4gIHJldHVybiBuZXcgSGVhZGVyVmlld01vZGVsKGFyZ3MuYXBwKTtcbn0pO1xuXG5mdW5jdGlvbiBIZWFkZXJWaWV3TW9kZWwoYXBwKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdGhpcy5hcHAgPSBhcHA7XG4gIHRoaXMuc2hvd0JhY2tCdXR0b24gPSBrby5vYnNlcnZhYmxlKGZhbHNlKTtcbiAgdGhpcy5wYXRoID0ga28ub2JzZXJ2YWJsZSgpO1xuICB0aGlzLmN1cnJlbnRWZXJzaW9uID0gdW5naXQudmVyc2lvbjtcbiAgdGhpcy5yZWZyZXNoQnV0dG9uID0gY29tcG9uZW50cy5jcmVhdGUoJ3JlZnJlc2hidXR0b24nKTtcbiAgdGhpcy5zaG93QWRkVG9SZXBvTGlzdEJ1dHRvbiA9IGtvLmNvbXB1dGVkKGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBzZWxmLnBhdGgoKSAmJiBzZWxmLmFwcC5yZXBvTGlzdCgpLmluZGV4T2Yoc2VsZi5wYXRoKCkpID09IC0xO1xuICB9KTtcbn1cbkhlYWRlclZpZXdNb2RlbC5wcm90b3R5cGUudXBkYXRlTm9kZSA9IGZ1bmN0aW9uKHBhcmVudEVsZW1lbnQpIHtcbiAga28ucmVuZGVyVGVtcGxhdGUoJ2hlYWRlcicsIHRoaXMsIHt9LCBwYXJlbnRFbGVtZW50KTtcbn1cbkhlYWRlclZpZXdNb2RlbC5wcm90b3R5cGUuc3VibWl0UGF0aCA9IGZ1bmN0aW9uKCkge1xuICBuYXZpZ2F0aW9uLmJyb3dzZVRvKCdyZXBvc2l0b3J5P3BhdGg9JyArIGVuY29kZVVSSUNvbXBvbmVudCh0aGlzLnBhdGgoKSkpO1xufVxuSGVhZGVyVmlld01vZGVsLnByb3RvdHlwZS5vblByb2dyYW1FdmVudCA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gIGlmIChldmVudC5ldmVudCA9PSAnbmF2aWdhdGlvbi1jaGFuZ2VkJykge1xuICAgIHRoaXMuc2hvd0JhY2tCdXR0b24oZXZlbnQucGF0aCAhPSAnJyk7XG4gICAgaWYgKGV2ZW50LnBhdGggPT0gJycpIHRoaXMucGF0aCgnJyk7XG4gIH0gZWxzZSBpZiAoZXZlbnQuZXZlbnQgPT0gJ25hdmlnYXRlZC10by1wYXRoJykge1xuICAgIHRoaXMucGF0aChldmVudC5wYXRoKTtcbiAgfVxufVxuSGVhZGVyVmlld01vZGVsLnByb3RvdHlwZS5hZGRDdXJyZW50UGF0aFRvUmVwb0xpc3QgPSBmdW5jdGlvbigpIHtcbiAgcHJvZ3JhbUV2ZW50cy5kaXNwYXRjaCh7IGV2ZW50OiAncmVxdWVzdC1yZW1lbWJlci1yZXBvJywgcmVwb1BhdGg6IHRoaXMucGF0aCgpIH0pO1xuICByZXR1cm4gdHJ1ZTtcbn1cbiJdfQ==
|
72
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/header/header.css
generated
vendored
Normal file
72
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/header/header.css
generated
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
.navbarPadder {
|
||||
height: 81px;
|
||||
}
|
||||
.navbar {
|
||||
padding-top: 13px;
|
||||
z-index: 5;
|
||||
box-shadow: 0px 15px 15px #252833;
|
||||
height: 81px;
|
||||
}
|
||||
.navbar .backlink {
|
||||
margin-left: 9px;
|
||||
margin-top: 7px;
|
||||
position: absolute;
|
||||
color: #686868;
|
||||
}
|
||||
.navbar .backlink:hover {
|
||||
text-decoration: none;
|
||||
color: #A5A5A5;
|
||||
}
|
||||
.navbar .backlink .glyphicon-arrow-left {
|
||||
-webkit-transition: opacity 0.5s ease-in-out;
|
||||
-moz-transition: opacity 0.5s ease-in-out;
|
||||
transition: opacity 0.5s ease-in-out;
|
||||
opacity: 0;
|
||||
}
|
||||
.navbar .backlink .glyphicon-arrow-left.glyph-shown {
|
||||
opacity: 1;
|
||||
}
|
||||
.navbar .form-container {
|
||||
margin-left: 180px;
|
||||
margin-right: 107px;
|
||||
}
|
||||
.navbar .form-container .path-input-form {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
.navbar .form-container .path-input-form .form-control {
|
||||
font-size: 1.7em;
|
||||
width: 100%;
|
||||
}
|
||||
.navbar .form-container .path-input-form .add-to-repolist {
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
top: 6px;
|
||||
background: transparent;
|
||||
border: 0px;
|
||||
opacity: 0.3;
|
||||
}
|
||||
.navbar .form-container .path-input-form .add-to-repolist:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
.navbar .arrowUp {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
left: 300px;
|
||||
height: 0px;
|
||||
width: 0px;
|
||||
border-bottom: 15px solid #242832;
|
||||
border-right: 15px solid transparent;
|
||||
border-left: 15px solid transparent;
|
||||
}
|
||||
.navbar .version {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
bottom: 2px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.toolbar {
|
||||
position: absolute;
|
||||
right: 55px;
|
||||
top: 13px;
|
||||
}
|
25
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/header/header.html
generated
vendored
Normal file
25
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/header/header.html
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
<div class="navbar navbar-default navbar-fixed-top">
|
||||
|
||||
<a data-ta-clickable="home-link" class="backlink bootstrap-tooltip" href="#/" data-toggle="tooltip" data-placement="bottom" data-original-title="Navigate to Ungit home page" data-delay='{"show":"2000", "hide":"0"}'>
|
||||
<span class="glyphicon glyphicon-arrow-left glyphicon-circled" data-bind="css: { 'glyph-shown': showBackButton }"></span>
|
||||
<img src="images/logo.png">
|
||||
</a>
|
||||
|
||||
<div class="form-container">
|
||||
<form class="path-input-form" data-bind="submit: submitPath">
|
||||
<input data-ta-input="navigation-path" type="text" class="form-control input-lg" data-bind="value: path, autocomplete: path" placeholder="Enter path to repository">
|
||||
<button type="button" class="add-to-repolist btn btn-default bootstrap-tooltip" data-bind="visible: showAddToRepoListButton, click: addCurrentPathToRepoList" data-toggle="tooltip" data-placement="bottom" data-original-title="Add current git directory to Ungit home page" data-delay='{"show":"2000", "hide":"0"}'>
|
||||
<span class="glyphicon glyphicon-plus"></span>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="toolbar">
|
||||
<!-- ko component: refreshButton --><!-- /ko -->
|
||||
</div>
|
||||
|
||||
<div class="arrowUp"></div>
|
||||
<div class="version" data-bind="text: currentVersion"></div>
|
||||
</div>
|
||||
|
||||
<div class="navbarPadder"></div>
|
39
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/header/header.js
generated
vendored
Normal file
39
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/header/header.js
generated
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
|
||||
var ko = require('knockout');
|
||||
var components = require('ungit-components');
|
||||
var navigation = require('ungit-navigation');
|
||||
var programEvents = require('ungit-program-events');
|
||||
|
||||
components.register('header', function(args) {
|
||||
return new HeaderViewModel(args.app);
|
||||
});
|
||||
|
||||
function HeaderViewModel(app) {
|
||||
var self = this;
|
||||
this.app = app;
|
||||
this.showBackButton = ko.observable(false);
|
||||
this.path = ko.observable();
|
||||
this.currentVersion = ungit.version;
|
||||
this.refreshButton = components.create('refreshbutton');
|
||||
this.showAddToRepoListButton = ko.computed(function() {
|
||||
return self.path() && self.app.repoList().indexOf(self.path()) == -1;
|
||||
});
|
||||
}
|
||||
HeaderViewModel.prototype.updateNode = function(parentElement) {
|
||||
ko.renderTemplate('header', this, {}, parentElement);
|
||||
}
|
||||
HeaderViewModel.prototype.submitPath = function() {
|
||||
navigation.browseTo('repository?path=' + encodeURIComponent(this.path()));
|
||||
}
|
||||
HeaderViewModel.prototype.onProgramEvent = function(event) {
|
||||
if (event.event == 'navigation-changed') {
|
||||
this.showBackButton(event.path != '');
|
||||
if (event.path == '') this.path('');
|
||||
} else if (event.event == 'navigated-to-path') {
|
||||
this.path(event.path);
|
||||
}
|
||||
}
|
||||
HeaderViewModel.prototype.addCurrentPathToRepoList = function() {
|
||||
programEvents.dispatch({ event: 'request-remember-repo', repoPath: this.path() });
|
||||
return true;
|
||||
}
|
75
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/header/header.less
generated
vendored
Normal file
75
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/header/header.less
generated
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
|
||||
.navbarPadder {
|
||||
height: 81px;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
padding-top: 13px;
|
||||
z-index: 5;
|
||||
box-shadow: 0px 15px 15px #252833;
|
||||
height: 81px;
|
||||
|
||||
.backlink {
|
||||
margin-left: 9px;
|
||||
margin-top: 7px;
|
||||
position: absolute;
|
||||
color: #686868;
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
color: #A5A5A5;
|
||||
}
|
||||
.glyphicon-arrow-left {
|
||||
-webkit-transition: opacity 0.5s ease-in-out;
|
||||
-moz-transition: opacity 0.5s ease-in-out;
|
||||
transition: opacity 0.5s ease-in-out;
|
||||
opacity: 0;
|
||||
&.glyph-shown {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
.form-container {
|
||||
margin-left: 180px;
|
||||
margin-right: 107px;
|
||||
.path-input-form {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
.form-control {
|
||||
font-size: 1.7em;
|
||||
width: 100%;
|
||||
}
|
||||
.add-to-repolist {
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
top: 6px;
|
||||
background: transparent;
|
||||
border: 0px;
|
||||
opacity: 0.3;
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.arrowUp {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
left: 300px;
|
||||
height: 0px;
|
||||
width: 0px;
|
||||
border-bottom: 15px solid #242832;
|
||||
border-right: 15px solid transparent;
|
||||
border-left: 15px solid transparent;
|
||||
}
|
||||
.version {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
bottom: 2px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
.toolbar {
|
||||
position: absolute;
|
||||
right: 55px;
|
||||
top: 13px;
|
||||
}
|
9
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/header/ungit-plugin.json
generated
vendored
Normal file
9
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/header/ungit-plugin.json
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"exports": {
|
||||
"knockoutTemplates": {
|
||||
"header": "header.html"
|
||||
},
|
||||
"javascript": "header.bundle.js",
|
||||
"css": "header.css"
|
||||
}
|
||||
}
|
66
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/home/home.bundle.js
generated
vendored
Normal file
66
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/home/home.bundle.js
generated
vendored
Normal file
|
@ -0,0 +1,66 @@
|
|||
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
|
||||
var ko = require('knockout');
|
||||
var components = require('ungit-components');
|
||||
|
||||
components.register('home', function(args) {
|
||||
return new HomeViewModel(args.app);
|
||||
});
|
||||
|
||||
function HomeRepositoryViewModel(home, path) {
|
||||
this.home = home;
|
||||
this.app = home.app;
|
||||
this.server = this.app.server;
|
||||
this.path = path;
|
||||
this.title = path;
|
||||
this.link = '/#/repository?path=' + encodeURIComponent(path);
|
||||
this.pathRemoved = ko.observable(false);
|
||||
this.remote = ko.observable('...');
|
||||
this.updateState();
|
||||
}
|
||||
HomeRepositoryViewModel.prototype.updateState = function() {
|
||||
var self = this;
|
||||
this.server.get('/fs/exists?path=' + encodeURIComponent(this.path), undefined, function(err, exists) {
|
||||
self.pathRemoved(!exists);
|
||||
});
|
||||
this.server.get('/remotes/origin?path=' + encodeURIComponent(this.path), undefined, function(err, remote) {
|
||||
if (err) {
|
||||
self.remote('');
|
||||
return true;
|
||||
}
|
||||
self.remote(remote.address);
|
||||
});
|
||||
}
|
||||
HomeRepositoryViewModel.prototype.remove = function() {
|
||||
this.app.repoList.remove(this.path);
|
||||
this.home.update();
|
||||
}
|
||||
|
||||
function HomeViewModel(app) {
|
||||
var self = this;
|
||||
this.app = app;
|
||||
this.repos = ko.observableArray();
|
||||
this.showNux = ko.computed(function() {
|
||||
return self.repos().length == 0;
|
||||
});
|
||||
}
|
||||
HomeViewModel.prototype.updateNode = function(parentElement) {
|
||||
ko.renderTemplate('home', this, {}, parentElement);
|
||||
}
|
||||
HomeViewModel.prototype.template = 'home';
|
||||
HomeViewModel.prototype.shown = function() {
|
||||
this.update();
|
||||
}
|
||||
HomeViewModel.prototype.update = function() {
|
||||
var self = this;
|
||||
var reposByPath = {};
|
||||
this.repos().forEach(function(repo) { reposByPath[repo.path] = repo; });
|
||||
this.repos(this.app.repoList().sort().map(function(path) {
|
||||
if (!reposByPath[path])
|
||||
reposByPath[path] = new HomeRepositoryViewModel(self, path);
|
||||
return reposByPath[path];
|
||||
}));
|
||||
}
|
||||
|
||||
},{"knockout":"knockout","ungit-components":"ungit-components"}]},{},[1])
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJjb21wb25lbnRzL2hvbWUvaG9tZS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCJcbnZhciBrbyA9IHJlcXVpcmUoJ2tub2Nrb3V0Jyk7XG52YXIgY29tcG9uZW50cyA9IHJlcXVpcmUoJ3VuZ2l0LWNvbXBvbmVudHMnKTtcblxuY29tcG9uZW50cy5yZWdpc3RlcignaG9tZScsIGZ1bmN0aW9uKGFyZ3MpIHtcbiAgcmV0dXJuIG5ldyBIb21lVmlld01vZGVsKGFyZ3MuYXBwKTtcbn0pO1xuXG5mdW5jdGlvbiBIb21lUmVwb3NpdG9yeVZpZXdNb2RlbChob21lLCBwYXRoKSB7XG4gIHRoaXMuaG9tZSA9IGhvbWU7XG4gIHRoaXMuYXBwID0gaG9tZS5hcHA7XG4gIHRoaXMuc2VydmVyID0gdGhpcy5hcHAuc2VydmVyO1xuICB0aGlzLnBhdGggPSBwYXRoO1xuICB0aGlzLnRpdGxlID0gcGF0aDtcbiAgdGhpcy5saW5rID0gJy8jL3JlcG9zaXRvcnk/cGF0aD0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHBhdGgpO1xuICB0aGlzLnBhdGhSZW1vdmVkID0ga28ub2JzZXJ2YWJsZShmYWxzZSk7XG4gIHRoaXMucmVtb3RlID0ga28ub2JzZXJ2YWJsZSgnLi4uJyk7XG4gIHRoaXMudXBkYXRlU3RhdGUoKTtcbn1cbkhvbWVSZXBvc2l0b3J5Vmlld01vZGVsLnByb3RvdHlwZS51cGRhdGVTdGF0ZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuc2VydmVyLmdldCgnL2ZzL2V4aXN0cz9wYXRoPScgKyBlbmNvZGVVUklDb21wb25lbnQodGhpcy5wYXRoKSwgdW5kZWZpbmVkLCBmdW5jdGlvbihlcnIsIGV4aXN0cykge1xuICAgIHNlbGYucGF0aFJlbW92ZWQoIWV4aXN0cyk7XG4gIH0pO1xuICB0aGlzLnNlcnZlci5nZXQoJy9yZW1vdGVzL29yaWdpbj9wYXRoPScgKyBlbmNvZGVVUklDb21wb25lbnQodGhpcy5wYXRoKSwgdW5kZWZpbmVkLCBmdW5jdGlvbihlcnIsIHJlbW90ZSkge1xuICAgIGlmIChlcnIpIHtcbiAgICAgIHNlbGYucmVtb3RlKCcnKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBzZWxmLnJlbW90ZShyZW1vdGUuYWRkcmVzcyk7XG4gIH0pO1xufVxuSG9tZVJlcG9zaXRvcnlWaWV3TW9kZWwucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLmFwcC5yZXBvTGlzdC5yZW1vdmUodGhpcy5wYXRoKTtcbiAgdGhpcy5ob21lLnVwZGF0ZSgpO1xufVxuXG5mdW5jdGlvbiBIb21lVmlld01vZGVsKGFwcCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuYXBwID0gYXBwO1xuICB0aGlzLnJlcG9zID0ga28ub2JzZXJ2YWJsZUFycmF5KCk7XG4gIHRoaXMuc2hvd051eCA9IGtvLmNvbXB1dGVkKGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBzZWxmLnJlcG9zKCkubGVuZ3RoID09IDA7XG4gIH0pO1xufVxuSG9tZVZpZXdNb2RlbC5wcm90b3R5cGUudXBkYXRlTm9kZSA9IGZ1bmN0aW9uKHBhcmVudEVsZW1lbnQpIHtcbiAga28ucmVuZGVyVGVtcGxhdGUoJ2hvbWUnLCB0aGlzLCB7fSwgcGFyZW50RWxlbWVudCk7XG59XG5Ib21lVmlld01vZGVsLnByb3RvdHlwZS50ZW1wbGF0ZSA9ICdob21lJztcbkhvbWVWaWV3TW9kZWwucHJvdG90eXBlLnNob3duID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMudXBkYXRlKCk7XG59XG5Ib21lVmlld01vZGVsLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgcmVwb3NCeVBhdGggPSB7fTtcbiAgdGhpcy5yZXBvcygpLmZvckVhY2goZnVuY3Rpb24ocmVwbykgeyByZXBvc0J5UGF0aFtyZXBvLnBhdGhdID0gcmVwbzsgfSk7XG4gIHRoaXMucmVwb3ModGhpcy5hcHAucmVwb0xpc3QoKS5zb3J0KCkubWFwKGZ1bmN0aW9uKHBhdGgpIHtcbiAgICBpZiAoIXJlcG9zQnlQYXRoW3BhdGhdKVxuICAgICAgcmVwb3NCeVBhdGhbcGF0aF0gPSBuZXcgSG9tZVJlcG9zaXRvcnlWaWV3TW9kZWwoc2VsZiwgcGF0aCk7XG4gICAgcmV0dXJuIHJlcG9zQnlQYXRoW3BhdGhdO1xuICB9KSk7XG59XG4iXX0=
|
20
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/home/home.css
generated
vendored
Normal file
20
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/home/home.css
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
.home .nux {
|
||||
text-align: center;
|
||||
}
|
||||
.home .nux .logo-large {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
.home .repository {
|
||||
position: relative;
|
||||
min-height: 62px;
|
||||
}
|
||||
.home .repository.path-removed .list-group-item-heading {
|
||||
color: #CF5353;
|
||||
}
|
||||
.home .repository .glyphicon {
|
||||
color: #686868;
|
||||
}
|
||||
.home .repository:hover .glyphicon {
|
||||
color: #A5A5A5;
|
||||
}
|
18
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/home/home.html
generated
vendored
Normal file
18
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/home/home.html
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
|
||||
<div class="container home animated fadeInLeft" data-ta-container="home-page" data-bind="shown: shown">
|
||||
<div class="nux" data-bind="visible: showNux">
|
||||
<img src="images/logoLarge.png" class="logo-large">
|
||||
<div class="alert alert-info">
|
||||
<h4>Enter a path to a repository to get started!</h4>
|
||||
Then press the <span class="glyphicon glyphicon-plus"></span> symbol to make it show up here.
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-group" data-bind="foreach: repos">
|
||||
<a class="list-group-item repository" data-bind="attr: { href: link }, css: { 'path-removed': pathRemoved }">
|
||||
<span class="glyphicon glyphicon-arrow-right glyphicon-circled pull-left"></span>
|
||||
<h4 class="list-group-item-heading" data-bind="text: title"></h4>
|
||||
<p class="list-group-item-text" data-bind="text: remote"></p>
|
||||
<button type="button" class="btn btn-default list-item-remove" data-bind="click: remove">✖</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
62
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/home/home.js
generated
vendored
Normal file
62
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/home/home.js
generated
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
|
||||
var ko = require('knockout');
|
||||
var components = require('ungit-components');
|
||||
|
||||
components.register('home', function(args) {
|
||||
return new HomeViewModel(args.app);
|
||||
});
|
||||
|
||||
function HomeRepositoryViewModel(home, path) {
|
||||
this.home = home;
|
||||
this.app = home.app;
|
||||
this.server = this.app.server;
|
||||
this.path = path;
|
||||
this.title = path;
|
||||
this.link = '/#/repository?path=' + encodeURIComponent(path);
|
||||
this.pathRemoved = ko.observable(false);
|
||||
this.remote = ko.observable('...');
|
||||
this.updateState();
|
||||
}
|
||||
HomeRepositoryViewModel.prototype.updateState = function() {
|
||||
var self = this;
|
||||
this.server.get('/fs/exists?path=' + encodeURIComponent(this.path), undefined, function(err, exists) {
|
||||
self.pathRemoved(!exists);
|
||||
});
|
||||
this.server.get('/remotes/origin?path=' + encodeURIComponent(this.path), undefined, function(err, remote) {
|
||||
if (err) {
|
||||
self.remote('');
|
||||
return true;
|
||||
}
|
||||
self.remote(remote.address);
|
||||
});
|
||||
}
|
||||
HomeRepositoryViewModel.prototype.remove = function() {
|
||||
this.app.repoList.remove(this.path);
|
||||
this.home.update();
|
||||
}
|
||||
|
||||
function HomeViewModel(app) {
|
||||
var self = this;
|
||||
this.app = app;
|
||||
this.repos = ko.observableArray();
|
||||
this.showNux = ko.computed(function() {
|
||||
return self.repos().length == 0;
|
||||
});
|
||||
}
|
||||
HomeViewModel.prototype.updateNode = function(parentElement) {
|
||||
ko.renderTemplate('home', this, {}, parentElement);
|
||||
}
|
||||
HomeViewModel.prototype.template = 'home';
|
||||
HomeViewModel.prototype.shown = function() {
|
||||
this.update();
|
||||
}
|
||||
HomeViewModel.prototype.update = function() {
|
||||
var self = this;
|
||||
var reposByPath = {};
|
||||
this.repos().forEach(function(repo) { reposByPath[repo.path] = repo; });
|
||||
this.repos(this.app.repoList().sort().map(function(path) {
|
||||
if (!reposByPath[path])
|
||||
reposByPath[path] = new HomeRepositoryViewModel(self, path);
|
||||
return reposByPath[path];
|
||||
}));
|
||||
}
|
25
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/home/home.less
generated
vendored
Normal file
25
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/home/home.less
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
.home {
|
||||
.nux {
|
||||
text-align: center;
|
||||
.logo-large {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
}
|
||||
.repository {
|
||||
position: relative;
|
||||
min-height: 62px;
|
||||
&.path-removed {
|
||||
.list-group-item-heading {
|
||||
color: #CF5353;
|
||||
}
|
||||
}
|
||||
.glyphicon {
|
||||
color: #686868;
|
||||
}
|
||||
&:hover .glyphicon {
|
||||
color: #A5A5A5;
|
||||
}
|
||||
}
|
||||
}
|
9
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/home/ungit-plugin.json
generated
vendored
Normal file
9
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/home/ungit-plugin.json
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"exports": {
|
||||
"knockoutTemplates": {
|
||||
"home": "home.html"
|
||||
},
|
||||
"javascript": "home.bundle.js",
|
||||
"css": "home.css"
|
||||
}
|
||||
}
|
44
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/imagediff/imagediff.bundle.js
generated
vendored
Normal file
44
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/imagediff/imagediff.bundle.js
generated
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
|
||||
var ko = require('knockout');
|
||||
var components = require('ungit-components');
|
||||
|
||||
components.register('imagediff', function(args) {
|
||||
return new ImageDiffViewModel(args);
|
||||
});
|
||||
|
||||
var ImageDiffViewModel = function(args) {
|
||||
var self = this;
|
||||
this.filename = args.filename;
|
||||
this.repoPath = args.repoPath;
|
||||
this.isNew = ko.observable(false);
|
||||
this.isRemoved = ko.observable(false);
|
||||
this.sha1 = args.sha1;
|
||||
this.state = ko.computed(function() {
|
||||
if (self.isNew()) return 'new';
|
||||
if (self.isRemoved()) return 'removed';
|
||||
return 'changed';
|
||||
});
|
||||
this.oldImageSrc = ko.computed(function() {
|
||||
return '/api/diff/image?path=' + encodeURIComponent(self.repoPath()) + '&filename=' + self.filename + '&version=' + (self.sha1 ? self.sha1 + '^': 'HEAD');
|
||||
});
|
||||
this.newImageSrc = ko.computed(function() {
|
||||
return '/api/diff/image?path=' + encodeURIComponent(self.repoPath()) + '&filename=' + self.filename + '&version=' + (self.sha1 ? self.sha1: 'current');
|
||||
});
|
||||
this.isShowingDiffs = args.isShowingDiffs;
|
||||
}
|
||||
ImageDiffViewModel.prototype.updateNode = function(parentElement) {
|
||||
ko.renderTemplate('imagediff', this, {}, parentElement);
|
||||
}
|
||||
ImageDiffViewModel.prototype.invalidateDiff = function(callback) {
|
||||
if (callback) callback();
|
||||
}
|
||||
ImageDiffViewModel.prototype.newImageError = function(data, event) {
|
||||
this.isRemoved(true);
|
||||
}
|
||||
ImageDiffViewModel.prototype.oldImageError = function(data, event) {
|
||||
this.isNew(true);
|
||||
}
|
||||
|
||||
},{"knockout":"knockout","ungit-components":"ungit-components"}]},{},[1])
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJjb21wb25lbnRzL2ltYWdlZGlmZi9pbWFnZWRpZmYuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIlxudmFyIGtvID0gcmVxdWlyZSgna25vY2tvdXQnKTtcbnZhciBjb21wb25lbnRzID0gcmVxdWlyZSgndW5naXQtY29tcG9uZW50cycpO1xuXG5jb21wb25lbnRzLnJlZ2lzdGVyKCdpbWFnZWRpZmYnLCBmdW5jdGlvbihhcmdzKSB7XG4gIHJldHVybiBuZXcgSW1hZ2VEaWZmVmlld01vZGVsKGFyZ3MpO1xufSk7XG5cbnZhciBJbWFnZURpZmZWaWV3TW9kZWwgPSBmdW5jdGlvbihhcmdzKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdGhpcy5maWxlbmFtZSA9IGFyZ3MuZmlsZW5hbWU7XG4gIHRoaXMucmVwb1BhdGggPSBhcmdzLnJlcG9QYXRoO1xuICB0aGlzLmlzTmV3ID0ga28ub2JzZXJ2YWJsZShmYWxzZSk7XG4gIHRoaXMuaXNSZW1vdmVkID0ga28ub2JzZXJ2YWJsZShmYWxzZSk7XG4gIHRoaXMuc2hhMSA9IGFyZ3Muc2hhMTtcbiAgdGhpcy5zdGF0ZSA9IGtvLmNvbXB1dGVkKGZ1bmN0aW9uKCkge1xuICAgIGlmIChzZWxmLmlzTmV3KCkpIHJldHVybiAnbmV3JztcbiAgICBpZiAoc2VsZi5pc1JlbW92ZWQoKSkgcmV0dXJuICdyZW1vdmVkJztcbiAgICByZXR1cm4gJ2NoYW5nZWQnO1xuICB9KTtcbiAgdGhpcy5vbGRJbWFnZVNyYyA9IGtvLmNvbXB1dGVkKGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiAnL2FwaS9kaWZmL2ltYWdlP3BhdGg9JyArIGVuY29kZVVSSUNvbXBvbmVudChzZWxmLnJlcG9QYXRoKCkpICsgJyZmaWxlbmFtZT0nICsgc2VsZi5maWxlbmFtZSArICcmdmVyc2lvbj0nICsgKHNlbGYuc2hhMSA/IHNlbGYuc2hhMSArICdeJzogJ0hFQUQnKTtcbiAgfSk7XG4gIHRoaXMubmV3SW1hZ2VTcmMgPSBrby5jb21wdXRlZChmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gJy9hcGkvZGlmZi9pbWFnZT9wYXRoPScgKyBlbmNvZGVVUklDb21wb25lbnQoc2VsZi5yZXBvUGF0aCgpKSArICcmZmlsZW5hbWU9JyArIHNlbGYuZmlsZW5hbWUgKyAnJnZlcnNpb249JyArIChzZWxmLnNoYTEgPyBzZWxmLnNoYTE6ICdjdXJyZW50Jyk7XG4gIH0pO1xuICB0aGlzLmlzU2hvd2luZ0RpZmZzID0gYXJncy5pc1Nob3dpbmdEaWZmcztcbn1cbkltYWdlRGlmZlZpZXdNb2RlbC5wcm90b3R5cGUudXBkYXRlTm9kZSA9IGZ1bmN0aW9uKHBhcmVudEVsZW1lbnQpIHtcbiAga28ucmVuZGVyVGVtcGxhdGUoJ2ltYWdlZGlmZicsIHRoaXMsIHt9LCBwYXJlbnRFbGVtZW50KTtcbn1cbkltYWdlRGlmZlZpZXdNb2RlbC5wcm90b3R5cGUuaW52YWxpZGF0ZURpZmYgPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICBpZiAoY2FsbGJhY2spIGNhbGxiYWNrKCk7XG59XG5JbWFnZURpZmZWaWV3TW9kZWwucHJvdG90eXBlLm5ld0ltYWdlRXJyb3IgPSBmdW5jdGlvbihkYXRhLCBldmVudCkge1xuICB0aGlzLmlzUmVtb3ZlZCh0cnVlKTtcbn1cbkltYWdlRGlmZlZpZXdNb2RlbC5wcm90b3R5cGUub2xkSW1hZ2VFcnJvciA9IGZ1bmN0aW9uKGRhdGEsIGV2ZW50KSB7XG4gIHRoaXMuaXNOZXcodHJ1ZSk7XG59XG4iXX0=
|
16
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/imagediff/imagediff.css
generated
vendored
Normal file
16
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/imagediff/imagediff.css
generated
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
.imageDiff {
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
.imageDiff .glyphicon-arrow-right {
|
||||
font-size: 104px;
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
.img-removed {
|
||||
background-color: rgba(230, 70, 100, 0.2);
|
||||
margin-top: 20px;
|
||||
}
|
||||
.img-added {
|
||||
background-color: rgba(70, 230, 100, 0.2);
|
||||
margin-top: 20px;
|
||||
}
|
27
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/imagediff/imagediff.html
generated
vendored
Normal file
27
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/imagediff/imagediff.html
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
<!-- ko if: isShowingDiffs -->
|
||||
<!-- ko if: state() == 'new' -->
|
||||
<div class="imageDiff img-added">
|
||||
<img data-bind="attr: { src: newImageSrc }" class="img-responsive">
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
<!-- ko if: state() == 'removed' -->
|
||||
<div class="imageDiff img-removed">
|
||||
<img data-bind="attr: { src: oldImageSrc }" class="img-responsive img-removed">
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
<!-- ko if: state() == 'changed' -->
|
||||
<div class="imageDiff">
|
||||
<div class="row">
|
||||
<div class="col-lg-5">
|
||||
<img data-bind="event: {error: oldImageError }, attr: { src: oldImageSrc }" class="img-responsive">
|
||||
</div>
|
||||
<div class="col-lg-2">
|
||||
<span class="glyphicon glyphicon-arrow-right"></span>
|
||||
</div>
|
||||
<div class="col-lg-5">
|
||||
<img data-bind="event: {error: newImageError }, attr: { src: newImageSrc }" class="img-responsive">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
<!-- /ko -->
|
40
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/imagediff/imagediff.js
generated
vendored
Normal file
40
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/imagediff/imagediff.js
generated
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
|
||||
var ko = require('knockout');
|
||||
var components = require('ungit-components');
|
||||
|
||||
components.register('imagediff', function(args) {
|
||||
return new ImageDiffViewModel(args);
|
||||
});
|
||||
|
||||
var ImageDiffViewModel = function(args) {
|
||||
var self = this;
|
||||
this.filename = args.filename;
|
||||
this.repoPath = args.repoPath;
|
||||
this.isNew = ko.observable(false);
|
||||
this.isRemoved = ko.observable(false);
|
||||
this.sha1 = args.sha1;
|
||||
this.state = ko.computed(function() {
|
||||
if (self.isNew()) return 'new';
|
||||
if (self.isRemoved()) return 'removed';
|
||||
return 'changed';
|
||||
});
|
||||
this.oldImageSrc = ko.computed(function() {
|
||||
return '/api/diff/image?path=' + encodeURIComponent(self.repoPath()) + '&filename=' + self.filename + '&version=' + (self.sha1 ? self.sha1 + '^': 'HEAD');
|
||||
});
|
||||
this.newImageSrc = ko.computed(function() {
|
||||
return '/api/diff/image?path=' + encodeURIComponent(self.repoPath()) + '&filename=' + self.filename + '&version=' + (self.sha1 ? self.sha1: 'current');
|
||||
});
|
||||
this.isShowingDiffs = args.isShowingDiffs;
|
||||
}
|
||||
ImageDiffViewModel.prototype.updateNode = function(parentElement) {
|
||||
ko.renderTemplate('imagediff', this, {}, parentElement);
|
||||
}
|
||||
ImageDiffViewModel.prototype.invalidateDiff = function(callback) {
|
||||
if (callback) callback();
|
||||
}
|
||||
ImageDiffViewModel.prototype.newImageError = function(data, event) {
|
||||
this.isRemoved(true);
|
||||
}
|
||||
ImageDiffViewModel.prototype.oldImageError = function(data, event) {
|
||||
this.isNew(true);
|
||||
}
|
19
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/imagediff/imagediff.less
generated
vendored
Normal file
19
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/imagediff/imagediff.less
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
|
||||
.imageDiff {
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
.glyphicon-arrow-right {
|
||||
font-size: 104px;
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
.img-removed {
|
||||
background-color: rgba(230, 70, 100, 0.2);
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.img-added {
|
||||
background-color: rgba(70, 230, 100, 0.2);
|
||||
margin-top: 20px;
|
||||
}
|
9
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/imagediff/ungit-plugin.json
generated
vendored
Normal file
9
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/imagediff/ungit-plugin.json
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"exports": {
|
||||
"knockoutTemplates": {
|
||||
"imagediff": "imagediff.html"
|
||||
},
|
||||
"javascript": "imagediff.bundle.js",
|
||||
"css": "imagediff.css"
|
||||
}
|
||||
}
|
47
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/login/login.bundle.js
generated
vendored
Normal file
47
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/login/login.bundle.js
generated
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
|
||||
var ko = require('knockout');
|
||||
var components = require('ungit-components');
|
||||
var signals = require('signals');
|
||||
|
||||
components.register('login', function(args) {
|
||||
return new LoginViewModel(args.server);
|
||||
});
|
||||
|
||||
var LoginViewModel = function(server) {
|
||||
var self = this;
|
||||
this.server = server;
|
||||
this.loggedIn = new signals.Signal();
|
||||
this.status = ko.observable('loading');
|
||||
this.username = ko.observable();
|
||||
this.password = ko.observable();
|
||||
this.loginError = ko.observable();
|
||||
this.server.get('/loggedin', undefined, function(err, status) {
|
||||
if (status.loggedIn) {
|
||||
self.loggedIn.dispatch();
|
||||
self.status('loggedIn');
|
||||
}
|
||||
else self.status('login');
|
||||
});
|
||||
}
|
||||
LoginViewModel.prototype.updateNode = function(parentElement) {
|
||||
ko.renderTemplate('login', this, {}, parentElement);
|
||||
}
|
||||
LoginViewModel.prototype.login = function() {
|
||||
var self = this;
|
||||
this.server.post('/login', { username: this.username(), password: this.password() }, function(err, res) {
|
||||
if (err) {
|
||||
if (err.res.body.error) {
|
||||
self.loginError(err.res.body.error);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
self.loggedIn.dispatch();
|
||||
self.status('loggedIn');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
},{"knockout":"knockout","signals":undefined,"ungit-components":"ungit-components"}]},{},[1])
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJjb21wb25lbnRzL2xvZ2luL2xvZ2luLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCJcbnZhciBrbyA9IHJlcXVpcmUoJ2tub2Nrb3V0Jyk7XG52YXIgY29tcG9uZW50cyA9IHJlcXVpcmUoJ3VuZ2l0LWNvbXBvbmVudHMnKTtcbnZhciBzaWduYWxzID0gcmVxdWlyZSgnc2lnbmFscycpO1xuXG5jb21wb25lbnRzLnJlZ2lzdGVyKCdsb2dpbicsIGZ1bmN0aW9uKGFyZ3MpIHtcbiAgcmV0dXJuIG5ldyBMb2dpblZpZXdNb2RlbChhcmdzLnNlcnZlcik7XG59KTtcblxudmFyIExvZ2luVmlld01vZGVsID0gZnVuY3Rpb24oc2VydmVyKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdGhpcy5zZXJ2ZXIgPSBzZXJ2ZXI7XG4gIHRoaXMubG9nZ2VkSW4gPSBuZXcgc2lnbmFscy5TaWduYWwoKTtcbiAgdGhpcy5zdGF0dXMgPSBrby5vYnNlcnZhYmxlKCdsb2FkaW5nJyk7XG4gIHRoaXMudXNlcm5hbWUgPSBrby5vYnNlcnZhYmxlKCk7XG4gIHRoaXMucGFzc3dvcmQgPSBrby5vYnNlcnZhYmxlKCk7XG4gIHRoaXMubG9naW5FcnJvciA9IGtvLm9ic2VydmFibGUoKTtcbiAgdGhpcy5zZXJ2ZXIuZ2V0KCcvbG9nZ2VkaW4nLCB1bmRlZmluZWQsIGZ1bmN0aW9uKGVyciwgc3RhdHVzKSB7XG4gICAgaWYgKHN0YXR1cy5sb2dnZWRJbikge1xuICAgICAgc2VsZi5sb2dnZWRJbi5kaXNwYXRjaCgpO1xuICAgICAgc2VsZi5zdGF0dXMoJ2xvZ2dlZEluJyk7XG4gICAgfVxuICAgIGVsc2Ugc2VsZi5zdGF0dXMoJ2xvZ2luJyk7XG4gIH0pO1xufVxuTG9naW5WaWV3TW9kZWwucHJvdG90eXBlLnVwZGF0ZU5vZGUgPSBmdW5jdGlvbihwYXJlbnRFbGVtZW50KSB7XG4gIGtvLnJlbmRlclRlbXBsYXRlKCdsb2dpbicsIHRoaXMsIHt9LCBwYXJlbnRFbGVtZW50KTtcbn1cbkxvZ2luVmlld01vZGVsLnByb3RvdHlwZS5sb2dpbiA9IGZ1bmN0aW9uKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuc2VydmVyLnBvc3QoJy9sb2dpbicsIHsgdXNlcm5hbWU6IHRoaXMudXNlcm5hbWUoKSwgcGFzc3dvcmQ6IHRoaXMucGFzc3dvcmQoKSB9LCBmdW5jdGlvbihlcnIsIHJlcykge1xuICAgIGlmIChlcnIpIHtcbiAgICAgIGlmIChlcnIucmVzLmJvZHkuZXJyb3IpIHtcbiAgICAgICAgc2VsZi5sb2dpbkVycm9yKGVyci5yZXMuYm9keS5lcnJvcik7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzZWxmLmxvZ2dlZEluLmRpc3BhdGNoKCk7XG4gICAgICBzZWxmLnN0YXR1cygnbG9nZ2VkSW4nKTtcbiAgICB9XG4gIH0pO1xufVxuXG4iXX0=
|
26
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/login/login.html
generated
vendored
Normal file
26
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/login/login.html
generated
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
|
||||
<div class="container">
|
||||
<div data-bind="visible: status() == 'loading'">
|
||||
</div>
|
||||
|
||||
<div class='login col-lg-6' data-bind="visible: status() == 'login'" data-ta-container="login-page">
|
||||
<h1>Login</h1>
|
||||
<!-- ko if: loginError -->
|
||||
<div class="loginError" data-ta-element="login-error" data-bind="text: loginError"></div>
|
||||
<!-- /ko -->
|
||||
<form data-bind="submit: login" role="form">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="inputUsername">Username</label>
|
||||
<input type="text" class="form-control" id="inputUsername" placeholder="Username" data-bind="value: username" data-ta-input="username">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="inputPassword">Password</label>
|
||||
<input type="password" class="form-control" id="inputPassword" placeholder="Password" data-bind="value: password" data-ta-input="password">
|
||||
</div>
|
||||
|
||||
<input type="submit" class="btn btn-primary" value="Login" data-ta-clickable="submit">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
43
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/login/login.js
generated
vendored
Normal file
43
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/login/login.js
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
|
||||
var ko = require('knockout');
|
||||
var components = require('ungit-components');
|
||||
var signals = require('signals');
|
||||
|
||||
components.register('login', function(args) {
|
||||
return new LoginViewModel(args.server);
|
||||
});
|
||||
|
||||
var LoginViewModel = function(server) {
|
||||
var self = this;
|
||||
this.server = server;
|
||||
this.loggedIn = new signals.Signal();
|
||||
this.status = ko.observable('loading');
|
||||
this.username = ko.observable();
|
||||
this.password = ko.observable();
|
||||
this.loginError = ko.observable();
|
||||
this.server.get('/loggedin', undefined, function(err, status) {
|
||||
if (status.loggedIn) {
|
||||
self.loggedIn.dispatch();
|
||||
self.status('loggedIn');
|
||||
}
|
||||
else self.status('login');
|
||||
});
|
||||
}
|
||||
LoginViewModel.prototype.updateNode = function(parentElement) {
|
||||
ko.renderTemplate('login', this, {}, parentElement);
|
||||
}
|
||||
LoginViewModel.prototype.login = function() {
|
||||
var self = this;
|
||||
this.server.post('/login', { username: this.username(), password: this.password() }, function(err, res) {
|
||||
if (err) {
|
||||
if (err.res.body.error) {
|
||||
self.loginError(err.res.body.error);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
self.loggedIn.dispatch();
|
||||
self.status('loggedIn');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
8
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/login/ungit-plugin.json
generated
vendored
Normal file
8
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/login/ungit-plugin.json
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"exports": {
|
||||
"knockoutTemplates": {
|
||||
"login": "login.html"
|
||||
},
|
||||
"javascript": "login.bundle.js"
|
||||
}
|
||||
}
|
109
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/path/path.bundle.js
generated
vendored
Normal file
109
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/path/path.bundle.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
74
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/path/path.html
generated
vendored
Normal file
74
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/path/path.html
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
|
||||
<div class="path" data-bind="shown: shown" data-ta-container="path-page">
|
||||
|
||||
<!-- ko if: status() == 'loading' -->
|
||||
<div class='animated fadeInLeft'>
|
||||
<!-- ko component: loadingProgressBar --><!-- /ko -->
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
|
||||
<!-- ko if: status() == 'cloning' -->
|
||||
<div class='animated fadeInLeft'>
|
||||
<h2>Cloning...</h2>
|
||||
<!-- ko component: cloningProgressBar --><!-- /ko -->
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
|
||||
<!-- ko if: status() == 'uninited' -->
|
||||
<div class="uninited" data-ta-container="uninited-path-page">
|
||||
<div class="container">
|
||||
<div class="alert alert-info" data-bind="visible: showDirectoryCreatedAlert">
|
||||
Directory '<span data-bind="text: dirName"></span>' created
|
||||
</div>
|
||||
<h1>'<span data-bind="text: dirName"></span>' is not a repository</h1>
|
||||
<p>There is no repository at the selected path.</p>
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Create a new repository</div>
|
||||
<div class="panel-body">
|
||||
<button data-ta-clickable="init-repository" class="btn btn-primary btn-lg" data-bind='click: initRepository'>
|
||||
Make '<span data-bind="text: dirName"></span>' a repository
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Clone a repository into a subfolder of '<span data-bind="text: dirName"></span>'</div>
|
||||
<div class="panel-body">
|
||||
<form data-bind="submit: cloneRepository">
|
||||
<div class="form-group">
|
||||
<label for="cloneFromInput">Clone from</label>
|
||||
<input class="form-control" type="text" data-ta-input="clone-url" id="cloneFromInput" placeholder="url" data-bind="value: cloneUrl, valueUpdate: 'afterkeydown'">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="cloneToInput">to</label>
|
||||
<input class="form-control" type="text" data-ta-input="clone-target" id="cloneToInput" data-bind="value: cloneDestination, attr: { placeholder: cloneDestinationImplicit }">
|
||||
</div>
|
||||
<input type="submit" class="btn btn-primary btn-lg" data-ta-clickable="clone-repository" value="Clone repository">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
|
||||
<!-- ko if: status() == 'no-such-path' -->
|
||||
<div data-ta-container="invalid-path" data-bind="visible: status() == 'no-such-path'">
|
||||
<h2>Invalid path</h2>
|
||||
<p>"<span data-bind="text: path"></span>" doesn't seem to be a valid path.</p>
|
||||
<div class="create-dir">
|
||||
<button class="btn btn-primary btn-lg" data-ta-clickable="create-dir" data-bind="click: createDir">Create directory</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
|
||||
<!-- ko if: repository -->
|
||||
<!-- ko component: repository --><!-- /ko -->
|
||||
<!-- /ko -->
|
||||
|
||||
</div>
|
105
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/path/path.js
generated
vendored
Normal file
105
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/path/path.js
generated
vendored
Normal file
|
@ -0,0 +1,105 @@
|
|||
|
||||
var ko = require('knockout');
|
||||
var components = require('ungit-components');
|
||||
var addressParser = require('ungit-address-parser');
|
||||
var navigation = require('ungit-navigation');
|
||||
var programEvents = require('ungit-program-events');
|
||||
|
||||
components.register('path', function(args) {
|
||||
return new PathViewModel(args.server, args.path);
|
||||
});
|
||||
|
||||
var PathViewModel = function(server, path) {
|
||||
var self = this;
|
||||
this.server = server;
|
||||
this.repoPath = ko.observable(path);
|
||||
this.dirName = this.repoPath().replace('\\', '/')
|
||||
.split('/')
|
||||
.filter(function(s) { return s; })
|
||||
.slice(-1)[0] || '/';
|
||||
|
||||
this.status = ko.observable('loading');
|
||||
this.loadingProgressBar = components.create('progressBar', { predictionMemoryKey: 'path-loading-' + path });
|
||||
this.loadingProgressBar.start();
|
||||
this.cloningProgressBar = components.create('progressBar', {
|
||||
predictionMemoryKey: 'path-cloning-' + path,
|
||||
fallbackPredictedTimeMs: 10000
|
||||
});
|
||||
this.cloneUrl = ko.observable();
|
||||
this.showDirectoryCreatedAlert = ko.observable(false);
|
||||
this.cloneDestinationImplicit = ko.computed(function() {
|
||||
var defaultText = 'destination folder';
|
||||
if (!self.cloneUrl()) return defaultText;
|
||||
|
||||
var parsedAddress = addressParser.parseAddress(self.cloneUrl());
|
||||
return parsedAddress.shortProject || defaultText;
|
||||
});
|
||||
this.cloneDestination = ko.observable();
|
||||
this.repository = ko.observable();
|
||||
}
|
||||
PathViewModel.prototype.updateNode = function(parentElement) {
|
||||
ko.renderTemplate('path', this, {}, parentElement);
|
||||
}
|
||||
PathViewModel.prototype.template = 'path';
|
||||
PathViewModel.prototype.shown = function() {
|
||||
this.updateStatus();
|
||||
}
|
||||
PathViewModel.prototype.updateAnimationFrame = function(deltaT) {
|
||||
if (this.repository())
|
||||
this.repository().updateAnimationFrame(deltaT);
|
||||
}
|
||||
PathViewModel.prototype.updateStatus = function() {
|
||||
var self = this;
|
||||
this.server.get('/quickstatus', { path: this.repoPath() }, function(err, status){
|
||||
self.loadingProgressBar.stop();
|
||||
if (err) return;
|
||||
if (status.type == 'inited' || status.type == 'bare') {
|
||||
if (self.repoPath() !== status.gitRootPath) {
|
||||
self.repoPath(status.gitRootPath);
|
||||
programEvents.dispatch({ event: 'navigated-to-path', path: self.repoPath() });
|
||||
programEvents.dispatch({ event: 'working-tree-changed' });
|
||||
}
|
||||
self.status(status.type);
|
||||
if (!self.repository()) {
|
||||
self.repository(components.create('repository', { server: self.server, path: self }));
|
||||
}
|
||||
} else if (status.type == 'uninited' || status.type == 'no-such-path') {
|
||||
self.status(status.type);
|
||||
self.repository(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
PathViewModel.prototype.initRepository = function() {
|
||||
var self = this;
|
||||
this.server.post('/init', { path: this.repoPath() }, function(err, res) {
|
||||
if (err) return;
|
||||
self.updateStatus();
|
||||
});
|
||||
}
|
||||
PathViewModel.prototype.onProgramEvent = function(event) {
|
||||
if (event.event == 'request-credentials') this.cloningProgressBar.pause();
|
||||
else if (event.event == 'request-credentials-response') this.cloningProgressBar.unpause();
|
||||
else if (event.event == 'working-tree-changed') this.updateStatus();
|
||||
else if (event.event == 'request-app-content-refresh') this.updateStatus();
|
||||
|
||||
if (this.repository()) this.repository().onProgramEvent(event);
|
||||
}
|
||||
PathViewModel.prototype.cloneRepository = function() {
|
||||
var self = this;
|
||||
self.status('cloning');
|
||||
this.cloningProgressBar.start();
|
||||
var dest = this.cloneDestination() || this.cloneDestinationImplicit();
|
||||
|
||||
this.server.post('/clone', { path: this.repoPath(), url: this.cloneUrl(), destinationDir: dest }, function(err, res) {
|
||||
self.cloningProgressBar.stop();
|
||||
if (err) return;
|
||||
navigation.browseTo('repository?path=' + encodeURIComponent(res.path));
|
||||
});
|
||||
}
|
||||
PathViewModel.prototype.createDir = function() {
|
||||
var self = this;
|
||||
this.showDirectoryCreatedAlert(true);
|
||||
this.server.post('/createDir', { dir: this.repoPath() }, function() {
|
||||
self.updateStatus();
|
||||
});
|
||||
}
|
8
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/path/ungit-plugin.json
generated
vendored
Normal file
8
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/path/ungit-plugin.json
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"exports": {
|
||||
"knockoutTemplates": {
|
||||
"path": "path.html"
|
||||
},
|
||||
"javascript": "path.bundle.js"
|
||||
}
|
||||
}
|
93
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/progressBar/progressBar.bundle.js
generated
vendored
Normal file
93
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/progressBar/progressBar.bundle.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
13
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/progressBar/progressBar.html
generated
vendored
Normal file
13
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/progressBar/progressBar.html
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!-- Always shown -->
|
||||
<script type="text/html" id="progressBar">
|
||||
<div class="progress" data-ta-element="progress-bar">
|
||||
<div class="progress-bar" data-bind="attr: { style: style }"></div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<!-- Only visible while it's running -->
|
||||
<script type="text/html" id="temporaryProgressBar">
|
||||
<!-- ko if: running -->
|
||||
<!-- ko template: { name: 'progressBar', data: $data } --><!-- /ko -->
|
||||
<!-- /ko -->
|
||||
</script>
|
89
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/progressBar/progressBar.js
generated
vendored
Normal file
89
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/progressBar/progressBar.js
generated
vendored
Normal file
|
@ -0,0 +1,89 @@
|
|||
|
||||
var ko = require('knockout');
|
||||
var components = require('ungit-components');
|
||||
|
||||
components.register('progressBar', function(args) {
|
||||
return new ProgressBarViewModel(args.predictionMemoryKey, args.fallbackPredictedTimeMs, args.temporary);
|
||||
});
|
||||
|
||||
var ProgressBarViewModel = function(predictionMemoryKey, fallbackPredictedTimeMs, temporary) {
|
||||
var self = this;
|
||||
if (fallbackPredictedTimeMs === undefined) fallbackPredictedTimeMs = 1000;
|
||||
this.temporary = temporary;
|
||||
this.style = ko.observable();
|
||||
this.running = ko.observable(false);
|
||||
self._width = ko.observable(0);
|
||||
self._opacity = ko.observable(1);
|
||||
self._widthSpeed = ko.observable(0);
|
||||
self._opacitySpeed = ko.observable(0);
|
||||
self._animationState = ko.observable('running');
|
||||
this.style = ko.computed(function() {
|
||||
return 'width: ' + self._width() + '%; ' +
|
||||
'opacity: ' + self._opacity() + '; ' +
|
||||
'-webkit-transition: width ' + self._widthSpeed() + 'ms, opacity ' + self._opacitySpeed() + 'ms;' +
|
||||
'transition: width ' + self._widthSpeed() + 'ms, opacity ' + self._opacitySpeed() + 'ms; ' +
|
||||
'animation-play-state: ' + self._animationState();
|
||||
});
|
||||
this.predictionMemoryKey = 'predict-' + predictionMemoryKey;
|
||||
this.isFirstRun = ko.observable(false);
|
||||
this.fallbackPredictedTimeMs = fallbackPredictedTimeMs;
|
||||
}
|
||||
ProgressBarViewModel.prototype.updateNode = function(parentElement) {
|
||||
ko.renderTemplate(this.temporary ? 'temporaryProgressBar' : 'progressBar', this, {}, parentElement);
|
||||
}
|
||||
ProgressBarViewModel.prototype.start = function() {
|
||||
if (this.running()) return;
|
||||
var self = this;
|
||||
var predictionMs = localStorage.getItem(this.predictionMemoryKey);
|
||||
if (!predictionMs || isNaN(predictionMs)) {
|
||||
this.isFirstRun(true);
|
||||
predictionMs = this.fallbackPredictedTimeMs;
|
||||
} else {
|
||||
predictionMs = parseInt(predictionMs);
|
||||
}
|
||||
this.predictionMs = predictionMs;
|
||||
this._width(0);
|
||||
this._opacity(1);
|
||||
this._opacitySpeed(0);
|
||||
this._widthSpeed(0);
|
||||
this._animationState('running');
|
||||
this.running(true);
|
||||
this.startMs = Date.now();
|
||||
this.pausedMs = 0;
|
||||
setTimeout(function(){
|
||||
predictionMs = Math.max(500, predictionMs);
|
||||
self._width(80);
|
||||
self._widthSpeed(predictionMs);
|
||||
}, 1);
|
||||
}
|
||||
|
||||
ProgressBarViewModel.prototype.pause = function() {
|
||||
this._animationState('paused');
|
||||
this.pauseStartMs = Date.now();
|
||||
}
|
||||
ProgressBarViewModel.prototype.unpause = function() {
|
||||
this._animationState('running');
|
||||
this.pausedMs += Date.now() - this.pauseStartMs;
|
||||
}
|
||||
ProgressBarViewModel.prototype.stop = function() {
|
||||
var self = this;
|
||||
var elapsedMs = Date.now() - this.startMs - this.pausedMs;
|
||||
var newPrediction;
|
||||
if (self.isFirstRun()) {
|
||||
self.isFirstRun(false);
|
||||
newPrediction = elapsedMs;
|
||||
} else {
|
||||
newPrediction = elapsedMs * 0.1 + self.predictionMs * 0.9;
|
||||
}
|
||||
localStorage.setItem(self.predictionMemoryKey, newPrediction.toString());
|
||||
|
||||
self._width(100);
|
||||
self._widthSpeed(300);
|
||||
setTimeout(function() {
|
||||
self._opacity(0);
|
||||
self._opacitySpeed(300);
|
||||
setTimeout(function() {
|
||||
self.running(false);
|
||||
}, 310);
|
||||
}, 400);
|
||||
}
|
6
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/progressBar/ungit-plugin.json
generated
vendored
Normal file
6
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/progressBar/ungit-plugin.json
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"exports": {
|
||||
"raw": "progressBar.html",
|
||||
"javascript": "progressBar.bundle.js"
|
||||
}
|
||||
}
|
12
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/refreshButton/refreshButton.css
generated
vendored
Normal file
12
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/refreshButton/refreshButton.css
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
.toolbar .refresh-button {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
border: 0px;
|
||||
font-size: 22px;
|
||||
}
|
||||
.repository-actions .refresh-button {
|
||||
background: #546565;
|
||||
border: 0px;
|
||||
font-size: 20px;
|
||||
height: 34px;
|
||||
padding-top: 3px;
|
||||
}
|
28
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/refreshButton/refreshbutton.bundle.js
generated
vendored
Normal file
28
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/refreshButton/refreshbutton.bundle.js
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
|
||||
var ko = require('knockout');
|
||||
var components = require('ungit-components');
|
||||
var programEvents = require('ungit-program-events');
|
||||
|
||||
components.register('refreshbutton', function() {
|
||||
return new RefreshButton();
|
||||
});
|
||||
|
||||
function RefreshButton() {
|
||||
this.refreshingProgressBar = components.create('progressBar', { predictionMemoryKey: 'refreshing-content', temporary: true });
|
||||
}
|
||||
RefreshButton.prototype.refresh = function() {
|
||||
var self = this;
|
||||
programEvents.dispatch({ event: 'request-app-content-refresh' });
|
||||
this.refreshingProgressBar.start();
|
||||
setTimeout(function() { // Fake the progress bar, for now (since we don't really know who and when this message will be handled)
|
||||
self.refreshingProgressBar.stop();
|
||||
}, 100);
|
||||
return true;
|
||||
}
|
||||
RefreshButton.prototype.updateNode = function(parentElement) {
|
||||
ko.renderTemplate('refreshbutton', this, {}, parentElement);
|
||||
}
|
||||
|
||||
},{"knockout":"knockout","ungit-components":"ungit-components","ungit-program-events":"ungit-program-events"}]},{},[1])
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJjb21wb25lbnRzL3JlZnJlc2hCdXR0b24vcmVmcmVzaEJ1dHRvbi5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIlxudmFyIGtvID0gcmVxdWlyZSgna25vY2tvdXQnKTtcbnZhciBjb21wb25lbnRzID0gcmVxdWlyZSgndW5naXQtY29tcG9uZW50cycpO1xudmFyIHByb2dyYW1FdmVudHMgPSByZXF1aXJlKCd1bmdpdC1wcm9ncmFtLWV2ZW50cycpO1xuXG5jb21wb25lbnRzLnJlZ2lzdGVyKCdyZWZyZXNoYnV0dG9uJywgZnVuY3Rpb24oKSB7XG4gIHJldHVybiBuZXcgUmVmcmVzaEJ1dHRvbigpO1xufSk7XG5cbmZ1bmN0aW9uIFJlZnJlc2hCdXR0b24oKSB7XG4gIHRoaXMucmVmcmVzaGluZ1Byb2dyZXNzQmFyID0gY29tcG9uZW50cy5jcmVhdGUoJ3Byb2dyZXNzQmFyJywgeyBwcmVkaWN0aW9uTWVtb3J5S2V5OiAncmVmcmVzaGluZy1jb250ZW50JywgdGVtcG9yYXJ5OiB0cnVlIH0pO1xufVxuUmVmcmVzaEJ1dHRvbi5wcm90b3R5cGUucmVmcmVzaCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHByb2dyYW1FdmVudHMuZGlzcGF0Y2goeyBldmVudDogJ3JlcXVlc3QtYXBwLWNvbnRlbnQtcmVmcmVzaCcgfSk7XG4gIHRoaXMucmVmcmVzaGluZ1Byb2dyZXNzQmFyLnN0YXJ0KCk7XG4gIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IC8vIEZha2UgdGhlIHByb2dyZXNzIGJhciwgZm9yIG5vdyAoc2luY2Ugd2UgZG9uJ3QgcmVhbGx5IGtub3cgd2hvIGFuZCB3aGVuIHRoaXMgbWVzc2FnZSB3aWxsIGJlIGhhbmRsZWQpXG4gICAgc2VsZi5yZWZyZXNoaW5nUHJvZ3Jlc3NCYXIuc3RvcCgpO1xuICB9LCAxMDApO1xuICByZXR1cm4gdHJ1ZTtcbn1cblJlZnJlc2hCdXR0b24ucHJvdG90eXBlLnVwZGF0ZU5vZGUgPSBmdW5jdGlvbihwYXJlbnRFbGVtZW50KSB7XG4gIGtvLnJlbmRlclRlbXBsYXRlKCdyZWZyZXNoYnV0dG9uJywgdGhpcywge30sIHBhcmVudEVsZW1lbnQpO1xufVxuIl19
|
5
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/refreshButton/refreshbutton.html
generated
vendored
Normal file
5
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/refreshButton/refreshbutton.html
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
<button class="btn btn-default refresh-button bootstrap-tooltip" data-bind="click: refresh" data-toggle="tooltip" data-placement="bottom" data-original-title="Refresh changes" data-delay='{"show":"2000", "hide":"0"}' data-ta-clickable="refresh-button">
|
||||
<span class="glyphicon glyphicon-refresh"></span>
|
||||
<!-- ko component: refreshingProgressBar --><!-- /ko -->
|
||||
</button>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user