Skip to content

Commit 800e59d

Browse files
author
Daniel Perez
committed
Add web plugin functionality.
1 parent 0d266be commit 800e59d

File tree

10 files changed

+562
-153
lines changed

10 files changed

+562
-153
lines changed

lib/GUI/css/styles.less

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,17 @@
2020
.main-header {
2121
background: @white;
2222

23+
.navbar-default .navbar-nav > .open {
24+
a.dropdown-toggle, a.dropdown-toggle:focus {
25+
color: #fff;
26+
background-color: #d9534f;
27+
}
28+
a:hover {
29+
color: #fff;
30+
background-color: #d9534f;
31+
}
32+
}
33+
2334
.navbar {
2435
margin-bottom: 0;
2536
}

lib/GUI/index.hbs

Lines changed: 32 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,127 +1,42 @@
1-
<!doctype html>
2-
<html lang="en-us">
3-
<head>
4-
<meta charset="utf-8">
5-
<title>{{ name }}</title>
6-
7-
<link rel="icon" type="image/png" href="{{ baseUrl }}/-/static/favicon.png"/>
8-
<link rel="stylesheet" type="text/css" href="{{ baseUrl }}/-/static/main.css">
9-
<meta name="viewport" content="width=device-width, initial-scale=1">
10-
</head>
11-
<body class="body">
12-
<header class="main-header">
13-
<nav class="navbar navbar-default red-bg white no-border no-rnd-cnr" role="navigation">
14-
<div class="container">
15-
<div class="navbar-header clearfix">
16-
<div class="npm-logo brand">
17-
<a href="{{ baseUrl }}"></a>
18-
</div>
19-
20-
<!-- login/logout for small devices -->
21-
<div class="pull-right visible-xs pad-right-10">
22-
<div>
23-
{{#if username}}
24-
<p class="white no-bg navbar-text pad-right-10 inline-block">Hi {{username}}</p>
25-
<button type="submit" class="btn btn-danger inline-block js-userLogoutBtn">Logout</button>
26-
{{else}}
27-
<p class="white no-bg navbar-text pad-right-10 inline-block">&nbsp;</p>
28-
<button type="submit" class="btn btn-danger inline-block" data-toggle="modal" data-target="#login-form" onclick="return false">Login</button>
29-
{{/if}}
30-
</div>
31-
</div>
32-
</div>
33-
34-
<div class="navbar-left hidden-xs">&nbsp;&nbsp;</div>
35-
36-
<div class="navbar-left setup hidden-xs">
37-
<code class="white no-bg">npm set registry {{ baseUrl }}</code><br>
38-
<code class="white no-bg">npm adduser --registry {{ baseUrl }}</code>
39-
</div>
40-
41-
<!-- login/logout for large devices -->
42-
<div class="navbar-collapse collapse">
43-
<div class="navbar-right">
44-
<form class="navbar-form navbar-right">
45-
{{#if username}}
46-
<p class="white no-bg pad-right-10 inline-block">Hi {{username}}</p>
47-
<button type="submit" class="btn btn-danger inline-block js-userLogoutBtn">Logout</button>
48-
{{else}}
49-
<button type="submit" class="btn btn-danger inline-block" data-toggle="modal" data-target="#login-form" onclick="return false">Login</button>
50-
{{/if}}
51-
</form>
52-
</div>
53-
</div>
54-
1+
{{#extend "layout"}}
2+
{{#content "main"}}
3+
<header class="sm-registry-info light-red-bg center hidden-sm hidden-lg hidden-md">
4+
<code class="white no-bg">{{ baseUrl }}</code><br>
5+
</header>
556

7+
<header class="packages-header container">
8+
<div class="row">
9+
<div class="col-md-5 hidden-xs hidden-sm">
10+
<h2 class="title">Available Packages</h2>
5611
</div>
57-
</nav>
58-
<header class="sm-registry-info light-red-bg center hidden-sm hidden-lg hidden-md">
59-
<code class="white no-bg">{{ baseUrl }}</code><br>
60-
</header>
61-
<header class="packages-header container">
62-
<div class="row">
63-
<div class="col-md-5 hidden-xs hidden-sm">
64-
<h2 class="title">Available Packages</h2>
65-
</div>
66-
<div class="col-md-4 col-md-offset-3 col-sm-12">
67-
<form id='search-form'>
68-
<div class="input-group input-group-lg search-container">
69-
<input type="text" class="form-control" placeholder="Search for packages">
70-
<span class="input-group-btn">
71-
<button class="btn btn-default search-icon js-search-btn"><i class="icon-search"></i></button>
72-
</span>
73-
</div>
74-
</form>
75-
</div>
12+
<div class="col-md-4 col-md-offset-3 col-sm-12">
13+
<form id='search-form'>
14+
<div class="input-group input-group-lg search-container">
15+
<input type="text" class="form-control" placeholder="Search for packages">
16+
<span class="input-group-btn">
17+
<button class="btn btn-default search-icon js-search-btn"><i class="icon-search"></i></button>
18+
</span>
19+
</div>
20+
</form>
7621
</div>
77-
</header>
22+
</div>
23+
</header>
7824
</header>
7925

8026
<section class="content container packages-container" id="all-packages">
81-
{{#each packages}}
82-
{{> entry}}
83-
{{/each}}
84-
85-
{{#unless packages.length}}
86-
<div class='no-results'>
87-
<big>No Packages</big><br>
88-
Use <code>npm publish</code>
89-
</div>
90-
{{/unless}}
27+
{{#each packages}}
28+
{{> entry}}
29+
{{/each}}
30+
31+
{{#unless packages.length}}
32+
<div class='no-results'>
33+
<big>No Packages</big><br>
34+
Use <code>npm publish</code>
35+
</div>
36+
{{/unless}}
9137
</section>
9238

9339
<section class="content container pkg-search-container" id="search-results"></section>
40+
{{/content}}
41+
{{/extend}}
9442

95-
<div class="modal fade" id="login-form" tabindex="-1" role="dialog" aria-labelledby="login-form-label" aria-hidden="true">
96-
<div class="modal-dialog modal-sm">
97-
<div class="modal-content">
98-
<div class="modal-header">
99-
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
100-
<h5 class="modal-title" id="login-form-label">Welcome back</h5>
101-
</div>
102-
<form role="form" action="{{ baseUrl }}/-/login" method="post" id="login-form" autocomplete="off">
103-
<div class="modal-body">
104-
<div class="form-group">
105-
<label for="user" class="sr-only">Email</label>
106-
<input name="user" id="user" class="form-control" placeholder="Username" type="text">
107-
</div>
108-
<div class="form-group">
109-
<label for="pass" class="sr-only">Password</label>
110-
<input name="pass" id="pass" class="form-control" placeholder="Password" type="password">
111-
</div>
112-
</div>
113-
<div class="modal-footer">
114-
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
115-
<button type="submit" class="btn btn-primary">Log in</button>
116-
</div>
117-
</form>
118-
</div>
119-
</div>
120-
</div>
121-
122-
<form action="{{ baseUrl }}/-/logout" method="post" class="hide" id="userLogoutForm"></form>
123-
124-
<script src="{{ baseUrl }}/-/static/jquery.min.js"></script>
125-
<script type='text/javascript' src='{{ baseUrl }}/-/static/main.js'></script>
126-
</body>
127-
</html>

lib/GUI/js/bootstrap-dropdown.js

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/* ========================================================================
2+
* Bootstrap: dropdown.js v3.3.0
3+
* http://getbootstrap.com/javascript/#dropdowns
4+
* ========================================================================
5+
* Copyright 2011-2014 Twitter, Inc.
6+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
7+
* ======================================================================== */
8+
9+
10+
+function ($) {
11+
'use strict';
12+
13+
// DROPDOWN CLASS DEFINITION
14+
// =========================
15+
16+
var backdrop = '.dropdown-backdrop'
17+
var toggle = '[data-toggle="dropdown"]'
18+
var Dropdown = function (element) {
19+
$(element).on('click.bs.dropdown', this.toggle)
20+
}
21+
22+
Dropdown.VERSION = '3.3.0'
23+
24+
Dropdown.prototype.toggle = function (e) {
25+
var $this = $(this)
26+
27+
if ($this.is('.disabled, :disabled')) return
28+
29+
var $parent = getParent($this)
30+
var isActive = $parent.hasClass('open')
31+
32+
clearMenus()
33+
34+
if (!isActive) {
35+
if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
36+
// if mobile we use a backdrop because click events don't delegate
37+
$('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
38+
}
39+
40+
var relatedTarget = { relatedTarget: this }
41+
$parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
42+
43+
if (e.isDefaultPrevented()) return
44+
45+
$this
46+
.trigger('focus')
47+
.attr('aria-expanded', 'true')
48+
49+
$parent
50+
.toggleClass('open')
51+
.trigger('shown.bs.dropdown', relatedTarget)
52+
}
53+
54+
return false
55+
}
56+
57+
Dropdown.prototype.keydown = function (e) {
58+
if (!/(38|40|27|32)/.test(e.which)) return
59+
60+
var $this = $(this)
61+
62+
e.preventDefault()
63+
e.stopPropagation()
64+
65+
if ($this.is('.disabled, :disabled')) return
66+
67+
var $parent = getParent($this)
68+
var isActive = $parent.hasClass('open')
69+
70+
if ((!isActive && e.which != 27) || (isActive && e.which == 27)) {
71+
if (e.which == 27) $parent.find(toggle).trigger('focus')
72+
return $this.trigger('click')
73+
}
74+
75+
var desc = ' li:not(.divider):visible a'
76+
var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc)
77+
78+
if (!$items.length) return
79+
80+
var index = $items.index(e.target)
81+
82+
if (e.which == 38 && index > 0) index-- // up
83+
if (e.which == 40 && index < $items.length - 1) index++ // down
84+
if (!~index) index = 0
85+
86+
$items.eq(index).trigger('focus')
87+
}
88+
89+
function clearMenus(e) {
90+
if (e && e.which === 3) return
91+
$(backdrop).remove()
92+
$(toggle).each(function () {
93+
var $this = $(this)
94+
var $parent = getParent($this)
95+
var relatedTarget = { relatedTarget: this }
96+
97+
if (!$parent.hasClass('open')) return
98+
99+
$parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
100+
101+
if (e.isDefaultPrevented()) return
102+
103+
$this.attr('aria-expanded', 'false')
104+
$parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
105+
})
106+
}
107+
108+
function getParent($this) {
109+
var selector = $this.attr('data-target')
110+
111+
if (!selector) {
112+
selector = $this.attr('href')
113+
selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
114+
}
115+
116+
var $parent = selector && $(selector)
117+
118+
return $parent && $parent.length ? $parent : $this.parent()
119+
}
120+
121+
122+
// DROPDOWN PLUGIN DEFINITION
123+
// ==========================
124+
125+
function Plugin(option) {
126+
return this.each(function () {
127+
var $this = $(this)
128+
var data = $this.data('bs.dropdown')
129+
130+
if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
131+
if (typeof option == 'string') data[option].call($this)
132+
})
133+
}
134+
135+
var old = $.fn.dropdown
136+
137+
$.fn.dropdown = Plugin
138+
$.fn.dropdown.Constructor = Dropdown
139+
140+
141+
// DROPDOWN NO CONFLICT
142+
// ====================
143+
144+
$.fn.dropdown.noConflict = function () {
145+
$.fn.dropdown = old
146+
return this
147+
}
148+
149+
150+
// APPLY TO STANDARD DROPDOWN ELEMENTS
151+
// ===================================
152+
153+
$(document)
154+
.on('click.bs.dropdown.data-api', clearMenus)
155+
.on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
156+
.on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
157+
.on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
158+
.on('keydown.bs.dropdown.data-api', '[role="menu"]', Dropdown.prototype.keydown)
159+
.on('keydown.bs.dropdown.data-api', '[role="listbox"]', Dropdown.prototype.keydown)
160+
161+
}(jQuery);

lib/GUI/js/main.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// twitter bootstrap stuff;
22
// not in static 'cause I want it to be bundled with the rest of javascripts
33
require('./bootstrap-modal')
4+
require('./bootstrap-dropdown')
45

56
// our own files
67
require('./search')

0 commit comments

Comments
 (0)