[gjs] docs: Convert docs to Markdown



commit 08d89ea501b91d5395f110c86e7885fb645950d7
Author: Philip Chimento <philip chimento gmail com>
Date:   Tue Nov 29 23:11:03 2016 -0800

    docs: Convert docs to Markdown
    
    Markdown is a pretty standard format and displays nicely in several Git
    repository viewers. It's a good replacement for the mishmash of different
    wiki formats that we previously had.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=595439

 doc/{gjs-byte-array.txt => ByteArray.md} |   80 +++++-----
 doc/SpiderMonkey_Memory.md               |   91 +++++++++++
 doc/SpiderMonkey_Memory.txt              |   82 ----------
 doc/Style_Guide.md                       |  242 +++++++++++++++++++++++++++++
 doc/Style_Guide.txt                      |  243 ------------------------------
 doc/cairo.md                             |   93 ++++++++++++
 doc/cairo.txt                            |   97 ------------
 7 files changed, 464 insertions(+), 464 deletions(-)
---
diff --git a/doc/gjs-byte-array.txt b/doc/ByteArray.md
similarity index 70%
rename from doc/gjs-byte-array.txt
rename to doc/ByteArray.md
index b6224a7..3c5dbf9 100644
--- a/doc/gjs-byte-array.txt
+++ b/doc/ByteArray.md
@@ -1,10 +1,10 @@
-The ByteArray type in the imports.byteArray module is based on an
+The ByteArray type in the `imports.byteArray` module is based on an
 ECMAScript 4 proposal that was never adopted. This can be found at:
 http://wiki.ecmascript.org/doku.php?id=proposals:bytearray
 and the wikitext of that page is appended to this file.
 
 The main difference from the ECMA proposal is that gjs's ByteArray is
-inside a module, and toString()/fromString() default to UTF-8 and take
+inside a module, and `toString()`/`fromString()` default to UTF-8 and take
 optional encoding arguments.
 
 There are a number of more elaborate byte array proposals in the
@@ -18,50 +18,49 @@ pretty rare, and slow ... an advantage of the
 gjs/gobject-introspection setup is that stuff best done in C, like
 messing with bytes, can be done in C.
 
+---
 
-========================
 ECMAScript proposal follows; remember it's almost but not quite like
 gjs ByteArray, in particular we use UTF-8 instead of busted Latin-1 as
 default encoding.
-========================
 
+---
 
-====== ByteArray ======
+# ByteArray #
 
-(Also see the [[discussion:bytearray|discussion page]] for this proposal)
+(Also see the [discussion page][1] for this proposal)
+
+## Overview ##
 
-===== Overview ======
 In previous versions of ECMAScript, there wasn't a good way to efficiently represent a packed array of 
arbitrary bytes. The predefined core object Array is inefficient for this purpose; some developers have 
(mis)used character strings for this purpose, which may be slightly more efficient for some implementations, 
but still a misuse of the string type and either a less efficient use of memory (if one byte per character 
was stored) or cycles (if two bytes per char).
 
 Edition 4 will add a new predefined core object, ByteArray. A ByteArray can be thought of as similar to an 
Array of uint ([uint]) with each element truncated to the integer range of 0..255.
 
-
-===== Creating a ByteArray =====
+## Creating a ByteArray ##
 
 To create a ByteArray object:
 
-
-<code>
+```js
 byteArrayObject = new ByteArray(byteArrayLength:uint)
-</code>
+```
 
 byteArrayLength is the initial length of the ByteArray, in bytes. If omitted, the initial length is zero.
 
 All elements in a ByteArray are initialized to the value of zero.
 
-Unlike Array, there is no special form that allows you to list the initial values for the ByteArray's 
elements. However, the ByteArray class has an ''intrinsic::to'' static method that can convert an Array to a 
ByteArray, and implementations are free to optimize away the Array instance if it is used exclusively to 
initialize a ByteArray:
+Unlike Array, there is no special form that allows you to list the initial values for the ByteArray's 
elements. However, the ByteArray class has an `intrinsic::to` static method that can convert an Array to a 
ByteArray, and implementations are free to optimize away the Array instance if it is used exclusively to 
initialize a ByteArray:
 
-<code>
+```js
 var values:ByteArray = [1, 2, 3, 4];   // legal by virtue of ByteArray.intrinsic::to
-</code>
+```
 
-===== Populating a ByteArray =====
+## Populating a ByteArray ##
 
 You can populate a ByteArray by assigning values to its elements. Each element can hold only an unsigned 
integer in the range 0..255 (inclusive). Values will be converted to unsigned integer (if necessary), then 
truncated to the least-significant 8 bits.
 
 For example,
 
-<code>
+```js
 var e = new ByteArray(3);
 
 e[0] = 0x12;           // stores 18
@@ -70,23 +69,21 @@ e[2] = "foo";               // stores 0 (generates compile error in strict mode)
 e[2] = "42";           // stores 42 (generates compile error in strict mode)
 e[2] = null;           // stores 0
 e[2] = undefined;      // stores 0
-</code>
-
+```
 
-===== Referring to ByteArray Elements =====
+## Referring to ByteArray Elements ##
 
-You refer to a ByteArray's elements by using the element's ordinal number; you refer to the first element of 
the array as myArray[0] and the second element of the array as myArray[1], etc. The index of the elements 
begins with zero (0), but the length of array (for example, myArray.length) reflects the number of elements 
in the array.
-
-===== ByteArray Methods =====
+You refer to a ByteArray's elements by using the element's ordinal number; you refer to the first element of 
the array as `myArray[0]` and the second element of the array as `myArray[1]`, etc. The index of the elements 
begins with zero (0), but the length of array (for example, `myArray.length`) reflects the number of elements 
in the array.
 
+## ByteArray Methods ##
 
 The ByteArray object has the follow methods:
 
-1. static function fromString(s:String):ByteArray
+### `static function fromString(s:String):ByteArray` ###
 
 Convert a String into newly constructed ByteArray; this creates a new ByteArray of the same length as the 
String, then assigns each ByteArray entry the corresponding charCodeAt() value of the String. As with other 
ByteArray assignments, only the lower 8 bits of the charCode value will be retained.
 
-<code>
+```js
 class ByteArray {
   ...
   static function fromString(s:String):ByteArray
@@ -98,13 +95,13 @@ class ByteArray {
   }
   ...
 }
-</code>
+```
 
-2. static function fromArray(s:Array):ByteArray
+### `static function fromArray(s:Array):ByteArray` ###
 
 Converts an Array into a newly constructed ByteArray; this creates a new ByteArray of the same length as the 
input Array, then assigns each ByteArray entry the corresponding entry value of the Array. As with other 
ByteArray assignments, only the lower 8 bits of the charCode value will be retained.
 
-<code>
+```js
 class ByteArray {
   ...
   static function fromArray(s:Array):ByteArray
@@ -115,15 +112,15 @@ class ByteArray {
     return a;
   ...
 }
-</code>
+```
 
-3. function toString():String
+### `function toString():String` ###
 
 Converts the ByteArray into a literal string, with each character entry set to the value of the 
corresponding ByteArray entry.
 
-The resulting string is guaranteed to round-trip back into an identical ByteArray by passing the result to 
ByteArray.fromString(), i.e., b === ByteArray.fromString(b.toString()). (Note that the reverse is not 
guaranteed to be true: ByteArray.fromString(s).toString != s unless all character codes in s are <= 255)
+The resulting string is guaranteed to round-trip back into an identical ByteArray by passing the result to 
`ByteArray.fromString()`, i.e., `b === ByteArray.fromString(b.toString())`. (Note that the reverse is not 
guaranteed to be true: `ByteArray.fromString(s).toString != s` unless all character codes in `s` are <= 255)
 
-<code>
+```js
 class ByteArray {
   ...
   function toString():String
@@ -136,26 +133,25 @@ class ByteArray {
   }
   ...
 }
-</code>
+```
 
-===== ByteArray Properties =====
+## ByteArray Properties ##
 
 The ByteArray object has the following properties:
 
-1.  length:uint
+### `length:uint` ###
 
 This property contains the number of bytes in the ByteArray. Setting the length property to a smaller value 
decreases the size of the ByteArray, discarding the unused bytes. Setting the length property to a larger 
value increases the size of the ByteArray, initializing all newly-allocated elements to zero.
 
-2. prototype:Object
+### `prototype:Object` ###
 
 This property contains the methods of ByteArray.
 
+## Prior Art ##
 
+Adobe's ActionScript 3.0 provides [`flash.utils.ByteArray`][2], which was the primary inspiration for this 
proposal. Note that the ActionScript version of ByteArray includes additional functionality which has been 
omitted here for the sake of allowing small implementations; it is anticipated that the extra functionality 
can be written in ES4 itself and provided as a standard library.
 
-===== Prior Art =====
-
-Adobe's ActionScript 3.0 provides 
[[http://livedocs.macromedia.com/flex/2/langref/flash/utils/ByteArray.html|flash.utils.ByteArray]], which was 
the primary inspiration for this proposal. Note that the ActionScript version of ByteArray includes 
additional functionality which has been omitted here for the sake of allowing small implementations; it is 
anticipated that the extra functionality can be written in ES4 itself and provided as a standard library.
-
-[Synopsis of ActionScript's implementation too detailed and moved to [[discussion:bytearray|discussion]] 
page]
-
+[Synopsis of ActionScript's implementation too detailed and moved to [discussion][1] page]
 
+[1] http://wiki.ecmascript.org/doku.php?id=discussion:bytearray
+[2] http://livedocs.macromedia.com/flex/2/langref/flash/utils/ByteArray.html
diff --git a/doc/SpiderMonkey_Memory.md b/doc/SpiderMonkey_Memory.md
new file mode 100644
index 0000000..3fd73f0
--- /dev/null
+++ b/doc/SpiderMonkey_Memory.md
@@ -0,0 +1,91 @@
+# Memory management in SpiderMonkey #
+
+When writing JavaScript extensions in C, we have to understand and be careful about memory management.
+
+This document only applies to C code using the jsapi.h API. If you simply write a GObject-style library and 
describe it via gobject-introspection typelib, there is no need to understand garbage collection details.
+
+## Mark-and-sweep collector ##
+
+As background, SpiderMonkey uses mark-and-sweep garbage collection. (see [this page][1] for one explanation, 
if not familiar with this.)
+
+This is a good approach for "embeddable" interpreters, because unlike say the Boehm GC, it doesn't rely on 
any weird hacks like scanning the entire memory or stack of the process. The collector only has to know about 
stuff that the language runtime created itself. Also, mark-and-sweep is simple to understand when working 
with the embedding API.
+
+## Representation of objects ##
+
+An object has two forms.
+* `JS::Value` is a type-tagged version, think of `GValue` (though it is much more efficient)
+* inside a `JS::Value` can be one of: a 32-bit integer, a boolean, a double, a `JSString*`, or a `JSObject*`.
+
+`JS::Value` is a 64 bits-wide union. Some of the bits are a type tag. However, don't rely on the layout of 
`JS::Value`, as it may change between API versions.
+
+You check the type tag with the methods `val.isObject()`, `val.isInt32()`, `val.isDouble()`, 
`val.isString()`, `val.isBoolean()`. Use `val.isNull()` and `val.isUndefined()` rather than comparing `val == 
JSVAL_NULL` and `val == JSVAL_VOID` to avoid an extra memory access.
+
+null does not count as an object, so `val.isObject()` does not return true for null. This contrasts with the 
behavior of `JSVAL_IS_OBJECT(val)`, which was the previous API, but this was changed because the 
object-or-null behavior was a source of bugs. If you still want this behaviour use `val.isObjectOrNull()`.
+
+The methods `val.toObject()`, `val.toInt32()`, etc. are just accessing the appropriate members of the union.
+
+The jsapi.h header is pretty readable, if you want to learn more. Types you see in there not mentioned 
above, such as `JSFunction*`, would show up as an object - `val.isObject()` would return true. From a 
`JS::Value` perspective, everything is one of object, string, double, int, boolean, null, or undefined.
+
+## Value types vs. allocated types; "gcthing" ##
+
+For integers, booleans, doubles, null, and undefined there is no pointer. The value is just part of the 
`JS::Value` union. So there is no way to "free" these, and no way for them to be finalized or become dangling.
+
+The importance is: these types just get ignored by the garbage collector.
+
+However, strings and objects are all allocated pointers that get finalized eventually. These are what 
garbage collection applies to.
+
+The API refers to these allocated types as "GC things." The macro `val.toGCThing()` returns the value part 
of the union as a pointer. `val.isGCThing()` returns true for string, object, null; and false for void, 
boolean, double, integer.
+
+## Tracing ##
+
+The general rule is that SpiderMonkey has a set of GC roots. To do the garbage collection, it finds all 
objects accessible from those roots, and finalizes all objects that are not.
+
+So if you have a `JS::Value` or `JSObject*`/`JSString*`/`JSFunction*` somewhere that is not reachable from 
one of SpiderMonkey's GC roots - say, declared on the stack or in the private data of an object - that will 
not be found. SpiderMonkey may try to finalize this object even though you have a reference to it.
+
+If you reference JavaScript objects from your custom object, you have to use `JS::Heap<T>` and set the 
`JSCLASS_MARK_IS_TRACE` flag in your JSClass, and define a trace function in the class struct. A trace 
function just invokes `JS_CallTracer()` to tell SpiderMonkey about any objects you reference. See [JSTraceOp 
docs][2].
+
+## Global roots ##
+
+The GC roots include anything you have declared with `JS::Rooted<T>` and the global object set on each 
`JSContext*`.
+You can also manually add roots with [`JS::PersistentRooted<T>()`][3]. Anything reachable from any of these 
root objects will not be collected.
+
+`JS::PersistentRooted<T>` pins an object in memory forever until it is destructed, so be careful of leaks. 
Basically `JS::PersistentRooted<T>` changes memory management of an object to manual mode.
+
+Note that the wrapped T in `JS::PersistentRooted<T>` is the location of your value, not the value itself. 
That is, a `JSObject**` or `JS::Value*`. Some implications are:
+* the location can't go away (don't use a stack address that will vanish before the 
`JS::PersistentRooted<T>` is destructed, for example)
+* the root is keeping "whatever is at the location" from being collected, not "whatever was originally at 
the location"
+
+## Local roots ##
+
+Here is the trickier part. If you create an object, say:
+
+```c++
+JSObject *obj = JS_New(cx, whatever, ...);
+```
+
+`obj` is NOT now referenced by any other object. If the GC ran right away, `obj` would be collected.
+
+This is what `JS::Rooted<T>` is for, and its specializations `JS::RootedValue`, `JS::RootedObject`, etc. 
`JS::Rooted<T>` adds its wrapped `T` to the GC root set, and removes it when the `JS::Rooted<T>` goes out of 
scope.
+
+Any SpiderMonkey APIs that can cause a garbage collection will force you to use `JS:Rooted<T>` by taking a 
`JS::Handle<T>` instead of a bare GC thing. `JS::Handle<T>` can only be created from `JS::Rooted<T`>.
+
+So instead of the above code, you would write
+
+```c++
+JS::RootedObject obj(cx, JS_New(cx, whatever, ...));
+```
+
+### JSFunctionSpec and extra local roots ###
+
+When SpiderMonkey is calling a native function, it will pass in an argv of `JS::Value`. It already has to 
add all the argv values as GC roots. The "extra local roots" feature tells SpiderMonkey to stick some extra 
slots on the end of argv that are also GC roots. You can then assign to `argv[MAX(min_args, actual_argc)]` 
and whatever you put in there won't get garbage collected.
+
+This is kind of a confusing and unreadable hack IMO, though it is probably efficient and thus justified in 
certain cases. I don't know really.
+
+## More tips ##
+
+For another attempt to explain all this, see [Rooting Guide from Mozilla.org][4].
+
+[1] http://www.brpreiss.com/books/opus5/html/page424.html
+[2] http://developer.mozilla.org/en/docs/JSTraceOp
+[3] 
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS::PersistentRooted
+[4] https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/GC_Rooting_Guide GC
diff --git a/doc/Style_Guide.md b/doc/Style_Guide.md
new file mode 100644
index 0000000..46852c5
--- /dev/null
+++ b/doc/Style_Guide.md
@@ -0,0 +1,242 @@
+# Coding style #
+
+Our goal is to have all JavaScript code in GNOME follow a consistent style. In a dynamic language like
+JavaScript, it is essential to be rigorous about style (and unit tests), or you rapidly end up
+with a spaghetti-code mess.
+
+## Semicolons ##
+
+JavaScript allows omitting semicolons at the end of lines, but don't. Always end
+statements with a semicolon.
+
+## js2-mode ##
+
+If using Emacs, try js2-mode. It functions as a "lint" by highlighting missing semicolons
+and the like.
+
+## Imports ##
+
+Use CamelCase when importing modules to distinguish them from ordinary variables, e.g.
+
+```js
+const Big = imports.big;
+const GLib = imports.gi.GLib;
+```
+
+## Variable declaration ##
+
+Always use one of `const`, `var`, or `let` when defining a variable. Always use `let` when block scope is 
intended; in particular, inside `for()` and `while()` loops, `let` is almost always correct.
+
+```js
+// Iterating over an array
+for (let i = 0; i < 10; ++i) {
+  let foo = bar(i);
+}
+// Iterating over an object's properties
+for (let prop in someobj) {
+  ...
+}
+```
+
+If you don't use `let` then the variable is added to function scope, not the for loop block scope.
+See [What's new in JavaScript 1.7][1]
+
+A common case where this matters is when you have a closure inside a loop:
+```js
+for (let i = 0; i < 10; ++i) {
+  mainloop.idle_add(function() { log("number is: " + i); });
+}
+```
+
+If you used `var` instead of `let` it would print "10" a bunch of times.
+
+Inside functions, `let` is always correct instead of `var` as far as we know. `var` is useful when you want 
to add something to the `with()` object, though... in particular we think you need `var` to define module 
variables, since our module system loads modules with the equivalent of `with (moduleObject)`
+
+## `this` in closures ##
+
+`this` will not be captured in a closure; `this` is relative to how the closure is invoked, not to
+the value of this where the closure is created, because `this` is a keyword with a value passed
+in at function invocation time, it is not a variable that can be captured in closures.
+
+To solve this, use `Lang.bind`, eg:
+
+```js
+const Lang = imports.lang;
+
+let closure = Lang.bind(this, function() { this._fnorbate() });
+```
+
+A more realistic example would be connecting to a signal on a
+method of a prototype:
+
+```js
+const Lang = imports.lang;
+
+MyPrototype = {
+    _init : function() {
+       fnorb.connect('frobate', Lang.bind(this, this._onFnorbFrobate));
+    },
+
+    _onFnorbFrobate : function(fnorb) {
+       this._updateFnorb();
+    },
+};
+```
+
+## Object literal syntax ##
+
+JavaScript allows equivalently:
+```js
+foo = { 'bar' : 42 };
+foo = { bar: 42 };
+```
+and
+```js
+var b = foo['bar'];
+var b = foo.bar;
+```
+
+If your usage of an object is like an object, then you're defining "member variables." For member variables, 
use the no-quotes no-brackets syntax, that is, `{ bar: 42 }` and `foo.bar`.
+
+If your usage of an object is like a hash table (and thus conceptually the keys can have special chars in 
them), don't use quotes, but use brackets, `{ bar: 42 }`, `foo['bar']`.
+
+## Variable naming ##
+
+- We use javaStyle variable names, with CamelCase for type names and lowerCamelCase for variable and method 
names. However, when calling a C method with underscore-based names via introspection, we just keep them 
looking as they do in C for simplicity.
+- Private variables, whether object member variables or module-scoped variables, should begin with `_`.
+- True global variables (in the global or 'window' object) should be avoided whenever possible. If you do 
create them, the variable name should have a namespace in it, like `BigFoo`
+- When you assign a module to an alias to avoid typing `imports.foo.bar` all the time, the alias should be 
`const TitleCase` so `const Bar = imports.foo.bar;`
+- If you need to name a variable something weird to avoid a namespace collision, add a trailing `_` (not 
leading, leading `_` means private).
+- For GObject constructors, always use the `lowerCamelCase` style for property names instead of dashes or 
underscores.
+
+## Whitespace ##
+
+* 4-space indentation (the Java style)
+* No trailing whitespace.
+* No tabs.
+* If you `chmod +x .git/hooks/pre-commit` it will not let you commit with messed-up whitespace (well, it 
doesn't catch tabs. turn off tabs in your text editor.)
+
+## JavaScript "classes" ##
+
+Keep in mind that JavaScript does not "really" have classes in the sense of C++ or Java; you can't create 
new types beyond the built-in ones (Object, Array, RegExp, String). However, you can create object instances 
that share common properties, including methods, using the prototype mechanism.
+
+Each JavaScript object has a property `__proto__`; if you write `obj.foo` and `foo` is not in `obj`, 
JavaScript will look for `foo` in `__proto__`. If several objects have the same `__proto__`, then they can 
share methods or other state.
+
+You can create objects with a constructor, which is a special function. Say you have:
+```js
+function Foo() {}
+let f = new Foo();
+```
+
+For `new Foo()` JavaScript will create a new, empty object; and execute `Foo()` with the new, empty object 
as `this`. So the function `Foo()` sets up the new object.
+
+`new Foo()` will also set `__proto__` on the new object to `Foo.prototype`. The property `prototype` on a 
constructor is used to initialize `__proto__` for objects the constructor creates. To get the right 
`__proto__` on objects, we need the right prototype property on the constructor.
+
+You could think of `f = new Foo()` as:
+```js
+let f = {}; // create new object
+f.__proto__ = Foo.prototype; // doing this by hand isn't actually allowed
+Foo.call(f); // invoke Foo() with new object as "this"
+```
+
+Our pattern for writing classes is:
+```js
+function Foo(arg1, arg2) {
+  this._init(arg1, arg2);
+}
+
+Foo.prototype = {
+  _init : function(arg1, arg2) {
+    this._myPrivateInstanceVariable = arg1;
+  },
+  myMethod : function() {
+
+  },
+  myClassVariable : 42,
+  myOtherClassVariable : "Hello"
+}
+```
+
+This pattern means that when you do `let f = new Foo()`, `f` will be a new object, `f.__proto__` will point 
to `Foo.prototype`, and `Foo.prototype._init` will be called to set up the object.
+
+> **NOTE:** Again, on the JavaScript language level, Foo is not a class in the sense of Java or C++; it's 
just a constructor function, which means it's intended for use with the `new Foo()` syntax to create an 
object. Once the object is created, from a JavaScript language perspective its type is the built-in type 
`Object` - though we're using it and thinking of it as if it had type `Foo`, JavaScript doesn't have a clue 
about that and will never do any type-checking based on which constructor was used to create something. All 
typing is "duck typing." The built-in types, such as `Object`, `String`, `Error`, `RegExp`, and `Array`, 
_are_ real types, however, and do get type-checked.
+
+> **NOTE:** If a constructor function has a return value, it is used as the value of `new Foo()` - replacing 
the automatically-created `this` object passed in to the constructor. If a constructor function returns 
nothing (undefined), then the passed-in `this` is used. In general, avoid this feature - constructors should 
have no return value. But this feature may be necessary if you need the new instance to have a built-in type 
other than Object. If you return a value from the constructor, `this` is simply discarded, so referring to 
`this` while in the constructor won't make sense. }}
+
+## JavaScript "inheritance" ##
+
+There are lots of ways to simulate "inheritance" in JavaScript. In general, it's a good idea to avoid class 
hierarchies in JavaScript. But sometimes it's the best solution.
+
+Our preferred approach is to use a Spidermonkey-specific extension and directly set the `__proto__` member 
of the subclass's prototype to point to the prototype of the base class. Looking up a property in the 
subclass starts with the properties of the instance. If the property isn't there, then the prototype chain is 
followed first to the subclass's prototype and then to the base class's prototype.
+```js
+const Lang = imports.lang;
+
+function Base(foo) {
+  this._init(foo);
+}
+
+Base.prototype = {
+  _init : function(foo) {
+    this._foo = foo;
+  },
+  frobate : function() {
+  }
+};
+
+function Sub(foo, bar) {
+  this._init(foo, bar);
+}
+
+Sub.prototype = {
+  __proto__ : Base.prototype,
+
+  _init : function(foo, bar) {
+    // here is an example of how to "chain up"
+    Base.prototype._init.call(this, foo);
+    this._bar = bar;
+  }
+
+  // add a newMethod property in Sub.prototype
+  newMethod : function() {
+  }
+}
+```
+
+> **NOTE:** You cannot use this mechanism to inherit from a built-in type, such as String or Error, because 
the methods on those objects expect them to have primitive type String or Error, while your constructor will 
create an Object instead.
+
+> **NOTE:** You cannot use this mechanism to inherit from a GObject. For that to work, we would need to 
create a new GType in C that was a subclass of the base class GType, and we'd need to override the class 
methods in the new GType so they called into JavaScript. Tons of work. For now, GObject subclasses must be 
implemented in C.
+
+In portable JavaScript code you'll often see a different technique used to get this prototype chain:
+```js
+function Base(foo) ...
+
+Base.prototype = ...
+
+function Sub(foo, bar) ...
+
+// Do NOT do this - do not use an instance of Base as the Sub prototype
+Sub.prototype = new Base();
+```
+
+The problem with this pattern is that you might want to have side effects in the `Base()` constructor. Say 
`Base()` in its constructor creates a window on the screen, because `Base()` is a dialog class or something. 
If you use the pattern that some instances of `Base()` are just prototypes for subclasses, you'll get extra 
windows on the screen.
+
+The other problem with this pattern is that it's just confusing and weird.
+
+## JavaScript attributes ##
+
+Don't use the getter/setter syntax when getting and setting has side effects, that is, the code:
+```js
+foo.bar = 10;
+```
+should not do anything other than save "10" as a property of `foo`. It's obfuscated otherwise; if the 
setting has side effects, it's better if it looks like a method.
+
+In practice this means the only use of attributes is to create read-only properties:
+```js
+get bar() {
+    return this._bar;
+}
+```
+
+If the property requires a setter, or if getting it has side effects, methods are probably clearer.
+
+[1] 
http://developer.mozilla.org/en/docs/index.php?title=New_in_JavaScript_1.7&printable=yes#Block_scope_with_let
diff --git a/doc/cairo.md b/doc/cairo.md
new file mode 100644
index 0000000..c83b370
--- /dev/null
+++ b/doc/cairo.md
@@ -0,0 +1,93 @@
+The cairo bindings follows the C API pretty closely.
+
+## Naming ##
+
+The module name is called 'cairo' and usually imported into
+the namespace as 'Cairo'.
+```js
+const Cairo = imports.cairo;
+```
+Methods are studlyCaps, similar to other JavaScript apis, eg
+
+`cairo_move_to` is wrapped to `Cairo.Context.moveTo()`
+`cairo_surface_write_to_png` to `Cairo.Context.writeToPNG()`.
+
+Abbrevations such as RGB, RGBA, PNG, PDF, SVG are always
+upper-case.
+
+Enums are set in the cairo namespace, the enum names are capitalized:
+
+`CAIRO_FORMAT_ARGB32` is mapped to `Cairo.Format.ARGB32` etc.
+
+## Surfaces (`cairo_surface_t`) ##
+
+Prototype hierarchy
+
+* `Surface` (abstract)
+  * `ImageSurface`
+  * `PDFSurface`
+  * `SVGSurface`
+  * `PostScriptSurface`
+
+The native surfaces (win32, quartz, xlib) are not supported at this point.
+
+Methods manipulating a surface are present in the surface class.
+Creating an ImageSurface from a PNG is done by calling a static method:
+```js
+let surface = Cairo.ImageSurface.createFromPNG("filename.png");
+```
+
+## Context (`cairo_t`) ##
+
+`cairo_t` is mapped as `Cairo.Context`.
+
+You will either get a context from a third-party library such
+as Clutter/Gtk/Poppler or by calling the `Cairo.Context` constructor.
+
+```js
+let cr = new Cairo.Context(surface);
+
+let cr = Gdk.cairo_create(...);
+```
+All introspection methods taking or returning a `cairo_t` will automatically
+create a `Cairo.Context`.
+
+## Patterns (`cairo_pattern_t`) ##
+
+Prototype hierarchy
+
+* `Pattern`
+  * `Gradient`
+    * `LinearGradient`
+    * `RadialGradient`
+  * `SurfacePattern`
+  * `SolidPattern`
+
+You can create a linear gradient by calling the constructor:
+
+Constructors:
+```js
+let pattern = new Cairo.LinearGradient(0, 0, 100, 100);
+
+let pattern = new Cairo.RadialGradient(0, 0, 10, 100, 100, 10);
+
+let pattern = new Cairo.SurfacePattern(surface);
+
+let pattern = new Cairo.SolidPattern.createRGB(0, 0, 0);
+
+let pattern = new Cairo.SolidPattern.createRGBA(0, 0, 0, 0);
+```
+TODO:
+* context: wrap the remaning methods
+* surface methods
+* image surface methods
+* matrix
+* version
+* iterating over `cairo_path_t`
+
+Fonts & Glyphs are not wrapped, use PangoCairo instead.
+* glyphs
+* text cluster
+* font face
+* scaled font
+* font options


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]