From df81d109e5183c09eac7ae64cbab7f96bc71b9a8 Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Thu, 28 Sep 2017 16:08:14 -0400 Subject: [PATCH] The ability to attach `attrs` when embedding widgets --- .../discourse/widgets/header-contents.js.es6 | 4 +-- lib/javascripts/widget-hbs-compiler.js.es6 | 35 ++++++++++++++++--- script/test_hbs_compiler.rb | 28 +++++++++++++++ test/javascripts/widgets/widget-test.js.es6 | 2 +- 4 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 script/test_hbs_compiler.rb diff --git a/app/assets/javascripts/discourse/widgets/header-contents.js.es6 b/app/assets/javascripts/discourse/widgets/header-contents.js.es6 index 819178b6ac0..e998053ff43 100644 --- a/app/assets/javascripts/discourse/widgets/header-contents.js.es6 +++ b/app/assets/javascripts/discourse/widgets/header-contents.js.es6 @@ -4,10 +4,10 @@ import hbs from 'discourse/widgets/hbs-compiler'; createWidget('header-contents', { tagName: 'div.contents.clearfix', template: hbs` - {{attach widget="home-logo"}} + {{attach widget="home-logo" attrs=attrs}}
{{yield}}
{{#if attrs.topic}} - {{attach widget="header-topic-info"}} + {{attach widget="header-topic-info" attrs=attrs}} {{/if}} `, }); diff --git a/lib/javascripts/widget-hbs-compiler.js.es6 b/lib/javascripts/widget-hbs-compiler.js.es6 index 3f96a64eaaf..07d418ff2ba 100644 --- a/lib/javascripts/widget-hbs-compiler.js.es6 +++ b/lib/javascripts/widget-hbs-compiler.js.es6 @@ -1,20 +1,45 @@ function resolve(path) { if (path.indexOf('settings') === 0) { return `this.${path}`; - } else if (path.indexOf('parentState') === 0) { - return `attrs._${path}`; } - return path; } +function sexp(value) { + if (value.path.original === "hash") { + + let result = []; + + value.hash.pairs.forEach(p => { + result.push(`"${p.key}": ${p.value.original}`); + }); + + return `{ ${result.join(", ")} }`; + } +} + +function argValue(arg) { + let value = arg.value; + if (value.type === "SubExpression") { + return sexp(arg.value); + } else if (value.type === "PathExpression") { + return value.original; + } +} + function mustacheValue(node, state) { let path = node.path.original; switch(path) { case 'attach': - const widgetName = node.hash.pairs.find(p => p.key === "widget").value.value; - return `this.attach("${widgetName}", state ? $.extend({}, attrs, { _parentState: state }) : attrs)`; + let widgetName = node.hash.pairs.find(p => p.key === "widget").value.value; + + let attrs = node.hash.pairs.find(p => p.key === "attrs"); + if (attrs) { + return `this.attach("${widgetName}", ${argValue(attrs)})`; + } + return `this.attach("${widgetName}", attrs)`; + break; case 'yield': return `this.attrs.contents()`; diff --git a/script/test_hbs_compiler.rb b/script/test_hbs_compiler.rb new file mode 100644 index 00000000000..1b846615dcd --- /dev/null +++ b/script/test_hbs_compiler.rb @@ -0,0 +1,28 @@ +template = <<~HBS + {{attach widget="widget-name" attrs=attrs}} + {{#if state.category}} + {{attach widget="category-display" attrs=(hash category=state.category)}} + {{/if}} +HBS + +ctx = MiniRacer::Context.new(timeout: 15000) +ctx.eval("var self = this; #{File.read("#{Rails.root}/vendor/assets/javascripts/babel.js")}") +ctx.eval(File.read(Ember::Source.bundled_path_for('ember-template-compiler.js'))) +ctx.eval("module = {}; exports = {};"); +ctx.attach("rails.logger.info", proc { |err| puts(err.to_s) }) +ctx.attach("rails.logger.error", proc { |err| puts(err.to_s) }) +ctx.eval <