diff --git a/Gemfile b/Gemfile index 8b9b4b72def..c314af4463b 100644 --- a/Gemfile +++ b/Gemfile @@ -48,7 +48,7 @@ gem 'onebox' gem 'http_accept_language', '~>2.0.5', require: false gem 'ember-rails', '0.18.5' -gem 'ember-source', '2.9.1.1' +gem 'ember-source', '2.10.0' gem 'barber' gem 'babel-transpiler' diff --git a/Gemfile.lock b/Gemfile.lock index 776f689dc00..bebf768f42f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -93,7 +93,7 @@ GEM ember-source (>= 1.1.0) jquery-rails (>= 1.0.17) railties (>= 3.1) - ember-source (2.9.1.1) + ember-source (2.10.0) erubis (2.7.0) eventmachine (1.2.0.1) excon (0.53.0) @@ -413,7 +413,7 @@ DEPENDENCIES discourse_fastimage (= 2.0.3) email_reply_trimmer (= 0.1.6) ember-rails (= 0.18.5) - ember-source (= 2.9.1.1) + ember-source (= 2.10.0) excon execjs fabrication (= 2.9.8) diff --git a/app/assets/javascripts/discourse-common/resolver.js.es6 b/app/assets/javascripts/discourse-common/resolver.js.es6 index a69efc4e30b..7e1bf585e09 100644 --- a/app/assets/javascripts/discourse-common/resolver.js.es6 +++ b/app/assets/javascripts/discourse-common/resolver.js.es6 @@ -11,18 +11,18 @@ export function setResolverOption(name, value) { } function parseName(fullName) { - const nameParts = fullName.split(":"), - type = nameParts[0], fullNameWithoutType = nameParts[1], - name = fullNameWithoutType, - namespace = get(this, 'namespace'), - root = namespace; + const nameParts = fullName.split(":"); + const type = nameParts[0]; + let fullNameWithoutType = nameParts[1]; + const namespace = get(this, 'namespace'); + const root = namespace; return { - fullName: fullName, - type: type, - fullNameWithoutType: fullNameWithoutType, - name: name, - root: root, + fullName, + type, + fullNameWithoutType, + name: fullNameWithoutType, + root, 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) { return this.findPluginMobileTemplate(parsedName) || this.findPluginTemplate(parsedName) || diff --git a/app/assets/javascripts/discourse.js.es6 b/app/assets/javascripts/discourse.js.es6 index 9012e8301b2..213ef89ceba 100644 --- a/app/assets/javascripts/discourse.js.es6 +++ b/app/assets/javascripts/discourse.js.es6 @@ -7,6 +7,7 @@ const Discourse = Ember.Application.extend({ rootElement: '#main', _docTitle: document.title, __TAGS_INCLUDED__: true, + RAW_TEMPLATES: {}, getURL(url) { if (!url) return url; diff --git a/app/assets/javascripts/discourse/components/badge-selector.js.es6 b/app/assets/javascripts/discourse/components/badge-selector.js.es6 index 315f7398a78..58171785559 100644 --- a/app/assets/javascripts/discourse/components/badge-selector.js.es6 +++ b/app/assets/javascripts/discourse/components/badge-selector.js.es6 @@ -18,7 +18,7 @@ export default Ember.Component.extend({ var self = this; 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({ allowAny: false, items: _.isArray(this.get('badgeNames')) ? this.get('badgeNames') : [this.get('badgeNames')], diff --git a/app/assets/javascripts/discourse/components/category-selector.js.es6 b/app/assets/javascripts/discourse/components/category-selector.js.es6 index 460a1dfdd65..d825b6117a1 100644 --- a/app/assets/javascripts/discourse/components/category-selector.js.es6 +++ b/app/assets/javascripts/discourse/components/category-selector.js.es6 @@ -13,7 +13,7 @@ export default Ember.Component.extend({ @on('didInsertElement') _initializeAutocomplete(opts) { 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/')}([^'\"]+)`); this.$('input').autocomplete({ diff --git a/app/assets/javascripts/discourse/components/composer-editor.js.es6 b/app/assets/javascripts/discourse/components/composer-editor.js.es6 index 55b69c64a1c..95d6a53df9a 100644 --- a/app/assets/javascripts/discourse/components/composer-editor.js.es6 +++ b/app/assets/javascripts/discourse/components/composer-editor.js.es6 @@ -62,7 +62,7 @@ export default Ember.Component.extend({ @on('didInsertElement') _composerEditorInit() { 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'); $input.autocomplete({ template, diff --git a/app/assets/javascripts/discourse/components/d-editor.js.es6 b/app/assets/javascripts/discourse/components/d-editor.js.es6 index 6e43dfde817..47264839e34 100644 --- a/app/assets/javascripts/discourse/components/d-editor.js.es6 +++ b/app/assets/javascripts/discourse/components/d-editor.js.es6 @@ -297,7 +297,7 @@ export default Ember.Component.extend({ }, _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; this.$('.d-editor-input').autocomplete({ @@ -323,7 +323,7 @@ export default Ember.Component.extend({ if (!this.siteSettings.enable_emoji) { return; } 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; $editorInput.autocomplete({ diff --git a/app/assets/javascripts/discourse/components/group-selector.js.es6 b/app/assets/javascripts/discourse/components/group-selector.js.es6 index 4f4fa0f6a5e..25cb3b8bab0 100644 --- a/app/assets/javascripts/discourse/components/group-selector.js.es6 +++ b/app/assets/javascripts/discourse/components/group-selector.js.es6 @@ -19,7 +19,7 @@ export default Ember.Component.extend({ var selectedGroups; 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({ allowAny: false, items: _.isArray(groupNames) ? groupNames : (Ember.isEmpty(groupNames)) ? [] : [groupNames], diff --git a/app/assets/javascripts/discourse/components/topic-list-item.js.es6 b/app/assets/javascripts/discourse/components/topic-list-item.js.es6 index a38dd9c8f4c..0293d128e27 100644 --- a/app/assets/javascripts/discourse/components/topic-list-item.js.es6 +++ b/app/assets/javascripts/discourse/components/topic-list-item.js.es6 @@ -32,7 +32,7 @@ export default Ember.Component.extend(bufferedRender({ }, 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) { buffer.push(template(this)); } diff --git a/app/assets/javascripts/discourse/components/user-selector.js.es6 b/app/assets/javascripts/discourse/components/user-selector.js.es6 index 94d6db9bfe4..27b2e48eab1 100644 --- a/app/assets/javascripts/discourse/components/user-selector.js.es6 +++ b/app/assets/javascripts/discourse/components/user-selector.js.es6 @@ -31,7 +31,7 @@ export default TextField.extend({ } 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'), single: this.get('single'), allowAny: this.get('allowAny'), diff --git a/app/assets/javascripts/discourse/helpers/custom-html.js.es6 b/app/assets/javascripts/discourse/helpers/custom-html.js.es6 index 29b98c46cf6..2218406e8f2 100644 --- a/app/assets/javascripts/discourse/helpers/custom-html.js.es6 +++ b/app/assets/javascripts/discourse/helpers/custom-html.js.es6 @@ -1,5 +1,5 @@ -const { registerKeyword } = Ember.__loader.require("ember-htmlbars/keywords"); -const { internal } = Ember.__loader.require('htmlbars-runtime'); +// const { registerKeyword } = Ember.__loader.require("ember-htmlbars/keywords"); +// const { internal } = Ember.__loader.require('htmlbars-runtime'); import PreloadStore from 'preload-store'; let _customizations = {}; @@ -25,35 +25,37 @@ export function setCustomHTML(key, html) { _customizations[key] = html; } -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; - } +export default Ember.Helper.helper(function() { }); +// 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; +// } +// }); diff --git a/app/assets/javascripts/discourse/helpers/plugin-outlet.js.es6 b/app/assets/javascripts/discourse/helpers/plugin-outlet.js.es6 index 32fd7d8bae9..f8831bc8780 100644 --- a/app/assets/javascripts/discourse/helpers/plugin-outlet.js.es6 +++ b/app/assets/javascripts/discourse/helpers/plugin-outlet.js.es6 @@ -91,48 +91,51 @@ Handlebars.registerHelper('plugin-outlet', function(name) { } }); -const { registerKeyword } = Ember.__loader.require("ember-htmlbars/keywords"); -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; - } +export default Ember.Helper.helper(function() { }); -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; -}); +// const { registerKeyword } = Ember.__loader.require("ember-htmlbars/keywords"); +// 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) { +// 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; +// }); diff --git a/app/assets/javascripts/discourse/helpers/raw.js.es6 b/app/assets/javascripts/discourse/helpers/raw.js.es6 index a6cf56e31f9..6b7bf0ec4d9 100644 --- a/app/assets/javascripts/discourse/helpers/raw.js.es6 +++ b/app/assets/javascripts/discourse/helpers/raw.js.es6 @@ -3,6 +3,7 @@ import { registerUnbound } from 'discourse-common/lib/helpers'; let _injections; function renderRaw(ctx, container, template, templateName, params) { + params = Object.assign({}, params); params.parent = params.parent || ctx; if (!params.view) { @@ -32,9 +33,9 @@ registerUnbound('raw', function(templateName, params) { templateName = templateName.replace('.', '/'); const container = Discourse.__container__; - var template = container.lookup('template:' + templateName + '.raw'); + const template = container.lookup('raw-template:' + templateName); if (!template) { - Ember.warn('Could not find raw template: ' + templateName); + console.warn('Could not find raw template: ' + templateName); return; } return renderRaw(this, container, template, templateName, params); diff --git a/app/assets/javascripts/discourse/mapping-router.js.es6 b/app/assets/javascripts/discourse/mapping-router.js.es6 index 31d7c2c2eaf..21e91303ec1 100644 --- a/app/assets/javascripts/discourse/mapping-router.js.es6 +++ b/app/assets/javascripts/discourse/mapping-router.js.es6 @@ -1,8 +1,14 @@ +import { defaultHomepage } from 'discourse/lib/utilities'; const rootURL = Discourse.BaseUri; const BareRouter = Ember.Router.extend({ 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 @@ -67,7 +73,8 @@ class RouteNode { if (paths.length > 1) { paths.filter(p => p !== this.opts.path).forEach(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); }); } } diff --git a/app/assets/javascripts/discourse/pre-initializers/inject-discourse-objects.js.es6 b/app/assets/javascripts/discourse/pre-initializers/inject-discourse-objects.js.es6 index 5e3de23fee3..d6846904a95 100644 --- a/app/assets/javascripts/discourse/pre-initializers/inject-discourse-objects.js.es6 +++ b/app/assets/javascripts/discourse/pre-initializers/inject-discourse-objects.js.es6 @@ -73,5 +73,7 @@ export default { injectAll(app, 'keyValueStore'); startTracking(topicTrackingState); + + app.registerOptionsForType('raw-template', { instantiate: false }); } }; diff --git a/app/assets/javascripts/discourse/routes/app-route-map.js.es6 b/app/assets/javascripts/discourse/routes/app-route-map.js.es6 index 37733386f1f..5cde512a631 100644 --- a/app/assets/javascripts/discourse/routes/app-route-map.js.es6 +++ b/app/assets/javascripts/discourse/routes/app-route-map.js.es6 @@ -1,5 +1,3 @@ -import { defaultHomepage } from 'discourse/lib/utilities'; - export default function() { // Error page this.route('exception', { path: '/exception' }); @@ -45,9 +43,6 @@ export default function() { this.route('categoryNone', { path: '/c/:slug/none' }); this.route('category', { path: '/c/:parentSlug/:slug' }); this.route('categoryWithID', { path: '/c/:parentSlug/:slug/:id' }); - - // homepage - this.route(defaultHomepage(), { path: '/' }); }); this.route('group', { path: '/groups/:name', resetNamespace: true }, function() { diff --git a/app/assets/javascripts/discourse/widgets/widget.js.es6 b/app/assets/javascripts/discourse/widgets/widget.js.es6 index 55ea1db528d..bd539e5f89d 100644 --- a/app/assets/javascripts/discourse/widgets/widget.js.es6 +++ b/app/assets/javascripts/discourse/widgets/widget.js.es6 @@ -266,8 +266,8 @@ export default class Widget { return; } - if (typeof name === "string") { - view.sendAction(name, param); + if (typeof method === "string") { + view.sendAction(method, param); promise = Ember.RSVP.resolve(); } else { const target = view.get('targetObject'); diff --git a/config/application.rb b/config/application.rb index 5ac23191642..a7a5531a691 100644 --- a/config/application.rb +++ b/config/application.rb @@ -142,7 +142,7 @@ module Discourse # Our templates shouldn't start with '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 'logster/redis_store'