docs: Update HACKING
We no longer use Lang.Class(), so update the guidelines accordingly. https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/361
This commit is contained in:
parent
e68dfed1f7
commit
b7e2718bdc
80
HACKING.md
80
HACKING.md
@ -120,40 +120,34 @@ See [What's new in JavaScript 1.7](https://developer.mozilla.org/en/JavaScript/N
|
|||||||
|
|
||||||
## Classes
|
## Classes
|
||||||
|
|
||||||
There are many approaches to classes in JavaScript. We use our own class framework
|
There are many approaches to classes in JavaScript. We use standard ES6 classes
|
||||||
(sigh), which is built in gjs. The advantage is that it supports inheriting from
|
whenever possible, that is when not inheriting from GObjects.
|
||||||
GObjects, although this feature isn't used very often in the Shell itself.
|
|
||||||
```javascript
|
```javascript
|
||||||
var IconLabelMenuItem = new Lang.Class({
|
var IconLabelMenuItem = class extends PopupMenu.PopupMenuBaseItem {
|
||||||
Name: 'IconLabelMenuItem',
|
constructor(icon, label) {
|
||||||
Extends: PopupMenu.PopupMenuBaseItem,
|
super({ reactive: false });
|
||||||
|
|
||||||
_init(icon, label) {
|
|
||||||
this.parent({ reactive: false });
|
|
||||||
this.actor.add_child(icon);
|
this.actor.add_child(icon);
|
||||||
this.actor.add_child(label);
|
this.actor.add_child(label);
|
||||||
},
|
}
|
||||||
|
|
||||||
open() {
|
open() {
|
||||||
log("menu opened!");
|
log("menu opened!");
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
* 'Name' is required. 'Extends' is optional. If you leave it out, you will
|
For GObject inheritence, we use the GObject.registerClass() function provided
|
||||||
automatically inherit from Object.
|
by gjs.
|
||||||
|
```javascript
|
||||||
|
var MyActor = GObject.registerClass(
|
||||||
|
class MyActor extends Clutter.Actor {
|
||||||
|
_init(params) {
|
||||||
|
super._init(params);
|
||||||
|
|
||||||
* Leave a blank line between the "class header" (Name, Extends, and other
|
this.name = 'MyCustomActor';
|
||||||
things) and the "class body" (methods). Leave a blank line between each
|
}
|
||||||
method.
|
});
|
||||||
|
```
|
||||||
* No space before the colon, one space after.
|
|
||||||
|
|
||||||
* No trailing comma after the last item.
|
|
||||||
|
|
||||||
* Make sure to use a semicolon after the closing paren to the class. It's
|
|
||||||
still a giant function call, even though it may resemble a more
|
|
||||||
conventional syntax.
|
|
||||||
|
|
||||||
## GObject Introspection
|
## GObject Introspection
|
||||||
|
|
||||||
@ -161,17 +155,16 @@ GObject Introspection is a powerful feature that allows us to have native
|
|||||||
bindings for almost any library built around GObject. If a library requires
|
bindings for almost any library built around GObject. If a library requires
|
||||||
you to inherit from a type to use it, you can do so:
|
you to inherit from a type to use it, you can do so:
|
||||||
```javascript
|
```javascript
|
||||||
var MyClutterActor = new Lang.Class({
|
var MyClutterActor = GObject.registerClass(
|
||||||
Name: 'MyClutterActor',
|
class MyClutterActor extends Clutter.Actor {
|
||||||
Extends: Clutter.Actor,
|
|
||||||
|
|
||||||
vfunc_get_preferred_width(actor, forHeight) {
|
vfunc_get_preferred_width(actor, forHeight) {
|
||||||
return [100, 100];
|
return [100, 100];
|
||||||
},
|
}
|
||||||
|
|
||||||
vfunc_get_preferred_height(actor, forWidth) {
|
vfunc_get_preferred_height(actor, forWidth) {
|
||||||
return [100, 100];
|
return [100, 100];
|
||||||
},
|
}
|
||||||
|
|
||||||
vfunc_paint(actor) {
|
vfunc_paint(actor) {
|
||||||
let alloc = this.get_allocation_box();
|
let alloc = this.get_allocation_box();
|
||||||
@ -206,20 +199,18 @@ that has a property called `actor`. We call this wrapper class the "delegate".
|
|||||||
We sometimes use expando properties to set a property called `_delegate` on
|
We sometimes use expando properties to set a property called `_delegate` on
|
||||||
the actor itself:
|
the actor itself:
|
||||||
```javascript
|
```javascript
|
||||||
var MyClass = new Lang.Class({
|
var MyClass = class {
|
||||||
Name: 'MyClass',
|
constructor() {
|
||||||
|
|
||||||
_init() {
|
|
||||||
this.actor = new St.Button({ text: "This is a button" });
|
this.actor = new St.Button({ text: "This is a button" });
|
||||||
this.actor._delegate = this;
|
this.actor._delegate = this;
|
||||||
|
|
||||||
this.actor.connect('clicked', this._onClicked.bind(this));
|
this.actor.connect('clicked', this._onClicked.bind(this));
|
||||||
},
|
}
|
||||||
|
|
||||||
_onClicked(actor) {
|
_onClicked(actor) {
|
||||||
actor.set_label("You clicked the button!");
|
actor.set_label("You clicked the button!");
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
The 'delegate' property is important for anything which trying to get the
|
The 'delegate' property is important for anything which trying to get the
|
||||||
@ -252,19 +243,18 @@ notation.
|
|||||||
A more realistic example would be connecting to a signal on a method of a
|
A more realistic example would be connecting to a signal on a method of a
|
||||||
prototype:
|
prototype:
|
||||||
```javascript
|
```javascript
|
||||||
const Lang = imports.lang;
|
|
||||||
const FnorbLib = imports.fborbLib;
|
const FnorbLib = imports.fborbLib;
|
||||||
|
|
||||||
var MyClass = new Lang.Class({
|
var MyClass = class {
|
||||||
_init() {
|
_init() {
|
||||||
let fnorb = new FnorbLib.Fnorb();
|
let fnorb = new FnorbLib.Fnorb();
|
||||||
fnorb.connect('frobate', this._onFnorbFrobate.bind(this));
|
fnorb.connect('frobate', this._onFnorbFrobate.bind(this));
|
||||||
},
|
}
|
||||||
|
|
||||||
_onFnorbFrobate(fnorb) {
|
_onFnorbFrobate(fnorb) {
|
||||||
this._updateFnorb();
|
this._updateFnorb();
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
## Object literal syntax
|
## Object literal syntax
|
||||||
@ -298,23 +288,21 @@ property.
|
|||||||
```javascript
|
```javascript
|
||||||
var ANIMATION_TIME = 2000;
|
var ANIMATION_TIME = 2000;
|
||||||
|
|
||||||
var MyClass = new Lang.Class({
|
var MyClass = class {
|
||||||
Name: 'MyClass',
|
constructor() {
|
||||||
|
|
||||||
_init() {
|
|
||||||
this.actor = new St.BoxLayout();
|
this.actor = new St.BoxLayout();
|
||||||
this._position = 0;
|
this._position = 0;
|
||||||
},
|
}
|
||||||
|
|
||||||
get position() {
|
get position() {
|
||||||
return this._position;
|
return this._position;
|
||||||
},
|
}
|
||||||
|
|
||||||
set position(value) {
|
set position(value) {
|
||||||
this._position = value;
|
this._position = value;
|
||||||
this.actor.set_position(value, value);
|
this.actor.set_position(value, value);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
let myThing = new MyClass();
|
let myThing = new MyClass();
|
||||||
Tweener.addTween(myThing,
|
Tweener.addTween(myThing,
|
||||||
|
Loading…
Reference in New Issue
Block a user