Voilà, voilà... Fin de l'aventure...

 

Fermeture de kolossaldrupal.org dans...


Bonjour tout le monde,

Drupal évolue, les versions changent et Kolossaldrupal.org était essentiellement consacré à la version 6 de Drupal.

Autant dire que les infos présentées ici commencent à dater...

Faute de temps, je ne peux plus garder le site Kolossaldrupal à jour...

Je vous aurais bien proposé de reprendre le flambeau mais... c'est tellement simple de nos jours de se faire son propre site à soi...Pourquoi s'embêter alors ? :-)

Ce site restera donc en l'état, tel qu'il était en 2011...

Ah la la ! Cela ne nous rajeunit pas !

Manuel Vila - Avril 2016

Normes de programmation JavaScript

Référence sur drupal.org : 26 Avril 2009 – 23h50 - http://drupal.org/node/172169


Indentation

Utilisez une indentation de 2 espaces, pas de tabulations. Pas d’espace après le dernier mot de la ligne.

Concaténation de chaînes

Utilisez toujours une espace entre le signe + et les chaînes à concaténer :

var string = 'Foo' + bar;
string = bar + 'foo';
string = bar() + 'foo';
string = 'foo' + 'bar';

Quand vous utilisez l’opérateur de concaténation +=, utilisez une espace de part et d’autre, comme pour le signe égal :

var string += 'Foo';
string += bar;
string += baz();

CamelCasing

A l’inverse des variables et fonctions déclarées dans le PHP Drupal, les noms de variables ou de fonctions JavaScript comportant plusieurs mots doivent être lowerCamelCased. La première lettre de chaque variable ou fonction doit être en minuscule, tandis que la première lettre de chaque mot doit être en capitale. Il ne devraient pas y avoir de signe souligné entre les mots.

Points-virgules

JavaScript autorise l’utilisation de toute expression comme instruction et utilise le point-virgule pour signaler la fin d’une instruction. 

Cependant, cela devient facultatif avec les « semi-colon insertion » 

(ajout, par JavaScript, d’un point-virgule entre deux instructions se trouvant sur deux lignes à la suite, exemple :

a = 1
b = 2

devient

a =1;
b= 2;
)

mais cela peut masquer des erreurs et causer un échec de l’aggrégation du code.

Toutes les instruction doivent être suivies d’un ; à l’exception des suivantes :

for, function, if, switch, try, while

Ces exceptions sont les fonctions déclarées comme

  Drupal.behaviors.tableSelect = function (context) {
    // Statements...
  };

et

  do {
    // Statements...
  } while (condition);

Elles doivent toujours être suivies d’un point-virgule.

De plus, le valeur de l’expression return doit débuter sur la même ligne que le mot-clé return, pour éviter l’ajout du point-virgule.

Si l’option de performance Drupal 6 « Optimiser les fichiers JavaScript » est activé et s’il manque des points-virgule, alors l’aggrégation JS échouera. Il est donc très important que les points-virgules soient utilisés.

Structures de contrôle

Cela concerne if, for, while, switch, etc. Voici un exemple de déclaration IF, puisque c’est une des plus complexe :

if (condition1 || condition2) {
  action1();
}
elseif (condition3 && condition4) {
 action2();
}
else {
  defaultAction();
}

Les déclaration de structures de contrôle doivent avoir une espace entre le mot-clé et la parenthèse ouvrante, afin de les distinguer des appels de fonctions.

Vous êtes fortement encouragés à toujours utiliser les accolades, même dans les cas où elles seraient techniquement facultatives. Ceci accroît la lisibilité et réduit les risques d’erreurs de logique qui peuvent apparaître avec l’ajout de nouvelles lignes.

switch

Pour les déclarations switch :

switch (condition) {
  case 1:
    action1();
    break;

  case 2:
    action2();
    break;

  default:
    defaultAction();
}

Try

Les instructions try doivent avoir la forme suivante :

  try {
    // Statements...
  }
  catch (variable) {
    // Error handling...
  }
  finally {
    // Statements...
  }

for in

L’instruction for in permet de parcourir toutes les propriétés d’un objet. Malheureusement, tous les membres qui auront été hérités via la chaîne prototype seront également inclus dans la boucle. 

Pour éviter cela, le corps de chaque instruction for in doit être encadrée par une instruction IF agissant comme filtre. Elle peut sélectionner un type ou une série de valeurs particuliers, ou elle peut exclure des fonctions, ou elle peut exclure des propriétés du prototype. Par exemple :

for (var variable in object) if (filter) {
  // Statements...
}

Vous pouvez utiliser la méthode hasOwnProperty pour différencier les vrais membres de l’objet :

for (var variable in object) if (object.hasOwnProperty(variable)) {
  // Statements...
}

Fonctions

Fonctions et méthodes

Les méthodes et fonctions doivent être nommées en utilisant lowerCamelCase :

Drupal.behaviors.tableDrag = function (context) {
  for (var base in Drupal.settings.tableDrag) {
    if (!$('#' + base + '.tabledrag-processed', context).size()) {
      $('#' + base).filter(':not(.tabledrag-processed)').each(addBehavior);
      $('#' + base).addClass('tabledrag-processed');
    }
  }
};

Appels de fonctions

Les fonctions doivent être appelées sans espace entre le nom de la fonction, la parenthèse ouvrante, et le premier paramètre; espaces entre les virgules et chaque paramètre, la parenthèse fermante, le point-virgule. Voici un exemple :

foobar = foo(bar, baz, quux);

Comme affiché ci-dessus, il devrait y avoir une espace de part et d’autre du signe égal utilisé pour affecter la valeur de retour de la fonction à la variable. Dans le cas de blocs comportant plusieurs affectations, plus d’espaces peuvent être insérées afin d’accroître la lisbilité :

short        = foo(bar);
longVariable = foo(baz);

Si une fonction littérale est anonyme, il doit y avoir une espace entre le mot function et la parenthèse gauche. Si l’espace est omis, il se pourrait que l’on prenne le mot « function » comme nom de fonction.

div.onclick = function (e) {
  return false;
};

Déclaration de fonctions

function funStuff(field) {
  alert("Ce script JS affiche des messages popup rigolos.");
  return field;
}

Les arguments ayant des valeurs par défaut se trouvent en dernières positions de la liste d’arguments. Tentez toujours de retourner une valeur d’une fonction s’il en existe d’adéquate.

Prenez en compte la notion de fonction anonyme décrite ci-dessus.

Variables et tableaux

Toutes les variables doivent être déclarée avec le mot var avant d’être utilisées et ne doivent être déclarées qu’une seule fois. Cela facilite la lecture du programme et la détection de variables non déclarées qui peuvent devenir implicitement globales.

La portée des  variables ne devrait pas être globale; essayez de leur donner une portée locale en les déclarant à tout prix dans une fonction. Toutes les variables doivent être déclarées au début des fonctions.

Constantes et variables globales

lowerCamelCasing doit être utilisé pour les constantes pré-définies. A l’inverse des normes pour le PHP, vous devez utilisez true, false et null puisque les majuscules ne sont pas valides en JavaScript.

Les variables ajoutées via drupal_add_js() doivent aussi être lowerCamelCased, pour être en conformité avec les autres variables une fois qu'elles seront utilisées dans le JavaScript.

<?php
drupal_add_js
(array('myModule' => array('basePath' => base_path())), 'setting');
?>

Cette variable sera référencée :

Drupal.settings.myModule.basePath;

Tableaux

Les tableaux devraient être formatés avec une espace séparant chaque élément et opérateur d’affectation, si le tableau le permet :

someArray = ['hello', 'world'];

Notez que si la ligne dépasse 80 caractères (ce qui est souvent le cas pour la déclaration  d’un formulaire ou d’un menu) chaque élément devra être disposé dans sa propre ligne, et indenter d’un niveau :

Notez qu’il n’y a pas de virgule après le dernier élément du tableau. C’est une différence avec les normes PHP. En JavaScript, mettre une virgule après le dernier élément du tableau causera une exception.

Commentaires

La documentation au sein du code-source devrait respecter les normes de formatage Doxygen.

Les commentaires divers sont fortement encouragés. Une règle générale dit que si vous regardez une portion de code et vous exclamez « La vache ! Je ne veux pas essayer d’expliquer ça ! », alors vous devez commenter le code avant d’oublier comment il marche. Les commentaires peuvent être enlevés ultérieurement par les utilitaires JS, ils n’impactent donc pas la taille du fichier téléchargé.

Les commentaires divers devraient utiliser des phrases avec des majuscules et ponctuées. Les lettres ne doivent être en capitales que pour désigner les constantes, par exemple : TRUE. Les commentaires devraient être sur une ligne à part juste avant la ligne de code ou le bloc de code qu’ils désignent. Par exemple :

// Unselect all other checkboxes.

Si chaque ligne d’une liste a besoin d’un commentaire, ils peuvent être placés sur la même ligne et indentés de façon uniforme pour une meilleure lisibilité.

Les commentaires comme en C /* */ et en C++ // sont valables. L’utilisation de commentaires à la façon Perl/shell # sont déconseillés.

Blocs de commentaires en en-tête

Tout code-source de Drupal doit contenir le commentaire suivant placé en début de fichier :

// $Id$

Cette balise sera complétée par le CVS avec les données utiles :

// $Id: CODING_STANDARDS.html,v 1.14 2008/02/19 03:36:41 ax Exp $

Emplacement du code JavaScript

Autant que faire se peut, le code JavaScript ne devrait pas être liée au HTML car cela  accroît significativement le poids d’une page sans offrir de possibilité de réduction par la mise en cache ou la compression.

Instruction with

L’instruction with est destinée à fournir un moyen d’accès rapide aux membres d’objets profondément imbriqués. Par exemple, il est possible (mais déconseillé) d’utiliser l’accès ci-dessous pour foo.bar.foobar.abc etc :

with (foo.bar.foobar) {
  var abc = true;
  var xyz = true;
}

Cependant, en regardant ce code, il est impossible de savoir lequel d’entre abc et xyz sera modifié. foo.bar.abc sera-t-il modifié ? Ou les variables globales abc et xyz ?

Vous devriez plutôt utiliser la version longue :

foo.bar.foobar.abc = true;
foo.bar.foobar.xyz = true;

ou si vous voulez réellement utiliser un raccourci, utilisez cette méthode :

  var o = foo.bar.foobar;
  o.abc = true;
  o.xyz = true;

Opérateurs

Comparaisons logiques

Les opérateurs == et != effectuent une conversion de type implicite avant d’effectuer la comparaison. Ce qui est une mauvaise chose puisque ' \t\r\n' == 0 sera vrai. Cela peut occulter des erreurs de types. Pour les comparaisons avec l’une des valeurs suivantes, utilisez les opérateurs === ou !== , qui ne provoquent pas de contraintes de type : <?php0 '' undefined null false true?>

Opérateur virgule

L’utilisation de l’opérateur virgule, qui entraîne l’exécution des expressions qui se trouvent à sa gauche et à sa droite, dans le sens gauche-droite et renvoie la valeur de l’expression située à sa droite, doit être évité. Un exemple d’utilisation est :

var x = (y = 3, z = 9);

Cette instruction initialise x à 9. Cette opération est déroutante pour les utilisateurs qui ne sont pas familiarisés avec cette syntaxe et rend plus difficiles la lecture et la compréhension du code-source. En conséquence, évitez l’utilisation de l’opérateur virgule, sauf dans la partie contrôle d’une instruction FOR.

Ceci ne s’applique pas au séparateur virgule utilisé dans les objets, tableaux, etc.

Éviter le code inaccessible

Pour éviter le code inaccessible, une instruction return, break, continue ou throw doit être suivie d’une } ou d'un case ou d'un default.

Constructeurs

Les constructeurs sont des fonctions conçues pour être utilisées avec le préfixe new. Ce préfixe crée un nouvel objet basé sur le prototype d’une fonction et lie cet objet aux fonctions par l’opérateur this. JavaScript n’émet pas d’avertissements si un new requis est omis. Si vous négligez le new, aucun nouvel objet ne sera créé et this sera lié à l’objet global (pas glop). 

Les constructeurs doivent être nommés avec une initiale en majuscule et une fonction dont l’initiale du nom est en majuscule ne devrait pas être appelée à moins qu’elle n’ait le préfixe new.

Utilisez des expressions littérales

Utilisez des expressions littérales à la place de l’opérateur new :

  • à la place de new Array(), utilisez []
  • à la place de new Object(), utilisez {}
  • n’utilisez pas les « wrappers » new Number, new String, new Boolean.

Dans la plupart des cas, la forme « wrapper » sera la même que l’expression littérale. Ce n’est cependant pas toujours le cas, voir l’exemple suivant :

var literalNum = 0;
var objectNum = new Number(0);
if (literalNum) { } // false because 0 is a false value, will not be executed.
if (objectNum) { }  // true because objectNum exists as an object, will be executed.
if (objectNum.valueOf()) { } // false because the value of objectNum is 0.

eval est mauvais

eval() est mauvais. Il demande au navigateur de créer un nouvel environnement de scripting (comme la création d’une nouvelle page web), d’importer toutes les variables de l’environnement en cours, d’exécuter le script, de lancer le ramasse-miettes (garbage collector) et d’exporter la variable dans l’environnement d’origine. De plus, le code ne peut être mis en cache aux fins d’optimisation.

Il s’agit probablement de la fonction la plus puissante et la plus mal employée de JavaScript. Elle a aussi ses alias. Aussi, n’utilisez pas le constructeur Function et ne passez pas des chaînes à setTimeout() ou setInterval().

Se prémunir contre les XSS

Toute sortie vers le navigateur qui a été fournie par l’utilisateur doit être exécutée dans la fonction Drupal.checkPlain(). Elle est semblable à la fonction PHP de Drupal check_plain() et encode les caractères spéciaux en plain-text pour l’afficher en tant qu’HTML.

TypeOf

Lorque vous utilisez une vérification tpeof, n’utilisez pas de parenthèse pour le typeof. Ce qui suit respecte les normes de programmation :

if (typeof myVariable == 'string') {
  // ...
}

Modifier le DOM

Lors de l’ajout de nouveaux éléments au DOM, n’utilisez pas document.createElement(). Pour des questions de compatibilité entre les navigateurs et aussi dans le but de réduire la taille des fichiers, utilisez son équivalent jQquery.

Ne faites pas :

this.popup = document.createElement('div');
this.popup.id = 'autocomplete';

Mais faites :

this.popup = $('<div id="autocomplete"></div>')[0];

Des trucs propres à Drupal 6 (et ultérieurs)

Drupal 6 a introduit l’habillage JavaScript et la traduction des fichiers JavaScript.

Habillage (theming)

Il y a un mécanisme d’habillage pour le code JavaScript. Tout module contenant du JavaScript qui produit du contenu HTML doit fournir des fonctions de thèmes par défaut dans le Drupal.theme.prototype namespace.

Traduction des chaînes

Toutes les chaînes des fichiers JavaScript doivent être passées dans Drupal.t(), qui est l’équivalent de la célèbre fonction t(). De même, il y a aussi un équivalent à format_plural(), nommé Drupal.formatPlural(). L’ordre des paramètres est le même que pour les fonctions PHP.