# Projects Coding & Testing Guidelines This guide covers the coding guidelines common to all xjs hosted projects. ## End User Requirements * All widget/custom elements MUST be enabled for globalization (including translatability & bidi support) * All widget/custom elements MUST be enabled for accessibility: * keyboard support * zoom (full zoom, not text only zoom, up to 200%) * screen reader accessibility (supported readers are JAWS on Windows and VoiceOver on iOS) * must support high contrast (IE and FF on Windows, with high contrast mode enabled in the OS settings); device specific themes (currently iOS and holodark) are exempt from this rule * The projects will only support modern browser/platforms: FF31+, Chrome latest, IE9/10+, Safari 7+, Android 4.1+, iOS6+, WindowsPhone8+ See https://docs.google.com/document/d/1Sa0rn4udqO_ea20o4xxogRP6P6ZLgHPMEj4A2V4g7hM for more details. ## Javascript Coding Guidelines Our components are written in Javascript rather than a derivative like Typescript or CoffeeScript. ### JSHint All projects MUST comply with the directives in this [jshintrc](.jshintrc) and MUST enforce it through a [TravisCI](https://travis-ci.org/) check. JSHint max complexity is set to 10 by default but CAN be temporarily put up to 15 for a given method if the committer feels this is not hurting the code readability. ### AMD For projects to be used in the browser (as opposed to Node.js specific projects), modules are wrapped in [AMD](http://requirejs.org/docs/whyamd.html#amd) rather than CommonJS or UMD format. Rationale: this is mainly for the benefit of the build tool. [RequireJS](http://requirejs.org/) is our main AMD loader. Plugins and builds are tailored for RequireJS. We standardize on using the following plugins: * [requirejs-domReady!](https://github.com/requirejs/domReady) - to detect when the DOM has finished loading * [requirejs-text!](https://github.com/requirejs/text) - to load non JS files (ex: HTML) * [requirejs-dplugins/i18n!](https://github.com/ibm-js/requirejs-dplugins/blob/master/i18n.js) - for loading message files (translated into different languages). * [requirejs-dplugins/has!](https://github.com/ibm-js/requirejs-dplugins/blob/master/has.js) - Feature and browser sniffing is done via `has.add()` and `has()`, so that a build can strip unneeded code. ### API documentation Public methods and properties should use JSDoc format, as detailed in https://docs.google.com/document/d/1fGBLuDAJRHFuSE4_NM2YfbRcCeYV40KWDXCuVyiSV_U/edit#heading=h.mrkbtrfyd36f ### Other JavaScript Coding Guidelines * Getters/Setters MUST use ES5 getter/setter and not getProp/setProp methods. * Calling mycomponent.myproperty = value for ES5-like setters SHOULD refresh the component either directly or using a simple delayed refresh mechanism provided by decor/Invalidating. If that is not the case it must be clearly documented * Variables SHOULD be declared as close to the point where they are first used as it helps to cluster groups of code together instead of spreading them throughout a function. Variables that are assigned in multiple places of a function (e.g. loop counters) CAN be declared at the beginning of the function. * In order to associate an object to be used as `this` when calling a function: * If the called function is public _and_ documented the code MUST use a closure construct with a `self` variable to preserve AOP: ```js var self = this; this.on("DOMNodeInserted", function(){ self.publicmethod(); }); ``` * If the called function is either private _or_ not documented the core MUST use Function.prototype.bind(): ```js this.on("DOMNodeInserted", this._privatemethod.bind(this)); ``` * By default, code SHOULD NOT check properties or parameters for validity, if there's a particular case where it's especially helpful to the user to check, then code SHOULD: * throw an exception rather than using console.log() or console.error() * add comment to the code about why you throwing the exception * Widget Template MUST have a top level tag of type ```