Branch data Line data Source code
1 : 15 : // application/javascript;version=1.8
2 : : // SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
3 : : // SPDX-FileCopyrightText: 2013 Giovanni Campagna
4 : :
5 : 8 : const Legacy = imports._legacy;
6 : 8 : const {Gio, GjsPrivate, GLib, GObject} = imports.gi;
7 : 8 : const {_createBuilderConnectFunc, _createClosure, _registerType} = imports._common;
8 : 8 : const Gi = imports._gi;
9 : :
10 : 8 : let Gtk;
11 : 8 : let BuilderScope;
12 : :
13 : 8 : function _init() {
14 : 8 : Gtk = this;
15 : :
16 : 8 : Gtk.children = GObject.__gtkChildren__;
17 : 8 : Gtk.cssName = GObject.__gtkCssName__;
18 : 8 : Gtk.internalChildren = GObject.__gtkInternalChildren__;
19 : 8 : Gtk.template = GObject.__gtkTemplate__;
20 : :
21 : 8 : let {GtkWidgetClass} = Legacy.defineGtkLegacyObjects(GObject, Gtk);
22 : 8 : Gtk.Widget.prototype.__metaclass__ = GtkWidgetClass;
23 : :
24 [ + + ][ + + ]: 8 : if (Gtk.Container && Gtk.Container.prototype.child_set_property) {
25 : 7 : Gtk.Container.prototype.child_set_property = function (child, property, value) {
26 : 1 : GjsPrivate.gtk_container_child_set_property(this, child, property, value);
27 : : };
28 : : }
29 : :
30 [ + + ]: 8 : if (Gtk.CustomSorter) {
31 : 1 : Gtk.CustomSorter.new = GjsPrivate.gtk_custom_sorter_new;
32 : 1 : Gtk.CustomSorter.prototype.set_sort_func = function (sortFunc) {
33 : 2 : GjsPrivate.gtk_custom_sorter_set_sort_func(this, sortFunc);
34 : : };
35 : : }
36 : :
37 : 138 : Gtk.Widget.prototype._init = function (params) {
38 : 130 : const klass = this.constructor;
39 [ + - ]: 130 : const wrapper = GObject.Object.prototype._init.call(this, params) ?? this;
40 : :
41 [ + + ]: 130 : if (klass[Gtk.template]) {
42 [ + + ]: 45 : let children = klass[Gtk.children] ?? [];
43 [ + + ]: 129 : for (let child of children) {
44 : 84 : wrapper[child.replace(/-/g, '_')] =
45 : 84 : wrapper.get_template_child(klass, child);
46 : : }
47 : :
48 [ + + ]: 45 : let internalChildren = klass[Gtk.internalChildren] ?? [];
49 [ + + ]: 87 : for (let child of internalChildren) {
50 : 42 : wrapper[`_${child.replace(/-/g, '_')}`] =
51 : 42 : wrapper.get_template_child(klass, child);
52 : : }
53 : : }
54 : :
55 : 130 : return wrapper;
56 : 130 : };
57 : :
58 : 8 : Gtk.Widget._classInit = function (klass) {
59 : 16 : return GObject.Object._classInit(klass);
60 : : };
61 : :
62 : 16 : Object.defineProperty(Gtk.Widget, _registerType, {
63 : 8 : value: _registerWidgetType,
64 : 8 : writable: false,
65 : 8 : configurable: false,
66 : 8 : enumerable: false,
67 : : });
68 : :
69 [ + + ]: 8 : if (Gtk.Widget.prototype.get_first_child) {
70 : 1 : Gtk.Widget.prototype[Symbol.iterator] = function* () {
71 [ # # ]: 0 : for (let c = this.get_first_child(); c; c = c.get_next_sibling())
72 : 0 : yield c;
73 : 0 : };
74 : : }
75 : :
76 [ + + ]: 8 : if (Gtk.BuilderScope) {
77 : 2 : BuilderScope = GObject.registerClass({
78 : 1 : Implements: [Gtk.BuilderScope],
79 [ - + ]: 8 : }, class extends GObject.Object {
80 : 44 : vfunc_create_closure(builder, handlerName, flags, connectObject) {
81 : 43 : const swapped = flags & Gtk.BuilderClosureFlags.SWAPPED;
82 : 43 : const thisArg = builder.get_current_object();
83 : 85 : return Gi.associateClosure(
84 [ + + ]: 43 : connectObject ?? thisArg,
85 : 43 : _createClosure(builder, thisArg, handlerName, swapped, connectObject)
86 : : );
87 : 42 : }
88 : : });
89 : : }
90 : : }
91 : :
92 : 16 : function _registerWidgetType(klass) {
93 : 16 : const template = klass[Gtk.template];
94 : 16 : const cssName = klass[Gtk.cssName];
95 : 16 : const children = klass[Gtk.children];
96 : 16 : const internalChildren = klass[Gtk.internalChildren];
97 : :
98 [ + + ]: 16 : if (template) {
99 : 13 : klass.prototype._instance_init = function () {
100 : 38 : this.init_template();
101 : : };
102 : : }
103 : :
104 : 16 : GObject.Object[_registerType](klass);
105 : :
106 [ + + ]: 16 : if (cssName)
107 : 4 : Gtk.Widget.set_css_name.call(klass, cssName);
108 : :
109 [ + + ]: 16 : if (template) {
110 [ + + ]: 13 : if (typeof template === 'string') {
111 : 7 : try {
112 : 7 : const uri = GLib.Uri.parse(template, GLib.UriFlags.NONE);
113 : 5 : const scheme = uri.get_scheme();
114 : :
115 [ + + ]: 5 : if (scheme === 'resource') {
116 : 2 : Gtk.Widget.set_template_from_resource.call(klass, uri.get_path());
117 [ + + ]: 3 : } else if (scheme === 'file') {
118 : 2 : const file = Gio.File.new_for_uri(template);
119 [ - + ][ - + ]: 2 : const [, contents] = file.load_contents(null);
[ # # ][ # # ]
[ # # ][ # # ]
120 : 2 : Gtk.Widget.set_template.call(klass, contents);
121 : : } else {
122 : 1 : throw new TypeError(`Invalid template URI: ${template}`);
123 : : }
124 : 3 : } catch (err) {
125 [ + + ]: 3 : if (!(err instanceof GLib.UriError))
126 : 1 : throw err;
127 : :
128 : 2 : const contents = new TextEncoder().encode(template);
129 : 2 : Gtk.Widget.set_template.call(klass, contents);
130 : : }
131 : : } else {
132 : 6 : Gtk.Widget.set_template.call(klass, template);
133 : : }
134 : :
135 [ + + ]: 12 : if (BuilderScope)
136 : 7 : Gtk.Widget.set_template_scope.call(klass, new BuilderScope());
137 : : else
138 : 5 : Gtk.Widget.set_connect_func.call(klass, _createBuilderConnectFunc(klass));
139 : : }
140 : :
141 [ + + ]: 15 : if (children) {
142 : 10 : children.forEach(child =>
143 : 20 : Gtk.Widget.bind_template_child_full.call(klass, child, false, 0));
144 : : }
145 : :
146 [ + + ]: 15 : if (internalChildren) {
147 : 10 : internalChildren.forEach(child =>
148 : 10 : Gtk.Widget.bind_template_child_full.call(klass, child, true, 0));
149 : : }
150 : : }
|