Firebug Coding Style
From FirebugWiki
Sebastianz (Talk | contribs) (Added more line wrapping information) |
Sebastianz (Talk | contribs) (Added file encoding and line feed character) |
||
| (14 intermediate revisions not shown) | |||
| Line 1: | Line 1: | ||
This document attempts to explain the basic styles and patterns, that are used in the Firebug codebase. New code should try to conform to these standards, so that it is as easy to maintain as existing code. Of course every rule has an exception, but it's important to know the rules nonetheless! | This document attempts to explain the basic styles and patterns, that are used in the Firebug codebase. New code should try to conform to these standards, so that it is as easy to maintain as existing code. Of course every rule has an exception, but it's important to know the rules nonetheless! | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
== Formatting Code == | == Formatting Code == | ||
| + | === File Encoding === | ||
| + | All source files should be encoded in UTF-8 without [http://en.wikipedia.org/wiki/Byte_order_mark BOM]. | ||
=== Whitespace === | === Whitespace === | ||
| - | No tabs. No whitespace at the end of a line. | + | No tabs. No whitespace at the end of a line. But, every line should end with a line feed character (<code>\n</code>, Unicode: <code>0x0A</code>), also the last line of a file. |
| - | Operators are surrounded by spaces as well as parameters in a function call. | + | Operators are surrounded by spaces as well as parameters in a function call, except the string concatinator. |
<source lang="javascript"> | <source lang="javascript"> | ||
| - | var text = "Message: " + msgID + ": " + msgText; | + | var text = "Message: "+msgID+": "+msgText; |
var result = result ? "positive" : "negative"; | var result = result ? "positive" : "negative"; | ||
var target = event.target || document.getElementsByTagName("body")[0]; | var target = event.target || document.getElementsByTagName("body")[0]; | ||
var expression = getExpressionAt(rangeParent.data, rangeOffset); | var expression = getExpressionAt(rangeParent.data, rangeOffset); | ||
</source> | </source> | ||
| + | |||
| + | The incrementation and decrementation operators are not separated by spaces. So e.g. you should write <code>while(i-- > 0)</code> instead of <code>while(i --> 0)</code> to avoid misinterpretations. | ||
| + | |||
| + | === Source File Size === | ||
| + | A source file should avoid huge amount of code lines. Couple thousands of lines in a file is already a lot. Firebug is using [http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition AMD syntax] and more smaller files (modules) is preferred. | ||
=== Line Length === | === Line Length === | ||
| Line 36: | Line 37: | ||
var string = ... + | var string = ... + | ||
...; | ...; | ||
| + | </source> | ||
| + | |||
| + | Also member operators stay at the end of the line. | ||
| + | |||
| + | <source lang="javascript"> | ||
| + | var service = Cc[...]. | ||
| + | getService(...); | ||
</source> | </source> | ||
=== Indentation === | === Indentation === | ||
Four spaces per logic level. | Four spaces per logic level. | ||
| + | |||
| + | === Commands === | ||
| + | Every command must end with a semicolon. | ||
| + | |||
| + | Variable definitions should be done separately, not comma-separated. | ||
| + | |||
| + | <source lang="javascript"> | ||
| + | var foo = 1; | ||
| + | var bar = 2; | ||
| + | |||
| + | foo = someFunction(); | ||
| + | </source> | ||
=== Licence === | === Licence === | ||
| Line 73: | Line 93: | ||
</source> | </source> | ||
| - | Yes, there can be exceptions and K&R style can be preferred in some cases. For example, definition of a config object. | + | Yes, there can be exceptions and [http://en.wikipedia.org/wiki/The_C_Programming_Language_%28book%29 K&R] style can be preferred in some cases. For example, definition of a config object. |
<source lang="javascript"> | <source lang="javascript"> | ||
| Line 125: | Line 145: | ||
{ | { | ||
case 1: | case 1: | ||
| - | + | ... | |
| - | + | break; | |
| + | |||
| + | case 2: | ||
| + | ... | ||
| + | break; | ||
| + | |||
| + | default: | ||
| + | ... | ||
} | } | ||
</source> | </source> | ||
| + | |||
| + | To avoid misunderstandings ''for'' loops are always written in their long form, i.e. loop heads like <code>for (var i = count; i--; )</code> should be avoided in favor of <code>for (var i = count-1; i>=0; i--)</code> | ||
<source lang="javascript"> | <source lang="javascript"> | ||
| Line 178: | Line 207: | ||
dump(2); | dump(2); | ||
} | } | ||
| + | </source> | ||
| + | |||
| + | === Comments === | ||
| + | Multi-line as well as single line comments should always be put into their own line. | ||
| + | So you should write: | ||
| + | <source lang="javascript"> | ||
| + | // This is a comment | ||
| + | var abc = xyz; | ||
</source> | </source> | ||
| Line 195: | Line 232: | ||
== Naming == | == Naming == | ||
| + | |||
| + | American English is used for all labels and comments. That means, that you should write e.g. <code>synchronize</code> instead of <code>synchronise</code> or <code>color</code> instead of <code>colour</code>. | ||
=== Functions and Methods === | === Functions and Methods === | ||
| Line 343: | Line 382: | ||
The code should also have [[Firebug Source Code Comments|comments]]. | The code should also have [[Firebug Source Code Comments|comments]]. | ||
| - | == Example Module File | + | == Example Module File == |
| - | Example of a typical asynchronous module definition. Every file in Firebug source base should use the AMD pattern starting from Firebug 1.8. | + | Example of a typical [http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition asynchronous module definition (AMD)]. Every file in Firebug source base should use the AMD pattern starting from Firebug 1.8. |
<source lang="javascript"> | <source lang="javascript"> | ||
| Line 393: | Line 432: | ||
The code should also have [[Firebug Source Code Comments|comments]]. | The code should also have [[Firebug Source Code Comments|comments]]. | ||
| + | |||
| + | == Resources == | ||
| + | * [https://github.com/fflorent/firebug_vimrc/ vimrc file] supporting Firebug coding style. | ||
| + | |||
| + | == See also == | ||
| + | * [[Firebug Modules]] | ||
| + | * [[Firebug Source Code Comments]] | ||
| + | * [https://developer.mozilla.org/en/JavaScript_Tips Mozilla JavaScript Tips] | ||
| + | * [https://developer.mozilla.org/en/Developer_Guide/Coding_Style Mozilla Coding Style] | ||
Revision as of 09:05, 22 October 2012
This document attempts to explain the basic styles and patterns, that are used in the Firebug codebase. New code should try to conform to these standards, so that it is as easy to maintain as existing code. Of course every rule has an exception, but it's important to know the rules nonetheless!
Contents |
Formatting Code
File Encoding
All source files should be encoded in UTF-8 without BOM.
Whitespace
No tabs. No whitespace at the end of a line. But, every line should end with a line feed character (\n, Unicode: 0x0A), also the last line of a file.
Operators are surrounded by spaces as well as parameters in a function call, except the string concatinator.
var text = "Message: "+msgID+": "+msgText; var result = result ? "positive" : "negative"; var target = event.target || document.getElementsByTagName("body")[0]; var expression = getExpressionAt(rangeParent.data, rangeOffset);
The incrementation and decrementation operators are not separated by spaces. So e.g. you should write while(i-- > 0) instead of while(i --> 0) to avoid misinterpretations.
Source File Size
A source file should avoid huge amount of code lines. Couple thousands of lines in a file is already a lot. Firebug is using AMD syntax and more smaller files (modules) is preferred.
Line Length
100 characters or less. There is no exception in *.js files! In some cases this rule can be broken in *.html or *.xul files. But keep in mind long lines are hard to read (also search results are hard to read).
When wrapping lines, operators stay at the end of a line.
if ((... && ...) || ...) { }
var string = ... + ...;
Also member operators stay at the end of the line.
var service = Cc[...]. getService(...);
Indentation
Four spaces per logic level.
Commands
Every command must end with a semicolon.
Variable definitions should be done separately, not comma-separated.
var foo = 1; var bar = 2; foo = someFunction();
Licence
Files should include a license note at the first line of the file:
/* See license.txt for terms of usage */
...In case of *.xml files (e.g. in overlays), this must be after XML declaration, for example:
<?xml version="1.0"?> <!-- See license.txt for terms of usage --> ... </xml>
In case of *.properties or *.manifest files, this must be commented using # character.
# See license.txt for terms of usage
...Control Structures
Existing Firebug codebase uses braces on the next line like as follows:
function foo() { // ... }
Yes, there can be exceptions and K&R style can be preferred in some cases. For example, definition of a config object.
var foo = { prop1: "value1" }; var bar = { prop1: "value1", prop2: "value2", };
Anyway, class and function definitions should always have the braces on the next line as follows:
Firebug.MyModule = extend(Firebug.Module, { initializeUI: function() { }, });
function myFunction() { // .... }
Control structures should look like as follows (also notice the spacing between a keyword and the left bracket):
if (...) { } else if (...) { }
Another example showing how to deal with spaces:
if ((a > 0) && (b > 0)) { }
switch (...) { case 1: ... break; case 2: ... break; default: ... }
To avoid misunderstandings for loops are always written in their long form, i.e. loop heads like for (var i = count; i--; ) should be avoided in favor of for (var i = count-1; i>=0; i--)
for (var i=0; i<10; i++) { }
try { } catch (err) { }
Firebug prefers no braces, if they are not necessary.
if (...) dump(true); else dump(false);
But if one of the branches needs braces use them for all. Also note
if (...) { dump("0"); dump("1"); } else { dump(2); }
If the head of a control structure is wrapped into several lines because it is longer than the maximum line length, also use braces, even when the block just contains one line.
if (... ...) { dump("0"); } else { dump(2); }
Comments
Multi-line as well as single line comments should always be put into their own line. So you should write:
// This is a comment var abc = xyz;
Horizontal Lines
Sometimes it is helpful to divide portions of a file by a horizontal line. For this you should use following comment (100 characters long):
// ********************************************************************************************* //Firebug codebase also uses the following horizontal separator for dividing members of one object (this separator uses indentation (4 spaces) since it's used within an object scope that is indented (100 characters long).
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //Naming
American English is used for all labels and comments. That means, that you should write e.g. synchronize instead of synchronise or color instead of colour.
Functions and Methods
Functions should use camelCase but should not capitalize the first letter.
function foo() { }
function myFoo() { }
Objects
Constructors for objects should be capitalized and use CamelCase.
function ObjectConstructor() { }
Firebug.MyModule = extend(Firebug.Module, { });
MyObject.prototype = () { myMethod: function() { } };
Constants
Constants should be capitalized as follows:
var MY_CONSTANT = true;
Use var instead of const, since the code can also be used in the browser environment where const is not supported.
Variables
Variables should use camelCase and not capitalize the first letter.
var thisIsMyVariable = true;
Prefixes
Firebug codebase doesn't use any prefixes for member fields.
Good Practices
Vertical Indentation
Method defintions should be separated by a new line. Note the new line between initialize and shutdown methods.
Firebug.MyModule = extend(Firebug.Module, { initialize: function() { }, shutdown: function() { } });
Also portions of code logically belonging together should be separated by a new line from other code. Note the new line between super.initialize and this.onMutateText.
initialize: function() { super.initialize.apply(this, arguments); this.onMutateText = bind(this.onMutateText, this); this.onMutateAttr = bind(this.onMutateAttr, this); this.onMutateNode = bind(this.onMutateNode, this); }
Horizontal lines should be surrounded by new lines too
function myFunc1() { } // ********************************************************************************************* // function myFunc2() { }
Example File
Example of a typical Firebug file implementing a module object. Firebug namespaces (FBL.ns) are no longer the preferred way for Firebug files. See AMD below.
/* See license.txt for terms of usage */ FBL.ns(function() { // ********************************************************************************************* // // Constants var MY_CONSTANT = true; // ********************************************************************************************* // // Module Implementation Firebug.MyModule = extend(Firebug.Module, { // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Initialization initializeUI: function() { }, // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Toolbar Actions myButtonHandler: function() { } }); // ********************************************************************************************* // // Registration Firebug.registerModule(Firebug.StartButton); // ********************************************************************************************* // });
The code should also have comments.
Example Module File
Example of a typical asynchronous module definition (AMD). Every file in Firebug source base should use the AMD pattern starting from Firebug 1.8.
/* See license.txt for terms of usage */ define([ "firebug/lib", "firebug/firebug", "firebug/domplate" ], function(FBL, Firebug, Domplate) { // ********************************************************************************************* // // Constants var MY_CONSTANT = true; // ********************************************************************************************* // // Module Implementation Firebug.MyModule = extend(Firebug.Module, { // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Initialization initializeUI: function() { }, // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Toolbar Actions myButtonHandler: function() { } }); // ********************************************************************************************* // // Registration Firebug.registerModule(Firebug.MyModule); return Firebug.MyModule; // ********************************************************************************************* // });
The code should also have comments.
Resources
- vimrc file supporting Firebug coding style.