JavaScript Style Guide
1 Code Conventions
The current codebase does not yet follow all of these principles.
- We use jslint. Look for jslint4java-maven-plugin in pom.xml in the repository root to see our jslint configuration.
- We use only the TAB character for indentation.
- We use UpperCamelCase for class names, and lowerCamelCase for method and property names.
- Methods and properties that begin with an underscore (_) are
private
. - We don’t use obfuscated variable names (e.g. with all vowels removed). Understandable abbreviations are OK.
- Don’t use “that” to refer to an outer “this”. Use the name of the class instead (with first char lowercased).
var MyObject = Class.extend({ _constructor: function() { // GOOD var myObject = this; setTimeout(function() { console.log(myObject.name + ' done.'); }; // BAD var that = this; setTimeout(function() { console.log(that.name + ' done.'); }; } });
2 Code Documentation
We use JSDoc
for code documentation. Please see plugins/common/block/ for an example on how to use this.
Further information about rendering documentation can be found in the Documentation Guide.
3 RequireJS module skeleton
All files which are RequireJS modules (scripts in package/lib) should follow this structure.
/*! * Aloha Editor * Author & Copyright (c) 2011 Gentics Software GmbH * aloha-sales@gentics.com * Licensed unter the terms of http://www.aloha-editor.com/license.html */ define([ 'dependency' ], function( Dependency ) { 'use strict'; // Declare exports return exports; });
4 Classes and Extension Mechanisms
We use the class definition syntax of John Resig – slightly adjusted. This means you can create a new class with Class.extend({ ....}).
The following example shows how to create and instanciate a class, and how the constructor (which must be named _construct()) is called.
var Greeter = Class.extend({ name: null, _constructor: function(name) { this.name = name; }, greet: function() { alert('Good Morning ' + this.name); } }); var greeterInstance = new Greeter('Christopher'); greeterInstance.greet(); // alerts "Good Morning Chistopher"
Now, if we want to subclass Greeter
, this is very easy: Just use Greeter.extend
for that:
var GreeterForMen = Greeter.extend({ _constructor: function(name) { this._super('Mr. ' + name); } }); var greeterInstance = new GreeterForMen('Christopher'); greeterInstance.greet(); // alerts "Good Morning Mr. Chistopher"
You can use this._super() to call the superclass constructor.
5 Singletons
All singletons should follow this structure:
/*! * Aloha Editor * Author & Copyright (c) 2011 Gentics Software GmbH * aloha-sales@gentics.com * Licensed unter the terms of http://www.aloha-editor.com/license.html */ define([], function() { "use strict"; var component = Class.extend({ // Class definition here }); return new component(); });
It will define a class and return a new instance that will be exported. Singletons are useful for global objects that have state.
6 RequireJS Dependency Order
The order of a module’s dependencies listed in the call to define([…], function(…) should be in the following order:
- The base class, if the module exports a subclass
- Other Classes, if the module instantiates or uses other classes
- i18n – plugin specific internationalization if applicable
- i18nCore – core specific internationalization if applicable
- vendor – third party modules and libraries
- css – css files if applicable
7 Public API, Private methods and attributes
All methods and properties which are public API are marked with @api. The public API is supported for a longer period by the Aloha Core Team, and when a public API changes, this is clearly communicated in the Release Notes of a version.
If you use methods that are not marked with @api@ you are on your own.
8 Initialization Methods
Initialization methods should be named init().
Good:
- init()
- initSidebar()
Bad:
initialize()
initializeSidebar()
start()
run()
8.1 Shutdown methods
Shutdown methods should be named destroy().
Good:
- destroy()
Bad:
shutdown()
stop()