mirror of
https://github.com/discourse/discourse.git
synced 2025-05-24 03:01:25 +08:00
Upgrade to Ember 2.10
This commit is contained in:
2
Gemfile
2
Gemfile
@ -48,7 +48,7 @@ gem 'onebox'
|
|||||||
gem 'http_accept_language', '~>2.0.5', require: false
|
gem 'http_accept_language', '~>2.0.5', require: false
|
||||||
|
|
||||||
gem 'ember-rails', '0.18.5'
|
gem 'ember-rails', '0.18.5'
|
||||||
gem 'ember-source', '2.9.1.1'
|
gem 'ember-source', '2.10.0'
|
||||||
gem 'barber'
|
gem 'barber'
|
||||||
gem 'babel-transpiler'
|
gem 'babel-transpiler'
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ GEM
|
|||||||
ember-source (>= 1.1.0)
|
ember-source (>= 1.1.0)
|
||||||
jquery-rails (>= 1.0.17)
|
jquery-rails (>= 1.0.17)
|
||||||
railties (>= 3.1)
|
railties (>= 3.1)
|
||||||
ember-source (2.9.1.1)
|
ember-source (2.10.0)
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
eventmachine (1.2.0.1)
|
eventmachine (1.2.0.1)
|
||||||
excon (0.53.0)
|
excon (0.53.0)
|
||||||
@ -413,7 +413,7 @@ DEPENDENCIES
|
|||||||
discourse_fastimage (= 2.0.3)
|
discourse_fastimage (= 2.0.3)
|
||||||
email_reply_trimmer (= 0.1.6)
|
email_reply_trimmer (= 0.1.6)
|
||||||
ember-rails (= 0.18.5)
|
ember-rails (= 0.18.5)
|
||||||
ember-source (= 2.9.1.1)
|
ember-source (= 2.10.0)
|
||||||
excon
|
excon
|
||||||
execjs
|
execjs
|
||||||
fabrication (= 2.9.8)
|
fabrication (= 2.9.8)
|
||||||
|
@ -11,18 +11,18 @@ export function setResolverOption(name, value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function parseName(fullName) {
|
function parseName(fullName) {
|
||||||
const nameParts = fullName.split(":"),
|
const nameParts = fullName.split(":");
|
||||||
type = nameParts[0], fullNameWithoutType = nameParts[1],
|
const type = nameParts[0];
|
||||||
name = fullNameWithoutType,
|
let fullNameWithoutType = nameParts[1];
|
||||||
namespace = get(this, 'namespace'),
|
const namespace = get(this, 'namespace');
|
||||||
root = namespace;
|
const root = namespace;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
fullName: fullName,
|
fullName,
|
||||||
type: type,
|
type,
|
||||||
fullNameWithoutType: fullNameWithoutType,
|
fullNameWithoutType,
|
||||||
name: name,
|
name: fullNameWithoutType,
|
||||||
root: root,
|
root,
|
||||||
resolveMethodName: "resolve" + classify(type)
|
resolveMethodName: "resolve" + classify(type)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -125,6 +125,18 @@ export function buildResolver(baseName) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
resolveRawTemplate(parsedName) {
|
||||||
|
const dashed = Ember.String.dasherize(parsedName.fullNameWithoutType);
|
||||||
|
return Discourse.RAW_TEMPLATES[dashed];
|
||||||
|
},
|
||||||
|
|
||||||
|
resolveOther(parsedName) {
|
||||||
|
if (parsedName.type === 'raw-template') {
|
||||||
|
return this.resolveRawTemplate(parsedName);
|
||||||
|
}
|
||||||
|
return this._super(parsedName);
|
||||||
|
},
|
||||||
|
|
||||||
resolveTemplate(parsedName) {
|
resolveTemplate(parsedName) {
|
||||||
return this.findPluginMobileTemplate(parsedName) ||
|
return this.findPluginMobileTemplate(parsedName) ||
|
||||||
this.findPluginTemplate(parsedName) ||
|
this.findPluginTemplate(parsedName) ||
|
||||||
|
@ -7,6 +7,7 @@ const Discourse = Ember.Application.extend({
|
|||||||
rootElement: '#main',
|
rootElement: '#main',
|
||||||
_docTitle: document.title,
|
_docTitle: document.title,
|
||||||
__TAGS_INCLUDED__: true,
|
__TAGS_INCLUDED__: true,
|
||||||
|
RAW_TEMPLATES: {},
|
||||||
|
|
||||||
getURL(url) {
|
getURL(url) {
|
||||||
if (!url) return url;
|
if (!url) return url;
|
||||||
|
@ -18,7 +18,7 @@ export default Ember.Component.extend({
|
|||||||
var self = this;
|
var self = this;
|
||||||
var selectedBadges;
|
var selectedBadges;
|
||||||
|
|
||||||
var template = getOwner(this).lookup('template:badge-selector-autocomplete.raw');
|
var template = getOwner(this).lookup('raw-template:badge-selector-autocomplete');
|
||||||
self.$('input').autocomplete({
|
self.$('input').autocomplete({
|
||||||
allowAny: false,
|
allowAny: false,
|
||||||
items: _.isArray(this.get('badgeNames')) ? this.get('badgeNames') : [this.get('badgeNames')],
|
items: _.isArray(this.get('badgeNames')) ? this.get('badgeNames') : [this.get('badgeNames')],
|
||||||
|
@ -13,7 +13,7 @@ export default Ember.Component.extend({
|
|||||||
@on('didInsertElement')
|
@on('didInsertElement')
|
||||||
_initializeAutocomplete(opts) {
|
_initializeAutocomplete(opts) {
|
||||||
const self = this,
|
const self = this,
|
||||||
template = getOwner(this).lookup('template:category-selector-autocomplete.raw'),
|
template = getOwner(this).lookup('raw-template:category-selector-autocomplete'),
|
||||||
regexp = new RegExp(`href=['\"]${Discourse.getURL('/c/')}([^'\"]+)`);
|
regexp = new RegExp(`href=['\"]${Discourse.getURL('/c/')}([^'\"]+)`);
|
||||||
|
|
||||||
this.$('input').autocomplete({
|
this.$('input').autocomplete({
|
||||||
|
@ -62,7 +62,7 @@ export default Ember.Component.extend({
|
|||||||
@on('didInsertElement')
|
@on('didInsertElement')
|
||||||
_composerEditorInit() {
|
_composerEditorInit() {
|
||||||
const topicId = this.get('topic.id');
|
const topicId = this.get('topic.id');
|
||||||
const template = getOwner(this).lookup('template:user-selector-autocomplete.raw');
|
const template = getOwner(this).lookup('raw-template:user-selector-autocomplete');
|
||||||
const $input = this.$('.d-editor-input');
|
const $input = this.$('.d-editor-input');
|
||||||
$input.autocomplete({
|
$input.autocomplete({
|
||||||
template,
|
template,
|
||||||
|
@ -297,7 +297,7 @@ export default Ember.Component.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_applyCategoryHashtagAutocomplete() {
|
_applyCategoryHashtagAutocomplete() {
|
||||||
const template = this.register.lookup('template:category-tag-autocomplete.raw');
|
const template = this.register.lookup('raw-template:category-tag-autocomplete');
|
||||||
const siteSettings = this.siteSettings;
|
const siteSettings = this.siteSettings;
|
||||||
|
|
||||||
this.$('.d-editor-input').autocomplete({
|
this.$('.d-editor-input').autocomplete({
|
||||||
@ -323,7 +323,7 @@ export default Ember.Component.extend({
|
|||||||
if (!this.siteSettings.enable_emoji) { return; }
|
if (!this.siteSettings.enable_emoji) { return; }
|
||||||
|
|
||||||
const register = this.register;
|
const register = this.register;
|
||||||
const template = this.register.lookup('template:emoji-selector-autocomplete.raw');
|
const template = this.register.lookup('raw-template:emoji-selector-autocomplete');
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
$editorInput.autocomplete({
|
$editorInput.autocomplete({
|
||||||
|
@ -19,7 +19,7 @@ export default Ember.Component.extend({
|
|||||||
var selectedGroups;
|
var selectedGroups;
|
||||||
var groupNames = this.get('groupNames');
|
var groupNames = this.get('groupNames');
|
||||||
|
|
||||||
var template = getOwner(this).lookup('template:group-selector-autocomplete.raw');
|
var template = getOwner(this).lookup('raw-template:group-selector-autocomplete');
|
||||||
self.$('input').autocomplete({
|
self.$('input').autocomplete({
|
||||||
allowAny: false,
|
allowAny: false,
|
||||||
items: _.isArray(groupNames) ? groupNames : (Ember.isEmpty(groupNames)) ? [] : [groupNames],
|
items: _.isArray(groupNames) ? groupNames : (Ember.isEmpty(groupNames)) ? [] : [groupNames],
|
||||||
|
@ -32,7 +32,7 @@ export default Ember.Component.extend(bufferedRender({
|
|||||||
},
|
},
|
||||||
|
|
||||||
buildBuffer(buffer) {
|
buildBuffer(buffer) {
|
||||||
const template = getOwner(this).lookup('template:list/topic-list-item.raw');
|
const template = getOwner(this).lookup('raw-template:list/topic-list-item');
|
||||||
if (template) {
|
if (template) {
|
||||||
buffer.push(template(this));
|
buffer.push(template(this));
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ export default TextField.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.$().val(this.get('usernames')).autocomplete({
|
this.$().val(this.get('usernames')).autocomplete({
|
||||||
template: getOwner(this).lookup('template:user-selector-autocomplete.raw'),
|
template: getOwner(this).lookup('raw-template:user-selector-autocomplete'),
|
||||||
disabled: this.get('disabled'),
|
disabled: this.get('disabled'),
|
||||||
single: this.get('single'),
|
single: this.get('single'),
|
||||||
allowAny: this.get('allowAny'),
|
allowAny: this.get('allowAny'),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
const { registerKeyword } = Ember.__loader.require("ember-htmlbars/keywords");
|
// const { registerKeyword } = Ember.__loader.require("ember-htmlbars/keywords");
|
||||||
const { internal } = Ember.__loader.require('htmlbars-runtime');
|
// const { internal } = Ember.__loader.require('htmlbars-runtime');
|
||||||
import PreloadStore from 'preload-store';
|
import PreloadStore from 'preload-store';
|
||||||
|
|
||||||
let _customizations = {};
|
let _customizations = {};
|
||||||
@ -25,35 +25,37 @@ export function setCustomHTML(key, html) {
|
|||||||
_customizations[key] = html;
|
_customizations[key] = html;
|
||||||
}
|
}
|
||||||
|
|
||||||
registerKeyword('custom-html', {
|
export default Ember.Helper.helper(function() {
|
||||||
setupState(state, env, scope, params) {
|
|
||||||
return { htmlKey: env.hooks.getValue(params[0]) };
|
|
||||||
},
|
|
||||||
|
|
||||||
render(renderNode, env, scope, params, hash, template, inverse, visitor) {
|
|
||||||
let state = renderNode.getState();
|
|
||||||
if (!state.htmlKey) { return true; }
|
|
||||||
|
|
||||||
const html = getCustomHTML(state.htmlKey);
|
|
||||||
if (html) {
|
|
||||||
const htmlHash = { html };
|
|
||||||
env.hooks.component(renderNode,
|
|
||||||
env,
|
|
||||||
scope,
|
|
||||||
'custom-html-container',
|
|
||||||
params,
|
|
||||||
htmlHash,
|
|
||||||
{ default: template, inverse },
|
|
||||||
visitor);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template = env.owner.lookup(`template:${state.htmlKey}`);
|
|
||||||
if (template) {
|
|
||||||
internal.hostBlock(renderNode, env, scope, template.raw, null, null, visitor, function(options) {
|
|
||||||
options.templates.template.yield();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
// registerKeyword('custom-html', {
|
||||||
|
// setupState(state, env, scope, params) {
|
||||||
|
// return { htmlKey: env.hooks.getValue(params[0]) };
|
||||||
|
// },
|
||||||
|
//
|
||||||
|
// render(renderNode, env, scope, params, hash, template, inverse, visitor) {
|
||||||
|
// let state = renderNode.getState();
|
||||||
|
// if (!state.htmlKey) { return true; }
|
||||||
|
//
|
||||||
|
// const html = getCustomHTML(state.htmlKey);
|
||||||
|
// if (html) {
|
||||||
|
// const htmlHash = { html };
|
||||||
|
// env.hooks.component(renderNode,
|
||||||
|
// env,
|
||||||
|
// scope,
|
||||||
|
// 'custom-html-container',
|
||||||
|
// params,
|
||||||
|
// htmlHash,
|
||||||
|
// { default: template, inverse },
|
||||||
|
// visitor);
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// template = env.owner.lookup(`template:${state.htmlKey}`);
|
||||||
|
// if (template) {
|
||||||
|
// internal.hostBlock(renderNode, env, scope, template.raw, null, null, visitor, function(options) {
|
||||||
|
// options.templates.template.yield();
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
@ -91,48 +91,51 @@ Handlebars.registerHelper('plugin-outlet', function(name) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const { registerKeyword } = Ember.__loader.require("ember-htmlbars/keywords");
|
export default Ember.Helper.helper(function() {
|
||||||
const { internal } = Ember.__loader.require('htmlbars-runtime');
|
|
||||||
|
|
||||||
registerKeyword('plugin-outlet', {
|
|
||||||
setupState(state, env, scope, params) {
|
|
||||||
if (!_connectorCache) { buildConnectorCache(); }
|
|
||||||
return { outletName: env.hooks.getValue(params[0]) };
|
|
||||||
},
|
|
||||||
|
|
||||||
render(renderNode, env, scope, params, hash, template, inverse, visitor) {
|
|
||||||
let state = renderNode.getState();
|
|
||||||
if (!state.outletName) { return true; }
|
|
||||||
const connector = _connectorCache[state.outletName];
|
|
||||||
if (!connector || connector.length === 0) { return true; }
|
|
||||||
|
|
||||||
const listTemplate = Ember.TEMPLATES['outlet-list'];
|
|
||||||
listTemplate.raw.locals = ['templateId', 'outletClasses', 'tagName'];
|
|
||||||
|
|
||||||
internal.hostBlock(renderNode, env, scope, listTemplate.raw, null, null, visitor, function(options) {
|
|
||||||
connector.forEach(source => {
|
|
||||||
const tid = source.templateId;
|
|
||||||
options.templates.template.yieldItem(`d-outlet-${tid}`, [
|
|
||||||
tid,
|
|
||||||
source.classNames,
|
|
||||||
hash.tagName || 'div'
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
registerKeyword('connector', function(morph, env, scope, params, hash, template, inverse, visitor) {
|
// const { registerKeyword } = Ember.__loader.require("ember-htmlbars/keywords");
|
||||||
template = _templateCache[parseInt(env.hooks.getValue(hash.templateId))];
|
// const { internal } = Ember.__loader.require('htmlbars-runtime');
|
||||||
|
//
|
||||||
env.hooks.component(morph,
|
// registerKeyword('plugin-outlet', {
|
||||||
env,
|
// setupState(state, env, scope, params) {
|
||||||
scope,
|
// if (!_connectorCache) { buildConnectorCache(); }
|
||||||
'connector-container',
|
// return { outletName: env.hooks.getValue(params[0]) };
|
||||||
params,
|
// },
|
||||||
hash,
|
//
|
||||||
{ default: template.raw, inverse },
|
// render(renderNode, env, scope, params, hash, template, inverse, visitor) {
|
||||||
visitor);
|
// let state = renderNode.getState();
|
||||||
return true;
|
// if (!state.outletName) { return true; }
|
||||||
});
|
// const connector = _connectorCache[state.outletName];
|
||||||
|
// if (!connector || connector.length === 0) { return true; }
|
||||||
|
//
|
||||||
|
// const listTemplate = Ember.TEMPLATES['outlet-list'];
|
||||||
|
// listTemplate.raw.locals = ['templateId', 'outletClasses', 'tagName'];
|
||||||
|
//
|
||||||
|
// internal.hostBlock(renderNode, env, scope, listTemplate.raw, null, null, visitor, function(options) {
|
||||||
|
// connector.forEach(source => {
|
||||||
|
// const tid = source.templateId;
|
||||||
|
// options.templates.template.yieldItem(`d-outlet-${tid}`, [
|
||||||
|
// tid,
|
||||||
|
// source.classNames,
|
||||||
|
// hash.tagName || 'div'
|
||||||
|
// ]);
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// registerKeyword('connector', function(morph, env, scope, params, hash, template, inverse, visitor) {
|
||||||
|
// template = _templateCache[parseInt(env.hooks.getValue(hash.templateId))];
|
||||||
|
//
|
||||||
|
// env.hooks.component(morph,
|
||||||
|
// env,
|
||||||
|
// scope,
|
||||||
|
// 'connector-container',
|
||||||
|
// params,
|
||||||
|
// hash,
|
||||||
|
// { default: template.raw, inverse },
|
||||||
|
// visitor);
|
||||||
|
// return true;
|
||||||
|
// });
|
||||||
|
@ -3,6 +3,7 @@ import { registerUnbound } from 'discourse-common/lib/helpers';
|
|||||||
let _injections;
|
let _injections;
|
||||||
|
|
||||||
function renderRaw(ctx, container, template, templateName, params) {
|
function renderRaw(ctx, container, template, templateName, params) {
|
||||||
|
params = Object.assign({}, params);
|
||||||
params.parent = params.parent || ctx;
|
params.parent = params.parent || ctx;
|
||||||
|
|
||||||
if (!params.view) {
|
if (!params.view) {
|
||||||
@ -32,9 +33,9 @@ registerUnbound('raw', function(templateName, params) {
|
|||||||
templateName = templateName.replace('.', '/');
|
templateName = templateName.replace('.', '/');
|
||||||
|
|
||||||
const container = Discourse.__container__;
|
const container = Discourse.__container__;
|
||||||
var template = container.lookup('template:' + templateName + '.raw');
|
const template = container.lookup('raw-template:' + templateName);
|
||||||
if (!template) {
|
if (!template) {
|
||||||
Ember.warn('Could not find raw template: ' + templateName);
|
console.warn('Could not find raw template: ' + templateName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return renderRaw(this, container, template, templateName, params);
|
return renderRaw(this, container, template, templateName, params);
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
|
import { defaultHomepage } from 'discourse/lib/utilities';
|
||||||
const rootURL = Discourse.BaseUri;
|
const rootURL = Discourse.BaseUri;
|
||||||
|
|
||||||
const BareRouter = Ember.Router.extend({
|
const BareRouter = Ember.Router.extend({
|
||||||
rootURL,
|
rootURL,
|
||||||
location: Ember.testing ? 'none': 'discourse-location'
|
location: Ember.testing ? 'none': 'discourse-location',
|
||||||
|
|
||||||
|
handleURL(url) {
|
||||||
|
if (url === "/") { url = defaultHomepage(); }
|
||||||
|
return this._super(url);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Ember's router can't be extended. We need to allow plugins to add routes to routes that were defined
|
// Ember's router can't be extended. We need to allow plugins to add routes to routes that were defined
|
||||||
@ -67,7 +73,8 @@ class RouteNode {
|
|||||||
if (paths.length > 1) {
|
if (paths.length > 1) {
|
||||||
paths.filter(p => p !== this.opts.path).forEach(path => {
|
paths.filter(p => p !== this.opts.path).forEach(path => {
|
||||||
const newOpts = jQuery.extend({}, this.opts, { path });
|
const newOpts = jQuery.extend({}, this.opts, { path });
|
||||||
router.route(this.name, newOpts, builder);
|
console.log(`warning: we can't have duplicate route names anymore`, newOpts);
|
||||||
|
// router.route(this.name, newOpts, builder);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,5 +73,7 @@ export default {
|
|||||||
injectAll(app, 'keyValueStore');
|
injectAll(app, 'keyValueStore');
|
||||||
|
|
||||||
startTracking(topicTrackingState);
|
startTracking(topicTrackingState);
|
||||||
|
|
||||||
|
app.registerOptionsForType('raw-template', { instantiate: false });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import { defaultHomepage } from 'discourse/lib/utilities';
|
|
||||||
|
|
||||||
export default function() {
|
export default function() {
|
||||||
// Error page
|
// Error page
|
||||||
this.route('exception', { path: '/exception' });
|
this.route('exception', { path: '/exception' });
|
||||||
@ -45,9 +43,6 @@ export default function() {
|
|||||||
this.route('categoryNone', { path: '/c/:slug/none' });
|
this.route('categoryNone', { path: '/c/:slug/none' });
|
||||||
this.route('category', { path: '/c/:parentSlug/:slug' });
|
this.route('category', { path: '/c/:parentSlug/:slug' });
|
||||||
this.route('categoryWithID', { path: '/c/:parentSlug/:slug/:id' });
|
this.route('categoryWithID', { path: '/c/:parentSlug/:slug/:id' });
|
||||||
|
|
||||||
// homepage
|
|
||||||
this.route(defaultHomepage(), { path: '/' });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.route('group', { path: '/groups/:name', resetNamespace: true }, function() {
|
this.route('group', { path: '/groups/:name', resetNamespace: true }, function() {
|
||||||
|
@ -266,8 +266,8 @@ export default class Widget {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof name === "string") {
|
if (typeof method === "string") {
|
||||||
view.sendAction(name, param);
|
view.sendAction(method, param);
|
||||||
promise = Ember.RSVP.resolve();
|
promise = Ember.RSVP.resolve();
|
||||||
} else {
|
} else {
|
||||||
const target = view.get('targetObject');
|
const target = view.get('targetObject');
|
||||||
|
@ -142,7 +142,7 @@ module Discourse
|
|||||||
|
|
||||||
# Our templates shouldn't start with 'discourse/templates'
|
# Our templates shouldn't start with 'discourse/templates'
|
||||||
config.handlebars.templates_root = 'discourse/templates'
|
config.handlebars.templates_root = 'discourse/templates'
|
||||||
config.handlebars.raw_template_namespace = "Ember.TEMPLATES"
|
config.handlebars.raw_template_namespace = "Discourse.RAW_TEMPLATES"
|
||||||
|
|
||||||
require 'discourse_redis'
|
require 'discourse_redis'
|
||||||
require 'logster/redis_store'
|
require 'logster/redis_store'
|
||||||
|
Reference in New Issue
Block a user