Skip to content

Commit

Permalink
jshint all of the code and fixed up the hint + whitespace tasks in th…
Browse files Browse the repository at this point in the history
…e jakefile
  • Loading branch information
filmaj authored and imhotep committed Apr 20, 2012
1 parent 88b2e2f commit a1f5ee2
Show file tree
Hide file tree
Showing 114 changed files with 480 additions and 362 deletions.
141 changes: 141 additions & 0 deletions .jshintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
// Defaults as of jshint edition 2011-04-16
{
// If the scan should stop on first error.
"passfail": false,
// Maximum errors before stopping.
"maxerr": 50,


// Predefined globals
// If the standard browser globals should be predefined.
"browser": true,
// If the Node.js environment globals should be predefined.
"node": true,
// If the Rhino environment globals should be predefined.
"rhino": false,
// If CouchDB globals should be predefined.
"couch": false,
// If the Windows Scripting Host environment globals should be predefined.
"wsh": false,

// If jQuery globals should be predefined.
"jquery": false,
// If Prototype and Scriptaculous globals should be predefined.
"prototypejs": false,
// If MooTools globals should be predefined.
"mootools": false,
// If Dojo Toolkit globals should be predefined.
"dojo": false,

// Custom predefined globals.
"predef": ["jasmine", "blackberry", "define", "alert", "prompt", "org"],


// Development
// If debugger statements should be allowed.
"debug": false,
// If logging globals should be predefined (console, alert, etc.).
"devel": false,


// ECMAScript 5
// If ES5 syntax should be allowed.
"es5": false,
// Require the "use strict"; pragma.
"strict": false,
// If global "use strict"; should be allowed (also enables strict).
"globalstrict": false,


// The Good Parts
// If automatic semicolon insertion should be tolerated.
"asi": false,
// If line breaks should not be checked, e.g. `return [\n] x`.
"laxbreak": false,
// If bitwise operators (&, |, ^, etc.) should not be allowed.
"bitwise": false,
// If assignments inside if, for and while should be allowed. Usually
// conditions and loops are for comparison, not assignments.
"boss": true,
// If curly braces around all blocks should be required.
"curly": false,
// If === should be required.
"eqeqeq": false,
// If == null comparisons should be tolerated.
"eqnull": false,
// If eval should be allowed.
"evil": true,
// If ExpressionStatement should be allowed as Programs.
"expr": true,
// If `for in` loops must filter with `hasOwnPrototype`.
"forin": false,
// If immediate invocations must be wrapped in parens, e.g.
// `( function(){}() );`.
"immed": false,
// If use before define should not be tolerated.
"latedef": false,
// If functions should be allowed to be defined within loops.
"loopfunc": true,
// If arguments.caller and arguments.callee should be disallowed.
"noarg": false,
// If the . should not be allowed in regexp literals.
"regexp": false,
// If unescaped first/last dash (-) inside brackets should be tolerated.
"regexdash": false,
// If script-targeted URLs should be tolerated.
"scripturl": false,
// If variable shadowing should be tolerated.
"shadow": false,
// If `new function () { ... };` and `new Object;` should be tolerated.
"supernew": false,
// If variables should be declared before used.
"undef": true,
// If `this` inside a non-constructor function is valid.
"validthis": false,
// If smarttabs should be tolerated
// (http://www.emacswiki.org/emacs/SmartTabs).
"smarttabs": false,
// If the `__proto__` property should be allowed.
"proto": false,
// If one case switch statements should be allowed.
"onecase": false,
// If non-standard (but widely adopted) globals should be predefined.
"nonstandard": false,
// Allow multiline strings.
"multistr": false,
// If line breaks should not be checked around commas.
"laxcomma": false,
// If semicolons may be ommitted for the trailing statements inside of a
// one-line blocks.
"lastsemic": false,
// If the `__iterator__` property should be allowed.
"iterator": false,
// If only function scope should be used for scope tests.
"funcscope": false,
// If es.next specific syntax should be allowed.
"esnext": false,


// Style preferences
// If constructor names must be capitalized.
"newcap": false,
// If empty blocks should be disallowed.
"noempty": false,
// If using `new` for side-effects should be disallowed.
"nonew": false,
// If names should be checked for leading or trailing underscores
// (object._attribute would be disallowed).
"nomen": false,
// If only one var statement per function should be allowed.
"onevar": false,
// If increment and decrement (`++` and `--`) should not be allowed.
"plusplus": false,
// If all forms of subscript notation are tolerated.
"sub": false,
// If trailing whitespace rules apply.
"trailing": true,
// If strict whitespace rules apply.
"white": false,
// Specify indentation.
"indent": 4
}
68 changes: 26 additions & 42 deletions Jakefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ var util = require('util'),
fs = require('fs'),
childProcess = require('child_process'),
path = require("path"),
hint = require('jshint'),
rexp_minified = new RegExp("\\.min\\.js$"),
rexp_src = new RegExp('\\.js$');

Expand Down Expand Up @@ -98,61 +97,46 @@ task('set-cwd', [], function() {
}
});

// Taken shamelessly from Jakefile from https://github.com/marcenuc/sammy
desc('check sources with JSHint');
task('hint', ['fixtabs'], function () {
var JSHINT = require('jshint').JSHINT;

function checkFile(file, cbDone) {
fs.readFile(file, 'utf8', function (err, src) {
if (err) throw err;

var res = [],
line;

if (!JSHINT(src)) {
res.push("\n" + file);
JSHINT.errors.forEach(function (e) {
if (e) {
if (line !== e.line) {
line = e.line;
res.push(line + ": " + e.evidence);
}
res.push("\t" + e.reason);
}
});
console.log(res.join('\n'));
}

cbDone();
task('hint', ['fixwhitespace'], function () {
var knownWarnings = ["Redefinition of 'FileReader'", "Redefinition of 'require'", "Read only"];
var filterKnownWarnings = function(el, index, array) {
var wut = false;
knownWarnings.forEach(function(e) {
wut = wut && (el.indexOf(e) > -1);
});
}

forEachFile('lib', function (err, file, stats, cbDone) {
if (err) throw err;
return wut;
};

if (rexp_minified.test(file) || !rexp_src.test(file)) {
cbDone();
} else {
checkFile(file, cbDone);
}
}, function() {
checkFile('Jakefile', complete);
childProcess.exec("jshint lib",function(err,stdout,stderr) {
var exs = stdout.split('\n');
console.log(exs.filter(filterKnownWarnings).join('\n'));
complete();
});
}, true);

desc('converts tabs to four spaces - enforcing style guide ftw!');
task('fixtabs', function() {
desc('converts tabs to four spaces, eliminates trailing white space, converts newlines to proper form - enforcing style guide ftw!');
task('fixwhitespace', function() {
forEachFile('lib', function(err, file, stats, cbDone) {
if (err) throw err;
//if (err) throw err;
if (rexp_minified.test(file) || !rexp_src.test(file)) {
cbDone();
} else {
var src = fs.readFileSync(file, 'utf8');

// tabs -> four spaces
if (src.indexOf('\t') >= 0) {
src = src.split('\t').join(' ');
fs.writeFileSync(file, src, 'utf8');
}

// convert carriage return + line feed to just a line feed
src = src.replace(/\r\n/g, '\n');

// eliminate trailing white space
src = src.replace(/ +\n/g, '\n');

// write it out yo
fs.writeFileSync(file, src, 'utf8');
cbDone();
}
}, complete);
Expand Down
97 changes: 40 additions & 57 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ A unified JavaScript layer for [Apache Cordova](http://incubator.apache.org/proj
| |-<platform>/
| | Contains the platform-specific base modules.
| |
| |-<platform>/plugin
| |-<platform>/plugin/<platform>
| | Contains the platform-specific plugin modules.

The way the resulting `cordova.<platform>.js` files will be built is by combining the scripts in the `lib/scripts` directory with modules from the `lib/common` and `lib/<platform>` directories. For cases where there is the same named module in `lib/common` and `lib/<platform>`, the `lib/<platform>` version wins. For instance, every `lib/<platform>` includes an `exec.js`, and there is also a version in `lib/common`, so the `lib/<platform>` version will always be used. In fact, the `lib/common` one will throw errors, so if you build a new platform and forget `exec.js`, the resulting `cordova.<platform>.js` file will also throw errors.
The way the resulting `cordova.<platform>.js` files will be built is by combining the scripts in the `lib/scripts` directory with modules from the `lib/common` and `lib/<platform>` directories. For cases where there is the same named module in `lib/common` and `lib/<platform>/plugin/<platform>`, the `lib/<platform>` version wins. For instance, every `lib/<platform>` includes an `exec.js`, and there is also a version in `lib/common`, so the `lib/<platform>` version will always be used. In fact, the `lib/common` one will throw errors, so if you build a new platform and forget `exec.js`, the resulting `cordova.<platform>.js` file will also throw errors.

# Building

Expand All @@ -65,19 +65,26 @@ Make sure you have [node.js](http://nodejs.org) installed. It should come pre-in

All of the build tasks can be run via the `jake` node module. Install it globally first by running:

npm install -g jake
sudo npm install -g jake

Every build also runs the scripts through [JSHint](). It is best
installed globally:

sudo npm install -g jshint

Then from the repository root run:

jake

This will run the `build` and `test` tasks by default. All of the available tasks are:
This will run the `build`, `hint` and `test` tasks by default. All of the available tasks are:

- `build`: creates platform versions of cordova-js and builds them into
the `pkg/` directory.
- `test`: runs all of the unit tests inside node.
- `btest`: creates a server so you can run the tests inside a browser.
the `pkg/` directory
- `test`: runs all of the unit tests inside node
- `btest`: creates a server so you can run the tests inside a browser
- `clean`: cleans out the `pkg/` directory
- `hint`: runs all of the script files through JSHint
- `fixtabs`: converts all tabs to four spaces within the script files

## Known Issues

Expand Down Expand Up @@ -118,6 +125,9 @@ Build the .js file and drop it in as a replacement for cordova.js.
### Supported Platforms

- Android
- iOS
- BlackBerry
- Windows Phone 7 Mango

## Ripple

Expand All @@ -132,13 +142,14 @@ and then load the upacked extension in chrome in the pkg/chromium folder. Use th

# Adding a New Platform

1. Write a module that encapsulates your platform's `exec` method and
call it <platform>.js. The `exec` method is a JavaScript function
1. Add your platform as a directory under the `lib` folder.
2. Write a module that encapsulates your platform's `exec` method and
call it exec.js. The `exec` method is a JavaScript function
that enables communication from the platform's JavaScript environment
into the platform's native environment. Each platform uses a different
mechanism to enable this bridge. We recommend you check out the other
platform `exec` definitions for inspiration. Drop this into the
`lib/exec` folder. The `exec` method has the following method
`lib/<platform>` folder you created in step 1. The `exec` method has the following method
signature: `function(success, fail, service, action, args)`, with the
following parameters:
- `success`: a success function callback
Expand All @@ -151,11 +162,12 @@ and then load the upacked extension in chrome in the pkg/chromium folder. Use th
by the `exec` call
It is required that new platform additions be as consistent as
possible with the existing `service` and `action` labels.
2. Define your platform definition object and name it <platform>.js. Drop this into the `lib/platform` folder. This file should contain a JSON object with the following properties:
2. Define your platform definition object and name it platform.js. Drop this into the `lib/<platform>` folder. This file should contain a JSON object with the following properties:
- `id`: a string representing the platform. This should be the same
name the .js file has
- `objects`: the property names defined as children of this property
are injected into `window`. Each property can have the following
are injected into `window`, and also *overrides any existing
properties*. Each property can have the following
child properties:
- `path`: a string representing the module ID that will define
this object. For example, the file `lib/plugin/accelerometer.js`
Expand All @@ -164,6 +176,9 @@ and then load the upacked extension in chrome in the pkg/chromium folder. Use th
- `children`: in a recursive fashion, can have `path` and
`children` properties of its own that are defined as children of
the parent property object
- `merges`: similar to the above `objects` property, this one will
not clobber existing objects, instead it will recursively merge
this object into the specific target
- `initialize`: a function that fires immediately after the `objects` (see above) are defined in the global scope

The following is a simple example of a platform definition:
Expand All @@ -187,49 +202,17 @@ and then load the upacked extension in chrome in the pkg/chromium folder. Use th
}
</pre>

3. You should probably add a `packager.bundle('<platform>')` call to the `Jakefile`.
3. You should probably add a `packager.bundle('<platform>')` call to the `Jakefile` under the `build` task.
4. Make sure your native implementation executes the following JavaScript once all of the native side is initialized and ready: `require('cordova/channel').onNativeReady.fire()`.

# Cordova-specific TODOs Before Final Integration

- Add a section about authoring plugins for cordova.
- Related to above, come up with a consistent sensor plugin API.
Functions like `getCurrent<data>` and `watch<data>` can be abstracted
into a nice plugin. Compass, Accel, Geo should all be basically the
same implementation. For example, on Android geo + accel handle
calling `start` (starting the listener) in the native code on its own.
However, Compass requires that JS initiates a `start`. This is dumb.
- Media (and other plugin) implementations across platforms need to use the established
cordova/exec callback method (instead of triggering globally-accessible functions to
dispatch listeners). On iOS, grep for "cast" in the native
code - you'll see a bunch of invoked JavaScript from native, which
shouldn't be there.
- Media needs updates across all platforms. Methods need fixing with
respect to timing: some methods use milliseconds, some use seconds.
Some methods not documented (setVolume on Android). Consolidate /
implement properly across platforms.
- Normalize `Entry.toURL` return values. iOS returns `"file://localhost" +
fullPath`, Android returns `"file://" + fullPath`, BlackBerry returns just `fullPath`
- APIs that are not cross-platform - what
to do with these?
- Crypto on Android
- SMS, telephony, splashscreen on iOS
- Once-over all of the cordova-docs with the APIs defined in here to
make sure all is consistent. There were function signature tweaks,
undocumented procedures, etc.

# TODO / Hacking / Contributing

- implementations:
- BlackBerry: button + app + contact + file + others (need to once-over)
- all of Playbook
- everything for WP7
- everything for Bada
- tests for channel, pretty much everything under lib/plugin
- think about whether to select and load the platform specific modules at
runtime or at buildtime. what about platform-specific overrides? can
we at buildtime decide to include only the overrides (to save a few
kb?). what about specifically denoting modules to include/exclude on a
per-platform basis?
- 3rd party plugins could be interesting. Need a little bit more thought about how these will fit into the system. I am thinking a package.json type file to handle per plugin.

5. The deviceready event is important. To make sure that the stock
common JavaScript fires this event off, the device and network
connection plugins must successfully be instantiated and return
information about the connectivity and device information. The
success callbacks for these plugins should include calls to
`require('cordova/channel').onCordovaInfoReady.fire()` (for device
information) and
`require('cordova/channel').OnCordovaConnectionReady.fire()` (for
network information).
6. Last but certainly not least: add yourself to the contributors list!
It's in the `package.json` file in the root of this repository. You
deserve it!
Loading

0 comments on commit a1f5ee2

Please sign in to comment.