Clean up discourse.js
This commit is contained in:
parent
b9ccf4d09c
commit
1caf1e6b45
21 changed files with 818 additions and 537 deletions
app/assets/javascripts
admin/routes
discourse.jsdiscourse
components
controllers
models
routes
templates
views
external
external_production
|
@ -4,7 +4,7 @@
|
||||||
@method buildRoutes
|
@method buildRoutes
|
||||||
@for Discourse.AdminRoute
|
@for Discourse.AdminRoute
|
||||||
**/
|
**/
|
||||||
Discourse.buildRoutes(function() {
|
Discourse.Route.buildRoutes(function() {
|
||||||
this.resource('admin', { path: '/admin' }, function() {
|
this.resource('admin', { path: '/admin' }, function() {
|
||||||
this.route('dashboard', { path: '/' });
|
this.route('dashboard', { path: '/' });
|
||||||
this.route('site_settings', { path: '/site_settings' });
|
this.route('site_settings', { path: '/site_settings' });
|
||||||
|
|
|
@ -1,31 +1,28 @@
|
||||||
/*global Modernizr:true*/
|
/*global Modernizr:true*/
|
||||||
/*global assetPath:true*/
|
/*global assetPath:true*/
|
||||||
|
|
||||||
var csrf_token;
|
/**
|
||||||
|
The main Discourse Application
|
||||||
|
|
||||||
|
@class Discourse
|
||||||
|
@extends Ember.Application
|
||||||
|
**/
|
||||||
Discourse = Ember.Application.createWithMixins({
|
Discourse = Ember.Application.createWithMixins({
|
||||||
rootElement: '#main',
|
rootElement: '#main',
|
||||||
|
|
||||||
// Data we want to remember for a short period
|
// Data we want to remember for a short period
|
||||||
transient: Em.Object.create(),
|
transient: Em.Object.create(),
|
||||||
|
|
||||||
|
// Whether the app has focus or not
|
||||||
hasFocus: true,
|
hasFocus: true,
|
||||||
|
|
||||||
|
// Are we currently scrolling?
|
||||||
scrolling: false,
|
scrolling: false,
|
||||||
|
|
||||||
// The highest seen post number by topic
|
// The highest seen post number by topic
|
||||||
highestSeenByTopic: {},
|
highestSeenByTopic: {},
|
||||||
|
|
||||||
logoSmall: (function() {
|
titleChanged: 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() {
|
|
||||||
var title;
|
var title;
|
||||||
title = "";
|
title = "";
|
||||||
if (this.get('title')) {
|
if (this.get('title')) {
|
||||||
|
@ -37,51 +34,45 @@ Discourse = Ember.Application.createWithMixins({
|
||||||
title = "(*) " + title;
|
title = "(*) " + title;
|
||||||
}
|
}
|
||||||
// chrome bug workaround see: http://stackoverflow.com/questions/2952384/changing-the-window-title-when-focussing-the-window-doesnt-work-in-chrome
|
// 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 = ".";
|
||||||
document.title = title;
|
document.title = title;
|
||||||
}), 200);
|
}, 200);
|
||||||
}).observes('title', 'hasFocus', 'notify'),
|
}.observes('title', 'hasFocus', 'notify'),
|
||||||
|
|
||||||
currentUserChanged: (function() {
|
currentUserChanged: function() {
|
||||||
var bus, user;
|
|
||||||
bus = Discourse.MessageBus;
|
|
||||||
|
|
||||||
// We don't want to receive any previous user notifications
|
// We don't want to receive any previous user notifications
|
||||||
|
var bus = Discourse.MessageBus;
|
||||||
bus.unsubscribe("/notification/*");
|
bus.unsubscribe("/notification/*");
|
||||||
bus.callbackInterval = Discourse.SiteSettings.anon_polling_interval;
|
bus.callbackInterval = Discourse.SiteSettings.anon_polling_interval;
|
||||||
bus.enableLongPolling = false;
|
bus.enableLongPolling = false;
|
||||||
user = this.get('currentUser');
|
|
||||||
|
var user = this.get('currentUser');
|
||||||
if (user) {
|
if (user) {
|
||||||
bus.callbackInterval = Discourse.SiteSettings.polling_interval;
|
bus.callbackInterval = Discourse.SiteSettings.polling_interval;
|
||||||
bus.enableLongPolling = true;
|
bus.enableLongPolling = true;
|
||||||
if (user.admin) {
|
if (user.admin) {
|
||||||
bus.subscribe("/flagged_counts", function(data) {
|
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);
|
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);
|
}), user.notification_channel_position);
|
||||||
}
|
}
|
||||||
}).observes('currentUser'),
|
}.observes('currentUser'),
|
||||||
notifyTitle: function() {
|
|
||||||
return this.set('notify', true);
|
|
||||||
},
|
|
||||||
|
|
||||||
// Browser aware replaceState
|
// The classes of buttons to show on a post
|
||||||
replaceState: function(path) {
|
postButtons: function() {
|
||||||
if (window.history &&
|
return Discourse.SiteSettings.post_menu.split("|").map(function(i) {
|
||||||
window.history.pushState &&
|
return (i.replace(/\+/, '').capitalize());
|
||||||
window.history.replaceState &&
|
});
|
||||||
!navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]|WebApps\/.+CFNetwork)/)) {
|
}.property('Discourse.SiteSettings.post_menu'),
|
||||||
if (window.location.pathname !== path) {
|
|
||||||
return history.replaceState({
|
notifyTitle: function() {
|
||||||
path: path
|
this.set('notify', true);
|
||||||
}, null, path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
openComposer: function(opts) {
|
openComposer: function(opts) {
|
||||||
|
@ -90,291 +81,108 @@ Discourse = Ember.Application.createWithMixins({
|
||||||
if (composer) composer.open(opts);
|
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.
|
Establishes global DOM events and bindings via jQuery.
|
||||||
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'),
|
|
||||||
|
|
||||||
|
@method bindDOMEvents
|
||||||
|
**/
|
||||||
bindDOMEvents: function() {
|
bindDOMEvents: function() {
|
||||||
var $html, hasTouch,
|
var $html, hasTouch;
|
||||||
_this = this;
|
|
||||||
$html = $('html');
|
|
||||||
|
|
||||||
/* Add the discourse touch event */
|
$html = $('html');
|
||||||
hasTouch = false;
|
hasTouch = false;
|
||||||
|
|
||||||
if ($html.hasClass('touch')) {
|
if ($html.hasClass('touch')) {
|
||||||
hasTouch = true;
|
hasTouch = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Modernizr.prefixed("MaxTouchPoints", navigator) > 1) {
|
if (Modernizr.prefixed("MaxTouchPoints", navigator) > 1) {
|
||||||
hasTouch = true;
|
hasTouch = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasTouch) {
|
if (hasTouch) {
|
||||||
$html.addClass('discourse-touch');
|
$html.addClass('discourse-touch');
|
||||||
this.touch = true;
|
this.touch = true;
|
||||||
this.hasTouch = true;
|
this.hasTouch = true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$html.addClass('discourse-no-touch');
|
$html.addClass('discourse-no-touch');
|
||||||
this.touch = false;
|
this.touch = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#main').on('click.discourse', '[data-not-implemented=true]', function(e) {
|
$('#main').on('click.discourse', '[data-not-implemented=true]', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
alert(Em.String.i18n('not_implemented'));
|
alert(Em.String.i18n('not_implemented'));
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#main').on('click.discourse', 'a', function(e) {
|
$('#main').on('click.discourse', 'a', function(e) {
|
||||||
var $currentTarget, href;
|
if (e.isDefaultPrevented() || e.metaKey || e.ctrlKey) return;
|
||||||
if (e.isDefaultPrevented() || e.metaKey || e.ctrlKey) {
|
|
||||||
return;
|
var $currentTarget = $(e.currentTarget);
|
||||||
}
|
var href = $currentTarget.attr('href');
|
||||||
$currentTarget = $(e.currentTarget);
|
if (!href) return;
|
||||||
href = $currentTarget.attr('href');
|
if (href === '#') return;
|
||||||
if (href === void 0) {
|
if ($currentTarget.attr('target')) return;
|
||||||
return;
|
if ($currentTarget.data('auto-route')) return;
|
||||||
}
|
if ($currentTarget.hasClass('lightbox')) return;
|
||||||
if (href === '#') {
|
if (href.indexOf("mailto:") === 0) return;
|
||||||
return;
|
if (href.match(/^http[s]?:\/\//i) && !href.match(new RegExp("^http:\\/\\/" + window.location.hostname, "i"))) 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();
|
e.preventDefault();
|
||||||
_this.routeTo(href);
|
Discourse.URL.routeTo(href);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
return $(window).focus(function() {
|
|
||||||
_this.set('hasFocus', true);
|
$(window).focus(function() {
|
||||||
return _this.set('notify', false);
|
Discourse.set('hasFocus', true);
|
||||||
|
Discourse.set('notify', false);
|
||||||
}).blur(function() {
|
}).blur(function() {
|
||||||
return _this.set('hasFocus', false);
|
Discourse.set('hasFocus', false);
|
||||||
});
|
});
|
||||||
},
|
|
||||||
logout: function() {
|
// Add a CSRF token to all AJAX requests
|
||||||
var username,
|
var csrfToken = $('meta[name=csrf-token]').attr('content');
|
||||||
_this = this;
|
jQuery.ajaxPrefilter(function(options, originalOptions, xhr) {
|
||||||
username = this.get('currentUser.username');
|
if (!options.crossDomain) {
|
||||||
Discourse.KeyValueStore.abandonLocal();
|
xhr.setRequestHeader('X-CSRF-Token', csrfToken);
|
||||||
return jQuery.ajax("/session/" + 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();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
/* fancy probes in ember
|
|
||||||
*/
|
|
||||||
|
|
||||||
insertProbes: function() {
|
/**
|
||||||
var topLevel;
|
Log the current user out of Discourse
|
||||||
if (typeof console === "undefined" || console === null) {
|
|
||||||
return;
|
@method logout
|
||||||
}
|
**/
|
||||||
topLevel = function(fn, name) {
|
logout: function() {
|
||||||
return window.probes.measure(fn, {
|
Discourse.KeyValueStore.abandonLocal();
|
||||||
name: name,
|
return jQuery.ajax("/session/" + this.get('currentUser.username'), {
|
||||||
before: function(data, owner, args) {
|
type: 'DELETE',
|
||||||
if (owner) {
|
success: function(result) {
|
||||||
return window.probes.clear();
|
// To keep lots of our variables unbound, we can handle a redirect on logging out.
|
||||||
}
|
window.location.reload();
|
||||||
},
|
}
|
||||||
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) {
|
authenticationComplete: function(options) {
|
||||||
// TODO, how to dispatch this to the view without the container?
|
// TODO, how to dispatch this to the view without the container?
|
||||||
var loginView;
|
var loginView;
|
||||||
loginView = Discourse.__container__.lookup('controller:modal').get('currentView');
|
loginView = Discourse.__container__.lookup('controller:modal').get('currentView');
|
||||||
return loginView.authenticationComplete(options);
|
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() {
|
start: function() {
|
||||||
this.bindDOMEvents();
|
Discourse.bindDOMEvents();
|
||||||
Discourse.SiteSettings = PreloadStore.getStatic('siteSettings');
|
Discourse.SiteSettings = PreloadStore.getStatic('siteSettings');
|
||||||
Discourse.MessageBus.start();
|
Discourse.MessageBus.start();
|
||||||
Discourse.KeyValueStore.init("discourse_", Discourse.MessageBus);
|
Discourse.KeyValueStore.init("discourse_", Discourse.MessageBus);
|
||||||
Discourse.insertProbes();
|
|
||||||
|
|
||||||
// subscribe to any site customizations that are loaded
|
// Developer specific functions
|
||||||
$('link.custom-css').each(function() {
|
Discourse.Development.setupProbes();
|
||||||
var id, split, stylesheet,
|
Discourse.Development.observeLiveChanges();
|
||||||
_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;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
$('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({
|
Discourse.Router = Discourse.Router.reopen({ location: 'discourse_location' });
|
||||||
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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ Discourse.ClickTrack = {
|
||||||
topic_id: topicId,
|
topic_id: topicId,
|
||||||
redirect: false
|
redirect: false
|
||||||
});
|
});
|
||||||
Discourse.routeTo(href);
|
Discourse.URL.routeTo(href);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
158
app/assets/javascripts/discourse/components/development.js
Normal file
158
app/assets/javascripts/discourse/components/development.js
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
69
app/assets/javascripts/discourse/components/url.js
Normal file
69
app/assets/javascripts/discourse/components/url.js
Normal file
|
@ -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 {
|
} else {
|
||||||
Discourse.set('currentUser.reply_count', Discourse.get('currentUser.reply_count') + 1);
|
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) {
|
}, function(error) {
|
||||||
composer.set('disableDrafts', false);
|
composer.set('disableDrafts', false);
|
||||||
bootbox.alert(error);
|
bootbox.alert(error);
|
||||||
|
@ -159,7 +159,7 @@ Discourse.ComposerController = Discourse.Controller.extend({
|
||||||
|
|
||||||
// View a new reply we've made
|
// View a new reply we've made
|
||||||
viewNewReply: function() {
|
viewNewReply: function() {
|
||||||
Discourse.routeTo(this.get('createdPost.url'));
|
Discourse.URL.routeTo(this.get('createdPost.url'));
|
||||||
this.close();
|
this.close();
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
/**
|
/**
|
||||||
This controller supports actions on the site header
|
This controller supports actions on the site header
|
||||||
|
|
||||||
@class HeaderController
|
@class HeaderController
|
||||||
@extends Discourse.Controller
|
@extends Discourse.Controller
|
||||||
@namespace Discourse
|
@namespace Discourse
|
||||||
@module Discourse
|
@module Discourse
|
||||||
**/
|
**/
|
||||||
Discourse.HeaderController = Discourse.Controller.extend({
|
Discourse.HeaderController = Discourse.Controller.extend({
|
||||||
topic: null,
|
topic: null,
|
||||||
showExtraInfo: false,
|
showExtraInfo: null,
|
||||||
|
|
||||||
toggleStar: function() {
|
toggleStar: function() {
|
||||||
var topic = this.get('topic');
|
var topic = this.get('topic');
|
||||||
if (topic) topic.toggleStar();
|
if (topic) topic.toggleStar();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ Discourse.TopicController = Discourse.ObjectController.extend({
|
||||||
userFilters: new Em.Set(),
|
userFilters: new Em.Set(),
|
||||||
multiSelect: false,
|
multiSelect: false,
|
||||||
bestOf: false,
|
bestOf: false,
|
||||||
showExtraHeaderInfo: false,
|
|
||||||
needs: ['header', 'modal', 'composer', 'quoteButton'],
|
needs: ['header', 'modal', 'composer', 'quoteButton'],
|
||||||
|
|
||||||
filter: (function() {
|
filter: (function() {
|
||||||
|
@ -42,10 +41,6 @@ Discourse.TopicController = Discourse.ObjectController.extend({
|
||||||
return this.get('canDeleteSelected');
|
return this.get('canDeleteSelected');
|
||||||
}).property('canDeleteSelected'),
|
}).property('canDeleteSelected'),
|
||||||
|
|
||||||
showExtraHeaderInfoChanged: (function() {
|
|
||||||
this.set('controllers.header.showExtraInfo', this.get('showExtraHeaderInfo'));
|
|
||||||
}).observes('showExtraHeaderInfo'),
|
|
||||||
|
|
||||||
canDeleteSelected: (function() {
|
canDeleteSelected: (function() {
|
||||||
var canDelete, selectedPosts;
|
var canDelete, selectedPosts;
|
||||||
selectedPosts = this.get('selectedPosts');
|
selectedPosts = this.get('selectedPosts');
|
||||||
|
@ -109,11 +104,11 @@ Discourse.TopicController = Discourse.ObjectController.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
jumpTop: function() {
|
jumpTop: function() {
|
||||||
Discourse.routeTo(this.get('content.url'));
|
Discourse.URL.routeTo(this.get('content.url'));
|
||||||
},
|
},
|
||||||
|
|
||||||
jumpBottom: function() {
|
jumpBottom: function() {
|
||||||
Discourse.routeTo(this.get('content.lastPostUrl'));
|
Discourse.URL.routeTo(this.get('content.lastPostUrl'));
|
||||||
},
|
},
|
||||||
|
|
||||||
cancelFilter: function() {
|
cancelFilter: function() {
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
Discourse.UserPrivateMessagesController = Discourse.ObjectController.extend({
|
Discourse.UserPrivateMessagesController = Discourse.ObjectController.extend({
|
||||||
|
|
||||||
editPreferences: function() {
|
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() {
|
composePrivateMessage: function() {
|
||||||
|
|
|
@ -14,7 +14,7 @@ Discourse.TopicList = Discourse.Model.extend({
|
||||||
_this = this;
|
_this = this;
|
||||||
promise = new RSVP.Promise();
|
promise = new RSVP.Promise();
|
||||||
if (moreUrl = this.get('more_topics_url')) {
|
if (moreUrl = this.get('more_topics_url')) {
|
||||||
Discourse.replaceState("/" + (this.get('filter')) + "/more");
|
Discourse.URL.replaceState("/" + (this.get('filter')) + "/more");
|
||||||
jQuery.ajax(moreUrl, {
|
jQuery.ajax(moreUrl, {
|
||||||
success: function(result) {
|
success: function(result) {
|
||||||
var newTopics, topicIds, topics;
|
var newTopics, topicIds, topics;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
@method buildRoutes
|
@method buildRoutes
|
||||||
@for Discourse.ApplicationRoute
|
@for Discourse.ApplicationRoute
|
||||||
**/
|
**/
|
||||||
Discourse.buildRoutes(function() {
|
Discourse.Route.buildRoutes(function() {
|
||||||
var router = this;
|
var router = this;
|
||||||
|
|
||||||
// Topic routes
|
// 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) {
|
setupController: function(controller, model) {
|
||||||
var headerController;
|
this.controllerFor('header').set('topic', model);
|
||||||
controller.set('showExtraHeaderInfo', false);
|
|
||||||
headerController = this.controllerFor('header');
|
|
||||||
headerController.set('topic', model);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,17 +1,7 @@
|
||||||
<div class='container'>
|
<div class='container'>
|
||||||
<div class='contents clearfix'>
|
<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}}
|
{{view Discourse.TopicExtraInfoView}}
|
||||||
|
|
||||||
<div class='panel clearfix'>
|
<div class='panel clearfix'>
|
||||||
|
@ -24,7 +14,7 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
<ul class='icons clearfix'>
|
<ul class='icons clearfix'>
|
||||||
<li class='notifications'>
|
<li class='notifications'>
|
||||||
{{#if view.currentUser}}
|
{{#if view.currentUser}}
|
||||||
<a class='icon' href="#" {{action showNotifications target="view"}} data-notifications="notifications-dropdown" id='user-notifications' title='{{i18n notifications.title}}'><i class='icon-comment'></i></a>
|
<a class='icon' href="#" {{action showNotifications target="view"}} data-notifications="notifications-dropdown" id='user-notifications' title='{{i18n notifications.title}}'><i class='icon-comment'></i></a>
|
||||||
|
@ -38,7 +28,7 @@
|
||||||
<a class='icon' href="#" {{action showLogin}} title='{{i18n notifications.title}}'><i class='icon-comment'></i></a>
|
<a class='icon' href="#" {{action showLogin}} title='{{i18n notifications.title}}'><i class='icon-comment'></i></a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a class='icon expand' href='#' data-dropdown="search-dropdown" title='{{i18n search.title}}'><i class='icon-search'></i></a>
|
<a class='icon expand' href='#' data-dropdown="search-dropdown" title='{{i18n search.title}}'><i class='icon-search'></i></a>
|
||||||
</li>
|
</li>
|
||||||
<li class='categories dropdown'>
|
<li class='categories dropdown'>
|
||||||
|
@ -46,7 +36,7 @@
|
||||||
{{#if view.currentUser.site_flagged_posts_count}}
|
{{#if view.currentUser.site_flagged_posts_count}}
|
||||||
<a href='/admin/flags/active' title='total flagged posts' class='badge-notification flagged-posts'>{{view.currentUser.site_flagged_posts_count}}</a>
|
<a href='/admin/flags/active' title='total flagged posts' class='badge-notification flagged-posts'>{{view.currentUser.site_flagged_posts_count}}</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</li>
|
</li>
|
||||||
<li class='current-user'>
|
<li class='current-user'>
|
||||||
{{#if view.currentUser}}
|
{{#if view.currentUser}}
|
||||||
{{#titledLinkTo user.activity view.currentUser titleKey="current_user" class="icon"}}{{avatar Discourse.currentUser imageSize="medium" }}{{/titledLinkTo}}
|
{{#titledLinkTo user.activity view.currentUser titleKey="current_user" class="icon"}}{{avatar Discourse.currentUser imageSize="medium" }}{{/titledLinkTo}}
|
||||||
|
@ -58,7 +48,7 @@
|
||||||
|
|
||||||
{{view Discourse.SearchView currentUserBinding="view.currentUser"}}
|
{{view Discourse.SearchView currentUserBinding="view.currentUser"}}
|
||||||
|
|
||||||
<section class='d-dropdown' id='notifications-dropdown'>
|
<section class='d-dropdown' id='notifications-dropdown'>
|
||||||
{{#if view.notifications}}
|
{{#if view.notifications}}
|
||||||
<ul>
|
<ul>
|
||||||
{{#each view.notifications}}
|
{{#each view.notifications}}
|
||||||
|
@ -73,7 +63,7 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class='d-dropdown' id='site-map-dropdown'>
|
<section class='d-dropdown' id='site-map-dropdown'>
|
||||||
<ul>
|
<ul>
|
||||||
{{#if Discourse.currentUser.admin}}
|
{{#if Discourse.currentUser.admin}}
|
||||||
<li><a href="/admin"><i class='icon-cog'></i>{{i18n admin_title}}</a></li>
|
<li><a href="/admin"><i class='icon-cog'></i>{{i18n admin_title}}</a></li>
|
||||||
|
@ -99,7 +89,7 @@
|
||||||
<li class='heading' title="{{i18n filters.categories.help}}">
|
<li class='heading' title="{{i18n filters.categories.help}}">
|
||||||
{{#linkTo "list.categories"}}{{i18n filters.categories.title}}{{/linkTo}}
|
{{#linkTo "list.categories"}}{{i18n filters.categories.title}}{{/linkTo}}
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
{{#each view.categories}}
|
{{#each view.categories}}
|
||||||
<li class='category'>
|
<li class='category'>
|
||||||
{{categoryLink this}}
|
{{categoryLink this}}
|
||||||
|
|
|
@ -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() {
|
willDestroyElement: function() {
|
||||||
$(window).unbind('scroll.discourse-dock');
|
$(window).unbind('scroll.discourse-dock');
|
||||||
return $(document).unbind('touchmove.discourse-dock');
|
return $(document).unbind('touchmove.discourse-dock');
|
||||||
|
|
|
@ -42,7 +42,7 @@ Discourse.EditCategoryView = Discourse.ModalBodyView.extend({
|
||||||
|
|
||||||
showCategoryTopic: function() {
|
showCategoryTopic: function() {
|
||||||
$('#discourse-modal').modal('hide');
|
$('#discourse-modal').modal('hide');
|
||||||
Discourse.routeTo(this.get('category.topic_url'));
|
Discourse.URL.routeTo(this.get('category.topic_url'));
|
||||||
return false;
|
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) {
|
Discourse.Topic.movePosts(this.get('topic.id'), this.get('topicName'), postIds).then(function(result) {
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
$('#discourse-modal').modal('hide');
|
$('#discourse-modal').modal('hide');
|
||||||
return Em.run.next(function() {
|
Em.run.next(function() {
|
||||||
return Discourse.routeTo(result.url);
|
Discourse.URL.routeTo(result.url);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
_this.flash(Em.String.i18n('topic.move_selected.error'));
|
_this.flash(Em.String.i18n('topic.move_selected.error'));
|
||||||
|
|
|
@ -139,13 +139,10 @@ window.Discourse.SearchView = Discourse.View.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
select: function() {
|
select: function() {
|
||||||
var href;
|
if (this.get('loading')) return;
|
||||||
if (this.get('loading')) {
|
var href = $('#search-dropdown li.selected a').prop('href');
|
||||||
return;
|
|
||||||
}
|
|
||||||
href = $('#search-dropdown li.selected a').prop('href');
|
|
||||||
if (href) {
|
if (href) {
|
||||||
Discourse.routeTo(href);
|
Discourse.URL.routeTo(href);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ Discourse.TopicView = Discourse.View.extend(Discourse.Scrolling, {
|
||||||
postUrl += "/best_of";
|
postUrl += "/best_of";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Discourse.replaceState(postUrl);
|
Discourse.URL.replaceState(postUrl);
|
||||||
|
|
||||||
// Show appropriate jump tools
|
// Show appropriate jump tools
|
||||||
if (current === 1) {
|
if (current === 1) {
|
||||||
|
@ -441,10 +441,12 @@ Discourse.TopicView = Discourse.View.extend(Discourse.Scrolling, {
|
||||||
this.docAt = title.offset().top;
|
this.docAt = title.offset().top;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var headerController = this.get('controller.controllers.header');
|
||||||
if (this.docAt) {
|
if (this.docAt) {
|
||||||
this.set('controller.showExtraHeaderInfo', offset >= this.docAt || !firstLoaded);
|
headerController.set('showExtraInfo', offset >= this.docAt || !firstLoaded);
|
||||||
} else {
|
} else {
|
||||||
this.set('controller.showExtraHeaderInfo', !firstLoaded);
|
headerController.set('showExtraInfo', !firstLoaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
// there is a whole bunch of caching we could add here
|
// there is a whole bunch of caching we could add here
|
||||||
|
|
336
app/assets/javascripts/external/ember.js
vendored
336
app/assets/javascripts/external/ember.js
vendored
|
@ -1,5 +1,5 @@
|
||||||
// Version: v1.0.0-pre.2-723-g052062c
|
// Version: v1.0.0-pre.2-756-gb26f1f0
|
||||||
// Last commit: 052062c (2013-02-18 19:32:17 -0800)
|
// Last commit: b26f1f0 (2013-02-26 09:03:26 -0800)
|
||||||
|
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
@ -150,8 +150,8 @@ Ember.deprecateFunc = function(message, func) {
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
// Version: v1.0.0-pre.2-723-g052062c
|
// Version: v1.0.0-pre.2-756-gb26f1f0
|
||||||
// Last commit: 052062c (2013-02-18 19:32:17 -0800)
|
// Last commit: b26f1f0 (2013-02-26 09:03:26 -0800)
|
||||||
|
|
||||||
|
|
||||||
(function() {
|
(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;
|
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.
|
Empty function. Useful for some operations.
|
||||||
|
|
||||||
|
@ -1752,7 +1761,7 @@ var MapWithDefault = Ember.MapWithDefault = function(options) {
|
||||||
@static
|
@static
|
||||||
@param [options]
|
@param [options]
|
||||||
@param {anything} [options.defaultValue]
|
@param {anything} [options.defaultValue]
|
||||||
@return {Ember.MapWithDefault|Ember.Map} If options are passed, returns
|
@return {Ember.MapWithDefault|Ember.Map} If options are passed, returns
|
||||||
`Ember.MapWithDefault` otherwise returns `Ember.Map`
|
`Ember.MapWithDefault` otherwise returns `Ember.Map`
|
||||||
*/
|
*/
|
||||||
MapWithDefault.create = function(options) {
|
MapWithDefault.create = function(options) {
|
||||||
|
@ -1826,7 +1835,7 @@ var FIRST_KEY = /^([^\.\*]+)/;
|
||||||
|
|
||||||
If you plan to run on IE8 and older browsers then you should use this
|
If you plan to run on IE8 and older browsers then you should use this
|
||||||
method anytime you want to retrieve a property on an object that you don't
|
method anytime you want to retrieve a property on an object that you don't
|
||||||
know for sure is private. (Properties beginning with an underscore '_'
|
know for sure is private. (Properties beginning with an underscore '_'
|
||||||
are considered private.)
|
are considered private.)
|
||||||
|
|
||||||
On all newer browsers, you only need to use this method to retrieve
|
On all newer browsers, you only need to use this method to retrieve
|
||||||
|
@ -1888,7 +1897,7 @@ get = function get(obj, keyName) {
|
||||||
|
|
||||||
If you plan to run on IE8 and older browsers then you should use this
|
If you plan to run on IE8 and older browsers then you should use this
|
||||||
method anytime you want to set a property on an object that you don't
|
method anytime you want to set a property on an object that you don't
|
||||||
know for sure is private. (Properties beginning with an underscore '_'
|
know for sure is private. (Properties beginning with an underscore '_'
|
||||||
are considered private.)
|
are considered private.)
|
||||||
|
|
||||||
On all newer browsers, you only need to use this method to set
|
On all newer browsers, you only need to use this method to set
|
||||||
|
@ -4229,7 +4238,7 @@ Ember.RunLoop = RunLoop;
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
Ember.run(function(){
|
Ember.run(function(){
|
||||||
// code to be execute within a RunLoop
|
// code to be execute within a RunLoop
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -4268,7 +4277,7 @@ var run = Ember.run;
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
Ember.run.begin();
|
Ember.run.begin();
|
||||||
// code to be execute within a RunLoop
|
// code to be execute within a RunLoop
|
||||||
Ember.run.end();
|
Ember.run.end();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -4286,7 +4295,7 @@ Ember.run.begin = function() {
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
Ember.run.begin();
|
Ember.run.begin();
|
||||||
// code to be execute within a RunLoop
|
// code to be execute within a RunLoop
|
||||||
Ember.run.end();
|
Ember.run.end();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -6123,7 +6132,6 @@ define("container",
|
||||||
register: function(type, name, factory, options) {
|
register: function(type, name, factory, options) {
|
||||||
var fullName;
|
var fullName;
|
||||||
|
|
||||||
|
|
||||||
if (type.indexOf(':') !== -1){
|
if (type.indexOf(':') !== -1){
|
||||||
options = factory;
|
options = factory;
|
||||||
factory = name;
|
factory = name;
|
||||||
|
@ -6133,15 +6141,23 @@ define("container",
|
||||||
fullName = type + ":" + name;
|
fullName = type + ":" + name;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.registry.set(fullName, factory);
|
var normalizedName = this.normalize(fullName);
|
||||||
this._options.set(fullName, options || {});
|
|
||||||
|
this.registry.set(normalizedName, factory);
|
||||||
|
this._options.set(normalizedName, options || {});
|
||||||
},
|
},
|
||||||
|
|
||||||
resolve: function(fullName) {
|
resolve: function(fullName) {
|
||||||
return this.resolver(fullName) || this.registry.get(fullName);
|
return this.resolver(fullName) || this.registry.get(fullName);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
normalize: function(fullName) {
|
||||||
|
return fullName;
|
||||||
|
},
|
||||||
|
|
||||||
lookup: function(fullName, options) {
|
lookup: function(fullName, options) {
|
||||||
|
fullName = this.normalize(fullName);
|
||||||
|
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
if (this.cache.has(fullName) && options.singleton !== false) {
|
if (this.cache.has(fullName) && options.singleton !== false) {
|
||||||
|
@ -6270,7 +6286,8 @@ define("container",
|
||||||
}
|
}
|
||||||
|
|
||||||
function factoryFor(container, fullName) {
|
function factoryFor(container, fullName) {
|
||||||
return container.resolve(fullName);
|
var name = container.normalize(fullName);
|
||||||
|
return container.resolve(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
function instantiate(container, fullName) {
|
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() {
|
(function() {
|
||||||
/**
|
/**
|
||||||
@module ember
|
@module ember
|
||||||
|
@ -7358,7 +7389,7 @@ Ember.Enumerable = Ember.Mixin.create(
|
||||||
|
|
||||||
@method nextObject
|
@method nextObject
|
||||||
@param {Number} index the current index of the iteration
|
@param {Number} index the current index of the iteration
|
||||||
@param {Object} previousObject the value returned by the last call to
|
@param {Object} previousObject the value returned by the last call to
|
||||||
`nextObject`.
|
`nextObject`.
|
||||||
@param {Object} context a context object you can use to maintain state.
|
@param {Object} context a context object you can use to maintain state.
|
||||||
@return {Object} the next object in the iteration or undefined
|
@return {Object} the next object in the iteration or undefined
|
||||||
|
@ -8425,9 +8456,9 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
|
||||||
|
|
||||||
@method arrayContentWillChange
|
@method arrayContentWillChange
|
||||||
@param {Number} startIdx The starting index in the array that will change.
|
@param {Number} startIdx The starting index in the array that will change.
|
||||||
@param {Number} removeAmt The number of items that will be removed. If you
|
@param {Number} removeAmt The number of items that will be removed. If you
|
||||||
pass `null` assumes 0
|
pass `null` assumes 0
|
||||||
@param {Number} addAmt The number of items that will be added If you
|
@param {Number} addAmt The number of items that will be added If you
|
||||||
pass `null` assumes 0.
|
pass `null` assumes 0.
|
||||||
@return {Ember.Array} receiver
|
@return {Ember.Array} receiver
|
||||||
*/
|
*/
|
||||||
|
@ -8901,11 +8932,11 @@ Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable,
|
||||||
passed array. You should also call `this.enumerableContentDidChange()`
|
passed array. You should also call `this.enumerableContentDidChange()`
|
||||||
|
|
||||||
@method replace
|
@method replace
|
||||||
@param {Number} idx Starting index in the array to replace. If
|
@param {Number} idx Starting index in the array to replace. If
|
||||||
idx >= length, then append to the end of the array.
|
idx >= length, then append to the end of the array.
|
||||||
@param {Number} amt Number of elements that should be removed from
|
@param {Number} amt Number of elements that should be removed from
|
||||||
the array, starting at *idx*.
|
the array, starting at *idx*.
|
||||||
@param {Array} objects An array of zero or more objects that should be
|
@param {Array} objects An array of zero or more objects that should be
|
||||||
inserted into the array at *idx*
|
inserted into the array at *idx*
|
||||||
*/
|
*/
|
||||||
replace: Ember.required(),
|
replace: Ember.required(),
|
||||||
|
@ -10160,14 +10191,14 @@ CoreObject.PrototypeMixin = Mixin.create({
|
||||||
view.get('classNames'); // ['ember-view', 'bar', 'foo', 'baz']
|
view.get('classNames'); // ['ember-view', 'bar', 'foo', 'baz']
|
||||||
```
|
```
|
||||||
Adding a single property that is not an array will just add it in the array:
|
Adding a single property that is not an array will just add it in the array:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var view = App.FooBarView.create({
|
var view = App.FooBarView.create({
|
||||||
classNames: 'baz'
|
classNames: 'baz'
|
||||||
})
|
})
|
||||||
view.get('classNames'); // ['ember-view', 'bar', 'foo', 'baz']
|
view.get('classNames'); // ['ember-view', 'bar', 'foo', 'baz']
|
||||||
```
|
```
|
||||||
|
|
||||||
Using the `concatenatedProperties` property, we can tell to Ember that mix
|
Using the `concatenatedProperties` property, we can tell to Ember that mix
|
||||||
the content of the properties.
|
the content of the properties.
|
||||||
|
|
||||||
|
@ -11125,40 +11156,8 @@ Ember.Mixin.prototype.toString = classToString;
|
||||||
|
|
||||||
|
|
||||||
(function() {
|
(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();
|
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
|
The NativeArray mixin contains the properties needed to to make the native
|
||||||
Array support Ember.MutableArray and all of its dependent APIs. Unless you
|
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
|
false, this will be applied automatically. Otherwise you can apply the mixin
|
||||||
at anytime by calling `Ember.NativeArray.activate`.
|
at anytime by calling `Ember.NativeArray.activate`.
|
||||||
|
|
||||||
|
@ -12440,7 +12458,8 @@ Ember.ArrayController = Ember.ArrayProxy.extend(Ember.ControllerMixin,
|
||||||
|
|
||||||
objectAtContent: function(idx) {
|
objectAtContent: function(idx) {
|
||||||
var length = get(this, 'length'),
|
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) {
|
if (idx >= 0 && idx < length) {
|
||||||
var controllerClass = this.lookupItemController(object);
|
var controllerClass = this.lookupItemController(object);
|
||||||
|
@ -12591,15 +12610,16 @@ Ember.$ = jQuery;
|
||||||
@module ember
|
@module ember
|
||||||
@submodule ember-views
|
@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
|
// Copies the `dataTransfer` property from a browser event object onto the
|
||||||
var dragEvents = Ember.String.w('dragstart drag dragenter dragleave dragover drop dragend');
|
// jQuery event object for the specified events
|
||||||
|
Ember.EnumerableUtils.forEach(dragEvents, function(eventName) {
|
||||||
// Copies the `dataTransfer` property from a browser event object onto the
|
Ember.$.event.fixHooks[eventName] = { props: ['dataTransfer'] };
|
||||||
// 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
|
// 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
|
// is a "zero-scope" element. This problem can be worked around by making
|
||||||
// the first node an invisible text node. We, like Modernizr, use ­
|
// the first node an invisible text node. We, like Modernizr, use ­
|
||||||
var needsShy = (function(){
|
|
||||||
|
var needsShy = this.document && (function(){
|
||||||
var testEl = document.createElement('div');
|
var testEl = document.createElement('div');
|
||||||
testEl.innerHTML = "<div></div>";
|
testEl.innerHTML = "<div></div>";
|
||||||
testEl.firstChild.innerHTML = "<script></script>";
|
testEl.firstChild.innerHTML = "<script></script>";
|
||||||
|
@ -12626,7 +12647,7 @@ var needsShy = (function(){
|
||||||
// IE 8 (and likely earlier) likes to move whitespace preceeding
|
// IE 8 (and likely earlier) likes to move whitespace preceeding
|
||||||
// a script tag to appear after it. This means that we can
|
// a script tag to appear after it. This means that we can
|
||||||
// accidentally remove whitespace when updating a morph.
|
// accidentally remove whitespace when updating a morph.
|
||||||
var movesWhitespace = (function() {
|
var movesWhitespace = this.document && (function() {
|
||||||
var testEl = document.createElement('div');
|
var testEl = document.createElement('div');
|
||||||
testEl.innerHTML = "Test: <script type='text/x-placeholder'></script>Value";
|
testEl.innerHTML = "Test: <script type='text/x-placeholder'></script>Value";
|
||||||
return testEl.childNodes[0].nodeValue === 'Test:' &&
|
return testEl.childNodes[0].nodeValue === 'Test:' &&
|
||||||
|
@ -13297,7 +13318,7 @@ Ember.EventDispatcher = Ember.Object.extend(
|
||||||
setup: function(addedEvents) {
|
setup: function(addedEvents) {
|
||||||
var event, events = {
|
var event, events = {
|
||||||
touchstart : 'touchStart',
|
touchstart : 'touchStart',
|
||||||
// touchmove : 'touchMove',
|
touchmove : 'touchMove',
|
||||||
touchend : 'touchEnd',
|
touchend : 'touchEnd',
|
||||||
touchcancel : 'touchCancel',
|
touchcancel : 'touchCancel',
|
||||||
keydown : 'keyDown',
|
keydown : 'keyDown',
|
||||||
|
@ -13308,8 +13329,7 @@ Ember.EventDispatcher = Ember.Object.extend(
|
||||||
contextmenu : 'contextMenu',
|
contextmenu : 'contextMenu',
|
||||||
click : 'click',
|
click : 'click',
|
||||||
dblclick : 'doubleClick',
|
dblclick : 'doubleClick',
|
||||||
// https://github.com/emberjs/ember.js/pull/2148
|
mousemove : 'mouseMove',
|
||||||
// mousemove : 'mouseMove',
|
|
||||||
focusin : 'focusIn',
|
focusin : 'focusIn',
|
||||||
focusout : 'focusOut',
|
focusout : 'focusOut',
|
||||||
mouseenter : 'mouseEnter',
|
mouseenter : 'mouseEnter',
|
||||||
|
@ -13459,8 +13479,9 @@ Ember.EventDispatcher = Ember.Object.extend(
|
||||||
// Add a new named queue for rendering views that happens
|
// Add a new named queue for rendering views that happens
|
||||||
// after bindings have synced, and a queue for scheduling actions
|
// after bindings have synced, and a queue for scheduling actions
|
||||||
// that that should occur after view rendering.
|
// that that should occur after view rendering.
|
||||||
var queues = Ember.run.queues;
|
var queues = Ember.run.queues,
|
||||||
queues.splice(Ember.$.inArray('actions', queues)+1, 0, 'render', 'afterRender');
|
indexOf = Ember.ArrayPolyfills.indexOf;
|
||||||
|
queues.splice(indexOf.call(queues, 'actions')+1, 0, 'render', 'afterRender');
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
@ -14250,7 +14271,7 @@ class:
|
||||||
* `mouseEnter`
|
* `mouseEnter`
|
||||||
* `mouseLeave`
|
* `mouseLeave`
|
||||||
|
|
||||||
Form events:
|
Form events:
|
||||||
|
|
||||||
* `submit`
|
* `submit`
|
||||||
* `change`
|
* `change`
|
||||||
|
@ -14258,7 +14279,7 @@ class:
|
||||||
* `focusOut`
|
* `focusOut`
|
||||||
* `input`
|
* `input`
|
||||||
|
|
||||||
HTML5 drag and drop events:
|
HTML5 drag and drop events:
|
||||||
|
|
||||||
* `dragStart`
|
* `dragStart`
|
||||||
* `drag`
|
* `drag`
|
||||||
|
@ -15706,17 +15727,24 @@ Ember.View = Ember.CoreView.extend(
|
||||||
// once the view has been inserted into the DOM, legal manipulations
|
// once the view has been inserted into the DOM, legal manipulations
|
||||||
// are done on the DOM element.
|
// are done on the DOM element.
|
||||||
|
|
||||||
|
function notifyMutationListeners() {
|
||||||
|
Ember.run.once(Ember.View, 'notifyMutationListeners');
|
||||||
|
}
|
||||||
|
|
||||||
var DOMManager = {
|
var DOMManager = {
|
||||||
prepend: function(view, html) {
|
prepend: function(view, html) {
|
||||||
view.$().prepend(html);
|
view.$().prepend(html);
|
||||||
|
notifyMutationListeners();
|
||||||
},
|
},
|
||||||
|
|
||||||
after: function(view, html) {
|
after: function(view, html) {
|
||||||
view.$().after(html);
|
view.$().after(html);
|
||||||
|
notifyMutationListeners();
|
||||||
},
|
},
|
||||||
|
|
||||||
html: function(view, html) {
|
html: function(view, html) {
|
||||||
view.$().html(html);
|
view.$().html(html);
|
||||||
|
notifyMutationListeners();
|
||||||
},
|
},
|
||||||
|
|
||||||
replace: function(view) {
|
replace: function(view) {
|
||||||
|
@ -15726,15 +15754,18 @@ var DOMManager = {
|
||||||
|
|
||||||
view._insertElementLater(function() {
|
view._insertElementLater(function() {
|
||||||
Ember.$(element).replaceWith(get(view, 'element'));
|
Ember.$(element).replaceWith(get(view, 'element'));
|
||||||
|
notifyMutationListeners();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
remove: function(view) {
|
remove: function(view) {
|
||||||
view.$().remove();
|
view.$().remove();
|
||||||
|
notifyMutationListeners();
|
||||||
},
|
},
|
||||||
|
|
||||||
empty: function(view) {
|
empty: function(view) {
|
||||||
view.$().empty();
|
view.$().empty();
|
||||||
|
notifyMutationListeners();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15795,14 +15826,14 @@ Ember.View.reopenClass({
|
||||||
`className` and optional `falsyClassName`.
|
`className` and optional `falsyClassName`.
|
||||||
|
|
||||||
- if a `className` or `falsyClassName` has been specified:
|
- if a `className` or `falsyClassName` has been specified:
|
||||||
- if the value is truthy and `className` has been specified,
|
- if the value is truthy and `className` has been specified,
|
||||||
`className` is returned
|
`className` is returned
|
||||||
- if the value is falsy and `falsyClassName` has been specified,
|
- if the value is falsy and `falsyClassName` has been specified,
|
||||||
`falsyClassName` is returned
|
`falsyClassName` is returned
|
||||||
- otherwise `null` is returned
|
- otherwise `null` is returned
|
||||||
- if the value is `true`, the dasherized last part of the supplied path
|
- if the value is `true`, the dasherized last part of the supplied path
|
||||||
is returned
|
is returned
|
||||||
- if the value is not `false`, `undefined` or `null`, the `value`
|
- if the value is not `false`, `undefined` or `null`, the `value`
|
||||||
is returned
|
is returned
|
||||||
- if none of the above rules apply, `null` is returned
|
- if none of the above rules apply, `null` is returned
|
||||||
|
|
||||||
|
@ -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
|
Global views hash
|
||||||
|
|
||||||
|
@ -16652,7 +16697,7 @@ var get = Ember.get, set = Ember.set, fmt = Ember.String.fmt;
|
||||||
|
|
||||||
Given an empty `<body>` and the following code:
|
Given an empty `<body>` and the following code:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
someItemsView = Ember.CollectionView.create({
|
someItemsView = Ember.CollectionView.create({
|
||||||
classNames: ['a-collection'],
|
classNames: ['a-collection'],
|
||||||
content: ['A','B','C'],
|
content: ['A','B','C'],
|
||||||
|
@ -17008,15 +17053,15 @@ define("metamorph",
|
||||||
|
|
||||||
var K = function(){},
|
var K = function(){},
|
||||||
guid = 0,
|
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
|
// 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
|
// 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
|
// is a "zero-scope" element. This problem can be worked around by making
|
||||||
// the first node an invisible text node. We, like Modernizr, use ­
|
// the first node an invisible text node. We, like Modernizr, use ­
|
||||||
needsShy = (function(){
|
needsShy = document && (function(){
|
||||||
var testEl = document.createElement('div');
|
var testEl = document.createElement('div');
|
||||||
testEl.innerHTML = "<div></div>";
|
testEl.innerHTML = "<div></div>";
|
||||||
testEl.firstChild.innerHTML = "<script></script>";
|
testEl.firstChild.innerHTML = "<script></script>";
|
||||||
|
@ -17027,7 +17072,7 @@ define("metamorph",
|
||||||
// IE 8 (and likely earlier) likes to move whitespace preceeding
|
// IE 8 (and likely earlier) likes to move whitespace preceeding
|
||||||
// a script tag to appear after it. This means that we can
|
// a script tag to appear after it. This means that we can
|
||||||
// accidentally remove whitespace when updating a morph.
|
// accidentally remove whitespace when updating a morph.
|
||||||
movesWhitespace = (function() {
|
movesWhitespace = document && (function() {
|
||||||
var testEl = document.createElement('div');
|
var testEl = document.createElement('div');
|
||||||
testEl.innerHTML = "Test: <script type='text/x-placeholder'></script>Value";
|
testEl.innerHTML = "Test: <script type='text/x-placeholder'></script>Value";
|
||||||
return testEl.childNodes[0].nodeValue === 'Test:' &&
|
return testEl.childNodes[0].nodeValue === 'Test:' &&
|
||||||
|
@ -17471,7 +17516,11 @@ var objectCreate = Object.create || function(parent) {
|
||||||
return new F();
|
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]+)?/));
|
Ember.assert("Ember Handlebars requires Handlebars 1.0.0-rc.3 or greater", Handlebars && Handlebars.VERSION.match(/^1\.0\.[0-9](\.rc\.[23456789]+)?/));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17824,7 +17873,7 @@ Ember.Handlebars.registerHelper('helperMissing', function(path, options) {
|
||||||
|
|
||||||
## Example with bound options
|
## Example with bound options
|
||||||
|
|
||||||
Bound hash options are also supported. Example:
|
Bound hash options are also supported. Example:
|
||||||
|
|
||||||
```handlebars
|
```handlebars
|
||||||
{{repeat text countBinding="numRepeats"}}
|
{{repeat text countBinding="numRepeats"}}
|
||||||
|
@ -17862,15 +17911,15 @@ Ember.Handlebars.registerHelper('helperMissing', function(path, options) {
|
||||||
{{concatenate prop1 prop2 prop3}}. If any of the properties change,
|
{{concatenate prop1 prop2 prop3}}. If any of the properties change,
|
||||||
the helpr will re-render. Note that dependency keys cannot be
|
the helpr will re-render. Note that dependency keys cannot be
|
||||||
using in conjunction with multi-property helpers, since it is ambiguous
|
using in conjunction with multi-property helpers, since it is ambiguous
|
||||||
which property the dependent keys would belong to.
|
which property the dependent keys would belong to.
|
||||||
|
|
||||||
## Use with unbound helper
|
## Use with unbound helper
|
||||||
|
|
||||||
The {{unbound}} helper can be used with bound helper invocations
|
The {{unbound}} helper can be used with bound helper invocations
|
||||||
to render them in their unbound form, e.g.
|
to render them in their unbound form, e.g.
|
||||||
|
|
||||||
```handlebars
|
```handlebars
|
||||||
{{unbound capitalize name}}
|
{{unbound capitalize name}}
|
||||||
```
|
```
|
||||||
|
|
||||||
In this example, if the name property changes, the helper
|
In this example, if the name property changes, the helper
|
||||||
|
@ -17896,7 +17945,7 @@ Ember.Handlebars.registerBoundHelper = function(name, fn) {
|
||||||
view = data.view,
|
view = data.view,
|
||||||
currentContext = (options.contexts && options.contexts[0]) || this,
|
currentContext = (options.contexts && options.contexts[0]) || this,
|
||||||
normalized,
|
normalized,
|
||||||
pathRoot, path,
|
pathRoot, path,
|
||||||
loc, hashOption;
|
loc, hashOption;
|
||||||
|
|
||||||
// Detect bound options (e.g. countBinding="otherCount")
|
// Detect bound options (e.g. countBinding="otherCount")
|
||||||
|
@ -18002,7 +18051,7 @@ function evaluateMultiPropertyBoundHelper(context, fn, normalizedProperties, opt
|
||||||
// Assemble liast of watched properties that'll re-render this helper.
|
// Assemble liast of watched properties that'll re-render this helper.
|
||||||
watchedProperties = [];
|
watchedProperties = [];
|
||||||
for (boundOption in boundOptions) {
|
for (boundOption in boundOptions) {
|
||||||
if (boundOptions.hasOwnProperty(boundOption)) {
|
if (boundOptions.hasOwnProperty(boundOption)) {
|
||||||
watchedProperties.push(normalizePath(context, boundOptions[boundOption], data));
|
watchedProperties.push(normalizePath(context, boundOptions[boundOption], data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18131,22 +18180,30 @@ Ember.Handlebars.resolvePaths = function(options) {
|
||||||
var set = Ember.set, get = Ember.get;
|
var set = Ember.set, get = Ember.get;
|
||||||
var Metamorph = requireModule('metamorph');
|
var Metamorph = requireModule('metamorph');
|
||||||
|
|
||||||
|
function notifyMutationListeners() {
|
||||||
|
Ember.run.once(Ember.View, 'notifyMutationListeners');
|
||||||
|
}
|
||||||
|
|
||||||
// DOMManager should just abstract dom manipulation between jquery and metamorph
|
// DOMManager should just abstract dom manipulation between jquery and metamorph
|
||||||
var DOMManager = {
|
var DOMManager = {
|
||||||
remove: function(view) {
|
remove: function(view) {
|
||||||
view.morph.remove();
|
view.morph.remove();
|
||||||
|
notifyMutationListeners();
|
||||||
},
|
},
|
||||||
|
|
||||||
prepend: function(view, html) {
|
prepend: function(view, html) {
|
||||||
view.morph.prepend(html);
|
view.morph.prepend(html);
|
||||||
|
notifyMutationListeners();
|
||||||
},
|
},
|
||||||
|
|
||||||
after: function(view, html) {
|
after: function(view, html) {
|
||||||
view.morph.after(html);
|
view.morph.after(html);
|
||||||
|
notifyMutationListeners();
|
||||||
},
|
},
|
||||||
|
|
||||||
html: function(view, html) {
|
html: function(view, html) {
|
||||||
view.morph.html(html);
|
view.morph.html(html);
|
||||||
|
notifyMutationListeners();
|
||||||
},
|
},
|
||||||
|
|
||||||
// This is messed up.
|
// This is messed up.
|
||||||
|
@ -18169,11 +18226,13 @@ var DOMManager = {
|
||||||
morph.replaceWith(buffer.string());
|
morph.replaceWith(buffer.string());
|
||||||
view.transitionTo('inDOM');
|
view.transitionTo('inDOM');
|
||||||
view.triggerRecursively('didInsertElement');
|
view.triggerRecursively('didInsertElement');
|
||||||
|
notifyMutationListeners();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
empty: function(view) {
|
empty: function(view) {
|
||||||
view.morph.html("");
|
view.morph.html("");
|
||||||
|
notifyMutationListeners();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18937,14 +18996,14 @@ EmberHandlebars.registerHelper('unless', function(context, options) {
|
||||||
|
|
||||||
Result in the following rendered output:
|
Result in the following rendered output:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<img class="aValue">
|
<img class="aValue">
|
||||||
```
|
```
|
||||||
|
|
||||||
A boolean return value will insert a specified class name if the property
|
A boolean return value will insert a specified class name if the property
|
||||||
returns `true` and remove the class name if the property returns `false`.
|
returns `true` and remove the class name if the property returns `false`.
|
||||||
|
|
||||||
A class name is provided via the syntax
|
A class name is provided via the syntax
|
||||||
`somePropertyName:class-name-if-true`.
|
`somePropertyName:class-name-if-true`.
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
|
@ -19103,9 +19162,9 @@ EmberHandlebars.registerHelper('bindAttr', function(options) {
|
||||||
@method bindClasses
|
@method bindClasses
|
||||||
@for Ember.Handlebars
|
@for Ember.Handlebars
|
||||||
@param {Ember.Object} context The context from which to lookup properties
|
@param {Ember.Object} context The context from which to lookup properties
|
||||||
@param {String} classBindings A string, space-separated, of class bindings
|
@param {String} classBindings A string, space-separated, of class bindings
|
||||||
to use
|
to use
|
||||||
@param {Ember.View} view The view in which observers should look for the
|
@param {Ember.View} view The view in which observers should look for the
|
||||||
element to update
|
element to update
|
||||||
@param {Srting} bindAttrId Optional bindAttr id used to lookup elements
|
@param {Srting} bindAttrId Optional bindAttr id used to lookup elements
|
||||||
@return {Array} An array of class names to add
|
@return {Array} An array of class names to add
|
||||||
|
@ -19795,7 +19854,7 @@ Ember.Handlebars.registerHelper('unbound', function(property, fn) {
|
||||||
// Unbound helper call.
|
// Unbound helper call.
|
||||||
options.data.isUnbound = true;
|
options.data.isUnbound = true;
|
||||||
helper = Ember.Handlebars.helpers[arguments[0]] || Ember.Handlebars.helperMissing;
|
helper = Ember.Handlebars.helpers[arguments[0]] || Ember.Handlebars.helperMissing;
|
||||||
out = helper.apply(this, Array.prototype.slice.call(arguments, 1));
|
out = helper.apply(this, Array.prototype.slice.call(arguments, 1));
|
||||||
delete options.data.isUnbound;
|
delete options.data.isUnbound;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -21093,7 +21152,7 @@ helpers = helpers || Ember.Handlebars.helpers; data = data || {};
|
||||||
var buffer = '', stack1, hashTypes, escapeExpression=this.escapeExpression, self=this;
|
var buffer = '', stack1, hashTypes, escapeExpression=this.escapeExpression, self=this;
|
||||||
|
|
||||||
function program1(depth0,data) {
|
function program1(depth0,data) {
|
||||||
|
|
||||||
var buffer = '', hashTypes;
|
var buffer = '', hashTypes;
|
||||||
data.buffer.push("<option value=\"\">");
|
data.buffer.push("<option value=\"\">");
|
||||||
hashTypes = {};
|
hashTypes = {};
|
||||||
|
@ -21103,7 +21162,7 @@ function program1(depth0,data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function program3(depth0,data) {
|
function program3(depth0,data) {
|
||||||
|
|
||||||
var hashTypes;
|
var hashTypes;
|
||||||
hashTypes = {'contentBinding': "STRING"};
|
hashTypes = {'contentBinding': "STRING"};
|
||||||
data.buffer.push(escapeExpression(helpers.view.call(depth0, "Ember.SelectOption", {hash:{
|
data.buffer.push(escapeExpression(helpers.view.call(depth0, "Ember.SelectOption", {hash:{
|
||||||
|
@ -21118,7 +21177,7 @@ function program3(depth0,data) {
|
||||||
stack1 = helpers.each.call(depth0, "view.content", {hash:{},inverse:self.noop,fn:self.program(3, program3, data),contexts:[depth0],types:["ID"],hashTypes:hashTypes,data:data});
|
stack1 = helpers.each.call(depth0, "view.content", {hash:{},inverse:self.noop,fn:self.program(3, program3, data),contexts:[depth0],types:["ID"],hashTypes:hashTypes,data:data});
|
||||||
if(stack1 || stack1 === 0) { data.buffer.push(stack1); }
|
if(stack1 || stack1 === 0) { data.buffer.push(stack1); }
|
||||||
return buffer;
|
return buffer;
|
||||||
|
|
||||||
}),
|
}),
|
||||||
attributeBindings: ['multiple', 'disabled', 'tabindex'],
|
attributeBindings: ['multiple', 'disabled', 'tabindex'],
|
||||||
|
|
||||||
|
@ -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() {
|
(function() {
|
||||||
/**
|
/**
|
||||||
@module ember
|
@module ember
|
||||||
|
@ -23564,7 +23651,7 @@ function teardownView(route) {
|
||||||
var get = Ember.get, set = Ember.set;
|
var get = Ember.get, set = Ember.set;
|
||||||
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;
|
isSimpleClick = Ember.ViewUtils.isSimpleClick;
|
||||||
|
|
||||||
function fullRouteName(router, name) {
|
function fullRouteName(router, name) {
|
||||||
|
@ -23847,7 +23934,7 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
||||||
*/
|
*/
|
||||||
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;
|
isSimpleClick = Ember.ViewUtils.isSimpleClick;
|
||||||
|
|
||||||
var EmberHandlebars = Ember.Handlebars,
|
var EmberHandlebars = Ember.Handlebars,
|
||||||
|
@ -24473,7 +24560,7 @@ Ember.HashLocation = Ember.Object.extend({
|
||||||
|
|
||||||
set(self, 'lastSetURL', null);
|
set(self, 'lastSetURL', null);
|
||||||
|
|
||||||
callback(location.hash.substr(1));
|
callback(path);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -24851,11 +24938,14 @@ var get = Ember.get, set = Ember.set,
|
||||||
```
|
```
|
||||||
|
|
||||||
By default, calling `Ember.Application.create()` will automatically initialize
|
By default, calling `Ember.Application.create()` will automatically initialize
|
||||||
your application by calling the `Ember.Application.initialize()` method. If
|
your application by calling the `Ember.Application.initialize()` method. If
|
||||||
you need to delay initialization, you can call your app's `deferReadiness()`
|
you need to delay initialization, you can call your app's `deferReadiness()`
|
||||||
method. When you are ready for your app to be initialized, call its
|
method. When you are ready for your app to be initialized, call its
|
||||||
`advanceReadiness()` method.
|
`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
|
Because `Ember.Application` inherits from `Ember.Namespace`, any classes
|
||||||
you create will have useful string representations when calling `toString()`.
|
you create will have useful string representations when calling `toString()`.
|
||||||
See the `Ember.Namespace` documentation for more information.
|
See the `Ember.Namespace` documentation for more information.
|
||||||
|
@ -25050,11 +25140,13 @@ var Application = Ember.Application = Ember.Namespace.extend({
|
||||||
this.scheduleInitialize();
|
this.scheduleInitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ember.debug('-------------------------------');
|
if ( Ember.LOG_VERSION ) {
|
||||||
Ember.debug('Ember.VERSION : ' + Ember.VERSION);
|
Ember.debug('-------------------------------');
|
||||||
Ember.debug('Handlebars.VERSION : ' + Ember.Handlebars.VERSION);
|
Ember.debug('Ember.VERSION : ' + Ember.VERSION);
|
||||||
Ember.debug('jQuery.VERSION : ' + Ember.$().jquery);
|
Ember.debug('Handlebars.VERSION : ' + Ember.Handlebars.VERSION);
|
||||||
Ember.debug('-------------------------------');
|
Ember.debug('jQuery.VERSION : ' + Ember.$().jquery);
|
||||||
|
Ember.debug('-------------------------------');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25414,6 +25506,7 @@ Ember.Application.reopenClass({
|
||||||
Ember.Container.defaultContainer = Ember.Container.defaultContainer || container;
|
Ember.Container.defaultContainer = Ember.Container.defaultContainer || container;
|
||||||
|
|
||||||
container.set = Ember.set;
|
container.set = Ember.set;
|
||||||
|
container.normalize = normalize;
|
||||||
container.resolver = resolverFor(namespace);
|
container.resolver = resolverFor(namespace);
|
||||||
container.optionsForType('view', { singleton: false });
|
container.optionsForType('view', { singleton: false });
|
||||||
container.optionsForType('template', { instantiate: false });
|
container.optionsForType('template', { instantiate: false });
|
||||||
|
@ -25453,6 +25546,7 @@ function resolverFor(namespace) {
|
||||||
|
|
||||||
if (type === 'template') {
|
if (type === 'template') {
|
||||||
var templateName = name.replace(/\./g, '/');
|
var templateName = name.replace(/\./g, '/');
|
||||||
|
|
||||||
if (Ember.TEMPLATES[templateName]) {
|
if (Ember.TEMPLATES[templateName]) {
|
||||||
return 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
|
// Version: v1.0.0-pre.2-756-gb26f1f0
|
||||||
// Last commit: 052062c (2013-02-18 19:32:17 -0800)
|
// Last commit: b26f1f0 (2013-02-26 09:03:26 -0800)
|
||||||
|
|
||||||
|
|
||||||
(function() {
|
(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;
|
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.
|
Empty function. Useful for some operations.
|
||||||
|
|
||||||
|
@ -1596,7 +1605,7 @@ var MapWithDefault = Ember.MapWithDefault = function(options) {
|
||||||
@static
|
@static
|
||||||
@param [options]
|
@param [options]
|
||||||
@param {anything} [options.defaultValue]
|
@param {anything} [options.defaultValue]
|
||||||
@return {Ember.MapWithDefault|Ember.Map} If options are passed, returns
|
@return {Ember.MapWithDefault|Ember.Map} If options are passed, returns
|
||||||
`Ember.MapWithDefault` otherwise returns `Ember.Map`
|
`Ember.MapWithDefault` otherwise returns `Ember.Map`
|
||||||
*/
|
*/
|
||||||
MapWithDefault.create = function(options) {
|
MapWithDefault.create = function(options) {
|
||||||
|
@ -1670,7 +1679,7 @@ var FIRST_KEY = /^([^\.\*]+)/;
|
||||||
|
|
||||||
If you plan to run on IE8 and older browsers then you should use this
|
If you plan to run on IE8 and older browsers then you should use this
|
||||||
method anytime you want to retrieve a property on an object that you don't
|
method anytime you want to retrieve a property on an object that you don't
|
||||||
know for sure is private. (Properties beginning with an underscore '_'
|
know for sure is private. (Properties beginning with an underscore '_'
|
||||||
are considered private.)
|
are considered private.)
|
||||||
|
|
||||||
On all newer browsers, you only need to use this method to retrieve
|
On all newer browsers, you only need to use this method to retrieve
|
||||||
|
@ -1731,7 +1740,7 @@ get = function get(obj, keyName) {
|
||||||
|
|
||||||
If you plan to run on IE8 and older browsers then you should use this
|
If you plan to run on IE8 and older browsers then you should use this
|
||||||
method anytime you want to set a property on an object that you don't
|
method anytime you want to set a property on an object that you don't
|
||||||
know for sure is private. (Properties beginning with an underscore '_'
|
know for sure is private. (Properties beginning with an underscore '_'
|
||||||
are considered private.)
|
are considered private.)
|
||||||
|
|
||||||
On all newer browsers, you only need to use this method to set
|
On all newer browsers, you only need to use this method to set
|
||||||
|
@ -4069,7 +4078,7 @@ Ember.RunLoop = RunLoop;
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
Ember.run(function(){
|
Ember.run(function(){
|
||||||
// code to be execute within a RunLoop
|
// code to be execute within a RunLoop
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -4108,7 +4117,7 @@ var run = Ember.run;
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
Ember.run.begin();
|
Ember.run.begin();
|
||||||
// code to be execute within a RunLoop
|
// code to be execute within a RunLoop
|
||||||
Ember.run.end();
|
Ember.run.end();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -4126,7 +4135,7 @@ Ember.run.begin = function() {
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
Ember.run.begin();
|
Ember.run.begin();
|
||||||
// code to be execute within a RunLoop
|
// code to be execute within a RunLoop
|
||||||
Ember.run.end();
|
Ember.run.end();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -5963,7 +5972,6 @@ define("container",
|
||||||
register: function(type, name, factory, options) {
|
register: function(type, name, factory, options) {
|
||||||
var fullName;
|
var fullName;
|
||||||
|
|
||||||
|
|
||||||
if (type.indexOf(':') !== -1){
|
if (type.indexOf(':') !== -1){
|
||||||
options = factory;
|
options = factory;
|
||||||
factory = name;
|
factory = name;
|
||||||
|
@ -5973,15 +5981,23 @@ define("container",
|
||||||
fullName = type + ":" + name;
|
fullName = type + ":" + name;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.registry.set(fullName, factory);
|
var normalizedName = this.normalize(fullName);
|
||||||
this._options.set(fullName, options || {});
|
|
||||||
|
this.registry.set(normalizedName, factory);
|
||||||
|
this._options.set(normalizedName, options || {});
|
||||||
},
|
},
|
||||||
|
|
||||||
resolve: function(fullName) {
|
resolve: function(fullName) {
|
||||||
return this.resolver(fullName) || this.registry.get(fullName);
|
return this.resolver(fullName) || this.registry.get(fullName);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
normalize: function(fullName) {
|
||||||
|
return fullName;
|
||||||
|
},
|
||||||
|
|
||||||
lookup: function(fullName, options) {
|
lookup: function(fullName, options) {
|
||||||
|
fullName = this.normalize(fullName);
|
||||||
|
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
if (this.cache.has(fullName) && options.singleton !== false) {
|
if (this.cache.has(fullName) && options.singleton !== false) {
|
||||||
|
@ -6110,7 +6126,8 @@ define("container",
|
||||||
}
|
}
|
||||||
|
|
||||||
function factoryFor(container, fullName) {
|
function factoryFor(container, fullName) {
|
||||||
return container.resolve(fullName);
|
var name = container.normalize(fullName);
|
||||||
|
return container.resolve(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
function instantiate(container, fullName) {
|
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() {
|
(function() {
|
||||||
/**
|
/**
|
||||||
@module ember
|
@module ember
|
||||||
|
@ -7197,7 +7228,7 @@ Ember.Enumerable = Ember.Mixin.create(
|
||||||
|
|
||||||
@method nextObject
|
@method nextObject
|
||||||
@param {Number} index the current index of the iteration
|
@param {Number} index the current index of the iteration
|
||||||
@param {Object} previousObject the value returned by the last call to
|
@param {Object} previousObject the value returned by the last call to
|
||||||
`nextObject`.
|
`nextObject`.
|
||||||
@param {Object} context a context object you can use to maintain state.
|
@param {Object} context a context object you can use to maintain state.
|
||||||
@return {Object} the next object in the iteration or undefined
|
@return {Object} the next object in the iteration or undefined
|
||||||
|
@ -8264,9 +8295,9 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
|
||||||
|
|
||||||
@method arrayContentWillChange
|
@method arrayContentWillChange
|
||||||
@param {Number} startIdx The starting index in the array that will change.
|
@param {Number} startIdx The starting index in the array that will change.
|
||||||
@param {Number} removeAmt The number of items that will be removed. If you
|
@param {Number} removeAmt The number of items that will be removed. If you
|
||||||
pass `null` assumes 0
|
pass `null` assumes 0
|
||||||
@param {Number} addAmt The number of items that will be added If you
|
@param {Number} addAmt The number of items that will be added If you
|
||||||
pass `null` assumes 0.
|
pass `null` assumes 0.
|
||||||
@return {Ember.Array} receiver
|
@return {Ember.Array} receiver
|
||||||
*/
|
*/
|
||||||
|
@ -8740,11 +8771,11 @@ Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable,
|
||||||
passed array. You should also call `this.enumerableContentDidChange()`
|
passed array. You should also call `this.enumerableContentDidChange()`
|
||||||
|
|
||||||
@method replace
|
@method replace
|
||||||
@param {Number} idx Starting index in the array to replace. If
|
@param {Number} idx Starting index in the array to replace. If
|
||||||
idx >= length, then append to the end of the array.
|
idx >= length, then append to the end of the array.
|
||||||
@param {Number} amt Number of elements that should be removed from
|
@param {Number} amt Number of elements that should be removed from
|
||||||
the array, starting at *idx*.
|
the array, starting at *idx*.
|
||||||
@param {Array} objects An array of zero or more objects that should be
|
@param {Array} objects An array of zero or more objects that should be
|
||||||
inserted into the array at *idx*
|
inserted into the array at *idx*
|
||||||
*/
|
*/
|
||||||
replace: Ember.required(),
|
replace: Ember.required(),
|
||||||
|
@ -9998,14 +10029,14 @@ CoreObject.PrototypeMixin = Mixin.create({
|
||||||
view.get('classNames'); // ['ember-view', 'bar', 'foo', 'baz']
|
view.get('classNames'); // ['ember-view', 'bar', 'foo', 'baz']
|
||||||
```
|
```
|
||||||
Adding a single property that is not an array will just add it in the array:
|
Adding a single property that is not an array will just add it in the array:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var view = App.FooBarView.create({
|
var view = App.FooBarView.create({
|
||||||
classNames: 'baz'
|
classNames: 'baz'
|
||||||
})
|
})
|
||||||
view.get('classNames'); // ['ember-view', 'bar', 'foo', 'baz']
|
view.get('classNames'); // ['ember-view', 'bar', 'foo', 'baz']
|
||||||
```
|
```
|
||||||
|
|
||||||
Using the `concatenatedProperties` property, we can tell to Ember that mix
|
Using the `concatenatedProperties` property, we can tell to Ember that mix
|
||||||
the content of the properties.
|
the content of the properties.
|
||||||
|
|
||||||
|
@ -10962,40 +10993,8 @@ Ember.Mixin.prototype.toString = classToString;
|
||||||
|
|
||||||
|
|
||||||
(function() {
|
(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();
|
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
|
The NativeArray mixin contains the properties needed to to make the native
|
||||||
Array support Ember.MutableArray and all of its dependent APIs. Unless you
|
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
|
false, this will be applied automatically. Otherwise you can apply the mixin
|
||||||
at anytime by calling `Ember.NativeArray.activate`.
|
at anytime by calling `Ember.NativeArray.activate`.
|
||||||
|
|
||||||
|
@ -12274,7 +12292,8 @@ Ember.ArrayController = Ember.ArrayProxy.extend(Ember.ControllerMixin,
|
||||||
|
|
||||||
objectAtContent: function(idx) {
|
objectAtContent: function(idx) {
|
||||||
var length = get(this, 'length'),
|
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) {
|
if (idx >= 0 && idx < length) {
|
||||||
var controllerClass = this.lookupItemController(object);
|
var controllerClass = this.lookupItemController(object);
|
||||||
|
@ -12425,15 +12444,16 @@ Ember.$ = jQuery;
|
||||||
@module ember
|
@module ember
|
||||||
@submodule ember-views
|
@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
|
// Copies the `dataTransfer` property from a browser event object onto the
|
||||||
var dragEvents = Ember.String.w('dragstart drag dragenter dragleave dragover drop dragend');
|
// jQuery event object for the specified events
|
||||||
|
Ember.EnumerableUtils.forEach(dragEvents, function(eventName) {
|
||||||
// Copies the `dataTransfer` property from a browser event object onto the
|
Ember.$.event.fixHooks[eventName] = { props: ['dataTransfer'] };
|
||||||
// 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
|
// 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
|
// is a "zero-scope" element. This problem can be worked around by making
|
||||||
// the first node an invisible text node. We, like Modernizr, use ­
|
// the first node an invisible text node. We, like Modernizr, use ­
|
||||||
var needsShy = (function(){
|
|
||||||
|
var needsShy = this.document && (function(){
|
||||||
var testEl = document.createElement('div');
|
var testEl = document.createElement('div');
|
||||||
testEl.innerHTML = "<div></div>";
|
testEl.innerHTML = "<div></div>";
|
||||||
testEl.firstChild.innerHTML = "<script></script>";
|
testEl.firstChild.innerHTML = "<script></script>";
|
||||||
|
@ -12460,7 +12481,7 @@ var needsShy = (function(){
|
||||||
// IE 8 (and likely earlier) likes to move whitespace preceeding
|
// IE 8 (and likely earlier) likes to move whitespace preceeding
|
||||||
// a script tag to appear after it. This means that we can
|
// a script tag to appear after it. This means that we can
|
||||||
// accidentally remove whitespace when updating a morph.
|
// accidentally remove whitespace when updating a morph.
|
||||||
var movesWhitespace = (function() {
|
var movesWhitespace = this.document && (function() {
|
||||||
var testEl = document.createElement('div');
|
var testEl = document.createElement('div');
|
||||||
testEl.innerHTML = "Test: <script type='text/x-placeholder'></script>Value";
|
testEl.innerHTML = "Test: <script type='text/x-placeholder'></script>Value";
|
||||||
return testEl.childNodes[0].nodeValue === 'Test:' &&
|
return testEl.childNodes[0].nodeValue === 'Test:' &&
|
||||||
|
@ -13131,7 +13152,7 @@ Ember.EventDispatcher = Ember.Object.extend(
|
||||||
setup: function(addedEvents) {
|
setup: function(addedEvents) {
|
||||||
var event, events = {
|
var event, events = {
|
||||||
touchstart : 'touchStart',
|
touchstart : 'touchStart',
|
||||||
// touchmove : 'touchMove',
|
touchmove : 'touchMove',
|
||||||
touchend : 'touchEnd',
|
touchend : 'touchEnd',
|
||||||
touchcancel : 'touchCancel',
|
touchcancel : 'touchCancel',
|
||||||
keydown : 'keyDown',
|
keydown : 'keyDown',
|
||||||
|
@ -13142,7 +13163,7 @@ Ember.EventDispatcher = Ember.Object.extend(
|
||||||
contextmenu : 'contextMenu',
|
contextmenu : 'contextMenu',
|
||||||
click : 'click',
|
click : 'click',
|
||||||
dblclick : 'doubleClick',
|
dblclick : 'doubleClick',
|
||||||
// mousemove : 'mouseMove',
|
mousemove : 'mouseMove',
|
||||||
focusin : 'focusIn',
|
focusin : 'focusIn',
|
||||||
focusout : 'focusOut',
|
focusout : 'focusOut',
|
||||||
mouseenter : 'mouseEnter',
|
mouseenter : 'mouseEnter',
|
||||||
|
@ -13290,8 +13311,9 @@ Ember.EventDispatcher = Ember.Object.extend(
|
||||||
// Add a new named queue for rendering views that happens
|
// Add a new named queue for rendering views that happens
|
||||||
// after bindings have synced, and a queue for scheduling actions
|
// after bindings have synced, and a queue for scheduling actions
|
||||||
// that that should occur after view rendering.
|
// that that should occur after view rendering.
|
||||||
var queues = Ember.run.queues;
|
var queues = Ember.run.queues,
|
||||||
queues.splice(Ember.$.inArray('actions', queues)+1, 0, 'render', 'afterRender');
|
indexOf = Ember.ArrayPolyfills.indexOf;
|
||||||
|
queues.splice(indexOf.call(queues, 'actions')+1, 0, 'render', 'afterRender');
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
@ -14080,7 +14102,7 @@ class:
|
||||||
* `mouseEnter`
|
* `mouseEnter`
|
||||||
* `mouseLeave`
|
* `mouseLeave`
|
||||||
|
|
||||||
Form events:
|
Form events:
|
||||||
|
|
||||||
* `submit`
|
* `submit`
|
||||||
* `change`
|
* `change`
|
||||||
|
@ -14088,7 +14110,7 @@ class:
|
||||||
* `focusOut`
|
* `focusOut`
|
||||||
* `input`
|
* `input`
|
||||||
|
|
||||||
HTML5 drag and drop events:
|
HTML5 drag and drop events:
|
||||||
|
|
||||||
* `dragStart`
|
* `dragStart`
|
||||||
* `drag`
|
* `drag`
|
||||||
|
@ -15530,17 +15552,24 @@ Ember.View = Ember.CoreView.extend(
|
||||||
// once the view has been inserted into the DOM, legal manipulations
|
// once the view has been inserted into the DOM, legal manipulations
|
||||||
// are done on the DOM element.
|
// are done on the DOM element.
|
||||||
|
|
||||||
|
function notifyMutationListeners() {
|
||||||
|
Ember.run.once(Ember.View, 'notifyMutationListeners');
|
||||||
|
}
|
||||||
|
|
||||||
var DOMManager = {
|
var DOMManager = {
|
||||||
prepend: function(view, html) {
|
prepend: function(view, html) {
|
||||||
view.$().prepend(html);
|
view.$().prepend(html);
|
||||||
|
notifyMutationListeners();
|
||||||
},
|
},
|
||||||
|
|
||||||
after: function(view, html) {
|
after: function(view, html) {
|
||||||
view.$().after(html);
|
view.$().after(html);
|
||||||
|
notifyMutationListeners();
|
||||||
},
|
},
|
||||||
|
|
||||||
html: function(view, html) {
|
html: function(view, html) {
|
||||||
view.$().html(html);
|
view.$().html(html);
|
||||||
|
notifyMutationListeners();
|
||||||
},
|
},
|
||||||
|
|
||||||
replace: function(view) {
|
replace: function(view) {
|
||||||
|
@ -15550,15 +15579,18 @@ var DOMManager = {
|
||||||
|
|
||||||
view._insertElementLater(function() {
|
view._insertElementLater(function() {
|
||||||
Ember.$(element).replaceWith(get(view, 'element'));
|
Ember.$(element).replaceWith(get(view, 'element'));
|
||||||
|
notifyMutationListeners();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
remove: function(view) {
|
remove: function(view) {
|
||||||
view.$().remove();
|
view.$().remove();
|
||||||
|
notifyMutationListeners();
|
||||||
},
|
},
|
||||||
|
|
||||||
empty: function(view) {
|
empty: function(view) {
|
||||||
view.$().empty();
|
view.$().empty();
|
||||||
|
notifyMutationListeners();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15619,14 +15651,14 @@ Ember.View.reopenClass({
|
||||||
`className` and optional `falsyClassName`.
|
`className` and optional `falsyClassName`.
|
||||||
|
|
||||||
- if a `className` or `falsyClassName` has been specified:
|
- if a `className` or `falsyClassName` has been specified:
|
||||||
- if the value is truthy and `className` has been specified,
|
- if the value is truthy and `className` has been specified,
|
||||||
`className` is returned
|
`className` is returned
|
||||||
- if the value is falsy and `falsyClassName` has been specified,
|
- if the value is falsy and `falsyClassName` has been specified,
|
||||||
`falsyClassName` is returned
|
`falsyClassName` is returned
|
||||||
- otherwise `null` is returned
|
- otherwise `null` is returned
|
||||||
- if the value is `true`, the dasherized last part of the supplied path
|
- if the value is `true`, the dasherized last part of the supplied path
|
||||||
is returned
|
is returned
|
||||||
- if the value is not `false`, `undefined` or `null`, the `value`
|
- if the value is not `false`, `undefined` or `null`, the `value`
|
||||||
is returned
|
is returned
|
||||||
- if none of the above rules apply, `null` is returned
|
- if none of the above rules apply, `null` is returned
|
||||||
|
|
||||||
|
@ -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
|
Global views hash
|
||||||
|
|
||||||
|
@ -16476,7 +16522,7 @@ var get = Ember.get, set = Ember.set, fmt = Ember.String.fmt;
|
||||||
|
|
||||||
Given an empty `<body>` and the following code:
|
Given an empty `<body>` and the following code:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
someItemsView = Ember.CollectionView.create({
|
someItemsView = Ember.CollectionView.create({
|
||||||
classNames: ['a-collection'],
|
classNames: ['a-collection'],
|
||||||
content: ['A','B','C'],
|
content: ['A','B','C'],
|
||||||
|
@ -16831,15 +16877,15 @@ define("metamorph",
|
||||||
|
|
||||||
var K = function(){},
|
var K = function(){},
|
||||||
guid = 0,
|
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
|
// 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
|
// 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
|
// is a "zero-scope" element. This problem can be worked around by making
|
||||||
// the first node an invisible text node. We, like Modernizr, use ­
|
// the first node an invisible text node. We, like Modernizr, use ­
|
||||||
needsShy = (function(){
|
needsShy = document && (function(){
|
||||||
var testEl = document.createElement('div');
|
var testEl = document.createElement('div');
|
||||||
testEl.innerHTML = "<div></div>";
|
testEl.innerHTML = "<div></div>";
|
||||||
testEl.firstChild.innerHTML = "<script></script>";
|
testEl.firstChild.innerHTML = "<script></script>";
|
||||||
|
@ -16850,7 +16896,7 @@ define("metamorph",
|
||||||
// IE 8 (and likely earlier) likes to move whitespace preceeding
|
// IE 8 (and likely earlier) likes to move whitespace preceeding
|
||||||
// a script tag to appear after it. This means that we can
|
// a script tag to appear after it. This means that we can
|
||||||
// accidentally remove whitespace when updating a morph.
|
// accidentally remove whitespace when updating a morph.
|
||||||
movesWhitespace = (function() {
|
movesWhitespace = document && (function() {
|
||||||
var testEl = document.createElement('div');
|
var testEl = document.createElement('div');
|
||||||
testEl.innerHTML = "Test: <script type='text/x-placeholder'></script>Value";
|
testEl.innerHTML = "Test: <script type='text/x-placeholder'></script>Value";
|
||||||
return testEl.childNodes[0].nodeValue === 'Test:' &&
|
return testEl.childNodes[0].nodeValue === 'Test:' &&
|
||||||
|
@ -17294,7 +17340,10 @@ var objectCreate = Object.create || function(parent) {
|
||||||
return new F();
|
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');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17647,7 +17696,7 @@ Ember.Handlebars.registerHelper('helperMissing', function(path, options) {
|
||||||
|
|
||||||
## Example with bound options
|
## Example with bound options
|
||||||
|
|
||||||
Bound hash options are also supported. Example:
|
Bound hash options are also supported. Example:
|
||||||
|
|
||||||
```handlebars
|
```handlebars
|
||||||
{{repeat text countBinding="numRepeats"}}
|
{{repeat text countBinding="numRepeats"}}
|
||||||
|
@ -17685,15 +17734,15 @@ Ember.Handlebars.registerHelper('helperMissing', function(path, options) {
|
||||||
{{concatenate prop1 prop2 prop3}}. If any of the properties change,
|
{{concatenate prop1 prop2 prop3}}. If any of the properties change,
|
||||||
the helpr will re-render. Note that dependency keys cannot be
|
the helpr will re-render. Note that dependency keys cannot be
|
||||||
using in conjunction with multi-property helpers, since it is ambiguous
|
using in conjunction with multi-property helpers, since it is ambiguous
|
||||||
which property the dependent keys would belong to.
|
which property the dependent keys would belong to.
|
||||||
|
|
||||||
## Use with unbound helper
|
## Use with unbound helper
|
||||||
|
|
||||||
The {{unbound}} helper can be used with bound helper invocations
|
The {{unbound}} helper can be used with bound helper invocations
|
||||||
to render them in their unbound form, e.g.
|
to render them in their unbound form, e.g.
|
||||||
|
|
||||||
```handlebars
|
```handlebars
|
||||||
{{unbound capitalize name}}
|
{{unbound capitalize name}}
|
||||||
```
|
```
|
||||||
|
|
||||||
In this example, if the name property changes, the helper
|
In this example, if the name property changes, the helper
|
||||||
|
@ -17719,7 +17768,7 @@ Ember.Handlebars.registerBoundHelper = function(name, fn) {
|
||||||
view = data.view,
|
view = data.view,
|
||||||
currentContext = (options.contexts && options.contexts[0]) || this,
|
currentContext = (options.contexts && options.contexts[0]) || this,
|
||||||
normalized,
|
normalized,
|
||||||
pathRoot, path,
|
pathRoot, path,
|
||||||
loc, hashOption;
|
loc, hashOption;
|
||||||
|
|
||||||
// Detect bound options (e.g. countBinding="otherCount")
|
// Detect bound options (e.g. countBinding="otherCount")
|
||||||
|
@ -17824,7 +17873,7 @@ function evaluateMultiPropertyBoundHelper(context, fn, normalizedProperties, opt
|
||||||
// Assemble liast of watched properties that'll re-render this helper.
|
// Assemble liast of watched properties that'll re-render this helper.
|
||||||
watchedProperties = [];
|
watchedProperties = [];
|
||||||
for (boundOption in boundOptions) {
|
for (boundOption in boundOptions) {
|
||||||
if (boundOptions.hasOwnProperty(boundOption)) {
|
if (boundOptions.hasOwnProperty(boundOption)) {
|
||||||
watchedProperties.push(normalizePath(context, boundOptions[boundOption], data));
|
watchedProperties.push(normalizePath(context, boundOptions[boundOption], data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17953,22 +18002,30 @@ Ember.Handlebars.resolvePaths = function(options) {
|
||||||
var set = Ember.set, get = Ember.get;
|
var set = Ember.set, get = Ember.get;
|
||||||
var Metamorph = requireModule('metamorph');
|
var Metamorph = requireModule('metamorph');
|
||||||
|
|
||||||
|
function notifyMutationListeners() {
|
||||||
|
Ember.run.once(Ember.View, 'notifyMutationListeners');
|
||||||
|
}
|
||||||
|
|
||||||
// DOMManager should just abstract dom manipulation between jquery and metamorph
|
// DOMManager should just abstract dom manipulation between jquery and metamorph
|
||||||
var DOMManager = {
|
var DOMManager = {
|
||||||
remove: function(view) {
|
remove: function(view) {
|
||||||
view.morph.remove();
|
view.morph.remove();
|
||||||
|
notifyMutationListeners();
|
||||||
},
|
},
|
||||||
|
|
||||||
prepend: function(view, html) {
|
prepend: function(view, html) {
|
||||||
view.morph.prepend(html);
|
view.morph.prepend(html);
|
||||||
|
notifyMutationListeners();
|
||||||
},
|
},
|
||||||
|
|
||||||
after: function(view, html) {
|
after: function(view, html) {
|
||||||
view.morph.after(html);
|
view.morph.after(html);
|
||||||
|
notifyMutationListeners();
|
||||||
},
|
},
|
||||||
|
|
||||||
html: function(view, html) {
|
html: function(view, html) {
|
||||||
view.morph.html(html);
|
view.morph.html(html);
|
||||||
|
notifyMutationListeners();
|
||||||
},
|
},
|
||||||
|
|
||||||
// This is messed up.
|
// This is messed up.
|
||||||
|
@ -17991,11 +18048,13 @@ var DOMManager = {
|
||||||
morph.replaceWith(buffer.string());
|
morph.replaceWith(buffer.string());
|
||||||
view.transitionTo('inDOM');
|
view.transitionTo('inDOM');
|
||||||
view.triggerRecursively('didInsertElement');
|
view.triggerRecursively('didInsertElement');
|
||||||
|
notifyMutationListeners();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
empty: function(view) {
|
empty: function(view) {
|
||||||
view.morph.html("");
|
view.morph.html("");
|
||||||
|
notifyMutationListeners();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18757,14 +18816,14 @@ EmberHandlebars.registerHelper('unless', function(context, options) {
|
||||||
|
|
||||||
Result in the following rendered output:
|
Result in the following rendered output:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<img class="aValue">
|
<img class="aValue">
|
||||||
```
|
```
|
||||||
|
|
||||||
A boolean return value will insert a specified class name if the property
|
A boolean return value will insert a specified class name if the property
|
||||||
returns `true` and remove the class name if the property returns `false`.
|
returns `true` and remove the class name if the property returns `false`.
|
||||||
|
|
||||||
A class name is provided via the syntax
|
A class name is provided via the syntax
|
||||||
`somePropertyName:class-name-if-true`.
|
`somePropertyName:class-name-if-true`.
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
|
@ -18919,9 +18978,9 @@ EmberHandlebars.registerHelper('bindAttr', function(options) {
|
||||||
@method bindClasses
|
@method bindClasses
|
||||||
@for Ember.Handlebars
|
@for Ember.Handlebars
|
||||||
@param {Ember.Object} context The context from which to lookup properties
|
@param {Ember.Object} context The context from which to lookup properties
|
||||||
@param {String} classBindings A string, space-separated, of class bindings
|
@param {String} classBindings A string, space-separated, of class bindings
|
||||||
to use
|
to use
|
||||||
@param {Ember.View} view The view in which observers should look for the
|
@param {Ember.View} view The view in which observers should look for the
|
||||||
element to update
|
element to update
|
||||||
@param {Srting} bindAttrId Optional bindAttr id used to lookup elements
|
@param {Srting} bindAttrId Optional bindAttr id used to lookup elements
|
||||||
@return {Array} An array of class names to add
|
@return {Array} An array of class names to add
|
||||||
|
@ -19610,7 +19669,7 @@ Ember.Handlebars.registerHelper('unbound', function(property, fn) {
|
||||||
// Unbound helper call.
|
// Unbound helper call.
|
||||||
options.data.isUnbound = true;
|
options.data.isUnbound = true;
|
||||||
helper = Ember.Handlebars.helpers[arguments[0]] || Ember.Handlebars.helperMissing;
|
helper = Ember.Handlebars.helpers[arguments[0]] || Ember.Handlebars.helperMissing;
|
||||||
out = helper.apply(this, Array.prototype.slice.call(arguments, 1));
|
out = helper.apply(this, Array.prototype.slice.call(arguments, 1));
|
||||||
delete options.data.isUnbound;
|
delete options.data.isUnbound;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -20905,7 +20964,7 @@ helpers = helpers || Ember.Handlebars.helpers; data = data || {};
|
||||||
var buffer = '', stack1, hashTypes, escapeExpression=this.escapeExpression, self=this;
|
var buffer = '', stack1, hashTypes, escapeExpression=this.escapeExpression, self=this;
|
||||||
|
|
||||||
function program1(depth0,data) {
|
function program1(depth0,data) {
|
||||||
|
|
||||||
var buffer = '', hashTypes;
|
var buffer = '', hashTypes;
|
||||||
data.buffer.push("<option value=\"\">");
|
data.buffer.push("<option value=\"\">");
|
||||||
hashTypes = {};
|
hashTypes = {};
|
||||||
|
@ -20915,7 +20974,7 @@ function program1(depth0,data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function program3(depth0,data) {
|
function program3(depth0,data) {
|
||||||
|
|
||||||
var hashTypes;
|
var hashTypes;
|
||||||
hashTypes = {'contentBinding': "STRING"};
|
hashTypes = {'contentBinding': "STRING"};
|
||||||
data.buffer.push(escapeExpression(helpers.view.call(depth0, "Ember.SelectOption", {hash:{
|
data.buffer.push(escapeExpression(helpers.view.call(depth0, "Ember.SelectOption", {hash:{
|
||||||
|
@ -20930,7 +20989,7 @@ function program3(depth0,data) {
|
||||||
stack1 = helpers.each.call(depth0, "view.content", {hash:{},inverse:self.noop,fn:self.program(3, program3, data),contexts:[depth0],types:["ID"],hashTypes:hashTypes,data:data});
|
stack1 = helpers.each.call(depth0, "view.content", {hash:{},inverse:self.noop,fn:self.program(3, program3, data),contexts:[depth0],types:["ID"],hashTypes:hashTypes,data:data});
|
||||||
if(stack1 || stack1 === 0) { data.buffer.push(stack1); }
|
if(stack1 || stack1 === 0) { data.buffer.push(stack1); }
|
||||||
return buffer;
|
return buffer;
|
||||||
|
|
||||||
}),
|
}),
|
||||||
attributeBindings: ['multiple', 'disabled', 'tabindex'],
|
attributeBindings: ['multiple', 'disabled', 'tabindex'],
|
||||||
|
|
||||||
|
@ -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() {
|
(function() {
|
||||||
/**
|
/**
|
||||||
@module ember
|
@module ember
|
||||||
|
@ -23371,7 +23458,7 @@ function teardownView(route) {
|
||||||
var get = Ember.get, set = Ember.set;
|
var get = Ember.get, set = Ember.set;
|
||||||
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;
|
isSimpleClick = Ember.ViewUtils.isSimpleClick;
|
||||||
|
|
||||||
function fullRouteName(router, name) {
|
function fullRouteName(router, name) {
|
||||||
|
@ -23652,7 +23739,7 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
||||||
*/
|
*/
|
||||||
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;
|
isSimpleClick = Ember.ViewUtils.isSimpleClick;
|
||||||
|
|
||||||
var EmberHandlebars = Ember.Handlebars,
|
var EmberHandlebars = Ember.Handlebars,
|
||||||
|
@ -24277,7 +24364,7 @@ Ember.HashLocation = Ember.Object.extend({
|
||||||
|
|
||||||
set(self, 'lastSetURL', null);
|
set(self, 'lastSetURL', null);
|
||||||
|
|
||||||
callback(location.hash.substr(1));
|
callback(path);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -24655,11 +24742,14 @@ var get = Ember.get, set = Ember.set,
|
||||||
```
|
```
|
||||||
|
|
||||||
By default, calling `Ember.Application.create()` will automatically initialize
|
By default, calling `Ember.Application.create()` will automatically initialize
|
||||||
your application by calling the `Ember.Application.initialize()` method. If
|
your application by calling the `Ember.Application.initialize()` method. If
|
||||||
you need to delay initialization, you can call your app's `deferReadiness()`
|
you need to delay initialization, you can call your app's `deferReadiness()`
|
||||||
method. When you are ready for your app to be initialized, call its
|
method. When you are ready for your app to be initialized, call its
|
||||||
`advanceReadiness()` method.
|
`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
|
Because `Ember.Application` inherits from `Ember.Namespace`, any classes
|
||||||
you create will have useful string representations when calling `toString()`.
|
you create will have useful string representations when calling `toString()`.
|
||||||
See the `Ember.Namespace` documentation for more information.
|
See the `Ember.Namespace` documentation for more information.
|
||||||
|
@ -24854,10 +24944,13 @@ var Application = Ember.Application = Ember.Namespace.extend({
|
||||||
this.scheduleInitialize();
|
this.scheduleInitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( Ember.LOG_VERSION ) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25216,6 +25309,7 @@ Ember.Application.reopenClass({
|
||||||
Ember.Container.defaultContainer = Ember.Container.defaultContainer || container;
|
Ember.Container.defaultContainer = Ember.Container.defaultContainer || container;
|
||||||
|
|
||||||
container.set = Ember.set;
|
container.set = Ember.set;
|
||||||
|
container.normalize = normalize;
|
||||||
container.resolver = resolverFor(namespace);
|
container.resolver = resolverFor(namespace);
|
||||||
container.optionsForType('view', { singleton: false });
|
container.optionsForType('view', { singleton: false });
|
||||||
container.optionsForType('template', { instantiate: false });
|
container.optionsForType('template', { instantiate: false });
|
||||||
|
@ -25255,6 +25349,7 @@ function resolverFor(namespace) {
|
||||||
|
|
||||||
if (type === 'template') {
|
if (type === 'template') {
|
||||||
var templateName = name.replace(/\./g, '/');
|
var templateName = name.replace(/\./g, '/');
|
||||||
|
|
||||||
if (Ember.TEMPLATES[templateName]) {
|
if (Ember.TEMPLATES[templateName]) {
|
||||||
return 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);
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
|
Reference in a new issue