@@ -76,6 +76,105 @@ const IteratorPrototype = Object.create(utils.IteratorPrototype, {
7676 }
7777});` ;
7878 }
79+ }
80+
81+ Interface . prototype . generateNamedPropertiesObject = function ( ) {
82+ if ( ! utils . isGlobal ( this . idl ) ) {
83+ return ;
84+ }
85+
86+ let overrideBuiltins = false ;
87+ let parent = this . idl ;
88+ while ( parent ) {
89+ if ( utils . getExtAttr ( parent . extAttrs , 'OverrideBuiltins' ) ) {
90+ overrideBuiltins = true ;
91+ }
92+
93+ const members = parent . members . filter ( ( m ) =>
94+ m . type === 'attribute' && utils . getExtAttr ( m . extAttrs , 'Unforgeable' )
95+ ) ;
96+ const parentInterface = this . opts . interfaces [ parent . inheritance ] ;
97+ parent = parentInterface && parentInterface . idl ;
98+ }
99+
100+ this . str += `
101+ function namedPropertiesIsVisible(P, O) {
102+ if (!true) { // is supported
103+ return false;
104+ }
105+
106+ if (Object.getOwnPropertyDescriptor(O, P)) {
107+ return false;
108+ }
109+ ` ;
110+
111+ if ( overrideBuiltins ) {
112+ this . str += `
113+ return true;` ;
114+ }
115+
116+ this . str += `
117+ let prototype = Object.getPrototypeOf(O);
118+ while (prototype) {
119+ if (prototype.constructor.name.endsWith("PropertiesConstructor") && Object.getOwnPropertyDescriptor(prototype, P)) {
120+ return false;
121+ }
122+ prototype = Object.getPrototypeOf(prototype);
123+ }` ;
124+ this . str += `
125+ return true;
126+ }` ;
127+
128+ this . str += `var ${ this . name } PropertiesConstructor = function () {
129+ throw new TypeError("Illegal constructor");
130+ }\n` ;
131+
132+ if ( this . idl . inheritance ) {
133+ this . str += `${ this . name } PropertiesConstructor.prototype = Object.create(${ this . idl . inheritance } .interface.prototype);
134+ ${ this . name } PropertiesConstructor.prototype.constructor = ${ this . name } PropertiesConstructor;\n`;
135+ } else if ( utils . getExtAttr ( this . idl . extAttrs , 'LegacyArrayClass' ) ) {
136+ this . str += `${ this . name } PropertiesConstructor.prototype = Object.create(Array.prototype);
137+ ${ this . name } PropertiesConstructor.prototype.constructor = ${ this . name } PropertiesConstructor;\n`;
138+ }
139+
140+ const getter = this . idl . members . filter ( ( m ) => m . getter ) [ 0 ] . name ;
141+ this . str += `
142+ const ${ this . name } Properties = new Proxy(${ this . name } PropertiesConstructor.prototype, {
143+ defineProperty() {
144+ return false;
145+ },
146+ deleteProperty() {
147+ return false;
148+ },
149+ getOwnPropertyDescriptor(target, key) {
150+ if (namedPropertiesIsVisible(key, target)) { // is visible
151+ const value = target${ getter ? "." + getter : "[utils.anonymousGetter]" } (key);
152+ return {
153+ value,
154+ enumerable: true,
155+ writable: true,
156+ configurable: true
157+ };
158+ } else {
159+ return Object.getOwnPropertyDescriptor(target, key);
160+ }
161+ },
162+ get(target, key) {
163+ if (namedPropertiesIsVisible(key, target)) { // is visible
164+ const value = target${ getter ? "." + getter : "[utils.anonymousGetter]" } (key);
165+ return value;
166+ } else {
167+ return target[key];
168+ }
169+ },
170+ has(target, key) {
171+ if (namedPropertiesIsVisible(key, target)) { // is visible
172+ return true;
173+ } else {
174+ return key in target;
175+ }
176+ }
177+ });\n\n` ;
79178} ;
80179
81180Interface . prototype . generateConstructor = function ( ) {
@@ -116,9 +215,11 @@ Interface.prototype.generateConstructor = function () {
116215}\n` ;
117216 }
118217
119- if ( this . idl . inheritance ) {
218+ if ( this . idl . inheritance && ! utils . isGlobal ( this . idl ) ) {
120219 this . str += `${ this . name } .prototype = Object.create(${ this . idl . inheritance } .interface.prototype);
121220${ this . name } .prototype.constructor = ${ this . name } ;\n`;
221+ } else if ( utils . isGlobal ( this . idl ) ) {
222+ this . str += `Object.setPrototypeOf(${ this . name } .prototype, ${ this . name } Properties);\n` ;
122223 }
123224} ;
124225
@@ -406,6 +507,7 @@ module.exports = {
406507 defaultPrivateData = defaultPrivateData === undefined ? {} : defaultPrivateData;\n\n` ;
407508 }
408509
510+ this . generateNamedPropertiesObject ( ) ;
409511 this . generateConstructor ( ) ;
410512 this . generateMixins ( ) ;
411513
0 commit comments