mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
Post Cloaking:
* We now use a new custom view, {{cloaked-collection}} to display posts in a topic.
* Posts are removed and inserted (cloaked/uncloaked) into the DOM dynamically based on whether they
are visible in the current browser viewport.
* There's been a lot of refactoring to ensure the relationship between the post views and the topic
controller is sane.
* Lots of fixes involving jumping to a post, including a new LockOn component to that tries to stay
focused on an element even if stuff is loading before it in the DOM that would normally push it
down.
This commit is contained in:
98
vendor/assets/javascripts/development/ember.js
vendored
98
vendor/assets/javascripts/development/ember.js
vendored
@@ -2258,7 +2258,7 @@ function suspendListener(obj, eventName, target, method, callback) {
|
||||
|
||||
Suspends multiple listeners during a callback.
|
||||
|
||||
|
||||
|
||||
@method suspendListeners
|
||||
@for Ember
|
||||
@param obj
|
||||
@@ -2326,7 +2326,7 @@ function watchedEvents(obj) {
|
||||
is skipped, and once listeners are removed. A listener without
|
||||
a target is executed on the passed object. If an array of actions
|
||||
is not passed, the actions stored on the passed object are invoked.
|
||||
|
||||
|
||||
@method sendEvent
|
||||
@for Ember
|
||||
@param obj
|
||||
@@ -3099,14 +3099,14 @@ Map.create = function() {
|
||||
Map.prototype = {
|
||||
/**
|
||||
This property will change as the number of objects in the map changes.
|
||||
|
||||
|
||||
@property length
|
||||
@type number
|
||||
@default 0
|
||||
*/
|
||||
length: 0,
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Retrieve the value associated with a given key.
|
||||
|
||||
@@ -12589,7 +12589,7 @@ Ember.computed.sort = function (itemsKey, sortDefinition) {
|
||||
(function() {
|
||||
/**
|
||||
Expose RSVP implementation
|
||||
|
||||
|
||||
Documentation can be found here: https://github.com/tildeio/rsvp.js/blob/master/README.md
|
||||
|
||||
@class RSVP
|
||||
@@ -14838,7 +14838,7 @@ function installPromise(proxy, promise) {
|
||||
controller.get('lastName') //=> 'Penner'
|
||||
```
|
||||
|
||||
If the controller is backing a template, the attributes are
|
||||
If the controller is backing a template, the attributes are
|
||||
bindable from within that template
|
||||
|
||||
```handlebars
|
||||
@@ -16338,7 +16338,7 @@ function classToString() {
|
||||
if (this[NAME_KEY]) {
|
||||
ret = this[NAME_KEY];
|
||||
} else if (this._toString) {
|
||||
ret = this._toString;
|
||||
ret = this._toString;
|
||||
} else {
|
||||
var str = superClassString(this);
|
||||
if (str) {
|
||||
@@ -17935,8 +17935,8 @@ var get = Ember.get, set = Ember.set, forEach = Ember.EnumerableUtils.forEach;
|
||||
```javascript
|
||||
songsController.get('content').get('firstObject'); // Returns the unsorted original content
|
||||
songsController.get('firstObject'); // Returns the sorted content.
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
Although the sorted content can also be accessed through the arrangedContent property,
|
||||
it is preferable to use the proxied class and not the arrangedContent array directly.
|
||||
|
||||
@@ -18025,7 +18025,7 @@ Ember.SortableMixin = Ember.Mixin.create(Ember.MutableEnumerable, {
|
||||
/**
|
||||
Overrides the default arrangedContent from arrayProxy in order to sort by sortFunction.
|
||||
Also sets up observers for each sortProperty on each item in the content Array.
|
||||
|
||||
|
||||
@property arrangedContent
|
||||
*/
|
||||
|
||||
@@ -22075,7 +22075,7 @@ Ember.merge(inBuffer, {
|
||||
// when a view is rendered in a buffer, rerendering it simply
|
||||
// replaces the existing buffer with a new one
|
||||
rerender: function(view) {
|
||||
throw new Ember.Error("Something you did caused a view to re-render after it rendered but before it was inserted into the DOM.");
|
||||
throw new Ember.Error("Something you did caused a view to re-render after it rendered but before it was inserted into the DOM." + view.get('content.id'));
|
||||
},
|
||||
|
||||
// when a view is rendered in a buffer, appending a child
|
||||
@@ -23581,7 +23581,7 @@ define("metamorph",
|
||||
|
||||
/**
|
||||
* @public
|
||||
*
|
||||
*
|
||||
* Remove this object (including starting and ending
|
||||
* placeholders).
|
||||
*
|
||||
@@ -27990,7 +27990,7 @@ helpers = this.merge(helpers, Ember.Handlebars.helpers); data = data || {};
|
||||
var buffer = '', stack1, hashTypes, hashContexts, escapeExpression=this.escapeExpression, self=this;
|
||||
|
||||
function program1(depth0,data) {
|
||||
|
||||
|
||||
var buffer = '', hashTypes, hashContexts;
|
||||
data.buffer.push("<option value=\"\">");
|
||||
hashTypes = {};
|
||||
@@ -28001,7 +28001,7 @@ function program1(depth0,data) {
|
||||
}
|
||||
|
||||
function program3(depth0,data) {
|
||||
|
||||
|
||||
var stack1, hashTypes, hashContexts;
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
@@ -28010,7 +28010,7 @@ function program3(depth0,data) {
|
||||
else { data.buffer.push(''); }
|
||||
}
|
||||
function program4(depth0,data) {
|
||||
|
||||
|
||||
var hashContexts, hashTypes;
|
||||
hashContexts = {'content': depth0,'label': depth0};
|
||||
hashTypes = {'content': "ID",'label': "ID"};
|
||||
@@ -28021,7 +28021,7 @@ function program4(depth0,data) {
|
||||
}
|
||||
|
||||
function program6(depth0,data) {
|
||||
|
||||
|
||||
var stack1, hashTypes, hashContexts;
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
@@ -28030,7 +28030,7 @@ function program6(depth0,data) {
|
||||
else { data.buffer.push(''); }
|
||||
}
|
||||
function program7(depth0,data) {
|
||||
|
||||
|
||||
var hashContexts, hashTypes;
|
||||
hashContexts = {'content': depth0};
|
||||
hashTypes = {'content': "ID"};
|
||||
@@ -28048,7 +28048,7 @@ function program7(depth0,data) {
|
||||
stack1 = helpers['if'].call(depth0, "view.optionGroupPath", {hash:{},inverse:self.program(6, program6, data),fn:self.program(3, program3, data),contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data});
|
||||
if(stack1 || stack1 === 0) { data.buffer.push(stack1); }
|
||||
return buffer;
|
||||
|
||||
|
||||
}),
|
||||
attributeBindings: ['multiple', 'disabled', 'tabindex', 'name'],
|
||||
|
||||
@@ -30515,7 +30515,7 @@ var get = Ember.get;
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
|
||||
Finds a controller instance.
|
||||
|
||||
@for Ember
|
||||
@@ -30531,7 +30531,7 @@ Ember.controllerFor = function(container, controllerName, lookupOptions) {
|
||||
The type of generated controller depends on the context.
|
||||
You can customize your generated controllers by defining
|
||||
`App.ObjectController` and `App.ArrayController`
|
||||
|
||||
|
||||
@for Ember
|
||||
@method generateController
|
||||
@private
|
||||
@@ -31237,7 +31237,7 @@ Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
|
||||
Transition into another route. Optionally supply model(s) for the
|
||||
route in question. If multiple models are supplied they will be applied
|
||||
last to first recursively up the resource tree (see Multiple Models Example
|
||||
below). The model(s) will be serialized into the URL using the appropriate
|
||||
below). The model(s) will be serialized into the URL using the appropriate
|
||||
route's `serialize` hook. See also 'replaceWith'.
|
||||
|
||||
Simple Transition Example
|
||||
@@ -31294,7 +31294,7 @@ Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
|
||||
|
||||
/**
|
||||
Transition into another route while replacing the current URL, if possible.
|
||||
This will replace the current history entry instead of adding a new one.
|
||||
This will replace the current history entry instead of adding a new one.
|
||||
Beside that, it is identical to `transitionTo` in all other respects. See
|
||||
'transitionTo' for additional information regarding multiple models.
|
||||
|
||||
@@ -32650,44 +32650,44 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
||||
|
||||
To override this option for your entire application, see
|
||||
"Overriding Application-wide Defaults".
|
||||
|
||||
|
||||
### Disabling the `link-to` helper
|
||||
By default `{{link-to}}` is enabled.
|
||||
By default `{{link-to}}` is enabled.
|
||||
any passed value to `disabled` helper property will disable the `link-to` helper.
|
||||
|
||||
|
||||
static use: the `disabled` option:
|
||||
|
||||
|
||||
```handlebars
|
||||
{{#link-to 'photoGallery' disabled=true}}
|
||||
Great Hamster Photos
|
||||
{{/link-to}}
|
||||
```
|
||||
|
||||
|
||||
dynamic use: the `disabledWhen` option:
|
||||
|
||||
|
||||
```handlebars
|
||||
{{#link-to 'photoGallery' disabledWhen=controller.someProperty}}
|
||||
Great Hamster Photos
|
||||
{{/link-to}}
|
||||
```
|
||||
|
||||
|
||||
any passed value to `disabled` will disable it except `undefined`.
|
||||
to ensure that only `true` disable the `link-to` helper you can
|
||||
override the global behaviour of `Ember.LinkView`.
|
||||
|
||||
```javascript
|
||||
|
||||
```javascript
|
||||
Ember.LinkView.reopen({
|
||||
disabled: Ember.computed(function(key, value) {
|
||||
if (value !== undefined) {
|
||||
this.set('_isDisabled', value === true);
|
||||
if (value !== undefined) {
|
||||
this.set('_isDisabled', value === true);
|
||||
}
|
||||
return value === true ? get(this, 'disabledClass') : false;
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
see "Overriding Application-wide Defaults" for more.
|
||||
|
||||
|
||||
### Handling `href`
|
||||
`{{link-to}}` will use your application's Router to
|
||||
fill the element's `href` property with a url that
|
||||
@@ -33007,13 +33007,13 @@ var get = Ember.get, set = Ember.set;
|
||||
Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
||||
|
||||
/**
|
||||
Calling ``{{render}}`` from within a template will insert another
|
||||
Calling ``{{render}}`` from within a template will insert another
|
||||
template that matches the provided name. The inserted template will
|
||||
access its properties on its own controller (rather than the controller
|
||||
of the parent template).
|
||||
|
||||
If a view class with the same name exists, the view class also will be used.
|
||||
|
||||
|
||||
Note: A given controller may only be used *once* in your app in this manner.
|
||||
A singleton instance of the controller will be created for you.
|
||||
|
||||
@@ -33035,7 +33035,7 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
||||
<h1>My great app</h1>
|
||||
{{render navigaton}}
|
||||
```
|
||||
|
||||
|
||||
```html
|
||||
<h1>My great app</h1>
|
||||
<div class='ember-view'>
|
||||
@@ -33259,8 +33259,8 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
||||
App.ApplicationController = Ember.Controller.extend({
|
||||
actions: {
|
||||
anActionName: function() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -33580,7 +33580,7 @@ Ember.ControllerMixin.reopen({
|
||||
this.resource('blogPost', {path:':blogPostId'}, function(){
|
||||
this.resource('blogComment', {path: ':blogCommentId'});
|
||||
});
|
||||
|
||||
|
||||
aController.transitionToRoute('blogComment', aPost, aComment);
|
||||
```
|
||||
|
||||
@@ -33611,7 +33611,7 @@ Ember.ControllerMixin.reopen({
|
||||
|
||||
/**
|
||||
Transition into another route while replacing the current URL, if possible.
|
||||
This will replace the current history entry instead of adding a new one.
|
||||
This will replace the current history entry instead of adding a new one.
|
||||
Beside that, it is identical to `transitionToRoute` in all other respects.
|
||||
|
||||
```javascript
|
||||
@@ -33635,7 +33635,7 @@ Ember.ControllerMixin.reopen({
|
||||
this.resource('blogPost', {path:':blogPostId'}, function(){
|
||||
this.resource('blogComment', {path: ':blogCommentId'});
|
||||
});
|
||||
|
||||
|
||||
aController.replaceRoute('blogComment', aPost, aComment);
|
||||
```
|
||||
|
||||
@@ -33825,7 +33825,7 @@ Ember.View.reopen({
|
||||
|
||||
// Add a new named queue after the 'actions' queue (where RSVP promises
|
||||
// resolve), which is used in router transitions to prevent unnecessary
|
||||
// loading state entry if all context promises resolve on the
|
||||
// loading state entry if all context promises resolve on the
|
||||
// 'actions' queue first.
|
||||
|
||||
var queues = Ember.run.queues,
|
||||
@@ -35165,7 +35165,7 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
|
||||
Call `advanceReadiness` after any asynchronous setup logic has completed.
|
||||
Each call to `deferReadiness` must be matched by a call to `advanceReadiness`
|
||||
or the application will never become ready and routing will not begin.
|
||||
|
||||
|
||||
@method advanceReadiness
|
||||
@see {Ember.Application#deferReadiness}
|
||||
*/
|
||||
@@ -36220,7 +36220,7 @@ var slice = [].slice,
|
||||
* Register/Unregister additional test helpers.
|
||||
* Setup callbacks to be fired when the test helpers are injected into
|
||||
your application.
|
||||
|
||||
|
||||
@class Test
|
||||
@namespace Ember
|
||||
*/
|
||||
@@ -36967,7 +36967,7 @@ Ember.StateManager = generateRemovedClass("Ember.StateManager");
|
||||
|
||||
/**
|
||||
This was exported to ember-states plugin for v 1.0.0 release. See: https://github.com/emberjs/ember-states
|
||||
|
||||
|
||||
@class StateManager
|
||||
@namespace Ember
|
||||
*/
|
||||
@@ -36976,7 +36976,7 @@ Ember.State = generateRemovedClass("Ember.State");
|
||||
|
||||
/**
|
||||
This was exported to ember-states plugin for v 1.0.0 release. See: https://github.com/emberjs/ember-states
|
||||
|
||||
|
||||
@class State
|
||||
@namespace Ember
|
||||
*/
|
||||
|
||||
54
vendor/assets/javascripts/lock-on.js
vendored
Normal file
54
vendor/assets/javascripts/lock-on.js
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
(function (exports) {
|
||||
|
||||
var scrollEvents = "scroll.lock-on touchmove.lock-on mousedown.lock-on wheel.lock-on DOMMouseScroll.lock-on mousewheel.lock-on keyup.lock-on";
|
||||
|
||||
var LockOn = function(selector, options) {
|
||||
this.selector = selector;
|
||||
this.options = options || {};
|
||||
};
|
||||
|
||||
LockOn.prototype.elementTop = function() {
|
||||
var offsetCalculator = this.options.offsetCalculator;
|
||||
return $(this.selector).offset().top - (offsetCalculator ? offsetCalculator() : 0);
|
||||
};
|
||||
|
||||
LockOn.prototype.lock = function() {
|
||||
var self = this,
|
||||
previousTop = this.elementTop(),
|
||||
startedAt = new Date().getTime()
|
||||
i = 0;
|
||||
|
||||
$(window).scrollTop(previousTop);
|
||||
|
||||
var interval = setInterval(function() {
|
||||
i = i + 1;
|
||||
|
||||
var top = self.elementTop(),
|
||||
scrollTop = $(window).scrollTop();
|
||||
|
||||
if ((top !== previousTop) || (scrollTop !== top)) {
|
||||
$(window).scrollTop(top);
|
||||
previousTop = top;
|
||||
}
|
||||
|
||||
// We commit suicide after 1s just to clean up
|
||||
var nowTime = new Date().getTime();
|
||||
if (nowTime - startedAt > 1000) {
|
||||
$('body,html').off(scrollEvents)
|
||||
clearInterval(interval);
|
||||
}
|
||||
|
||||
}, 50);
|
||||
|
||||
$('body,html').off(scrollEvents).on(scrollEvents, function(e){
|
||||
if ( e.which > 0 || e.type === "mousedown" || e.type === "mousewheel" || e.type === "touchmove") {
|
||||
$('body,html').off(scrollEvents);
|
||||
clearInterval(interval);
|
||||
}
|
||||
})
|
||||
|
||||
};
|
||||
|
||||
exports.LockOn = LockOn;
|
||||
|
||||
})(window);
|
||||
Reference in New Issue
Block a user