client/general: replace handlebars with underscore

This commit is contained in:
rr- 2016-05-09 20:07:54 +02:00
parent c34b1e3ccf
commit 6405fbe9f2
24 changed files with 242 additions and 231 deletions

View File

@ -1,4 +1,4 @@
<div class='page'> <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 class='page-content-holder'></div>
</div> </div>

View File

@ -1,11 +1,11 @@
<div class='file-dropper-holder'> <div class='file-dropper-holder'>
<input type='file' name='{{this.name}}' id='{{this.id}}'/> <input type='file' id='<%= id %>'/>
<label class='file-dropper' for='{{this.id}}'> <label class='file-dropper' for='<%= id %>'>
{{#if this.allowMultiple}} <% if (allowMultiple) { %>
Drop files here! Drop files here!
{{else}} <% } else { %>
Drop file here! Drop file here!
{{/if}} <% } %>
<br/> <br/>
Or just click on this box. Or just click on this box.
</label> </label>

View File

@ -1,4 +1,4 @@
<p>By accessing {{ name }} (&ldquo;Site&rdquo;) you agree to the following <p>By accessing <%= name %> (&ldquo;Site&rdquo;) you agree to the following
Terms of Service. If you do not agree to these terms, then please do not access Terms of Service. If you do not agree to these terms, then please do not access
the Site.</p> the Site.</p>

View File

@ -1,5 +1,5 @@
<div class='content-wrapper transparent' id='home'> <div class='content-wrapper transparent' id='home'>
<div class='messages'></div> <div class='messages'></div>
<h1>{{name}}</h1> <h1><%= name %></h1>
<footer>Version: <span class='version'>{{version}}</span> (built {{reltime buildDate}})</footer> <footer>Version: <span class='version'><%= version %></span> (built <%= makeRelativeTime(buildDate) %>)</footer>
</div> </div>

View File

@ -4,22 +4,22 @@
<div class='input'> <div class='input'>
<ul> <ul>
<li> <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>
<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>
<li> <li>
{{checkbox text='Remember me' id='remember-user' name='remember-user'}} <%= makeCheckbox({text: 'Remember me', id: 'remember-user', name: 'remember-user'}) %>
</li> </li>
</ul> </ul>
</div> </div>
<div class='messages'></div> <div class='messages'></div>
<div class='buttons'> <div class='buttons'>
<input type='submit' value='Log in'/> <input type='submit' value='Log in'/>
{{#if this.canSendMails}} <% if (canSendMails) { %>
<a class='append' href='/password-reset'>Forgot the password?</a> <a class='append' href='/password-reset'>Forgot the password?</a>
{{/if}} <% } %>
</div> </div>
</form> </form>
</div> </div>

View File

@ -1,36 +1,36 @@
<nav class='text-nav'> <nav class='text-nav'>
<ul> <ul>
<li> <li>
{{#if this.prevLinkActive}} <% if (prevLinkActive) { %>
<a class='prev' href='{{this.prevLink}}'> <a class='prev' href='<%= prevLink %>'>
{{else}} <% } else { %>
<a class='prev disabled'> <a class='prev disabled'>
{{/if}} <% } %>
<i class='fa fa-chevron-left'></i> <i class='fa fa-chevron-left'></i>
<span>Previous page</span> <span>Previous page</span>
</a> </a>
</li> </li>
{{#each this.pages}} <% _.each(pages, page => { %>
{{#if this.ellipsis}} <% if (page.ellipsis) { %>
<li>&hellip;</li> <li>&hellip;</li>
{{else}} <% } else { %>
{{#if this.active}} <% if (page.active) { %>
<li class='active'> <li class='active'>
{{else}} <% } else { %>
<li> <li>
{{/if}} <% } %>
<a href='{{this.link}}'>{{this.number}}</a> <a href='<%= page.link %>'><%= page.number %></a>
</li> </li>
{{/if}} <% } %>
{{/each}} <% }) %>
<li> <li>
{{#if this.nextLinkActive}} <% if (nextLinkActive) { %>
<a class='next' href='{{this.nextLink}}'> <a class='next' href='<%= nextLink %>'>
{{else}} <% } else { %>
<a class='next disabled'> <a class='next disabled'>
{{/if}} <% } %>
<i class='fa fa-chevron-right'></i> <i class='fa fa-chevron-right'></i>
<span>Next page</span> <span>Next page</span>
</a> </a>

View File

@ -4,7 +4,7 @@
<div class='input'> <div class='input'>
<ul> <ul>
<li> <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> </li>
</ul> </ul>
</div> </div>

View File

@ -5,11 +5,11 @@
<div class='input'> <div class='input'>
<ul> <ul>
<li> <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> <p class='hint'>Rather than using a paged navigation, smoothly scroll through the content.</p>
</li> </li>
<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> <a class='append icon' href='/help/keyboard'><i class='fa fa-question-circle-o'></i></a>
</li> </li>
</ul> </ul>

View File

@ -3,7 +3,7 @@
<div class='input'> <div class='input'>
<ul> <ul>
<li> <li>
{{textInput id='search-text' name='search-text' value=this.searchQuery.text}} <%= makeTextInput({id: 'search-text', name: 'search-text', value: searchQuery.text}) %>
</li> </li>
</ul> </ul>
</div> </div>

View File

@ -1,5 +1,5 @@
<div class='tag-list'> <div class='tag-list'>
{{#if this.results}} <% if (results) { %>
<table> <table>
<thead> <thead>
<th class='names'>Tag name(s)</th> <th class='names'>Tag name(s)</th>
@ -8,43 +8,43 @@
<th class='usages'>Usages</th> <th class='usages'>Usages</th>
</thead> </thead>
<tbody> <tbody>
{{#each this.results}} <% _.each(results, tag => { %>
<tr> <tr>
<td class='names'> <td class='names'>
<ul> <ul>
{{#each this.names}} <% _.each(tag.names, name => { %>
<li><a href='/tag/{{this}}'>{{this}}</a></li> <li><a href='/tag/<%= name %>'><%= name %></a></li>
{{/each}} <% }) %>
</ul> </ul>
</td> </td>
<td class='implications'> <td class='implications'>
{{#if this.implications}} <% if (tag.implications.length) { %>
<ul> <ul>
{{#each this.implications}} <% _.each(tag.implications, name => { %>
<li><a href='/tag/{{this}}'>{{this}}</a></li> <li><a href='/tag/<%= name %>'><%= name %></a></li>
{{/each}} <% }) %>
</ul> </ul>
{{else}} <% } else { %>
- -
{{/if}} <% } %>
</td> </td>
<td class='suggestions'> <td class='suggestions'>
{{#if this.suggestions}} <% if (tag.suggestions.length) { %>
<ul> <ul>
{{#each this.suggestions}} <% _.each(tag.suggestions, name => { %>
<li><a href='/tag/{{this}}'>{{this}}</a></li> <li><a href='/tag/<%= name %>'><%= name %></a></li>
{{/each}} <% }) %>
</ul> </ul>
{{else}} <% } else { %>
- -
{{/if}} <% } %>
</td> </td>
<td class='usages'> <td class='usages'>
{{this.usages}} <%= tag.usages %>
</td> </td>
</tr> </tr>
{{/each}} <% }) %>
</tbody> </tbody>
</table> </table>
{{/if}} <% } %>
</div> </div>

View File

@ -1,14 +1,14 @@
<nav id='top-nav' class='text-nav'> <nav id='top-nav' class='text-nav'>
<ul><!-- <ul><!--
-->{{#each items}}<!-- --><% _.each(items, (item, key) => { %><!--
-->{{#if this.available}}<!-- --><% if (item.available) { %><!--
--><li data-name='{{@key}}'><!-- --><li data-name='<%= key %>'><!--
--><a href='{{this.url}}' accesskey='{{this.accessKey}}'><!-- --><a href='<%= item.url %>' accesskey='<%= item.accessKey %>'><!--
-->{{#if this.imageUrl}}{{thumbnail this.imageUrl}}{{/if}}<!-- --><% if (item.imageUrl) { print(makeThumbnail(item.imageUrl)); } %><!--
--><span class='text'>{{this.name}}</span><!-- --><span class='text'><%- item.name %></span><!--
--></a><!-- --></a><!--
--></li><!-- --></li><!--
-->{{/if}}<!-- --><% } %><!--
-->{{/each}}<!-- --><% }) %><!--
--></ul> --></ul>
</nav> </nav>

View File

@ -1,14 +1,14 @@
<div class='content-wrapper' id='user'> <div class='content-wrapper' id='user'>
<h1>{{this.user.name}}</h1> <h1><%= user.name %></h1>
<nav class='text-nav'><!-- <nav class='text-nav'><!--
--><ul><!-- --><ul><!--
--><li data-name='summary'><a href='/user/{{this.user.name}}'>Summary</a></li><!-- --><li data-name='summary'><a href='/user/<%= user.name %>'>Summary</a></li><!--
-->{{#if this.canEditAnything}}<!-- --><% if (canEditAnything) { %><!--
--><li data-name='edit'><a href='/user/{{this.user.name}}/edit'>Account settings</a></li><!-- --><li data-name='edit'><a href='/user/<%= user.name %>/edit'>Account settings</a></li><!--
-->{{/if}}<!-- --><% } %><!--
-->{{#if this.canDelete}}<!-- --><% if (canDelete) { %><!--
--><li data-name='delete'><a href='/user/{{this.user.name}}/delete'>Account deletion</a></li><!-- --><li data-name='delete'><a href='/user/<%= user.name %>/delete'>Account deletion</a></li><!--
-->{{/if}}<!-- --><% } %><!--
--></ul><!-- --></ul><!--
--></nav> --></nav>
<div id='user-content-holder'></div> <div id='user-content-holder'></div>

View File

@ -3,7 +3,7 @@
<div class='input'> <div class='input'>
<ul> <ul>
<li> <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> </li>
</ul> </ul>
</div> </div>

View File

@ -3,29 +3,29 @@
<div class='left'> <div class='left'>
<div class='input'> <div class='input'>
<ul> <ul>
{{#if this.canEditName}} <% if (canEditName) { %>
<li> <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> </li>
{{/if}} <% } %>
{{#if this.canEditPassword}} <% if (canEditPassword) { %>
<li> <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> </li>
{{/if}} <% } %>
{{#if this.canEditEmail}} <% if (canEditEmail) { %>
<li> <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> </li>
{{/if}} <% } %>
{{#if this.canEditRank}} <% if (canEditRank) { %>
<li> <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> </li>
{{/if}} <% } %>
</ul> </ul>
</div> </div>
<div class='messages'></div> <div class='messages'></div>
@ -34,18 +34,18 @@
</div> </div>
</div> </div>
{{#if this.canEditAvatar}} <% if (canEditAvatar) { %>
<div class='right'> <div class='right'>
<ul> <ul>
<li> <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>
<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> <div id='avatar-content'></div>
</li> </li>
</ul> </ul>
</div> </div>
{{/if}} <% } %>
</form> </form>
</div> </div>

View File

@ -3,7 +3,7 @@
<div class='input'> <div class='input'>
<ul> <ul>
<li> <li>
{{textInput id='search-text' name='search-text' value=this.searchQuery.text}} <%= makeTextInput({id: 'search-text', name: 'search-text', value: searchQuery.text}) %>
</li> </li>
</ul> </ul>
</div> </div>

View File

@ -1,17 +1,17 @@
<div class='user-list'> <div class='user-list'>
<ul><!-- <ul><!--
-->{{#each this.results}}<!-- --><% _.each(results, user => { %><!--
--><li> --><li>
<div class='wrapper'> <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'> <div class='details'>
<a href='/user/{{this.name}}'>{{this.name}}</a><br/> <a href='/user/<%= user.name %>'><%= user.name %></a><br/>
Registered: {{reltime this.creationTime}}<br/> Registered: <%= makeRelativeTime(user.creationTime) %><br/>
Last seen: {{reltime this.lastLoginTime}} Last seen: <%= makeRelativeTime(user.lastLoginTime) %>
</div> </div>
</div> </div>
</li><!-- </li><!--
-->{{/each}}<!-- --><% }) %><!--
-->{{alignFlexbox}}<!-- --><%= makeFlexboxAlign() %><!--
--></ul> --></ul>
</div> </div>

View File

@ -4,13 +4,13 @@
<div class='input'> <div class='input'>
<ul> <ul>
<li> <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>
<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>
<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> <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> </li>
</ul> </ul>

View File

@ -1,22 +1,22 @@
<div id='user-summary'> <div id='user-summary'>
{{thumbnail this.user.avatarUrl}} <%= makeThumbnail(user.avatarUrl) %>
<ul class='basic-info'> <ul class='basic-info'>
<li>Registered: {{reltime this.user.creationTime}}</li> <li>Registered: <%= makeRelativeTime(user.creationTime) %></li>
<li>Last seen: {{reltime this.user.lastLoginTime}}</li> <li>Last seen: <%= makeRelativeTime(user.lastLoginTime) %></li>
<li>Rank: {{toLowerCase this.user.rankName}}</li> <li>Rank: <%= user.rankName.toLowerCase() %></li>
</ul> </ul>
<div> <div>
<nav class='plain-nav'> <nav class='plain-nav'>
<p><strong>Quick links</strong></p> <p><strong>Quick links</strong></p>
<ul> <ul>
<li><a href='/posts/submit:{{this.user.name}}'>Uploads</a></li> <li><a href='/posts/submit:<%= user.name %>'>Uploads</a></li>
<li><a href='/posts/fav:{{this.user.name}}'>Favorites</a></li> <li><a href='/posts/fav:<%= user.name %>'>Favorites</a></li>
<li><a href='/posts/commented:{{this.user.name}}'>Posts commented on</a></li> <li><a href='/posts/comment:<%= user.name %>'>Posts commented on</a></li>
</ul> </ul>
</nav> </nav>
{{#if this.isLoggedIn}} <% if (isLoggedIn) { %>
<nav class='plain-nav'> <nav class='plain-nav'>
<p><strong>Only visible to you</strong></p> <p><strong>Only visible to you</strong></p>
<ul> <ul>
@ -24,6 +24,6 @@
<li><a href='/posts/special:disliked'>Disliked posts</a></li> <li><a href='/posts/special:disliked'>Disliked posts</a></li>
</ul> </ul>
</nav> </nav>
{{/if}} <% } %>
</div> </div>
</div> </div>

View File

@ -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(''));
});

View File

@ -1,9 +1,114 @@
'use strict'; 'use strict';
require('../util/polyfill.js'); require('../util/polyfill.js');
const handlebars = require('handlebars'); const underscore = require('underscore');
const events = require('../events.js'); const events = require('../events.js');
const domParser = new DOMParser(); 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) { function _messageHandler(target, message, className) {
if (!message) { if (!message) {
@ -81,9 +186,24 @@ function getTemplate(templatePath) {
return null; return null;
} }
const templateText = templates[templatePath].trim(); const templateText = templates[templatePath].trim();
const templateFactory = handlebars.compile(templateText); const templateFactory = underscore.template(templateText);
return (...args) => { return ctx => {
return htmlToDom(templateFactory(...args)); 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));
}; };
} }

View File

@ -10,6 +10,7 @@ class FileDropperControl {
render(ctx) { render(ctx) {
const target = ctx.target; const target = ctx.target;
const source = this.template({ const source = this.template({
allowMultiple: ctx.allowMultiple,
id: 'file-' + Math.random().toString(36).substring(7), id: 'file-' + Math.random().toString(36).substring(7),
}); });

View File

@ -10,7 +10,11 @@ class LoginView {
render(ctx) { render(ctx) {
const target = document.getElementById('content-holder'); 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 form = source.querySelector('form');
const userNameField = source.querySelector('#user-name'); const userNameField = source.querySelector('#user-name');

View File

@ -1,6 +1,5 @@
'use strict'; 'use strict';
require('../util/handlebars-helpers.js');
const views = require('../util/views.js'); const views = require('../util/views.js');
class TopNavView { class TopNavView {

View File

@ -14,7 +14,6 @@
"camelcase-keys": "*", "camelcase-keys": "*",
"csso": "^1.8.0", "csso": "^1.8.0",
"glob": "^7.0.3", "glob": "^7.0.3",
"handlebars": "^4.0.5",
"html-minifier": "^1.3.1", "html-minifier": "^1.3.1",
"js-cookie": "^2.1.0", "js-cookie": "^2.1.0",
"js-yaml": "^3.5.5", "js-yaml": "^3.5.5",
@ -24,7 +23,8 @@
"page": "^1.7.1", "page": "^1.7.1",
"stylus": "^0.54.2", "stylus": "^0.54.2",
"superagent": "^1.8.3", "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": { "devDependencies": {
"watch": "latest" "watch": "latest"