chore: small changes

This commit is contained in:
redhoodsu
2022-12-17 13:37:08 +08:00
parent 025c8cea6e
commit 586e81c009
5 changed files with 189 additions and 213 deletions

View File

@@ -120,7 +120,6 @@ LocalStorage, sessionStorage, cookies, scripts, styleSheets and images.
|Name |Type |Desc |
|----------------|-------|---------------------|
|hideErudaSetting|boolean|Hide Eruda Setting |
|observeElement |boolean|Auto Refresh Elements|
## Sources

View File

@@ -3,6 +3,7 @@ import lowerCase from 'licia/lowerCase'
import pick from 'licia/pick'
import toStr from 'licia/toStr'
import map from 'licia/map'
import isEl from 'licia/isEl'
import escape from 'licia/escape'
import startWith from 'licia/startWith'
import contain from 'licia/contain'
@@ -14,23 +15,63 @@ import each from 'licia/each'
import keys from 'licia/keys'
import isNull from 'licia/isNull'
import trim from 'licia/trim'
import isFn from 'licia/isFn'
import isBool from 'licia/isBool'
import safeGet from 'licia/safeGet'
import $ from 'licia/$'
import MutationObserver from 'licia/MutationObserver'
import CssStore from './CssStore'
import Settings from '../Settings/Settings'
import LunaModal from 'luna-modal'
import { formatNodeName } from './util'
import { pxToNum, classPrefix as c } from '../lib/util'
import { pxToNum, isErudaEl, classPrefix as c } from '../lib/util'
export default class Detail {
constructor($container) {
constructor($container, devtools) {
this._$container = $container
this._devtools = devtools
this._curEl = document.documentElement
this._bindEvent()
this._initObserver()
this._initCfg()
}
show(el) {
this._curEl = el
this._rmDefComputedStyle = true
this._computedStyleSearchKeyword = ''
this._enableObserver()
this._render()
}
hide() {
this._disableObserver()
}
destroy() {
this._disableObserver()
this.restoreEventTarget()
this._rmCfg()
}
overrideEventTarget() {
const winEventProto = getWinEventProto()
const origAddEvent = (this._origAddEvent = winEventProto.addEventListener)
const origRmEvent = (this._origRmEvent = winEventProto.removeEventListener)
winEventProto.addEventListener = function (type, listener, useCapture) {
addEvent(this, type, listener, useCapture)
origAddEvent.apply(this, arguments)
}
winEventProto.removeEventListener = function (type, listener, useCapture) {
rmEvent(this, type, listener, useCapture)
origRmEvent.apply(this, arguments)
}
}
restoreEventTarget() {
const winEventProto = getWinEventProto()
if (this._origAddEvent) winEventProto.addEventListener = this._origAddEvent
if (this._origRmEvent) winEventProto.removeEventListener = this._origRmEvent
}
_toggleAllComputedStyle() {
this._rmDefComputedStyle = !this._rmDefComputedStyle
@@ -250,6 +291,8 @@ export default class Detail {
return ret
}
_bindEvent() {
const devtools = this._devtools
this._$container
.on('click', c('.toggle-all-computed-style'), () =>
this._toggleAllComputedStyle()
@@ -262,6 +305,81 @@ export default class Detail {
this._render()
})
})
.on('click', '.eruda-listener-content', function () {
const text = $(this).text()
const sources = devtools.get('sources')
if (sources) {
sources.set('js', text)
devtools.showTool('sources')
}
})
.on('click', '.eruda-breadcrumb', () => {
const sources = devtools.get('sources')
if (sources) {
sources.set('object', this._curEl)
devtools.showTool('sources')
}
})
}
_initObserver() {
this._observer = new MutationObserver((mutations) => {
each(mutations, (mutation) => this._handleMutation(mutation))
})
}
_enableObserver() {
this._observer.observe(document.documentElement, {
attributes: true,
childList: true,
subtree: true,
})
}
_disableObserver() {
this._observer.disconnect()
}
_handleMutation(mutation) {
if (isErudaEl(mutation.target)) return
if (mutation.type === 'attributes') {
if (mutation.target !== this._curEl) return
this._render()
}
}
_rmCfg() {
const cfg = this.config
const settings = this._container.get('settings')
if (!settings) return
settings
.remove(cfg, 'overrideEventTarget')
.remove(cfg, 'observeElement')
.remove('Elements')
}
_initCfg() {
const cfg = (this.config = Settings.createCfg('elements', {
overrideEventTarget: true,
}))
if (cfg.get('overrideEventTarget')) this.overrideEventTarget()
cfg.on('change', (key, val) => {
switch (key) {
case 'overrideEventTarget':
return val ? this.overrideEventTarget() : this.restoreEventTarget()
}
})
const settings = this._devtools.get('settings')
if (!settings) return
settings
.text('Elements')
.switch(cfg, 'overrideEventTarget', 'Catch Event Listeners')
settings.separator()
}
}
@@ -350,3 +468,40 @@ function boxModelValue(val, type) {
return ret === 0 ? '' : ret
}
function addEvent(el, type, listener, useCapture = false) {
if (!isEl(el) || !isFn(listener) || !isBool(useCapture)) return
const events = (el.erudaEvents = el.erudaEvents || {})
events[type] = events[type] || []
events[type].push({
listener: listener,
listenerStr: listener.toString(),
useCapture: useCapture,
})
}
function rmEvent(el, type, listener, useCapture = false) {
if (!isEl(el) || !isFn(listener) || !isBool(useCapture)) return
const events = el.erudaEvents
if (!(events && events[type])) return
const listeners = events[type]
for (let i = 0, len = listeners.length; i < len; i++) {
if (listeners[i].listener === listener) {
listeners.splice(i, 1)
break
}
}
if (listeners.length === 0) delete events[type]
if (keys(events).length === 0) delete el.erudaEvents
}
const getWinEventProto = () => {
return safeGet(window, 'EventTarget.prototype') || window.Node.prototype
}

View File

@@ -1,15 +1,8 @@
import Tool from '../DevTools/Tool'
import Highlight from './Highlight'
import Select from './Select'
import Settings from '../Settings/Settings'
import $ from 'licia/$'
import keys from 'licia/keys'
import MutationObserver from 'licia/MutationObserver'
import each from 'licia/each'
import isEl from 'licia/isEl'
import isFn from 'licia/isFn'
import isBool from 'licia/isBool'
import safeGet from 'licia/safeGet'
import nextTick from 'licia/nextTick'
import Emitter from 'licia/Emitter'
import map from 'licia/map'
@@ -42,7 +35,8 @@ export default class Elements extends Tool {
this._initTpl()
this._htmlEl = document.documentElement
this._detail = new Detail(this._$detail)
this._detail = new Detail(this._$detail, container)
this.config = this._detail.config
this._domViewer = new LunaDomViewer(this._$domViewer.get(0), {
node: this._htmlEl,
ignore: (node) => isErudaEl(node),
@@ -51,62 +45,32 @@ export default class Elements extends Tool {
this._highlight = new Highlight(this._container.$container)
this._select = new Select()
this._bindEvent()
this._initObserver()
this._initCfg()
nextTick(() => this._updateHistory())
}
show() {
super.show()
if (this._observeElement) this._enableObserver()
if (!this._curEl) this._setEl(this._htmlEl)
}
hide() {
this._disableObserver()
return super.hide()
if (!this._curNode) {
this._setNode(document.body)
}
}
// To be removed in 3.0.0
set(node) {
return this.select(node)
}
select(node) {
this._setEl(node)
this._setNode(node)
this.emit('change', node)
return this
}
overrideEventTarget() {
const winEventProto = getWinEventProto()
const origAddEvent = (this._origAddEvent = winEventProto.addEventListener)
const origRmEvent = (this._origRmEvent = winEventProto.removeEventListener)
winEventProto.addEventListener = function (type, listener, useCapture) {
addEvent(this, type, listener, useCapture)
origAddEvent.apply(this, arguments)
}
winEventProto.removeEventListener = function (type, listener, useCapture) {
rmEvent(this, type, listener, useCapture)
origRmEvent.apply(this, arguments)
}
}
restoreEventTarget() {
const winEventProto = getWinEventProto()
if (this._origAddEvent) winEventProto.addEventListener = this._origAddEvent
if (this._origRmEvent) winEventProto.removeEventListener = this._origRmEvent
}
destroy() {
super.destroy()
evalCss.remove(this._style)
this._detail.destroy()
this._select.disable()
this._highlight.destroy()
this._disableObserver()
this.restoreEventTarget()
this._rmCfg()
}
_initTpl() {
const $el = this._$el
@@ -129,7 +93,7 @@ export default class Elements extends Tool {
this._$crumbs = $el.find(c('.crumbs'))
}
_renderCrumbs() {
const crumbs = getCrumbs(this._curEl)
const crumbs = getCrumbs(this._curNode)
let html = ''
if (!isEmpty(crumbs)) {
html = map(crumbs, ({ text, idx }) => {
@@ -139,7 +103,7 @@ export default class Elements extends Tool {
this._$crumbs.html(html)
}
_back() {
if (this._curEl === this._htmlEl) return
if (this._curNode === this._htmlEl) return
const parentQueue = this._curParentQueue
let parent = parentQueue.shift()
@@ -150,57 +114,28 @@ export default class Elements extends Tool {
}
_bindEvent() {
const self = this
const container = this._container
const select = this._select
this._$el
.on('click', '.eruda-listener-content', function () {
const text = $(this).text()
const sources = container.get('sources')
this._$el.on('click', c('.crumb'), function () {
let idx = toNum($(this).data('idx'))
let el = self._curNode
if (sources) {
sources.set('js', text)
container.showTool('sources')
}
})
.on('click', '.eruda-breadcrumb', () => {
const sources = container.get('sources')
while (idx-- && el.parentElement) {
el = el.parentElement
}
if (sources) {
sources.set('object', this._curEl)
container.showTool('sources')
}
})
.on('click', c('.crumb'), function () {
let idx = toNum($(this).data('idx'))
let el = self._curEl
while (idx-- && el.parentElement) {
el = el.parentElement
}
if (isElExist(el)) {
self.set(el)
}
})
if (isElExist(el)) {
self.set(el)
}
})
this._$control
.on('click', c('.select'), () => this._toggleSelect())
.on('click', c('.show'), () => this._detail.show(this._curEl))
.on('click', c('.show'), () => this._detail.show(this._curNode))
select.on('select', (target) => this.set(target))
this._domViewer.on('select', this._setEl)
}
_enableObserver() {
this._observer.observe(this._htmlEl, {
attributes: true,
childList: true,
subtree: true,
})
}
_disableObserver() {
this._observer.disconnect()
this._domViewer.on('select', this._setNode)
}
_toggleHighlight() {
if (this._selectElement) return
@@ -225,18 +160,18 @@ export default class Elements extends Tool {
select.disable()
}
}
_setEl = (el) => {
if (el === this._curEl) return
_setNode = (node) => {
if (node === this._curNode) return
this._curEl = el
this._domViewer.select(el)
this._curNode = node
this._domViewer.select(node)
this._renderCrumbs()
this._highlight.setEl(el)
this._highlight.setEl(node)
const parentQueue = []
let parent = el.parentNode
let parent = node.parentNode
while (parent) {
parentQueue.push(parent)
parent = parent.parentNode
@@ -250,122 +185,12 @@ export default class Elements extends Tool {
if (!console) return
const history = this._history
history.unshift(this._curEl)
history.unshift(this._curNode)
if (history.length > 5) history.pop()
for (let i = 0; i < 5; i++) {
console.setGlobal(`$${i}`, history[i])
}
}
_initObserver() {
this._observer = new MutationObserver((mutations) => {
each(mutations, (mutation) => this._handleMutation(mutation))
})
}
_handleMutation(mutation) {
let i, len, node
if (isErudaEl(mutation.target)) return
if (mutation.type === 'attributes') {
if (mutation.target !== this._curEl) return
this._render()
} else if (mutation.type === 'childList') {
if (mutation.target === this._curEl) return this._render()
const addedNodes = mutation.addedNodes
for (i = 0, len = addedNodes.length; i < len; i++) {
node = addedNodes[i]
if (node.parentNode === this._curEl) return this._render()
}
const removedNodes = mutation.removedNodes
for (i = 0, len = removedNodes.length; i < len; i++) {
if (removedNodes[i] === this._curEl) return this.set(this._htmlEl)
}
}
}
_rmCfg() {
const cfg = this.config
const settings = this._container.get('settings')
if (!settings) return
settings
.remove(cfg, 'overrideEventTarget')
.remove(cfg, 'observeElement')
.remove('Elements')
}
_initCfg() {
const cfg = (this.config = Settings.createCfg('elements', {
overrideEventTarget: true,
observeElement: true,
}))
if (cfg.get('overrideEventTarget')) this.overrideEventTarget()
if (cfg.get('observeElement')) this._observeElement = false
cfg.on('change', (key, val) => {
switch (key) {
case 'overrideEventTarget':
return val ? this.overrideEventTarget() : this.restoreEventTarget()
case 'observeElement':
this._observeElement = val
return val ? this._enableObserver() : this._disableObserver()
}
})
const settings = this._container.get('settings')
if (!settings) return
settings
.text('Elements')
.switch(cfg, 'overrideEventTarget', 'Catch Event Listeners')
if (this._observer) settings.switch(cfg, 'observeElement', 'Auto Refresh')
settings.separator()
}
}
function addEvent(el, type, listener, useCapture = false) {
if (!isEl(el) || !isFn(listener) || !isBool(useCapture)) return
const events = (el.erudaEvents = el.erudaEvents || {})
events[type] = events[type] || []
events[type].push({
listener: listener,
listenerStr: listener.toString(),
useCapture: useCapture,
})
}
function rmEvent(el, type, listener, useCapture = false) {
if (!isEl(el) || !isFn(listener) || !isBool(useCapture)) return
const events = el.erudaEvents
if (!(events && events[type])) return
const listeners = events[type]
for (let i = 0, len = listeners.length; i < len; i++) {
if (listeners[i].listener === listener) {
listeners.splice(i, 1)
break
}
}
if (listeners.length === 0) delete events[type]
if (keys(events).length === 0) delete el.erudaEvents
}
const getWinEventProto = () => {
return safeGet(window, 'EventTarget.prototype') || window.Node.prototype
}
const isElExist = (val) => isEl(val) && val.parentNode

View File

@@ -28,6 +28,7 @@
font-size: $font-size-s;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
li {
cursor: pointer;
padding: 0 7px;

View File

@@ -203,13 +203,9 @@ export function pxToNum(str) {
}
export function isErudaEl(el) {
let parentNode = el.parentNode
if (!parentNode) return false
while (parentNode) {
if (parentNode.id === 'eruda') return true
parentNode = parentNode.parentNode
while (el) {
if (el.id === 'eruda') return true
el = el.parentNode
}
return false