feat(tracker): StyleSheet rules messages unifyied for Constructed and style-tag based cases
This commit is contained in:
parent
23240536b7
commit
c29c29ab7c
6 changed files with 85 additions and 56 deletions
|
|
@ -265,6 +265,8 @@ export default class DOMManager extends ListWalker<Message> {
|
|||
vn.applyChanges()
|
||||
}
|
||||
return
|
||||
|
||||
// @depricated since 4.0.2 in favor of adopted_ss_insert/delete_rule + add_owner as being common case for StyleSheets
|
||||
case "css_insert_rule":
|
||||
vn = this.vElements.get(msg.id)
|
||||
if (!vn) { logger.error("Node not found", msg); return }
|
||||
|
|
@ -283,6 +285,8 @@ export default class DOMManager extends ListWalker<Message> {
|
|||
}
|
||||
vn.onStyleSheet(sheet => deleteRule(sheet, msg))
|
||||
return
|
||||
// end @depricated
|
||||
|
||||
case "create_i_frame_document":
|
||||
vn = this.vElements.get(msg.frameID)
|
||||
if (!vn) { logger.error("Node not found", msg); return }
|
||||
|
|
@ -326,18 +330,7 @@ export default class DOMManager extends ListWalker<Message> {
|
|||
}
|
||||
deleteRule(styleSheet, msg)
|
||||
return
|
||||
case "replace_vcss":
|
||||
styleSheet = this.styleSheets.get(msg.sheetID)
|
||||
if (!styleSheet) {
|
||||
logger.warn("No stylesheet was created for ", msg)
|
||||
return
|
||||
}
|
||||
const toRemove = styleSheet.cssRules.length
|
||||
for (let i = 0; i < toRemove; i++) {
|
||||
styleSheet.deleteRule(i)
|
||||
}
|
||||
styleSheet.insertRule(msg.styles)
|
||||
return
|
||||
|
||||
case "adopted_ss_replace":
|
||||
styleSheet = this.styleSheets.get(msg.sheetID)
|
||||
if (!styleSheet) {
|
||||
|
|
@ -349,7 +342,14 @@ export default class DOMManager extends ListWalker<Message> {
|
|||
return
|
||||
case "adopted_ss_add_owner":
|
||||
vn = this.vRoots.get(msg.id)
|
||||
if (!vn) { logger.error("Node not found", msg); return }
|
||||
if (!vn) {
|
||||
// non-constructed case
|
||||
vn = this.vElements.get(msg.id)
|
||||
if (!vn) { logger.error("Node not found", msg); return }
|
||||
if (!(vn instanceof VStyleElement)) { logger.error("Non-style owner", msg); return }
|
||||
this.styleSheets.set(msg.sheetID, vn.node.sheet)
|
||||
return
|
||||
}
|
||||
styleSheet = this.styleSheets.get(msg.sheetID)
|
||||
if (!styleSheet) {
|
||||
let context: typeof globalThis
|
||||
|
|
|
|||
|
|
@ -238,15 +238,18 @@ message 36, 'CustomEvent', :tracker => false, :replayer => false do
|
|||
string 'Name'
|
||||
string 'Payload'
|
||||
end
|
||||
# depricated since 4.0.2 in favor of AdoptedSSInsertRule + AdoptedSSAddOwner
|
||||
message 37, 'CSSInsertRule' do
|
||||
uint 'ID'
|
||||
string 'Rule'
|
||||
uint 'Index'
|
||||
end
|
||||
# depricated since 4.0.2
|
||||
message 38, 'CSSDeleteRule' do
|
||||
uint 'ID'
|
||||
uint 'Index'
|
||||
end
|
||||
|
||||
message 39, 'Fetch' do
|
||||
string 'Method'
|
||||
string 'URL'
|
||||
|
|
@ -421,6 +424,7 @@ message 70, 'CreateIFrameDocument' do
|
|||
end
|
||||
|
||||
#Since 4.0.0 AdoptedStyleSheets etc
|
||||
# TODO: rename to StyleSheets...
|
||||
message 71, 'AdoptedSSReplaceURLBased' do
|
||||
uint 'SheetID'
|
||||
string 'Text'
|
||||
|
|
|
|||
|
|
@ -291,6 +291,7 @@ export default abstract class Observer {
|
|||
const width = el.clientWidth
|
||||
const height = el.clientHeight
|
||||
el = node.cloneNode() as Element
|
||||
// TODO: use ResizeObserver
|
||||
;(el as HTMLElement | SVGElement).style.width = width + 'px'
|
||||
;(el as HTMLElement | SVGElement).style.height = height + 'px'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import Performance from './modules/performance.js'
|
|||
import Scroll from './modules/scroll.js'
|
||||
import Viewport from './modules/viewport.js'
|
||||
import CSSRules from './modules/cssrules.js'
|
||||
import AdoptedStyleSheets from './modules/adoptedStyleSheets.js'
|
||||
import ConstructedStyleSheets from './modules/constructedStyleSheets.js'
|
||||
import { IN_BROWSER, deprecationWarn, DOCS_HOST } from './utils.js'
|
||||
|
||||
import type { Options as AppOptions } from './app/index.js'
|
||||
|
|
@ -112,7 +112,7 @@ export default class API {
|
|||
if (app !== null) {
|
||||
Viewport(app)
|
||||
CSSRules(app)
|
||||
AdoptedStyleSheets(app)
|
||||
ConstructedStyleSheets(app)
|
||||
Connection(app)
|
||||
Console(app, options)
|
||||
Exception(app, options)
|
||||
|
|
|
|||
|
|
@ -19,6 +19,13 @@ function hasAdoptedSS(node: Node): node is StyleSheetOwner {
|
|||
)
|
||||
}
|
||||
|
||||
// TODO: incapsulate to be init-ed on-start and join with cssrules.ts under one folder
|
||||
let _id = 0xf
|
||||
export function nextID(): number {
|
||||
return _id++
|
||||
}
|
||||
export const styleSheetIDMap: Map<CSSStyleSheet, number> = new Map()
|
||||
|
||||
export default function (app: App | null) {
|
||||
if (app === null) {
|
||||
return
|
||||
|
|
@ -31,7 +38,6 @@ export default function (app: App | null) {
|
|||
return
|
||||
}
|
||||
|
||||
let nextID = 0xf
|
||||
const styleSheetIDMap: Map<CSSStyleSheet, number> = new Map()
|
||||
const adoptedStyleSheetsOwnings: Map<number, number[]> = new Map()
|
||||
|
||||
|
|
@ -53,7 +59,7 @@ export default function (app: App | null) {
|
|||
let sheetID = styleSheetIDMap.get(s)
|
||||
const init = !sheetID
|
||||
if (!sheetID) {
|
||||
sheetID = ++nextID
|
||||
sheetID = nextID()
|
||||
}
|
||||
nowOwning.push(sheetID)
|
||||
if (!pastOwning.includes(sheetID)) {
|
||||
|
|
@ -1,6 +1,12 @@
|
|||
import type App from '../app/index.js'
|
||||
import { CSSInsertRuleURLBased, CSSDeleteRule, TechnicalInfo } from '../app/messages.gen.js'
|
||||
import {
|
||||
AdoptedSSInsertRuleURLBased, // TODO: rename to common StyleSheet names
|
||||
AdoptedSSDeleteRule,
|
||||
AdoptedSSAddOwner,
|
||||
TechnicalInfo,
|
||||
} from '../app/messages.gen.js'
|
||||
import { hasTag } from '../app/guards.js'
|
||||
import { nextID, styleSheetIDMap } from './constructedStyleSheets.js'
|
||||
|
||||
export default function (app: App | null) {
|
||||
if (app === null) {
|
||||
|
|
@ -11,41 +17,43 @@ export default function (app: App | null) {
|
|||
return
|
||||
}
|
||||
|
||||
const processOperation = app.safe((stylesheet: CSSStyleSheet, index: number, rule?: string) => {
|
||||
const sendMessage =
|
||||
typeof rule === 'string'
|
||||
? (nodeID: number) =>
|
||||
app.send(CSSInsertRuleURLBased(nodeID, rule, index, app.getBaseHref()))
|
||||
: (nodeID: number) => app.send(CSSDeleteRule(nodeID, index))
|
||||
// TODO: Extend messages to maintain nested rules (CSSGroupingRule prototype, as well as CSSKeyframesRule)
|
||||
if (!stylesheet.ownerNode) {
|
||||
throw new Error('Owner Node not found')
|
||||
}
|
||||
const nodeID = app.nodes.getID(stylesheet.ownerNode)
|
||||
if (nodeID !== undefined) {
|
||||
sendMessage(nodeID)
|
||||
} // else error?
|
||||
})
|
||||
const sendInserDeleteRule = app.safe(
|
||||
(stylesheet: CSSStyleSheet, index: number, rule?: string) => {
|
||||
const sheetID = styleSheetIDMap.get(stylesheet)
|
||||
if (!sheetID) {
|
||||
app.debug.warn('No sheedID found', stylesheet, styleSheetIDMap)
|
||||
return
|
||||
}
|
||||
if (typeof rule === 'string') {
|
||||
app.send(AdoptedSSInsertRuleURLBased(sheetID, rule, index, app.getBaseHref()))
|
||||
} else {
|
||||
app.send(AdoptedSSDeleteRule(sheetID, index))
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
const replaceGroupingRule = app.safe((ctx: CSSGroupingRule) => {
|
||||
let topmostRule: CSSRule = ctx
|
||||
// TODO: proper rule insertion/removal (how?)
|
||||
const sendReplaceGroupingRule = app.safe((rule: CSSGroupingRule) => {
|
||||
let topmostRule: CSSRule = rule
|
||||
while (topmostRule.parentRule) {
|
||||
topmostRule = topmostRule.parentRule
|
||||
}
|
||||
if (topmostRule.parentStyleSheet?.ownerNode) {
|
||||
const entireStyle = topmostRule.cssText
|
||||
const nodeID = app.nodes.getID(topmostRule.parentStyleSheet.ownerNode)
|
||||
if (nodeID === undefined) {
|
||||
return
|
||||
}
|
||||
const ruleList = topmostRule.parentStyleSheet.cssRules
|
||||
const idx = Array.from(ruleList).indexOf(topmostRule)
|
||||
if (idx >= 0) {
|
||||
app.send(CSSDeleteRule(nodeID, idx))
|
||||
app.send(CSSInsertRuleURLBased(nodeID, entireStyle, idx, app.getBaseHref()))
|
||||
}
|
||||
} else {
|
||||
app.debug.error('Owner Node not found for the rule', topmostRule)
|
||||
const sheet = topmostRule.parentStyleSheet
|
||||
if (!sheet) {
|
||||
app.debug.warn('No parent StyleSheet found for', topmostRule, rule)
|
||||
return
|
||||
}
|
||||
const sheetID = styleSheetIDMap.get(sheet)
|
||||
if (!sheetID) {
|
||||
app.debug.warn('No sheedID found for', sheet, styleSheetIDMap)
|
||||
return
|
||||
}
|
||||
const cssText = topmostRule.cssText
|
||||
const ruleList = sheet.cssRules
|
||||
const idx = Array.from(ruleList).indexOf(topmostRule)
|
||||
if (idx >= 0) {
|
||||
app.send(AdoptedSSInsertRuleURLBased(sheetID, cssText, idx, app.getBaseHref()))
|
||||
app.send(AdoptedSSDeleteRule(sheetID, idx + 1)) // Remove previous clone
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -55,22 +63,22 @@ export default function (app: App | null) {
|
|||
context.CSSGroupingRule.prototype
|
||||
|
||||
context.CSSStyleSheet.prototype.insertRule = function (rule: string, index = 0) {
|
||||
processOperation(this, index, rule)
|
||||
sendInserDeleteRule(this, index, rule)
|
||||
return insertRule.call(this, rule, index) as number
|
||||
}
|
||||
context.CSSStyleSheet.prototype.deleteRule = function (index: number) {
|
||||
processOperation(this, index)
|
||||
sendInserDeleteRule(this, index)
|
||||
return deleteRule.call(this, index) as number
|
||||
}
|
||||
|
||||
context.CSSGroupingRule.prototype.insertRule = function (rule: string, index = 0) {
|
||||
const result = groupInsertRule.call(this, rule, index) as number
|
||||
replaceGroupingRule(this)
|
||||
sendReplaceGroupingRule(this)
|
||||
return result
|
||||
}
|
||||
context.CSSGroupingRule.prototype.deleteRule = function (index = 0) {
|
||||
const result = groupDeleteRule.call(this, index) as number
|
||||
replaceGroupingRule(this)
|
||||
sendReplaceGroupingRule(this)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
|
@ -83,11 +91,21 @@ export default function (app: App | null) {
|
|||
return
|
||||
}
|
||||
if (node.textContent !== null && node.textContent.trim().length > 0) {
|
||||
return // Only fully virtual sheets maintained so far
|
||||
return // Non-virtual styles captured by the observer as a text
|
||||
}
|
||||
const rules = node.sheet.cssRules
|
||||
|
||||
const nodeID = app.nodes.getID(node)
|
||||
if (!nodeID) {
|
||||
return
|
||||
}
|
||||
const sheet = node.sheet
|
||||
const sheetID = nextID()
|
||||
styleSheetIDMap.set(sheet, sheetID)
|
||||
app.send(AdoptedSSAddOwner(sheetID, nodeID))
|
||||
|
||||
const rules = sheet.cssRules
|
||||
for (let i = 0; i < rules.length; i++) {
|
||||
processOperation(node.sheet, i, rules[i].cssText)
|
||||
sendInserDeleteRule(sheet, i, rules[i].cssText)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue