Giter Site home page Giter Site logo

t3js's Introduction

Build Status Project Status

DEPRECATED

Box has migrated using react, webpack, and the latest version of ECMAScript for our frontend projects as of 2018. We no longer support changes, pull requests, or upgrades to this package. We appreciate all of the user contributions that you have given us over the past few years.

T3 JavaScript Framework

T3 is a client-side JavaScript framework for building large-scale web applications. Its design is based on the principles of Scalable JavaScript Application Architecture, specifically:

  • Enforcing loose coupling between components
  • Making dependencies explicit
  • Providing extension points to allow for unforeseen requirements
  • Abstracting away common pain points
  • Encouraging progressive enhancement

The approaches taken in T3 have been battle-hardened through continuous production use at Box since 2013, where we use T3 along with jQuery, jQuery UI, and several other third-party libraries and frameworks.

Framework Design

T3 is different from most JavaScript frameworks. It's meant to be a small piece of an overall architecture that allows you to build scalable client-side code.

No MVC Here

T3 is explicitly not an MVC framework. It's a framework that allows the creation of loosely-coupled components while letting you decide what other pieces you need for your web application. You can use T3 with other frameworks like Backbone or React, or you can use T3 by itself. If you decide you want model and views, in whatever form, you can still use them with T3.

Unopinionated by Design

T3 is made to be unopinionated while prescribing how some problems might be solved. Our goal here is not to create a single framework that can do everything for you, but rather, to provide some structure to your client-side code that allows you to make good choices. Then, you can add in other libraries and frameworks to suit your needs.

Three Component Types

T3 allows you to define functionality using just three component types:

  1. Services are utility libraries that provide additional capabilities to your application. You can think of services as tools in a toolbox that you use to build an application. They intended to be reusable pieces of code such as cookie parsing, Ajax communication, string utilities, and so on.
  2. Modules represent a particular DOM element on a page and manage the interaction inside of that element. It's a module's job to respond to user interaction within its boundaries. Your application is made up of a series of modules. Modules may not interact directly with other modules, but may do so indirectly.
  3. Behaviors are mixins for modules and are used primarily to allow shared declarative event handling for modules without duplicating code. If, for instance, you use a particular attribute to indicate a link should use Ajax navigation instead of full-page navigation, you can share that functionality amongst multiple modules.

We've found that by using a combination of these three component types, we're able to create compelling, progressively-enhanced user experiences.

Installation

To include T3 in a web page, you can use RawGit.

The last published release:

<!-- Recommended: Latest version of T3 -->
<script src="https://cdn.rawgit.com/box/t3js/v2.7.0/dist/t3.js"></script>

<!-- Recommended: Latest minified version of T3 -->
<script src="https://cdn.rawgit.com/box/t3js/v2.7.0/dist/t3.min.js"></script>

<!-- jQuery version (IE8 + 1.8.0+ jQuery) -->
<script src="https://cdn.rawgit.com/box/t3js/v2.7.0/dist/t3-jquery.js"></script>

<!-- jQuery minified version (IE8 + 1.8.0+ jQuery) -->
<script src="https://cdn.rawgit.com/box/t3js/v2.7.0/dist/t3-jquery.min.js"></script>

You may also use bower to install t3js:

bower install t3js

Upgrade from 1.5.1 to 2.0.0

T3 2.0.0 was released on November 18th, 2015 with some major changes. To upgrade, please see these instructions.

Getting Started

Your T3 front-end is made up of modules, so the first step is to indicate which modules are responsible for which parts of the page. You can do that by using the data-module attribute and specifying the module ID, such as:

<div data-module="header">
    <h1>Box</h1>
    <button data-type="welcome-btn">Show Welcome</button>
</div>

This example specifies the module header should manage this particular part of the page. The module header is then defined as:

Box.Application.addModule('header', function(context) {

    return {

        onclick: function(event, element, elementType) {
            if (elementType === 'welcome-btn') {
                alert('Welcome, T3 user!');
            } else {
                alert('You clicked outside the button.');
            }
        }

    };

});

This is a very simple module that has an onclick handler. T3 automatically wires up specified event handlers so you don't have to worry about using event delegation or removing event handlers when they are no longer needed. The onclick handler receives a DOM-normalized event object that can be used to get event details. When the button is clicked, a message is displayed. Additionally, clicking anywhere inside the module will display a different message. Event handlers are tied to the entire module area, so there's no need to attach multiple handlers of the same type.

The last step is to initialize the T3 application:

Box.Application.init();

This call starts all modules on the page (be sure to include both the T3 library and your module code before calling init()). We recommend calling init() as soon as possible after your JavaScript is loaded. Whether you do that onload, earlier, or later, is completely up to you.

There are more extensive tutorials and examples on our website.

Browser Support

T3 is tested and known to work in the following browsers:

  • Internet Explorer 9 and higher
  • Firefox (latest version)
  • Chrome (latest version)
  • Safari (latest version)

With the exception of Internet Explorer, T3 will continue to support the current and previous one version of all major browsers.

Contributing

The main purpose of sharing T3 is to continue its development, making it faster, more efficient, and easier to use.

Directory Structure

  • config - configuration files for the project
  • dist - browser bundles (this directory is updated automatically with each release)
  • lib - the source code as individual files
  • tests - the test code

Prerequisites

In order to get started contributing to T3, you'll need to be familiar and have installed:

  1. Git
  2. npm
  3. Node.js or IO.js

Setup

Following the instructions in the contributor guidelines to setup a local copy of the T3 repository.

Once you clone the T3 git repository, run the following inside the t3js directory:

$ npm i

This sets up all the dependencies that the T3 build system needs to function.

Note: You'll need to do this periodically when pulling the latest code from our repository as dependencies might change. If you find unexpected errors, be sure to run npm i again to ensure your dependencies are up-to-date.

Running Tests

After that, you can run all tests by running:

$ npm test

This will start by linting the code and then running all unit tests.

Build Commands

The following build commands are available:

  1. npm test - runs all linting and uni tests
  2. npm run lint - runs all linting
  3. npm run dist - creates the browser bundles and places them in /dist

Frequently Asked Questions

Can I use this with older browsers?

We provide a custom version of T3 built with jQuery that is compatible with older browsers such as IE8.

Why support IE8?

The Box web application currently supports IE8 with a planned end-of-life of December 31, 2015. We will be dropping T3 support for IE8 at the same time.

Support

Need to contact us directly? Email [email protected] with your questions or comments.

Copyright and License

Copyright 2015 Box, Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

t3js's People

Contributors

azu avatar j3tan avatar mattbasta avatar matthewhadley avatar mduvall avatar nzakas avatar priyajeet avatar rodenis avatar winhuang avatar zephraph avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

t3js's Issues

Change error reporter to `mocha`

current reporters:

reporters: ['progress', 'coverage', 'threshold']

it outputs:

screen shot 2015-04-17 at 12 48 24 am

which is fine if you don't have an error, but let's say sandbox.verifyAndRestore failed, you will see this:

screen shot 2015-04-17 at 12 52 49 am

which is difficult to debug because you don't know which test it is, your test name doesn't show up since you run sandbox.verifyAndRestore in the afterEach block (technically, the test passed, it's your afterEach block that failed)

since you are using mocha, I recommend replacing progress with a reporter that better support mocha, eg. https://www.npmjs.com/package/karma-mocha-reporter, which outputs:

screen shot 2015-04-17 at 12 55 51 am

and when you failed:

screen shot 2015-04-17 at 12 56 59 am

screen shot 2015-04-17 at 1 01 24 am

better?

[question] t3js for canvas game development

Hello,

I really like the architecture of this framework and I would like to use it for games development. This coupling to the DOM makes it very difficult to use though. Any plans to make the DOM dependency optional?

duplicated assign code

t3js has private assign function, but use duplicated code in setGlobalConfig.

setGlobalConfig: function(config) {
    if (initialized) {
        error(new Error('Cannot set global configuration after application initialization'));
        return;
    }
       // here is the same with `assign`
    for (var prop in config) {
        if (config.hasOwnProperty(prop)) {
            globalConfig[prop] = config[prop];
        }
    }
},

Adding support for focus and blur

In reading through the docs i see you have the usual problem with blur and focus event's not bubbling.

These events are useful, especially in keyboard accessibility for drawing a clear focus indicator (though perhaps CSS support is better now). Also they are often required for keyboard access in custom controls.

We can't use the bubbling focusin focusout until Firefox supports them, see https://bugzilla.mozilla.org/show_bug.cgi?id=687787

A common approach is to use a capturing handler to get the event earlier - eg http://yuiblog.com/blog/2008/10/07/onfocus-onblur/

Submodules

Is there a way to organise submodules? This is probably not an issue but I could not see a place to just ask questions

Confusion about phrasing on behaviors being accessed by modules

In Thinking in T3, heading "Loose Coupling of Components":

  1. Modules cannot access other modules directly.
  2. Modules cannot access behaviors directly.
  3. Behaviors cannot access other behaviors directly.
  4. Behaviors cannot access modules directly.
  5. [fifth point not relevant to this issue]

These all make sense to me โ€” except point 2, which seems flat-out wrong.

Later, in Understanding Behaviors, heading "Using Behaviors", this code example is shown:

Box.Application.addModule('test-module', function(context) {

    return {

        behaviors: [ 'behavior-name' ],

        init: function() {
            //code
        }

    };

});

That's a module accessing a behavior directly. In fact, it seems to me that the main raison d'รชtre of behaviors is for modules to directly access them.

Or does this not count as "directly", because we're accessing the module through its string name, and the framework takes care of the lookup? But this doesn't hold up, because (as far as I could find out), this only happens with modules accessing behaviors, but not with any of the other three combinations.

Furthermore, the "Loose Coupling" section continues: "Only services can be accessed directly by modules and behaviors". This access looks a bit different, but is essentially also a string lookup:

var anotherService = application.getService('another-service');

So I'm confused. It seems to me that behaviors can be accessed directly by modules just as much as services can.

Am I missing something fundamental here? What is the purpose of point 2?

Create a better way to reuse modules.

It wouldn't be nice to have a better way to reuse modules? Based on the spikes that I've done with T3 and from what I've understood from the documentation, If I want to reuse a module I must import the script and also the html. Couldn't be implemented a feature where the module(script) wraps html and add it to the DOM in runtime?

Eg. For reusing a module(Based on todo example)

From

<header id="header" data-module="header">
    <h1>todos</h1>
        <form data-type="new-todo-form">
            <input id="new-todo" data-type="new-todo-input">
        </form>
</header>

To

<header id="header" data-module="header">
</header>

Make T3 throw or warn when attempting to retrieve a service that doesn't exist in debug mode

Recently we discovered a ~6mo old bug in our system that was able to persist because T3 silently allowed a features flip service that didn't exist to be retrieved and used as a falsey value in subsequent logic. This could have been identified if T3 had thrown upon attempting to fetch the service, or at least dumped to conosle.warn when in debug mode to at least let a developer know they're attempting to access a service that does not exist.

For code cleanliness console statements can then later be stripped out during our build process with the drop_console flag when the code is minified for production use.

Suggestion: consider distribute this framework as bower package too

As per title, I think many users would love to just do bower install t3 to install this framework, like me ; ).
Is there any plan to distribute this on bower?

Also, speaking of bower, npm install t3 is also a common way for people (those who use browserify for example) to download this framework.

So what if I want to subscribe an even inside React component

Consider code below:

var UI = React.createClass({
  getInitialState: function() {
    return 'initial text';
  },

  render: function() {
    return (<div>{this.state.text}</div>);
  }
});

Application.addModule('ui', function(context) {
  return {
    messages: ['update'],

    onmessage: function(name) {
      if (name == 'update') {
        context.ui.setState({text: 'updated'});
      }
    },

    init: function() {
        context.ui = React.render(<UI />, document.getElementById('root'));
    }
  };
});

Application.init();

As you can see that to update the React component (UI), we often setState, but in this case, the UI needs to expose itself to module context, so that later on in onmessage function, we can reference it. Is there any way that we can directly subscribe to certain messages inside the React component?

Thank you

Create a way for services to autowire up events like modules

People seem to really like using the autowiring of events in modules and behaviors, and when they get to modules, they are disappointed that they need to wire up their own event handlers the old-fashioned way. It would be nice to provide some facility for services to do declarative event handling in the same way behaviors and modules do.

Make some changes to Todo example

Hi. I'm going to make some minor changes to Todo example.

  1. When a todo changes its state, the list should be filtered corresponding to the filter's value. More specifically, a todo should be removed from the current list if it get completed in /active or get re-opened in /completed.
  2. A minor duplicated declaration in list module

Question: iframe inside a module

I have an iframe inside one of my modules. The iframe conforms to same-origin policy - in other words, I can reach inside and do all kinds of stuff with its DOM with just jQuery. The question itself is as follows:

  1. Can I use any of T3's event handling capabilities, or am I bound to using plain old jQuery's 'on' method?
  2. Can I create a module that encompasses the CONTENTS of the iframe (not the iframe element, but the DOM inside)?

Possibly make some application methods chainable

Hey very nice app architecture framework. Where I work we have a need to use progressive enhancement quite a bit and I found most other app architecture frameworks didn't make it easy to serve HTML from the server. We just needed something simple to help organize our JavaScript. This looks to fit the bill.

On to my question. We'd like to lazy-load not only the module HTML but also the JavaScript file associated with it.

From the few tests I've done it looks to be possible, we'd just have to make sure each T3 component starts itself rather than using the Box.Application.init method (at least I think that'll work.. if there's a cleaner way... I'm all ears).

With that said, would it be possible to make Box.Application.addModule, addService, etc. return an instance of the application instead of undefined. This way I could do something like the following:

Box.Application.addModule('some-module', function(context) {

    'use strict';

    return {

        init: function() {

    },

    destroy: function() {

        }
    };

}).start(document.getElementById('some-module'));

This is really more of a stylistic preference but would be nice to have.

Load via npm as module

Now, there is no way to load t3js properly via browserify or webpack, as package.json does not have any main file entry, so I can't just write:

import Box from "t3js";

But it would be very nice to have such opportunity (not to use global Box variable, but the one exported by module).

Abstract out DOM methods and event handling

A few people have commented that since we use jQuery just for event handling, then it's possible to extract that out so jQuery is no longer a hard dependency. This is a great idea!

In the discussions within our team, we talked a bit about the preferred approach to doing so. #17 was proposed, but the general feeling was that we don't want to bake jQuery detection into the core of T3. So, we'd like to consider another option where we created something like this:

Box.Events = {
    on: function(element, type, listener) {},
    off: function(element, type, listenter) {}
};

Then, we can have both a jQuery version and a native version, while the core of T3 relies on Box.Events.on/off instead of either native or jQuery.

The remaining question is how best to work that into the bundled version in /dist.

Question: Event Handling Order

When a click occurs in a module, the click event will first be handled by the module, then the behaviors in the specified order.
Is there a way to handle the click event by the module after the behaviors?

Todo example fails to update completed items

when select all box is checked but you are in a filtered view, like showing only completed items.
This is because the UI only renders/modifies the checkboxes on screen and not all checkboxes from the model

[question] module lifecycle

When we init() the application we do a startAll. There are cases though that we don't want to start a module on init but after an action or after another module has been started. Do you handle cases like these in projects made with t3js? Is it possible to specify the starting order?

Change entry point in package.json

The actual main entry point in package.json file is :

"main": "dist/t3.js"

And this version of T3 still depends on jQuery.

Now that there is a native version of the framework (without jQuery dependency), it would be great to have it included as the new entry point in package.json file :

"main": "dist/t3-native.js"

It would allow us to require('t3js') (with Browserify for example) without the need to require also jQuery and pollute the global scope to make it work with T3.

Any thoughts about it ?

Thanks !

Allow non-T3 components to listen for messages

Right now, when a message is broadcast(), only modules can listen for it. That works fine when you're dealing with just T3 components, but sometimes there are non-T3 components that need to be informed of messages as well.

We can implement this quite simply by firing a message event when broadcast() is called. This would allow non-T3 components to do the following:

Box.Application.on('message', function(event) {

    if (event.data.message === 'some_specific_message') {
        // do something
    }

});

So event.data.message is the message name and event.data.messageData is whatever would be passed in as the second argument to onmessage in a module.

[question] Module loaders

I am wondering if using a module loader like requireJS, webpack etc is a good practise for a t3js project.
Because this way you could require a service instead of using the Application object API.

Behavior event handlers shouldn't be called if event.stopImmediatePropagation() is called

Hi there

I think when event handler in module return false, event handlers in behaviors must not be called.
propose change in bindEventType function for simulate bubbling between module and behaviors:

function bindEventType(element, type, handlers) {
        function eventHandler(event) {
            var targetElement = getNearestTypeElement(event.target),
                elementType = targetElement ? targetElement.getAttribute('data-type') : '',
                result
                ;

```
        for (var i = 0; i < handlers.length; i++) {
            //handlers[i](event, targetElement, elementType);                
            result = handlers[i](event, targetElement, elementType);
            if(result===false) return false;                
        }

        return result;
    }

    // @NOTE(nzakas): Using jQuery for event normalization
    $(element).on(type, eventHandler);

    return eventHandler;
}
```

update docs with more info around focus/blur

Hi - I have not written anything with T3 yet, but am currently reading the docs and the part about blur and focus events being unsupported surprises me.

I think it's quite common to want extra functionality on form inputs when a user focuses or blurs them. Example: consider a sign-up form. When the username input is blurred, it can be useful to use ajax to query the server to check that the provided username is valid (and not already in use), and then to display a message alongside the input.

What would you suggest is the best way forward in this situation? I guess you could add the events manually in the module init function but that doesn't sound like a good practice. I thought about onkeyup, but that could trigger unnecessary multiple ajax requests to the server.

Discussion - multiple points

I have been working with Single page application from last 3-4 year. I liked @nzakas 's video on and implemented a slightly modified version for scalable arch with Javascript. So, I want to discuss my experience.
Before I write, I want to thanks @nzakas for video+books. I consider you are my Teacher too. :)

Here is the link of library I made. https://github.com/nsisodiya/choona.js , We at Unicommerce are using this library in production from last 1.5 years.

So here are few points to discuss.

Events

Every module is registering 16 events. I see a array eventTypes. I think this is not a good idea. In choona.js, I have used backbone view syntax.

        events : {
            "click #submitBtn" : "onSubmitBtnClick"
        },

I must say, t3.js should take this approach, mainly because

  • Register events which use need.
  • Simple syntax, and not need to make lots of if/else like
    if (elementType === 'new-todo-input') {
    }

Module Definition

I noticed that, t3.js has module definition where we need to create a function which return module object. you are passing context which is basically a sandbox (If I am not wrong).
Instead of this, we can use Constructor pattern too. In my opinion this will save memory with common methods over prototype chain.

Dynamic modules/Views + recursively destroy

I noticed that most of the html present in index.html itself. In most SASS based app, everything is dynamically loaded. Server send almost empty html page and every module load its own html using template property or simple moduleEle.innerHTML etc. Every module further load some sub-module. submodule loading is provided using methods which are provided by sandbox/context. In my current implementation, every module has a registry for its submodule. Why this registry should be maintained by module ? because when top-level router want to "UN-LOAD" a module, all its submodule much be ended. Its like calling destroy function recursively.
I am unable to see such such recursiveness. May be this is not for t3.js.
Also, It will be great If we can have some demo/guideline for applications which has every module load dynamic html. Or t3.js is best suitable for web-apps which are server side rendered.

Demo

In demo, http://t3js.org/examples/todo/live/ , new dynamic todo is added and functionality is added using behavior. https://github.com/box/t3js/blob/gh-pages/examples/todo/live/js/behaviors/todo.js . I am unable to get difference between module and behaviors. I think, module & behavior share common context and both moduleEl.

PS: Thanks for nice library.

How well does T3 work with ReactJS?

I love ReactJS but it basically only renders View and I still need the other things like event handling, etc. It seems T3 has very simple and elegant idea. I tried a bit tonight with T3 + ReactJS. One thing I did notice is that when I run Box.Application.init, it expects that all the elements with data-module attributes are already added to Box.Application.

It seems I've found that componentWillMount is a good place to write Box.Application.addModule and in componentDidMount, you can run Box.Application.init.

I attached my code below. Do you think this is the proper way to use T3 and ReactJS? Thank you!

           var CommentBox = React.createClass({
                getInitialState: function() {
                    return {
                        showSubmit: true
                    };
                },

                componentWillMount: function() {
                    var r = this;
                    Box.Application.addModule('comment-box', function(context) {

                        // private methods here
                        return {

                            init: function() {
                                // capture the reference when the module is started
                                moduleEl = context.getElement();
                                console.log(moduleEl);
                            },

                            onclick: function(event, element, elementType) {
                                if (elementType == 'submit-btn') {
                                    r.setState({showSubmit: false});
                                    context.broadcast('submit', 'Submitted!');
                                } else if (elementType == 'close-btn') {
                                    r.setState({showSubmit: true});
                                    context.broadcast('close', 'Closed!');
                                }
                            }

                        };
                    });
                },

                render: function() {
                    return (
                        <div className="commentBox" data-module="comment-box">
                            <input type="text" />
                            {this.state.showSubmit ? <button data-type="submit-btn">Submit</button> : <button type="button" data-type="close-btn">Close</button>}
                        </div>
                    );
                }
            });

            var Article = React.createClass({
                getInitialState: function() {
                    return {text: ''};
                },

                componentWillMount: function() {
                    var r = this;
                    Box.Application.addModule('article', function(context) {
                        return {
                            messages: ['submit', 'close'],

                            onmessage: function(name, data) {
                                if (name == 'submit') {
                                    r.setState({text: 'submit: ' + data});
                                } else if (name == 'close') {
                                    r.setState({text: 'close: ' + data});
                                }
                            }
                        };
                    });
                },

                render: function() {
                    return (
                        <div data-module="article">
                            <p>{this.state.text}</p>
                        </div>
                    );
                }
            });

            var UI = React.createClass({
                componentDidMount: function() {
                    Box.Application.init({debug: true});
                },

                render: function() {
                    return (
                        <div>
                            <CommentBox />
                            <Article />
                        </div>
                    );
                }
            });

            React.render(
                <UI />,
                document.getElementById('content')
            );

Consider calling start/stop on root element passed to startAll/stopAll

Would it be against any of the design choices to change the logic inside startAll and stopAll to also pick up any module declared on the element passed to those methods (the root arg) in addition to child modules found under the root?

In our app we have partials that reload and replace themselves; and they sometimes are T3 modules also. While we have the standard stopAll(elem); loadAndReplace(elem, url); startAll(elem) cycle implemented, if the author of the partial decides that the module needs to be bound to the elem, it won't be picked by the startAll/stopAll methods. The alternative is to add an outside wrapper element (mostly not possible in our case, the partial would not know about it) or inner, direct child container and treat it as the module host (however, this container is artificial and is there only as a workaround for chosen javascript library's issue; not mentioning it could mess with css selectors designed for the partial's content). As we're moving our here-and-there js "code islands" progressively to T3 modules, we'd love not to have to change the html structure to make the move possible.

As a bonus, the change would allow declaring modules on the html element (referenced as document.documentElement in Box.Application.init/destroy methods), if anyone so desires.

What do you think abou the proposed change?

Question: why jQuery dependency?

I understand Box.com might be using jQuery features extensively, but if T3's idea is to stay modular, then why not decouple jQuery as well.

Looking at the documents (apologize if I missed something), it seems jQuery would be used for data-binding, but there can be lots of approach to data-binding, not to mention virtual-dom approach (where binding is handled differently)

Seems like T3 can be done without jQuery, or at least with alternatives like DOMtastic.

Either way, I am just very excited to see a framework that takes progressive enhancement into account and I am very interested in using it for my current project.

pass data from module to behavior

Hi there

I want to pass some data from module to behavior. can I do it?
I handle onclick in module and behavior. I know that module handler called first, and then behavior handler. In normal bubbling when return some value from inner handler I can get it in outer handler as event.result
but this is not a bubbling then what is the solution?

Expand captureObjectErrors to wrap behaviors and services in addition to modules

This came up while looking for a way to have captureObjectErrors also provide metadata as to whether an errors spawned for a behavior, service, or module. We learned that only modules were being wrapped so errors from services and behaviors aren't falling into this logic path where we can wrap them properly.

Discussion of providing this came about from #78

Third param to addService?

Is there any documentation on the third param to addService()? It's being used in the ToDo router. It looks like it lets you attach methods directly to the application object, with room to expand this behavior in the future.

Is this API public, functional, and intentional? And are these exports available to other services, or only as a shorthand for the service doing the exporting? Etc :)

Module Name in Creater Context

I'd like to re-use the module name for namespacing things like events and CSS classes. I could replicate the name in a private variable like this:

Box.Application.addModule('some-module', function(context) {

    'use strict';

    var MODULE_NAME = 'some-module';

    function broadcast ( name, data ) {
        context.broadcast( MODULE_NAME + ':' + name, data );
    };

    return {

        onclick: function(event, element, elementType) {

            // TODO: Handle specific events...
            broadcast('show', 'some data');
        },

        init: function() {
            // ...
        },

        destroy: function() {
            // ...
        }

    };

});

However, it'd be nice not to have to replicate the name since it's already defined. Would it be possible to add the module's name to the this context inside of the creator function? Then I could do something like:

Box.Application.addModule('some-module', function(context) {

    'use strict';

    var MODULE_NAME = this.name;

    function broadcast ( name, data ) {
        context.broadcast( MODULE_NAME + ':' + name, data );
    };

    return {

        onclick: function(event, element, elementType) {

            // TODO: Handle specific events...
            broadcast('show', 'some data');
        },

        init: function() {
            // ...
        },

        destroy: function() {
            // ...
        }

    };

});

Or if there's already another way to get the name, I'd love to hear about it.

Add docs for dynamic loading of modules

Hi, I like your approach but I don't find something in your documentation:

How to load modules without having an index.html with all of them.

Something independent of the main page and encapsulated in a single container.

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.