Branch data Line data Source code
1 : 48 : /* exported _init, interfaces, properties, registerClass, requires, signals */
2 : : // SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
3 : : // SPDX-FileCopyrightText: 2011 Jasper St. Pierre
4 : : // SPDX-FileCopyrightText: 2017 Philip Chimento <philip.chimento@gmail.com>, <philip@endlessm.com>
5 : :
6 : 48 : const Gi = imports._gi;
7 : 48 : const {GjsPrivate, GLib} = imports.gi;
8 : 48 : const {_checkAccessors, _registerType} = imports._common;
9 : 48 : const Legacy = imports._legacy;
10 : :
11 : 48 : let GObject;
12 : :
13 : 48 : var GTypeName = Symbol('GType name');
14 : 48 : var GTypeFlags = Symbol('GType flags');
15 : 48 : var interfaces = Symbol('GObject interfaces');
16 : 48 : var properties = Symbol('GObject properties');
17 : 48 : var requires = Symbol('GObject interface requires');
18 : 48 : var signals = Symbol('GObject signals');
19 : :
20 : : // These four will be aliased to GTK
21 : 48 : var _gtkChildren = Symbol('GTK widget template children');
22 : 48 : var _gtkCssName = Symbol('GTK widget CSS name');
23 : 48 : var _gtkInternalChildren = Symbol('GTK widget template internal children');
24 : 48 : var _gtkTemplate = Symbol('GTK widget template');
25 : :
26 : 107 : function registerClass(...args) {
27 : 107 : let klass = args[0];
28 [ + + ]: 107 : if (args.length === 2) {
29 : : // The two-argument form is the convenient syntax without ESnext
30 : : // decorators and class data properties. The first argument is an
31 : : // object with meta info such as properties and signals. The second
32 : : // argument is the class expression for the class itself.
33 : : //
34 : : // var MyClass = GObject.registerClass({
35 : : // Properties: { ... },
36 : : // Signals: { ... },
37 : : // }, class MyClass extends GObject.Object {
38 : : // _init() { ... }
39 : : // });
40 : : //
41 : : // When decorators and class data properties become part of the JS
42 : : // standard, this function can be used directly as a decorator.
43 : 69 : let metaInfo = args[0];
44 : 69 : klass = args[1];
45 [ + + ]: 69 : if ('GTypeName' in metaInfo)
46 : 6 : klass[GTypeName] = metaInfo.GTypeName;
47 [ + + ]: 69 : if ('GTypeFlags' in metaInfo)
48 : 2 : klass[GTypeFlags] = metaInfo.GTypeFlags;
49 [ + + ]: 69 : if ('Implements' in metaInfo)
50 : 27 : klass[interfaces] = metaInfo.Implements;
51 [ + + ]: 69 : if ('Properties' in metaInfo)
52 : 27 : klass[properties] = metaInfo.Properties;
53 [ + + ]: 69 : if ('Signals' in metaInfo)
54 : 8 : klass[signals] = metaInfo.Signals;
55 [ + + ]: 69 : if ('Requires' in metaInfo)
56 : 3 : klass[requires] = metaInfo.Requires;
57 [ + + ]: 69 : if ('CssName' in metaInfo)
58 : 2 : klass[_gtkCssName] = metaInfo.CssName;
59 [ + + ]: 69 : if ('Template' in metaInfo)
60 : 11 : klass[_gtkTemplate] = metaInfo.Template;
61 [ + + ]: 69 : if ('Children' in metaInfo)
62 : 8 : klass[_gtkChildren] = metaInfo.Children;
63 [ + + ]: 69 : if ('InternalChildren' in metaInfo)
64 : 8 : klass[_gtkInternalChildren] = metaInfo.InternalChildren;
65 : : }
66 : :
67 [ + + ]: 107 : if (!(klass.prototype instanceof GObject.Object) &&
68 [ + + ]: 8 : !(klass.prototype instanceof GObject.Interface)) {
69 : 10 : throw new TypeError('GObject.registerClass() used with invalid base ' +
70 : 5 : `class (is ${Object.getPrototypeOf(klass).name})`);
71 : : }
72 : :
73 [ + + ]: 102 : if ('_classInit' in klass) {
74 : 101 : klass = klass._classInit(klass);
75 : : } else {
76 : : // Lang.Class compatibility.
77 : 1 : klass = _resolveLegacyClassFunction(klass, '_classInit')(klass);
78 : : }
79 : :
80 : 91 : return klass;
81 : 91 : }
82 : :
83 : 2 : function _resolveLegacyClassFunction(klass, func) {
84 : : // Find the "least derived" class with a _classInit static function; there
85 : : // definitely is one, since this class must inherit from GObject
86 : 2 : let initclass = klass;
87 [ + + ]: 6 : while (typeof initclass[func] === 'undefined')
88 : 4 : initclass = Object.getPrototypeOf(initclass.prototype).constructor;
89 : 2 : return initclass[func];
90 : 2 : }
91 : :
92 : 100 : function _defineGType(klass, giPrototype, registeredType) {
93 : 100 : const config = {
94 : 100 : enumerable: false,
95 : 100 : configurable: false,
96 : : };
97 : :
98 : : /**
99 : : * class Example {
100 : : * // The JS object for this class' ObjectPrototype
101 : : * static [Gi.gobject_prototype_symbol] = ...
102 : : * static get $gtype () {
103 : : * return ...;
104 : : * }
105 : : * }
106 : : *
107 : : * // Equal to the same property on the constructor
108 : : * Example.prototype[Gi.gobject_prototype_symbol] = ...
109 : : */
110 : :
111 : 200 : Object.defineProperty(klass, '$gtype', {
112 : 100 : ...config,
113 : 100 : get() {
114 : 359 : return registeredType;
115 : : },
116 : : });
117 : :
118 : 200 : Object.defineProperty(klass.prototype, Gi.gobject_prototype_symbol, {
119 : 100 : ...config,
120 : 100 : writable: false,
121 : 100 : value: giPrototype,
122 : : });
123 : : }
124 : :
125 : : // Some common functions between GObject.Class and GObject.Interface
126 : :
127 : 100 : function _createSignals(gtype, sigs) {
128 [ + + ]: 121 : for (let signalName in sigs) {
129 : 21 : let obj = sigs[signalName];
130 [ + + ]: 21 : let flags = obj.flags !== undefined ? obj.flags : GObject.SignalFlags.RUN_FIRST;
131 [ + + ]: 21 : let accumulator = obj.accumulator !== undefined ? obj.accumulator : GObject.AccumulatorType.NONE;
132 [ + + ]: 21 : let rtype = obj.return_type !== undefined ? obj.return_type : GObject.TYPE_NONE;
133 [ + + ]: 21 : let paramtypes = obj.param_types !== undefined ? obj.param_types : [];
134 : :
135 : 21 : try {
136 : 21 : obj.signal_id = Gi.signal_new(gtype, signalName, flags, accumulator, rtype, paramtypes);
137 : 0 : } catch (e) {
138 : 0 : throw new TypeError(`Invalid signal ${signalName}: ${e.message}`);
139 : : }
140 : : }
141 : : }
142 : :
143 : 2 : function _getCallerBasename() {
144 : 2 : const stackLines = new Error().stack.trim().split('\n');
145 : 2 : const lineRegex = new RegExp(/@(.+:\/\/)?(.*\/)?(.+)\.js:\d+(:[\d]+)?$/);
146 : 2 : let thisFile = null;
147 : 2 : let thisDir = null;
148 : :
149 [ + + ]: 12 : for (let line of stackLines) {
150 : 12 : let match = line.match(lineRegex);
151 [ - + ]: 12 : if (match) {
152 : 12 : let scriptDir = match[2];
153 : 12 : let scriptBasename = match[3];
154 : :
155 [ + + ]: 12 : if (!thisFile) {
156 : 2 : thisDir = scriptDir;
157 : 2 : thisFile = scriptBasename;
158 : 2 : continue;
159 : : }
160 : :
161 [ + + ][ + + ]: 10 : if (scriptDir === thisDir && scriptBasename === thisFile)
162 : 8 : continue;
163 : :
164 [ - + ][ + - ]: 2 : if (scriptDir && scriptDir.startsWith('/org/gnome/gjs/'))
165 : 0 : continue;
166 : :
167 : 2 : let basename = scriptBasename;
168 [ - + ]: 2 : if (scriptDir) {
169 : 2 : scriptDir = scriptDir.replace(/^\/|\/$/g, '');
170 : 2 : basename = `${scriptDir.split('/').reverse()[0]}_${basename}`;
171 : : }
172 : 2 : return basename;
173 : : }
174 : : }
175 : :
176 : 0 : return null;
177 : 2 : }
178 : :
179 : 102 : function _createGTypeName(klass) {
180 : 204 : const sanitizeGType = s => s.replace(/[^a-z0-9+_-]/gi, '_');
181 : :
182 [ + + ]: 102 : if (Object.hasOwn(klass, GTypeName)) {
183 : 8 : let sanitized = sanitizeGType(klass[GTypeName]);
184 [ + + ]: 8 : if (sanitized !== klass[GTypeName]) {
185 : 2 : logError(new RangeError(`Provided GType name '${klass[GTypeName]}' ` +
186 : 1 : `is not valid; automatically sanitized to '${sanitized}'`));
187 : : }
188 : 8 : return sanitized;
189 : : }
190 : :
191 : 94 : let gtypeClassName = klass.name;
192 [ + + ]: 94 : if (GObject.gtypeNameBasedOnJSPath) {
193 : 2 : let callerBasename = _getCallerBasename();
194 [ - + ]: 2 : if (callerBasename)
195 : 2 : gtypeClassName = `${callerBasename}_${gtypeClassName}`;
196 : : }
197 : :
198 [ + + ]: 94 : if (gtypeClassName === '')
199 : 6 : gtypeClassName = `anonymous_${GLib.uuid_string_random()}`;
200 : :
201 : 94 : return sanitizeGType(`Gjs_${gtypeClassName}`);
202 : 102 : }
203 : :
204 : 102 : function _propertiesAsArray(klass) {
205 : 102 : let propertiesArray = [];
206 [ + + ]: 102 : if (Object.hasOwn(klass, properties)) {
207 [ + + ]: 81 : for (let prop in klass[properties])
208 : 52 : propertiesArray.push(klass[properties][prop]);
209 : : }
210 : 102 : return propertiesArray;
211 : 102 : }
212 : :
213 : 60 : function _copyInterfacePrototypeDescriptors(targetPrototype, sourceInterface) {
214 : 60 : Object.entries(Object.getOwnPropertyDescriptors(sourceInterface))
215 [ - + ][ - + ]: 322 : .filter(([key, descriptor]) =>
[ - + ][ # # ]
[ # # ][ # # ]
[ # # ]
216 : : // Don't attempt to copy the constructor or toString implementations
217 [ + + ]: 262 : !['constructor', 'toString'].includes(key) &&
218 : : // Ignore properties starting with __
219 [ - + ][ + + ]: 211 : (typeof key !== 'string' || !key.startsWith('__')) &&
220 : : // Don't override an implementation on the target
221 [ + + ]: 207 : !Object.hasOwn(targetPrototype, key) &&
222 [ - + ]: 76 : descriptor &&
223 : : // Only copy if the descriptor has a getter, is a function, or is enumerable.
224 [ + - ][ # # ]: 76 : (typeof descriptor.value === 'function' || descriptor.get || descriptor.enumerable))
225 [ - + ][ - + ]: 136 : .forEach(([key, descriptor]) => {
[ - + ][ # # ]
[ # # ][ # # ]
[ # # ]
226 : 76 : Object.defineProperty(targetPrototype, key, descriptor);
227 : : });
228 : : }
229 : :
230 : 17 : function _interfacePresent(required, klass) {
231 [ + + ]: 17 : if (!klass[interfaces])
232 : 7 : return false;
233 [ + + ]: 10 : if (klass[interfaces].includes(required))
234 : 2 : return true; // implemented here
235 : : // Might be implemented on a parent class
236 : 8 : return _interfacePresent(required, Object.getPrototypeOf(klass));
237 : : }
238 : :
239 : 27 : function _checkInterface(iface, proto) {
240 : : // Checks for specific interfaces
241 : :
242 : : // Default vfunc_async_init() will run vfunc_init() in a thread and crash.
243 : : // Change error message when https://gitlab.gnome.org/GNOME/gjs/issues/72
244 : : // has been solved.
245 [ + + ]: 27 : if (iface.$gtype.name === 'GAsyncInitable' &&
246 [ + + ]: 1 : !Object.getOwnPropertyNames(proto).includes('vfunc_init_async'))
247 : 1 : throw new Error("It's not currently possible to implement Gio.AsyncInitable.");
248 : :
249 : : // Check that proto implements all of this interface's required interfaces.
250 : : // "proto" refers to the object's prototype (which implements the interface)
251 : : // whereas "iface.prototype" is the interface's prototype (which may still
252 : : // contain unimplemented methods.)
253 [ + + ]: 26 : if (typeof iface[requires] === 'undefined')
254 : 17 : return;
255 : :
256 : 18 : let unfulfilledReqs = iface[requires].filter(required => {
257 : : // Either the interface is not present or it is not listed before the
258 : : // interface that requires it or the class does not inherit it. This is
259 : : // so that required interfaces don't copy over properties from other
260 : : // interfaces that require them.
261 : 9 : let ifaces = proto.constructor[interfaces];
262 [ + + ]: 9 : return (!_interfacePresent(required, proto.constructor) ||
263 [ + + ]: 2 : ifaces.indexOf(required) > ifaces.indexOf(iface)) &&
264 : 7 : !(proto instanceof required);
265 : 18 : }).map(required =>
266 : : // required.name will be present on JS classes, but on introspected
267 : : // GObjects it will be the C name. The alternative is just so that
268 : : // we print something if there is garbage in Requires.
269 [ # # ]: 0 : required.name || required);
270 [ + - ]: 9 : if (unfulfilledReqs.length > 0) {
271 : 0 : throw new Error('The following interfaces must be implemented before ' +
272 : 0 : `${iface.name}: ${unfulfilledReqs.join(', ')}`);
273 : : }
274 : 17 : }
275 : :
276 : 99 : function _registerGObjectType(klass) {
277 : 99 : const gtypename = _createGTypeName(klass);
278 [ + + ]: 99 : const gflags = Object.hasOwn(klass, GTypeFlags) ? klass[GTypeFlags] : 0;
279 [ + + ]: 99 : const gobjectInterfaces = Object.hasOwn(klass, interfaces) ? klass[interfaces] : [];
280 : 99 : const propertiesArray = _propertiesAsArray(klass);
281 : 99 : const parent = Object.getPrototypeOf(klass);
282 [ + + ]: 99 : const gobjectSignals = Object.hasOwn(klass, signals) ? klass[signals] : [];
283 : :
284 : : // Default to the GObject-specific prototype, fallback on the JS prototype
285 : : // for GI native classes.
286 [ + + ]: 99 : const parentPrototype = parent.prototype[Gi.gobject_prototype_symbol] ?? parent.prototype;
287 : :
288 [ - + ][ - + ]: 198 : const [giPrototype, registeredType] = Gi.register_type_with_class(klass,
[ - + ][ # # ]
[ # # ][ # # ]
[ # # ]
289 : 99 : parentPrototype, gtypename, gflags, gobjectInterfaces, propertiesArray);
290 : :
291 : 97 : _defineGType(klass, giPrototype, registeredType);
292 : 97 : _createSignals(klass.$gtype, gobjectSignals);
293 : :
294 : : // Reverse the interface array to give the last required interface
295 : : // precedence over the first.
296 [ + + ]: 97 : const requiredInterfaces = [...gobjectInterfaces].reverse();
297 : 97 : requiredInterfaces.forEach(iface =>
298 : 30 : _copyInterfacePrototypeDescriptors(klass, iface));
299 : 97 : requiredInterfaces.forEach(iface =>
300 : 30 : _copyInterfacePrototypeDescriptors(klass.prototype, iface.prototype));
301 : :
302 : 97 : Object.getOwnPropertyNames(klass)
303 : 521 : .filter(name => name.startsWith('vfunc_'))
304 : 100 : .forEach(name => {
305 : 3 : const prop = Object.getOwnPropertyDescriptor(klass, name);
306 [ + - ]: 3 : if (!(prop.value instanceof Function))
307 : 0 : return;
308 : :
309 : 3 : giPrototype[Gi.hook_up_vfunc_symbol](name.slice(6), klass[name], true);
310 : 0 : });
311 : :
312 : 94 : Object.getOwnPropertyNames(klass.prototype)
313 [ + + ]: 447 : .filter(name => name.startsWith('vfunc_') || name.startsWith('on_'))
314 : 167 : .forEach(name => {
315 : 73 : let descr = Object.getOwnPropertyDescriptor(klass.prototype, name);
316 [ + - ]: 73 : if (typeof descr.value !== 'function')
317 : 0 : return;
318 : :
319 : 73 : let func = klass.prototype[name];
320 : :
321 [ + + ]: 73 : if (name.startsWith('vfunc_')) {
322 : 67 : giPrototype[Gi.hook_up_vfunc_symbol](name.slice(6), func);
323 [ - + ]: 6 : } else if (name.startsWith('on_')) {
324 : 12 : let id = GObject.signal_lookup(name.slice(3).replace('_', '-'),
325 : 6 : klass.$gtype);
326 [ - + ]: 6 : if (id !== 0) {
327 : 22 : GObject.signal_override_class_closure(id, klass.$gtype, function (...argArray) {
328 : 16 : let emitter = argArray.shift();
329 : :
330 : 16 : return func.apply(emitter, argArray);
331 : 16 : });
332 : : }
333 : : }
334 : 0 : });
335 : :
336 : 117 : gobjectInterfaces.forEach(iface => _checkInterface(iface, klass.prototype));
337 : :
338 : : // Lang.Class parent classes don't support static inheritance
339 [ + - ]: 89 : if (!('implements' in klass))
340 : 0 : klass.implements = GObject.Object.implements;
341 : : }
342 : :
343 : 18 : function _interfaceInstanceOf(instance) {
344 [ + + ][ + + ]: 18 : if (instance && typeof instance === 'object' &&
345 [ + + ]: 12 : GObject.Interface.prototype.isPrototypeOf(this.prototype))
346 : 12 : return GObject.type_is_a(instance, this);
347 : :
348 : 6 : return false;
349 : : }
350 : :
351 : 3 : function _registerInterfaceType(klass) {
352 : 3 : const gtypename = _createGTypeName(klass);
353 [ - + ]: 3 : const gobjectInterfaces = Object.hasOwn(klass, requires) ? klass[requires] : [];
354 : 3 : const props = _propertiesAsArray(klass);
355 [ + + ]: 3 : const gobjectSignals = Object.hasOwn(klass, signals) ? klass[signals] : [];
356 : :
357 [ - + ][ - + ]: 6 : const [giPrototype, registeredType] = Gi.register_interface_with_class(
[ - + ][ # # ]
[ # # ][ # # ]
[ # # ]
358 : 3 : klass, gtypename, gobjectInterfaces, props);
359 : :
360 : 3 : _defineGType(klass, giPrototype, registeredType);
361 : 3 : _createSignals(klass.$gtype, gobjectSignals);
362 : :
363 : 6 : Object.defineProperty(klass, Symbol.hasInstance, {
364 : 3 : value: _interfaceInstanceOf,
365 : : });
366 : : }
367 : :
368 : 99 : function _checkProperties(klass) {
369 [ + + ]: 99 : if (!Object.hasOwn(klass, properties))
370 : 71 : return;
371 : :
372 [ + + ]: 79 : for (let pspec of Object.values(klass[properties]))
373 : 51 : _checkAccessors(klass.prototype, pspec, GObject);
374 : : }
375 : :
376 : 48 : function _init() {
377 : 48 : GObject = this;
378 : :
379 : 576 : function _makeDummyClass(obj, name, upperName, gtypeName, actual) {
380 : 576 : let gtype = GObject.type_from_name(gtypeName);
381 : 576 : obj[`TYPE_${upperName}`] = gtype;
382 : 576 : obj[name] = function (v) {
383 : 6 : return actual(v);
384 : : };
385 : 576 : obj[name].$gtype = gtype;
386 : : }
387 : :
388 : 48 : GObject.gtypeNameBasedOnJSPath = false;
389 : :
390 : 48 : _makeDummyClass(GObject, 'VoidType', 'NONE', 'void', function () {});
391 : 48 : _makeDummyClass(GObject, 'Char', 'CHAR', 'gchar', Number);
392 : 48 : _makeDummyClass(GObject, 'UChar', 'UCHAR', 'guchar', Number);
393 : 48 : _makeDummyClass(GObject, 'Unichar', 'UNICHAR', 'gint', String);
394 : :
395 : 48 : GObject.TYPE_BOOLEAN = GObject.type_from_name('gboolean');
396 : 48 : GObject.Boolean = Boolean;
397 : 48 : Boolean.$gtype = GObject.TYPE_BOOLEAN;
398 : :
399 : 48 : _makeDummyClass(GObject, 'Int', 'INT', 'gint', Number);
400 : 48 : _makeDummyClass(GObject, 'UInt', 'UINT', 'guint', Number);
401 : 48 : _makeDummyClass(GObject, 'Long', 'LONG', 'glong', Number);
402 : 48 : _makeDummyClass(GObject, 'ULong', 'ULONG', 'gulong', Number);
403 : 48 : _makeDummyClass(GObject, 'Int64', 'INT64', 'gint64', Number);
404 : 48 : _makeDummyClass(GObject, 'UInt64', 'UINT64', 'guint64', Number);
405 : :
406 : 48 : GObject.TYPE_ENUM = GObject.type_from_name('GEnum');
407 : 48 : GObject.TYPE_FLAGS = GObject.type_from_name('GFlags');
408 : :
409 : 48 : _makeDummyClass(GObject, 'Float', 'FLOAT', 'gfloat', Number);
410 : 48 : GObject.TYPE_DOUBLE = GObject.type_from_name('gdouble');
411 : 48 : GObject.Double = Number;
412 : 48 : Number.$gtype = GObject.TYPE_DOUBLE;
413 : :
414 : 48 : GObject.TYPE_STRING = GObject.type_from_name('gchararray');
415 : 48 : GObject.String = String;
416 : 48 : String.$gtype = GObject.TYPE_STRING;
417 : :
418 : 48 : GObject.TYPE_JSOBJECT = GObject.type_from_name('JSObject');
419 : 48 : GObject.JSObject = Object;
420 : 48 : Object.$gtype = GObject.TYPE_JSOBJECT;
421 : :
422 : 48 : GObject.TYPE_POINTER = GObject.type_from_name('gpointer');
423 : 48 : GObject.TYPE_BOXED = GObject.type_from_name('GBoxed');
424 : 48 : GObject.TYPE_PARAM = GObject.type_from_name('GParam');
425 : 48 : GObject.TYPE_INTERFACE = GObject.type_from_name('GInterface');
426 : 48 : GObject.TYPE_OBJECT = GObject.type_from_name('GObject');
427 : 48 : GObject.TYPE_VARIANT = GObject.type_from_name('GVariant');
428 : :
429 : 48 : _makeDummyClass(GObject, 'Type', 'GTYPE', 'GType', GObject.type_from_name);
430 : :
431 : 48 : GObject.ParamSpec.char = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
432 : 0 : return GObject.param_spec_char(name, nick, blurb, minimum, maximum, defaultValue, flags);
433 : : };
434 : :
435 : 48 : GObject.ParamSpec.uchar = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
436 : 0 : return GObject.param_spec_uchar(name, nick, blurb, minimum, maximum, defaultValue, flags);
437 : : };
438 : :
439 : 48 : GObject.ParamSpec.int = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
440 : 19 : return GObject.param_spec_int(name, nick, blurb, minimum, maximum, defaultValue, flags);
441 : : };
442 : :
443 : 48 : GObject.ParamSpec.uint = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
444 : 3 : return GObject.param_spec_uint(name, nick, blurb, minimum, maximum, defaultValue, flags);
445 : : };
446 : :
447 : 48 : GObject.ParamSpec.long = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
448 : 0 : return GObject.param_spec_long(name, nick, blurb, minimum, maximum, defaultValue, flags);
449 : : };
450 : :
451 : 48 : GObject.ParamSpec.ulong = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
452 : 0 : return GObject.param_spec_ulong(name, nick, blurb, minimum, maximum, defaultValue, flags);
453 : : };
454 : :
455 : 48 : GObject.ParamSpec.int64 = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
456 : 6 : return GObject.param_spec_int64(name, nick, blurb, minimum, maximum, defaultValue, flags);
457 : : };
458 : :
459 : 48 : GObject.ParamSpec.uint64 = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
460 : 5 : return GObject.param_spec_uint64(name, nick, blurb, minimum, maximum, defaultValue, flags);
461 : : };
462 : :
463 : 48 : GObject.ParamSpec.float = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
464 : 0 : return GObject.param_spec_float(name, nick, blurb, minimum, maximum, defaultValue, flags);
465 : : };
466 : :
467 : 48 : GObject.ParamSpec.boolean = function (name, nick, blurb, flags, defaultValue) {
468 : 4 : return GObject.param_spec_boolean(name, nick, blurb, defaultValue, flags);
469 : : };
470 : :
471 : 48 : GObject.ParamSpec.flags = function (name, nick, blurb, flags, flagsType, defaultValue) {
472 : 3 : return GObject.param_spec_flags(name, nick, blurb, flagsType, defaultValue, flags);
473 : : };
474 : :
475 : 48 : GObject.ParamSpec.enum = function (name, nick, blurb, flags, enumType, defaultValue) {
476 : 3 : return GObject.param_spec_enum(name, nick, blurb, enumType, defaultValue, flags);
477 : : };
478 : :
479 : 48 : GObject.ParamSpec.double = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
480 : 0 : return GObject.param_spec_double(name, nick, blurb, minimum, maximum, defaultValue, flags);
481 : : };
482 : :
483 : 48 : GObject.ParamSpec.string = function (name, nick, blurb, flags, defaultValue) {
484 : 27 : return GObject.param_spec_string(name, nick, blurb, defaultValue, flags);
485 : : };
486 : :
487 : 48 : GObject.ParamSpec.boxed = function (name, nick, blurb, flags, boxedType) {
488 : 0 : return GObject.param_spec_boxed(name, nick, blurb, boxedType, flags);
489 : : };
490 : :
491 : 48 : GObject.ParamSpec.object = function (name, nick, blurb, flags, objectType) {
492 : 5 : return GObject.param_spec_object(name, nick, blurb, objectType, flags);
493 : : };
494 : :
495 : 48 : GObject.ParamSpec.jsobject = function (name, nick, blurb, flags) {
496 : 5 : return GObject.param_spec_boxed(name, nick, blurb, Object.$gtype, flags);
497 : : };
498 : :
499 : 48 : GObject.ParamSpec.param = function (name, nick, blurb, flags, paramType) {
500 : 0 : return GObject.param_spec_param(name, nick, blurb, paramType, flags);
501 : : };
502 : :
503 : 48 : GObject.ParamSpec.override = Gi.override_property;
504 : :
505 : 96 : Object.defineProperties(GObject.ParamSpec.prototype, {
506 : 48 : 'name': {
507 : 48 : configurable: false,
508 : 48 : enumerable: false,
509 : 48 : get() {
510 : 112 : return this.get_name();
511 : : },
512 : : },
513 : 48 : '_nick': {
514 : 48 : configurable: false,
515 : 48 : enumerable: false,
516 : 48 : get() {
517 : 9 : return this.get_nick();
518 : : },
519 : : },
520 : 48 : 'nick': {
521 : 48 : configurable: false,
522 : 48 : enumerable: false,
523 : 48 : get() {
524 : 2 : return this.get_nick();
525 : : },
526 : : },
527 : 48 : '_blurb': {
528 : 48 : configurable: false,
529 : 48 : enumerable: false,
530 : 48 : get() {
531 : 9 : return this.get_blurb();
532 : : },
533 : : },
534 : 48 : 'blurb': {
535 : 48 : configurable: false,
536 : 48 : enumerable: false,
537 : 48 : get() {
538 : 2 : return this.get_blurb();
539 : : },
540 : : },
541 : 48 : 'default_value': {
542 : 48 : configurable: false,
543 : 48 : enumerable: false,
544 : 48 : get() {
545 : 12 : return this.get_default_value();
546 : : },
547 : : },
548 : 48 : 'flags': {
549 : 48 : configurable: false,
550 : 48 : enumerable: false,
551 : 48 : get() {
552 : 110 : return GjsPrivate.param_spec_get_flags(this);
553 : : },
554 : : },
555 : 48 : 'value_type': {
556 : 48 : configurable: false,
557 : 48 : enumerable: false,
558 : 48 : get() {
559 : 2 : return GjsPrivate.param_spec_get_value_type(this);
560 : : },
561 : : },
562 : 48 : 'owner_type': {
563 : 48 : configurable: false,
564 : 48 : enumerable: false,
565 : 48 : get() {
566 : 0 : return GjsPrivate.param_spec_get_owner_type(this);
567 : : },
568 : : },
569 : : });
570 : :
571 : 48 : let {GObjectMeta, GObjectInterface} = Legacy.defineGObjectLegacyObjects(GObject);
572 : 48 : GObject.Class = GObjectMeta;
573 : 48 : GObject.Interface = GObjectInterface;
574 : 48 : GObject.Object.prototype.__metaclass__ = GObject.Class;
575 : :
576 : : // For compatibility with Lang.Class... we need a _construct
577 : : // or the Lang.Class constructor will fail.
578 : 48 : GObject.Object.prototype._construct = function (...args) {
579 [ # # ][ # # ]: 0 : this._init(...args);
580 : 0 : return this;
581 : : };
582 : :
583 : 48 : GObject.registerClass = registerClass;
584 : :
585 [ + + ]: 59 : GObject.Object.new = function (gtype, props = {}) {
586 : 11 : const constructor = Gi.lookupConstructor(gtype);
587 : :
588 [ + - ]: 11 : if (!constructor)
589 : 0 : throw new Error(`Constructor for gtype ${gtype} not found`);
590 : 11 : return new constructor(props);
591 : 7 : };
592 : :
593 : 57 : GObject.Object.new_with_properties = function (gtype, names, values) {
594 [ + + ][ + + ]: 9 : if (!Array.isArray(names) || !Array.isArray(values))
595 : 3 : throw new Error('new_with_properties takes two arrays (names, values)');
596 [ + + ]: 6 : if (names.length !== values.length)
597 : 1 : throw new Error('Arrays passed to new_with_properties must be the same length');
598 : :
599 : 10 : const props = Object.fromEntries(names.map((name, ix) => [name, values[ix]]));
600 : 5 : return GObject.Object.new(gtype, props);
601 : 3 : };
602 : :
603 : 48 : GObject.Object._classInit = function (klass) {
604 : 99 : _checkProperties(klass);
605 : :
606 [ + + ]: 99 : if (_registerType in klass)
607 : 98 : klass[_registerType](klass);
608 : : else
609 : 1 : _resolveLegacyClassFunction(klass, _registerType)(klass);
610 : :
611 : 88 : return klass;
612 : : };
613 : :
614 : : // For backwards compatibility only. Use instanceof instead.
615 : 48 : GObject.Object.implements = function (iface) {
616 [ - + ]: 2 : if (iface.$gtype)
617 : 2 : return GObject.type_is_a(this, iface.$gtype);
618 : 0 : return false;
619 : : };
620 : :
621 : 96 : Object.defineProperty(GObject.Object, _registerType, {
622 : 48 : value: _registerGObjectType,
623 : 48 : writable: false,
624 : 48 : configurable: false,
625 : 48 : enumerable: false,
626 : : });
627 : :
628 : 96 : Object.defineProperty(GObject.Interface, _registerType, {
629 : 48 : value: _registerInterfaceType,
630 : 48 : writable: false,
631 : 48 : configurable: false,
632 : 48 : enumerable: false,
633 : : });
634 : :
635 : 48 : GObject.Interface._classInit = function (klass) {
636 [ - + ]: 3 : if (_registerType in klass)
637 : 3 : klass[_registerType](klass);
638 : : else
639 : 0 : _resolveLegacyClassFunction(klass, _registerType)(klass);
640 : :
641 : 3 : Object.getOwnPropertyNames(klass.prototype)
642 : 9 : .filter(key => key !== 'constructor')
643 : 3 : .concat(Object.getOwnPropertySymbols(klass.prototype))
644 : 9 : .forEach(key => {
645 : 6 : let descr = Object.getOwnPropertyDescriptor(klass.prototype, key);
646 : :
647 : : // Create wrappers on the interface object so that generics work (e.g.
648 : : // SomeInterface.some_function(this, blah) instead of
649 : : // SomeInterface.prototype.some_function.call(this, blah)
650 [ + + ]: 6 : if (typeof descr.value === 'function') {
651 : 3 : let interfaceProto = klass.prototype; // capture in closure
652 : 7 : klass[key] = function (thisObj, ...args) {
653 [ + - ]: 4 : return interfaceProto[key].call(thisObj, ...args);
654 : : };
655 : : }
656 : :
657 : 6 : Object.defineProperty(klass.prototype, key, descr);
658 : : });
659 : :
660 : 3 : return klass;
661 : : };
662 : :
663 : : /**
664 : : * Use this to signify a function that must be overridden in an
665 : : * implementation of the interface.
666 : : */
667 [ - + ]: 49 : GObject.NotImplementedError = class NotImplementedError extends Error {
668 : 48 : get name() {
669 : 0 : return 'NotImplementedError';
670 : : }
671 : : };
672 : :
673 : : // These will be copied in the Gtk overrides
674 : : // Use __X__ syntax to indicate these variables should not be used publicly.
675 : :
676 : 48 : GObject.__gtkCssName__ = _gtkCssName;
677 : 48 : GObject.__gtkTemplate__ = _gtkTemplate;
678 : 48 : GObject.__gtkChildren__ = _gtkChildren;
679 : 48 : GObject.__gtkInternalChildren__ = _gtkInternalChildren;
680 : :
681 : : // Expose GObject static properties for ES6 classes
682 : :
683 : 48 : GObject.GTypeName = GTypeName;
684 : 48 : GObject.requires = requires;
685 : 48 : GObject.interfaces = interfaces;
686 : 48 : GObject.properties = properties;
687 : 48 : GObject.signals = signals;
688 : :
689 : : // Replacement for non-introspectable g_object_set()
690 : 48 : GObject.Object.prototype.set = function (params) {
691 : 1 : Object.assign(this, params);
692 : : };
693 : :
694 : 49 : GObject.Object.prototype.bind_property_full = function (...args) {
695 [ + + ]: 1 : return GjsPrivate.g_object_bind_property_full(this, ...args);
696 : : };
697 : :
698 [ - + ]: 48 : if (GObject.BindingGroup !== undefined) {
699 : 49 : GObject.BindingGroup.prototype.bind_full = function (...args) {
700 [ + + ]: 1 : return GjsPrivate.g_binding_group_bind_full(this, ...args);
701 : : };
702 : : }
703 : :
704 : : // fake enum for signal accumulators, keep in sync with gi/object.c
705 : 48 : GObject.AccumulatorType = {
706 : 48 : NONE: 0,
707 : 48 : FIRST_WINS: 1,
708 : 48 : TRUE_HANDLED: 2,
709 : : };
710 : :
711 : 48 : GObject.Object.prototype.disconnect = function (id) {
712 : 100 : return GObject.signal_handler_disconnect(this, id);
713 : : };
714 : 48 : GObject.Object.prototype.block_signal_handler = function (id) {
715 : 0 : return GObject.signal_handler_block(this, id);
716 : : };
717 : 48 : GObject.Object.prototype.unblock_signal_handler = function (id) {
718 : 0 : return GObject.signal_handler_unblock(this, id);
719 : : };
720 : 48 : GObject.Object.prototype.stop_emission_by_name = function (detailedName) {
721 : 0 : return GObject.signal_stop_emission_by_name(this, detailedName);
722 : : };
723 : :
724 : : // A simple workaround if you have a class with .connect, .disconnect or .emit
725 : : // methods (such as Gio.Socket.connect or NMClient.Device.disconnect)
726 : : // The original g_signal_* functions are not introspectable anyway, because
727 : : // we need our own handling of signal argument marshalling
728 : 48 : GObject.signal_connect = function (object, name, handler) {
729 : 4 : return GObject.Object.prototype.connect.call(object, name, handler);
730 : : };
731 : 48 : GObject.signal_connect_after = function (object, name, handler) {
732 : 0 : return GObject.Object.prototype.connect_after.call(object, name, handler);
733 : : };
734 : 52 : GObject.signal_emit_by_name = function (object, ...nameAndArgs) {
735 : 4 : return GObject.Object.prototype.emit.apply(object, nameAndArgs);
736 : : };
737 : :
738 : : // Replacements for signal_handler_find() and similar functions, which can't
739 : : // work normally since we connect private closures
740 : 48 : GObject._real_signal_handler_find = GObject.signal_handler_find;
741 : 48 : GObject._real_signal_handlers_block_matched = GObject.signal_handlers_block_matched;
742 : 48 : GObject._real_signal_handlers_unblock_matched = GObject.signal_handlers_unblock_matched;
743 : 48 : GObject._real_signal_handlers_disconnect_matched = GObject.signal_handlers_disconnect_matched;
744 : :
745 : : /**
746 : : * Finds the first signal handler that matches certain selection criteria.
747 : : * The criteria are passed as properties of a match object.
748 : : * The match object has to be non-empty for successful matches.
749 : : * If no handler was found, a falsy value is returned.
750 : : *
751 : : * @function
752 : : * @param {GObject.Object} instance - the instance owning the signal handler
753 : : * to be found.
754 : : * @param {object} match - a properties object indicating whether to match
755 : : * by signal ID, detail, or callback function.
756 : : * @param {string} [match.signalId] - signal the handler has to be connected
757 : : * to.
758 : : * @param {string} [match.detail] - signal detail the handler has to be
759 : : * connected to.
760 : : * @param {Function} [match.func] - the callback function the handler will
761 : : * invoke.
762 : : * @returns {number | bigint | object | null} A valid non-0 signal handler ID for
763 : : * a successful match.
764 : : */
765 : 48 : GObject.signal_handler_find = function (instance, match) {
766 : : // For backwards compatibility
767 [ + - ]: 12 : if (arguments.length === 7)
768 : : // eslint-disable-next-line prefer-rest-params
769 [ # # ][ # # ]: 0 : return GObject._real_signal_handler_find(...arguments);
770 : 12 : return instance[Gi.signal_find_symbol](match);
771 : : };
772 : : /**
773 : : * Blocks all handlers on an instance that match certain selection criteria.
774 : : * The criteria are passed as properties of a match object.
775 : : * The match object has to have at least `func` for successful matches.
776 : : * If no handlers were found, 0 is returned, the number of blocked handlers
777 : : * otherwise.
778 : : *
779 : : * @function
780 : : * @param {GObject.Object} instance - the instance owning the signal handler
781 : : * to be found.
782 : : * @param {object} match - a properties object indicating whether to match
783 : : * by signal ID, detail, or callback function.
784 : : * @param {string} [match.signalId] - signal the handler has to be connected
785 : : * to.
786 : : * @param {string} [match.detail] - signal detail the handler has to be
787 : : * connected to.
788 : : * @param {Function} match.func - the callback function the handler will
789 : : * invoke.
790 : : * @returns {number} The number of handlers that matched.
791 : : */
792 : 48 : GObject.signal_handlers_block_matched = function (instance, match) {
793 : : // For backwards compatibility
794 [ + - ]: 3 : if (arguments.length === 7)
795 : : // eslint-disable-next-line prefer-rest-params
796 [ # # ][ # # ]: 0 : return GObject._real_signal_handlers_block_matched(...arguments);
797 : 3 : return instance[Gi.signals_block_symbol](match);
798 : : };
799 : : /**
800 : : * Unblocks all handlers on an instance that match certain selection
801 : : * criteria.
802 : : * The criteria are passed as properties of a match object.
803 : : * The match object has to have at least `func` for successful matches.
804 : : * If no handlers were found, 0 is returned, the number of unblocked
805 : : * handlers otherwise.
806 : : * The match criteria should not apply to any handlers that are not
807 : : * currently blocked.
808 : : *
809 : : * @function
810 : : * @param {GObject.Object} instance - the instance owning the signal handler
811 : : * to be found.
812 : : * @param {object} match - a properties object indicating whether to match
813 : : * by signal ID, detail, or callback function.
814 : : * @param {string} [match.signalId] - signal the handler has to be connected
815 : : * to.
816 : : * @param {string} [match.detail] - signal detail the handler has to be
817 : : * connected to.
818 : : * @param {Function} match.func - the callback function the handler will
819 : : * invoke.
820 : : * @returns {number} The number of handlers that matched.
821 : : */
822 : 48 : GObject.signal_handlers_unblock_matched = function (instance, match) {
823 : : // For backwards compatibility
824 [ + - ]: 3 : if (arguments.length === 7)
825 : : // eslint-disable-next-line prefer-rest-params
826 [ # # ][ # # ]: 0 : return GObject._real_signal_handlers_unblock_matched(...arguments);
827 : 3 : return instance[Gi.signals_unblock_symbol](match);
828 : : };
829 : : /**
830 : : * Disconnects all handlers on an instance that match certain selection
831 : : * criteria.
832 : : * The criteria are passed as properties of a match object.
833 : : * The match object has to have at least `func` for successful matches.
834 : : * If no handlers were found, 0 is returned, the number of disconnected
835 : : * handlers otherwise.
836 : : *
837 : : * @function
838 : : * @param {GObject.Object} instance - the instance owning the signal handler
839 : : * to be found.
840 : : * @param {object} match - a properties object indicating whether to match
841 : : * by signal ID, detail, or callback function.
842 : : * @param {string} [match.signalId] - signal the handler has to be connected
843 : : * to.
844 : : * @param {string} [match.detail] - signal detail the handler has to be
845 : : * connected to.
846 : : * @param {Function} match.func - the callback function the handler will
847 : : * invoke.
848 : : * @returns {number} The number of handlers that matched.
849 : : */
850 : 48 : GObject.signal_handlers_disconnect_matched = function (instance, match) {
851 : : // For backwards compatibility
852 [ + - ]: 3 : if (arguments.length === 7)
853 : : // eslint-disable-next-line prefer-rest-params
854 [ # # ][ # # ]: 0 : return GObject._real_signal_handlers_disconnect_matched(...arguments);
855 : 3 : return instance[Gi.signals_disconnect_symbol](match);
856 : : };
857 : :
858 : : // Also match the macros used in C APIs, even though they're not introspected
859 : :
860 : : /**
861 : : * Blocks all handlers on an instance that match `func`.
862 : : *
863 : : * @function
864 : : * @param {GObject.Object} instance - the instance to block handlers from.
865 : : * @param {Function} func - the callback function the handler will invoke.
866 : : * @returns {number} The number of handlers that matched.
867 : : */
868 : 48 : GObject.signal_handlers_block_by_func = function (instance, func) {
869 : 3 : return instance[Gi.signals_block_symbol]({func});
870 : : };
871 : : /**
872 : : * Unblocks all handlers on an instance that match `func`.
873 : : *
874 : : * @function
875 : : * @param {GObject.Object} instance - the instance to unblock handlers from.
876 : : * @param {Function} func - the callback function the handler will invoke.
877 : : * @returns {number} The number of handlers that matched.
878 : : */
879 : 48 : GObject.signal_handlers_unblock_by_func = function (instance, func) {
880 : 3 : return instance[Gi.signals_unblock_symbol]({func});
881 : : };
882 : : /**
883 : : * Disconnects all handlers on an instance that match `func`.
884 : : *
885 : : * @function
886 : : * @param {GObject.Object} instance - the instance to remove handlers from.
887 : : * @param {Function} func - the callback function the handler will invoke.
888 : : * @returns {number} The number of handlers that matched.
889 : : */
890 : 48 : GObject.signal_handlers_disconnect_by_func = function (instance, func) {
891 : 3 : return instance[Gi.signals_disconnect_symbol]({func});
892 : : };
893 : 48 : GObject.signal_handlers_disconnect_by_data = function () {
894 : 1 : throw new Error('GObject.signal_handlers_disconnect_by_data() is not \
895 : : introspectable. Use GObject.signal_handlers_disconnect_by_func() instead.');
896 : : };
897 : :
898 : 5 : function unsupportedDataMethod() {
899 : 5 : throw new Error('Data access methods are unsupported. Use normal JS properties instead.');
900 : : }
901 : 48 : GObject.Object.prototype.get_data = unsupportedDataMethod;
902 : 48 : GObject.Object.prototype.get_qdata = unsupportedDataMethod;
903 : 48 : GObject.Object.prototype.set_data = unsupportedDataMethod;
904 : 48 : GObject.Object.prototype.steal_data = unsupportedDataMethod;
905 : 48 : GObject.Object.prototype.steal_qdata = unsupportedDataMethod;
906 : :
907 : 4 : function unsupportedRefcountingMethod() {
908 : 4 : throw new Error("Don't modify an object's reference count in JS.");
909 : : }
910 : 48 : GObject.Object.prototype.force_floating = unsupportedRefcountingMethod;
911 : 48 : GObject.Object.prototype.ref = unsupportedRefcountingMethod;
912 : 48 : GObject.Object.prototype.ref_sink = unsupportedRefcountingMethod;
913 : 48 : GObject.Object.prototype.unref = unsupportedRefcountingMethod;
914 : :
915 : 48 : const gValConstructor = GObject.Value;
916 : 385 : GObject.Value = function (...args) {
917 : 337 : const v = new gValConstructor();
918 [ + + ]: 337 : if (args.length !== 2)
919 : 256 : return v;
920 : :
921 : 81 : const type = args[0], val = args[1];
922 : 81 : v.init(type);
923 : 81 : switch (v.g_type) {
924 [ + + ]: 81 : case GObject.TYPE_BOOLEAN:
925 : 6 : v.set_boolean(val);
926 : : break;
927 [ - + ]: 75 : case GObject.TYPE_BOXED:
928 : 0 : v.set_boxed(val);
929 : : break;
930 [ + + ]: 75 : case GObject.TYPE_CHAR:
931 : 6 : v.set_schar(val);
932 : : break;
933 [ + + ]: 69 : case GObject.TYPE_DOUBLE:
934 : 6 : v.set_double(val);
935 : : break;
936 [ + + ]: 63 : case GObject.TYPE_FLOAT:
937 : 3 : v.set_float(val);
938 : : break;
939 [ + + ]: 60 : case GObject.TYPE_GTYPE:
940 : 3 : v.set_gtype(val);
941 : : break;
942 [ + + ]: 57 : case GObject.TYPE_INT:
943 : 3 : v.set_int(val);
944 : : break;
945 [ + + ]: 54 : case GObject.TYPE_INT64:
946 : 3 : v.set_int64(val);
947 : : break;
948 [ + + ]: 51 : case GObject.TYPE_LONG:
949 : 3 : v.set_long(val);
950 : : break;
951 [ + + ]: 48 : case GObject.TYPE_OBJECT:
952 : 3 : v.set_object(val);
953 : : break;
954 [ + + ]: 45 : case GObject.TYPE_PARAM:
955 : 3 : v.set_param(val);
956 : : break;
957 [ + + ]: 42 : case GObject.TYPE_STRING:
958 : 6 : v.set_string(val);
959 : : break;
960 [ + + ]: 36 : case GObject.TYPE_UCHAR:
961 : 3 : v.set_uchar(val);
962 : : break;
963 [ + + ]: 33 : case GObject.TYPE_UINT:
964 : 3 : v.set_uint(val);
965 : : break;
966 [ + + ]: 30 : case GObject.TYPE_UINT64:
967 : 3 : v.set_uint64(val);
968 : : break;
969 [ + + ]: 27 : case GObject.TYPE_ULONG:
970 : 3 : v.set_ulong(val);
971 : : break;
972 [ + + ]: 24 : case GObject.TYPE_VARIANT:
973 : 3 : v.set_variant(val);
974 : : break;
975 : : // case TYPE_POINTER omitted
976 : : default:
977 [ + - ]: 21 : if (GObject.type_is_a(v.g_type, GObject.TYPE_FLAGS))
978 : 0 : v.set_flag(val);
979 [ + + ]: 21 : else if (GObject.type_is_a(v.g_type, GObject.TYPE_ENUM))
980 : 6 : v.set_enum(val);
981 [ + + ]: 15 : else if (GObject.type_is_a(v.g_type, GObject.TYPE_BOXED))
982 : 9 : v.set_boxed(val);
983 [ + + ]: 6 : else if (GObject.type_is_a(v.g_type, GObject.TYPE_OBJECT))
984 : 3 : v.set_object(val);
985 : : else
986 : 3 : throw new TypeError(`Invalid type argument ${type} to GObject.Value constructor!`);
987 : : }
988 : :
989 : 78 : return v;
990 : 334 : };
991 : 48 : GObject.Value.prototype = gValConstructor.prototype;
992 : 48 : GObject.Value.prototype.constructor = GObject.Value;
993 : 48 : GObject.Value.$gtype = gValConstructor.$gtype;
994 [ - + ][ - + ]: 144 : Object.entries(gValConstructor).forEach(([k, v]) => {
[ - + ][ # # ]
[ # # ][ # # ]
[ # # ]
995 : 96 : GObject.Value[k] = v;
996 : : });
997 : : }
|