Ember 1.12 support
This commit is contained in:
parent
02a968bd27
commit
22844b9e46
|
@ -20,5 +20,5 @@ vendor/
|
|||
test/javascripts/helpers/
|
||||
test/javascripts/test_helper.js
|
||||
test/javascripts/test_helper.js
|
||||
test/javascripts/fixtures
|
||||
app/assets/javascripts/ember-addons/
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
{
|
||||
"env": {
|
||||
"jasmine": true,
|
||||
"node": true,
|
||||
"mocha": true,
|
||||
"browser": true,
|
||||
"builtin": true
|
||||
},
|
||||
ecmaVersion: 7,
|
||||
"globals":
|
||||
{"Ember":true,
|
||||
"jQuery":true,
|
||||
"$":true,
|
||||
"RSVP":true,
|
||||
"Discourse":true,
|
||||
"Em":true,
|
||||
"PreloadStore":true,
|
||||
"Handlebars":true,
|
||||
"I18n":true,
|
||||
"bootbox":true,
|
||||
"module":true,
|
||||
"moduleFor":true,
|
||||
"moduleForComponent":true,
|
||||
"Pretender":true,
|
||||
"sandbox":true,
|
||||
"controllerFor":true,
|
||||
"test":true,
|
||||
"ok":true,
|
||||
"not":true,
|
||||
"expect":true,
|
||||
"equal":true,
|
||||
"visit":true,
|
||||
"andThen":true,
|
||||
"click":true,
|
||||
"currentPath":true,
|
||||
"currentRouteName":true,
|
||||
"currentURL":true,
|
||||
"fillIn":true,
|
||||
"keyEvent":true,
|
||||
"triggerEvent":true,
|
||||
"count":true,
|
||||
"exists":true,
|
||||
"visible":true,
|
||||
"invisible":true,
|
||||
"asyncRender":true,
|
||||
"selectDropdown":true,
|
||||
"asyncTestDiscourse":true,
|
||||
"fixture":true,
|
||||
"find":true,
|
||||
"sinon":true,
|
||||
"moment":true,
|
||||
"start":true,
|
||||
"_":true,
|
||||
"alert":true,
|
||||
"containsInstance":true,
|
||||
"deepEqual":true,
|
||||
"notEqual":true,
|
||||
"define":true,
|
||||
"require":true,
|
||||
"requirejs":true,
|
||||
"hasModule":true,
|
||||
"Blob":true,
|
||||
"File":true},
|
||||
"rules": {
|
||||
"block-scoped-var": 2,
|
||||
"dot-notation": 0,
|
||||
"eqeqeq": [
|
||||
2,
|
||||
"allow-null"
|
||||
],
|
||||
"guard-for-in": 2,
|
||||
"no-bitwise": 2,
|
||||
"no-caller": 2,
|
||||
"no-cond-assign": 0,
|
||||
"no-debugger": 2,
|
||||
"no-empty": 0,
|
||||
"no-eval": 2,
|
||||
"no-extend-native": 2,
|
||||
"no-extra-parens": 0,
|
||||
"no-irregular-whitespace": 2,
|
||||
"no-iterator": 2,
|
||||
"no-loop-func": 2,
|
||||
"no-multi-str": 2,
|
||||
"no-new": 2,
|
||||
"no-plusplus": 0,
|
||||
"no-proto": 2,
|
||||
"no-script-url": 2,
|
||||
"no-sequences": 2,
|
||||
"no-shadow": 2,
|
||||
"no-undef": 2,
|
||||
"no-unused-vars": 2,
|
||||
"no-with": 2,
|
||||
"semi": [
|
||||
0,
|
||||
"never"
|
||||
],
|
||||
"strict": 0,
|
||||
"valid-typeof": 2,
|
||||
"wrap-iife": [
|
||||
2,
|
||||
"inside"
|
||||
]
|
||||
},
|
||||
"parser": "babel-eslint"
|
||||
}
|
83
.jshintrc
83
.jshintrc
|
@ -1,83 +0,0 @@
|
|||
{
|
||||
"predef":["Ember",
|
||||
"jQuery",
|
||||
"$",
|
||||
"RSVP",
|
||||
"Discourse",
|
||||
"Em",
|
||||
"PreloadStore",
|
||||
"Handlebars",
|
||||
"I18n",
|
||||
"bootbox",
|
||||
"module",
|
||||
"moduleFor",
|
||||
"moduleForComponent",
|
||||
"Pretender",
|
||||
"sandbox",
|
||||
"controllerFor",
|
||||
"test",
|
||||
"ok",
|
||||
"not",
|
||||
"expect",
|
||||
"equal",
|
||||
"visit",
|
||||
"andThen",
|
||||
"click",
|
||||
"currentPath",
|
||||
"currentRouteName",
|
||||
"currentURL",
|
||||
"fillIn",
|
||||
"keyEvent",
|
||||
"triggerEvent",
|
||||
"count",
|
||||
"exists",
|
||||
"visible",
|
||||
"invisible",
|
||||
"asyncRender",
|
||||
"selectDropdown",
|
||||
"asyncTestDiscourse",
|
||||
"fixture",
|
||||
"find",
|
||||
"sinon",
|
||||
"moment",
|
||||
"start",
|
||||
"_",
|
||||
"alert",
|
||||
"containsInstance",
|
||||
"deepEqual",
|
||||
"notEqual",
|
||||
"define",
|
||||
"require",
|
||||
"requirejs",
|
||||
"hasModule",
|
||||
"Blob",
|
||||
"File"],
|
||||
"node" : false,
|
||||
"browser" : true,
|
||||
"boss" : true,
|
||||
"curly": false,
|
||||
"debug": false,
|
||||
"devel": false,
|
||||
"eqeqeq": true,
|
||||
"evil": true,
|
||||
"forin": false,
|
||||
"immed": false,
|
||||
"laxbreak": false,
|
||||
"newcap": true,
|
||||
"noarg": true,
|
||||
"noempty": false,
|
||||
"nonew": false,
|
||||
"nomen": false,
|
||||
"onevar": false,
|
||||
"plusplus": false,
|
||||
"regexp": false,
|
||||
"undef": true,
|
||||
"unused": true,
|
||||
"sub": true,
|
||||
"strict": false,
|
||||
"white": false,
|
||||
"eqnull": true,
|
||||
"quotmark": false,
|
||||
"lastsemic": true,
|
||||
"esnext": true
|
||||
}
|
|
@ -46,9 +46,9 @@ GEM
|
|||
multi_json (~> 1.0)
|
||||
aws-sdk-resources (2.0.45)
|
||||
aws-sdk-core (= 2.0.45)
|
||||
babel-source (4.6.6)
|
||||
babel-transpiler (0.6.0)
|
||||
babel-source (>= 4.0, < 5)
|
||||
babel-source (5.8.19)
|
||||
babel-transpiler (0.7.0)
|
||||
babel-source (>= 4.0, < 6)
|
||||
execjs (~> 2.0)
|
||||
barber (0.9.0)
|
||||
ember-source (>= 1.0, < 2)
|
||||
|
@ -86,7 +86,7 @@ GEM
|
|||
ember-source (>= 1.1.0)
|
||||
jquery-rails (>= 1.0.17)
|
||||
railties (>= 3.1)
|
||||
ember-source (1.11.3.1)
|
||||
ember-source (1.12.1)
|
||||
erubis (2.7.0)
|
||||
eventmachine (1.0.7)
|
||||
excon (0.45.3)
|
||||
|
|
|
@ -2,6 +2,7 @@ import BufferedContent from 'discourse/mixins/buffered-content';
|
|||
import ScrollTop from 'discourse/mixins/scroll-top';
|
||||
import SiteSetting from 'admin/models/site-setting';
|
||||
import { propertyNotEqual } from 'discourse/lib/computed';
|
||||
import computed from 'ember-addons/ember-computed-decorators';
|
||||
|
||||
const CustomTypes = ['bool', 'enum', 'list', 'url_list', 'host_list'];
|
||||
|
||||
|
@ -20,19 +21,22 @@ export default Ember.Component.extend(BufferedContent, ScrollTop, {
|
|||
}
|
||||
}.property('buffered.value'),
|
||||
|
||||
typeClass: function() {
|
||||
@computed('partialType')
|
||||
typeClass() {
|
||||
return this.get('partialType').replace("_", "-");
|
||||
}.property('partialType'),
|
||||
},
|
||||
|
||||
enabled: function(key, value) {
|
||||
if (arguments.length > 1) {
|
||||
@computed('buffered.value')
|
||||
enabled: {
|
||||
get() {
|
||||
const bufferedValue = this.get('buffered.value');
|
||||
if (Ember.isEmpty(bufferedValue)) { return false; }
|
||||
return bufferedValue === 'true';
|
||||
},
|
||||
set(key, value) {
|
||||
this.set('buffered.value', value ? 'true' : 'false');
|
||||
}
|
||||
|
||||
const bufferedValue = this.get('buffered.value');
|
||||
if (Ember.isEmpty(bufferedValue)) { return false; }
|
||||
return bufferedValue === 'true';
|
||||
}.property('buffered.value'),
|
||||
},
|
||||
|
||||
settingName: function() {
|
||||
return this.get('setting.setting').replace(/\_/g, ' ');
|
||||
|
@ -40,7 +44,7 @@ export default Ember.Component.extend(BufferedContent, ScrollTop, {
|
|||
|
||||
partialType: function() {
|
||||
let type = this.get('setting.type');
|
||||
return (CustomTypes.indexOf(type) !== -1) ? type : 'string';
|
||||
return CustomTypes.indexOf(type) !== -1 ? type : 'string';
|
||||
}.property('setting.type'),
|
||||
|
||||
partialName: function() {
|
||||
|
|
|
@ -3,7 +3,7 @@ var DiscourseResolver = require('discourse/ember/resolver').default;
|
|||
|
||||
// Allow us to import Ember
|
||||
define('ember', ['exports'], function(__exports__) {
|
||||
__exports__["default"] = Ember;
|
||||
__exports__.default = Ember;
|
||||
});
|
||||
|
||||
window.Discourse = Ember.Application.createWithMixins(Discourse.Ajax, {
|
||||
|
@ -16,7 +16,7 @@ window.Discourse = Ember.Application.createWithMixins(Discourse.Ajax, {
|
|||
// if it's a non relative URL, return it.
|
||||
if (!/^\/[^\/]/.test(url)) return url;
|
||||
|
||||
var u = (Discourse.BaseUri === undefined ? "/" : Discourse.BaseUri);
|
||||
var u = Discourse.BaseUri === undefined ? "/" : Discourse.BaseUri;
|
||||
|
||||
if (u[u.length-1] === '/') u = u.substring(0, u.length-1);
|
||||
if (url.indexOf(u) !== -1) return url;
|
||||
|
@ -66,7 +66,7 @@ window.Discourse = Ember.Application.createWithMixins(Discourse.Ajax, {
|
|||
// The classes of buttons to show on a post
|
||||
postButtons: function() {
|
||||
return Discourse.SiteSettings.post_menu.split("|").map(function(i) {
|
||||
return (i.replace(/\+/, '').capitalize());
|
||||
return i.replace(/\+/, '').capitalize();
|
||||
});
|
||||
}.property(),
|
||||
|
||||
|
@ -109,12 +109,26 @@ window.Discourse = Ember.Application.createWithMixins(Discourse.Ajax, {
|
|||
|
||||
$('noscript').remove();
|
||||
|
||||
// Load any ES6 initializers
|
||||
Ember.keys(requirejs._eak_seen).forEach(function(key) {
|
||||
if (/\/pre\-initializers\//.test(key)) {
|
||||
var module = require(key, null, null, true);
|
||||
if (!module) { throw new Error(key + ' must export an initializer.'); }
|
||||
Discourse.initializer(module.default);
|
||||
}
|
||||
});
|
||||
|
||||
Ember.keys(requirejs._eak_seen).forEach(function(key) {
|
||||
if (/\/initializers\//.test(key)) {
|
||||
var module = require(key, null, null, true);
|
||||
if (!module) { throw new Error(key + ' must export an initializer.'); }
|
||||
Discourse.initializer(module.default);
|
||||
|
||||
var init = module.default;
|
||||
var oldInitialize = init.initialize;
|
||||
init.initialize = function(app) {
|
||||
oldInitialize.call(this, app.container, app);
|
||||
};
|
||||
|
||||
Discourse.instanceInitializer(init);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -125,17 +139,22 @@ window.Discourse = Ember.Application.createWithMixins(Discourse.Ajax, {
|
|||
return desired && Discourse.get("currentAssetVersion") !== desired;
|
||||
}.property("currentAssetVersion", "desiredAssetVersion"),
|
||||
|
||||
assetVersion: function(prop, val) {
|
||||
if(val) {
|
||||
if(this.get("currentAssetVersion")){
|
||||
this.set("desiredAssetVersion", val);
|
||||
} else {
|
||||
this.set("currentAssetVersion", val);
|
||||
}
|
||||
}
|
||||
return this.get("currentAssetVersion");
|
||||
}.property()
|
||||
|
||||
assetVersion: Ember.computed({
|
||||
get: function() {
|
||||
return this.get("currentAssetVersion");
|
||||
},
|
||||
set: function(key, val) {
|
||||
if(val) {
|
||||
if (this.get("currentAssetVersion")) {
|
||||
this.set("desiredAssetVersion", val);
|
||||
} else {
|
||||
this.set("currentAssetVersion", val);
|
||||
}
|
||||
}
|
||||
return this.get("currentAssetVersion");
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// TODO: Remove this, it is in for backwards compatibiltiy with plugins
|
||||
|
@ -159,5 +178,3 @@ proxyDep('URL', function() { return require('discourse/lib/url').default });
|
|||
proxyDep('Quote', function() { return require('discourse/lib/quote').default });
|
||||
proxyDep('debounce', function() { return require('discourse/lib/debounce').default });
|
||||
proxyDep('View', function() { return Ember.View }, "Use `Ember.View` instead");
|
||||
proxyDep('Controller', function() { return Ember.Controller }, "Use `Ember.Controller` instead");
|
||||
proxyDep('ObjectController', function() { return Ember.ObjectController }, "Use `Ember.Controller` instead");
|
||||
|
|
|
@ -1,23 +1,31 @@
|
|||
import computed from 'ember-addons/ember-computed-decorators';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNames: ['controls'],
|
||||
|
||||
notificationsPermission: function() {
|
||||
@computed
|
||||
notificationsPermission() {
|
||||
if (this.get('isNotSupported')) return '';
|
||||
|
||||
return Notification.permission;
|
||||
}.property(),
|
||||
},
|
||||
|
||||
notificationsDisabled: function(_, value) {
|
||||
if (arguments.length > 1) {
|
||||
localStorage.setItem('notifications-disabled', value);
|
||||
@computed
|
||||
notificationsDisabled: {
|
||||
set(key, value) {
|
||||
if (arguments.length > 1) {
|
||||
localStorage.setItem('notifications-disabled', value);
|
||||
}
|
||||
return localStorage.getItem('notifications-disabled');
|
||||
},
|
||||
get() {
|
||||
return localStorage.getItem('notifications-disabled');
|
||||
}
|
||||
return localStorage.getItem('notifications-disabled');
|
||||
}.property(),
|
||||
},
|
||||
|
||||
|
||||
isNotSupported: function() {
|
||||
return !window['Notification'];
|
||||
}.property(),
|
||||
@computed
|
||||
isNotSupported() {
|
||||
return typeof window.Notification === "undefined";
|
||||
},
|
||||
|
||||
isDefaultPermission: function() {
|
||||
if (this.get('isNotSupported')) return false;
|
||||
|
|
|
@ -50,7 +50,7 @@ export default Ember.Controller.extend({
|
|||
// create a marker element
|
||||
const markerElement = document.createElement("span");
|
||||
// containing a single invisible character
|
||||
markerElement.appendChild(document.createTextNode("\u{feff}"));
|
||||
markerElement.appendChild(document.createTextNode("\ufeff"));
|
||||
|
||||
// collapse the range at the beginning/end of the selection
|
||||
range.collapse(!Discourse.Mobile.isMobileDevice);
|
||||
|
|
|
@ -1,20 +1,27 @@
|
|||
import searchForTerm from 'discourse/lib/search-for-term';
|
||||
import DiscourseURL from 'discourse/lib/url';
|
||||
import computed from 'ember-addons/ember-computed-decorators';
|
||||
|
||||
let _dontSearch = false;
|
||||
|
||||
export default Em.Controller.extend({
|
||||
typeFilter: null,
|
||||
|
||||
contextType: function(key, value){
|
||||
if(arguments.length > 1) {
|
||||
@computed('searchContext')
|
||||
contextType: {
|
||||
get(searchContext) {
|
||||
if (searchContext) {
|
||||
return Ember.get(searchContext, 'type');
|
||||
}
|
||||
},
|
||||
set(key, value) {
|
||||
// a bit hacky, consider cleaning this up, need to work through all observers though
|
||||
const context = $.extend({}, this.get('searchContext'));
|
||||
context.type = value;
|
||||
this.set('searchContext', context);
|
||||
return this.get('searchContext.type');
|
||||
}
|
||||
return this.get('searchContext.type');
|
||||
}.property('searchContext'),
|
||||
},
|
||||
|
||||
contextChanged: function(){
|
||||
if (this.get('searchContextEnabled')) {
|
||||
|
|
|
@ -4,6 +4,7 @@ import { spinnerHTML } from 'discourse/helpers/loading-spinner';
|
|||
import Topic from 'discourse/models/topic';
|
||||
import Quote from 'discourse/lib/quote';
|
||||
import { setting } from 'discourse/lib/computed';
|
||||
import computed from 'ember-addons/ember-computed-decorators';
|
||||
|
||||
export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, {
|
||||
multiSelect: false,
|
||||
|
@ -65,35 +66,53 @@ export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, {
|
|||
|
||||
}.observes('model.postStream', 'model.postStream.loadedAllPosts'),
|
||||
|
||||
show_deleted: function(key, value) {
|
||||
const postStream = this.get('model.postStream');
|
||||
if (!postStream) { return; }
|
||||
@computed('model.postStream.summary')
|
||||
show_deleted: {
|
||||
set(key, value) {
|
||||
const postStream = this.get('model.postStream');
|
||||
if (!postStream) { return; }
|
||||
|
||||
if (arguments.length > 1) {
|
||||
postStream.set('show_deleted', value);
|
||||
if (arguments.length > 1) {
|
||||
postStream.set('show_deleted', value);
|
||||
}
|
||||
return postStream.get('show_deleted') ? true : undefined;
|
||||
},
|
||||
get() {
|
||||
return this.get('postStream.show_deleted') ? true : undefined;
|
||||
}
|
||||
return postStream.get('show_deleted') ? true : undefined;
|
||||
}.property('model.postStream.summary'),
|
||||
},
|
||||
|
||||
filter: function(key, value) {
|
||||
const postStream = this.get('model.postStream');
|
||||
if (!postStream) { return; }
|
||||
@computed('model.postStream.summary')
|
||||
filter: {
|
||||
set(key, value) {
|
||||
const postStream = this.get('model.postStream');
|
||||
if (!postStream) { return; }
|
||||
|
||||
if (arguments.length > 1) {
|
||||
postStream.set('summary', value === "summary");
|
||||
if (arguments.length > 1) {
|
||||
postStream.set('summary', value === "summary");
|
||||
}
|
||||
return postStream.get('summary') ? "summary" : undefined;
|
||||
},
|
||||
get() {
|
||||
return this.get('postStream.summary') ? "summary" : undefined;
|
||||
}
|
||||
return postStream.get('summary') ? "summary" : undefined;
|
||||
}.property('model.postStream.summary'),
|
||||
},
|
||||
|
||||
username_filters: function(key, value) {
|
||||
const postStream = this.get('model.postStream');
|
||||
if (!postStream) { return; }
|
||||
@computed('model.postStream.streamFilters.username_filters')
|
||||
username_filters: {
|
||||
set(key, value) {
|
||||
const postStream = this.get('model.postStream');
|
||||
if (!postStream) { return; }
|
||||
|
||||
if (arguments.length > 1) {
|
||||
postStream.set('streamFilters.username_filters', value);
|
||||
if (arguments.length > 1) {
|
||||
postStream.set('streamFilters.username_filters', value);
|
||||
}
|
||||
return postStream.get('streamFilters.username_filters');
|
||||
},
|
||||
get() {
|
||||
return this.get('postStream.streamFilters.username_filters');
|
||||
}
|
||||
return postStream.get('streamFilters.username_filters');
|
||||
}.property('model.postStream.streamFilters.username_filters'),
|
||||
},
|
||||
|
||||
_clearSelected: function() {
|
||||
this.set('selectedPosts', []);
|
||||
|
@ -489,13 +508,13 @@ export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, {
|
|||
|
||||
canMergeTopic: function() {
|
||||
if (!this.get('model.details.can_move_posts')) return false;
|
||||
return (this.get('selectedPostsCount') > 0);
|
||||
return this.get('selectedPostsCount') > 0;
|
||||
}.property('selectedPostsCount'),
|
||||
|
||||
canSplitTopic: function() {
|
||||
if (!this.get('model.details.can_move_posts')) return false;
|
||||
if (this.get('allPostsSelected')) return false;
|
||||
return (this.get('selectedPostsCount') > 0);
|
||||
return this.get('selectedPostsCount') > 0;
|
||||
}.property('selectedPostsCount'),
|
||||
|
||||
canChangeOwner: function() {
|
||||
|
|
|
@ -2,6 +2,5 @@ import { applyFlaggedProperties } from 'discourse/controllers/header';
|
|||
|
||||
export default {
|
||||
name: 'apply-flagged-properties',
|
||||
after: 'register-discourse-location',
|
||||
initialize: applyFlaggedProperties
|
||||
};
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// Append our CSRF token to AJAX requests when necessary.
|
||||
export default {
|
||||
name: "csrf-token",
|
||||
after: 'inject-objects',
|
||||
initialize: function(container) {
|
||||
|
||||
var session = container.lookup('session:main');
|
||||
|
|
|
@ -2,7 +2,6 @@ import { showSelector } from "discourse/lib/emoji/emoji-toolbar";
|
|||
|
||||
export default {
|
||||
name: 'enable-emoji',
|
||||
after: 'inject-objects',
|
||||
|
||||
initialize(container) {
|
||||
const siteSettings = container.lookup('site-settings:main');
|
||||
|
|
|
@ -1,50 +1,6 @@
|
|||
import Session from 'discourse/models/session';
|
||||
import AppEvents from 'discourse/lib/app-events';
|
||||
import Store from 'discourse/models/store';
|
||||
import DiscourseURL from 'discourse/lib/url';
|
||||
|
||||
function inject() {
|
||||
const app = arguments[0],
|
||||
name = arguments[1],
|
||||
singletonName = Ember.String.underscore(name).replace(/_/, '-') + ':main';
|
||||
|
||||
Array.prototype.slice.call(arguments, 2).forEach(function(dest) {
|
||||
app.inject(dest, name, singletonName);
|
||||
});
|
||||
}
|
||||
|
||||
function injectAll(app, name) {
|
||||
inject(app, name, 'controller', 'component', 'route', 'view', 'model');
|
||||
}
|
||||
// backwards compatibility for plugins that depend on this initializer
|
||||
|
||||
export default {
|
||||
name: "inject-objects",
|
||||
initialize(container, app) {
|
||||
const appEvents = AppEvents.create();
|
||||
app.register('app-events:main', appEvents, { instantiate: false });
|
||||
injectAll(app, 'appEvents');
|
||||
DiscourseURL.appEvents = appEvents;
|
||||
|
||||
app.register('store:main', Store);
|
||||
inject(app, 'store', 'route', 'controller');
|
||||
|
||||
// Inject Discourse.Site to avoid using Discourse.Site.current()
|
||||
const site = Discourse.Site.current();
|
||||
app.register('site:main', site, { instantiate: false });
|
||||
injectAll(app, 'site');
|
||||
|
||||
// Inject Discourse.SiteSettings to avoid using Discourse.SiteSettings globals
|
||||
app.register('site-settings:main', Discourse.SiteSettings, { instantiate: false });
|
||||
injectAll(app, 'siteSettings');
|
||||
|
||||
// Inject Session for transient data
|
||||
app.register('session:main', Session.current(), { instantiate: false });
|
||||
injectAll(app, 'session');
|
||||
|
||||
app.register('current-user:main', Discourse.User.current(), { instantiate: false });
|
||||
inject(app, 'currentUser', 'component', 'route', 'controller');
|
||||
|
||||
app.register('message-bus:main', window.MessageBus, { instantiate: false });
|
||||
inject(app, 'messageBus', 'route', 'controller', 'view', 'component');
|
||||
}
|
||||
initialize: Ember.K
|
||||
};
|
||||
|
|
|
@ -3,7 +3,6 @@ import PageTracker from 'discourse/lib/page-tracker';
|
|||
|
||||
export default {
|
||||
name: "page-tracking",
|
||||
after: 'register-discourse-location',
|
||||
|
||||
initialize(container) {
|
||||
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
import DiscourseLocation from 'discourse/lib/discourse-location';
|
||||
// backwards compatibility for plugins that depend on this initializer
|
||||
|
||||
export default {
|
||||
name: "register-discourse-location",
|
||||
after: 'inject-objects',
|
||||
|
||||
initialize: function(container, application) {
|
||||
application.register('location:discourse-location', DiscourseLocation);
|
||||
}
|
||||
initialize: Ember.K
|
||||
};
|
||||
|
|
|
@ -4,14 +4,13 @@ import DiscoverySortableController from 'discourse/controllers/discovery-sortabl
|
|||
|
||||
export default {
|
||||
name: 'dynamic-route-builders',
|
||||
after: 'register-discourse-location',
|
||||
|
||||
initialize(container, app) {
|
||||
app.DiscoveryCategoryRoute = buildCategoryRoute('latest');
|
||||
app.DiscoveryParentCategoryRoute = buildCategoryRoute('latest');
|
||||
app.DiscoveryCategoryNoneRoute = buildCategoryRoute('latest', {no_subcategories: true});
|
||||
|
||||
var site = container.lookup('site:main');
|
||||
const site = Discourse.Site.current();
|
||||
site.get('filters').forEach(function(filter) {
|
||||
app["Discovery" + filter.capitalize() + "Controller"] = DiscoverySortableController.extend();
|
||||
app["Discovery" + filter.capitalize() + "Route"] = buildTopicRoute(filter);
|
|
@ -0,0 +1,53 @@
|
|||
import Session from 'discourse/models/session';
|
||||
import AppEvents from 'discourse/lib/app-events';
|
||||
import Store from 'discourse/models/store';
|
||||
import DiscourseURL from 'discourse/lib/url';
|
||||
import DiscourseLocation from 'discourse/lib/discourse-location';
|
||||
|
||||
function inject() {
|
||||
const app = arguments[0],
|
||||
name = arguments[1],
|
||||
singletonName = Ember.String.underscore(name).replace(/_/, '-') + ':main';
|
||||
|
||||
Array.prototype.slice.call(arguments, 2).forEach(function(dest) {
|
||||
app.inject(dest, name, singletonName);
|
||||
});
|
||||
}
|
||||
|
||||
function injectAll(app, name) {
|
||||
inject(app, name, 'controller', 'component', 'route', 'view', 'model');
|
||||
}
|
||||
|
||||
export default {
|
||||
name: "inject-discourse-objects",
|
||||
initialize(container, app) {
|
||||
const appEvents = AppEvents.create();
|
||||
app.register('app-events:main', appEvents, { instantiate: false });
|
||||
injectAll(app, 'appEvents');
|
||||
DiscourseURL.appEvents = appEvents;
|
||||
|
||||
app.register('store:main', Store);
|
||||
inject(app, 'store', 'route', 'controller');
|
||||
|
||||
// Inject Discourse.Site to avoid using Discourse.Site.current()
|
||||
const site = Discourse.Site.current();
|
||||
app.register('site:main', site, { instantiate: false });
|
||||
injectAll(app, 'site');
|
||||
|
||||
// Inject Discourse.SiteSettings to avoid using Discourse.SiteSettings globals
|
||||
app.register('site-settings:main', Discourse.SiteSettings, { instantiate: false });
|
||||
injectAll(app, 'siteSettings');
|
||||
|
||||
// Inject Session for transient data
|
||||
app.register('session:main', Session.current(), { instantiate: false });
|
||||
injectAll(app, 'session');
|
||||
|
||||
app.register('current-user:main', Discourse.User.current(), { instantiate: false });
|
||||
inject(app, 'currentUser', 'component', 'route', 'controller');
|
||||
|
||||
app.register('message-bus:main', window.MessageBus, { instantiate: false });
|
||||
inject(app, 'messageBus', 'route', 'controller', 'view', 'component');
|
||||
|
||||
app.register('location:discourse-location', DiscourseLocation);
|
||||
}
|
||||
};
|
|
@ -2,7 +2,7 @@ import { mapRoutes } from 'discourse/router';
|
|||
|
||||
export default {
|
||||
name: "map-routes",
|
||||
after: 'inject-objects',
|
||||
after: 'inject-discourse-objects',
|
||||
|
||||
initialize(container, app) {
|
||||
app.register('router:main', mapRoutes());
|
|
@ -1,3 +1,3 @@
|
|||
export default Discourse.View.extend({
|
||||
export default Ember.View.extend({
|
||||
classNames: ["topic-unsubscribe"]
|
||||
});
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
import extractValue from './utils/extract-value';
|
||||
|
||||
export default function decoratorAlias(fn, errorMessage) {
|
||||
return function(...params) {
|
||||
// determine if user called as @computed('blah', 'blah') or @computed
|
||||
if (params.length === 0) {
|
||||
throw new Error(errorMessage);
|
||||
} else {
|
||||
return function(target, key, desc) {
|
||||
return {
|
||||
enumerable: desc.enumerable,
|
||||
configurable: desc.configurable,
|
||||
writable: desc.writable,
|
||||
initializer: function() {
|
||||
var value = extractValue(desc);
|
||||
return fn.apply(null, params.concat(value));
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
import handleDescriptor from './utils/handle-descriptor';
|
||||
import isDescriptor from './utils/is-descriptor';
|
||||
import extractValue from './utils/extract-value';
|
||||
|
||||
export default function computedDecorator(...params) {
|
||||
// determine if user called as @computed('blah', 'blah') or @computed
|
||||
if (isDescriptor(params[params.length - 1])) {
|
||||
return handleDescriptor(...arguments);
|
||||
} else {
|
||||
return function(/* target, key, desc */) {
|
||||
return handleDescriptor(...arguments, params);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function readOnly(target, name, desc) {
|
||||
return {
|
||||
writable: false,
|
||||
enumerable: desc.enumerable,
|
||||
configurable: desc.configurable,
|
||||
initializer: function() {
|
||||
var value = extractValue(desc);
|
||||
return value.readOnly();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
import decoratorAlias from './decorator-alias';
|
||||
|
||||
export var on = decoratorAlias(Ember.on, 'Can not `on` without event names');
|
||||
export var observes = decoratorAlias(Ember.observer, 'Can not `observe` without property names');
|
||||
|
||||
import macroAlias from './macro-alias';
|
||||
|
||||
export var alias = macroAlias(Ember.computed.alias);
|
||||
export var and = macroAlias(Ember.computed.and);
|
||||
export var bool = macroAlias(Ember.computed.bool);
|
||||
export var collect = macroAlias(Ember.computed.collect);
|
||||
export var empty = macroAlias(Ember.computed.empty);
|
||||
export var equal = macroAlias(Ember.computed.equal);
|
||||
export var filter = macroAlias(Ember.computed.filter);
|
||||
export var filterBy = macroAlias(Ember.computed.filterBy);
|
||||
export var gt = macroAlias(Ember.computed.gt);
|
||||
export var gte = macroAlias(Ember.computed.gte);
|
||||
export var lt = macroAlias(Ember.computed.lt);
|
||||
export var lte = macroAlias(Ember.computed.lte);
|
||||
export var map = macroAlias(Ember.computed.map);
|
||||
export var mapBy = macroAlias(Ember.computed.mapBy);
|
||||
export var match = macroAlias(Ember.computed.match);
|
||||
export var max = macroAlias(Ember.computed.max);
|
||||
export var min = macroAlias(Ember.computed.min);
|
||||
export var none = macroAlias(Ember.computed.none);
|
||||
export var not = macroAlias(Ember.computed.not);
|
||||
export var notEmpty = macroAlias(Ember.computed.notEmpty);
|
||||
export var oneWay = macroAlias(Ember.computed.oneWay);
|
||||
export var or = macroAlias(Ember.computed.or);
|
||||
export var readOnly = macroAlias(Ember.computed.readOnly);
|
||||
export var reads = macroAlias(Ember.computed.reads);
|
||||
export var setDiff = macroAlias(Ember.computed.setDiff);
|
||||
export var sort = macroAlias(Ember.computed.sort);
|
||||
export var sum = macroAlias(Ember.computed.sum);
|
||||
export var union = macroAlias(Ember.computed.union);
|
||||
export var uniq = macroAlias(Ember.computed.uniq);
|
|
@ -0,0 +1,24 @@
|
|||
import isDescriptor from './utils/is-descriptor';
|
||||
|
||||
function handleDescriptor(target, property, desc, fn, params = []) {
|
||||
return {
|
||||
enumerable: desc.enumerable,
|
||||
configurable: desc.configurable,
|
||||
writable: desc.writable,
|
||||
initializer: function() {
|
||||
return fn(...params);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default function macroAlias(fn) {
|
||||
return function(...params) {
|
||||
if (isDescriptor(params[params.length - 1])) {
|
||||
return handleDescriptor(...params, fn);
|
||||
} else {
|
||||
return function(target, property, desc) {
|
||||
return handleDescriptor(target, property, desc, fn, params);
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
export default function extractValue(desc) {
|
||||
return desc.value ||
|
||||
(typeof desc.initializer === 'function' && desc.initializer());
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
import Ember from 'ember';
|
||||
import extractValue from './extract-value';
|
||||
|
||||
const { computed, get } = Ember;
|
||||
|
||||
export default function handleDescriptor(target, key, desc, params = []) {
|
||||
return {
|
||||
enumerable: desc.enumerable,
|
||||
configurable: desc.configurable,
|
||||
writeable: desc.writeable,
|
||||
initializer: function() {
|
||||
let computedDescriptor;
|
||||
|
||||
if (desc.writable) {
|
||||
var val = extractValue(desc);
|
||||
if (typeof val === 'object') {
|
||||
let value = { };
|
||||
if (val.get) { value.get = callUserSuppliedGet(params, val.get); }
|
||||
if (val.set) { value.set = callUserSuppliedSet(params, val.set); }
|
||||
computedDescriptor = value;
|
||||
} else {
|
||||
computedDescriptor = callUserSuppliedGet(params, val);
|
||||
}
|
||||
} else {
|
||||
throw new Error('ember-computed-decorators does not support using getters and setters');
|
||||
}
|
||||
|
||||
return computed.apply(null, params.concat(computedDescriptor));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function niceAttr(attr) {
|
||||
const parts = attr.split('.');
|
||||
let i;
|
||||
|
||||
for (i = 0; i < parts.length; i++) {
|
||||
if (parts[i] === '@each' ||
|
||||
parts[i] === '[]' ||
|
||||
parts[i].indexOf('{') !== -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return parts.slice(0, i).join('.');
|
||||
}
|
||||
|
||||
function callUserSuppliedGet(params, func) {
|
||||
params = params.map(niceAttr);
|
||||
return function() {
|
||||
let paramValues = params.map(p => get(this, p));
|
||||
|
||||
return func.apply(this, paramValues);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function callUserSuppliedSet(params, func) {
|
||||
params = params.map(niceAttr);
|
||||
return function(key, value) {
|
||||
let paramValues = params.map(p => get(this, p));
|
||||
paramValues.unshift(value);
|
||||
|
||||
return func.apply(this, paramValues);
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
export default function isDescriptor(item) {
|
||||
return item &&
|
||||
typeof item === 'object' &&
|
||||
'writable' in item &&
|
||||
'enumerable' in item &&
|
||||
'configurable' in item;
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
<%
|
||||
if Rails.env.development? || Rails.env.test?
|
||||
require_asset ("ember-template-compiler.js")
|
||||
require_asset ("ember.custom.debug.js")
|
||||
require_asset ("ember.debug.js")
|
||||
else
|
||||
require_asset ("ember-template-compiler.js")
|
||||
require_asset ("ember.prod.js")
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
//= require ./pagedown_custom.js
|
||||
|
||||
// Stuff we need to load first
|
||||
//= require_tree ./ember-addons/utils
|
||||
//= require ./ember-addons/decorator-alias
|
||||
//= require ./ember-addons/macro-alias
|
||||
//= require ./ember-addons/ember-computed-decorators
|
||||
//= require ./discourse/lib/load-script
|
||||
//= require ./discourse/lib/notification-levels
|
||||
//= require ./discourse/lib/app-events
|
||||
|
@ -94,4 +98,5 @@
|
|||
//= require_tree ./discourse/helpers
|
||||
//= require_tree ./discourse/templates
|
||||
//= require_tree ./discourse/routes
|
||||
//= require_tree ./discourse/pre-initializers
|
||||
//= require_tree ./discourse/initializers
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
});
|
||||
|
||||
<% if Rails.env.development? || Rails.env.test? %>
|
||||
Ember.ENV.RAISE_ON_DEPRECATION = true
|
||||
Ember.LOG_STACKTRACE_ON_DEPRECATION = true
|
||||
//Ember.ENV.RAISE_ON_DEPRECATION = true
|
||||
//Ember.LOG_STACKTRACE_ON_DEPRECATION = true
|
||||
<% end %>
|
||||
|
||||
</script>
|
||||
|
|
|
@ -31,7 +31,7 @@ class DiscourseIIFE < Sprockets::Processor
|
|||
req_path = path.sub(Rails.root.to_s, '')
|
||||
.sub("/app/assets/javascripts", "")
|
||||
.sub("/test/javascripts", "")
|
||||
res << "\nwindow.__jshintSrc = window.__jshintSrc || {}; window.__jshintSrc['/assets#{req_path}'] = #{data.to_json};\n"
|
||||
res << "\nwindow.__eslintSrc = window.__eslintSrc || {}; window.__eslintSrc['/assets#{req_path}'] = #{data.to_json};\n"
|
||||
end
|
||||
|
||||
res
|
||||
|
|
|
@ -83,8 +83,6 @@ module Tilt
|
|||
@output = klass.v8.eval(generate_source(scope))
|
||||
end
|
||||
|
||||
source = @output.dup
|
||||
|
||||
# For backwards compatibility with plugins, for now export the Global format too.
|
||||
# We should eventually have an upgrade system for plugins to use ES6 or some other
|
||||
# resolve based API.
|
||||
|
@ -129,7 +127,7 @@ module Tilt
|
|||
end
|
||||
req_path = "/assets/#{scope.logical_path}.#{extension}"
|
||||
|
||||
@output << "\nwindow.__jshintSrc = window.__jshintSrc || {}; window.__jshintSrc['#{req_path}'] = #{data.to_json};\n"
|
||||
@output << "\nwindow.__eslintSrc = window.__eslintSrc || {}; window.__eslintSrc['#{req_path}'] = #{data.to_json};\n"
|
||||
end
|
||||
|
||||
@output
|
||||
|
@ -139,7 +137,7 @@ module Tilt
|
|||
|
||||
def generate_source(scope)
|
||||
js_source = ::JSON.generate(data, quirks_mode: true)
|
||||
js_source = "babel.transform(#{js_source}, {ast: false, whitelist: ['es6.constants', 'es6.properties.shorthand', 'es6.arrowFunctions', 'es6.blockScoping', 'es6.destructuring', 'es6.templateLiterals', 'es6.regex.unicode']})['code']"
|
||||
js_source = "babel.transform(#{js_source}, {ast: false, whitelist: ['es6.constants', 'es6.properties.shorthand', 'es6.arrowFunctions', 'es6.blockScoping', 'es6.destructuring', 'es6.spread', 'es6.parameters', 'es6.templateLiterals', 'es6.regex.unicode', 'es7.decorators']})['code']"
|
||||
"new module.exports.Compiler(#{js_source}, '#{module_name(scope.root_path, scope.logical_path)}', #{compiler_options}).#{compiler_method}()"
|
||||
end
|
||||
|
||||
|
|
|
@ -1,107 +0,0 @@
|
|||
module("JSHint");
|
||||
|
||||
<%= "const JSHINT_OPTS = #{File.read(File.join(Rails.root, '.jshintrc'))};" %>
|
||||
|
||||
var qHint = function(name, sourceFile) {
|
||||
return asyncTestDiscourse(name, function() {
|
||||
if (typeof window.__jshintSrc !== "undefined") {
|
||||
var src = window.__jshintSrc[sourceFile];
|
||||
if (src) {
|
||||
start();
|
||||
qHint.validateFile(src, JSHINT_OPTS);
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
qHint.validateFile = function (source, options, globals) {
|
||||
var i, len, err;
|
||||
|
||||
source = source.replace(/^[^]*\/\/ IIFE Wrapped Content Begins:\n\n/m, "");
|
||||
source = source.replace(/\n\n\/\/ IIFE Wrapped Content Ends[^]*$/m, "");
|
||||
|
||||
if (JSHINT(source, options, globals)) {
|
||||
ok(true);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0, len = JSHINT.errors.length; i < len; i++) {
|
||||
err = JSHINT.errors[i];
|
||||
if (!err) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ok(false, err.reason +
|
||||
" on line " + err.line +
|
||||
", character " + err.character);
|
||||
}
|
||||
};
|
||||
|
||||
var XMLHttpFactories = [
|
||||
function () { return new XMLHttpRequest(); },
|
||||
function () { return new ActiveXObject("Msxml2.XMLHTTP"); },
|
||||
function () { return new ActiveXObject("Msxml3.XMLHTTP"); },
|
||||
function () { return new ActiveXObject("Microsoft.XMLHTTP"); }
|
||||
];
|
||||
|
||||
function createXMLHTTPObject() {
|
||||
for (var i = 0; i < XMLHttpFactories.length; i++) {
|
||||
try {
|
||||
return XMLHttpFactories[i]();
|
||||
} catch (e) {}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// modified version of XHR script by PPK
|
||||
// http://www.quirksmode.org/js/xmlhttp.html
|
||||
// attached to qHint to allow substitution / mocking
|
||||
qHint.sendRequest = function (url, callback) {
|
||||
var req = createXMLHTTPObject();
|
||||
if (!req) {
|
||||
return;
|
||||
}
|
||||
|
||||
var method = "GET";
|
||||
req.open(method,url + "?" + (new Date().getTime()),true);
|
||||
req.onreadystatechange = function () {
|
||||
if (req.readyState != 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
callback(req);
|
||||
};
|
||||
|
||||
if (req.readyState == 4) {
|
||||
return;
|
||||
}
|
||||
req.send();
|
||||
};
|
||||
|
||||
<%
|
||||
TO_IGNORE = File.read("#{Rails.root}/.jshintignore").split("\n")
|
||||
|
||||
def jshint(dir, remove)
|
||||
result = ""
|
||||
|
||||
Dir.glob(dir).each do |f|
|
||||
filename = f.sub("#{Rails.root}/#{remove}", "")
|
||||
|
||||
ok = true
|
||||
TO_IGNORE.each do |ig|
|
||||
ok = false unless (filename.index(ig.sub(remove, '')).nil?)
|
||||
end
|
||||
|
||||
depend_on filename
|
||||
result << "qHint('#{filename}', '/assets/#{filename}', JSHINT_OPTS);\n" if ok
|
||||
|
||||
end
|
||||
result
|
||||
end
|
||||
%>
|
||||
|
||||
<%= jshint("#{Rails.root}/test/**/*.js", "test/javascripts/") %>
|
||||
<%= jshint("#{Rails.root}/app/assets/javascripts/**/*.js", "app/assets/javascripts/") %>
|
||||
<%= jshint("#{Rails.root}/app/assets/javascripts/**/*.es6", "app/assets/javascripts/") %>
|
||||
|
|
@ -75,7 +75,7 @@ test("removes the href and put it as a data attribute", function() {
|
|||
ok(DiscourseURL.redirectTo.calledOnce);
|
||||
});
|
||||
|
||||
asyncTest("restores the href after a while", function() {
|
||||
asyncTestDiscourse("restores the href after a while", function() {
|
||||
expect(1);
|
||||
|
||||
track(generateClickEventOn('a'));
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/*jshint maxlen:250 */
|
||||
/*global document, sinon, QUnit, Logster */
|
||||
|
||||
//= require env
|
||||
|
@ -12,7 +11,7 @@
|
|||
//= require jquery.debug
|
||||
//= require jquery.ui.widget
|
||||
//= require handlebars
|
||||
//= require ember.custom.debug
|
||||
//= require ember.debug
|
||||
//= require message-bus
|
||||
//= require ember-qunit
|
||||
//= require fake_xml_http_request
|
||||
|
@ -36,7 +35,6 @@
|
|||
|
||||
//= require sinon-1.7.1
|
||||
//= require sinon-qunit-1.0.0
|
||||
//= require jshint
|
||||
|
||||
//= require helpers/qunit-helpers
|
||||
//= require helpers/assertions
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue