e Please enter the commit message for your changes. Lines starting
remove node modules :wq
This commit is contained in:
parent
e30bf5242f
commit
16846d0db8
|
@ -84,11 +84,14 @@ else
|
||||||
|
|
||||||
upgradepkg --install-new &plgPATH;/&plgNAME;.txz
|
upgradepkg --install-new &plgPATH;/&plgNAME;.txz
|
||||||
|
|
||||||
|
npm -g update
|
||||||
|
npm -g install ungit
|
||||||
|
|
||||||
#restart event daemon
|
#restart event daemon
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
/usr/local/emhttp/plugins/ungit/scripts/stop >/dev/null 2>&1 < /dev/null &
|
/usr/local/emhttp/plugins/ungit/scripts/stop >/dev/null 2>&1 < /dev/null &
|
||||||
sleep 1
|
sleep 1
|
||||||
echo "starting libvirtwol..."
|
echo "starting ungit..."
|
||||||
setsid /usr/local/emhttp/plugins/ungit/scripts/start >/dev/null 2>&1 < /dev/null &
|
setsid /usr/local/emhttp/plugins/ungit/scripts/start >/dev/null 2>&1 < /dev/null &
|
||||||
]]>
|
]]>
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# start/stop/restart ungit daemon:
|
# start/stop/restart ungit daemon:
|
||||||
PLG="ungit"
|
PLG="ungit"
|
||||||
EMHTTP="/usr/local/emhttp/plugins/$PLG"
|
PROG="/usr/lib64/node_modules/$PLG/src/server.js"
|
||||||
PROG="$EMHTTP/node_modules/$PLG/src/server.js"
|
|
||||||
LOCKFILE="/var/lock/$PLG"
|
LOCKFILE="/var/lock/$PLG"
|
||||||
PIDFILE="/var/run/$PLG.pid"
|
PIDFILE="/var/run/$PLG.pid"
|
||||||
CONFIG="/boot/config/plugins/$PLG/$PLG.cfg"
|
CONFIG="/boot/config/plugins/$PLG/$PLG.cfg"
|
||||||
|
@ -17,7 +16,6 @@ ungit_start() {
|
||||||
if [ "$DAEMON" == "enable" ]; then
|
if [ "$DAEMON" == "enable" ]; then
|
||||||
echo "starting $PLG..."
|
echo "starting $PLG..."
|
||||||
sleep 1
|
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 &
|
nohup /usr/bin/node $PROG --port="$PORT" --logDirectory="/var/log/" --logGitCommands --logGitOutput >/var/log/$PLG 2>&1 | echo $! > $PIDFILE &
|
||||||
touch $LOCKFILE
|
touch $LOCKFILE
|
||||||
TIMER=0
|
TIMER=0
|
||||||
|
@ -58,6 +56,14 @@ ungit_restart() {
|
||||||
ungit_start
|
ungit_start
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Restart ungit:
|
||||||
|
ungit_update() {
|
||||||
|
ungit_stop
|
||||||
|
sleep 1
|
||||||
|
npm -g update
|
||||||
|
ungit_start
|
||||||
|
}
|
||||||
|
|
||||||
case "$1" in
|
case "$1" in
|
||||||
'start')
|
'start')
|
||||||
ungit_start
|
ungit_start
|
||||||
|
@ -68,6 +74,9 @@ case "$1" in
|
||||||
'restart')
|
'restart')
|
||||||
ungit_restart
|
ungit_restart
|
||||||
;;
|
;;
|
||||||
|
'update')
|
||||||
|
ungit_update
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo "usage rc.ungit: start|stop|restart"
|
echo "usage rc.ungit: start|stop|restart"
|
||||||
esac
|
esac
|
|
@ -1 +0,0 @@
|
||||||
../ungit/bin/credentials-helper
|
|
1
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/.bin/ungit
generated
vendored
1
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/.bin/ungit
generated
vendored
|
@ -1 +0,0 @@
|
||||||
../ungit/bin/ungit
|
|
3
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/.gitattributes
generated
vendored
3
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/.gitattributes
generated
vendored
|
@ -1,3 +0,0 @@
|
||||||
* 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
3
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/.nodemonignore
generated
vendored
|
@ -1,3 +0,0 @@
|
||||||
/public/*
|
|
||||||
.git/*
|
|
||||||
.git
|
|
40
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/.npmignore
generated
vendored
40
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/.npmignore
generated
vendored
|
@ -1,40 +0,0 @@
|
||||||
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
52
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/CHANGELOG.md
generated
vendored
|
@ -1,52 +0,0 @@
|
||||||
# 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
88
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/CONTRIBUTING.md
generated
vendored
|
@ -1,88 +0,0 @@
|
||||||
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
76
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/PLUGINS.md
generated
vendored
|
@ -1,76 +0,0 @@
|
||||||
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
103
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/README.md
generated
vendored
|
@ -1,103 +0,0 @@
|
||||||
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
18
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/appveyor.yml
generated
vendored
|
@ -1,18 +0,0 @@
|
||||||
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
46
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/bin/credentials-helper
generated
vendored
|
@ -1,46 +0,0 @@
|
||||||
#!/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
98
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/bin/ungit
generated
vendored
|
@ -1,98 +0,0 @@
|
||||||
#!/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
170
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/app/app.bundle.js
generated
vendored
File diff suppressed because one or more lines are too long
|
@ -1,4 +0,0 @@
|
||||||
|
|
||||||
.app-wrapper {
|
|
||||||
padding-top: 21px;
|
|
||||||
}
|
|
61
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/app/app.html
generated
vendored
61
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/app/app.html
generated
vendored
|
@ -1,61 +0,0 @@
|
||||||
|
|
||||||
<!-- 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
166
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/app/app.js
generated
vendored
|
@ -1,166 +0,0 @@
|
||||||
|
|
||||||
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;
|
|
||||||
};
|
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
"exports": {
|
|
||||||
"knockoutTemplates": {
|
|
||||||
"app": "app.html"
|
|
||||||
},
|
|
||||||
"javascript": "app.bundle.js"
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
|
@ -1,18 +0,0 @@
|
||||||
<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>
|
|
|
@ -1,87 +0,0 @@
|
||||||
|
|
||||||
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 });
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
"exports": {
|
|
||||||
"knockoutTemplates": {
|
|
||||||
"branches": "branches.html"
|
|
||||||
},
|
|
||||||
"javascript": "branches.bundle.js"
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
|
@ -1,92 +0,0 @@
|
||||||
.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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
<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>
|
|
|
@ -1,93 +0,0 @@
|
||||||
|
|
||||||
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
114
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/commit/commit.less
generated
vendored
|
@ -1,114 +0,0 @@
|
||||||
|
|
||||||
@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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"exports": {
|
|
||||||
"knockoutTemplates": {
|
|
||||||
"commit": "commit.html"
|
|
||||||
},
|
|
||||||
"javascript": "commit.bundle.js",
|
|
||||||
"css": "commit.css"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,73 +0,0 @@
|
||||||
(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
|
|
|
@ -1,39 +0,0 @@
|
||||||
.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;
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
<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>
|
|
|
@ -1,29 +0,0 @@
|
||||||
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));
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
|
|
||||||
.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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
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' });
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"exports": {
|
|
||||||
"knockoutTemplates": {
|
|
||||||
"commitdiff": "commitdiff.html"
|
|
||||||
},
|
|
||||||
"javascript": "commitdiff.bundle.js",
|
|
||||||
"css": "commitdiff.css"
|
|
||||||
}
|
|
||||||
}
|
|
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
149
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/dialogs/dialogs.js
generated
vendored
|
@ -1,149 +0,0 @@
|
||||||
|
|
||||||
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);
|
|
|
@ -1,26 +0,0 @@
|
||||||
|
|
||||||
<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>
|
|
|
@ -1,18 +0,0 @@
|
||||||
|
|
||||||
<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>
|
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"exports": {
|
|
||||||
"knockoutTemplates": {
|
|
||||||
"formDialog": "formDialog.html",
|
|
||||||
"prompt": "prompt.html"
|
|
||||||
},
|
|
||||||
"javascript": "dialogs.bundle.js"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
(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
|
|
|
@ -1,22 +0,0 @@
|
||||||
|
|
||||||
<!-- 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 -->
|
|
|
@ -1,61 +0,0 @@
|
||||||
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
"exports": {
|
|
||||||
"knockoutTemplates": {
|
|
||||||
"gitErrors": "gitErrors.html"
|
|
||||||
},
|
|
||||||
"javascript": "gitErrors.bundle.js"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
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
26
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/edge.js
generated
vendored
|
@ -1,26 +0,0 @@
|
||||||
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;
|
|
|
@ -1,353 +0,0 @@
|
||||||
|
|
||||||
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
258
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/git-node.js
generated
vendored
|
@ -1,258 +0,0 @@
|
||||||
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
168
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/git-ref.js
generated
vendored
|
@ -1,168 +0,0 @@
|
||||||
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);
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
|
|
||||||
<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>
|
|
Before Width: | Height: | Size: 2.4 KiB |
1238
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/graph.bundle.js
generated
vendored
1238
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/graph.bundle.js
generated
vendored
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
186
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/graph.css
generated
vendored
|
@ -1,186 +0,0 @@
|
||||||
.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;
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
|
|
||||||
<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
297
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/graph.js
generated
vendored
|
@ -1,297 +0,0 @@
|
||||||
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
197
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/graph/graph.less
generated
vendored
|
@ -1,197 +0,0 @@
|
||||||
|
|
||||||
@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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,77 +0,0 @@
|
||||||
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;
|
|
|
@ -1,19 +0,0 @@
|
||||||
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;
|
|
|
@ -1,10 +0,0 @@
|
||||||
{
|
|
||||||
"exports": {
|
|
||||||
"knockoutTemplates": {
|
|
||||||
"graph": "graph.html",
|
|
||||||
"graphGraphics": "graph-graphics.html"
|
|
||||||
},
|
|
||||||
"javascript": "graph.bundle.js",
|
|
||||||
"css": "graph.css"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
(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==
|
|
|
@ -1,72 +0,0 @@
|
||||||
.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;
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
|
|
||||||
<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>
|
|
|
@ -1,39 +0,0 @@
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
|
@ -1,75 +0,0 @@
|
||||||
|
|
||||||
.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;
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"exports": {
|
|
||||||
"knockoutTemplates": {
|
|
||||||
"header": "header.html"
|
|
||||||
},
|
|
||||||
"javascript": "header.bundle.js",
|
|
||||||
"css": "header.css"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
(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
20
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/home/home.css
generated
vendored
|
@ -1,20 +0,0 @@
|
||||||
.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
18
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/home/home.html
generated
vendored
|
@ -1,18 +0,0 @@
|
||||||
|
|
||||||
<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
62
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/home/home.js
generated
vendored
|
@ -1,62 +0,0 @@
|
||||||
|
|
||||||
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
25
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/home/home.less
generated
vendored
|
@ -1,25 +0,0 @@
|
||||||
|
|
||||||
.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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"exports": {
|
|
||||||
"knockoutTemplates": {
|
|
||||||
"home": "home.html"
|
|
||||||
},
|
|
||||||
"javascript": "home.bundle.js",
|
|
||||||
"css": "home.css"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
(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=
|
|
|
@ -1,16 +0,0 @@
|
||||||
.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;
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
<!-- 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 -->
|
|
|
@ -1,40 +0,0 @@
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
|
|
||||||
.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;
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"exports": {
|
|
||||||
"knockoutTemplates": {
|
|
||||||
"imagediff": "imagediff.html"
|
|
||||||
},
|
|
||||||
"javascript": "imagediff.bundle.js",
|
|
||||||
"css": "imagediff.css"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
(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=
|
|
|
@ -1,26 +0,0 @@
|
||||||
|
|
||||||
<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
43
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/login/login.js
generated
vendored
|
@ -1,43 +0,0 @@
|
||||||
|
|
||||||
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');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
"exports": {
|
|
||||||
"knockoutTemplates": {
|
|
||||||
"login": "login.html"
|
|
||||||
},
|
|
||||||
"javascript": "login.bundle.js"
|
|
||||||
}
|
|
||||||
}
|
|
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
74
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/path/path.html
generated
vendored
|
@ -1,74 +0,0 @@
|
||||||
|
|
||||||
<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
105
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/path/path.js
generated
vendored
|
@ -1,105 +0,0 @@
|
||||||
|
|
||||||
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();
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
"exports": {
|
|
||||||
"knockoutTemplates": {
|
|
||||||
"path": "path.html"
|
|
||||||
},
|
|
||||||
"javascript": "path.bundle.js"
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
|
@ -1,13 +0,0 @@
|
||||||
<!-- 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>
|
|
|
@ -1,89 +0,0 @@
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"exports": {
|
|
||||||
"raw": "progressBar.html",
|
|
||||||
"javascript": "progressBar.bundle.js"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
.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;
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
(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
|
|
|
@ -1,5 +0,0 @@
|
||||||
|
|
||||||
<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>
|
|
|
@ -1,24 +0,0 @@
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
|
|
||||||
.toolbar {
|
|
||||||
.refresh-button {
|
|
||||||
background: rgba(0, 0, 0, 0.1);
|
|
||||||
border: 0px;
|
|
||||||
font-size: 22px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.repository-actions {
|
|
||||||
.refresh-button {
|
|
||||||
background: rgba(84, 101, 101, 1);
|
|
||||||
border: 0px;
|
|
||||||
font-size: 20px;
|
|
||||||
height: 34px;
|
|
||||||
padding-top: 3px;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"exports": {
|
|
||||||
"knockoutTemplates": {
|
|
||||||
"refreshbutton": "refreshbutton.html"
|
|
||||||
},
|
|
||||||
"javascript": "refreshbutton.bundle.js",
|
|
||||||
"css": "refreshbutton.css"
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
|
@ -1,20 +0,0 @@
|
||||||
<div class="btn-group fetchButton">
|
|
||||||
<button type="button" class="btn btn-default btn-main" data-ta-clickable="fetch" data-bind="click: clickFetch, enable: fetchEnabled">
|
|
||||||
<span class="glyphicon glyphicon-download-alt"></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="remotes-menu">
|
|
||||||
<span class="caret"></span>
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-menu pull-right" role="menu" data-ta-container="remotes">
|
|
||||||
<!-- ko foreach: remotes -->
|
|
||||||
<li>
|
|
||||||
<a href="#" data-bind="text: name, click: changeRemote, attr: { 'data-ta-clickable': name }"></a>
|
|
||||||
<a href="#" class="list-link list-remove" data-bind="text: 'X', click: $parent.remoteRemove.bind($parent), attr: { 'data-ta-clickable': name + '-remove' }"></a>
|
|
||||||
</li>
|
|
||||||
<!-- /ko -->
|
|
||||||
<li class="divider"></li>
|
|
||||||
<li><a href="#" data-bind="click: showAddRemoteDialog" data-ta-clickable="show-add-remote-dialog">Add a new remote</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
115
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/remotes/remotes.js
generated
vendored
115
source/ungit/usr/local/emhttp/plugins/ungit/node_modules/ungit/components/remotes/remotes.js
generated
vendored
|
@ -1,115 +0,0 @@
|
||||||
|
|
||||||
var ko = require('knockout');
|
|
||||||
var _ = require('lodash');
|
|
||||||
var async = require('async');
|
|
||||||
var components = require('ungit-components');
|
|
||||||
var programEvents = require('ungit-program-events');
|
|
||||||
|
|
||||||
components.register('remotes', function(args) {
|
|
||||||
return new RemotesViewModel(args.server, args.repoPath);
|
|
||||||
});
|
|
||||||
|
|
||||||
function RemotesViewModel(server, repoPath) {
|
|
||||||
var self = this;
|
|
||||||
this.repoPath = repoPath;
|
|
||||||
this.server = server;
|
|
||||||
this.remotes = ko.observable([]);
|
|
||||||
this.currentRemote = ko.observable(null);
|
|
||||||
this.currentRemote.subscribe(function(value) {
|
|
||||||
programEvents.dispatch({ event: 'current-remote-changed', newRemote: value });
|
|
||||||
});
|
|
||||||
this.fetchLabel = ko.computed(function() {
|
|
||||||
if (self.currentRemote()) return 'Fetch from ' + self.currentRemote();
|
|
||||||
else return 'No remotes specified';
|
|
||||||
})
|
|
||||||
|
|
||||||
this.fetchingProgressBar = components.create('progressBar', { predictionMemoryKey: 'fetching-' + this.repoPath(), temporary: true });
|
|
||||||
|
|
||||||
this.fetchEnabled = ko.computed(function() {
|
|
||||||
return self.remotes().length > 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.shouldAutoFetch = ungit.config.autoFetch;
|
|
||||||
this.updateRemotes();
|
|
||||||
}
|
|
||||||
RemotesViewModel.prototype.updateNode = function(parentElement) {
|
|
||||||
ko.renderTemplate('remotes', this, {}, parentElement);
|
|
||||||
}
|
|
||||||
RemotesViewModel.prototype.clickFetch = function() { this.fetch({ nodes: true, tags: true }); }
|
|
||||||
RemotesViewModel.prototype.onProgramEvent = function(event) {
|
|
||||||
if (event.event == 'request-credentials') this.fetchingProgressBar.pause();
|
|
||||||
else if (event.event == 'request-credentials-response') this.fetchingProgressBar.unpause();
|
|
||||||
else if (event.event == 'request-fetch-tags') this.fetch({ tags: true });
|
|
||||||
}
|
|
||||||
RemotesViewModel.prototype.fetch = function(options) {
|
|
||||||
if (this.fetchingProgressBar.running()) return;
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
this.fetchingProgressBar.start();
|
|
||||||
var jobs = [];
|
|
||||||
if (options.tags) jobs.push(function(done) { self.server.get('/remote/tags', { path: self.repoPath(), remote: self.currentRemote() }, done); });
|
|
||||||
if (options.nodes) jobs.push(function(done) { self.server.post('/fetch', { path: self.repoPath(), remote: self.currentRemote() }, done); });
|
|
||||||
async.parallel(jobs, function(err, result) {
|
|
||||||
self.fetchingProgressBar.stop();
|
|
||||||
|
|
||||||
if (!err && options.tags) programEvents.dispatch({ event: 'remote-tags-update', tags: result[0] });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
RemotesViewModel.prototype.updateRemotes = function() {
|
|
||||||
var self = this;
|
|
||||||
this.server.get('/remotes', { path: this.repoPath() }, function(err, remotes) {
|
|
||||||
if (err && err.errorCode == 'not-a-repository') return true;
|
|
||||||
if (err) return;
|
|
||||||
remotes = remotes.map(function(remote) {
|
|
||||||
return {
|
|
||||||
name: remote,
|
|
||||||
changeRemote: function() { self.currentRemote(remote) }
|
|
||||||
}
|
|
||||||
});
|
|
||||||
self.remotes(remotes);
|
|
||||||
if (!self.currentRemote() && remotes.length > 0) {
|
|
||||||
if (_.find(remotes, { 'name': 'origin' })) // default to origin if it exists
|
|
||||||
self.currentRemote('origin');
|
|
||||||
else // otherwise take the first one
|
|
||||||
self.currentRemote(remotes[0].name);
|
|
||||||
if (self.shouldAutoFetch) {
|
|
||||||
self.fetch({ nodes: true, tags: true });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.shouldAutoFetch = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
RemotesViewModel.prototype.showAddRemoteDialog = function() {
|
|
||||||
var self = this;
|
|
||||||
var diag = components.create('addremotedialog');
|
|
||||||
diag.closed.add(function() {
|
|
||||||
if (diag.isSubmitted()) {
|
|
||||||
self.server.post('/remotes/' + encodeURIComponent(diag.name()), { path: self.repoPath(), url: diag.url() }, function(err, res) {
|
|
||||||
if (err) return;
|
|
||||||
self.updateRemotes();
|
|
||||||
})
|
|
||||||
}
|
|
||||||
});
|
|
||||||
programEvents.dispatch({ event: 'request-show-dialog', dialog: diag });
|
|
||||||
}
|
|
||||||
|
|
||||||
RemotesViewModel.prototype.remoteRemove = function(remote) {
|
|
||||||
var self = this;
|
|
||||||
var diag = components.create('yesnodialog', { title: 'Are you sure?', details: 'Deleting ' + remote.name + ' remote cannot be undone with ungit.'});
|
|
||||||
diag.closed.add(function() {
|
|
||||||
if (diag.result()) {
|
|
||||||
self.fetchingProgressBar.start();
|
|
||||||
self.server.del('/remotes/' + remote.name, { path: self.repoPath() }, function(err, result) {
|
|
||||||
if (err) {
|
|
||||||
console.log(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.updateRemotes();
|
|
||||||
self.fetchingProgressBar.stop();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
programEvents.dispatch({ event: 'request-show-dialog', dialog: diag });
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
"exports": {
|
|
||||||
"knockoutTemplates": {
|
|
||||||
"remotes": "remotes.html"
|
|
||||||
},
|
|
||||||
"javascript": "remotes.bundle.js"
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user