Add observers for stylesheet mutations (#177)

* hack together stylesheet observer

* Add test coverage for insertRule/deleteRule on stylesheets

* Add new observers

* update patch based on changes to master

* Functioning event recording

* Remove print statements

* Fix ID usage and mark add vs remove

* Correct type

Co-authored-by: Jon Perl <perl.jonathan@gmail.com>
This commit is contained in:
David Cramer
2020-02-21 20:59:55 -08:00
committed by GitHub
parent efea82fc29
commit 046936b3e8
10 changed files with 273 additions and 64 deletions

View File

@@ -82,9 +82,11 @@ function record(options: recordOptions = {}): listenerHandler | undefined {
inlineStylesheet,
maskAllInputs,
);
if (!node) {
return console.warn('Failed to snapshot the document');
}
mirror.map = idNodeMap;
wrappedEmit(
wrapEvent({
@@ -188,6 +190,16 @@ function record(options: recordOptions = {}): listenerHandler | undefined {
},
}),
),
styleSheetRuleCb: r =>
wrappedEmit(
wrapEvent({
type: EventType.IncrementalSnapshot,
data: {
source: IncrementalSource.StyleSheetRule,
...r,
},
}),
),
blockClass,
ignoreClass,
maskAllInputs,

View File

@@ -21,6 +21,7 @@ import {
MouseInteractions,
listenerHandler,
scrollCallback,
styleSheetRuleCallback,
viewportResizeCallback,
inputValue,
inputCallback,
@@ -519,6 +520,31 @@ function initInputObserver(
};
}
function initStyleSheetObserver(cb: styleSheetRuleCallback): listenerHandler {
const insertRule = CSSStyleSheet.prototype.insertRule;
CSSStyleSheet.prototype.insertRule = function(rule: string, index?: number) {
cb({
id: mirror.getId(this.ownerNode as INode),
adds: [{ rule, index }],
});
return insertRule.apply(this, arguments);
};
const deleteRule = CSSStyleSheet.prototype.deleteRule;
CSSStyleSheet.prototype.deleteRule = function(index: number) {
cb({
id: mirror.getId(this.ownerNode as INode),
removes: [{ index }],
});
return deleteRule.apply(this, arguments);
};
return () => {
CSSStyleSheet.prototype.insertRule = insertRule;
CSSStyleSheet.prototype.deleteRule = deleteRule;
};
}
function initMediaInteractionObserver(
mediaInteractionCb: mediaInteractionCallback,
blockClass: blockClass,
@@ -548,6 +574,7 @@ function mergeHooks(o: observerParam, hooks: hooksParam) {
viewportResizeCb,
inputCb,
mediaInteractionCb,
styleSheetRuleCb,
} = o;
o.mutationCb = (...p: Arguments<mutationCallBack>) => {
if (hooks.mutation) {
@@ -591,6 +618,12 @@ function mergeHooks(o: observerParam, hooks: hooksParam) {
}
mediaInteractionCb(...p);
};
o.styleSheetRuleCb = (...p: Arguments<styleSheetRuleCallback>) => {
if (hooks.styleSheetRule) {
hooks.styleSheetRule(...p);
}
styleSheetRuleCb(...p);
};
}
export default function initObservers(
@@ -621,6 +654,8 @@ export default function initObservers(
o.mediaInteractionCb,
o.blockClass,
);
const styleSheetObserver = initStyleSheetObserver(o.styleSheetRuleCb);
return () => {
mutationObserver.disconnect();
mousemoveHandler();
@@ -629,5 +664,6 @@ export default function initObservers(
viewportResizeHandler();
inputHandler();
mediaInteractionHandler();
styleSheetObserver();
};
}

View File

@@ -52,6 +52,8 @@ export type customEvent<T = unknown> = {
};
};
export type styleSheetEvent = {};
export enum IncrementalSource {
Mutation,
MouseMove,
@@ -61,6 +63,7 @@ export enum IncrementalSource {
Input,
TouchMove,
MediaInteraction,
StyleSheetRule,
}
export type mutationData = {
@@ -93,6 +96,10 @@ export type mediaInteractionData = {
source: IncrementalSource.MediaInteraction;
} & mediaInteractionParam;
export type styleSheetRuleData = {
source: IncrementalSource.StyleSheetRule;
} & styleSheetRuleParam;
export type incrementalData =
| mutationData
| mousemoveData
@@ -100,7 +107,8 @@ export type incrementalData =
| scrollData
| viewportResizeData
| inputData
| mediaInteractionData;
| mediaInteractionData
| styleSheetRuleData;
export type event =
| domContentLoadedEvent
@@ -141,6 +149,7 @@ export type observerParam = {
ignoreClass: string;
maskAllInputs: boolean;
inlineStylesheet: boolean;
styleSheetRuleCb: styleSheetRuleCallback;
mousemoveWait: number;
};
@@ -152,6 +161,7 @@ export type hooksParam = {
viewportResize?: viewportResizeCallback;
input?: inputCallback;
mediaInteaction?: mediaInteractionCallback;
styleSheetRule?: styleSheetRuleCallback;
};
export type textCursor = {
@@ -239,6 +249,23 @@ export type scrollPosition = {
export type scrollCallback = (p: scrollPosition) => void;
export type styleSheetAddRule = {
rule: string;
index?: number;
};
export type styleSheetDeleteRule = {
index: number;
};
export type styleSheetRuleParam = {
id: number;
removes?: styleSheetDeleteRule[];
adds?: styleSheetAddRule[];
};
export type styleSheetRuleCallback = (s: styleSheetRuleParam) => void;
export type viewportResizeDimention = {
width: number;
height: number;