brunschgi / terrificjs Goto Github PK
View Code? Open in Web Editor NEWTerrific JavaScript Framework
License: MIT License
Terrific JavaScript Framework
License: MIT License
For convenience reasons – to not be forced to do the inheritance stuff on yourself – there should be a solution provided by the framework.
Examples
Create module with instance properties
var T.Module.Foo = T.createModule({
foo: 'Foo',
bar: function() {
return 'bar'
}
});
Create module with static properties
var T.Module.Foo = T.createModule({
statics: {
foo: 'Foo',
bar: function() {
return 'bar'
}
}
});
TerrificJS does only use a very small subset of jQuery / Zepto. Therefore it would be nice if it would work without one of the two.
Please see: http://semver.org/
By now TerrificJS does only take care of instantiating the correct modules and skins. It does not provide a mechanism to lazy load modules on a granular level. Most of the time its assumed, that all module classes exists on page load.
With the more descriptive approach described in #40 TerrificJS is able to introduce granular loading out-of-the-box. Its even possible to only lazy load modules that do not exist on page load.
The mechanism will work as follows:
Add support for http://browserify.org/.
At the moment, the fire method fires on all (connected) channels. Is it possible to have it fire only on selected channels? Eg.
/**
* Notifies all attached connectors about changes.
*
* @method fire
* @param {String} state the new state
* @param {Object} data the data to provide to your connected modules
* @param {Object} channels the channels fired to, null for all
* @param {Function} defaultAction the default action to perform
* @return {void}
*/
fire: function(state, [data], [channels], [defaultAction]) {
this.fire('changeMood', { mood : 'perfect' }, {1,2}, function() {});
For Responsive Layouts the use of the window.matchMedia API (https://developer.mozilla.org/en/CSS/Using_media_queries_from_code) would be very useful.
Possible Solution:
Replace the qUnit Test suite with Jasmine / Karma
Hello! I have been working with terrific js for a while, and have to say first that it works quite good. :-)
However, I wonder if it's possible to bind several modules to same element, I created a test page which shows whats happens when trying to do this:
http://jsfiddle.net/olof/tArGp/2/
As you can see, on element 3, I bind both mod-logo and mod-test to the div, but it only trigger the last module. Same happens with 4, but mod-logo is loaded instead.
Am I doing something wrong here, or is this a limitation with terrificjs?
Thanks!
// Olof
Should the current version (3.0.0-beta.9) work on IE-Browser (IE9 - 11). As I understood TerrificJS uses shims/polyfills to work on these browsers.
On IE11 f.e. I get the following error:
'Promise' is undefined
When I remove some modules via _sandbox.removeModules, the event listeners are not removed. This results in an undefined exception when a event is called.
could be solved with:
removeAllListeners in unregisterModule (or before stop)
add trailing ; in minified version to be able to include/to mix in a file with other scripts.
In addition to jQuery, Zepto should also be supported.
For convenience reasons – to not be forced to handle the decoration part on yourself – there should be a solution provided by the framework.
Example
Create Module
var T.Module.Foo = T.createModule({
value: 'foo',
start : function (resolve, reject) {
resolve()
},
foo: function() {
return 'foo';
}
});
Create Skin
T.Module.Foo.Bar = T.createSkin({
/* override property */
value: 'bar',
/* extended (decorated) lifecycle method */
start : function (resolve, reject) {
this._parent.start(resolve, reject);
},
/* new method */
bar : function () {
return "bar";
},
/* extended (decorated) method */
foo : function () {
var value = this._parent.foo();
return 'bar-'+ value;
}
});
Usage
var module = this.application.registerModule(document.createElement('div'), 'Foo', ['Bar']);
module.bar(); // -> bar
module.foo(); // -> bar-foo
module.value; // -> bar (as we are decorating and not inheriting from the module, the property gets overriden)
module.start(); // -> executes the start from the skin and the module
Basically the this._parent
property allows you to call all methods from the decorated module.
Mention: as we are decorating and not inheriting from the module, all properties gets overriden directly on the instance.
Replace grunt build script with gulp.
Currently addModules (http://terrifically.org/api/sandbox/#addmodules) does only look inside of the given context for terrific modules. This causes some wrapping issues etc.
The functionality should be extended to support modules on the root node itself too.
Note: this is about the methods beforeBinding, onBinding and afterBinding.
During daily use of Terrific I often found it somewhat tedious to have to write some patterns over and over again. I'm talking about the following:
var self = this
and $(selector, this.$ctx)
The first is needed to access the module instance inside closures (callbacks) that have a different scope than the surrounding method. The second pattern is used for efficiency in order to query only the module contents instead of the whole document.
I'm proposing changing the signature of those methods like this:
beforeBinding: function(self, $$, callback) {
callback();
},
onBinding: function(self, $$) {
// Examples...
var $nav = $$('nav'); // shortcut for $('nav').find('nav') OR $('nav', this.$ctx);
$nav.find('li').each(function() {
// In here 'this' is a li. Without 'self' we have no reference to the Module (unless we stored it in a var).
// (I don't like 'that').
self.doSomethingWithNavLi(this);
});
},
doSomethingWithNavLi: function(li) {
// doing something
return true;
},
afterBinding: function(self, $$) {}
I'm aware that this disturbs the beauty of the API, eg. when using JS skins , but in my experience the convenience of not having to repeat my self all the time trumps the aesthetic consideration.
About self
... It's certainly not beautiful to pass the Module instance into the method as a param, but it makes the subsequent coding inside jQuery closures hassle-free. I chose self
because it reminds me of the way we can reference a static class in PHP, and because I never liked that
. But If you dont want to implement this I won't cry. :)
The second param $$
is more important to me... It would just be so handy to have this. We have to select some child of a module so often, that I think this really makes sense.
I'll say again that this is a very pragmatic proposal, more geared towards daily use than aesthetics. But I really think it has some merit! (And so do my co-workers.) I have the necessary changes to Tc.module.js in a local branch that I can push if you like...
Scenario
Wishes
To be able to version the documentation, the documentation should be moved from http://terrifically.org/api to the README.
The TerrificJS build script still relies on Ant (as grunt does not yet exist). To simplify the build process a switch to grunt is overdue.
To provide more flexibility we are going to change the naming conventions.
Instead of using classes – .mod .mod-xyz – we will switch to data attributes.
This makes the binding completely independent from styling, so that TerrificJS is compatible with all CSS modularization «philosophies» (e.g. BEM, Atomic Design etc.).
Enable the possibility to register hooks in the bootstrap, eg.
var application = new Tc.Application();
application.registerModules();
// register end hook (is executed at the end of all phases)
application.end(function() {
// do something here
});
application.start();
This allows to do something after the module initialization (eg. trigger something) from within the bootstrap.
Currently removeModules
only has the option to take an array of module instances as parameter.
It would be nice if alternatively removeModules
would support a context parameter. This would add some consistency regarding the addModules
method.
TerrificJS makes extensive use of qUnit tests. But the tests still needs to be executed manually in the browser. As the build script is now node-based, the tests should be automated by using a headless browser.
In some cases it would be nice to be able to load dependencies in a certain order, e.g., if plugins are depending on each other. http://labjs.com/ has a nice way of handling this.
To make things more transparent and clear for developers, skin
is renamed to decorator
.
At the moment the module api provides the following methods:
start
-> only used to coordinate the on/after methodon
-> main logic goes hereafter
-> synchronized logic goes here (optional)stop
-> called when the module is removedThe introduction of the lifecycle events #53 provides us some room for improvements. The new module api is going to be much cleaner:
start
-> replaces the on
methodstop
The after
method is being replaced with the lifecycle event t.sync
.
The connector model of TerrificJS is very flexible, but this flexibility is almost never needed. To reduce complexity and to make the usage of connectors more convenient EventEmitter is going to replace the current connector model.
For example
Tc.Sandbox.subscribe
Tc.Sandbox.subscribe
Should either throw an error or return boolean values if needed params are incorrect (especially @param module
).
This makes debugging much easier.
Lifecycle events offers the possibility to listen and react on some application internals by using Connectors.
At the moment the following events are planned:
application.registerModules()
is startedapplication.registerModules()
is ended=> The above 3 could eg. be used to collect all missing modules and lazy load them on demand
application.unregisterModules()
is startedapplication.unregisterModules()
is endedProvide an alternative to the T.Module namespace by using data-t-namespace
.
Hi Remo
Would it be possible to provide the sandbox with the possibility to add connectors dynamically or manually instead of having to make application in the bootstrap public.
Something like this or similar should be possible:
current
application.registerConnection('1', this);
new
moduleinstance.registerConnection('1');
Terrific Rocks!
This feature was originally inspired by YUI 2. Due to the fact that is has almost never been used and raised a lot of questions, we decided to completely remove the callback.
Would be nice to have the possibility to return values from a fired function, and also pass them to the provided actions...
Or I just don't get how to do this :)
To make terrific.js compliant with server-side javascript – e.g. Node.js – we need to export everything in the Tc namespace.
It would be nice if it were configurable whether the naming conventions are camelCase or with dash. This would make the markup nicer in projects where the dash variant is preferred.
The current inheritance model is based on John Resig's Simple Inheritance http://ejohn.org/blog/simple-javascript-inheritance/.
To make this more flexible – eg. use of https://nodejs.org/docs/latest/api/util.html#util_util_inherits_constructor_superconstructor or even ES6 like inheritance in your own modules – the inheritance model of the framework components is changed to use only plain vanilla JS.
I have created a new Module (lets call it Foo
) and a Decorator (Bar
), see example files here.
Executing this results in an TypeError: Cannot read property 'start' of undefined
error which is not traceable.
After calling this.bar()
, the _parent
property is not bound to this
anymore and therefore this._parent.start(resolve);
can't be called anymore. It doesn't matter what the bar()
method does, an empty function body has the same effect as anything else.
I've played around with some things like var mod = this; mod.bar();
and similar, but the problem still exists. Also adding an (empty) bar()
method to Foo
doesn't helper either.
It would be very helpful to use additional methods in a decorator ;)
I'm using 3.0.0-beta.8
.
Cheers,
Rob
Modules should have a "tag" (eg. data-ignore="true") to ignore them in the initial TerrificJS bootstrap. This makes it possible to reduce the initial workload and to lazy init the modules on demand (eg. after scrolling beyond the fold, on click for rarely used functionality etc.).
Using of
Tc.$ = jQuery.noConflict(false);
detaches window.$.
Since TerrificJs doesn't need window.$ but other jQuery plugins or so do, why not just:
Tc.$ = jQuery;
?
Allow the usage of terrific.js in projects with require.js or any other AMD compliant resource loader.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.