Clean up discourse.js
This commit is contained in:
parent
b9ccf4d09c
commit
1caf1e6b45
|
@ -4,7 +4,7 @@
|
|||
@method buildRoutes
|
||||
@for Discourse.AdminRoute
|
||||
**/
|
||||
Discourse.buildRoutes(function() {
|
||||
Discourse.Route.buildRoutes(function() {
|
||||
this.resource('admin', { path: '/admin' }, function() {
|
||||
this.route('dashboard', { path: '/' });
|
||||
this.route('site_settings', { path: '/site_settings' });
|
||||
|
|
|
@ -1,31 +1,28 @@
|
|||
/*global Modernizr:true*/
|
||||
/*global assetPath:true*/
|
||||
|
||||
var csrf_token;
|
||||
/**
|
||||
The main Discourse Application
|
||||
|
||||
@class Discourse
|
||||
@extends Ember.Application
|
||||
**/
|
||||
Discourse = Ember.Application.createWithMixins({
|
||||
rootElement: '#main',
|
||||
|
||||
// Data we want to remember for a short period
|
||||
transient: Em.Object.create(),
|
||||
|
||||
// Whether the app has focus or not
|
||||
hasFocus: true,
|
||||
|
||||
// Are we currently scrolling?
|
||||
scrolling: false,
|
||||
|
||||
// The highest seen post number by topic
|
||||
highestSeenByTopic: {},
|
||||
|
||||
logoSmall: (function() {
|
||||
var logo;
|
||||
logo = Discourse.SiteSettings.logo_small_url;
|
||||
if (logo && logo.length > 1) {
|
||||
return "<img src='" + logo + "' width='33' height='33'>";
|
||||
} else {
|
||||
return "<i class='icon-home'></i>";
|
||||
}
|
||||
}).property(),
|
||||
|
||||
titleChanged: (function() {
|
||||
titleChanged: function() {
|
||||
var title;
|
||||
title = "";
|
||||
if (this.get('title')) {
|
||||
|
@ -37,51 +34,45 @@ Discourse = Ember.Application.createWithMixins({
|
|||
title = "(*) " + title;
|
||||
}
|
||||
// chrome bug workaround see: http://stackoverflow.com/questions/2952384/changing-the-window-title-when-focussing-the-window-doesnt-work-in-chrome
|
||||
window.setTimeout((function() {
|
||||
window.setTimeout(function() {
|
||||
document.title = ".";
|
||||
document.title = title;
|
||||
}), 200);
|
||||
}).observes('title', 'hasFocus', 'notify'),
|
||||
}, 200);
|
||||
}.observes('title', 'hasFocus', 'notify'),
|
||||
|
||||
currentUserChanged: (function() {
|
||||
var bus, user;
|
||||
bus = Discourse.MessageBus;
|
||||
currentUserChanged: function() {
|
||||
|
||||
// We don't want to receive any previous user notifications
|
||||
var bus = Discourse.MessageBus;
|
||||
bus.unsubscribe("/notification/*");
|
||||
bus.callbackInterval = Discourse.SiteSettings.anon_polling_interval;
|
||||
bus.enableLongPolling = false;
|
||||
user = this.get('currentUser');
|
||||
|
||||
var user = this.get('currentUser');
|
||||
if (user) {
|
||||
bus.callbackInterval = Discourse.SiteSettings.polling_interval;
|
||||
bus.enableLongPolling = true;
|
||||
if (user.admin) {
|
||||
bus.subscribe("/flagged_counts", function(data) {
|
||||
return user.set('site_flagged_posts_count', data.total);
|
||||
user.set('site_flagged_posts_count', data.total);
|
||||
});
|
||||
}
|
||||
return bus.subscribe("/notification/" + user.id, (function(data) {
|
||||
bus.subscribe("/notification/" + user.id, (function(data) {
|
||||
user.set('unread_notifications', data.unread_notifications);
|
||||
return user.set('unread_private_messages', data.unread_private_messages);
|
||||
user.set('unread_private_messages', data.unread_private_messages);
|
||||
}), user.notification_channel_position);
|
||||
}
|
||||
}).observes('currentUser'),
|
||||
notifyTitle: function() {
|
||||
return this.set('notify', true);
|
||||
},
|
||||
}.observes('currentUser'),
|
||||
|
||||
// Browser aware replaceState
|
||||
replaceState: function(path) {
|
||||
if (window.history &&
|
||||
window.history.pushState &&
|
||||
window.history.replaceState &&
|
||||
!navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]|WebApps\/.+CFNetwork)/)) {
|
||||
if (window.location.pathname !== path) {
|
||||
return history.replaceState({
|
||||
path: path
|
||||
}, null, path);
|
||||
}
|
||||
}
|
||||
// The classes of buttons to show on a post
|
||||
postButtons: function() {
|
||||
return Discourse.SiteSettings.post_menu.split("|").map(function(i) {
|
||||
return (i.replace(/\+/, '').capitalize());
|
||||
});
|
||||
}.property('Discourse.SiteSettings.post_menu'),
|
||||
|
||||
notifyTitle: function() {
|
||||
this.set('notify', true);
|
||||
},
|
||||
|
||||
openComposer: function(opts) {
|
||||
|
@ -90,291 +81,108 @@ Discourse = Ember.Application.createWithMixins({
|
|||
if (composer) composer.open(opts);
|
||||
},
|
||||
|
||||
// Like router.route, but allow full urls rather than relative one
|
||||
// HERE BE HACKS - uses the ember container for now until we can do this nicer.
|
||||
routeTo: function(path) {
|
||||
var newMatches, newTopicId, oldMatches, oldTopicId, opts, router, topicController, topicRegexp;
|
||||
path = path.replace(/https?\:\/\/[^\/]+/, '');
|
||||
|
||||
// If we're in the same topic, don't push the state
|
||||
topicRegexp = /\/t\/([^\/]+)\/(\d+)\/?(\d+)?/;
|
||||
newMatches = topicRegexp.exec(path);
|
||||
newTopicId = newMatches ? newMatches[2] : null;
|
||||
if (newTopicId) {
|
||||
oldMatches = topicRegexp.exec(window.location.pathname);
|
||||
if ((oldTopicId = oldMatches ? oldMatches[2] : void 0) && (oldTopicId === newTopicId)) {
|
||||
Discourse.replaceState(path);
|
||||
topicController = Discourse.__container__.lookup('controller:topic');
|
||||
opts = {
|
||||
trackVisit: false
|
||||
};
|
||||
if (newMatches[3]) {
|
||||
opts.nearPost = newMatches[3];
|
||||
}
|
||||
topicController.get('content').loadPosts(opts);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Be wary of looking up the router. In this case, we have links in our
|
||||
// HTML, say form compiled markdown posts, that need to be routed.
|
||||
router = Discourse.__container__.lookup('router:main');
|
||||
router.router.updateURL(path);
|
||||
return router.handleURL(path);
|
||||
},
|
||||
|
||||
// The classes of buttons to show on a post
|
||||
postButtons: (function() {
|
||||
return Discourse.SiteSettings.post_menu.split("|").map(function(i) {
|
||||
return "" + (i.replace(/\+/, '').capitalize());
|
||||
});
|
||||
}).property('Discourse.SiteSettings.post_menu'),
|
||||
/**
|
||||
Establishes global DOM events and bindings via jQuery.
|
||||
|
||||
@method bindDOMEvents
|
||||
**/
|
||||
bindDOMEvents: function() {
|
||||
var $html, hasTouch,
|
||||
_this = this;
|
||||
$html = $('html');
|
||||
var $html, hasTouch;
|
||||
|
||||
/* Add the discourse touch event */
|
||||
$html = $('html');
|
||||
hasTouch = false;
|
||||
|
||||
if ($html.hasClass('touch')) {
|
||||
hasTouch = true;
|
||||
}
|
||||
|
||||
if (Modernizr.prefixed("MaxTouchPoints", navigator) > 1) {
|
||||
hasTouch = true;
|
||||
}
|
||||
|
||||
if (hasTouch) {
|
||||
$html.addClass('discourse-touch');
|
||||
this.touch = true;
|
||||
this.hasTouch = true;
|
||||
|
||||
} else {
|
||||
$html.addClass('discourse-no-touch');
|
||||
this.touch = false;
|
||||
}
|
||||
|
||||
$('#main').on('click.discourse', '[data-not-implemented=true]', function(e) {
|
||||
e.preventDefault();
|
||||
alert(Em.String.i18n('not_implemented'));
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#main').on('click.discourse', 'a', function(e) {
|
||||
var $currentTarget, href;
|
||||
if (e.isDefaultPrevented() || e.metaKey || e.ctrlKey) {
|
||||
return;
|
||||
}
|
||||
$currentTarget = $(e.currentTarget);
|
||||
href = $currentTarget.attr('href');
|
||||
if (href === void 0) {
|
||||
return;
|
||||
}
|
||||
if (href === '#') {
|
||||
return;
|
||||
}
|
||||
if ($currentTarget.attr('target')) {
|
||||
return;
|
||||
}
|
||||
if ($currentTarget.data('auto-route')) {
|
||||
return;
|
||||
}
|
||||
if ($currentTarget.hasClass('lightbox')) {
|
||||
return;
|
||||
}
|
||||
if (href.indexOf("mailto:") === 0) {
|
||||
return;
|
||||
}
|
||||
if (href.match(/^http[s]?:\/\//i) && !href.match(new RegExp("^http:\\/\\/" + window.location.hostname, "i"))) {
|
||||
return;
|
||||
}
|
||||
if (e.isDefaultPrevented() || e.metaKey || e.ctrlKey) return;
|
||||
|
||||
var $currentTarget = $(e.currentTarget);
|
||||
var href = $currentTarget.attr('href');
|
||||
if (!href) return;
|
||||
if (href === '#') return;
|
||||
if ($currentTarget.attr('target')) return;
|
||||
if ($currentTarget.data('auto-route')) return;
|
||||
if ($currentTarget.hasClass('lightbox')) return;
|
||||
if (href.indexOf("mailto:") === 0) return;
|
||||
if (href.match(/^http[s]?:\/\//i) && !href.match(new RegExp("^http:\\/\\/" + window.location.hostname, "i"))) return;
|
||||
|
||||
e.preventDefault();
|
||||
_this.routeTo(href);
|
||||
Discourse.URL.routeTo(href);
|
||||
return false;
|
||||
});
|
||||
return $(window).focus(function() {
|
||||
_this.set('hasFocus', true);
|
||||
return _this.set('notify', false);
|
||||
|
||||
$(window).focus(function() {
|
||||
Discourse.set('hasFocus', true);
|
||||
Discourse.set('notify', false);
|
||||
}).blur(function() {
|
||||
return _this.set('hasFocus', false);
|
||||
Discourse.set('hasFocus', false);
|
||||
});
|
||||
|
||||
// Add a CSRF token to all AJAX requests
|
||||
var csrfToken = $('meta[name=csrf-token]').attr('content');
|
||||
jQuery.ajaxPrefilter(function(options, originalOptions, xhr) {
|
||||
if (!options.crossDomain) {
|
||||
xhr.setRequestHeader('X-CSRF-Token', csrfToken);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
Log the current user out of Discourse
|
||||
|
||||
@method logout
|
||||
**/
|
||||
logout: function() {
|
||||
var username,
|
||||
_this = this;
|
||||
username = this.get('currentUser.username');
|
||||
Discourse.KeyValueStore.abandonLocal();
|
||||
return jQuery.ajax("/session/" + username, {
|
||||
return jQuery.ajax("/session/" + this.get('currentUser.username'), {
|
||||
type: 'DELETE',
|
||||
success: function(result) {
|
||||
/* To keep lots of our variables unbound, we can handle a redirect on logging out.
|
||||
*/
|
||||
return window.location.reload();
|
||||
// To keep lots of our variables unbound, we can handle a redirect on logging out.
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
},
|
||||
/* fancy probes in ember
|
||||
*/
|
||||
|
||||
insertProbes: function() {
|
||||
var topLevel;
|
||||
if (typeof console === "undefined" || console === null) {
|
||||
return;
|
||||
}
|
||||
topLevel = function(fn, name) {
|
||||
return window.probes.measure(fn, {
|
||||
name: name,
|
||||
before: function(data, owner, args) {
|
||||
if (owner) {
|
||||
return window.probes.clear();
|
||||
}
|
||||
},
|
||||
after: function(data, owner, args) {
|
||||
var ary, f, n, v, _ref;
|
||||
if (owner && data.time > 10) {
|
||||
f = function(name, data) {
|
||||
if (data && data.count) {
|
||||
return "" + name + " - " + data.count + " calls " + ((data.time + 0.0).toFixed(2)) + "ms";
|
||||
}
|
||||
};
|
||||
if (console && console.group) {
|
||||
console.group(f(name, data));
|
||||
} else {
|
||||
console.log("");
|
||||
console.log(f(name, data));
|
||||
}
|
||||
ary = [];
|
||||
_ref = window.probes;
|
||||
for (n in _ref) {
|
||||
v = _ref[n];
|
||||
if (n === name || v.time < 1) {
|
||||
continue;
|
||||
}
|
||||
ary.push({
|
||||
k: n,
|
||||
v: v
|
||||
});
|
||||
}
|
||||
ary.sortBy(function(item) {
|
||||
if (item.v && item.v.time) {
|
||||
return -item.v.time;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}).each(function(item) {
|
||||
var output = f("" + item.k, item.v);
|
||||
if (output) {
|
||||
return console.log(output);
|
||||
}
|
||||
});
|
||||
if (typeof console !== "undefined" && console !== null) {
|
||||
if (typeof console.groupEnd === "function") {
|
||||
console.groupEnd();
|
||||
}
|
||||
}
|
||||
return window.probes.clear();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
Ember.View.prototype.renderToBuffer = window.probes.measure(Ember.View.prototype.renderToBuffer, "renderToBuffer");
|
||||
Discourse.routeTo = topLevel(Discourse.routeTo, "Discourse.routeTo");
|
||||
Ember.run.end = topLevel(Ember.run.end, "Ember.run.end");
|
||||
},
|
||||
authenticationComplete: function(options) {
|
||||
// TODO, how to dispatch this to the view without the container?
|
||||
var loginView;
|
||||
loginView = Discourse.__container__.lookup('controller:modal').get('currentView');
|
||||
return loginView.authenticationComplete(options);
|
||||
},
|
||||
buildRoutes: function(builder) {
|
||||
var oldBuilder;
|
||||
oldBuilder = Discourse.routeBuilder;
|
||||
Discourse.routeBuilder = function() {
|
||||
if (oldBuilder) {
|
||||
oldBuilder.call(this);
|
||||
}
|
||||
return builder.call(this);
|
||||
};
|
||||
},
|
||||
|
||||
start: function() {
|
||||
this.bindDOMEvents();
|
||||
Discourse.bindDOMEvents();
|
||||
Discourse.SiteSettings = PreloadStore.getStatic('siteSettings');
|
||||
Discourse.MessageBus.start();
|
||||
Discourse.KeyValueStore.init("discourse_", Discourse.MessageBus);
|
||||
Discourse.insertProbes();
|
||||
|
||||
// subscribe to any site customizations that are loaded
|
||||
$('link.custom-css').each(function() {
|
||||
var id, split, stylesheet,
|
||||
_this = this;
|
||||
split = this.href.split("/");
|
||||
id = split[split.length - 1].split(".css")[0];
|
||||
stylesheet = this;
|
||||
return Discourse.MessageBus.subscribe("/file-change/" + id, function(data) {
|
||||
var orig, sp;
|
||||
if (!$(stylesheet).data('orig')) {
|
||||
$(stylesheet).data('orig', stylesheet.href);
|
||||
// Developer specific functions
|
||||
Discourse.Development.setupProbes();
|
||||
Discourse.Development.observeLiveChanges();
|
||||
}
|
||||
orig = $(stylesheet).data('orig');
|
||||
sp = orig.split(".css?");
|
||||
stylesheet.href = sp[0] + ".css?" + data;
|
||||
});
|
||||
});
|
||||
$('header.custom').each(function() {
|
||||
var header;
|
||||
header = $(this);
|
||||
return Discourse.MessageBus.subscribe("/header-change/" + ($(this).data('key')), function(data) {
|
||||
return header.html(data);
|
||||
});
|
||||
});
|
||||
|
||||
// possibly move this to dev only
|
||||
return Discourse.MessageBus.subscribe("/file-change", function(data) {
|
||||
Ember.TEMPLATES.empty = Handlebars.compile("<div></div>");
|
||||
return data.each(function(me) {
|
||||
var js;
|
||||
if (me === "refresh") {
|
||||
return document.location.reload(true);
|
||||
} else if (me.name.substr(-10) === "handlebars") {
|
||||
js = me.name.replace(".handlebars", "").replace("app/assets/javascripts", "/assets");
|
||||
return $LAB.script(js + "?hash=" + me.hash).wait(function() {
|
||||
var templateName;
|
||||
templateName = js.replace(".js", "").replace("/assets/", "");
|
||||
return jQuery.each(Ember.View.views, function() {
|
||||
var _this = this;
|
||||
if (this.get('templateName') === templateName) {
|
||||
this.set('templateName', 'empty');
|
||||
this.rerender();
|
||||
return Em.run.next(function() {
|
||||
_this.set('templateName', templateName);
|
||||
return _this.rerender();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return $('link').each(function() {
|
||||
if (this.href.match(me.name) && me.hash) {
|
||||
if (!$(this).data('orig')) {
|
||||
$(this).data('orig', this.href);
|
||||
}
|
||||
this.href = $(this).data('orig') + "&hash=" + me.hash;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Discourse.Router = Discourse.Router.reopen({
|
||||
location: 'discourse_location'
|
||||
});
|
||||
|
||||
// since we have no jquery-rails these days, hook up csrf token
|
||||
csrf_token = $('meta[name=csrf-token]').attr('content');
|
||||
|
||||
jQuery.ajaxPrefilter(function(options, originalOptions, xhr) {
|
||||
if (!options.crossDomain) {
|
||||
xhr.setRequestHeader('X-CSRF-Token', csrf_token);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Discourse.Router = Discourse.Router.reopen({ location: 'discourse_location' });
|
|
@ -88,7 +88,7 @@ Discourse.ClickTrack = {
|
|||
topic_id: topicId,
|
||||
redirect: false
|
||||
});
|
||||
Discourse.routeTo(href);
|
||||
Discourse.URL.routeTo(href);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
/**
|
||||
Functions to help development of Discourse, such as inserting probes
|
||||
|
||||
@class Development
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.Development = {
|
||||
|
||||
|
||||
/**
|
||||
Set up probes for performance measurements.
|
||||
|
||||
@method setupProbes
|
||||
**/
|
||||
setupProbes: function() {
|
||||
|
||||
// Don't probe if we don't have a console
|
||||
if (typeof console === "undefined" || console === null) return;
|
||||
|
||||
var topLevel = function(fn, name) {
|
||||
return window.probes.measure(fn, {
|
||||
name: name,
|
||||
|
||||
before: function(data, owner, args) {
|
||||
if (owner) {
|
||||
return window.probes.clear();
|
||||
}
|
||||
},
|
||||
|
||||
after: function(data, owner, args) {
|
||||
var ary, f, n, v, _ref;
|
||||
if (owner && data.time > 10) {
|
||||
|
||||
f = function(name, data) {
|
||||
if (data && data.count) return name + " - " + data.count + " calls " + ((data.time + 0.0).toFixed(2)) + "ms";
|
||||
};
|
||||
|
||||
if (console && console.group) {
|
||||
console.group(f(name, data));
|
||||
} else {
|
||||
console.log("");
|
||||
console.log(f(name, data));
|
||||
}
|
||||
|
||||
ary = [];
|
||||
_ref = window.probes;
|
||||
for (n in _ref) {
|
||||
v = _ref[n];
|
||||
if (n === name || v.time < 1) {
|
||||
continue;
|
||||
}
|
||||
ary.push({
|
||||
k: n,
|
||||
v: v
|
||||
});
|
||||
}
|
||||
ary.sortBy(function(item) {
|
||||
if (item.v && item.v.time) {
|
||||
return -item.v.time;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}).each(function(item) {
|
||||
var output = f("" + item.k, item.v);
|
||||
if (output) {
|
||||
return console.log(output);
|
||||
}
|
||||
});
|
||||
if (typeof console !== "undefined" && console !== null) {
|
||||
if (typeof console.groupEnd === "function") {
|
||||
console.groupEnd();
|
||||
}
|
||||
}
|
||||
return window.probes.clear();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Ember.View.prototype.renderToBuffer = window.probes.measure(Ember.View.prototype.renderToBuffer, "renderToBuffer");
|
||||
Discourse.URL.routeTo = topLevel(Discourse.URL.routeTo, "Discourse.URL.routeTo");
|
||||
Ember.run.end = topLevel(Ember.run.end, "Ember.run.end");
|
||||
},
|
||||
|
||||
/**
|
||||
Use the message bus for live reloading of components for faster development.
|
||||
|
||||
@method observeLiveChanges
|
||||
**/
|
||||
observeLiveChanges: function() {
|
||||
|
||||
// subscribe to any site customizations that are loaded
|
||||
$('link.custom-css').each(function() {
|
||||
var id, split, stylesheet,
|
||||
_this = this;
|
||||
split = this.href.split("/");
|
||||
id = split[split.length - 1].split(".css")[0];
|
||||
stylesheet = this;
|
||||
return Discourse.MessageBus.subscribe("/file-change/" + id, function(data) {
|
||||
var orig, sp;
|
||||
if (!$(stylesheet).data('orig')) {
|
||||
$(stylesheet).data('orig', stylesheet.href);
|
||||
}
|
||||
orig = $(stylesheet).data('orig');
|
||||
sp = orig.split(".css?");
|
||||
stylesheet.href = sp[0] + ".css?" + data;
|
||||
});
|
||||
});
|
||||
|
||||
// Custom header changes
|
||||
$('header.custom').each(function() {
|
||||
var header;
|
||||
header = $(this);
|
||||
return Discourse.MessageBus.subscribe("/header-change/" + ($(this).data('key')), function(data) {
|
||||
return header.html(data);
|
||||
});
|
||||
});
|
||||
|
||||
// Observe file changes
|
||||
return Discourse.MessageBus.subscribe("/file-change", function(data) {
|
||||
Ember.TEMPLATES.empty = Handlebars.compile("<div></div>");
|
||||
return data.each(function(me) {
|
||||
var js;
|
||||
if (me === "refresh") {
|
||||
return document.location.reload(true);
|
||||
} else if (me.name.substr(-10) === "handlebars") {
|
||||
js = me.name.replace(".handlebars", "").replace("app/assets/javascripts", "/assets");
|
||||
return $LAB.script(js + "?hash=" + me.hash).wait(function() {
|
||||
var templateName;
|
||||
templateName = js.replace(".js", "").replace("/assets/", "");
|
||||
return jQuery.each(Ember.View.views, function() {
|
||||
var _this = this;
|
||||
if (this.get('templateName') === templateName) {
|
||||
this.set('templateName', 'empty');
|
||||
this.rerender();
|
||||
return Em.run.next(function() {
|
||||
_this.set('templateName', templateName);
|
||||
return _this.rerender();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return $('link').each(function() {
|
||||
if (this.href.match(me.name) && me.hash) {
|
||||
if (!$(this).data('orig')) {
|
||||
$(this).data('orig', this.href);
|
||||
}
|
||||
this.href = $(this).data('orig') + "&hash=" + me.hash;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
};
|
|
@ -0,0 +1,69 @@
|
|||
/**
|
||||
URL related functions.
|
||||
|
||||
@class URL
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.URL = {
|
||||
|
||||
/**
|
||||
Browser aware replaceState. Will only be invoked if the browser supports it.
|
||||
|
||||
@method replaceState
|
||||
@param {String} path The path we are replacing our history state with.
|
||||
**/
|
||||
replaceState: function(path) {
|
||||
if (window.history &&
|
||||
window.history.pushState &&
|
||||
window.history.replaceState &&
|
||||
!navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]|WebApps\/.+CFNetwork)/) &&
|
||||
(window.location.pathname !== path)) {
|
||||
return history.replaceState({ path: path }, null, path);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Our custom routeTo method is used to intelligently overwrite default routing
|
||||
behavior.
|
||||
|
||||
It contains the logic necessary to route within a topic using replaceState to
|
||||
keep the history intact.
|
||||
|
||||
Note that currently it uses `__container__` which is not advised
|
||||
but there is no other way to access the router.
|
||||
|
||||
@method routeTo
|
||||
@param {String} path The path we are routing to.
|
||||
**/
|
||||
routeTo: function(path) {
|
||||
var newMatches, newTopicId, oldMatches, oldTopicId, opts, router, topicController, topicRegexp;
|
||||
path = path.replace(/https?\:\/\/[^\/]+/, '');
|
||||
|
||||
console.log("route to: " + path);
|
||||
|
||||
// If we're in the same topic, don't push the state
|
||||
topicRegexp = /\/t\/([^\/]+)\/(\d+)\/?(\d+)?/;
|
||||
newMatches = topicRegexp.exec(path);
|
||||
newTopicId = newMatches ? newMatches[2] : null;
|
||||
if (newTopicId) {
|
||||
oldMatches = topicRegexp.exec(window.location.pathname);
|
||||
if ((oldTopicId = oldMatches ? oldMatches[2] : void 0) && (oldTopicId === newTopicId)) {
|
||||
Discourse.URL.replaceState(path);
|
||||
topicController = Discourse.__container__.lookup('controller:topic');
|
||||
opts = { trackVisit: false };
|
||||
if (newMatches[3]) {
|
||||
opts.nearPost = newMatches[3];
|
||||
}
|
||||
topicController.get('content').loadPosts(opts);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Be wary of looking up the router. In this case, we have links in our
|
||||
// HTML, say form compiled markdown posts, that need to be routed.
|
||||
router = Discourse.__container__.lookup('router:main');
|
||||
router.router.updateURL(path);
|
||||
return router.handleURL(path);
|
||||
}
|
||||
|
||||
};
|
|
@ -42,7 +42,7 @@ Discourse.ComposerController = Discourse.Controller.extend({
|
|||
} else {
|
||||
Discourse.set('currentUser.reply_count', Discourse.get('currentUser.reply_count') + 1);
|
||||
}
|
||||
Discourse.routeTo(opts.post.get('url'));
|
||||
Discourse.URL.routeTo(opts.post.get('url'));
|
||||
}, function(error) {
|
||||
composer.set('disableDrafts', false);
|
||||
bootbox.alert(error);
|
||||
|
@ -159,7 +159,7 @@ Discourse.ComposerController = Discourse.Controller.extend({
|
|||
|
||||
// View a new reply we've made
|
||||
viewNewReply: function() {
|
||||
Discourse.routeTo(this.get('createdPost.url'));
|
||||
Discourse.URL.routeTo(this.get('createdPost.url'));
|
||||
this.close();
|
||||
return false;
|
||||
},
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
**/
|
||||
Discourse.HeaderController = Discourse.Controller.extend({
|
||||
topic: null,
|
||||
showExtraInfo: false,
|
||||
showExtraInfo: null,
|
||||
|
||||
toggleStar: function() {
|
||||
var topic = this.get('topic');
|
||||
|
|
|
@ -10,7 +10,6 @@ Discourse.TopicController = Discourse.ObjectController.extend({
|
|||
userFilters: new Em.Set(),
|
||||
multiSelect: false,
|
||||
bestOf: false,
|
||||
showExtraHeaderInfo: false,
|
||||
needs: ['header', 'modal', 'composer', 'quoteButton'],
|
||||
|
||||
filter: (function() {
|
||||
|
@ -42,10 +41,6 @@ Discourse.TopicController = Discourse.ObjectController.extend({
|
|||
return this.get('canDeleteSelected');
|
||||
}).property('canDeleteSelected'),
|
||||
|
||||
showExtraHeaderInfoChanged: (function() {
|
||||
this.set('controllers.header.showExtraInfo', this.get('showExtraHeaderInfo'));
|
||||
}).observes('showExtraHeaderInfo'),
|
||||
|
||||
canDeleteSelected: (function() {
|
||||
var canDelete, selectedPosts;
|
||||
selectedPosts = this.get('selectedPosts');
|
||||
|
@ -109,11 +104,11 @@ Discourse.TopicController = Discourse.ObjectController.extend({
|
|||
},
|
||||
|
||||
jumpTop: function() {
|
||||
Discourse.routeTo(this.get('content.url'));
|
||||
Discourse.URL.routeTo(this.get('content.url'));
|
||||
},
|
||||
|
||||
jumpBottom: function() {
|
||||
Discourse.routeTo(this.get('content.lastPostUrl'));
|
||||
Discourse.URL.routeTo(this.get('content.lastPostUrl'));
|
||||
},
|
||||
|
||||
cancelFilter: function() {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
Discourse.UserPrivateMessagesController = Discourse.ObjectController.extend({
|
||||
|
||||
editPreferences: function() {
|
||||
return Discourse.routeTo("/users/" + (this.get('content.username_lower')) + "/preferences");
|
||||
return Discourse.URL.routeTo("/users/" + (this.get('content.username_lower')) + "/preferences");
|
||||
},
|
||||
|
||||
composePrivateMessage: function() {
|
||||
|
|
|
@ -14,7 +14,7 @@ Discourse.TopicList = Discourse.Model.extend({
|
|||
_this = this;
|
||||
promise = new RSVP.Promise();
|
||||
if (moreUrl = this.get('more_topics_url')) {
|
||||
Discourse.replaceState("/" + (this.get('filter')) + "/more");
|
||||
Discourse.URL.replaceState("/" + (this.get('filter')) + "/more");
|
||||
jQuery.ajax(moreUrl, {
|
||||
success: function(result) {
|
||||
var newTopics, topicIds, topics;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
@method buildRoutes
|
||||
@for Discourse.ApplicationRoute
|
||||
**/
|
||||
Discourse.buildRoutes(function() {
|
||||
Discourse.Route.buildRoutes(function() {
|
||||
var router = this;
|
||||
|
||||
// Topic routes
|
||||
|
|
|
@ -28,3 +28,14 @@ Discourse.Route = Em.Route.extend({
|
|||
});
|
||||
|
||||
|
||||
Discourse.Route.reopenClass({
|
||||
|
||||
buildRoutes: function(builder) {
|
||||
var oldBuilder = Discourse.routeBuilder;
|
||||
Discourse.routeBuilder = function() {
|
||||
if (oldBuilder) oldBuilder.call(this);
|
||||
return builder.call(this);
|
||||
};
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -34,10 +34,7 @@ Discourse.TopicRoute = Discourse.Route.extend({
|
|||
},
|
||||
|
||||
setupController: function(controller, model) {
|
||||
var headerController;
|
||||
controller.set('showExtraHeaderInfo', false);
|
||||
headerController = this.controllerFor('header');
|
||||
headerController.set('topic', model);
|
||||
this.controllerFor('header').set('topic', model);
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -1,17 +1,7 @@
|
|||
<div class='container'>
|
||||
<div class='contents clearfix'>
|
||||
<div class='title'>
|
||||
{{#if controller.showExtraInfo}}
|
||||
|
||||
{{#linkTo list.popular}}{{{Discourse.logoSmall}}}{{/linkTo}}
|
||||
|
||||
{{else}}
|
||||
|
||||
{{#linkTo list.popular}}<img src="{{unbound Discourse.SiteSettings.logo_url}}" alt="{{unbound Discourse.SiteSettings.title}}" id='site-logo'>{{/linkTo}}
|
||||
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
{{view.logoHTML}}
|
||||
{{view Discourse.TopicExtraInfoView}}
|
||||
|
||||
<div class='panel clearfix'>
|
||||
|
|
|
@ -81,6 +81,27 @@ Discourse.HeaderView = Discourse.View.extend({
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Display the correct logo in the header, showing a custom small icon if it exists.
|
||||
|
||||
@property logoHTML
|
||||
**/
|
||||
logoHTML: function() {
|
||||
var result = "<div class='title'><a href='/'>";
|
||||
if (this.get('controller.showExtraInfo')) {
|
||||
var logo = Discourse.SiteSettings.logo_small_url;
|
||||
if (logo && logo.length > 1) {
|
||||
result += "<img src='" + logo + "' width='33' height='33'>";
|
||||
} else {
|
||||
result += "<i class='icon-home'></i>";
|
||||
}
|
||||
} else {
|
||||
result += "<img src=\"" + Discourse.SiteSettings.logo_url + "\" alt=\"" + Discourse.SiteSettings.title + "\" id='site-logo'>";
|
||||
}
|
||||
result += "</a></div>";
|
||||
return new Handlebars.SafeString(result);
|
||||
}.property('controller.showExtraInfo'),
|
||||
|
||||
willDestroyElement: function() {
|
||||
$(window).unbind('scroll.discourse-dock');
|
||||
return $(document).unbind('touchmove.discourse-dock');
|
||||
|
|
|
@ -42,7 +42,7 @@ Discourse.EditCategoryView = Discourse.ModalBodyView.extend({
|
|||
|
||||
showCategoryTopic: function() {
|
||||
$('#discourse-modal').modal('hide');
|
||||
Discourse.routeTo(this.get('category.topic_url'));
|
||||
Discourse.URL.routeTo(this.get('category.topic_url'));
|
||||
return false;
|
||||
},
|
||||
|
||||
|
|
|
@ -36,8 +36,8 @@ Discourse.MoveSelectedView = Discourse.ModalBodyView.extend({
|
|||
Discourse.Topic.movePosts(this.get('topic.id'), this.get('topicName'), postIds).then(function(result) {
|
||||
if (result.success) {
|
||||
$('#discourse-modal').modal('hide');
|
||||
return Em.run.next(function() {
|
||||
return Discourse.routeTo(result.url);
|
||||
Em.run.next(function() {
|
||||
Discourse.URL.routeTo(result.url);
|
||||
});
|
||||
} else {
|
||||
_this.flash(Em.String.i18n('topic.move_selected.error'));
|
||||
|
|
|
@ -139,13 +139,10 @@ window.Discourse.SearchView = Discourse.View.extend({
|
|||
},
|
||||
|
||||
select: function() {
|
||||
var href;
|
||||
if (this.get('loading')) {
|
||||
return;
|
||||
}
|
||||
href = $('#search-dropdown li.selected a').prop('href');
|
||||
if (this.get('loading')) return;
|
||||
var href = $('#search-dropdown li.selected a').prop('href');
|
||||
if (href) {
|
||||
Discourse.routeTo(href);
|
||||
Discourse.URL.routeTo(href);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ Discourse.TopicView = Discourse.View.extend(Discourse.Scrolling, {
|
|||
postUrl += "/best_of";
|
||||
}
|
||||
}
|
||||
Discourse.replaceState(postUrl);
|
||||
Discourse.URL.replaceState(postUrl);
|
||||
|
||||
// Show appropriate jump tools
|
||||
if (current === 1) {
|
||||
|
@ -441,10 +441,12 @@ Discourse.TopicView = Discourse.View.extend(Discourse.Scrolling, {
|
|||
this.docAt = title.offset().top;
|
||||
}
|
||||
}
|
||||
|
||||
var headerController = this.get('controller.controllers.header');
|
||||
if (this.docAt) {
|
||||
this.set('controller.showExtraHeaderInfo', offset >= this.docAt || !firstLoaded);
|
||||
headerController.set('showExtraInfo', offset >= this.docAt || !firstLoaded);
|
||||
} else {
|
||||
this.set('controller.showExtraHeaderInfo', !firstLoaded);
|
||||
headerController.set('showExtraInfo', !firstLoaded);
|
||||
}
|
||||
|
||||
// there is a whole bunch of caching we could add here
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Version: v1.0.0-pre.2-723-g052062c
|
||||
// Last commit: 052062c (2013-02-18 19:32:17 -0800)
|
||||
// Version: v1.0.0-pre.2-756-gb26f1f0
|
||||
// Last commit: b26f1f0 (2013-02-26 09:03:26 -0800)
|
||||
|
||||
|
||||
(function() {
|
||||
|
@ -150,8 +150,8 @@ Ember.deprecateFunc = function(message, func) {
|
|||
|
||||
})();
|
||||
|
||||
// Version: v1.0.0-pre.2-723-g052062c
|
||||
// Last commit: 052062c (2013-02-18 19:32:17 -0800)
|
||||
// Version: v1.0.0-pre.2-756-gb26f1f0
|
||||
// Last commit: b26f1f0 (2013-02-26 09:03:26 -0800)
|
||||
|
||||
|
||||
(function() {
|
||||
|
@ -297,6 +297,15 @@ Ember.LOG_STACKTRACE_ON_DEPRECATION = (Ember.ENV.LOG_STACKTRACE_ON_DEPRECATION !
|
|||
*/
|
||||
Ember.SHIM_ES5 = (Ember.ENV.SHIM_ES5 === false) ? false : Ember.EXTEND_PROTOTYPES;
|
||||
|
||||
/**
|
||||
Determines whether Ember logs info about version of used libraries
|
||||
|
||||
@property LOG_VERSION
|
||||
@type Boolean
|
||||
@default true
|
||||
*/
|
||||
Ember.LOG_VERSION = (Ember.ENV.LOG_VERSION === false) ? false : true;
|
||||
|
||||
/**
|
||||
Empty function. Useful for some operations.
|
||||
|
||||
|
@ -6123,7 +6132,6 @@ define("container",
|
|||
register: function(type, name, factory, options) {
|
||||
var fullName;
|
||||
|
||||
|
||||
if (type.indexOf(':') !== -1){
|
||||
options = factory;
|
||||
factory = name;
|
||||
|
@ -6133,15 +6141,23 @@ define("container",
|
|||
fullName = type + ":" + name;
|
||||
}
|
||||
|
||||
this.registry.set(fullName, factory);
|
||||
this._options.set(fullName, options || {});
|
||||
var normalizedName = this.normalize(fullName);
|
||||
|
||||
this.registry.set(normalizedName, factory);
|
||||
this._options.set(normalizedName, options || {});
|
||||
},
|
||||
|
||||
resolve: function(fullName) {
|
||||
return this.resolver(fullName) || this.registry.get(fullName);
|
||||
},
|
||||
|
||||
normalize: function(fullName) {
|
||||
return fullName;
|
||||
},
|
||||
|
||||
lookup: function(fullName, options) {
|
||||
fullName = this.normalize(fullName);
|
||||
|
||||
options = options || {};
|
||||
|
||||
if (this.cache.has(fullName) && options.singleton !== false) {
|
||||
|
@ -6270,7 +6286,8 @@ define("container",
|
|||
}
|
||||
|
||||
function factoryFor(container, fullName) {
|
||||
return container.resolve(fullName);
|
||||
var name = container.normalize(fullName);
|
||||
return container.resolve(name);
|
||||
}
|
||||
|
||||
function instantiate(container, fullName) {
|
||||
|
@ -6745,6 +6762,20 @@ Ember.Error.prototype = Ember.create(Error.prototype);
|
|||
|
||||
|
||||
|
||||
(function() {
|
||||
/**
|
||||
Expose RSVP implementation
|
||||
|
||||
@class RSVP
|
||||
@namespace Ember
|
||||
@constructor
|
||||
*/
|
||||
Ember.RSVP = requireModule('rsvp');
|
||||
|
||||
})();
|
||||
|
||||
|
||||
|
||||
(function() {
|
||||
/**
|
||||
@module ember
|
||||
|
@ -11125,40 +11156,8 @@ Ember.Mixin.prototype.toString = classToString;
|
|||
|
||||
|
||||
(function() {
|
||||
/**
|
||||
@module ember
|
||||
@submodule ember-runtime
|
||||
*/
|
||||
|
||||
/**
|
||||
Defines a namespace that will contain an executable application. This is
|
||||
very similar to a normal namespace except that it is expected to include at
|
||||
least a 'ready' function which can be run to initialize the application.
|
||||
|
||||
Currently `Ember.Application` is very similar to `Ember.Namespace.` However,
|
||||
this class may be augmented by additional frameworks so it is important to
|
||||
use this instance when building new applications.
|
||||
|
||||
# Example Usage
|
||||
|
||||
```javascript
|
||||
MyApp = Ember.Application.create({
|
||||
VERSION: '1.0.0',
|
||||
store: Ember.Store.create().from(Ember.fixtures)
|
||||
});
|
||||
|
||||
MyApp.ready = function() {
|
||||
//..init code goes here...
|
||||
}
|
||||
```
|
||||
|
||||
@class Application
|
||||
@namespace Ember
|
||||
@extends Ember.Namespace
|
||||
*/
|
||||
Ember.Application = Ember.Namespace.extend();
|
||||
|
||||
|
||||
})();
|
||||
|
||||
|
||||
|
@ -11544,6 +11543,25 @@ Ember.ObjectProxy = Ember.Object.extend(
|
|||
}
|
||||
});
|
||||
|
||||
Ember.ObjectProxy.reopenClass({
|
||||
create: function () {
|
||||
var mixin, prototype, i, l, properties, keyName;
|
||||
if (arguments.length) {
|
||||
prototype = this.proto();
|
||||
for (i = 0, l = arguments.length; i < l; i++) {
|
||||
properties = arguments[i];
|
||||
for (keyName in properties) {
|
||||
if (!properties.hasOwnProperty(keyName) || keyName in prototype) { continue; }
|
||||
if (!mixin) mixin = {};
|
||||
mixin[keyName] = null;
|
||||
}
|
||||
}
|
||||
if (mixin) this._initMixins([mixin]);
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
|
||||
|
@ -11864,7 +11882,7 @@ if (ignore.length>0) {
|
|||
/**
|
||||
The NativeArray mixin contains the properties needed to to make the native
|
||||
Array support Ember.MutableArray and all of its dependent APIs. Unless you
|
||||
have `Ember.EXTEND_PROTOTYPES or `Ember.EXTEND_PROTOTYPES.Array` set to
|
||||
have `Ember.EXTEND_PROTOTYPES` or `Ember.EXTEND_PROTOTYPES.Array` set to
|
||||
false, this will be applied automatically. Otherwise you can apply the mixin
|
||||
at anytime by calling `Ember.NativeArray.activate`.
|
||||
|
||||
|
@ -12440,7 +12458,8 @@ Ember.ArrayController = Ember.ArrayProxy.extend(Ember.ControllerMixin,
|
|||
|
||||
objectAtContent: function(idx) {
|
||||
var length = get(this, 'length'),
|
||||
object = get(this,'arrangedContent').objectAt(idx);
|
||||
arrangedContent = get(this,'arrangedContent'),
|
||||
object = arrangedContent && arrangedContent.objectAt(idx);
|
||||
|
||||
if (idx >= 0 && idx < length) {
|
||||
var controllerClass = this.lookupItemController(object);
|
||||
|
@ -12591,15 +12610,16 @@ Ember.$ = jQuery;
|
|||
@module ember
|
||||
@submodule ember-views
|
||||
*/
|
||||
if (Ember.$) {
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dndevents
|
||||
var dragEvents = Ember.String.w('dragstart drag dragenter dragleave dragover drop dragend');
|
||||
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dndevents
|
||||
var dragEvents = Ember.String.w('dragstart drag dragenter dragleave dragover drop dragend');
|
||||
|
||||
// Copies the `dataTransfer` property from a browser event object onto the
|
||||
// jQuery event object for the specified events
|
||||
Ember.EnumerableUtils.forEach(dragEvents, function(eventName) {
|
||||
// Copies the `dataTransfer` property from a browser event object onto the
|
||||
// jQuery event object for the specified events
|
||||
Ember.EnumerableUtils.forEach(dragEvents, function(eventName) {
|
||||
Ember.$.event.fixHooks[eventName] = { props: ['dataTransfer'] };
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
})();
|
||||
|
||||
|
@ -12616,7 +12636,8 @@ Ember.EnumerableUtils.forEach(dragEvents, function(eventName) {
|
|||
// Internet Explorer prior to 9 does not allow setting innerHTML if the first element
|
||||
// is a "zero-scope" element. This problem can be worked around by making
|
||||
// the first node an invisible text node. We, like Modernizr, use ­
|
||||
var needsShy = (function(){
|
||||
|
||||
var needsShy = this.document && (function(){
|
||||
var testEl = document.createElement('div');
|
||||
testEl.innerHTML = "<div></div>";
|
||||
testEl.firstChild.innerHTML = "<script></script>";
|
||||
|
@ -12626,7 +12647,7 @@ var needsShy = (function(){
|
|||
// IE 8 (and likely earlier) likes to move whitespace preceeding
|
||||
// a script tag to appear after it. This means that we can
|
||||
// accidentally remove whitespace when updating a morph.
|
||||
var movesWhitespace = (function() {
|
||||
var movesWhitespace = this.document && (function() {
|
||||
var testEl = document.createElement('div');
|
||||
testEl.innerHTML = "Test: <script type='text/x-placeholder'></script>Value";
|
||||
return testEl.childNodes[0].nodeValue === 'Test:' &&
|
||||
|
@ -13297,7 +13318,7 @@ Ember.EventDispatcher = Ember.Object.extend(
|
|||
setup: function(addedEvents) {
|
||||
var event, events = {
|
||||
touchstart : 'touchStart',
|
||||
// touchmove : 'touchMove',
|
||||
touchmove : 'touchMove',
|
||||
touchend : 'touchEnd',
|
||||
touchcancel : 'touchCancel',
|
||||
keydown : 'keyDown',
|
||||
|
@ -13308,8 +13329,7 @@ Ember.EventDispatcher = Ember.Object.extend(
|
|||
contextmenu : 'contextMenu',
|
||||
click : 'click',
|
||||
dblclick : 'doubleClick',
|
||||
// https://github.com/emberjs/ember.js/pull/2148
|
||||
// mousemove : 'mouseMove',
|
||||
mousemove : 'mouseMove',
|
||||
focusin : 'focusIn',
|
||||
focusout : 'focusOut',
|
||||
mouseenter : 'mouseEnter',
|
||||
|
@ -13459,8 +13479,9 @@ Ember.EventDispatcher = Ember.Object.extend(
|
|||
// Add a new named queue for rendering views that happens
|
||||
// after bindings have synced, and a queue for scheduling actions
|
||||
// that that should occur after view rendering.
|
||||
var queues = Ember.run.queues;
|
||||
queues.splice(Ember.$.inArray('actions', queues)+1, 0, 'render', 'afterRender');
|
||||
var queues = Ember.run.queues,
|
||||
indexOf = Ember.ArrayPolyfills.indexOf;
|
||||
queues.splice(indexOf.call(queues, 'actions')+1, 0, 'render', 'afterRender');
|
||||
|
||||
})();
|
||||
|
||||
|
@ -15706,17 +15727,24 @@ Ember.View = Ember.CoreView.extend(
|
|||
// once the view has been inserted into the DOM, legal manipulations
|
||||
// are done on the DOM element.
|
||||
|
||||
function notifyMutationListeners() {
|
||||
Ember.run.once(Ember.View, 'notifyMutationListeners');
|
||||
}
|
||||
|
||||
var DOMManager = {
|
||||
prepend: function(view, html) {
|
||||
view.$().prepend(html);
|
||||
notifyMutationListeners();
|
||||
},
|
||||
|
||||
after: function(view, html) {
|
||||
view.$().after(html);
|
||||
notifyMutationListeners();
|
||||
},
|
||||
|
||||
html: function(view, html) {
|
||||
view.$().html(html);
|
||||
notifyMutationListeners();
|
||||
},
|
||||
|
||||
replace: function(view) {
|
||||
|
@ -15726,15 +15754,18 @@ var DOMManager = {
|
|||
|
||||
view._insertElementLater(function() {
|
||||
Ember.$(element).replaceWith(get(view, 'element'));
|
||||
notifyMutationListeners();
|
||||
});
|
||||
},
|
||||
|
||||
remove: function(view) {
|
||||
view.$().remove();
|
||||
notifyMutationListeners();
|
||||
},
|
||||
|
||||
empty: function(view) {
|
||||
view.$().empty();
|
||||
notifyMutationListeners();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -15849,6 +15880,20 @@ Ember.View.reopenClass({
|
|||
}
|
||||
});
|
||||
|
||||
var mutation = Ember.Object.extend(Ember.Evented).create();
|
||||
|
||||
Ember.View.addMutationListener = function(callback) {
|
||||
mutation.on('change', callback);
|
||||
};
|
||||
|
||||
Ember.View.removeMutationListener = function(callback) {
|
||||
mutation.off('change', callback);
|
||||
};
|
||||
|
||||
Ember.View.notifyMutationListeners = function() {
|
||||
mutation.trigger('change');
|
||||
};
|
||||
|
||||
/**
|
||||
Global views hash
|
||||
|
||||
|
@ -17008,15 +17053,15 @@ define("metamorph",
|
|||
|
||||
var K = function(){},
|
||||
guid = 0,
|
||||
document = window.document,
|
||||
document = this.document,
|
||||
|
||||
// Feature-detect the W3C range API, the extended check is for IE9 which only partially supports ranges
|
||||
supportsRange = ('createRange' in document) && (typeof Range !== 'undefined') && Range.prototype.createContextualFragment,
|
||||
supportsRange = document && ('createRange' in document) && (typeof Range !== 'undefined') && Range.prototype.createContextualFragment,
|
||||
|
||||
// Internet Explorer prior to 9 does not allow setting innerHTML if the first element
|
||||
// is a "zero-scope" element. This problem can be worked around by making
|
||||
// the first node an invisible text node. We, like Modernizr, use ­
|
||||
needsShy = (function(){
|
||||
needsShy = document && (function(){
|
||||
var testEl = document.createElement('div');
|
||||
testEl.innerHTML = "<div></div>";
|
||||
testEl.firstChild.innerHTML = "<script></script>";
|
||||
|
@ -17027,7 +17072,7 @@ define("metamorph",
|
|||
// IE 8 (and likely earlier) likes to move whitespace preceeding
|
||||
// a script tag to appear after it. This means that we can
|
||||
// accidentally remove whitespace when updating a morph.
|
||||
movesWhitespace = (function() {
|
||||
movesWhitespace = document && (function() {
|
||||
var testEl = document.createElement('div');
|
||||
testEl.innerHTML = "Test: <script type='text/x-placeholder'></script>Value";
|
||||
return testEl.childNodes[0].nodeValue === 'Test:' &&
|
||||
|
@ -17471,7 +17516,11 @@ var objectCreate = Object.create || function(parent) {
|
|||
return new F();
|
||||
};
|
||||
|
||||
var Handlebars = this.Handlebars || Ember.imports.Handlebars;
|
||||
var Handlebars = this.Handlebars || (Ember.imports && Ember.imports.Handlebars);
|
||||
if(!Handlebars && typeof require === 'function') {
|
||||
Handlebars = require('handlebars');
|
||||
}
|
||||
|
||||
Ember.assert("Ember Handlebars requires Handlebars 1.0.0-rc.3 or greater", Handlebars && Handlebars.VERSION.match(/^1\.0\.[0-9](\.rc\.[23456789]+)?/));
|
||||
|
||||
/**
|
||||
|
@ -18131,22 +18180,30 @@ Ember.Handlebars.resolvePaths = function(options) {
|
|||
var set = Ember.set, get = Ember.get;
|
||||
var Metamorph = requireModule('metamorph');
|
||||
|
||||
function notifyMutationListeners() {
|
||||
Ember.run.once(Ember.View, 'notifyMutationListeners');
|
||||
}
|
||||
|
||||
// DOMManager should just abstract dom manipulation between jquery and metamorph
|
||||
var DOMManager = {
|
||||
remove: function(view) {
|
||||
view.morph.remove();
|
||||
notifyMutationListeners();
|
||||
},
|
||||
|
||||
prepend: function(view, html) {
|
||||
view.morph.prepend(html);
|
||||
notifyMutationListeners();
|
||||
},
|
||||
|
||||
after: function(view, html) {
|
||||
view.morph.after(html);
|
||||
notifyMutationListeners();
|
||||
},
|
||||
|
||||
html: function(view, html) {
|
||||
view.morph.html(html);
|
||||
notifyMutationListeners();
|
||||
},
|
||||
|
||||
// This is messed up.
|
||||
|
@ -18169,11 +18226,13 @@ var DOMManager = {
|
|||
morph.replaceWith(buffer.string());
|
||||
view.transitionTo('inDOM');
|
||||
view.triggerRecursively('didInsertElement');
|
||||
notifyMutationListeners();
|
||||
});
|
||||
},
|
||||
|
||||
empty: function(view) {
|
||||
view.morph.html("");
|
||||
notifyMutationListeners();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -23555,6 +23614,34 @@ function teardownView(route) {
|
|||
|
||||
|
||||
|
||||
(function() {
|
||||
Ember.onLoad('Ember.Handlebars', function() {
|
||||
var handlebarsResolve = Ember.Handlebars.resolveParams,
|
||||
map = Ember.ArrayPolyfills.map,
|
||||
get = Ember.get;
|
||||
|
||||
function resolveParams(context, params, options) {
|
||||
var resolved = handlebarsResolve(context, params, options);
|
||||
return map.call(resolved, unwrap);
|
||||
|
||||
function unwrap(object, i) {
|
||||
if (params[i] === 'controller') { return object; }
|
||||
|
||||
if (Ember.ControllerMixin.detect(object)) {
|
||||
return unwrap(get(object, 'model'));
|
||||
} else {
|
||||
return object;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ember.Router.resolveParams = resolveParams;
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
|
||||
|
||||
(function() {
|
||||
/**
|
||||
@module ember
|
||||
|
@ -23564,7 +23651,7 @@ function teardownView(route) {
|
|||
var get = Ember.get, set = Ember.set;
|
||||
Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
||||
|
||||
var resolveParams = Ember.Handlebars.resolveParams,
|
||||
var resolveParams = Ember.Router.resolveParams,
|
||||
isSimpleClick = Ember.ViewUtils.isSimpleClick;
|
||||
|
||||
function fullRouteName(router, name) {
|
||||
|
@ -23847,7 +23934,7 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
|||
*/
|
||||
Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
||||
|
||||
var resolveParams = Ember.Handlebars.resolveParams,
|
||||
var resolveParams = Ember.Router.resolveParams,
|
||||
isSimpleClick = Ember.ViewUtils.isSimpleClick;
|
||||
|
||||
var EmberHandlebars = Ember.Handlebars,
|
||||
|
@ -24473,7 +24560,7 @@ Ember.HashLocation = Ember.Object.extend({
|
|||
|
||||
set(self, 'lastSetURL', null);
|
||||
|
||||
callback(location.hash.substr(1));
|
||||
callback(path);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
@ -24856,6 +24943,9 @@ var get = Ember.get, set = Ember.set,
|
|||
method. When you are ready for your app to be initialized, call its
|
||||
`advanceReadiness()` method.
|
||||
|
||||
You can define a `ready` method on the `Ember.Application` instance, which
|
||||
will be run by Ember when the application is initialized.
|
||||
|
||||
Because `Ember.Application` inherits from `Ember.Namespace`, any classes
|
||||
you create will have useful string representations when calling `toString()`.
|
||||
See the `Ember.Namespace` documentation for more information.
|
||||
|
@ -25050,11 +25140,13 @@ var Application = Ember.Application = Ember.Namespace.extend({
|
|||
this.scheduleInitialize();
|
||||
}
|
||||
|
||||
if ( Ember.LOG_VERSION ) {
|
||||
Ember.debug('-------------------------------');
|
||||
Ember.debug('Ember.VERSION : ' + Ember.VERSION);
|
||||
Ember.debug('Handlebars.VERSION : ' + Ember.Handlebars.VERSION);
|
||||
Ember.debug('jQuery.VERSION : ' + Ember.$().jquery);
|
||||
Ember.debug('-------------------------------');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -25414,6 +25506,7 @@ Ember.Application.reopenClass({
|
|||
Ember.Container.defaultContainer = Ember.Container.defaultContainer || container;
|
||||
|
||||
container.set = Ember.set;
|
||||
container.normalize = normalize;
|
||||
container.resolver = resolverFor(namespace);
|
||||
container.optionsForType('view', { singleton: false });
|
||||
container.optionsForType('template', { instantiate: false });
|
||||
|
@ -25453,6 +25546,7 @@ function resolverFor(namespace) {
|
|||
|
||||
if (type === 'template') {
|
||||
var templateName = name.replace(/\./g, '/');
|
||||
|
||||
if (Ember.TEMPLATES[templateName]) {
|
||||
return Ember.TEMPLATES[templateName];
|
||||
}
|
||||
|
@ -25483,9 +25577,31 @@ function resolverFor(namespace) {
|
|||
};
|
||||
}
|
||||
|
||||
Ember.runLoadHooks('Ember.Application', Ember.Application);
|
||||
function normalize(fullName) {
|
||||
var split = fullName.split(':'),
|
||||
type = split[0],
|
||||
name = split[1];
|
||||
|
||||
|
||||
if (type !== 'template') {
|
||||
var result = name;
|
||||
|
||||
if (result.indexOf('.') > -1) {
|
||||
result = result.replace(/\.(.)/g, function(m) { return m[1].toUpperCase(); });
|
||||
}
|
||||
|
||||
if (name.indexOf('_') > -1) {
|
||||
result = result.replace(/_(.)/g, function(m) { return m[1].toUpperCase(); });
|
||||
}
|
||||
|
||||
return type + ':' + result;
|
||||
} else {
|
||||
return fullName;
|
||||
}
|
||||
}
|
||||
|
||||
Ember.runLoadHooks('Ember.Application', Ember.Application);
|
||||
|
||||
})();
|
||||
|
||||
|
||||
|
@ -26831,8 +26947,8 @@ Ember States
|
|||
|
||||
|
||||
})();
|
||||
// Version: v1.0.0-pre.2-723-g052062c
|
||||
// Last commit: 052062c (2013-02-18 19:32:17 -0800)
|
||||
// Version: v1.0.0-pre.2-756-gb26f1f0
|
||||
// Last commit: b26f1f0 (2013-02-26 09:03:26 -0800)
|
||||
|
||||
|
||||
(function() {
|
||||
|
|
|
@ -141,6 +141,15 @@ Ember.LOG_STACKTRACE_ON_DEPRECATION = (Ember.ENV.LOG_STACKTRACE_ON_DEPRECATION !
|
|||
*/
|
||||
Ember.SHIM_ES5 = (Ember.ENV.SHIM_ES5 === false) ? false : Ember.EXTEND_PROTOTYPES;
|
||||
|
||||
/**
|
||||
Determines whether Ember logs info about version of used libraries
|
||||
|
||||
@property LOG_VERSION
|
||||
@type Boolean
|
||||
@default true
|
||||
*/
|
||||
Ember.LOG_VERSION = (Ember.ENV.LOG_VERSION === false) ? false : true;
|
||||
|
||||
/**
|
||||
Empty function. Useful for some operations.
|
||||
|
||||
|
@ -5963,7 +5972,6 @@ define("container",
|
|||
register: function(type, name, factory, options) {
|
||||
var fullName;
|
||||
|
||||
|
||||
if (type.indexOf(':') !== -1){
|
||||
options = factory;
|
||||
factory = name;
|
||||
|
@ -5973,15 +5981,23 @@ define("container",
|
|||
fullName = type + ":" + name;
|
||||
}
|
||||
|
||||
this.registry.set(fullName, factory);
|
||||
this._options.set(fullName, options || {});
|
||||
var normalizedName = this.normalize(fullName);
|
||||
|
||||
this.registry.set(normalizedName, factory);
|
||||
this._options.set(normalizedName, options || {});
|
||||
},
|
||||
|
||||
resolve: function(fullName) {
|
||||
return this.resolver(fullName) || this.registry.get(fullName);
|
||||
},
|
||||
|
||||
normalize: function(fullName) {
|
||||
return fullName;
|
||||
},
|
||||
|
||||
lookup: function(fullName, options) {
|
||||
fullName = this.normalize(fullName);
|
||||
|
||||
options = options || {};
|
||||
|
||||
if (this.cache.has(fullName) && options.singleton !== false) {
|
||||
|
@ -6110,7 +6126,8 @@ define("container",
|
|||
}
|
||||
|
||||
function factoryFor(container, fullName) {
|
||||
return container.resolve(fullName);
|
||||
var name = container.normalize(fullName);
|
||||
return container.resolve(name);
|
||||
}
|
||||
|
||||
function instantiate(container, fullName) {
|
||||
|
@ -6584,6 +6601,20 @@ Ember.Error.prototype = Ember.create(Error.prototype);
|
|||
|
||||
|
||||
|
||||
(function() {
|
||||
/**
|
||||
Expose RSVP implementation
|
||||
|
||||
@class RSVP
|
||||
@namespace Ember
|
||||
@constructor
|
||||
*/
|
||||
Ember.RSVP = requireModule('rsvp');
|
||||
|
||||
})();
|
||||
|
||||
|
||||
|
||||
(function() {
|
||||
/**
|
||||
@module ember
|
||||
|
@ -10962,40 +10993,8 @@ Ember.Mixin.prototype.toString = classToString;
|
|||
|
||||
|
||||
(function() {
|
||||
/**
|
||||
@module ember
|
||||
@submodule ember-runtime
|
||||
*/
|
||||
|
||||
/**
|
||||
Defines a namespace that will contain an executable application. This is
|
||||
very similar to a normal namespace except that it is expected to include at
|
||||
least a 'ready' function which can be run to initialize the application.
|
||||
|
||||
Currently `Ember.Application` is very similar to `Ember.Namespace.` However,
|
||||
this class may be augmented by additional frameworks so it is important to
|
||||
use this instance when building new applications.
|
||||
|
||||
# Example Usage
|
||||
|
||||
```javascript
|
||||
MyApp = Ember.Application.create({
|
||||
VERSION: '1.0.0',
|
||||
store: Ember.Store.create().from(Ember.fixtures)
|
||||
});
|
||||
|
||||
MyApp.ready = function() {
|
||||
//..init code goes here...
|
||||
}
|
||||
```
|
||||
|
||||
@class Application
|
||||
@namespace Ember
|
||||
@extends Ember.Namespace
|
||||
*/
|
||||
Ember.Application = Ember.Namespace.extend();
|
||||
|
||||
|
||||
})();
|
||||
|
||||
|
||||
|
@ -11379,6 +11378,25 @@ Ember.ObjectProxy = Ember.Object.extend(
|
|||
}
|
||||
});
|
||||
|
||||
Ember.ObjectProxy.reopenClass({
|
||||
create: function () {
|
||||
var mixin, prototype, i, l, properties, keyName;
|
||||
if (arguments.length) {
|
||||
prototype = this.proto();
|
||||
for (i = 0, l = arguments.length; i < l; i++) {
|
||||
properties = arguments[i];
|
||||
for (keyName in properties) {
|
||||
if (!properties.hasOwnProperty(keyName) || keyName in prototype) { continue; }
|
||||
if (!mixin) mixin = {};
|
||||
mixin[keyName] = null;
|
||||
}
|
||||
}
|
||||
if (mixin) this._initMixins([mixin]);
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
|
||||
|
@ -11699,7 +11717,7 @@ if (ignore.length>0) {
|
|||
/**
|
||||
The NativeArray mixin contains the properties needed to to make the native
|
||||
Array support Ember.MutableArray and all of its dependent APIs. Unless you
|
||||
have `Ember.EXTEND_PROTOTYPES or `Ember.EXTEND_PROTOTYPES.Array` set to
|
||||
have `Ember.EXTEND_PROTOTYPES` or `Ember.EXTEND_PROTOTYPES.Array` set to
|
||||
false, this will be applied automatically. Otherwise you can apply the mixin
|
||||
at anytime by calling `Ember.NativeArray.activate`.
|
||||
|
||||
|
@ -12274,7 +12292,8 @@ Ember.ArrayController = Ember.ArrayProxy.extend(Ember.ControllerMixin,
|
|||
|
||||
objectAtContent: function(idx) {
|
||||
var length = get(this, 'length'),
|
||||
object = get(this,'arrangedContent').objectAt(idx);
|
||||
arrangedContent = get(this,'arrangedContent'),
|
||||
object = arrangedContent && arrangedContent.objectAt(idx);
|
||||
|
||||
if (idx >= 0 && idx < length) {
|
||||
var controllerClass = this.lookupItemController(object);
|
||||
|
@ -12425,15 +12444,16 @@ Ember.$ = jQuery;
|
|||
@module ember
|
||||
@submodule ember-views
|
||||
*/
|
||||
if (Ember.$) {
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dndevents
|
||||
var dragEvents = Ember.String.w('dragstart drag dragenter dragleave dragover drop dragend');
|
||||
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dndevents
|
||||
var dragEvents = Ember.String.w('dragstart drag dragenter dragleave dragover drop dragend');
|
||||
|
||||
// Copies the `dataTransfer` property from a browser event object onto the
|
||||
// jQuery event object for the specified events
|
||||
Ember.EnumerableUtils.forEach(dragEvents, function(eventName) {
|
||||
// Copies the `dataTransfer` property from a browser event object onto the
|
||||
// jQuery event object for the specified events
|
||||
Ember.EnumerableUtils.forEach(dragEvents, function(eventName) {
|
||||
Ember.$.event.fixHooks[eventName] = { props: ['dataTransfer'] };
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
})();
|
||||
|
||||
|
@ -12450,7 +12470,8 @@ Ember.EnumerableUtils.forEach(dragEvents, function(eventName) {
|
|||
// Internet Explorer prior to 9 does not allow setting innerHTML if the first element
|
||||
// is a "zero-scope" element. This problem can be worked around by making
|
||||
// the first node an invisible text node. We, like Modernizr, use ­
|
||||
var needsShy = (function(){
|
||||
|
||||
var needsShy = this.document && (function(){
|
||||
var testEl = document.createElement('div');
|
||||
testEl.innerHTML = "<div></div>";
|
||||
testEl.firstChild.innerHTML = "<script></script>";
|
||||
|
@ -12460,7 +12481,7 @@ var needsShy = (function(){
|
|||
// IE 8 (and likely earlier) likes to move whitespace preceeding
|
||||
// a script tag to appear after it. This means that we can
|
||||
// accidentally remove whitespace when updating a morph.
|
||||
var movesWhitespace = (function() {
|
||||
var movesWhitespace = this.document && (function() {
|
||||
var testEl = document.createElement('div');
|
||||
testEl.innerHTML = "Test: <script type='text/x-placeholder'></script>Value";
|
||||
return testEl.childNodes[0].nodeValue === 'Test:' &&
|
||||
|
@ -13131,7 +13152,7 @@ Ember.EventDispatcher = Ember.Object.extend(
|
|||
setup: function(addedEvents) {
|
||||
var event, events = {
|
||||
touchstart : 'touchStart',
|
||||
// touchmove : 'touchMove',
|
||||
touchmove : 'touchMove',
|
||||
touchend : 'touchEnd',
|
||||
touchcancel : 'touchCancel',
|
||||
keydown : 'keyDown',
|
||||
|
@ -13142,7 +13163,7 @@ Ember.EventDispatcher = Ember.Object.extend(
|
|||
contextmenu : 'contextMenu',
|
||||
click : 'click',
|
||||
dblclick : 'doubleClick',
|
||||
// mousemove : 'mouseMove',
|
||||
mousemove : 'mouseMove',
|
||||
focusin : 'focusIn',
|
||||
focusout : 'focusOut',
|
||||
mouseenter : 'mouseEnter',
|
||||
|
@ -13290,8 +13311,9 @@ Ember.EventDispatcher = Ember.Object.extend(
|
|||
// Add a new named queue for rendering views that happens
|
||||
// after bindings have synced, and a queue for scheduling actions
|
||||
// that that should occur after view rendering.
|
||||
var queues = Ember.run.queues;
|
||||
queues.splice(Ember.$.inArray('actions', queues)+1, 0, 'render', 'afterRender');
|
||||
var queues = Ember.run.queues,
|
||||
indexOf = Ember.ArrayPolyfills.indexOf;
|
||||
queues.splice(indexOf.call(queues, 'actions')+1, 0, 'render', 'afterRender');
|
||||
|
||||
})();
|
||||
|
||||
|
@ -15530,17 +15552,24 @@ Ember.View = Ember.CoreView.extend(
|
|||
// once the view has been inserted into the DOM, legal manipulations
|
||||
// are done on the DOM element.
|
||||
|
||||
function notifyMutationListeners() {
|
||||
Ember.run.once(Ember.View, 'notifyMutationListeners');
|
||||
}
|
||||
|
||||
var DOMManager = {
|
||||
prepend: function(view, html) {
|
||||
view.$().prepend(html);
|
||||
notifyMutationListeners();
|
||||
},
|
||||
|
||||
after: function(view, html) {
|
||||
view.$().after(html);
|
||||
notifyMutationListeners();
|
||||
},
|
||||
|
||||
html: function(view, html) {
|
||||
view.$().html(html);
|
||||
notifyMutationListeners();
|
||||
},
|
||||
|
||||
replace: function(view) {
|
||||
|
@ -15550,15 +15579,18 @@ var DOMManager = {
|
|||
|
||||
view._insertElementLater(function() {
|
||||
Ember.$(element).replaceWith(get(view, 'element'));
|
||||
notifyMutationListeners();
|
||||
});
|
||||
},
|
||||
|
||||
remove: function(view) {
|
||||
view.$().remove();
|
||||
notifyMutationListeners();
|
||||
},
|
||||
|
||||
empty: function(view) {
|
||||
view.$().empty();
|
||||
notifyMutationListeners();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -15673,6 +15705,20 @@ Ember.View.reopenClass({
|
|||
}
|
||||
});
|
||||
|
||||
var mutation = Ember.Object.extend(Ember.Evented).create();
|
||||
|
||||
Ember.View.addMutationListener = function(callback) {
|
||||
mutation.on('change', callback);
|
||||
};
|
||||
|
||||
Ember.View.removeMutationListener = function(callback) {
|
||||
mutation.off('change', callback);
|
||||
};
|
||||
|
||||
Ember.View.notifyMutationListeners = function() {
|
||||
mutation.trigger('change');
|
||||
};
|
||||
|
||||
/**
|
||||
Global views hash
|
||||
|
||||
|
@ -16831,15 +16877,15 @@ define("metamorph",
|
|||
|
||||
var K = function(){},
|
||||
guid = 0,
|
||||
document = window.document,
|
||||
document = this.document,
|
||||
|
||||
// Feature-detect the W3C range API, the extended check is for IE9 which only partially supports ranges
|
||||
supportsRange = ('createRange' in document) && (typeof Range !== 'undefined') && Range.prototype.createContextualFragment,
|
||||
supportsRange = document && ('createRange' in document) && (typeof Range !== 'undefined') && Range.prototype.createContextualFragment,
|
||||
|
||||
// Internet Explorer prior to 9 does not allow setting innerHTML if the first element
|
||||
// is a "zero-scope" element. This problem can be worked around by making
|
||||
// the first node an invisible text node. We, like Modernizr, use ­
|
||||
needsShy = (function(){
|
||||
needsShy = document && (function(){
|
||||
var testEl = document.createElement('div');
|
||||
testEl.innerHTML = "<div></div>";
|
||||
testEl.firstChild.innerHTML = "<script></script>";
|
||||
|
@ -16850,7 +16896,7 @@ define("metamorph",
|
|||
// IE 8 (and likely earlier) likes to move whitespace preceeding
|
||||
// a script tag to appear after it. This means that we can
|
||||
// accidentally remove whitespace when updating a morph.
|
||||
movesWhitespace = (function() {
|
||||
movesWhitespace = document && (function() {
|
||||
var testEl = document.createElement('div');
|
||||
testEl.innerHTML = "Test: <script type='text/x-placeholder'></script>Value";
|
||||
return testEl.childNodes[0].nodeValue === 'Test:' &&
|
||||
|
@ -17294,7 +17340,10 @@ var objectCreate = Object.create || function(parent) {
|
|||
return new F();
|
||||
};
|
||||
|
||||
var Handlebars = this.Handlebars || Ember.imports.Handlebars;
|
||||
var Handlebars = this.Handlebars || (Ember.imports && Ember.imports.Handlebars);
|
||||
if(!Handlebars && typeof require === 'function') {
|
||||
Handlebars = require('handlebars');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -17953,22 +18002,30 @@ Ember.Handlebars.resolvePaths = function(options) {
|
|||
var set = Ember.set, get = Ember.get;
|
||||
var Metamorph = requireModule('metamorph');
|
||||
|
||||
function notifyMutationListeners() {
|
||||
Ember.run.once(Ember.View, 'notifyMutationListeners');
|
||||
}
|
||||
|
||||
// DOMManager should just abstract dom manipulation between jquery and metamorph
|
||||
var DOMManager = {
|
||||
remove: function(view) {
|
||||
view.morph.remove();
|
||||
notifyMutationListeners();
|
||||
},
|
||||
|
||||
prepend: function(view, html) {
|
||||
view.morph.prepend(html);
|
||||
notifyMutationListeners();
|
||||
},
|
||||
|
||||
after: function(view, html) {
|
||||
view.morph.after(html);
|
||||
notifyMutationListeners();
|
||||
},
|
||||
|
||||
html: function(view, html) {
|
||||
view.morph.html(html);
|
||||
notifyMutationListeners();
|
||||
},
|
||||
|
||||
// This is messed up.
|
||||
|
@ -17991,11 +18048,13 @@ var DOMManager = {
|
|||
morph.replaceWith(buffer.string());
|
||||
view.transitionTo('inDOM');
|
||||
view.triggerRecursively('didInsertElement');
|
||||
notifyMutationListeners();
|
||||
});
|
||||
},
|
||||
|
||||
empty: function(view) {
|
||||
view.morph.html("");
|
||||
notifyMutationListeners();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -23362,6 +23421,34 @@ function teardownView(route) {
|
|||
|
||||
|
||||
|
||||
(function() {
|
||||
Ember.onLoad('Ember.Handlebars', function() {
|
||||
var handlebarsResolve = Ember.Handlebars.resolveParams,
|
||||
map = Ember.ArrayPolyfills.map,
|
||||
get = Ember.get;
|
||||
|
||||
function resolveParams(context, params, options) {
|
||||
var resolved = handlebarsResolve(context, params, options);
|
||||
return map.call(resolved, unwrap);
|
||||
|
||||
function unwrap(object, i) {
|
||||
if (params[i] === 'controller') { return object; }
|
||||
|
||||
if (Ember.ControllerMixin.detect(object)) {
|
||||
return unwrap(get(object, 'model'));
|
||||
} else {
|
||||
return object;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ember.Router.resolveParams = resolveParams;
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
|
||||
|
||||
(function() {
|
||||
/**
|
||||
@module ember
|
||||
|
@ -23371,7 +23458,7 @@ function teardownView(route) {
|
|||
var get = Ember.get, set = Ember.set;
|
||||
Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
||||
|
||||
var resolveParams = Ember.Handlebars.resolveParams,
|
||||
var resolveParams = Ember.Router.resolveParams,
|
||||
isSimpleClick = Ember.ViewUtils.isSimpleClick;
|
||||
|
||||
function fullRouteName(router, name) {
|
||||
|
@ -23652,7 +23739,7 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
|||
*/
|
||||
Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
||||
|
||||
var resolveParams = Ember.Handlebars.resolveParams,
|
||||
var resolveParams = Ember.Router.resolveParams,
|
||||
isSimpleClick = Ember.ViewUtils.isSimpleClick;
|
||||
|
||||
var EmberHandlebars = Ember.Handlebars,
|
||||
|
@ -24277,7 +24364,7 @@ Ember.HashLocation = Ember.Object.extend({
|
|||
|
||||
set(self, 'lastSetURL', null);
|
||||
|
||||
callback(location.hash.substr(1));
|
||||
callback(path);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
@ -24660,6 +24747,9 @@ var get = Ember.get, set = Ember.set,
|
|||
method. When you are ready for your app to be initialized, call its
|
||||
`advanceReadiness()` method.
|
||||
|
||||
You can define a `ready` method on the `Ember.Application` instance, which
|
||||
will be run by Ember when the application is initialized.
|
||||
|
||||
Because `Ember.Application` inherits from `Ember.Namespace`, any classes
|
||||
you create will have useful string representations when calling `toString()`.
|
||||
See the `Ember.Namespace` documentation for more information.
|
||||
|
@ -24854,10 +24944,13 @@ var Application = Ember.Application = Ember.Namespace.extend({
|
|||
this.scheduleInitialize();
|
||||
}
|
||||
|
||||
if ( Ember.LOG_VERSION ) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -25216,6 +25309,7 @@ Ember.Application.reopenClass({
|
|||
Ember.Container.defaultContainer = Ember.Container.defaultContainer || container;
|
||||
|
||||
container.set = Ember.set;
|
||||
container.normalize = normalize;
|
||||
container.resolver = resolverFor(namespace);
|
||||
container.optionsForType('view', { singleton: false });
|
||||
container.optionsForType('template', { instantiate: false });
|
||||
|
@ -25255,6 +25349,7 @@ function resolverFor(namespace) {
|
|||
|
||||
if (type === 'template') {
|
||||
var templateName = name.replace(/\./g, '/');
|
||||
|
||||
if (Ember.TEMPLATES[templateName]) {
|
||||
return Ember.TEMPLATES[templateName];
|
||||
}
|
||||
|
@ -25284,9 +25379,31 @@ function resolverFor(namespace) {
|
|||
};
|
||||
}
|
||||
|
||||
Ember.runLoadHooks('Ember.Application', Ember.Application);
|
||||
function normalize(fullName) {
|
||||
var split = fullName.split(':'),
|
||||
type = split[0],
|
||||
name = split[1];
|
||||
|
||||
|
||||
if (type !== 'template') {
|
||||
var result = name;
|
||||
|
||||
if (result.indexOf('.') > -1) {
|
||||
result = result.replace(/\.(.)/g, function(m) { return m[1].toUpperCase(); });
|
||||
}
|
||||
|
||||
if (name.indexOf('_') > -1) {
|
||||
result = result.replace(/_(.)/g, function(m) { return m[1].toUpperCase(); });
|
||||
}
|
||||
|
||||
return type + ':' + result;
|
||||
} else {
|
||||
return fullName;
|
||||
}
|
||||
}
|
||||
|
||||
Ember.runLoadHooks('Ember.Application', Ember.Application);
|
||||
|
||||
})();
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue