Skip to content

Commit

Permalink
Documentation using JSDoc and Markdown + AutoXHR docs
Browse files Browse the repository at this point in the history
* Add JSDoc support and build target to Gruntfile.js

* Add JSDoc style documentation and migrate existing HTML documentation to markdown

* Use SOASTA fork of jsdoc with disabled strict mode
  • Loading branch information
andreas-marschke authored and nicjansma committed Jun 24, 2016
1 parent dd6d22d commit a77714e
Show file tree
Hide file tree
Showing 60 changed files with 1,225 additions and 783 deletions.
6 changes: 4 additions & 2 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
"no-label-var": 2,
"no-labels": 2,
"no-lone-blocks": 2,
"no-loop-func": 2,
"no-multi-str": 2,
"no-native-reassign": 2,
"no-new": 2,
Expand Down Expand Up @@ -104,6 +103,9 @@
"no-delete-var": 0,

// We use spaces for alignment in many places
"no-multi-spaces": 0
"no-multi-spaces": 0,

// Ignored
"no-loop-func": 0
}
}
39 changes: 34 additions & 5 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,12 @@ module.exports = function() {
options: {
script: "tests/server/app.js"
}
},
doc: {
options: {
port: 4002,
script: "tests/server/doc-server.js"
}
}
},
"saucelabs-mocha": {
Expand Down Expand Up @@ -581,6 +587,18 @@ module.exports = function() {
}
}
},
jsdoc: {
dist: {
src: ["boomerang.js", "plugins/*.js"],
jsdoc: "./node_modules/jsdoc/jsdoc.js",
options: {
destination: "build/doc",
package: "package.json",
readme: "README.md",
configure: "jsdoc.conf.json"
}
}
},
watch: {
test: {
files: [
Expand Down Expand Up @@ -611,7 +629,15 @@ module.exports = function() {
files: [
"tests/server/*.js"
],
tasks: ["express"]
tasks: ["express:dev"]
},
doc: {
files: [
"boomerang.js",
"plugins/*.js",
"doc/**/**"
],
tasks: ["clean", "jsdoc"]
}
}
});
Expand All @@ -635,6 +661,7 @@ module.exports = function() {
grunt.loadNpmTasks("grunt-saucelabs");
grunt.loadNpmTasks("grunt-strip-code");
grunt.loadNpmTasks("grunt-contrib-watch");
grunt.loadNpmTasks("grunt-jsdoc");

// tasks/*.js
if (grunt.file.exists("tasks")) {
Expand Down Expand Up @@ -682,7 +709,7 @@ module.exports = function() {
"test:build:react": ["babel:spa-react-test-templates", "browserify:spa-react-test-templates"],

// useful for debugging tests, leaves a webbrowser open at http://localhost:3001
"test:debug": ["test:build", "build:test", "express", "watch"],
"test:debug": ["test:build", "build:test", "express:dev", "watch"],

// open your browser to http://localhost:4000/debug.html to debug
"test:karma:debug": ["test:build", "build:test", "karma:debug"],
Expand All @@ -698,9 +725,11 @@ module.exports = function() {

// End-to-End tests
"test:e2e": ["test:build", "build", "test:e2e:phantomjs"],
"test:e2e:chrome": ["build", "express", "protractor_webdriver", "protractor:chrome"],
"test:e2e:debug": ["build", "test:build", "build:test", "express", "protractor_webdriver", "protractor:debug"],
"test:e2e:phantomjs": ["build", "express", "protractor_webdriver", "protractor:phantomjs"],
"test:e2e:chrome": ["build", "express:dev", "protractor_webdriver", "protractor:chrome"],
"test:e2e:debug": ["build", "test:build", "build:test", "express:dev", "protractor_webdriver", "protractor:debug"],
"test:e2e:phantomjs": ["build", "express:dev", "protractor_webdriver", "protractor:phantomjs"],

"test:doc": ["clean", "jsdoc", "express:doc", "watch:doc"],

// SauceLabs tests
"test:matrix": ["test:matrix:unit", "test:matrix:e2e"],
Expand Down
111 changes: 60 additions & 51 deletions boomerang.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,47 @@
/*
* Copyright (c) 2011, Yahoo! Inc. All rights reserved.
* Copyright (c) 2011-2012, Log-Normal, Inc. All rights reserved.
* Copyright (c) 2012-2016, SOASTA, Inc. All rights reserved.
/**
* @copyright (c) 2011, Yahoo! Inc. All rights reserved.
* @copyright (c) 2012, Log-Normal, Inc. All rights reserved.
* @copyright (c) 2012-2016, SOASTA, Inc. All rights reserved.
* Copyrights licensed under the BSD License. See the accompanying LICENSE.txt file for terms.
*/

/**
\file boomerang.js
boomerang measures various performance characteristics of your user's browsing
experience and beacons it back to your server.
\details
To use this you'll need a web site, lots of users and the ability to do
something with the data you collect. How you collect the data is up to
you, but we have a few ideas.
* @namespace Boomerang
* @desc
* boomerang measures various performance characteristics of your user's browsing
* experience and beacons it back to your server.
*
* To use this you'll need a web site, lots of users and the ability to do
* something with the data you collect. How you collect the data is up to
* you, but we have a few ideas.
*/

// Measure the time the script started
// This has to be global so that we don't wait for the entire
// BOOMR function to download and execute before measuring the
// time. We also declare it without `var` so that we can later
// `delete` it. This is the only way that works on Internet Explorer
/**
* @memberof Boomerang
* @type {TimeStamp}
* @desc
* Measure the time the script started
* This has to be global so that we don't wait for the entire
* BOOMR function to download and execute before measuring the
* time. We also declare it without `var` so that we can later
* `delete` it. This is the only way that works on Internet Explorer
*/
BOOMR_start = new Date().getTime();

/**
Check the value of document.domain and fix it if incorrect.
This function is run at the top of boomerang, and then whenever
init() is called. If boomerang is running within an iframe, this
function checks to see if it can access elements in the parent
iframe. If not, it will fudge around with document.domain until
it finds a value that works.
This allows customers to change the value of document.domain at
any point within their page's load process, and we will adapt to
it.
* @function
* @desc
* Check the value of document.domain and fix it if incorrect.
* This function is run at the top of boomerang, and then whenever
* init() is called. If boomerang is running within an iframe, this
* function checks to see if it can access elements in the parent
* iframe. If not, it will fudge around with document.domain until
* it finds a value that works.
*
* This allows customers to change the value of document.domain at
* any point within their page's load process, and we will adapt to
* it.
* @param {string} domain - domain name as retrieved from page url
*/
function BOOMR_check_doc_domain(domain) {
/*eslint no-unused-vars:0*/
Expand Down Expand Up @@ -615,30 +623,31 @@ BOOMR_check_doc_domain();
return result;
},
/**
Add a MutationObserver for a given element and terminate after `timeout`ms.
@param el DOM element to watch for mutations
@param config MutationObserverInit object (https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver#MutationObserverInit)
@param timeout Number of milliseconds of no mutations after which the observer should be automatically disconnected
If set to a falsy value, the observer will wait indefinitely for Mutations.
@param callback Callback function to call either on timeout or if mutations are detected. The signature of this method is:
function(mutations, callback_data)
Where:
mutations is the list of mutations detected by the observer or `undefined` if the observer timed out
callback_data is the passed in `callback_data` parameter without modifications
The callback function may return a falsy value to disconnect the observer after it returns, or a truthy value to
keep watching for mutations. If the return value is numeric and greater than 0, then this will be the new timeout
if it is boolean instead, then the timeout will not fire any more so the caller MUST call disconnect() at some point
@param callback_data Any data to be passed to the callback function as its second parameter
@param callback_ctx An object that represents the `this` object of the `callback` method. Leave unset the callback function is not a method of an object
@returns - `null` if a MutationObserver could not be created OR
- An object containing the observer and the timer object:
{ observer: <MutationObserver>, timer: <Timeout Timer if any> }
The caller can use this to disconnect the observer at any point by calling `retval.observer.disconnect()`
Note that the caller should first check to see if `retval.observer` is set before calling `disconnect()` as it may
have been cleared automatically.
* @desc
* Add a MutationObserver for a given element and terminate after `timeout`ms.
* @param el DOM element to watch for mutations
* @param config MutationObserverInit object (https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver#MutationObserverInit)
* @param timeout Number of milliseconds of no mutations after which the observer should be automatically disconnected
* If set to a falsy value, the observer will wait indefinitely for Mutations.
* @param callback Callback function to call either on timeout or if mutations are detected. The signature of this method is:
* function(mutations, callback_data)
* Where:
* mutations is the list of mutations detected by the observer or `undefined` if the observer timed out
* callback_data is the passed in `callback_data` parameter without modifications
*
* The callback function may return a falsy value to disconnect the observer after it returns, or a truthy value to
* keep watching for mutations. If the return value is numeric and greater than 0, then this will be the new timeout
* if it is boolean instead, then the timeout will not fire any more so the caller MUST call disconnect() at some point
* @param callback_data Any data to be passed to the callback function as its second parameter
* @param callback_ctx An object that represents the `this` object of the `callback` method. Leave unset the callback function is not a method of an object
*
* @returns {?object} - `null` if a MutationObserver could not be created OR
* - An object containing the observer and the timer object:
* { observer: <MutationObserver>, timer: <Timeout Timer if any> }
*
* The caller can use this to disconnect the observer at any point by calling `retval.observer.disconnect()`
* Note that the caller should first check to see if `retval.observer` is set before calling `disconnect()` as it may
* have been cleared automatically.
*/
addObserver: function(el, config, timeout, callback, callback_data, callback_ctx) {
var o = {observer: null, timer: null};
Expand Down
File renamed without changes.
38 changes: 38 additions & 0 deletions doc/about.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# this, is boomerang

> boomerang always comes back, except when it hits something.
## What?

boomerang is a piece of javascript that you add to your web pages, where it measures
the performance of your website from your end user's point of view. It has the ability
to send this data back to your server for further analysis. With boomerang, you find
out exactly how fast your users think your site is.

boomerang is opensource and released under the BSD license,
and we have a whole bunch of documentation about it.

## How?

- [Use Cases](tutorial-use-cases.html) -- Just some of the uses of boomerang that we can think of
- [How it works](tutorial-methodology.html) -- A short description of how boomerang works internally
- [Bugs, hugs and code](tutorial-community.html) -- This is where the community comes in
- [TODO](tutorial-TODO.txt.html) -- There's a lot that we still need to do. Wanna help?
- [Howto API Documentation](tutorial-howtos/index.html) -- Short recipes on how to do a bunch of things with boomerang
- [API Documentation](tutorial-api/index.html) -- For all you hackers out there
- [Press coverage](tutorial-press) -- A list of articles about boomerang

boomerang comes to you from the [Exceptional Performance](http://developer.yahoo.com/performance/)
team at [Yahoo!](http://www.yahoo.com/), aided by the [Yahoo! Developer Network](http://developer.yahoo.com/).

## Where?

- Get a zip or tarball from [github.com/lognormal/boomerang/archives/master](https://github.com/lognormal/boomerang/archives/master)
- Get the working source code from [github.com/lognormal/boomerang](https://github.com/lognormal/boomerang)

<!--
Copyright (c) 2011, Yahoo! Inc. All rights reserved.
Copyright (c) 2012, Log-Normal, Inc. All rights reserved.
Copyright (c) 2015, SOASTA, Inc. All rights reserved.
Copyrights licensed under the BSD License. See the accompanying LICENSE.txt file for terms.
-->
Empty file added doc/api.md
Empty file.
92 changes: 92 additions & 0 deletions doc/api/AutoXHR.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
AutoXHR - Instrument and measure AJAX requests and DOM manipulations triggering network requests

With this plugin sites can not only monitor their page load but also the XMLHttpRequests after the page has been loaded
as well as the DOM manipulations that trigger an asset to be fetched.

### Configuring Boomerang with AutoXHR included

You can enable the AutoXHR plugin with:

```js
BOOMR.init({
instrument_xhr: true
})
```

Once this has been done and the site has been loaded and instrumented with this plugin, we have replaced the `XMLHttpRequest` object
on the site with our very own!

### Monitoring XHRs

If you were to send an `XMLHttpRequest` on your page now you can see not only a page load beacon but also an XHR beacon:

```js
xhr = new XMLHttpRequest();
xhr.open("GET", "support/script200.js"); //200, async
xhr.send(null);
```

If you have boomerang with the auto_xhr.js plugin included in your page and someone visited the page, we are able
to measure the time this asset takes to come down from the server. Measured performance data will include:

- `u`: the URL of the image that has been fetched
- `http.initiator`: The type of Beacon or Request that has been triggered in this case `xhr`

### Using AutoXHR to monitor DOM events

Say for example that you have button on the page that will insert a new picture, we can monitor this asset coming down and
send timing information for that page:

```html
<script type="text/javascript">
(function(w, d) {
var imageHolder = d.getElementById("picture");
var clickable = d.getElementById("clickable");
function clickCb() {
var imageElement = d.createElement("img");
imageElement.src = "support/img.jpg";
imageHolder.appendChild(imageElement);
}
function addEvent(element, event, funct){
if (element.attachEvent) {
return element.attachEvent("on"+event, funct);
}
else {
return element.addEventListener(event, funct);
}
}
addEvent(clickable, "mouseup", clickCb);
}(this, this.document));
</script>

<div id="clickable">Click Me!</div>
<div id="picture"></div>
```

### Before Page Load XHR Beacons

By default AutoXHR will wait until the pages page load beacon has been sent to enable itself to start sending beacons that will correspond with the pages
XHRs. If you wish to enable AutoXHR Beacons sending before the site itself has loaded, you can set a config flag for the AutoXHR plugin to enable it to
send beacons as soon as it has instrumented the page.

```
BOOMR.init({
instrument_xhr: true,
AutoXHR: {
alwaysSendXhr: true
}
})
```

### Compatibility and Browser Support

Currently supported Browsers and platforms that AutoXHR will work on:

- IE 9+ (not in quirks mode)
- Chrome 38+
- Firefox 25+

In general we support all browsers that support `MutationObserver`, `XMLHttpRequest` with `addEventListener` on the XMLHttpRequest instance


Loading

0 comments on commit a77714e

Please sign in to comment.