add idb api

This commit is contained in:
David Reed 2023-02-24 22:47:40 -05:00
parent b777938cab
commit a645ac4653
No known key found for this signature in database
GPG key ID: 2211691D8A1EE72F
4 changed files with 124 additions and 1 deletions

View file

@ -1,11 +1,35 @@
/**
*
* @template Data
* @template Target
* @template That
* @property {Data} data
* @property {Target} target
* @property {That} that
*/
class HookEvent {
#intercepted;
#returnValue;
/**
*
* @param {Data} data
* @param {Target} target
* @param {That} that
*/
constructor(data = {}, target = null, that = null) {
this.#intercepted = false;
this.#returnValue = null;
/**
* @type {Data}
*/
this.data = data;
/**
* @type {Target}
*/
this.target = target;
/**
* @type {That}
*/
this.that = that;
}
get intercepted() {

62
src/client/idb.js Normal file
View file

@ -0,0 +1,62 @@
import EventEmitter from 'events';
import HookEvent from './hook.js';
/**
* @typedef {import('./index').default} Ultraviolet
*/
class IDBApi extends EventEmitter {
/**
*
* @param {Ultraviolet} ctx
*/
constructor(ctx) {
super();
this.ctx = ctx;
this.window = this.ctx.window;
this.IDBDatabase = this.window.IDBDatabase || {};
this.idbDatabaseProto = this.IDBDatabase.prototype || {};
this.IDBFactory = this.window.IDBFactory || {};
this.idbFactoryProto = this.IDBFactory.prototype || {};
this.open = this.idbFactoryProto.open;
}
overrideOpen() {
this.ctx.override(
this.IDBFactory.prototype,
'open',
(target, that, args) => {
if (!args.length) return target.apply(that, args);
if (!args.length) return target.apply(that, args);
const [name, version] = args;
const event = new HookEvent({ name, version }, target, that);
this.emit('idbFactoryOpen', event);
if (event.intercepted) return event.returnValue;
return event.target.call(
event.that,
event.data.name,
event.data.version
);
}
);
}
overrideName() {
this.ctx.overrideDescriptor(this.idbDatabaseProto, 'name', {
get: (target, that) => {
const event = new HookEvent(
{ value: target.call(that) },
target,
that
);
this.emit('idbFactoryName', event);
if (event.intercepted) return event.returnValue;
return event.data.value;
},
});
}
}
export default IDBApi;

View file

@ -16,6 +16,7 @@ import URLApi from './url.js';
import EventEmitter from 'events';
import StorageApi from './storage.js';
import StyleApi from './dom/style.js';
import IDBApi from './idb.js';
class UVClient extends EventEmitter {
constructor(window = self, worker = !window.window) {
@ -43,6 +44,7 @@ class UVClient extends EventEmitter {
this.worker = worker;
this.fetch = new Fetch(this);
this.xhr = new Xhr(this);
this.idb = new IDBApi(this);
this.history = new History(this);
this.element = new ElementApi(this);
this.node = new NodeApi(this);
@ -67,10 +69,19 @@ class UVClient extends EventEmitter {
this.worker
);
}
/**
*
* @param {*} obj
* @param {*} prop
* @param {WrapFun} wrapper
* @param {*} construct
* @returns
*/
override(obj, prop, wrapper, construct) {
// if (!(prop in obj)) return false;
const wrapped = this.wrap(obj, prop, wrapper, construct);
return (obj[prop] = wrapped);
obj[prop] = wrapped;
return wrapped;
}
overrideDescriptor(obj, prop, wrapObj = {}) {
const wrapped = this.wrapDescriptor(obj, prop, wrapObj);
@ -78,6 +89,19 @@ class UVClient extends EventEmitter {
this.nativeMethods.defineProperty(obj, prop, wrapped);
return wrapped;
}
/**
* @template {Function} [T=Function]
* @typedef {(fn: T, that: any, args: any[]) => {}} WrapFun
*/
/**
*
* @template T
* @param {*} obj
* @param {*} prop
* @param {WrapFun<T>} wrap
* @param {boolean} construct
* @returns {T}
*/
wrap(obj, prop, wrap, construct) {
const fn = obj[prop];
if (!fn) return fn;

View file

@ -409,6 +409,17 @@ function __uvHook(window) {
event.data.url = __uv.rewriteUrl(event.data.url);
});
// IDB
client.idb.on('idbFactoryOpen', (event) => {
event.data.name = `${__uv.meta.url.origin}@${event.data.name}`;
});
client.idb.on('idbFactoryName', (event) => {
event.data.value = event.data.value.slice(
__uv.meta.url.origin.length + 1 /*the @*/
);
});
// History
client.history.on('replaceState', (event) => {
if (event.data.url)
@ -1400,6 +1411,8 @@ function __uvHook(window) {
//client.document.overrideQuerySelector();
client.object.overrideGetPropertyNames();
client.object.overrideGetOwnPropertyDescriptors();
client.idb.overrideName();
client.idb.overrideOpen();
client.history.overridePushState();
client.history.overrideReplaceState();
client.eventSource.overrideConstruct();