page('/proposal/:id', citizen.optional, load, function(ctx) { bus.emit('page:change'); // Render sidebar list sidebar.render('aside.nav-proposal'); sidebar.ready(function() { sidebar.select(ctx.law.id); }); // Get content's container var contentContainer = document.querySelector('section.app-content'); // Build page's content var article = new Article(ctx.proposal); // !!MUST be aware of citizen's data too var options = new Options(ctx.proposal, ctx.citizen); var comments = new Comments('proposal', ctx.proposal.id); comments.initialize(); // Empty container before render empty(contentContainer); // Render page's content contentContainer.appendChild(article.render()); contentContainer.appendChild(options.render()); contentContainer.appendChild(comments.render()); });
View.prototype.build = function() { var list = this.el.querySelector('ul.nav.navlist'); empty(list); this.items.sort(function(a,b) { if (a.closingAt != b.closingAt) { if (a.closingAt==undefined) { return 1; } else if (b.closingAt==undefined) { return -1; } else if (+a.closingAt<+b.closingAt) { return -1; } else { return 1; } } else { if (a.participants.length>b.participants.length) { return -1; } else { return 1; } } }); this.items.forEach(function(item) { this.append(item) }, this); return this; }
page("/settings/:page?", valid, citizen.required, function(ctx, next) { var page = ctx.params.page || "profile"; var container = render.dom(settings); var content = o('.settings-content', container); var profile = new Profile; var password = new Password; // prepare wrapper and container empty(o('#content')).appendChild(container); // set active section on sidebar if (o('.active', container)) { classes(o('.active', container)).remove("active"); }; classes(o('[href="/settings/' + page + '"]:parent', container)).add("active"); // Set page's title title(o('[href="/settings/' + page + '"]').textContent); // render all settings pages profile.render(content); password.render(content); // Display current settings page classes(o("#" + page + "-wrapper", container)).remove("hide"); });
View.prototype.refreshFilters = function() { var container = this.el.querySelector('ul.dropdown-menu'); var map = []; this.filters = this.items.map(function(item) { var tag = item.tag; if (!~map.indexOf(tag.hash)) { map.push(tag.hash); return tag; }; return null; }).filter(function(tag) { return tag; }); this.filters.unshift({ id: 'all', hash: 'all', name: t('Listing all {listType}s', { listType: this.type }) }); empty(container); this.filters.forEach(function(f) { container.appendChild(domify(filterItem({ filter: f }))); }); return this; }
page('/forgot', citizen.optional, function(ctx, next) { // If citizen is logged in // redirect to `/` if (ctx.citizen.id) return page('/'); // Build form view with options var form = ForgotView({}); // Update page's title title(t('Forgot Password?')); // Empty container and render form empty(o('#content')).appendChild(form.render()); form.on('submit', function(data) { request .post('/forgot') .send(data) .end(function(err, res) { if (!res.ok) { return form.errors([JSON.parse(res.text).error]); }; if (err || (res.body && res.body.error)) { return form.errors([err || res.body.error]); }; form.showSuccess(); }); }); });
page('/raid', user.required, function(ctx, next) { var container = document.querySelector('section.site-content'); empty(container) .appendChild(domify(template({ user: user }))); });
BackgroundVideo.prototype.append = function(el){ if (this.video){ empty(this.el); this.parent.appendChild(this.overlay); this.el.insertBefore(this.parent, this.el.firstChild); } return this; };
it('should empty an element', function(){ var el = create('div'); var ul = create('ul'); el.appendChild(create('div')); ul.appendChild(create('li')); el.appendChild(ul); assert(el.innerHTML); assert('' == empty(el).innerHTML); })
.end(function(err, res) { // Empty container and render form empty(o('#content')).appendChild(form.render()); if (!res.ok) { return form.errors([res.error]); }; if (err || (res.body && res.body.error)) { return form.errors([err || res.body.error]); }; });
YouTubeCute.prototype.playVideo = function(){ this.events.unbind(); empty(this.el); this.el.classList.add('playing'); this.vid = new Youtube(this.src, this.el, { width: this.target.clientWidth, height: this.target.clientHeight }); this.vid.play(); return this; };
View.prototype.errors = function(errors) { var ul = this.form.querySelector('ul.form-errors'); if (!arguments.length) return empty(ul); errors.forEach(function(e) { var li = document.createElement('li'); li.innerText = e; ul.appendChild(li); }); }
ProfileView.prototype.messages = function(msgs, type) { var ul = o('ul.form-messages', this.el); if (!arguments.length) return empty(ul); msgs.forEach(function(m) { var li = document.createElement('li'); li.innerHTML = m; classes(li).add(type || 'error'); ul.appendChild(li); }); }
Days.prototype.show = function(date){ var year = date.getFullYear(); var month = date.getMonth(); this.showSelectedYear(year); this.showSelectedMonth(month); var subhead = this.head.querySelector('.subheading'); if (subhead) { subhead.parentElement.removeChild(subhead); } this.head.appendChild(this.renderHeading(this.locale.weekdaysMin)); empty(this.body); this.body.appendChild(this.renderDays(date)); };
ProposalArticle.prototype.showclauses = function(ev) { ev.preventDefault(); var container = this.el.querySelector('.clauses'); empty(container); this.clauses.forEach(function(c) { container.appendChild(domify(clause({ clause: c }))); }); this.events.unbind('click .clauses a.read-more'); }
page('/proposal/:id', citizen.optional, load, getComments, function(ctx) { log('/proposal/%s match', ctx.params.id); // Get content's container var contentContainer = document.querySelector('section.app-content'); // Build page's content var list = new List(ctx.proposals, ctx.proposal); var article = new Article(ctx.proposal); // !!MUST be aware of citizen's data too var options = new Options(ctx.proposal, ctx.citizen); var comments = new Comments(ctx.proposal, ctx.comments); // Render sidebar list empty(document.querySelector('aside.nav-proposal')) .appendChild(list.render()); // Empty container before render empty(contentContainer); // Render page's content contentContainer.appendChild(article.render()); contentContainer.appendChild(options.render()); contentContainer.appendChild(comments.render()); });
FormView.prototype.errors = function(errors) { var ul = this.el.querySelector('ul.form-errors'); if (!arguments.length) return empty(ul); errors.forEach(function(e) { var li = document.createElement('li'); li.innerHTML = e; ul.appendChild(li); }); var success = this.el.querySelector('#email-validation-message'); classes(ul).remove('hide'); classes(success).add('hide'); }
ListView.prototype.refresh = function () { var old = this.el; this.switchOff(); this.build(); this.switchOn(); // Build list contents empty(this.el); filter.items().forEach(function (item) { this.append(item) }, this); if (old.parentNode) old.parentNode.replaceChild(this.el, old); old.remove(); }
CommentsRepliesView.prototype.errors = function(errors) { this.state('error'); var span = o('span.form-errors', this.el); errors = errors || []; empty(span); errors.forEach(function(err) { span.innerHTML += t(err); }); // Unregister all `ready` listeners this.off('ready'); return this; }
function onsidebarready() { if (!validUrl()) return; classes(document.body).add('browser-page'); var law = sidebar.items(0); if (!law) { var el = render.dom(noLaws); empty(o('#browser .app-content')).appendChild(el); return bus.emit('page:render'); } log('render law %s', law.id); ctx.path = '/law/' + law.id; next(); }
page("/admin/:section(*)?", valid, citizen.required, citizen.isStaff, function(ctx, next) { var section = ctx.params.section; var container = render.dom(template); var content = o('.admin-content', container); // prepare wrapper and container empty(o('#content .content-container')).appendChild(container); // set active section on sidebar sidebar.set(section); sidebar.render(o('.sidebar-container', container)); // Set page's title title(); // if all good, then jump to section route handler next(); });
page('/forgotpassword/step2', function(ctx, next) { // Retrieve container var container = document.querySelector('section.site-content'); // Build form view with options var form = FormStep2({}); // Empty container and render form empty(container).appendChild(form.render()); var token = ctx.querystring.substring(6); var verifyTokenRequest = request .post('/forgotpassword/verifytoken') .send({token : token}) .end(function(err, res) { if (!res.ok) { return form.errors([res.error]); }; if (err || (res.body && res.body.error)) { return form.errors([err || res.body.error]); }; }); form.on('submit', function(data) { data.token = token; // TODO cancel verify request if not finished request .post('/forgotpassword/step2') .send(data) .end(function(err, res) { if (!res.ok) { return form.errors([res.error]); }; if (err || (res.body && res.body.error)) { return form.errors([err || res.body.error]); }; window.location.replace('/'); }); }); });
page("/help/:page?", valid, parse, function(ctx, next) { if (!ctx.valid) return next(); var page = ctx.params.page || "markdown"; var container = render.dom(helpContainer); var content = o('.help-content', container); // prepare wrapper and container empty(o('#content')).appendChild(container); var faq = new FAQ; var tos = new TOS; var pp = new PP; var glossary = new Glossary(ctx.query.word); var markdown = new Markdown; // set active section on sidebar if (o('.active', container)) { classes(o('.active', container)).remove('active'); }; classes(o('[href="/help/' + page + '"]:parent', container)).add('active'); // Set page's title title(o('[href="/help/' + page + '"]').textContent); // render all help pages if(config['faq']) faq.appendTo(content); if(config['tos']) tos.appendTo(content); if(config['pp']) pp.appendTo(content); if(config['glossary']) glossary.appendTo(content); markdown.appendTo(content); // Display current help page classes(o("#" + page + "-wrapper", container)).remove("hide"); if (page == 'glossary') glossary.scroll(); });
CommentsView.prototype.onreplyclick = function(ev) { ev.preventDefault(); var target = ev.delegateTarget || closest(ev.target, 'a'); var commentEl = closest(target,'li[data-id]'); var id = commentEl.getAttribute('data-id'); var comment = get(this.comments, 'id === "%id"'.replace('%id', id)); if (!comment) { comment = get(this.myArguments, 'id === "%id"'.replace('%id', id)); } var repliesContainer = o('.replies-container', commentEl); if (repliesContainer.firstChild) { empty(repliesContainer); classes(target).remove('no-hide') } else { var commentsRepliesView = new CommentsRepliesView(comment); classes(target).add('no-hide') commentsRepliesView.render(repliesContainer); commentsRepliesView.on('post', this.newreply.bind(this)) commentsRepliesView.on('remove', this.removereply.bind(this)) } }
View.prototype.onfilterselect = function(ev) { ev.preventDefault(); var list = this.el.querySelector('ul.nav.navlist'); empty(list); var target = ev.delegateTarget || closest(ev.target, '[data-id]'); var id = target.getAttribute('data-id'); log('filter select click %s', id); var items = 'all' === id ? this.items : this.items.filter(function(i) { return i.tag.id === id; }); items.forEach(function(item) { this.append(item); }, this); // Update current filter box text var tag = get(this.filters, 'id === "%id"'.replace('%id', id)); this.el.querySelector('.dropdown-department .current-department').innerHTML = tag.name; }
page('/forgotpassword/step1', function(ctx, next) { // Retrieve container var container = document.querySelector('section.site-content'); // Build form view with options var form = FormStep1({}); // Empty container and render form empty(container).appendChild(form.render()); form.on('submit', function(data) { request .post('/forgotpassword/step1') .send(data) .end(function(err, res) { if (!res.ok) { return form.errors([res.error]); }; if (err || (res.body && res.body.error)) { return form.errors([err || res.body.error]); }; window.location.replace('/'); }); }); });
showElement: function (el) { empty(this.container); this.container.appendChild(el); },
page('/law/:id', citizen.optional, load, function(ctx, next) { bus.emit('page:render'); // Render sidebar list sidebar.ready(function() { select() && filter.on('reload', select); function select() { log('select sidebar law %s', ctx.law.id); return setTimeout(sidebar.select.bind(sidebar, ctx.law.id), 0); } }); // Clean page's content empty(o('section.app-content')) // Build article's content container // and render to section.app-content var article = new Article(ctx.law); article.render('section.app-content'); // Build article's meta // and render to section.app-content var options = new Options(ctx.law, ctx.citizen); options.render('section.app-content'); // Build article's comments, feth them // and render to section.app-content var comments = new Comments('law', ctx.law.id); comments.render('section.app-content'); comments.fetch(); classes(document.body).add('browser-page'); title(ctx.law.mediaTitle); log('render %s', ctx.params.id); bus.once('page:change', pagechange); function pagechange(url) { // restore page's original title title(); // lock article's section locker.lock(); // hide it from user classes(o('section.app-content')).add('hide'); // once render, unlock and show bus.once('page:render', function() { locker.unlock(); classes(o('section.app-content')).remove('hide'); }); // check if loading to same page // and if not, scroll to top if (url !== ctx.path) o('section#browser').scrollTop = 0; // don't remove 'browser-page' body class // if we still are in a browsing laws page if (/^\/$/.test(url)) return; if (/^\/(law|proposal)/.test(url)) return; classes(document.body).remove('browser-page'); }; });
page('/', function(ctx, next) { var container = document.querySelector('section.site-content'); empty(container) .appendChild(domify(template())); });
page('/law/:id', citizen.optional, load, loadSidebar, function(ctx, next) { function validUrl() { var pathname = window.location.pathname; return pathname == '/' || /^\/(law|proposal)/.test(pathname); } if (!validUrl()) return classes(document.body).remove('browser-page'); bus.emit('page:render'); if (!ctx.law) { log('Law %s not found', ctx.params.id); return next(); } ctx.sidebar.replace('aside.nav-proposal'); // Clean page's content empty(o('section.app-content')) // Build article's content container // and render to section.app-content var article = new Article(ctx.law, nextLaw); article.render('section.app-content'); // Build article's meta // and render to section.app-content var options = new Options(ctx.law, ctx.citizen); options.render('section.app-content'); var nextLaw = new NextLaw(ctx); nextLaw.appendTo('section.app-content'); // Build article's comments, feth them // and render to section.app-content if (ctx.law.votable) { var comments = new Comments('law', ctx.law.id); comments.render('section.app-content'); comments.initialize(); } classes(document.body).add('browser-page'); title(ctx.law.mediaTitle); log('render %s', ctx.params.id); bus.once('page:change', pagechange); function pagechange(url) { // restore page's original title title(); // lock article's section locker.lock(); // hide it from user classes(o('section.app-content')).add('hide'); // once render, unlock and show bus.once('page:render', function() { locker.unlock(); classes(o('section.app-content')).remove('hide'); }); // check if loading to same page // and if not, scroll to top if (url !== ctx.path) o('section#browser').scrollTop = 0; // don't remove 'browser-page' body class // if we still are in a browsing laws page if (/^\/law/.test(url)) return; classes(document.body).remove('browser-page'); }; });