Mercurial > wikked
view static/js/wikked/views.js @ 63:97efd73f2158
Changed RequireJS paths to make it usable with the optimizer.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Wed, 06 Feb 2013 23:48:34 -0800 |
parents | a73a3c0b6d4a |
children | 0adac3bc079e |
line wrap: on
line source
/** * Wikked views. */ define([ 'jquery', 'underscore', 'backbone', 'handlebars', 'js/wikked/client', 'js/wikked/models', 'js/wikked/util', 'text!tpl/read-page.html', 'text!tpl/edit-page.html', 'text!tpl/history-page.html', 'text!tpl/revision-page.html', 'text!tpl/diff-page.html', 'text!tpl/inlinks-page.html', 'text!tpl/nav.html', 'text!tpl/footer.html', 'text!tpl/search-results.html', 'text!tpl/login.html', 'text!tpl/error-unauthorized.html', 'text!tpl/error-not-found.html', 'text!tpl/error-unauthorized-edit.html', 'text!tpl/state-warning.html', 'text!tpl/special-nav.html', 'text!tpl/special-pages.html', 'text!tpl/special-changes.html', 'text!tpl/special-orphans.html' ], function($, _, Backbone, Handlebars, Client, Models, Util, tplReadPage, tplEditPage, tplHistoryPage, tplRevisionPage, tplDiffPage, tplInLinksPage, tplNav, tplFooter, tplSearchResults, tplLogin, tplErrorNotAuthorized, tplErrorNotFound, tplErrorUnauthorizedEdit, tplStateWarning, tplSpecialNav, tplSpecialPages, tplSpecialChanges, tplSpecialOrphans) { var exports = {}; var PageView = exports.PageView = Backbone.View.extend({ tagName: 'div', className: 'wrapper', initialize: function() { PageView.__super__.initialize.apply(this, arguments); if (this.model !== undefined) { var $view = this; this.model.on("change", function() { $view._onModelChange(); }); } if (this.templateSource !== undefined) { this.template = Handlebars.compile(_.result(this, 'templateSource')); } return this; }, render: function(view) { if (this.template !== undefined) { this.renderTemplate(this.template); if (this.renderCallback !== undefined) { this.renderCallback(); } } this.renderTitle(this.titleFormat); return this; }, renderTemplate: function(tpl) { this.$el.html(tpl(this.model.toJSON())); }, renderTitle: function(formatter) { var title = this.model.title(); if (formatter !== undefined) { title = formatter.call(this, title); } document.title = title; }, _onModelChange: function() { this.render(); } }); _.extend(PageView, Backbone.Events); var NavigationView = exports.NavigationView = PageView.extend({ templateSource: tplNav, initialize: function() { NavigationView.__super__.initialize.apply(this, arguments); return this; }, render: function() { this.renderTemplate(this.template); this.origPageEl = $('#app .page'); return this; }, events: { "submit #search": "_submitSearch", "input #search>.search-query": "_previewSearch", "keyup #search>.search-query": "_searchQueryChanged" }, _submitSearch: function(e) { e.preventDefault(); this.model.doSearch(e.currentTarget); return false; }, _previewSearch: function(e) { // Restore the original content if the query is now // empty. Otherwise, run a search and render only the // `.page` portion of the results page. var origPageEl = this.origPageEl; var curPreviewEl = $('#app .page[class~="preview-search-results"]'); var query = $(e.currentTarget).val(); if (query && query.length > 0) { var template = Handlebars.compile(tplSearchResults); this.model.doPreviewSearch(query, function(data) { data.is_instant = true; var resultList = $(template(data)); var inner = $('.page', resultList) .addClass('preview-search-results') .detach(); if (origPageEl.is(':visible')) { inner.insertAfter(origPageEl); origPageEl.hide(); } else { curPreviewEl.replaceWith(inner); } }); } else { curPreviewEl.remove(); origPageEl.show(); } }, _searchQueryChanged: function(e) { if (e.keyCode == 27) { // Clear search on `Esc`. $(e.currentTarget).val('').trigger('input'); } } }); var FooterView = exports.FooterView = PageView.extend({ templateSource: tplFooter, initialize: function() { FooterView.__super__.initialize.apply(this, arguments); return this; }, render: function() { this.renderTemplate(this.template); return this; } }); var LoginView = exports.LoginView = PageView.extend({ templateSource: tplLogin, initialize: function() { LoginView.__super__.initialize.apply(this, arguments); return this; }, render: function() { this.renderTemplate(this.template); document.title = 'Login'; return this; }, events: { "submit #login": "_submitLogin" }, _submitLogin: function(e) { e.preventDefault(); this.model.doLogin(e.currentTarget); return false; } }); var MasterPageView = exports.MasterPageView = PageView.extend({ initialize: function() { MasterPageView.__super__.initialize.apply(this, arguments); this.nav = this._createNavigation(this.model.nav); this.footer = this._createFooter(this.model.footer); return this; }, renderCallback: function() { this.$el.prepend('<div id="nav"></div>'); this.$el.append('<div id="footer"></div>'); this.nav.setElement(this.$('#nav')).render(); this.footer.setElement(this.$('#footer')).render(); }, templateSource: function() { switch (this.model.get('error_code')) { case 401: return tplErrorNotAuthorized; case 404: return tplErrorNotFound; default: return _.result(this, 'defaultTemplateSource'); } }, _createNavigation: function(model) { return new NavigationView({ model: model }); }, _createFooter: function(model) { return new FooterView({ model: model }); } }); var PageReadView = exports.PageReadView = MasterPageView.extend({ defaultTemplateSource: tplReadPage, initialize: function() { PageReadView.__super__.initialize.apply(this, arguments); this.warningTemplate = Handlebars.compile(tplStateWarning); return this; }, renderCallback: function() { PageReadView.__super__.renderCallback.apply(this, arguments); // Replace all wiki links with proper hyperlinks using the JS app's // URL scheme. this.$('a.wiki-link[data-wiki-url]').each(function(i) { var jel = $(this); if (jel.hasClass('missing')) jel.attr('href', '/#/edit/' + jel.attr('data-wiki-url')); else jel.attr('href', '/#/read/' + jel.attr('data-wiki-url')); }); }, events: { "click .wiki-link": "_navigateLink" }, _navigateLink: function(e) { var url = $(e.currentTarget).attr('data-wiki-url'); this.model.app.navigate('/read/' + url); this.model.set('path', url); this.model.fetch(); e.preventDefault(); return false; }, _checkPageState: function() { var stateTpl = this.warningTemplate; var stateModel = new Models.PageStateModel({ path: this.model.get('path') }); stateModel.fetch({ success: function(model, response, options) { if (model.get('state') == 'new' || model.get('state') == 'modified') { var warning = $(stateTpl(model.toJSON())); warning.css('display', 'none'); warning.prependTo($('#app .page')); warning.slideDown(); $('.dismiss', warning).click(function() { warning.slideUp(); return false; }); } } }); }, _firstRender: true, _onModelChange: function() { PageReadView.__super__._onModelChange.apply(this, arguments); // Fetch the state if the current page changed. if (this.model.hasChanged('path') || this._firstRender) { this._checkPageState(); this._firstRender = false; } } }); var PageEditView = exports.PageEditView = MasterPageView.extend({ templateSource: function() { if (this.model.get('error_code') == 401) { return tplErrorUnauthorizedEdit; } return tplEditPage; }, renderCallback: function() { PageEditView.__super__.renderCallback.apply(this, arguments); // Create the Markdown editor. var formatter = new Client.PageFormatter(); formatter.baseUrl = this.model.get('path').match(/.*\//); var converter = new Markdown.Converter(); converter.hooks.chain("preConversion", function(text) { return formatter.formatText(text); }); var editor = new Markdown.Editor(converter); //TODO: pass options editor.run(); var editor_control = this.$('textarea#wmd-input'); editor_control.outerWidth(this.$('.wmd-input-wrapper').innerWidth()); }, events: { "mousedown .wmd-input-grip": "_inputGripMouseDown", "click .wmd-preview-wrapper>h3>a": "_togglePreview", "submit #page-edit": "_submitEditedPage" }, _inputGripMouseDown: function(e) { // Input area resizing with the grip. var last_pageY; last_pageY = e.pageY; $('body') .on('mousemove.wikked.editor_resize', function(e) { var editor_control = $('textarea#wmd-input'); editor_control.height(editor_control.height() + e.pageY - last_pageY); last_pageY = e.pageY; }) .on('mouseup.wikked.editor_resize mouseleave.wikked.editor_resize', function(e) { $('body').off('.wikked.editor_resize'); }); }, _togglePreview: function(e) { // Show/hide live preview. this.$('#wmd-preview').fadeToggle(function() { var icon = this.$('.wmd-preview-wrapper>h3>a i'); if (icon.hasClass('icon-minus')) { icon.removeClass('icon-minus'); icon.addClass('icon-plus'); } else { icon.removeClass('icon-plus'); icon.addClass('icon-minus'); } }); }, _submitEditedPage: function(e) { // Make the model submit the form. e.preventDefault(); this.model.doEdit(e.currentTarget); return false; }, titleFormat: function(title) { return 'Editing: ' + title; } }); var PageHistoryView = exports.PageHistoryView = MasterPageView.extend({ defaultTemplateSource: tplHistoryPage, events: { "submit #diff-page": "_submitDiffPage" }, _submitDiffPage: function(e) { e.preventDefault(); this.model.doDiff(this); return false; }, titleFormat: function(title) { return 'History: ' + title; } }); var PageRevisionView = exports.PageRevisionView = MasterPageView.extend({ defaultTemplateSource: tplRevisionPage, titleFormat: function(title) { return title + ' [' + this.model.get('rev') + ']'; } }); var PageDiffView = exports.PageDiffView = MasterPageView.extend({ defaultTemplateSource: tplDiffPage, titleFormat: function(title) { return title + ' [' + this.model.get('rev1') + '-' + this.model.get('rev2') + ']'; } }); var IncomingLinksView = exports.IncomingLinksView = MasterPageView.extend({ defaultTemplateSource: tplInLinksPage, titleFormat: function(title) { return 'Incoming Links: ' + title; } }); var WikiSearchView = exports.WikiSearchView = MasterPageView.extend({ defaultTemplateSource: tplSearchResults }); var SpecialNavigationView = exports.SpecialNavigationView = NavigationView.extend({ templateSource: tplSpecialNav }); var SpecialMasterPageView = exports.SpecialMasterPageView = MasterPageView.extend({ _createNavigation: function(model) { model.set('show_root_link', true); return new SpecialNavigationView({ model: model }); } }); var SpecialPagesView = exports.SpecialPagesView = SpecialMasterPageView.extend({ defaultTemplateSource: tplSpecialPages }); var SpecialChangesView = exports.SpecialChangesView = SpecialMasterPageView.extend({ defaultTemplateSource: tplSpecialChanges, _onModelChange: function() { var history = this.model.get('history'); if (history) { for (var i = 0; i < history.length; ++i) { var rev = history[i]; rev.changes = []; for (var j = 0; j < rev.pages.length; ++j) { var page = rev.pages[j]; switch (page.action) { case 'edit': rev.changes.push({ is_edit: true, url: page.url }); break; case 'add': rev.changes.push({ is_add: true, url: page.url }); break; case 'delete': rev.changes.push({ is_delete: true, url: page.url }); break; } rev.pages[j] = page; } history[i] = rev; } this.model.set('history', history); } SpecialChangesView.__super__._onModelChange.apply(this, arguments); } }); var SpecialOrphansView = exports.SpecialOrphansView = SpecialMasterPageView.extend({ defaultTemplateSource: tplSpecialOrphans }); return exports; });