client/general: replace handlebars with underscore
This commit is contained in:
parent
c34b1e3ccf
commit
6405fbe9f2
24 changed files with 242 additions and 231 deletions
|
@ -1,4 +1,4 @@
|
|||
<div class='page'>
|
||||
<p><span>Page {{this.page}} of {{this.totalPages}}</span></p>
|
||||
<p><span>Page <%= page %> of <%= totalPages %></span></p>
|
||||
<div class='page-content-holder'></div>
|
||||
</div>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<div class='file-dropper-holder'>
|
||||
<input type='file' name='{{this.name}}' id='{{this.id}}'/>
|
||||
<label class='file-dropper' for='{{this.id}}'>
|
||||
{{#if this.allowMultiple}}
|
||||
<input type='file' id='<%= id %>'/>
|
||||
<label class='file-dropper' for='<%= id %>'>
|
||||
<% if (allowMultiple) { %>
|
||||
Drop files here!
|
||||
{{else}}
|
||||
<% } else { %>
|
||||
Drop file here!
|
||||
{{/if}}
|
||||
<% } %>
|
||||
<br/>
|
||||
Or just click on this box.
|
||||
</label>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<p>By accessing {{ name }} (“Site”) you agree to the following
|
||||
<p>By accessing <%= name %> (“Site”) you agree to the following
|
||||
Terms of Service. If you do not agree to these terms, then please do not access
|
||||
the Site.</p>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class='content-wrapper transparent' id='home'>
|
||||
<div class='messages'></div>
|
||||
<h1>{{name}}</h1>
|
||||
<footer>Version: <span class='version'>{{version}}</span> (built {{reltime buildDate}})</footer>
|
||||
<h1><%= name %></h1>
|
||||
<footer>Version: <span class='version'><%= version %></span> (built <%= makeRelativeTime(buildDate) %>)</footer>
|
||||
</div>
|
||||
|
|
|
@ -4,22 +4,22 @@
|
|||
<div class='input'>
|
||||
<ul>
|
||||
<li>
|
||||
{{textInput text='User name' id='user-name' name='name' required=true pattern=this.userNamePattern}}
|
||||
<%= makeTextInput({text: 'User name', id: 'user-name', name: 'name', required: true, pattern: userNamePattern}) %>
|
||||
</li>
|
||||
<li>
|
||||
{{passwordInput text='Password' id='user-password' name='password' required=true pattern=this.passwordPattern}}
|
||||
<%= makePasswordInput({text: 'Password', id: 'user-password', name: 'password', required: true, pattern: passwordPattern}) %>
|
||||
</li>
|
||||
<li>
|
||||
{{checkbox text='Remember me' id='remember-user' name='remember-user'}}
|
||||
<%= makeCheckbox({text: 'Remember me', id: 'remember-user', name: 'remember-user'}) %>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='messages'></div>
|
||||
<div class='buttons'>
|
||||
<input type='submit' value='Log in'/>
|
||||
{{#if this.canSendMails}}
|
||||
<% if (canSendMails) { %>
|
||||
<a class='append' href='/password-reset'>Forgot the password?</a>
|
||||
{{/if}}
|
||||
<% } %>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -1,36 +1,36 @@
|
|||
<nav class='text-nav'>
|
||||
<ul>
|
||||
<li>
|
||||
{{#if this.prevLinkActive}}
|
||||
<a class='prev' href='{{this.prevLink}}'>
|
||||
{{else}}
|
||||
<a class='prev disabled'>
|
||||
{{/if}}
|
||||
<% if (prevLinkActive) { %>
|
||||
<a class='prev' href='<%= prevLink %>'>
|
||||
<% } else { %>
|
||||
<a class='prev disabled'>
|
||||
<% } %>
|
||||
<i class='fa fa-chevron-left'></i>
|
||||
<span>Previous page</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
{{#each this.pages}}
|
||||
{{#if this.ellipsis}}
|
||||
<% _.each(pages, page => { %>
|
||||
<% if (page.ellipsis) { %>
|
||||
<li>…</li>
|
||||
{{else}}
|
||||
{{#if this.active}}
|
||||
<% } else { %>
|
||||
<% if (page.active) { %>
|
||||
<li class='active'>
|
||||
{{else}}
|
||||
<% } else { %>
|
||||
<li>
|
||||
{{/if}}
|
||||
<a href='{{this.link}}'>{{this.number}}</a>
|
||||
<% } %>
|
||||
<a href='<%= page.link %>'><%= page.number %></a>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
<% } %>
|
||||
<% }) %>
|
||||
|
||||
<li>
|
||||
{{#if this.nextLinkActive}}
|
||||
<a class='next' href='{{this.nextLink}}'>
|
||||
{{else}}
|
||||
<a class='next disabled'>
|
||||
{{/if}}
|
||||
<% if (nextLinkActive) { %>
|
||||
<a class='next' href='<%= nextLink %>'>
|
||||
<% } else { %>
|
||||
<a class='next disabled'>
|
||||
<% } %>
|
||||
<i class='fa fa-chevron-right'></i>
|
||||
<span>Next page</span>
|
||||
</a>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<div class='input'>
|
||||
<ul>
|
||||
<li>
|
||||
{{textInput text='User name or e-mail address' id='user-name' name='user-name' required=true}}
|
||||
<%= makeTextInput({text: 'User name or e-mail address', id: 'user-name', name: 'user-name', required: true}) %>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
<div class='input'>
|
||||
<ul>
|
||||
<li>
|
||||
{{checkbox text='Endless scroll' id='endless-scroll' name='endless-scroll' checked=this.browsingSettings.endlessScroll}}
|
||||
<%= makeCheckbox({text: 'Endless scroll', id: 'endless-scroll', name: 'endless-scroll', checked: browsingSettings.endlessScroll}) %>
|
||||
<p class='hint'>Rather than using a paged navigation, smoothly scroll through the content.</p>
|
||||
</li>
|
||||
<li>
|
||||
{{checkbox text='Enable keyboard shortcuts' id='keyboard-shortcuts' name='keyboard-shortcuts' checked=this.browsingSettings.keyboardShortcuts}}
|
||||
<%= makeCheckbox({text: 'Enable keyboard shortcuts', id: 'keyboard-shortcuts', name: 'keyboard-shortcuts', checked: browsingSettings.keyboardShortcuts}) %>
|
||||
<a class='append icon' href='/help/keyboard'><i class='fa fa-question-circle-o'></i></a>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<div class='input'>
|
||||
<ul>
|
||||
<li>
|
||||
{{textInput id='search-text' name='search-text' value=this.searchQuery.text}}
|
||||
<%= makeTextInput({id: 'search-text', name: 'search-text', value: searchQuery.text}) %>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class='tag-list'>
|
||||
{{#if this.results}}
|
||||
<% if (results) { %>
|
||||
<table>
|
||||
<thead>
|
||||
<th class='names'>Tag name(s)</th>
|
||||
|
@ -8,43 +8,43 @@
|
|||
<th class='usages'>Usages</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each this.results}}
|
||||
<% _.each(results, tag => { %>
|
||||
<tr>
|
||||
<td class='names'>
|
||||
<ul>
|
||||
{{#each this.names}}
|
||||
<li><a href='/tag/{{this}}'>{{this}}</a></li>
|
||||
{{/each}}
|
||||
<% _.each(tag.names, name => { %>
|
||||
<li><a href='/tag/<%= name %>'><%= name %></a></li>
|
||||
<% }) %>
|
||||
</ul>
|
||||
</td>
|
||||
<td class='implications'>
|
||||
{{#if this.implications}}
|
||||
<% if (tag.implications.length) { %>
|
||||
<ul>
|
||||
{{#each this.implications}}
|
||||
<li><a href='/tag/{{this}}'>{{this}}</a></li>
|
||||
{{/each}}
|
||||
<% _.each(tag.implications, name => { %>
|
||||
<li><a href='/tag/<%= name %>'><%= name %></a></li>
|
||||
<% }) %>
|
||||
</ul>
|
||||
{{else}}
|
||||
<% } else { %>
|
||||
-
|
||||
{{/if}}
|
||||
<% } %>
|
||||
</td>
|
||||
<td class='suggestions'>
|
||||
{{#if this.suggestions}}
|
||||
<% if (tag.suggestions.length) { %>
|
||||
<ul>
|
||||
{{#each this.suggestions}}
|
||||
<li><a href='/tag/{{this}}'>{{this}}</a></li>
|
||||
{{/each}}
|
||||
<% _.each(tag.suggestions, name => { %>
|
||||
<li><a href='/tag/<%= name %>'><%= name %></a></li>
|
||||
<% }) %>
|
||||
</ul>
|
||||
{{else}}
|
||||
<% } else { %>
|
||||
-
|
||||
{{/if}}
|
||||
<% } %>
|
||||
</td>
|
||||
<td class='usages'>
|
||||
{{this.usages}}
|
||||
<%= tag.usages %>
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
<% }) %>
|
||||
</tbody>
|
||||
</table>
|
||||
{{/if}}
|
||||
<% } %>
|
||||
</div>
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<nav id='top-nav' class='text-nav'>
|
||||
<ul><!--
|
||||
-->{{#each items}}<!--
|
||||
-->{{#if this.available}}<!--
|
||||
--><li data-name='{{@key}}'><!--
|
||||
--><a href='{{this.url}}' accesskey='{{this.accessKey}}'><!--
|
||||
-->{{#if this.imageUrl}}{{thumbnail this.imageUrl}}{{/if}}<!--
|
||||
--><span class='text'>{{this.name}}</span><!--
|
||||
--><% _.each(items, (item, key) => { %><!--
|
||||
--><% if (item.available) { %><!--
|
||||
--><li data-name='<%= key %>'><!--
|
||||
--><a href='<%= item.url %>' accesskey='<%= item.accessKey %>'><!--
|
||||
--><% if (item.imageUrl) { print(makeThumbnail(item.imageUrl)); } %><!--
|
||||
--><span class='text'><%- item.name %></span><!--
|
||||
--></a><!--
|
||||
--></li><!--
|
||||
-->{{/if}}<!--
|
||||
-->{{/each}}<!--
|
||||
--><% } %><!--
|
||||
--><% }) %><!--
|
||||
--></ul>
|
||||
</nav>
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<div class='content-wrapper' id='user'>
|
||||
<h1>{{this.user.name}}</h1>
|
||||
<h1><%= user.name %></h1>
|
||||
<nav class='text-nav'><!--
|
||||
--><ul><!--
|
||||
--><li data-name='summary'><a href='/user/{{this.user.name}}'>Summary</a></li><!--
|
||||
-->{{#if this.canEditAnything}}<!--
|
||||
--><li data-name='edit'><a href='/user/{{this.user.name}}/edit'>Account settings</a></li><!--
|
||||
-->{{/if}}<!--
|
||||
-->{{#if this.canDelete}}<!--
|
||||
--><li data-name='delete'><a href='/user/{{this.user.name}}/delete'>Account deletion</a></li><!--
|
||||
-->{{/if}}<!--
|
||||
--><li data-name='summary'><a href='/user/<%= user.name %>'>Summary</a></li><!--
|
||||
--><% if (canEditAnything) { %><!--
|
||||
--><li data-name='edit'><a href='/user/<%= user.name %>/edit'>Account settings</a></li><!--
|
||||
--><% } %><!--
|
||||
--><% if (canDelete) { %><!--
|
||||
--><li data-name='delete'><a href='/user/<%= user.name %>/delete'>Account deletion</a></li><!--
|
||||
--><% } %><!--
|
||||
--></ul><!--
|
||||
--></nav>
|
||||
<div id='user-content-holder'></div>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<div class='input'>
|
||||
<ul>
|
||||
<li>
|
||||
{{checkbox id='confirm-deletion' name='confirm-deletion' required=true text='I confirm that I want to delete this account.'}}
|
||||
<%= makeCheckbox({id: 'confirm-deletion', name: 'confirm-deletion', required: true, text: 'I confirm that I want to delete this account.'}) %>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -3,29 +3,29 @@
|
|||
<div class='left'>
|
||||
<div class='input'>
|
||||
<ul>
|
||||
{{#if this.canEditName}}
|
||||
<% if (canEditName) { %>
|
||||
<li>
|
||||
{{textInput text='User name' id='user-name' name='name' value=this.user.name pattern=this.userNamePattern}}
|
||||
<%= makeTextInput({text: 'User name', id: 'user-name', name: 'name', value: user.name, pattern: userNamePattern}) %>
|
||||
</li>
|
||||
{{/if}}
|
||||
<% } %>
|
||||
|
||||
{{#if this.canEditPassword}}
|
||||
<% if (canEditPassword) { %>
|
||||
<li>
|
||||
{{passwordInput text='Password' id='user-password' name='password' placeholder='leave blank if not changing' pattern=this.passwordPattern}}
|
||||
<%= makePasswordInput({text: 'Password', id: 'user-password', name: 'password', placeholder: 'leave blank if not changing', pattern: passwordPattern}) %>
|
||||
</li>
|
||||
{{/if}}
|
||||
<% } %>
|
||||
|
||||
{{#if this.canEditEmail}}
|
||||
<% if (canEditEmail) { %>
|
||||
<li>
|
||||
{{emailInput text='Email' id='user-email' name='email' value=this.user.email}}
|
||||
<%= makeEmailInput({text: 'Email', id: 'user-email', name: 'email', value: user.email}) %>
|
||||
</li>
|
||||
{{/if}}
|
||||
<% } %>
|
||||
|
||||
{{#if this.canEditRank}}
|
||||
<% if (canEditRank) { %>
|
||||
<li>
|
||||
{{select text='Rank' id='user-rank' name='rank' keyValues=this.ranks selectedKey=this.user.rank}}
|
||||
<%= makeSelect({text: 'Rank', id: 'user-rank', name: 'rank', keyValues: ranks, selectedKey: user.rank}) %>
|
||||
</li>
|
||||
{{/if}}
|
||||
<% } %>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='messages'></div>
|
||||
|
@ -34,18 +34,18 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{#if this.canEditAvatar}}
|
||||
<% if (canEditAvatar) { %>
|
||||
<div class='right'>
|
||||
<ul>
|
||||
<li>
|
||||
{{radio text='Gravatar' id='gravatar-radio' name='avatar-style' value='gravatar' selectedValue=this.user.avatarStyle}}
|
||||
<%= makeRadio({text: 'Gravatar', id: 'gravatar-radio', name: 'avatar-style', value: 'gravatar', selectedValue: user.avatarStyle}) %>
|
||||
</li>
|
||||
<li>
|
||||
{{radio text='Manual avatar' id='avatar-radio' name='avatar-style' value='manual' selectedValue=this.user.avatarStyle}}
|
||||
<%= makeRadio({text: 'Manual avatar', id: 'avatar-radio', name: 'avatar-style', value: 'manual', selectedValue: user.avatarStyle}) %>
|
||||
<div id='avatar-content'></div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{{/if}}
|
||||
<% } %>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<div class='input'>
|
||||
<ul>
|
||||
<li>
|
||||
{{textInput id='search-text' name='search-text' value=this.searchQuery.text}}
|
||||
<%= makeTextInput({id: 'search-text', name: 'search-text', value: searchQuery.text}) %>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
<div class='user-list'>
|
||||
<ul><!--
|
||||
-->{{#each this.results}}<!--
|
||||
--><% _.each(results, user => { %><!--
|
||||
--><li>
|
||||
<div class='wrapper'>
|
||||
<a class='image' href='/user/{{this.name}}'>{{thumbnail this.avatarUrl}}</a>
|
||||
<a class='image' href='/user/<%= user.name %>'><%= makeThumbnail(user.avatarUrl) %></a>
|
||||
<div class='details'>
|
||||
<a href='/user/{{this.name}}'>{{this.name}}</a><br/>
|
||||
Registered: {{reltime this.creationTime}}<br/>
|
||||
Last seen: {{reltime this.lastLoginTime}}
|
||||
<a href='/user/<%= user.name %>'><%= user.name %></a><br/>
|
||||
Registered: <%= makeRelativeTime(user.creationTime) %><br/>
|
||||
Last seen: <%= makeRelativeTime(user.lastLoginTime) %>
|
||||
</div>
|
||||
</div>
|
||||
</li><!--
|
||||
-->{{/each}}<!--
|
||||
-->{{alignFlexbox}}<!--
|
||||
--><% }) %><!--
|
||||
--><%= makeFlexboxAlign() %><!--
|
||||
--></ul>
|
||||
</div>
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
<div class='input'>
|
||||
<ul>
|
||||
<li>
|
||||
{{textInput text='User name' id='user-name' name='user-name' placeholder='letters, digits, _, -' required=true pattern=this.userNamePattern}}
|
||||
<%= makeTextInput({text: 'User name', id: 'user-name', name: 'user-name', placeholder: 'letters, digits, _, -', required: true, pattern: userNamePattern}) %>
|
||||
</li>
|
||||
<li>
|
||||
{{passwordInput text='Password' id='user-password' name='user-password' placeholder='5+ characters' required=true pattern=this.passwordPattern}}
|
||||
<%= makePasswordInput({text: 'Password', id: 'user-password', name: 'user-password', placeholder: '5+ characters', required: true, pattern: passwordPattern}) %>
|
||||
</li>
|
||||
<li>
|
||||
{{emailInput text='Email' id='user-email' name='user-email' placeholder='optional'}}
|
||||
<%= makeEmailInput({text: 'Email', id: 'user-email', name: 'user-email', placeholder: 'optional'}) %>
|
||||
<p class='hint'>Used for password reminder and to show a <a href='http://gravatar.com/'>Gravatar</a>. Leave blank for random Gravatar.</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
<div id='user-summary'>
|
||||
{{thumbnail this.user.avatarUrl}}
|
||||
<%= makeThumbnail(user.avatarUrl) %>
|
||||
<ul class='basic-info'>
|
||||
<li>Registered: {{reltime this.user.creationTime}}</li>
|
||||
<li>Last seen: {{reltime this.user.lastLoginTime}}</li>
|
||||
<li>Rank: {{toLowerCase this.user.rankName}}</li>
|
||||
<li>Registered: <%= makeRelativeTime(user.creationTime) %></li>
|
||||
<li>Last seen: <%= makeRelativeTime(user.lastLoginTime) %></li>
|
||||
<li>Rank: <%= user.rankName.toLowerCase() %></li>
|
||||
</ul>
|
||||
|
||||
<div>
|
||||
<nav class='plain-nav'>
|
||||
<p><strong>Quick links</strong></p>
|
||||
<ul>
|
||||
<li><a href='/posts/submit:{{this.user.name}}'>Uploads</a></li>
|
||||
<li><a href='/posts/fav:{{this.user.name}}'>Favorites</a></li>
|
||||
<li><a href='/posts/commented:{{this.user.name}}'>Posts commented on</a></li>
|
||||
<li><a href='/posts/submit:<%= user.name %>'>Uploads</a></li>
|
||||
<li><a href='/posts/fav:<%= user.name %>'>Favorites</a></li>
|
||||
<li><a href='/posts/comment:<%= user.name %>'>Posts commented on</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
{{#if this.isLoggedIn}}
|
||||
<% if (isLoggedIn) { %>
|
||||
<nav class='plain-nav'>
|
||||
<p><strong>Only visible to you</strong></p>
|
||||
<ul>
|
||||
|
@ -24,6 +24,6 @@
|
|||
<li><a href='/posts/special:disliked'>Disliked posts</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
{{/if}}
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,113 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
const views = require('../util/views.js');
|
||||
const handlebars = require('handlebars');
|
||||
const misc = require('./misc.js');
|
||||
|
||||
function makeLabel(options, attrs) {
|
||||
if (!options.hash.text) {
|
||||
return '';
|
||||
}
|
||||
if (!attrs) {
|
||||
attrs = {};
|
||||
}
|
||||
attrs.for = options.hash.id;
|
||||
return views.makeNonVoidElement('label', attrs, options.hash.text);
|
||||
}
|
||||
|
||||
handlebars.registerHelper('reltime', function(time) {
|
||||
return new handlebars.SafeString(
|
||||
views.makeNonVoidElement(
|
||||
'time',
|
||||
{datetime: time, title: time},
|
||||
misc.formatRelativeTime(time)));
|
||||
});
|
||||
|
||||
handlebars.registerHelper('thumbnail', function(url) {
|
||||
return new handlebars.SafeString(
|
||||
views.makeNonVoidElement('span', {
|
||||
class: 'thumbnail',
|
||||
style: 'background-image: url(\'{0}\')'.format(url)
|
||||
}, views.makeVoidElement('img', {alt: 'thumbnail', src: url})));
|
||||
});
|
||||
|
||||
handlebars.registerHelper('toLowerCase', function(str) {
|
||||
return str.toLowerCase();
|
||||
});
|
||||
|
||||
handlebars.registerHelper('radio', function(options) {
|
||||
return new handlebars.SafeString('{0}{1}'.format(
|
||||
views.makeVoidElement('input', {
|
||||
id: options.hash.id,
|
||||
name: options.hash.name,
|
||||
value: options.hash.value,
|
||||
type: 'radio',
|
||||
checked: options.hash.selectedValue === options.hash.value,
|
||||
required: options.hash.required,
|
||||
}),
|
||||
makeLabel(options, {class: 'radio'})));
|
||||
});
|
||||
|
||||
handlebars.registerHelper('checkbox', function(options) {
|
||||
return new handlebars.SafeString('{0}{1}'.format(
|
||||
views.makeVoidElement('input', {
|
||||
id: options.hash.id,
|
||||
name: options.hash.name,
|
||||
value: options.hash.value,
|
||||
type: 'checkbox',
|
||||
checked: options.hash.checked !== undefined ?
|
||||
options.hash.checked : false,
|
||||
required: options.hash.required,
|
||||
}),
|
||||
makeLabel(options, {class: 'checkbox'})));
|
||||
});
|
||||
|
||||
handlebars.registerHelper('select', function(options) {
|
||||
return new handlebars.SafeString('{0}{1}'.format(
|
||||
makeLabel(options),
|
||||
views.makeNonVoidElement(
|
||||
'select',
|
||||
{id: options.hash.id, name: options.hash.name},
|
||||
Object.keys(options.hash.keyValues).map(key => {
|
||||
return views.makeNonVoidElement(
|
||||
'option',
|
||||
{value: key, selected: key === options.hash.selectedKey},
|
||||
options.hash.keyValues[key]);
|
||||
}).join(''))));
|
||||
});
|
||||
|
||||
handlebars.registerHelper('input', function(options) {
|
||||
return new handlebars.SafeString('{0}{1}'.format(
|
||||
makeLabel(options),
|
||||
views.makeVoidElement(
|
||||
'input', {
|
||||
type: options.hash.inputType,
|
||||
name: options.hash.name,
|
||||
id: options.hash.id,
|
||||
value: options.hash.value || '',
|
||||
required: options.hash.required,
|
||||
pattern: options.hash.pattern,
|
||||
placeholder: options.hash.placeholder,
|
||||
})));
|
||||
});
|
||||
|
||||
handlebars.registerHelper('textInput', function(options) {
|
||||
options.hash.inputType = 'text';
|
||||
return handlebars.helpers.input(options);
|
||||
});
|
||||
|
||||
handlebars.registerHelper('passwordInput', function(options) {
|
||||
options.hash.inputType = 'password';
|
||||
return handlebars.helpers.input(options);
|
||||
});
|
||||
|
||||
handlebars.registerHelper('emailInput', function(options) {
|
||||
options.hash.inputType = 'email';
|
||||
return handlebars.helpers.input(options);
|
||||
});
|
||||
|
||||
handlebars.registerHelper('alignFlexbox', function(options) {
|
||||
return new handlebars.SafeString(
|
||||
Array.from(misc.range(20))
|
||||
.map(() => '<li class="flexbox-dummy"></li>').join(''));
|
||||
});
|
|
@ -1,9 +1,114 @@
|
|||
'use strict';
|
||||
|
||||
require('../util/polyfill.js');
|
||||
const handlebars = require('handlebars');
|
||||
const underscore = require('underscore');
|
||||
const events = require('../events.js');
|
||||
const domParser = new DOMParser();
|
||||
const misc = require('./misc.js');
|
||||
|
||||
function _makeLabel(options, attrs) {
|
||||
if (!options.text) {
|
||||
return '';
|
||||
}
|
||||
if (!attrs) {
|
||||
attrs = {};
|
||||
}
|
||||
attrs.for = options.id;
|
||||
return makeNonVoidElement('label', attrs, options.text);
|
||||
}
|
||||
|
||||
function makeRelativeTime(time) {
|
||||
return makeNonVoidElement(
|
||||
'time',
|
||||
{datetime: time, title: time},
|
||||
misc.formatRelativeTime(time));
|
||||
}
|
||||
|
||||
function makeThumbnail(url) {
|
||||
return makeNonVoidElement(
|
||||
'span',
|
||||
{
|
||||
class: 'thumbnail',
|
||||
style: 'background-image: url(\'{0}\')'.format(url)
|
||||
},
|
||||
makeVoidElement('img', {alt: 'thumbnail', src: url}));
|
||||
}
|
||||
|
||||
function makeRadio(options) {
|
||||
return makeVoidElement(
|
||||
'input',
|
||||
{
|
||||
id: options.id,
|
||||
name: options.name,
|
||||
value: options.value,
|
||||
type: 'radio',
|
||||
checked: options.selectedValue === options.value,
|
||||
required: options.required,
|
||||
}) +
|
||||
_makeLabel(options, {class: 'radio'});
|
||||
}
|
||||
|
||||
function makeCheckbox(options) {
|
||||
return makeVoidElement(
|
||||
'input',
|
||||
{
|
||||
id: options.id,
|
||||
name: options.name,
|
||||
value: options.value,
|
||||
type: 'checkbox',
|
||||
checked: options.checked !== undefined ?
|
||||
options.checked : false,
|
||||
required: options.required,
|
||||
}) +
|
||||
_makeLabel(options, {class: 'checkbox'});
|
||||
}
|
||||
|
||||
function makeSelect(options) {
|
||||
return _makeLabel(options) +
|
||||
makeNonVoidElement(
|
||||
'select',
|
||||
{id: options.id, name: options.name},
|
||||
Object.keys(options.keyValues).map(key => {
|
||||
return makeNonVoidElement(
|
||||
'option',
|
||||
{value: key, selected: key === options.selectedKey},
|
||||
options.keyValues[key]);
|
||||
}).join(''));
|
||||
}
|
||||
|
||||
function makeInput(options) {
|
||||
return _makeLabel(options)
|
||||
+ makeVoidElement(
|
||||
'input', {
|
||||
type: options.inputType,
|
||||
name: options.name,
|
||||
id: options.id,
|
||||
value: options.value || '',
|
||||
required: options.required,
|
||||
pattern: options.pattern,
|
||||
placeholder: options.placeholder,
|
||||
});
|
||||
}
|
||||
|
||||
function makeTextInput(options) {
|
||||
options.inputType = 'text';
|
||||
return makeInput(options);
|
||||
}
|
||||
|
||||
function makePasswordInput(options) {
|
||||
options.inputType = 'password';
|
||||
return makeInput(options);
|
||||
}
|
||||
|
||||
function makeEmailInput(options) {
|
||||
options.inputType = 'email';
|
||||
return makeInput(options);
|
||||
}
|
||||
|
||||
function makeFlexboxAlign(options) {
|
||||
return Array.from(misc.range(20))
|
||||
.map(() => '<li class="flexbox-dummy"></li>').join('');
|
||||
}
|
||||
|
||||
function _messageHandler(target, message, className) {
|
||||
if (!message) {
|
||||
|
@ -81,9 +186,24 @@ function getTemplate(templatePath) {
|
|||
return null;
|
||||
}
|
||||
const templateText = templates[templatePath].trim();
|
||||
const templateFactory = handlebars.compile(templateText);
|
||||
return (...args) => {
|
||||
return htmlToDom(templateFactory(...args));
|
||||
const templateFactory = underscore.template(templateText);
|
||||
return ctx => {
|
||||
if (!ctx) {
|
||||
ctx = {};
|
||||
}
|
||||
underscore.extend(ctx, {
|
||||
makeRelativeTime: makeRelativeTime,
|
||||
makeThumbnail: makeThumbnail,
|
||||
makeRadio: makeRadio,
|
||||
makeCheckbox: makeCheckbox,
|
||||
makeSelect: makeSelect,
|
||||
makeInput: makeInput,
|
||||
makeTextInput: makeTextInput,
|
||||
makePasswordInput: makePasswordInput,
|
||||
makeEmailInput: makeEmailInput,
|
||||
makeFlexboxAlign: makeFlexboxAlign,
|
||||
});
|
||||
return htmlToDom(templateFactory(ctx));
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ class FileDropperControl {
|
|||
render(ctx) {
|
||||
const target = ctx.target;
|
||||
const source = this.template({
|
||||
allowMultiple: ctx.allowMultiple,
|
||||
id: 'file-' + Math.random().toString(36).substring(7),
|
||||
});
|
||||
|
||||
|
|
|
@ -10,7 +10,11 @@ class LoginView {
|
|||
|
||||
render(ctx) {
|
||||
const target = document.getElementById('content-holder');
|
||||
const source = this.template({canSendMails: config.canSendMails});
|
||||
const source = this.template({
|
||||
userNamePattern: config.userNameRegex,
|
||||
passwordPattern: config.passwordRegex,
|
||||
canSendMails: config.canSendMails,
|
||||
});
|
||||
|
||||
const form = source.querySelector('form');
|
||||
const userNameField = source.querySelector('#user-name');
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
'use strict';
|
||||
|
||||
require('../util/handlebars-helpers.js');
|
||||
const views = require('../util/views.js');
|
||||
|
||||
class TopNavView {
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
"camelcase-keys": "*",
|
||||
"csso": "^1.8.0",
|
||||
"glob": "^7.0.3",
|
||||
"handlebars": "^4.0.5",
|
||||
"html-minifier": "^1.3.1",
|
||||
"js-cookie": "^2.1.0",
|
||||
"js-yaml": "^3.5.5",
|
||||
|
@ -24,7 +23,8 @@
|
|||
"page": "^1.7.1",
|
||||
"stylus": "^0.54.2",
|
||||
"superagent": "^1.8.3",
|
||||
"uglify-js": "git://github.com/mishoo/UglifyJS2.git#harmony"
|
||||
"uglify-js": "git://github.com/mishoo/UglifyJS2.git#harmony",
|
||||
"underscore": "^1.8.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"watch": "latest"
|
||||
|
|
Loading…
Reference in a new issue