Developer's Guide
=================
:toc: left
:icons: font

////

    This file is part of the SOGo project.

    See docinfo.xml for authors, copyright and license information.

////

include::includes/global-attributes.asciidoc[]

UI and UX
---------

* https://material.io/design/

Frameworks & Tools
------------------

GNUstep
~~~~~~~

SOPE
~~~~

JavaScript libraries
~~~~~~~~~~~~~~~~~~~~

* https://angularjs.org/
* https://material.angularjs.org/
* http://angular-ui.github.io/ui-router/
* http://lodash.com/
* https://github.com/nervgh/angular-file-upload
* https://github.com/a5hik/ng-sortable

Code Style
----------

Objective-C
~~~~~~~~~~~

* To document the Web APIs, we follow the http://apidocjs.com/[APIDOC] standards.

    apidoc -f ".*\\.m" -i UI -o Documentation/JSON-API

* When returning JSON from an object extending UIxComponent, use the following method:

    - (WOResponse *) responseWithStatus: (unsigned int) status
                  andJSONRepresentation: (NSObject *) contentObject;

HTML
~~~~

* Localize your strings:

    <var:string label:value="I'm localized!"/>

* Localize your attributes:

    <input type="text" label:placeholder="I'm localized!"/>

* Reuse existing localized strings as much as possible. Otherwise don't forget to update the English Localizable.strings file of the appropriate module.

JavaScript
~~~~~~~~~~

* http://eslint.org/
* http://standardjs.com
* https://github.com/toddmotto/angularjs-styleguide
* https://github.com/angular/material/blob/master/docs/guides/CODING.md
* http://jshint.com/
* https://github.com/angular/material/tree/master/docs/guides

* We conform to https://github.com/airbnb/javascript[Airbnb coding standards]. Use https://github.com/jscs-dev/node-jscs[jscs] with the 'airbnb' preset to validate your code style:

    jscs -p airbnb *.js

* For documentation, we follow the http://usejsdoc.org/[JSDoc3] standards:

    jsdoc UI/WebServerResources/js/{Common,Contacts,Mailer,Preferences,Scheduler}/*.js -d Documentation/JavaScript-API

Models (facades)
^^^^^^^^^^^^^^^^

////
http://trochette.github.io/Angular-Design-Patterns-Best-Practices/
////
* Move business logic into models and share them.
* Keep it simple, separate server interaction and error handling from the model. That way model only handle data processing and code is easier to maintain.

Controllers
^^^^^^^^^^^

* Functions not exposed in the controller must be prefixed with an underscore.

SASS/CSS
~~~~~~~~

* http://componentcss.com/
* https://github.com/styleguide/css
* https://smacss.com/
* http://cssguidelin.es/
* http://sixrevisions.com/css/css-methodologies/
* https://css-tricks.com/what-a-css-code-review-might-look-like/
* http://una.im/classy-css/
* http://stylelint.io/

A `@mixin` is like a stamp: it creates a duplicated version of the property block (optionally) with arguments provided. An `@extend` appends the element you are extending to the property block. It is your "yes, and ___" statement.

* For documentation, we follow http://sassdoc.com/[SassDoc] annotations.
* FlexBox compatibility http://caniuse.com/#feat=flexbox

Fonts
^^^^^

* http://mozilla.github.io/Fira/[Mozilla Fira]
* https://material.io/tools/icons/[Material icons]

Building frontend
-----------------

* Install the latest stable release of https://nodejs.org[Node.js]
* Install grunt

    npm install -g grunt-cli
    npm install -g bower

* We need the SASS files of Angular Material to build our CSS. The git repository of Angular Material is included as a submodule of SOGo:

    git submodule init
    git submodule update

* Generate the JavaScript and CSS files

    cd UI/WebServerResources
    npm install
    bower install
    grunt build

Defining an alternate color theme
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

SOGo relies on the https://material.angularjs.org/latest/Theming/01_introduction[theming system of Angular Material] to define the colors of the Web interface.

To overwrite the default theme in SOGo, set the following parameter in `/etc/sogo/sogo.conf`:

    SOGoUIAdditionalJSFiles = (js/theme.js);

Edit `theme.js` under `/usr/lib64/GNUstep/SOGo/WebServerResources/js` or `/usr/lib/GNUstep/SOGo/WebServerResources/js` depending on your platform and restart sogod.

If the configuration parameter `SOGoUIxDebugEnabled` is unset or set to `NO` in `/etc/sogo/sogo.conf`, you'll need to generate a new `theme-default.css` stylesheet for the new theme.

. Temporarily set `SOGoUIxDebugEnabled` to `YES`;
. Restart sogod;
. From your favorite browser, open the JavaScript console and type the following:

    copy([].slice.call(document.styleSheets)
      .map(e => e.ownerNode)
      .filter(e => e.hasAttribute('md-theme-style'))
      .map(e => e.textContent)
      .join('\n')
    )

. Overwrite the content of `WebServerResources/css/theme-default.css` with the content of the clipboard;
. Restore the value of `SOGoUIxDebugEnabled` (`NO` or unset);
. Restart sogod.

Version Control
---------------

* https://devcharm.com/articles/46/improve-your-git-workflow/
* https://github.com/angular/material/blob/master/docs/guides/CONTRIBUTING.md#-commit-message-format
* Each commit should cover only one thing;
* Begin the commit message with a single short (less than 50 characters) line summarizing the change, followed by a blank line and then a more thorough description;
* When fixing a bug, commit to the devel branch as well as the maintenance branch of the latest release version (named maintenance/x.y). When a ticket is associated to the bug, add to the description a line saying *Fixes #1234*.
* `git pull` may introduce http://stackoverflow.com/questions/15316601/in-what-cases-could-git-pull-be-harmful[inconsistencies and problems]. Replace it with the following alias:

    git config --global alias.up '!git remote update -p; git merge --ff-only @{u}'

Testing
-------

* https://github.com/angular/protractor
* http://karma-runner.github.io/

JSON API
~~~~~~~~

One practical way to test the JSON API is to use `curl`. To do so, you need to enable `SOGoTrustProxyAuthentication` and configure HTTP authentifcation in Apache. You can pipe the result to http://stedolan.github.io/jq/[jq] to nicely format and filter the output:

    curl -u username:password http://localhost/SOGo/so/username/Calendar/calendarslist | jq '.'

    curl -u username:password -H 'Content-Type: application/json' -d '{}' http://localhost/SOGo/so/francis/Calendar/personal/71B6-54904400-1-7C308500.ics/save