You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
That would possible, although obviously not recommended in production due to the additional computation required to internalize the input. Agree it would be nice to be able to run everything in a browser, though, esp. for testing and tinkering. My argument against this was that precompiling templates as per the supplied examples is fairly trivial to do / modify, but if there's enough interest (not enough atm to justify the effort) I can provide a browser version at some point
but if there's enough interest (not enough atm to justify the effort) I can provide a browser version at some point
+100 please! )
It'd be really nice to have a browser-ready build. I tried to combine all scripts with Browserify but failed.
browserify-ed version failed on load somewhere deep inside uglifyjs with error:
Uncaught TypeError: require.resolve is not a function
Unfortunately atm I am a bit swamped with things to look into this. The versions I use are slightly different from the one in this repo for some reason, so it's a bit tricky to "port" the browser version here. However, as you can see the dependencies are not that special - and there in principle no reason why a browserified version of this could not work with minor tweaks. iIRC html-minifier was a bit of a PITA for some reason so you may want to disable that temporarily to get things going.
just removing "auto registration emmiters" in transpiler\index.js makes the lib to be just Handlebars - it behaves as w/o backend specified. So I had to add explicit import of idom backend:
var emitter = require('./backends/idom');
TemplateTranspiler.registerBackend('idom', emitter);
That makes sense, since you're not using fs any longer. Let me know how it works - and bear in mind that full in-browser transpile+compile may get prohibitively slow for production (but still pretty fun, tho :))
On 21 May 2018, at 20:48, Sergei Dorogin ***@***.***> wrote:
just removing "auto registration emmiters" in transpiler\index.js makes the lib to be just Handlebars - it behaves as w/o backend specified. So I had to add explicit import of idom backend:
var emitter = require('./backends/idom');
TemplateTranspiler.registerBackend('idom', emitter);
—
You are receiving this because you were assigned.
Reply to this email directly, view it on GitHub, or mute the thread.
Thanks for your interest. And thanks for the lib by the way. It looks like very interesting piece of software.
Previously with Handlebars I loaded all template via my requireJS-plugin that compiles templates on the fly. At the same time for production they were compiled in build-time and plugins detected that and did nothing. So all other code isn't dependent on the fact whether templates are compiled or not. I want to keep this approach. Unfortunately I have lots of block helpers which returns html strings and all they won't work any more. So I'm far away from something working. But it seems that the lib itself works - I can see compiled js code with IncrementalDOM calls.
BTW I think it makes sense to mention in the README that apps should import IncrementalDOM globally.
If you wonder what kind of helpers I have here's some details.
For example my templates have code like:
{{render someProp}}
that means the view should take a object from property someProp and treat it as a nested view - so that call its render method. But during helper execution it's not possible (as we have string and no DOM element available yet - it's needed for render). So render helper return a simple html stub (like <span id="some-generatd-id"></span>) and adds some callback into context associate with the current view. Then (after html inserter into DOM) the view executes all callbacks, and the added callaback finds its stub as DOM element and execute render method for appropriate object.
it fails on first IncrementalDOM.elementVoid call with the following stack:
TypeError: Cannot read property 'firstChild' of null
at getNextNode (incremental-dom.js?v=2.36.0-SNAPSHOT-180320T1423-20180521T2002:722)
at nextNode (incremental-dom.js?v=2.36.0-SNAPSHOT-180320T1423-20180521T2002:730)
at coreElementOpen (incremental-dom.js?v=2.36.0-SNAPSHOT-180320T1423-20180521T2002:754)
at elementOpen (incremental-dom.js?v=2.36.0-SNAPSHOT-180320T1423-20180521T2002:1005)
at Object.elementVoid (incremental-dom.js?v=2.36.0-SNAPSHOT-180320T1423-20180521T2002:1156)
in getNextNode the field currentParent is null:
var getNextNode = function () {
if (currentNode) {
return currentNode.nextSibling;
} else {
return currentParent.firstChild;
}
};
thanks it's helpful, I should look there at start.
but as I can see there's no way to pass additional options into templates as it was be possible with HB.
What I mean. registerHelper's callbacks have context and options args. context is an object the template is being applied to, kinda viewmodel. And options is:
fn, inverse and hash are taken from template, but data can be an arbitrary object passed via template function as second arg.
That second argument for template function is documented here - http://handlebarsjs.com/execution.html
Besides arbitrary data we could pass additional helpers and partials.
With ibar/idom it seems not possible due to patch method accept only one arg with data.
But ibar's compile return a function that expect two args:
function ret(context, execOptions) {
if (!compiled) {
compiled = compileInput();
}
return compiled.call(this, context, execOptions);
}
that execOptions seems exactly what I need. Currently is always undefined. The only problem is how to pass it via IncrementalDOM.patch:
So I would suggest to pack context and options into data. To distinguish that case from the simple one (the current) we can tell via specifying data:true argument for compile:
Incremental DOM wants a function and a context. But that does not mean you cannot pass options to the template, you just need to do it in a slightly different way - like curry them etc. Example
var template = ....
var templatefn = function(options) {
return function(context) {
return template(context, options);
}
};
....
IncrementalDOM.patch(container, templatefn({ data : .... }), { something : ... });
Yeah, I've just discovered that as well, but unfortunately it's not enough as template function returned by compile method is a wrapper which should support two args as well.
So to make the approach you mentioned to work I had to change code in i-bars:
function ret(context) {
// skipped
function main(context , options) {
var opts = container.merge(options || {}, data); // this is my change
return '' + templateSpec.main(container, context, container.helpers, container.partials, opts, blockParams, depths);
}
main = executeDecorators(templateSpec.main, main, container, options.depths || [], data, blockParams);
return main(context, options);
}
In the main wrapper I added merging options and data (initially options is commented)
Did you use compile in the browser? As I can see all samples compile templates via precompile in build-time and import templates as js-code in run-time. I'm trying to compile template on the fly.
And it seems it's not working as intended.
As I can see ibars' compile returns a function which ultimately calls into the Handlebars' compileInput func:
function compileInput() {
var ast = env.parse(input, options),
environment = new env.Compiler().compile(ast, options),
templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true);
return env.template(templateSpec);
}
That compileInput returns a function from Handlebars:
templateSpec.main is ibars' generated code with i-dom calls but wrapping it with Handlerbars's main that returns string seems weird for me. As in the end we call for HB's parse and compile for already compiled input, and template function returns string. Is it intended behavior?
I also have a question about migrating code like <div {{helper..}}> but will ask it in a separate issue.
Activity
atomictag commentedon Jun 2, 2017
That would possible, although obviously not recommended in production due to the additional computation required to internalize the input. Agree it would be nice to be able to run everything in a browser, though, esp. for testing and tinkering. My argument against this was that precompiling templates as per the supplied examples is fairly trivial to do / modify, but if there's enough interest (not enough atm to justify the effort) I can provide a browser version at some point
maxymajzr commentedon Jul 3, 2017
I'd be interested in this.
evil-shrike commentedon May 21, 2018
+100 please! )
It'd be really nice to have a browser-ready build. I tried to combine all scripts with Browserify but failed.
browserify-ed version failed on load somewhere deep inside uglifyjs with error:
It's a known issue with UglifyJS browserify/browserify#1832.
May I ask how do you use the lib in runtime?
atomictag commentedon May 21, 2018
Unfortunately atm I am a bit swamped with things to look into this. The versions I use are slightly different from the one in this repo for some reason, so it's a bit tricky to "port" the browser version here. However, as you can see the dependencies are not that special - and there in principle no reason why a browserified version of this could not work with minor tweaks. iIRC html-minifier was a bit of a PITA for some reason so you may want to disable that temporarily to get things going.
evil-shrike commentedon May 21, 2018
thanks. As I removed usage of
html-minifierandfsin transpiler\index.js then Browerify starts working.evil-shrike commentedon May 21, 2018
just removing "auto registration emmiters" in
transpiler\index.jsmakes the lib to be just Handlebars - it behaves as w/o backend specified. So I had to add explicit import of idom backend:atomictag commentedon May 21, 2018
evil-shrike commentedon May 22, 2018
Thanks for your interest. And thanks for the lib by the way. It looks like very interesting piece of software.
Previously with Handlebars I loaded all template via my requireJS-plugin that compiles templates on the fly. At the same time for production they were compiled in build-time and plugins detected that and did nothing. So all other code isn't dependent on the fact whether templates are compiled or not. I want to keep this approach. Unfortunately I have lots of block helpers which returns html strings and all they won't work any more. So I'm far away from something working. But it seems that the lib itself works - I can see compiled js code with IncrementalDOM calls.
BTW I think it makes sense to mention in the README that apps should import
IncrementalDOMglobally.If you wonder what kind of helpers I have here's some details.
For example my templates have code like:
that means the view should take a object from property
somePropand treat it as a nested view - so that call itsrendermethod. But during helper execution it's not possible (as we have string and no DOM element available yet - it's needed for render). Sorenderhelper return a simple html stub (like<span id="some-generatd-id"></span>) and adds some callback into context associate with the current view. Then (after html inserter into DOM) the view executes all callbacks, and the added callaback finds its stub as DOM element and executerendermethod for appropriate object.evil-shrike commentedon May 24, 2018
Hi.
Well, it turned out that I have difficulties even without any custom helper.
Any advice is appreciated.
Given a HB template containg only html (no helpers at all)
The templates is compiled with a
compilecall:then that
tmplis executed:datais:I never got a result from
template()function. It fails somewhere inside incremental-domHere's template function:
it fails on first
IncrementalDOM.elementVoidcall with the following stack:in
getNextNodethe fieldcurrentParentis null:atomictag commentedon May 24, 2018
Are you sure you are correctly invoking the template function? It should be something like
evil-shrike commentedon May 24, 2018
Thanks, definitely I'm not.
So HB-like approach:
is becoming:
but let me ask what's about the second argument for HB-template function -
data(see http://handlebarsjs.com/block_helpers.html#block-params). Where is it going in the new idom-approach?atomictag commentedon May 24, 2018
have a look at the examples perhaps that can help clarifying things a bit
evil-shrike commentedon May 24, 2018
thanks it's helpful, I should look there at start.
but as I can see there's no way to pass additional options into templates as it was be possible with HB.
What I mean.
registerHelper's callbacks havecontextandoptionsargs.contextis an object the template is being applied to, kinda viewmodel. Andoptionsis:fn,inverseandhashare taken from template, butdatacan be an arbitrary object passed via template function as second arg.That second argument for template function is documented here - http://handlebarsjs.com/execution.html
Besides arbitrary data we could pass additional helpers and partials.
With ibar/idom it seems not possible due to
patchmethod accept only one arg with data.But ibar's compile return a function that expect two args:
that
execOptionsseems exactly what I need. Currently is always undefined. The only problem is how to pass it viaIncrementalDOM.patch:So I would suggest to pack context and options into
data. To distinguish that case from the simple one (the current) we can tell via specifyingdata:trueargument forcompile:that would mean -
dataargument forpatchwill containcontextandoptionsand so instead of:ibars would call:
and then:
atomictag commentedon May 24, 2018
Incremental DOM wants a function and a context. But that does not mean you cannot pass options to the template, you just need to do it in a slightly different way - like curry them etc. Example
evil-shrike commentedon May 24, 2018
Yeah, I've just discovered that as well, but unfortunately it's not enough as template function returned by
compilemethod is a wrapper which should support two args as well.So to make the approach you mentioned to work I had to change code in i-bars:
In the
mainwrapper I added mergingoptionsanddata(initiallyoptionsis commented)atomictag commentedon May 24, 2018
I use it all the time i guarantee it works - you may just need to try out a few patterns that suit your needs
evil-shrike commentedon May 25, 2018
Did you use
compilein the browser? As I can see all samples compile templates viaprecompilein build-time and import templates as js-code in run-time. I'm trying to compile template on the fly.And it seems it's not working as intended.
As I can see ibars'
compilereturns a function which ultimately calls into the Handlebars'compileInputfunc:That
compileInputreturns a function from Handlebars:templateSpec.mainis ibars' generated code with i-dom calls but wrapping it with Handlerbars's main that returns string seems weird for me. As in the end we call for HB's parse and compile for already compiled input, and template function returns string. Is it intended behavior?I also have a question about migrating code like
<div {{helper..}}>but will ask it in a separate issue.