├── .bowerrc
├── .editorconfig
├── .gitignore
├── .jshintrc
├── LICENSE
├── README.md
├── app
├── components
│ ├── d3
│ │ ├── .bower.json
│ │ ├── .gitattributes
│ │ ├── CONTRIBUTING.md
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── bower.json
│ │ ├── d3.js
│ │ ├── d3.min.js
│ │ └── package.js
│ ├── font-fit
│ │ ├── .bower.json
│ │ ├── bower.json
│ │ └── font-fit.js
│ ├── fxos-mvc
│ │ ├── .bower.json
│ │ ├── bower.json
│ │ ├── gulpfile.js
│ │ └── mvc.js
│ ├── gaia-component
│ │ ├── .bower.json
│ │ ├── bower.json
│ │ └── gaia-component.js
│ ├── gaia-fonts
│ │ ├── .bower.json
│ │ ├── bower.json
│ │ ├── fonts
│ │ │ ├── FiraSans-Bold.woff
│ │ │ ├── FiraSans-BoldItalic.woff
│ │ │ ├── FiraSans-Light.woff
│ │ │ ├── FiraSans-LightItalic.woff
│ │ │ ├── FiraSans-Medium.woff
│ │ │ ├── FiraSans-MediumItalic.woff
│ │ │ ├── FiraSans-Regular.woff
│ │ │ └── FiraSans-RegularItalic.woff
│ │ └── style.css
│ ├── gaia-header
│ │ ├── .bower.json
│ │ ├── .jshintrc
│ │ ├── bower.json
│ │ ├── dist
│ │ │ └── gaia-header.js
│ │ └── gaia-header.js
│ ├── gaia-icons
│ │ ├── .bower.json
│ │ ├── .jshintrc
│ │ ├── bin
│ │ │ └── report.js
│ │ ├── bower.json
│ │ ├── fonts
│ │ │ └── gaia-icons.ttf
│ │ ├── gaia-icons-embedded.css
│ │ ├── gaia-icons.css
│ │ └── gaia-icons.js
│ ├── node-isnumber
│ │ ├── .bower.json
│ │ ├── .gitignore
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ └── test
│ │ │ └── index.js
│ ├── node-stats-lite
│ │ ├── .bower.json
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── examples
│ │ │ └── dice.js
│ │ ├── package.json
│ │ ├── stats.js
│ │ └── test
│ │ │ └── index.js
│ ├── regression-js
│ │ ├── .bower.json
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── Gruntfile.js
│ │ ├── bower.json
│ │ ├── build
│ │ │ └── regression.min.js
│ │ ├── index.js
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── src
│ │ │ └── regression.js
│ └── threads
│ │ ├── .bower.json
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── bower.json
│ │ ├── index.js
│ │ ├── lib
│ │ ├── child-thread.js
│ │ ├── client
│ │ │ ├── index.js
│ │ │ └── stream.js
│ │ ├── emitter.js
│ │ ├── manager.js
│ │ ├── messenger.js
│ │ ├── service
│ │ │ ├── index.js
│ │ │ └── stream.js
│ │ ├── thread-global.js
│ │ └── utils.js
│ │ ├── package.json
│ │ ├── threads.js
│ │ └── threads.min.js
├── css
│ └── app.css
├── img
│ ├── creation-barchart.svg
│ ├── creation-scatter-plot.svg
│ ├── icon.svg
│ ├── icons
│ │ ├── 128.png
│ │ ├── 16.png
│ │ ├── 256.png
│ │ ├── 32.png
│ │ ├── 48.png
│ │ ├── 512.png
│ │ ├── 60.png
│ │ ├── 64.png
│ │ └── 90.png
│ ├── latency-barchart.svg
│ ├── latency-scatter-plot.svg
│ ├── transfer-speed-barchart.svg
│ └── transfer-speed-scatter-plot.svg
├── index.html
├── js
│ ├── app.js
│ ├── controllers
│ │ ├── creation.js
│ │ ├── home.js
│ │ ├── latency.js
│ │ ├── main.js
│ │ └── message.js
│ └── views
│ │ ├── creation.js
│ │ ├── home.js
│ │ ├── latency.js
│ │ └── message.js
├── manifest.webapp
└── workers
│ ├── creation-window
│ ├── index.html
│ └── script.js
│ ├── creation-worker.js
│ ├── latency-service.js
│ ├── latency-shared-worker.js
│ ├── latency-worker.js
│ ├── message-service.js
│ └── message-worker.js
├── bower.json
├── gulpfile.js
└── package.json
/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory": "app/components/"
3 | }
4 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # This file is installed as part of the build script setup.
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
15 | [*.yml]
16 | indent_style = space
17 | indent_size = 2
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 | TODO.md
4 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "curly": true,
3 | "devel": false,
4 | "esnext": true,
5 | "expr": false,
6 | "forin": false,
7 | "latedef": "nofunc",
8 | "newcap": true,
9 | "noarg": true,
10 | "nonew": false,
11 | "quotmark": "single",
12 | "undef": true,
13 | "unused": "vars",
14 | "strict": false,
15 | "laxcomma": false,
16 | "maxerr": 1000,
17 | "maxlen": 120,
18 | "proto": true,
19 | "browser": true,
20 | "node": true,
21 | "worker": true
22 | }
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #  Web workers benchmark
2 |
3 | > Benchmark various aspects of Web workers.
4 |
5 | ## What?
6 |
7 | A technical, mobile first app to benchmark different aspects related to web workers:
8 |
9 | * Instantiation
10 | * Messaging latency
11 | * Transfer speed
12 |
13 | The following communication methods are used:
14 |
15 | * [postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage)
16 | * [BroadcastChannel](https://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel/BroadcastChannel)
17 | * the [threads](https://github.com/gaia-components/threads) library
18 |
19 | ## Results
20 |
21 | Results measured on a Flame.
22 |
23 | ### Creation time
24 |
25 | 
26 |
27 | 
28 |
29 | ### Latency
30 |
31 | 
32 |
33 | 
34 |
35 | ### Transfer speed
36 |
37 | 
38 |
39 | 
40 |
41 | ## Compatibility
42 |
43 | While this app itself works cross-browser, the thread.js library requires an environment that
44 | supports the Broadcast Channel API (i.e. Firefox only currently). In the future, this may not be the
45 | case. It will then be possible to run this app in other browsers.
46 |
--------------------------------------------------------------------------------
/app/components/d3/.bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "d3",
3 | "version": "3.5.5",
4 | "main": "d3.js",
5 | "scripts": [
6 | "d3.js"
7 | ],
8 | "ignore": [
9 | ".DS_Store",
10 | ".git",
11 | ".gitignore",
12 | ".npmignore",
13 | ".spmignore",
14 | ".travis.yml",
15 | "Makefile",
16 | "bin",
17 | "component.json",
18 | "composer.json",
19 | "index.js",
20 | "lib",
21 | "node_modules",
22 | "package.json",
23 | "src",
24 | "test"
25 | ],
26 | "homepage": "https://github.com/mbostock/d3",
27 | "_release": "3.5.5",
28 | "_resolution": {
29 | "type": "version",
30 | "tag": "v3.5.5",
31 | "commit": "9628a923cb9df82058a4a2fcc8d415e45b6d5d2f"
32 | },
33 | "_source": "git://github.com/mbostock/d3.git",
34 | "_target": "~3.5.5",
35 | "_originalSource": "d3"
36 | }
--------------------------------------------------------------------------------
/app/components/d3/.gitattributes:
--------------------------------------------------------------------------------
1 | bower.json -diff merge=ours
2 | component.json -diff merge=ours
3 | d3.js -diff merge=ours
4 | d3.min.js -diff merge=ours
5 | package.js -diff merge=ours
6 |
--------------------------------------------------------------------------------
/app/components/d3/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | **Important:** these GitHub issues are for *bug reports and feature requests only*. Please use [StackOverflow](http://stackoverflow.com/questions/tagged/d3.js) or the [d3-js Google group](https://groups.google.com/d/forum/d3-js) for general help.
4 |
5 | If you’re looking for ways to contribute, please [peruse open issues](https://github.com/mbostock/d3/issues?milestone=&page=1&state=open). The icebox is a good place to find ideas that are not currently in development. If you already have an idea, please check past issues to see whether your idea or a similar one was previously discussed.
6 |
7 | Before submitting a pull request, consider implementing a live example first, say using [bl.ocks.org](http://bl.ocks.org). Real-world use cases go a long way to demonstrating the usefulness of a proposed feature. The more complex a feature’s implementation, the more usefulness it should provide. Share your demo using the #d3js tag on Twitter or by sending it to the [d3-js Google group](https://groups.google.com/d/forum/d3-js).
8 |
9 | If your proposed feature does not involve changing core functionality, consider submitting it instead as a [D3 plugin](https://github.com/d3/d3-plugins). New core features should be for general use, whereas plugins are suitable for more specialized use cases. When in doubt, it’s easier to start with a plugin before “graduating” to core.
10 |
11 | To contribute new documentation or add examples to the gallery, just [edit the Wiki](https://github.com/mbostock/d3/wiki)!
12 |
13 | ## How to Submit a Pull Request
14 |
15 | 1. Click the “Fork” button to create your personal fork of the D3 repository.
16 |
17 | 2. After cloning your fork of the D3 repository in the terminal, run `npm install` to install D3’s dependencies.
18 |
19 | 3. Create a new branch for your new feature. For example: `git checkout -b my-awesome-feature`. A dedicated branch for your pull request means you can develop multiple features at the same time, and ensures that your pull request is stable even if you later decide to develop an unrelated feature.
20 |
21 | 4. The `d3.js` and `d3.min.js` files are built from source files in the `src` directory. _Do not edit `d3.js` directly._ Instead, edit the source files, and then run `make` to build the generated files.
22 |
23 | 5. Use `make test` to run tests and verify your changes. If you are adding a new feature, you should add new tests! If you are changing existing functionality, make sure the existing tests run, or update them as appropriate.
24 |
25 | 6. Sign D3’s [Individual Contributor License Agreement](https://docs.google.com/forms/d/1CzjdBKtDuA8WeuFJinadx956xLQ4Xriv7-oDvXnZMaI/viewform). Unless you are submitting a trivial patch (such as fixing a typo), this form is needed to verify that you are able to contribute.
26 |
27 | 7. Submit your pull request, and good luck!
28 |
--------------------------------------------------------------------------------
/app/components/d3/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010-2015, Michael Bostock
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | * The name Michael Bostock may not be used to endorse or promote products
15 | derived from this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT,
21 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
24 | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 |
--------------------------------------------------------------------------------
/app/components/d3/README.md:
--------------------------------------------------------------------------------
1 | # Data-Driven Documents
2 |
3 |
4 |
5 | **D3.js** is a JavaScript library for manipulating documents based on data. **D3** helps you bring data to life using HTML, SVG and CSS. D3’s emphasis on web standards gives you the full capabilities of modern browsers without tying yourself to a proprietary framework, combining powerful visualization components and a data-driven approach to DOM manipulation.
6 |
7 | Want to learn more? [See the wiki.](https://github.com/mbostock/d3/wiki)
8 |
9 | For examples, [see the gallery](https://github.com/mbostock/d3/wiki/Gallery) and [mbostock’s bl.ocks](http://bl.ocks.org/mbostock).
10 |
--------------------------------------------------------------------------------
/app/components/d3/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "d3",
3 | "version": "3.5.5",
4 | "main": "d3.js",
5 | "scripts": [
6 | "d3.js"
7 | ],
8 | "ignore": [
9 | ".DS_Store",
10 | ".git",
11 | ".gitignore",
12 | ".npmignore",
13 | ".spmignore",
14 | ".travis.yml",
15 | "Makefile",
16 | "bin",
17 | "component.json",
18 | "composer.json",
19 | "index.js",
20 | "lib",
21 | "node_modules",
22 | "package.json",
23 | "src",
24 | "test"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/app/components/d3/package.js:
--------------------------------------------------------------------------------
1 | // Package metadata for Meteor.js.
2 |
3 | Package.describe({
4 | name: "d3js:d3", // http://atmospherejs.com/d3js/d3
5 | summary: "D3 (official): A JavaScript visualization library for HTML and SVG.",
6 | version: "3.5.5",
7 | git: "https://github.com/mbostock/d3.git"
8 | });
9 |
10 | Package.onUse(function(api) {
11 | api.versionsFrom(["METEOR@1.0"]);
12 | api.addFiles("d3.js", "client");
13 | });
14 |
--------------------------------------------------------------------------------
/app/components/font-fit/.bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "font-fit",
3 | "main": "font-fit.js",
4 | "version": "0.3.1",
5 | "authors": [
6 | "Wilson Page "
7 | ],
8 | "license": "MIT",
9 | "ignore": [
10 | "**/.*",
11 | "node_modules",
12 | "bower_components",
13 | "test",
14 | "README.md",
15 | "index.html",
16 | "package.json"
17 | ],
18 | "homepage": "https://github.com/gaia-components/font-fit",
19 | "_release": "0.3.1",
20 | "_resolution": {
21 | "type": "version",
22 | "tag": "v0.3.1",
23 | "commit": "07a497519b335a3d86a66268f990d8844b83d517"
24 | },
25 | "_source": "git://github.com/gaia-components/font-fit.git",
26 | "_target": "~0.3.0",
27 | "_originalSource": "gaia-components/font-fit"
28 | }
--------------------------------------------------------------------------------
/app/components/font-fit/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "font-fit",
3 | "main": "font-fit.js",
4 | "version": "0.3.1",
5 | "authors": [
6 | "Wilson Page "
7 | ],
8 | "license": "MIT",
9 | "ignore": [
10 | "**/.*",
11 | "node_modules",
12 | "bower_components",
13 | "test",
14 | "README.md",
15 | "index.html",
16 | "package.json"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/app/components/font-fit/font-fit.js:
--------------------------------------------------------------------------------
1 | ;(function(define){define(function(require,exports,module){
2 | 'use strict';
3 |
4 | /**
5 | * Simple logger.
6 | *
7 | * @return {Function}
8 | */
9 | var debug = 0 ? console.log.bind(console) : function(){};
10 |
11 | /**
12 | * Global canvas cache.
13 | *
14 | * @type {Object}
15 | */
16 | var cache = {};
17 |
18 | /**
19 | * Default min/max font-size.
20 | *
21 | * @type {Number}
22 | */
23 | var MIN = 16;
24 | var MAX = 24;
25 |
26 | /**
27 | * The number of pixels to subtract from
28 | * the given `config.space` to ensure
29 | * HTML text doesn't overflow container.
30 | *
31 | * Ideally we would use 1px, but in some
32 | * cases italicised text in canvas is ~2px
33 | * longer than the same text in HTML.
34 | *
35 | * http://bugzil.la/1126391
36 | *
37 | * @type {Number}
38 | */
39 | var BUFFER = 3;
40 |
41 | /**
42 | * Get the font-size that closest fits
43 | * the given space with the given font.
44 | *
45 | * Config:
46 | *
47 | * - {String} `text` The text string
48 | * - {String} `font` Font shorthand string
49 | * - {Number} `space` Width (px) to fit the text into
50 | * - {Number} `min` Min font-size (px) (optional)
51 | * - {Number} `max` Max font-size (px) (optional)
52 | *
53 | * @param {Object} config
54 | * @return {Object} {fontSize,overflowing,textWidth}
55 | */
56 | module.exports = function(config) {
57 | debug('font fit', config);
58 | var space = config.space - BUFFER;
59 | var min = config.min || MIN;
60 | var max = config.max || MAX;
61 | var text = trim(config.text);
62 | var fontSize = max;
63 | var textWidth;
64 | var font;
65 |
66 | do {
67 | font = config.font.replace(/\d+px/, fontSize + 'px');
68 | textWidth = getTextWidth(text, font);
69 | } while (textWidth > space && fontSize !== min && fontSize--);
70 |
71 | return {
72 | textWidth: textWidth,
73 | fontSize: fontSize,
74 | overflowing: textWidth > space
75 | };
76 | };
77 |
78 | /**
79 | * Get the width of the given text
80 | * with the given font style.
81 | *
82 | * @param {String} text
83 | * @param {String} font (CSS shorthand)
84 | * @return {Number} (px)
85 | */
86 | function getTextWidth(text, font) {
87 | var ctx = getCanvasContext(font);
88 | var width = ctx.measureText(text).width;
89 | debug('got text width', width);
90 | return width;
91 | }
92 |
93 | /**
94 | * Get a canvas context configured
95 | * to the given font style.
96 | *
97 | * @param {String} font
98 | * @return {CanvasRenderingContext2D}
99 | */
100 | function getCanvasContext(font) {
101 | debug('get canvas context', font);
102 |
103 | var cached = cache[font];
104 | if (cached) { return cached; }
105 |
106 | var canvas = document.createElement('canvas');
107 | canvas.setAttribute('moz-opaque', 'true');
108 | canvas.setAttribute('width', '1px');
109 | canvas.setAttribute('height', '1px');
110 | debug('created canvas', canvas);
111 |
112 | var ctx = canvas.getContext('2d', { willReadFrequently: true });
113 | ctx.font = font;
114 |
115 | return cache[font] = ctx;
116 | }
117 |
118 | /**
119 | * Trim leading, trailing
120 | * and excess whitespace.
121 | *
122 | * @param {String} text
123 | * @return {String}
124 | */
125 | function trim(text) {
126 | return text.replace(/\s+/g, ' ').trim();
127 | }
128 |
129 | });})(typeof define=='function'&&define.amd?define
130 | :(function(n,w){'use strict';return typeof module=='object'?function(c){
131 | c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){
132 | return w[n];},m.exports,m);w[n]=m.exports;};})('font-fit',this));
133 |
--------------------------------------------------------------------------------
/app/components/fxos-mvc/.bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fxos-mvc",
3 | "version": "0.0.5",
4 | "homepage": "https://github.com/fxos/mvc",
5 | "license": "MPL",
6 | "main": "mvc.js",
7 | "ignore": [
8 | "**/.*",
9 | "example",
10 | "node_modules",
11 | "package.json",
12 | "README.md",
13 | "test"
14 | ],
15 | "_release": "0.0.5",
16 | "_resolution": {
17 | "type": "version",
18 | "tag": "v0.0.5",
19 | "commit": "4f9ed9c5f9ad591730548afd82d5d1f34c70c0c3"
20 | },
21 | "_source": "git@github.com:fxos/mvc.git",
22 | "_target": "*",
23 | "_originalSource": "git@github.com:fxos/mvc.git"
24 | }
--------------------------------------------------------------------------------
/app/components/fxos-mvc/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fxos-mvc",
3 | "version": "0.0.5",
4 | "homepage": "https://github.com/fxos/mvc",
5 | "license": "MPL",
6 | "main": "mvc.js",
7 | "ignore": [
8 | "**/.*",
9 | "example",
10 | "node_modules",
11 | "package.json",
12 | "README.md",
13 | "test"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/app/components/fxos-mvc/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var merge = require('gulp-merge');
3 | var concat = require('gulp-concat');
4 | var to5 = require('gulp-6to5');
5 |
6 | /**
7 | * converts javascript to es5.
8 | */
9 | gulp.task('to5', function () {
10 | try {
11 | return merge(
12 | gulp
13 | .src([
14 | './node_modules/observe-shim/lib/observe-shim.js',
15 | './node_modules/observe-utils/lib/observe-utils.js'
16 | ])
17 | .pipe(concat('shim.js')),
18 | gulp
19 | .src('./mvc.js')
20 | .pipe(to5({
21 | modules: 'amd'
22 | }).on('error', function(e) {
23 | console.log('error running 6to5', e);
24 | })
25 | )
26 | )
27 | .pipe(concat('mvc.js'))
28 | .pipe(gulp.dest('./dist/'));
29 | } catch(e) {
30 | console.log('Got error in 6to5', e);
31 | }
32 | });
33 |
34 | gulp.task('default', ['to5']);
35 |
--------------------------------------------------------------------------------
/app/components/fxos-mvc/mvc.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Model
3 | */
4 | export class Model {
5 | constructor(properties) {
6 | properties = properties || {};
7 |
8 | for (var key in properties) {
9 | this[key] = properties[key];
10 | }
11 |
12 | this.observableProperties = {};
13 |
14 | Object.observe(this, (changes) => {
15 | changes.forEach((change) => {
16 | var handlers = this.observableProperties[change.name];
17 | if (handlers) {
18 | handlers.forEach((handler) => {
19 | handler(change);
20 | });
21 | }
22 | });
23 | });
24 | }
25 |
26 | on(property, handler) {
27 | if (typeof handler !== 'function') {
28 | return;
29 | }
30 |
31 | if (!this.observableProperties[property]) {
32 | ObserveUtils.defineObservableProperties(this, property);
33 | this.observableProperties[property] = [];
34 | }
35 |
36 | this.observableProperties[property].push(handler);
37 | }
38 | }
39 |
40 | /**
41 | * View
42 | */
43 | var events = {};
44 |
45 | export class View {
46 | constructor(options) {
47 | options = options || {};
48 |
49 | for (var key in options) {
50 | this[key] = options[key];
51 | }
52 |
53 | if (!this.el) {
54 | this.el = document.createElement('div');
55 | }
56 | }
57 |
58 | /**
59 | * Initializes an instance with the specified controller.
60 | *
61 | * @param {Controller} controller
62 | * @return {View}
63 | */
64 | init(controller) {
65 | this.controller = controller;
66 |
67 | return this;
68 | }
69 |
70 | /**
71 | * Renders the layout wrapper for the template.
72 | *
73 | * @param {Template} Inner template
74 | * @return {String} Rendered layout with template
75 | */
76 | layout(template) {
77 | return template;
78 | }
79 |
80 | /**
81 | * Render the default template.
82 | */
83 | render(params) {
84 | var innerHTML = '';
85 |
86 | if (params) {
87 | if (typeof params === 'object') {
88 | for (var index in params) {
89 | var param = params[index];
90 | innerHTML += this.template(param);
91 | }
92 | } else {
93 | for (let i = 0; i < params.length; i++) {
94 | var param = params[i];
95 | innerHTML += this.template(param);
96 | }
97 | }
98 | } else {
99 | innerHTML = this.template();
100 | }
101 |
102 | this.el.innerHTML = this.layout(innerHTML);
103 | }
104 |
105 | /**
106 | * Override to provide a function that returns the template string.
107 | *
108 | * @return {String}
109 | */
110 | template() {
111 | return '';
112 | }
113 |
114 | /**
115 | * Finds a single child element using the specified selector.
116 | *
117 | * @param {String} query
118 | * @return {Element | null}
119 | */
120 | $(selector) {
121 | return this.el.querySelector(selector);
122 | }
123 |
124 | /**
125 | * Finds all child elements using the specified selector.
126 | *
127 | * @param {String} query
128 | * @return {NodeList}
129 | */
130 | $$(selector) {
131 | return this.el.querySelectorAll(selector);
132 | }
133 |
134 | /**
135 | *
136 | *
137 | */
138 | on(type, selector, handler, scope) {
139 | var controller = this.controller;
140 | scope = scope || this.el;
141 |
142 | if (!events[type]) {
143 | events[type] = [];
144 | window.addEventListener(type, delegateHandler, true);
145 | }
146 |
147 | events[type].push({
148 | selector: selector,
149 | handler: handler,
150 | controller: controller,
151 | scope: scope
152 | });
153 | }
154 |
155 | /**
156 | *
157 | *
158 | */
159 | off(type, selector, handler) {
160 | if (!events[type]) {
161 | return;
162 | }
163 |
164 | events[type] = events[type].filter((delegate) => {
165 | if (typeof handler === 'function') {
166 | return delegate.selector !== selector ||
167 | delegate.handler !== handler;
168 | }
169 |
170 | return delegate.selector !== selector;
171 | });
172 | }
173 | }
174 |
175 | /**
176 | * Forward an event based on the target's `[data-action]` attr to the controller.
177 | * e.g. "click" on a `