🎨 Optimized runtime

pull/8022/head
TheCymaera 4 years ago
parent 8a1e0a2c78
commit 1e295ead46

@ -11,7 +11,7 @@ import StyleDirective from './StyleDirective';
import Text from './Text';
import { namespaces } from '../../utils/namespaces';
import map_children from './shared/map_children';
import { regex_dimensions, regex_starts_with_newline, regex_non_whitespace_character, regex_box_size, regex_border_box_size, regex_content_box_size } from '../../utils/patterns';
import { regex_dimensions, regex_starts_with_newline, regex_non_whitespace_character, regex_box_size } from '../../utils/patterns';
import fuzzymatch from '../../utils/fuzzymatch';
import list from '../../utils/list';
import Let from './Let';

@ -416,13 +416,7 @@ function get_value_from_dom(
// <div bind:contentRect|contentBoxSize|borderBoxSize|devicePixelContentBoxSize>
if (regex_box_size.test(name)) {
const functionName = ({
"contentRect": "get_content_rect",
"contentBoxSize": "get_content_box_size",
"borderBoxSize": "get_border_box_size",
"devicePixelContentBoxSize": "get_device_pixel_content_box_size",
})[name];
return x`@${functionName}(this)`;
return x`@ResizeObserverSingleton.entries.get(this)?.${name}`;
}
// <select bind:value='selected>

@ -70,15 +70,10 @@ const events = [
regex_dimensions.test(name)
},
{
event_names: ['elementresizeobservecontentrect'],
filter: (_node: Element, name: string) =>
regex_content_rect.test(name)
},
{
event_names: ['elementresizeobservecontentbox'],
filter: (_node: Element, name: string) =>
regex_content_box_size.test(name)
regex_content_rect.test(name) ?? regex_content_box_size.test(name)
},
{
event_names: ['elementresizeobserveborderbox'],
@ -710,11 +705,10 @@ export default class ElementWrapper extends Wrapper {
binding_group.events.forEach(name => {
const resizeListenerFunctions = {
"elementresize": "add_iframe_resize_listener",
"elementresizeobservecontentrect": "add_content_rect_observer",
"elementresizeobservecontentbox": "add_content_box_observer",
"elementresizeobserveborderbox": "add_border_box_observer",
"elementresizeobservedevicepixelcontentbox": "add_device_pixel_content_box_observer",
elementresize: 'add_iframe_resize_listener',
elementresizeobservecontentbox: 'resize_observer_content_box.observe',
elementresizeobserveborderbox: 'resize_observer_border_box.observe',
elementresizeobservedevicepixelcontentbox: 'resize_observer_device_pixel_content_box.observe'
};
if (name in resizeListenerFunctions) {

@ -27,4 +27,4 @@ export const regex_content_rect = /^(?:contentRect)$/;
export const regex_content_box_size = /^(?:contentBoxSize)$/;
export const regex_border_box_size = /^(?:borderBoxSize)$/;
export const regex_device_pixel_content_box_size = /^(?:devicePixelContentBoxSize)$/;
export const regex_box_size = /^(?:contentRect|contentBoxSize|borderBoxSize|devicePixelContentBoxSize)$/
export const regex_box_size = /^(?:contentRect|contentBoxSize|borderBoxSize|devicePixelContentBoxSize)$/;

@ -1,4 +1,4 @@
const MapImplementation = "WeakMap" in window ? WeakMap : ("Map" in window ? Map : undefined);
const MapImplementation = 'WeakMap' in window ? WeakMap : ('Map' in window ? Map : undefined);
/**
* Resize observer singleton
@ -7,35 +7,27 @@ const MapImplementation = "WeakMap" in window ? WeakMap : ("Map" in window ? Map
export class ResizeObserverSingleton {
constructor(readonly options?: ResizeObserverOptions) {}
addListener(element: Element, listener: Listener) {
this._subscriptions.set(element, {listener});
observe(element: Element, listener: Listener) {
this._listeners.set(element, listener);
this._getObserver().observe(element, this.options);
return () => {
this._subscriptions.delete(element);
this._observer!.unobserve(element); // this line can probably be removed
}
this._listeners.delete(element);
this._observer.unobserve(element); // this line can probably be removed
};
}
getLastEntry(element: Element) {
return this._subscriptions.get(element)?.lastEntry;
}
static readonly entries: WeakMap<Element, ResizeObserverEntry> = MapImplementation ? new MapImplementation() : undefined;
private readonly _subscriptions: WeakMap<Element, Subscription> = MapImplementation ? new MapImplementation() : undefined;
private readonly _listeners: WeakMap<Element, Listener> = MapImplementation ? new MapImplementation() : undefined;
private _observer?: ResizeObserver;
private _getObserver() {
return this._observer ?? (this._observer = new ResizeObserver((entries) => {
for (const entry of entries) {
const subscription = this._subscriptions.get(entry.target)!;
subscription.lastEntry = entry;
subscription.listener(entry);
ResizeObserverSingleton.entries.set(entry.target, entry);
this._listeners.get(entry.target)?.(entry);
}
}));
}
}
type Listener = (entry: ResizeObserverEntry)=>any;
interface Subscription {
readonly listener: Listener,
lastEntry?: ResizeObserverEntry,
}

@ -641,43 +641,11 @@ export function add_iframe_resize_listener(node: HTMLElement, fn: () => void) {
};
}
const resize_observer_content_rect = new ResizeObserverSingleton({ box: "content-box" });
const resize_observer_content_box = new ResizeObserverSingleton({ box: "content-box" });
const resize_observer_border_box = new ResizeObserverSingleton({ box: "border-box" });
const resize_observer_device_pixel_content_box = new ResizeObserverSingleton({ box: "device-pixel-content-box" });
export function add_content_rect_observer(node: Element, fn: () => void) {
return resize_observer_content_rect.addListener(node, fn);
}
export function add_content_box_observer(node: Element, fn: () => void) {
return resize_observer_content_box.addListener(node, fn);
}
export function add_border_box_observer(node: Element, fn: () => void) {
return resize_observer_border_box.addListener(node, fn);
}
export function add_device_pixel_content_box_observer(node: Element, fn: () => void) {
return resize_observer_device_pixel_content_box.addListener(node, fn);
}
export function get_content_rect(node: Element) {
return resize_observer_content_rect.getLastEntry(node)?.contentRect;
}
export function get_content_box_size(node: Element) {
return resize_observer_content_box.getLastEntry(node)?.contentBoxSize;
}
export function get_border_box_size(node: Element) {
return resize_observer_border_box.getLastEntry(node)?.borderBoxSize;
}
export function get_device_pixel_content_box_size(node: Element) {
return resize_observer_device_pixel_content_box.getLastEntry(node)?.devicePixelContentBoxSize;
}
export const resize_observer_content_rect = new ResizeObserverSingleton({ box: 'content-box' });
export const resize_observer_content_box = new ResizeObserverSingleton({ box: 'content-box' });
export const resize_observer_border_box = new ResizeObserverSingleton({ box: 'border-box' });
export const resize_observer_device_pixel_content_box = new ResizeObserverSingleton({ box: 'device-pixel-content-box' });
export { ResizeObserverSingleton };
export function toggle_class(element, name, toggle) {
element.classList[toggle ? 'add' : 'remove'](name);

Loading…
Cancel
Save