This file is licensed under the terms of the expat license, see the file EXPAT. + Hacking guide for Midori + - How to contribute - Coding style - Source files in the project - Examplary source code +++ How to contribute +++ There are several ways to contribute to the project: For translating, have a look at the file TRANSLATE. For helping with testing and triaging bug reports, you should registers with the bug tracker at https://bugs.launchpad.net/midori and join #midori on irc.freenode.net where a lot of problems are discussed. You can start right away by trying to reproduce bug reports and comment with your findings. If you are interested in contributing code, there are a few options. You can join #midori to discuss a particular problem you would like to look into, or a feature you would want to implement. Opening a bug report or feature request if there isn't already one is the next step. To attract some attention, if you attached a patch or have questions, ask in #midori. +++ Coding style +++ Indentation is 4 spaces, no tabs, preferrably at 80 to 120 columns per line to avoid automated line-breaks. Trailing whitespace is not desirable. Declarations go to the beginning of a block, not inline. Variables of one plain type may be grouped in one declaration, pointer types may not be grouped. The asterisk goes next to the type. Variables should be ordered in the order they are used. Comments explain functionality, they should not state facts. The appropriate style is always C style /* */, not C++ style. Variable and function names should be animal, animal_shelter or animalsc in case it would otherwise be very long. Loop counters may be single letters. Type names should be Animal, AnimalShelter or AnimalSC. No prefixes from third party projects should be used, such as GTK or WebKit, while underlines may be used but do not have a particular meaning. There is a space between functions or keywords and round brackets, and curly brackets always go on separate lines, at the indentation level of the function, conditional or loop expression. Curly brackets are left out for single statement conditionals and loops unless they notably help readability. The type of a function goes on a separate line before the function. Preprocessor instructions are indented with the code they relate to. Code history is precious, so one should avoid renaming a lot of functions at once or moving whole paragraphs only to add or remove a level of indentation. Moving blocks of code around is also undesriable because it makes patches less readable since the result looks like new code. +++ Source files in the project +++ Core: Files prefixed with "midori-" in the folder "midori" make up the core. They are essential to running the browser and mostly tailored to the browser. All header files prefixed with "midori-" are considered supported API and can be used to implement extensions. "sokoke" is a collection of very specialized helper functions which change from time to time as needed. In the past some of the code was moved to "katze" when it was considered generally useful. "socket" is a socket implementation with no dependency on other parts of the core, which is used if Midori is built without an external single instance support library. Panels: Files in the "panels" folder are classes that implement MidoriViewable and which are loaded into the MidoriPanel at startup. These panels are in principle optional. Katze: Re-usable classes and utility functions that don't depend on the core and some of that code indeed found its way into other projects. Extensions: These are extensions, written in C, which are loaded optionally if the user so chooses. Extensions can use API from "midori-" and "katze-" headers. Each module consists of either a single .c file or a folder with .c files. Tests: Unit tests are run regularly to verify possible regressions or measure performance of implementations. Except for select cases code changes should not cause failure of unit tests. +++ Examplary source code +++ /* Copyright LICENSE TEXT */ #include "foo.h" #include "bar.h" #include void foobar (FooEnum bar, const gchar* foo) { gint n, i; if (!foo) return; #ifdef BAR_STRICT if (bar == FOO_N) { g_print ("illegal value for 'bar'.\n"); return; } #endif /* this is an example */ switch (bar) { case FOO_FOO: n = bar + 1; break; case FOO_BAR: n = bar + 10; break; default: n = 1; } for (i = 0; i < n; i++) { g_print ("%s\n", foo); } } Header file example: /* Copyright LICENSE TEXT */ #ifndef __FOO_H__ #define __FOO_H__ 1 #ifdef HAVE_BAR_H #define BAR_STRICT #endif /* Types */ typedef enum { FOO_FOO, FOO_BAR, FOO_N } FooEnum; typedef struct { FooEnum foo_bar; } FooStruct; /* Declarations */ void foo_bar (FooEnum bar, const gchar* foo); const gchar* foo_foo (FooStruct foo_struct, guint number, gboolean flag); #endif /* !__FOO_H__ */