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