@gjsify/adwaita-core 0.64.1-next.243 → 0.64.1-next.244

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- import"../_virtual/_rolldown/runtime.js";const e=[`error`,`bytes`,`filter`,`dialog`,`open`,`save`,`stream`,`cancel`,`promisify`,`refusal`],bytesOf=e=>Uint8Array.from(e,e=>e.charCodeAt(0)),textOf=e=>String.fromCharCode(...e??[]);function throws(e){try{return e(),!1}catch{return!0}}async function refused(e){try{return await e(),!1}catch{return!0}}async function rejection(e,t){try{return await t(),`resolved`}catch(t){let{GLib:n,Gio:r,Gtk:i}=e,a=t;return{glibError:t instanceof n.Error,dismissed:a.matches?.(i.DialogError,i.DialogError.DISMISSED),failed:a.matches?.(i.DialogError,i.DialogError.FAILED),cancelled:a.matches?.(r.IOErrorEnum,r.IOErrorEnum.CANCELLED),closed:a.matches?.(r.IOErrorEnum,r.IOErrorEnum.CLOSED),pending:a.matches?.(r.IOErrorEnum,r.IOErrorEnum.PENDING)}}}function filterStore({Gio:e,Gtk:t}){let n=new e.ListStore({item_type:t.FileFilter.$gtype}),r=t.FileFilter.new();r.set_name(`Assembly Files`),r.add_pattern(`*.asm`),r.add_pattern(`*.s`);let i=t.FileFilter.new();return i.set_name(`All Files`),i.add_pattern(`*`),n.append(r),n.append(i),n}async function pickToOpen(e,t,n){return e.script({basename:t,contents:bytesOf(n)}),new e.Gtk.FileDialog({modal:!0,filters:filterStore(e)}).open(null,null)}async function pickToSave(e,t){return e.script({basename:t}),new e.Gtk.FileDialog({initial_name:t}).save(null,null)}function replaceContents(e,t,n){return new Promise((r,i)=>{t.replace_contents_async(bytesOf(n),null,!1,e.Gio.FileCreateFlags.NONE,null,(e,n)=>{try{r(t.replace_contents_finish(n))}catch(e){i(e)}})})}const t=[{row:`error`,rule:`new GLib.Error(domain, code, message) reads back its fields and matches its own domain and code only`,observe:({GLib:e,Gio:t,Gtk:n})=>{let r=new e.Error(n.DialogError,n.DialogError.DISMISSED,`gone`);return[r instanceof e.Error,typeof r.domain,r.code,r.message,r.matches(n.DialogError,n.DialogError.DISMISSED),r.matches(n.DialogError,n.DialogError.FAILED),r.matches(t.IOErrorEnum,n.DialogError.DISMISSED),new e.Error(r.domain,1,`y`).matches(n.DialogError,1)]},shows:[!0,`number`,2,`gone`,!0,!1,!1,!0]},{row:`error`,rule:`a GLib.Error names its domain when printed and is not a JS Error`,observe:({GLib:e,Gtk:t})=>{let n=new e.Error(t.DialogError,t.DialogError.FAILED,`x`);return[String(n),n instanceof Error]},shows:[`Gtk.DialogError: x`,!1]},{row:`error`,rule:`the enum members the subset raises have GIO and GTK values`,observe:({Gio:e,Gtk:t})=>[t.DialogError.FAILED,t.DialogError.CANCELLED,t.DialogError.DISMISSED,e.IOErrorEnum.CLOSED,e.IOErrorEnum.CANCELLED,e.IOErrorEnum.PENDING,e.FileCreateFlags.NONE],shows:[0,1,2,18,19,20,0]},{row:`bytes`,rule:`GLib.Bytes copies its input; get_size and get_data give it back, each read a copy`,observe:({GLib:e})=>{let t=Uint8Array.of(1,2,3),n=new e.Bytes(t);t[0]=9;let r=n.get_data();return r[1]=7,[n.get_size(),Array.from(n.get_data()),n.get_data()instanceof Uint8Array]},shows:[3,[1,2,3],!0]},{row:`filter`,rule:`a FileFilter has no name until set, and a ListStore of FileFilter.$gtype holds what is appended`,observe:e=>{let t=e.Gtk.FileFilter.new(),n=t.get_name();return t.set_name(`A`),[n,t.get_name(),t.name,filterStore(e).get_n_items()]},shows:[null,`A`,`A`,2]},{row:`filter`,rule:`the filters of the dialog reach the picker: *.asm and *.s in one, * in the other`,async observe(e){return await pickToOpen(e,`f.asm`,``),e.pickerFilters()},shows:[[`*.asm`,`*.s`],[`*`]]},{row:`dialog`,rule:`a new FileDialog is modal with no title, initial name or filters`,observe:({Gtk:e})=>{let t=new e.FileDialog;return[t.modal,t.title,t.initial_name,t.filters,t.default_filter]},shows:[!0,null,null,null,null]},{row:`dialog`,rule:`the construct properties read back, the filters store by identity`,observe:e=>{let t=filterStore(e),n=new e.Gtk.FileDialog({title:`t`,modal:!0,filters:t,initial_name:`a.asm`});return[n.title,n.modal,n.initial_name,n.filters===t]},shows:[`t`,!0,`a.asm`,!0]},{row:`open`,rule:`open resolves a File with the picked basename whose load_contents_async gives the bytes`,async observe(e){let t=await pickToOpen(e,`prog.asm`,`LDA #$01`),[n]=await t.load_contents_async(null);return[t.get_basename(),textOf(n),n instanceof Uint8Array]},shows:[`prog.asm`,`LDA #$01`,!0]},{row:`open`,rule:`the callback forms hand back the source and a leading true; the promise form drops it`,async observe(e){let t=await pickToOpen(e,`cb.asm`,`x`),n=await new Promise(e=>{t.load_contents_async(null,(n,r)=>{let i=n.load_contents_finish(r);e([n===t,i.length,i[0],textOf(i[1])])})}),r=await t.load_contents_async(null);return[...n,r.length,textOf(r[0])]},shows:[!0,3,!0,`x`,2,`x`]},{row:`open`,rule:`open in the callback form resolves through open_finish with the dialog as source`,async observe(e){e.script({basename:`c.s`,contents:bytesOf(``)});let t=new e.Gtk.FileDialog;return new Promise(e=>{t.open(null,null,(n,r)=>{e([n===t,n.open_finish(r).get_basename()])})})},shows:[!0,`c.s`]},{row:`open`,rule:`a picked file has no local path`,holds:`subset`,async observe(e){return(await pickToOpen(e,`p.asm`,``)).get_path()},shows:null},{row:`save`,rule:`save, replace_contents_async, load_contents_async round-trip; a second replace overwrites`,async observe(e){let t=await pickToSave(e,`out.asm`),n=await replaceContents(e,t,`first version`),[r]=await t.load_contents_async(null);await replaceContents(e,t,`short`);let[i]=await t.load_contents_async(null);return[t.get_basename(),n.length,n[0],textOf(r),textOf(i)]},shows:[`out.asm`,2,!0,`first version`,`short`]},{row:`stream`,rule:`replace_async gives a FileOutputStream; write_bytes_async counts, close_async is true, bytes land`,async observe(e){let{GLib:t,Gio:n}=e,r=await pickToSave(e,`stream.asm`);await replaceContents(e,r,`old content that is longer`);let i=await r.replace_async(null,!1,n.FileCreateFlags.NONE,t.PRIORITY_DEFAULT,null),a=await i.write_bytes_async(new t.Bytes(bytesOf(`AB`)),0,null),o=await i.write_bytes_async(new t.Bytes(bytesOf(`CDE`)),0,null),s=await i.close_async(0,null),[c]=await r.load_contents_async(null);return[i instanceof n.FileOutputStream,a,o,s,textOf(c)]},shows:[!0,2,3,!0,`ABCDE`]},{row:`stream`,rule:`a write after close rejects with a GLib.Error, IOErrorEnum.CLOSED`,async observe(e){let{GLib:t,Gio:n}=e,r=await(await pickToSave(e,`closed.asm`)).replace_async(null,!1,n.FileCreateFlags.NONE,0,null);return await r.close_async(0,null),rejection(e,()=>r.write_bytes_async(new t.Bytes(bytesOf(`x`)),0,null))},shows:{glibError:!0,dismissed:!1,failed:!1,cancelled:!1,closed:!0,pending:!1}},{row:`stream`,rule:`a second write while one is pending rejects with IOErrorEnum.PENDING`,async observe(e){let{GLib:t,Gio:n}=e,r=await(await pickToSave(e,`pending.asm`)).replace_async(null,!1,n.FileCreateFlags.NONE,0,null),i=r.write_bytes_async(new t.Bytes(bytesOf(`a`)),0,null),a=await rejection(e,()=>r.write_bytes_async(new t.Bytes(bytesOf(`b`)),0,null));return await i,await r.close_async(0,null),a},shows:{glibError:!0,dismissed:!1,failed:!1,cancelled:!1,closed:!1,pending:!0}},{row:`cancel`,rule:`a dismissed dialog rejects with a GLib.Error matching Gtk.DialogError.DISMISSED only`,async observe(e){return e.script(null),rejection(e,()=>new e.Gtk.FileDialog().open(null,null))},shows:{glibError:!0,dismissed:!0,failed:!1,cancelled:!1,closed:!1,pending:!1}},{row:`cancel`,rule:`load_contents_async with a cancelled cancellable rejects with IOErrorEnum.CANCELLED`,async observe(e){let t=await pickToOpen(e,`c.asm`,`x`);return rejection(e,()=>t.load_contents_async(e.cancelled()))},shows:{glibError:!0,dismissed:!1,failed:!1,cancelled:!0,closed:!1,pending:!1}},{row:`cancel`,rule:`open with a cancelled cancellable rejects with IOErrorEnum.CANCELLED before the picker opens`,holds:`subset`,async observe(e){return e.script({basename:`never.asm`}),rejection(e,()=>new e.Gtk.FileDialog().open(null,e.cancelled()))},shows:{glibError:!0,dismissed:!1,failed:!1,cancelled:!0,closed:!1,pending:!1}},{row:`promisify`,rule:`Gio._promisify throws at the call when the async or the finish method is missing`,observe:({Gio:e})=>[throws(()=>e._promisify(e.File.prototype,`nope_async`,`nope_finish`)),throws(()=>e._promisify(e.File.prototype,`load_contents_async`,`nope_finish`))],shows:[!0,!0]},{row:`refusal`,rule:`what ADR 0100 refuses throws by name`,holds:`subset`,async observe(e){let{GLib:t,Gio:n,Gtk:r}=e,i=await pickToSave(e,`r.asm`),a=await i.replace_async(null,!1,n.FileCreateFlags.NONE,0,null),o=new r.FileDialog,s=r.FileFilter.new(),call=(e,t)=>()=>e[t]();return{modalFalse:throws(()=>new r.FileDialog({modal:!1})),initialFolder:throws(()=>new r.FileDialog({initial_folder:null})),acceptLabel:throws(()=>new r.FileDialog({accept_label:`Go`})),openMultiple:throws(call(o,`open_multiple`)),selectFolder:throws(call(o,`select_folder`)),otherGlob:throws(()=>s.add_pattern(`a*.s`)),newForPath:throws(()=>n.File.new_for_path(`/tmp/x`)),newForUri:throws(()=>n.File.new_for_uri(`file:///tmp/x`)),getParent:throws(()=>i.get_parent()),queryExists:throws(()=>i.query_exists(null)),etag:await refused(()=>i.replace_async(`e`,!1,n.FileCreateFlags.NONE,0,null)),makeBackup:await refused(()=>i.replace_async(null,!0,n.FileCreateFlags.NONE,0,null)),flags:await refused(()=>i.replace_async(null,!1,1,0,null)),bytesSlice:throws(call(new t.Bytes(bytesOf(`x`)),`slice`)),streamWrite:throws(call(a,`write`)),streamFlush:throws(call(a,`flush`)),newLiteral:throws(call(t.Error,`new_literal`))}},shows:{modalFalse:!0,initialFolder:!0,acceptLabel:!0,openMultiple:!0,selectFolder:!0,otherGlob:!0,newForPath:!0,newForUri:!0,getParent:!0,queryExists:!0,etag:!0,makeBackup:!0,flags:!0,bytesSlice:!0,streamWrite:!0,streamFlush:!0,newLiteral:!0}}];function promisifyFileChooser({Gio:e,Gtk:t}){e._promisify(e.OutputStream.prototype,`write_bytes_async`,`write_bytes_finish`),e._promisify(e.OutputStream.prototype,`close_async`,`close_finish`),e._promisify(e.File.prototype,`load_contents_async`,`load_contents_finish`),e._promisify(e.File.prototype,`replace_async`,`replace_finish`),e._promisify(t.FileDialog.prototype,`open`,`open_finish`),e._promisify(t.FileDialog.prototype,`save`,`save_finish`)}async function driveFileChooserVectors(e,n,r=t){let{describe:i,it:a,expect:o}=n;promisifyFileChooser(e),await i(`${e.name}: Gtk.FileDialog and Gio.File`,async()=>{for(let t of r)t.holds===`subset`&&e.isOracle||await a(`${t.row}: ${t.rule}`,async()=>{let n=await t.observe(e);o(JSON.stringify(n)).toBe(JSON.stringify(t.shows))})})}export{e as FILE_CHOOSER_ROWS,t as FILE_CHOOSER_VECTORS,driveFileChooserVectors,promisifyFileChooser};
1
+ import"../_virtual/_rolldown/runtime.js";const e=[`error`,`bytes`,`filter`,`dialog`,`open`,`save`,`stream`,`cancel`,`promisify`,`refusal`],bytesOf=e=>Uint8Array.from(e,e=>e.charCodeAt(0)),textOf=e=>String.fromCharCode(...e??[]);function throws(e){try{return e(),!1}catch{return!0}}async function refused(e){try{return await e(),!1}catch{return!0}}async function rejection(e,t){try{return await t(),`resolved`}catch(t){let{GLib:n,Gio:r,Gtk:i}=e,a=t;return{glibError:t instanceof n.Error,dismissed:a.matches?.(i.DialogError,i.DialogError.DISMISSED),failed:a.matches?.(i.DialogError,i.DialogError.FAILED),cancelled:a.matches?.(r.IOErrorEnum,r.IOErrorEnum.CANCELLED),closed:a.matches?.(r.IOErrorEnum,r.IOErrorEnum.CLOSED),pending:a.matches?.(r.IOErrorEnum,r.IOErrorEnum.PENDING)}}}function filterStore({Gio:e,Gtk:t}){let n=new e.ListStore({item_type:t.FileFilter.$gtype}),r=t.FileFilter.new();r.set_name(`Assembly Files`),r.add_pattern(`*.asm`),r.add_pattern(`*.s`);let i=t.FileFilter.new();return i.set_name(`All Files`),i.add_pattern(`*`),n.append(r),n.append(i),n}async function pickToOpen(e,t,n){return e.script({basename:t,contents:bytesOf(n)}),new e.Gtk.FileDialog({modal:!0,filters:filterStore(e)}).open(null,null)}async function pickToSave(e,t){return e.script({basename:t}),new e.Gtk.FileDialog({initial_name:t}).save(null,null)}function replaceContents(e,t,n){return new Promise((r,i)=>{t.replace_contents_async(bytesOf(n),null,!1,e.Gio.FileCreateFlags.NONE,null,(e,n)=>{try{r(t.replace_contents_finish(n))}catch(e){i(e)}})})}const t=[{row:`error`,rule:`new GLib.Error(domain, code, message) reads back its fields and matches its own domain and code only`,observe:({GLib:e,Gio:t,Gtk:n})=>{let r=new e.Error(n.DialogError,n.DialogError.DISMISSED,`gone`);return[r instanceof e.Error,typeof r.domain,r.code,r.message,r.matches(n.DialogError,n.DialogError.DISMISSED),r.matches(n.DialogError,n.DialogError.FAILED),r.matches(t.IOErrorEnum,n.DialogError.DISMISSED),new e.Error(r.domain,1,`y`).matches(n.DialogError,1)]},shows:[!0,`number`,2,`gone`,!0,!1,!1,!0]},{row:`error`,rule:`a GLib.Error names its domain when printed and is not a JS Error`,observe:({GLib:e,Gtk:t})=>{let n=new e.Error(t.DialogError,t.DialogError.FAILED,`x`);return[String(n),n instanceof Error]},shows:[`Gtk.DialogError: x`,!1]},{row:`error`,rule:`the enum members the subset raises have GIO and GTK values`,observe:({Gio:e,Gtk:t})=>[t.DialogError.FAILED,t.DialogError.CANCELLED,t.DialogError.DISMISSED,e.IOErrorEnum.CLOSED,e.IOErrorEnum.CANCELLED,e.IOErrorEnum.PENDING,e.FileCreateFlags.NONE],shows:[0,1,2,18,19,20,0]},{row:`bytes`,rule:`GLib.Bytes copies its input; get_size and get_data give it back, each read a copy`,observe:({GLib:e})=>{let t=Uint8Array.of(1,2,3),n=new e.Bytes(t);t[0]=9;let r=n.get_data();return r[1]=7,[n.get_size(),Array.from(n.get_data()),n.get_data()instanceof Uint8Array]},shows:[3,[1,2,3],!0]},{row:`filter`,rule:`a FileFilter has no name until set, and a ListStore of FileFilter.$gtype holds what is appended`,observe:e=>{let t=e.Gtk.FileFilter.new(),n=t.get_name();return t.set_name(`A`),[n,t.get_name(),t.name,filterStore(e).get_n_items()]},shows:[null,`A`,`A`,2]},{row:`filter`,rule:`the filters of the dialog reach the picker: *.asm and *.s in one, * in the other`,async observe(e){return await pickToOpen(e,`f.asm`,``),e.pickerFilters()},shows:[[`*.asm`,`*.s`],[`*`]]},{row:`dialog`,rule:`a new FileDialog is modal with no title, initial name or filters`,observe:({Gtk:e})=>{let t=new e.FileDialog;return[t.modal,t.title,t.initial_name,t.filters,t.default_filter]},shows:[!0,null,null,null,null]},{row:`dialog`,rule:`the construct properties read back, the filters store by identity`,observe:e=>{let t=filterStore(e),n=new e.Gtk.FileDialog({title:`t`,modal:!0,filters:t,initial_name:`a.asm`});return[n.title,n.modal,n.initial_name,n.filters===t]},shows:[`t`,!0,`a.asm`,!0]},{row:`open`,rule:`open resolves a File with the picked basename whose load_contents_async gives the bytes`,async observe(e){let t=await pickToOpen(e,`prog.asm`,`LDA #$01`),[n]=await t.load_contents_async(null);return[t.get_basename(),textOf(n),n instanceof Uint8Array]},shows:[`prog.asm`,`LDA #$01`,!0]},{row:`open`,rule:`the callback forms hand back the source and a leading true; the promise form drops it`,async observe(e){let t=await pickToOpen(e,`cb.asm`,`x`),n=await new Promise(e=>{t.load_contents_async(null,(n,r)=>{let i=n.load_contents_finish(r);e([n===t,i.length,i[0],textOf(i[1])])})}),r=await t.load_contents_async(null);return[...n,r.length,textOf(r[0])]},shows:[!0,3,!0,`x`,2,`x`]},{row:`open`,rule:`open in the callback form resolves through open_finish with the dialog as source`,async observe(e){e.script({basename:`c.s`,contents:bytesOf(``)});let t=new e.Gtk.FileDialog;return new Promise(e=>{t.open(null,null,(n,r)=>{e([n===t,n.open_finish(r).get_basename()])})})},shows:[!0,`c.s`]},{row:`open`,rule:`a picked file has no local path`,holds:`subset`,async observe(e){return(await pickToOpen(e,`p.asm`,``)).get_path()},shows:null},{row:`save`,rule:`save, replace_contents_async, load_contents_async round-trip; a second replace overwrites`,async observe(e){let t=await pickToSave(e,`out.asm`),n=await replaceContents(e,t,`first version`),[r]=await t.load_contents_async(null);await replaceContents(e,t,`short`);let[i]=await t.load_contents_async(null);return[t.get_basename(),n.length,n[0],textOf(r),textOf(i)]},shows:[`out.asm`,2,!0,`first version`,`short`]},{row:`stream`,rule:`replace_async gives a FileOutputStream; write_bytes_async counts, close_async is true, bytes land`,async observe(e){let{GLib:t,Gio:n}=e,r=await pickToSave(e,`stream.asm`);await replaceContents(e,r,`old content that is longer`);let i=await r.replace_async(null,!1,n.FileCreateFlags.NONE,t.PRIORITY_DEFAULT,null),a=await i.write_bytes_async(new t.Bytes(bytesOf(`AB`)),0,null),o=await i.write_bytes_async(new t.Bytes(bytesOf(`CDE`)),0,null),s=await i.close_async(0,null),[c]=await r.load_contents_async(null);return[i instanceof n.FileOutputStream,a,o,s,textOf(c)]},shows:[!0,2,3,!0,`ABCDE`]},{row:`stream`,rule:`a write after close rejects with a GLib.Error, IOErrorEnum.CLOSED`,async observe(e){let{GLib:t,Gio:n}=e,r=await(await pickToSave(e,`closed.asm`)).replace_async(null,!1,n.FileCreateFlags.NONE,0,null);return await r.close_async(0,null),rejection(e,()=>r.write_bytes_async(new t.Bytes(bytesOf(`x`)),0,null))},shows:{glibError:!0,dismissed:!1,failed:!1,cancelled:!1,closed:!0,pending:!1}},{row:`stream`,rule:`a second write while one is pending rejects with IOErrorEnum.PENDING`,async observe(e){let{GLib:t,Gio:n}=e,r=await(await pickToSave(e,`pending.asm`)).replace_async(null,!1,n.FileCreateFlags.NONE,0,null),i=r.write_bytes_async(new t.Bytes(bytesOf(`a`)),0,null),a=await rejection(e,()=>r.write_bytes_async(new t.Bytes(bytesOf(`b`)),0,null));return await i,await r.close_async(0,null),a},shows:{glibError:!0,dismissed:!1,failed:!1,cancelled:!1,closed:!1,pending:!0}},{row:`cancel`,rule:`a dismissed dialog rejects with a GLib.Error matching Gtk.DialogError.DISMISSED only`,async observe(e){return e.script(null),rejection(e,()=>new e.Gtk.FileDialog().open(null,null))},shows:{glibError:!0,dismissed:!0,failed:!1,cancelled:!1,closed:!1,pending:!1}},{row:`cancel`,rule:`load_contents_async with a cancelled cancellable rejects with IOErrorEnum.CANCELLED`,async observe(e){let t=await pickToOpen(e,`c.asm`,`x`);return rejection(e,()=>t.load_contents_async(e.cancelled()))},shows:{glibError:!0,dismissed:!1,failed:!1,cancelled:!0,closed:!1,pending:!1}},{row:`cancel`,rule:`open with a cancelled cancellable rejects with IOErrorEnum.CANCELLED before the picker opens`,holds:`subset`,async observe(e){return e.script({basename:`never.asm`}),rejection(e,()=>new e.Gtk.FileDialog().open(null,e.cancelled()))},shows:{glibError:!0,dismissed:!1,failed:!1,cancelled:!0,closed:!1,pending:!1}},{row:`promisify`,rule:`Gio._promisify throws at the call when the async or the finish method is missing`,observe:({Gio:e})=>[throws(()=>e._promisify(e.File.prototype,`nope_async`,`nope_finish`)),throws(()=>e._promisify(e.File.prototype,`load_contents_async`,`nope_finish`))],shows:[!0,!0]},{row:`refusal`,rule:`what ADR 0100 refuses throws by name`,holds:`subset`,async observe(e){let{GLib:t,Gio:n,Gtk:r}=e,i=await pickToSave(e,`r.asm`),a=await i.replace_async(null,!1,n.FileCreateFlags.NONE,0,null),o=new r.FileDialog,s=r.FileFilter.new(),call=(e,t)=>()=>e[t](),c={modalFalse:throws(()=>new r.FileDialog({modal:!1})),initialFolder:throws(()=>new r.FileDialog({initial_folder:null})),acceptLabel:throws(()=>new r.FileDialog({accept_label:`Go`})),openMultiple:throws(call(o,`open_multiple`)),selectFolder:throws(call(o,`select_folder`)),otherGlob:throws(()=>s.add_pattern(`a*.s`)),newForPath:throws(()=>n.File.new_for_path(`/tmp/x`)),newForUri:throws(()=>n.File.new_for_uri(`file:///tmp/x`)),getParent:throws(()=>i.get_parent()),queryExists:throws(()=>i.query_exists(null)),etag:await refused(()=>i.replace_async(`e`,!1,n.FileCreateFlags.NONE,0,null)),makeBackup:await refused(()=>i.replace_async(null,!0,n.FileCreateFlags.NONE,0,null)),flags:await refused(()=>i.replace_async(null,!1,1,0,null)),bytesSlice:throws(call(new t.Bytes(bytesOf(`x`)),`slice`)),streamWrite:throws(call(a,`write`)),streamFlush:throws(call(a,`flush`)),newLiteral:throws(call(t.Error,`new_literal`))};return await a.close_async(0,null),c},shows:{modalFalse:!0,initialFolder:!0,acceptLabel:!0,openMultiple:!0,selectFolder:!0,otherGlob:!0,newForPath:!0,newForUri:!0,getParent:!0,queryExists:!0,etag:!0,makeBackup:!0,flags:!0,bytesSlice:!0,streamWrite:!0,streamFlush:!0,newLiteral:!0}}];function promisifyFileChooser({Gio:e,Gtk:t}){e._promisify(e.OutputStream.prototype,`write_bytes_async`,`write_bytes_finish`),e._promisify(e.OutputStream.prototype,`close_async`,`close_finish`),e._promisify(e.File.prototype,`load_contents_async`,`load_contents_finish`),e._promisify(e.File.prototype,`replace_async`,`replace_finish`),e._promisify(t.FileDialog.prototype,`open`,`open_finish`),e._promisify(t.FileDialog.prototype,`save`,`save_finish`)}async function driveFileChooserVectors(e,n,r=t){let{describe:i,it:a,expect:o}=n;promisifyFileChooser(e),await i(`${e.name}: Gtk.FileDialog and Gio.File`,async()=>{for(let t of r)t.holds===`subset`&&e.isOracle||await a(`${t.row}: ${t.rule}`,async()=>{let n=await t.observe(e);o(JSON.stringify(n)).toBe(JSON.stringify(t.shows))})})}export{e as FILE_CHOOSER_ROWS,t as FILE_CHOOSER_VECTORS,driveFileChooserVectors,promisifyFileChooser};
@@ -122,7 +122,7 @@ export type { AdwSourcePalette, AdwSourceSyntaxRole, AdwSourceTokenClass, AdwSou
122
122
  export { GObjectObject, META_SYMBOLS, ParamFlags, ParamSpec, Value, TYPE_BOOLEAN, TYPE_DOUBLE, TYPE_INT, TYPE_STRING, TYPE_UINT, UnsupportedGObjectError, bindProperties, connectInstance, constructRegistered, createClosure, createGObject, disconnectInstance, emitInstance, gobjectEngineName, notifyInstance, PURE_JS_ENGINE, registeredClassOf, registerBaseClass, STOP_EMISSION, type StoppableEmitter, UNLOCKED_VFUNCS, GIR_TYPE, } from './gobject.js';
123
123
  export { ApplicationFlags, GioApplicationBase, GtkApplicationBase, withGtkApplication, dispatchAccelerator, isValidApplicationId, } from './application.js';
124
124
  export { CloseRequestState, HandledAccumulator, WindowMemberState } from './window-members.js';
125
- export type { CloseOutcome, CloseRequestSteps, WindowMemberInit, WindowMemberProperty } from './window-members.js';
125
+ export type { CloseOutcome, CloseRequestSteps, WindowCommon, WindowMemberInit, WindowMemberProperty, } from './window-members.js';
126
126
  export { AcceleratorMap, ModifierMask, acceleratorName, parseAcceleratorKeyval } from './accelerators.js';
127
127
  export type { Accelerator } from './accelerators.js';
128
128
  export type { ApplicationHost, GtkApplicationMembers, GtkApplicationConstructor } from './application.js';
@@ -82,3 +82,33 @@ export declare class CloseRequestState {
82
82
  /** Run one close request through GTK's sequence. */
83
83
  close(steps: CloseRequestSteps): CloseOutcome;
84
84
  }
85
+ /**
86
+ * `Gtk.WindowCommon` (ADR 0098 Amendment 4): the part of `Gtk.Window` that GJS, `<gtk-window>` and the
87
+ * NativeScript window all have, so code shared between them types a window without a cast. A TRUE
88
+ * subset: `Gtk.Window` from `@girs/gtk-4.0` is assignable to it, and so is every window class of
89
+ * both ports. `TWidget` is what focus holds — `Gtk.Widget`, `Element` or a NativeScript `View`.
90
+ *
91
+ * Handlers are typed by the emitter alone: what follows it differs (a `GParamSpec` in GJS, an event
92
+ * payload on NativeScript), so shared code reads the window, not the extra arguments.
93
+ * `notify::focus-widget` is left out: NativeScript cannot observe focus the user moves.
94
+ */
95
+ export interface WindowCommon<TWidget = unknown> {
96
+ /** `Gtk.Window:is-active`, read-only. */
97
+ readonly is_active: boolean;
98
+ readonly isActive: boolean;
99
+ /** `Gtk.Window:focus-widget`; writing it is `set_focus`. */
100
+ focus_widget: TWidget | null;
101
+ get_focus(): TWidget | null;
102
+ set_focus(focus: TWidget | null): void;
103
+ /** `Gtk.Window:maximized`. */
104
+ maximized: boolean;
105
+ is_maximized(): boolean;
106
+ maximize(): void;
107
+ unmaximize(): void;
108
+ present(): void;
109
+ /** `gtk_window_close`: emits `close-request`, whose first handler to return true keeps the window. */
110
+ close(): void;
111
+ connect(signal: 'close-request', callback: (self: this) => boolean | void): number;
112
+ connect(signal: 'notify::is-active' | 'notify::maximized', callback: (self: this) => void): number;
113
+ disconnect(id: number): void;
114
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/adwaita-core",
3
- "version": "0.64.1-next.243",
3
+ "version": "0.64.1-next.244",
4
4
  "description": "Headless Adwaita widget behavior (breakpoint condition grammar + apply/unapply state machine, color-scheme observable, avatar derivation) shared by the web and NativeScript Adwaita renderers — pure TS, no platform imports",
5
5
  "type": "module",
6
6
  "module": "lib/esm/index.js",
@@ -60,9 +60,9 @@
60
60
  "headless"
61
61
  ],
62
62
  "devDependencies": {
63
- "@gjsify/cli": "0.64.1-next.243",
63
+ "@gjsify/cli": "0.64.1-next.244",
64
64
  "@gjsify/node-gi": "file:../../../packages/node-gi/node-gi",
65
- "@gjsify/unit": "0.64.1-next.243",
65
+ "@gjsify/unit": "0.64.1-next.244",
66
66
  "@types/node": "^25.9.2",
67
67
  "typescript": "^6.0.3"
68
68
  },
@@ -86,5 +86,5 @@
86
86
  "url": "https://github.com/gjsify/gjsify/issues"
87
87
  },
88
88
  "homepage": "https://github.com/gjsify/gjsify/tree/main/packages/web/adwaita-core#readme",
89
- "gitHead": "f88c7b1074d454e211094963a9f4dc7d0982bf32"
89
+ "gitHead": "9a6ca179c1a74477f23791c5b8f6d5a7bffaee61"
90
90
  }