Refactoring
This commit is contained in:
parent
c0f0edf633
commit
cfb7edd659
|
@ -3,16 +3,20 @@
|
|||
}
|
||||
html,
|
||||
body {
|
||||
background: #fff;
|
||||
color: #34495e;
|
||||
font: 13px Helvetica, Arial, sans-serif;
|
||||
height: 100%;
|
||||
font: 14px sans-serif;
|
||||
margin: 0;
|
||||
}
|
||||
h1,
|
||||
h2 {
|
||||
margin: 0;
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
a,
|
||||
.user {
|
||||
color: #16a085;
|
||||
text-decoration: none;
|
||||
transition: all .25s;
|
||||
}
|
||||
a:hover,
|
||||
|
@ -20,14 +24,10 @@ a:hover,
|
|||
color: #1abc9c;
|
||||
}
|
||||
a:focus,
|
||||
button:focus {
|
||||
button:focus,
|
||||
input {
|
||||
outline: 0;
|
||||
}
|
||||
h1,
|
||||
h2 {
|
||||
font: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
button {
|
||||
background: none;
|
||||
border: 0;
|
||||
|
@ -47,7 +47,6 @@ button::-moz-focus-inner {
|
|||
border: 2px solid #bdc3c7;
|
||||
border-radius: 3px;
|
||||
color: #aeb6bf;
|
||||
font: 14px Helvetica, Arial, sans-serif;
|
||||
padding: 8px 12px;
|
||||
text-decoration: none;
|
||||
transition: all .25s;
|
||||
|
@ -56,175 +55,158 @@ button::-moz-focus-inner {
|
|||
border-color: #7f8c8d;
|
||||
color: #7f8c8d;
|
||||
}
|
||||
.badge {
|
||||
background-color: #d8dce0;
|
||||
border-radius: 4px;
|
||||
color: #ffffff;
|
||||
font-size: 13px;
|
||||
line-height: 1.615;
|
||||
padding: 0 8px;
|
||||
}
|
||||
#wrap,
|
||||
#viewport {
|
||||
#wrap {
|
||||
height: 100%;
|
||||
min-width: 720px;
|
||||
position: relative;
|
||||
min-width: 640px;
|
||||
width: 100%;
|
||||
}
|
||||
#sidebar {
|
||||
border-right: 4px solid #bdc3c7;
|
||||
float: left;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
padding: 20px;
|
||||
width: 200px;
|
||||
width: 240px;
|
||||
}
|
||||
#sidebar .network + .network {
|
||||
border-top: 2px solid #ebedef;
|
||||
margin-top: 14px;
|
||||
padding-top: 14px;
|
||||
}
|
||||
#sidebar .header {
|
||||
#sidebar h2 {
|
||||
color: #aeb6bf;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
font: bold 13px sans-serif;
|
||||
padding: 6px 12px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
#sidebar .channel {
|
||||
#sidebar button {
|
||||
border-radius: 2px;
|
||||
color: #16a085;
|
||||
display: block;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
line-height: 1.2;
|
||||
padding: 6px 12px;
|
||||
line-height: 21px;
|
||||
margin-bottom: 3px;
|
||||
padding: 6px 13px;
|
||||
text-align: left;
|
||||
transition: all .25s;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
}
|
||||
#sidebar .channel + .channel {
|
||||
margin-top: 3px;
|
||||
}
|
||||
#sidebar .channel:hover {
|
||||
#sidebar button:hover {
|
||||
background-color: #f1f2f3;
|
||||
color: #1abc9c;
|
||||
}
|
||||
#sidebar .channel.active {
|
||||
#sidebar button.active {
|
||||
background-color: #ebedef;
|
||||
color: #526476;
|
||||
}
|
||||
#chat {
|
||||
background: #fff;
|
||||
#sidebar .badge {
|
||||
color: #bdc3c7;
|
||||
font: 12px sans-serif;
|
||||
line-height: 21px;
|
||||
}
|
||||
#menu,
|
||||
#networks {
|
||||
margin: 20px;
|
||||
}
|
||||
#networks .network + .network {
|
||||
border-top: 2px solid #ebedef;
|
||||
margin-top: 14px;
|
||||
padding-top: 14px;
|
||||
}
|
||||
#networks .badge {
|
||||
float: right;
|
||||
}
|
||||
#footer {
|
||||
bottom: 0;
|
||||
font: 12px "Consolas", monospace;
|
||||
left: 200px;
|
||||
line-height: 16px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
#chat form {
|
||||
border-top: 1px solid #bdc3c7;
|
||||
bottom: 1px;
|
||||
height: 30px;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
}
|
||||
#chat form input {
|
||||
border: 0;
|
||||
font: inherit;
|
||||
height: 30px;
|
||||
margin: 0;
|
||||
outline: none;
|
||||
padding: 0 10px;
|
||||
width: 100%;
|
||||
}
|
||||
#chat .query .users,
|
||||
#chat .lobby .users,
|
||||
#chat .lobby .close {
|
||||
display: none;
|
||||
#footer .btn {
|
||||
background: #fff;
|
||||
display: block;
|
||||
text-align: center;
|
||||
margin: 20px;
|
||||
}
|
||||
#chat .query .messages,
|
||||
#chat .lobby .messages {
|
||||
#main {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
left: 240px;
|
||||
right: 0;
|
||||
}
|
||||
#chat .window {
|
||||
#main .window {
|
||||
background: #fff;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
#chat .messages {
|
||||
bottom: 30px;
|
||||
left: 0;
|
||||
#chat {
|
||||
font: 13px "Consolas", monospace;
|
||||
height: 100%;
|
||||
}
|
||||
#chat .lobby .messages,
|
||||
#chat .query .messages {
|
||||
right: 0;
|
||||
}
|
||||
#chat .lobby .users,
|
||||
#chat .query .users {
|
||||
display: none;
|
||||
}
|
||||
#chat .messages,
|
||||
#chat .users {
|
||||
bottom: 35px;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
padding: 0 8px 4px;
|
||||
position: absolute;
|
||||
right: 160px;
|
||||
top: 0;
|
||||
word-wrap: break-word;
|
||||
z-index: 0;
|
||||
}
|
||||
#chat .messages {
|
||||
left: 0px;
|
||||
padding: 2px 0;
|
||||
right: 160px;
|
||||
}
|
||||
#chat .show-more {
|
||||
display: none;
|
||||
margin-top: 4px;
|
||||
padding: 2px 0;
|
||||
margin: 6px 8px 4px;
|
||||
}
|
||||
#chat .show-more .btn {
|
||||
width: 100%;
|
||||
}
|
||||
#chat .msg {
|
||||
margin: 4px 0;
|
||||
line-height: 1.4;
|
||||
margin: 2px 8px;
|
||||
}
|
||||
#chat .time {
|
||||
#chat .time,
|
||||
#chat .type {
|
||||
color: #bdc3c7;
|
||||
}
|
||||
#chat .error,
|
||||
#chat .join,
|
||||
#chat .kick,
|
||||
#chat .mode,
|
||||
#chat .motd,
|
||||
#chat .nick,
|
||||
#chat .notice,
|
||||
#chat .part,
|
||||
#chat .quit,
|
||||
#chat .topic,
|
||||
#chat .whois {
|
||||
color: #95a5a6;
|
||||
}
|
||||
#chat .motd .type,
|
||||
#chat .notice .type,
|
||||
#chat .whois .type {
|
||||
display: none;
|
||||
}
|
||||
#chat .users {
|
||||
background: #fff;
|
||||
border-left: 4px solid #bdc3c7;
|
||||
bottom: 30px;
|
||||
overflow-y: auto;
|
||||
padding-bottom: 6px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 160px;
|
||||
}
|
||||
#chat .users .count {
|
||||
background: #ecf0f1;
|
||||
color: #aeb6bf;
|
||||
margin-bottom: 4px;
|
||||
padding: 8px 12px;
|
||||
}
|
||||
#chat .users .user {
|
||||
display: block;
|
||||
padding: 4px 12px;
|
||||
}
|
||||
#footer {
|
||||
#chat .count {
|
||||
background: #ecf0f1;
|
||||
color: #aeb6bf;
|
||||
margin-bottom: 4px;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
#chat .form {
|
||||
bottom: 0;
|
||||
height: 35px;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
width: 195px;
|
||||
right: 0;
|
||||
left: 0;
|
||||
}
|
||||
#footer .btn {
|
||||
display: block;
|
||||
margin: 20px;
|
||||
#chat .input {
|
||||
border: 0;
|
||||
border-top: 1px solid #bdc3c7;
|
||||
height: 35px;
|
||||
padding: 0 10px;
|
||||
width: 100%;
|
||||
}
|
|
@ -7,102 +7,114 @@
|
|||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no">
|
||||
|
||||
<link rel="stylesheet" href="/normalize.css">
|
||||
<link rel="stylesheet" href="/style.css">
|
||||
<link rel="stylesheet" href="<%= typeof theme !== 'undefined' ? theme : '' %>">
|
||||
<link rel="stylesheet" href="/css/normalize.css">
|
||||
<link rel="stylesheet" href="/css/style.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="wrap">
|
||||
<div id="viewport">
|
||||
|
||||
<aside id="sidebar"></aside>
|
||||
<div id="chat"></div>
|
||||
|
||||
<footer id="footer">
|
||||
<a href="<%= homepage %>" target="_blank" class="btn">
|
||||
<strong><%= name %></strong>
|
||||
<%= version %>
|
||||
</a>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/html" id="networks">
|
||||
{{#each networks}}
|
||||
<div id="network-{{id}}" data-nick="{{nick}}" class="network">
|
||||
<h2 class="header">{{host}}</h2>
|
||||
{{partial "#channels"}}
|
||||
</div>
|
||||
{{/each}}
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="channels">
|
||||
{{#each channels}}
|
||||
<button id="channel-{{id}}" class="channel">
|
||||
{{name}}
|
||||
</button>
|
||||
{{/each}}
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="windows">
|
||||
{{#each windows}}
|
||||
<div id="window-{{id}}" class="window {{type}}">
|
||||
<div class="users">
|
||||
{{partial "#users"}}
|
||||
</div>
|
||||
<div class="messages">
|
||||
<div class="show-more">
|
||||
<button class="btn">Show more</button>
|
||||
<div id="wrap" class="table">
|
||||
<aside id="sidebar">
|
||||
<div id="menu">
|
||||
<h2>Shout Client</h2>
|
||||
<button data-target="#settings">Settings</button>
|
||||
</div>
|
||||
<div id="networks">
|
||||
</div>
|
||||
<footer id="footer">
|
||||
<a href="<%= homepage %>" target="_blank" class="btn">
|
||||
<strong><%= name %></strong>
|
||||
<%= version %>
|
||||
</a>
|
||||
</footer>
|
||||
</aside>
|
||||
<div id="main">
|
||||
<div id="windows">
|
||||
<div id="settings" class="window">
|
||||
</div>
|
||||
</div>
|
||||
<div id="chat">
|
||||
</div>
|
||||
{{partial "#messages"}}
|
||||
</div>
|
||||
<form onSubmit="return false;">
|
||||
<input type="text" class="input" data-target="{{id}}"/>
|
||||
<input type="submit" style="display: none;"/>
|
||||
</form>
|
||||
</div>
|
||||
{{/each}}
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="users">
|
||||
<div class="count">
|
||||
Users: {{users.length}}
|
||||
</div>
|
||||
{{#each users}}
|
||||
<button class="user">
|
||||
{{mode}}{{name}}
|
||||
</button>
|
||||
{{/each}}
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="messages">
|
||||
{{#slice messages limit="20"}}
|
||||
<div class="msg {{type}}">
|
||||
<span class="time">
|
||||
{{time}}
|
||||
</span>
|
||||
<button class="user">
|
||||
{{from}}
|
||||
<div id="templates">
|
||||
<script type="text/html" class="networks">
|
||||
{{#each networks}}
|
||||
<div id="network-{{id}}" class="network">
|
||||
<h2>{{name}}</h2>
|
||||
{{partial "channels"}}
|
||||
</div>
|
||||
{{/each}}
|
||||
</script>
|
||||
|
||||
<script type="text/html" class="channels">
|
||||
{{#each channels}}
|
||||
<button id="channel-{{id}}" class="channel" data-target="#window-{{id}}">
|
||||
<span class="badge"></span>
|
||||
{{name}}
|
||||
</button>
|
||||
<span class="text">
|
||||
{{#if type}}
|
||||
<em class="type">{{type}}</em>
|
||||
{{/if}}
|
||||
{{{uri text}}}
|
||||
</span>
|
||||
|
||||
{{/each}}
|
||||
</script>
|
||||
|
||||
<script type="text/html" class="windows">
|
||||
{{#each windows}}
|
||||
<div id="window-{{id}}" class="window {{type}}">
|
||||
<div class="chat">
|
||||
<div class="messages">
|
||||
<div class="show-more">
|
||||
<button class="btn">Show more</button>
|
||||
</div>
|
||||
{{partial "messages"}}
|
||||
</div>
|
||||
<div class="users">
|
||||
{{partial "users"}}
|
||||
</div>
|
||||
</div>
|
||||
<form class="form" onSubmit="return false" data-target="{{id}}">
|
||||
<input type="text" class="input">
|
||||
</form>
|
||||
</div>
|
||||
{{/each}}
|
||||
</script>
|
||||
|
||||
<script type="text/html" class="users">
|
||||
<div class="count">
|
||||
Users: {{users.length}}
|
||||
</div>
|
||||
{{#each users}}
|
||||
<button class="user">
|
||||
{{mode}}{{name}}
|
||||
</button>
|
||||
{{/each}}
|
||||
</script>
|
||||
|
||||
<script type="text/html" class="messages">
|
||||
{{#slice messages limit=100}}
|
||||
<div class="msg {{type}}">
|
||||
<span class="time">
|
||||
{{time}}
|
||||
</span>
|
||||
<button class="user">
|
||||
{{from}}
|
||||
</button>
|
||||
<span class="text">
|
||||
{{#if type}}
|
||||
<em class="type">{{type}}</em>
|
||||
{{/if}}
|
||||
{{{uri text}}}
|
||||
</span>
|
||||
</div>
|
||||
{{/slice}}
|
||||
</script>
|
||||
</div>
|
||||
{{/slice}}
|
||||
</script>
|
||||
|
||||
<script src="/socket.io/socket.io.js"></script>
|
||||
<script src="/js/jquery.js"></script>
|
||||
<script src="/js/jquery.plugins.js"></script>
|
||||
<script src="/js/uri.js"></script>
|
||||
<script src="/js/handlebars.js"></script>
|
||||
<script src="/socket.io/socket.io.js"></script>
|
||||
<script src="/js/handlebars.helpers.js"></script>
|
||||
<script src="/js/chat.js"></script>
|
||||
|
||||
</body>
|
||||
|
|
|
@ -38,69 +38,58 @@ $(function() {
|
|||
});
|
||||
|
||||
var tpl = [];
|
||||
function render(id, data) {
|
||||
tpl[id] = tpl[id] || Handlebars.compile($(id).remove().html());
|
||||
return tpl[id](data);
|
||||
function render(name, data) {
|
||||
tpl[name] = tpl[name] || Handlebars.compile($("#templates ." + name).html());
|
||||
return tpl[name](data);
|
||||
}
|
||||
|
||||
function event(e, data) {
|
||||
switch (e) {
|
||||
case "join":
|
||||
chat.append(render("#windows", {windows: [data.chan]}))
|
||||
.find(".window")
|
||||
chat.append(render("windows", {windows: [data.chan]}))
|
||||
.find(".messages")
|
||||
.last()
|
||||
.scrollGlue({speed: 200})
|
||||
.end()
|
||||
.find(".input")
|
||||
.tabComplete({list: commands})
|
||||
.inputHistory({submit: true})
|
||||
.end()
|
||||
.bringToTop()
|
||||
.find(".messages")
|
||||
.scrollGlue({speed: 400})
|
||||
.end();
|
||||
|
||||
|
||||
$("#network-" + data.id)
|
||||
.append(render("#channels", {channels: [data.chan]}))
|
||||
.append(render("channels", {channels: [data.chan]}))
|
||||
.find(".channel")
|
||||
.last()
|
||||
.uniqueClass("active")
|
||||
.trigger("click")
|
||||
.end();
|
||||
break;
|
||||
|
||||
case "msg":
|
||||
$("#window-" + data.id)
|
||||
.find(".messages")
|
||||
.append(render("#messages", {messages: [data.msg]}));
|
||||
.append(render("messages", {messages: [data.msg]}));
|
||||
break;
|
||||
|
||||
case "networks":
|
||||
var channels = $.map(data.networks, function(n) { return n.channels; });
|
||||
chat.html(render("#windows", {windows: channels}))
|
||||
.find(".window")
|
||||
.last()
|
||||
.bringToTop()
|
||||
.end()
|
||||
chat.html(render("windows", {windows: channels}))
|
||||
.find(".input")
|
||||
.tabComplete({list: commands})
|
||||
.inputHistory({submit: true})
|
||||
.end()
|
||||
.find(".hidden")
|
||||
.prev(".show-more")
|
||||
.show();
|
||||
chat.find(".messages")
|
||||
.scrollGlue({speed: 400})
|
||||
.scrollGlue({speed: 200})
|
||||
.end();
|
||||
|
||||
sidebar.html(render("#networks", {networks: data.networks}))
|
||||
$("#networks")
|
||||
.html(render("networks", {networks: data.networks}))
|
||||
.find(".channel")
|
||||
.last()
|
||||
.addClass("active")
|
||||
.end();
|
||||
break;
|
||||
|
||||
case "nick":
|
||||
// ..
|
||||
break;
|
||||
|
||||
case "part":
|
||||
$("#channel-" + data.id)
|
||||
.add("#window-" + data.id)
|
||||
|
@ -110,21 +99,55 @@ $(function() {
|
|||
case "users":
|
||||
$("#window-" + data.id)
|
||||
.find(".users")
|
||||
.html(render("#users", {users: data.users}))
|
||||
.html(render("users", {users: data.users}))
|
||||
.end();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var z = 1;
|
||||
sidebar.on("click", "button", function() {
|
||||
var button = $(this);
|
||||
var target = button.data("target");
|
||||
sidebar.find(".active").removeClass("active");
|
||||
button.addClass("active")
|
||||
$(target)
|
||||
.css({"z-index": z++})
|
||||
.find(".input")
|
||||
.focus()
|
||||
.end();
|
||||
});
|
||||
|
||||
chat.on("click", ".show-more .btn", function() {
|
||||
var target = $(this).parent();
|
||||
var html = $.parseHTML(target.next(".hidden").remove().html());
|
||||
target.replaceWith(html);
|
||||
});
|
||||
|
||||
chat.on("click", ".user", function() {
|
||||
var user = $(this);
|
||||
var id = user.closest(".window").find(".form").data("target");
|
||||
var name = user.html().replace(/[\s+@]/g, "");
|
||||
if (name == "-!-" || name.indexOf(".") != -1) {
|
||||
return;
|
||||
}
|
||||
console.log({id: id, text: "/whois " + name});
|
||||
socket.emit("input", {
|
||||
id: id,
|
||||
text: "/whois " + name,
|
||||
});
|
||||
});
|
||||
|
||||
chat.on("submit", "form", function() {
|
||||
var input = $(this).find(".input");
|
||||
var form = $(this);
|
||||
var input = form.find(".input");
|
||||
var text = input.val();
|
||||
if (text == "") {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
input.val("");
|
||||
socket.emit("input", {
|
||||
id: input.data("target"),
|
||||
id: form.data("target"),
|
||||
text: text,
|
||||
});
|
||||
});
|
||||
|
@ -133,74 +156,9 @@ $(function() {
|
|||
var input = $(this).parents().eq(1).find(".messages").scrollToBottom();
|
||||
});
|
||||
|
||||
chat.on("click", ".user", function() {
|
||||
var user = $(this);
|
||||
var id = user.closest(".window").find(".input").data("target");
|
||||
var name = user.text().trim();
|
||||
if (name == "-!-" || name.indexOf(".") != -1) {
|
||||
return;
|
||||
}
|
||||
socket.emit("input", {
|
||||
id: id,
|
||||
text: "/whois " + name,
|
||||
});
|
||||
});
|
||||
|
||||
chat.on("click", ".close", function() {
|
||||
var id = $(this).closest(".window").find(".input").data("target");
|
||||
socket.emit("input", {
|
||||
id: id,
|
||||
text: "/part",
|
||||
});
|
||||
});
|
||||
|
||||
chat.on("click", ".show-more .btn", function() {
|
||||
var more = $(this).parent();
|
||||
var html = $.parseHTML(more.next(".hidden").remove().html());
|
||||
more.replaceWith(html);
|
||||
});
|
||||
|
||||
sidebar.on("click", ".channel", function(e) {
|
||||
e.preventDefault();
|
||||
sidebar.find(".channel").removeClass("active");
|
||||
$("#window-" + $(this).addClass("active").attr("id").replace("channel-", ""))
|
||||
.bringToTop();
|
||||
});
|
||||
|
||||
function escape(text) {
|
||||
var e = {
|
||||
"<": "<",
|
||||
">": ">"
|
||||
};
|
||||
return text.replace(/[<>]/g, function (c) {
|
||||
return e[c];
|
||||
});
|
||||
}
|
||||
|
||||
Handlebars.registerHelper({
|
||||
"partial": function(id) {
|
||||
Handlebars.registerHelper(
|
||||
"partial", function(id) {
|
||||
return new Handlebars.SafeString(render(id, this));
|
||||
},
|
||||
"slice": function(items, block) {
|
||||
var limit = block.hash.limit;
|
||||
var rows = $.map(items, function(i) {
|
||||
return block.fn(i);
|
||||
});
|
||||
var html = "";
|
||||
var hide = rows
|
||||
.slice(0, Math.max(0, rows.length - limit))
|
||||
.join("");
|
||||
if (hide != "") {
|
||||
html = "<script type='text/html' class='hidden'>" + hide + "</script>";
|
||||
}
|
||||
html += rows.slice(-limit).join("");
|
||||
return html;
|
||||
},
|
||||
"uri": function(text) {
|
||||
text = escape(text);
|
||||
return URI.withinString(text, function(url) {
|
||||
return "<a href='" + url.replace(/^www/, "//www") + "' target='_blank'>" + url + "</a>";
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
Handlebars.registerHelper(
|
||||
"slice", function(items, block) {
|
||||
var limit = block.hash.limit;
|
||||
var rows = [];
|
||||
items.forEach(function(i) {
|
||||
rows.push(block.fn(i));
|
||||
});
|
||||
var html = "";
|
||||
var hide = rows
|
||||
.slice(0, Math.max(0, rows.length - limit))
|
||||
.join("");
|
||||
if (hide != "") {
|
||||
html = "<script type='text/html' class='hidden'>" + hide + "</script>";
|
||||
}
|
||||
html += rows.slice(-limit).join("");
|
||||
return html;
|
||||
}
|
||||
);
|
||||
|
||||
function escape(text) {
|
||||
var e = {
|
||||
"<": "<",
|
||||
">": ">"
|
||||
};
|
||||
return text.replace(/[<>]/g, function (c) {
|
||||
return e[c];
|
||||
});
|
||||
}
|
||||
|
||||
Handlebars.registerHelper(
|
||||
"uri", function(text) {
|
||||
text = escape(text);
|
||||
return URI.withinString(text, function(url) {
|
||||
return "<a href='" + url.replace(/^www/, "//www") + "' target='_blank'>" + url + "</a>";
|
||||
});
|
||||
}
|
||||
);
|
|
@ -179,7 +179,7 @@
|
|||
* Copyright (c) 2014 Mattias Erming <mattias@mattiaserming.com>
|
||||
* Licensed under the MIT License.
|
||||
*
|
||||
* Version 0.2.3
|
||||
* Version 0.2.4
|
||||
*/
|
||||
(function($) {
|
||||
$.fn.tabComplete = function(options) {
|
||||
|
@ -211,16 +211,25 @@
|
|||
var last = text.splice(-1)[0];
|
||||
|
||||
if (!match.length) {
|
||||
match = $.grep(self.data('list'), function(w) {
|
||||
match = [];
|
||||
$.each(self.data('list'), function(i, w) {
|
||||
var l = last;
|
||||
if (l == '') {
|
||||
return;
|
||||
} else if (typeof w === "function") {
|
||||
var words = w(l);
|
||||
if (words) {
|
||||
match = match.concat(words);
|
||||
}
|
||||
} else if (!settings.caseSensitive) {
|
||||
if (0 == w.toLowerCase().indexOf(l.toLowerCase())) {
|
||||
match.push(w);
|
||||
}
|
||||
} else {
|
||||
if (0 == w.indexOf(l)) {
|
||||
match.push(w);
|
||||
}
|
||||
}
|
||||
if (!settings.caseSensitive) {
|
||||
l = l.toLowerCase();
|
||||
w = w.toLowerCase();
|
||||
}
|
||||
return w.indexOf(l) == 0;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
module.exports = {
|
||||
port: 9000,
|
||||
theme: "",
|
||||
defaults: {
|
||||
nick: "shout_user",
|
||||
realname: "http://github.com/erming/shout",
|
||||
|
|
|
@ -19,13 +19,7 @@ function Network(attr) {
|
|||
};
|
||||
|
||||
Network.prototype.toJSON = function() {
|
||||
var copy = _.omit(
|
||||
this,
|
||||
"client"
|
||||
);
|
||||
var name = copy.host.split(".")[1];
|
||||
if (name) {
|
||||
copy.host = name;
|
||||
}
|
||||
return copy;
|
||||
var clone = _.omit(this, "client");
|
||||
clone.name = clone.host.split(".")[1] || clone.host;
|
||||
return clone;
|
||||
};
|
||||
|
|
|
@ -14,9 +14,7 @@ var Network = require("./models/network");
|
|||
var User = require("./models/user");
|
||||
|
||||
var sockets = null;
|
||||
var networks = [
|
||||
new Network({host: "Shout Client"})
|
||||
];
|
||||
var networks = [];
|
||||
|
||||
var events = [
|
||||
"join",
|
||||
|
@ -59,7 +57,7 @@ function index(req, res, next) {
|
|||
fs.readFile("client/index.html", function(err, file) {
|
||||
var data = _.merge(
|
||||
require("../package.json"),
|
||||
config
|
||||
{} // config
|
||||
);
|
||||
res.end(_.template(
|
||||
file,
|
||||
|
|
Loading…
Reference in New Issue