// console.log("Loading Location...") Spontaneous.Location = (function($, S) { var ajax = S.Ajax; var State = new JS.Class({ initialize: function(path) { this.page_id = false; this.mode = null; if (path) { path = path.substr(ajax.namespace.length+1); this.parse_path(path); } }, parse_path: function(path) { var areas = path.split('/'), id = areas[0], mode = areas[1]; this.page_id = id; this.mode = mode; }, restore: function() { if (this.mode) { Spontaneous.Location.view_mode_changed(this.mode); Spontaneous.TopBar.set_mode(this.mode); } if (this.page_id) { Spontaneous.Location.load_id(this.page_id); } else { Spontaneous.Location.load_path('/'); } }, to_hash: function() { return '#/'+(this.page_id || '') + (this.mode ? ('@' + this.mode) : ''); }, to_path: function() { return [ajax.namespace, (this.page_id || ''), this.mode].join('/'); }, to_obj: function() { return { page_id: this.page_id, mode: this.mode }; } }); State.extend({ // currently just produces some kind of loop popstate: function(event) { State.restore(event); return false; }, restore: function(event) { var state = new State(window.location.pathname); state.restore(); }, page: function(location, mode) { var s = new State(); s.page_id = location.id; s.mode = mode; window.history.replaceState(s.to_obj(), ''+s.page_id, s.to_path()); } }); var Location = new JS.Singleton({ include: Spontaneous.Properties, init: function(callback) { this.locationCache = {}; callback(); State.restore(); // $(window).bind('hashchange', State.restore); }, page_loaded: function(page) { // page.watch('slot', this, 'slot_changed'); }, slot_changed: function(slot) { // console.log('Location.slot_changed', slot, slot.uid(), slot.container.id()); }, view_mode_changed: function(mode) { this.set('view_mode', mode); if (this.get('location')) { this.update_state(this.get('location'), mode); } }, load_map: function() { }, location_loaded: function(location, status, xhr) { S.Popover.close(); if (xhr.status === 406) { // Code returned if site is missing a root page var d = new Spontaneous.AddHomeDialogue(Spontaneous.Types.get('types')); d.open(); } else { this.set('location', location); // HACK: see preview.js (Preview.display) this.set('path', location.path); this.update_state(location, this.get('view_mode')); } this.set('loading_location', null); }, update_state: function(location, mode) { State.page(location, mode); }, load_id: function(id) { var l = this.location(); if (!l || id != l.id) { this.find_id(id); } }, load_path: function(path) { this.find_path(path); }, path_changed: function(path) { this.set('path', path); }, url: function() { var l = this.location(); return (l ? l.url : '/about'); }, location: function() { return this.get('location'); }, update: function(location) { this.set('location', location); this.path_from_url(location.url); }, current_path: function() { return this.path_from_url(this.url()); }, find_path: function(path) { if (this.location() && path === this.location().path) { return this.location(); } this.retrieve_with_progress('/map/path'+path, this.location_loaded.bind(this)); }, find_id: function(id) { if (this.location() && id === this.location().id) { return this.location(); } this.retrieve_with_progress('/map/'+id, this.location_loaded.bind(this)); }, path_from_url: function(url) { var map = this.get('map'), children = map.children, path = [], i, ii, parts = url.split('/').slice(1), position = 0; // add root to path path.push({selected:0, pages:[map], root:true}); while (position < parts.length) { for (i = 0, ii = children.length; i < ii; i++) { var child = children[i], slug = child.url.split('/').slice(-1)[0]; if (slug === parts[position]) { path.push({selected:i, pages: children}); children = child.children; break; } } position += 1; } return path; }, retrieve_with_progress: function(url, callback) { this.set('loading_location', url); return this.retrieve(url, callback); }, retrieve: function(url, callback) { ajax.get(url, {}, callback, {ifModified: true, cache: true}); }, lastModified: function(path) { return (this.locationCache[path] || {}).lastModified; }, setLocationCache: function(path, lastModified, location) { this.locationCache[path] = { lastModified: lastModified, location: location }; }, getLocationCache: function(path) { return this.locationCache[path].location; } }); // $(window).bind('popstate', State.popstate); return Location; })(jQuery, Spontaneous);