Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b8929b9a5 | ||
|
|
ddac0c9353 | ||
|
|
600ea6213a | ||
|
|
27b85b4834 | ||
|
|
ce3f6aef38 | ||
|
|
d99b38e725 | ||
|
|
588dba7b74 | ||
|
|
8c05dba355 | ||
|
|
6cd4259c49 | ||
|
|
a402cc5fd5 | ||
|
|
a8dbc49907 | ||
|
|
becfd98fef |
19
.github/workflows/main.yml
vendored
19
.github/workflows/main.yml
vendored
@@ -14,22 +14,15 @@ jobs:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [18.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
node-version: '18.x'
|
||||
- run: |
|
||||
npm install -g @liriliri/lsla
|
||||
npm i
|
||||
npm run ci
|
||||
- run: |
|
||||
npm install -g codecov
|
||||
codecov --disable=gcov
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
- uses: codecov/codecov-action@v4
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
12
.github/workflows/publish.yml
vendored
12
.github/workflows/publish.yml
vendored
@@ -11,20 +11,16 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v2
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '18.x'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
- name: Build eruda
|
||||
run: |
|
||||
- run: |
|
||||
npm i -g @liriliri/lsla
|
||||
npm i
|
||||
npm run build
|
||||
- name: Publish package on NPM
|
||||
working-directory: dist
|
||||
- working-directory: dist
|
||||
run: npm publish
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
@@ -1,3 +1,12 @@
|
||||
## 3.4.0 (27 Sep 2024)
|
||||
|
||||
* feat: support shadow dom [#158](https://github.com/liriliri/eruda/issues/158)
|
||||
* fix: quirks mode table rendering [#459](https://github.com/liriliri/eruda/issues/459)
|
||||
|
||||
## 3.3.0 (9 Sep 2024)
|
||||
|
||||
* feat: add vue devtools plugin
|
||||
|
||||
## 3.2.3 (10 AUG 2024)
|
||||
|
||||
* fix: WebSocket message base64 encoded [#447](https://github.com/liriliri/eruda/issues/447)
|
||||
|
||||
@@ -29,11 +29,11 @@ Console for Mobile Browsers.
|
||||
[license-image]: https://img.shields.io/npm/l/eruda?style=flat-square
|
||||
[donate-image]: https://img.shields.io/badge/$-donate-0070ba.svg?style=flat-square
|
||||
|
||||
<img src="https://eruda.liriliri.io/img/screenshot.jpg" style="width:100%">
|
||||
<img src="https://eruda.liriliri.io/screenshot.jpg" style="width:100%">
|
||||
|
||||
## Demo
|
||||
|
||||

|
||||

|
||||
|
||||
Browse it on your phone: [https://eruda.liriliri.io/](https://eruda.liriliri.io/)
|
||||
|
||||
@@ -71,7 +71,7 @@ Add this script to your page.
|
||||
It's also available on [jsDelivr](http://www.jsdelivr.com/projects/eruda) and [cdnjs](https://cdnjs.com/libraries/eruda).
|
||||
|
||||
```html
|
||||
<script src="//cdn.jsdelivr.net/npm/eruda"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/eruda"></script>
|
||||
<script>eruda.init();</script>
|
||||
```
|
||||
|
||||
@@ -124,6 +124,7 @@ eruda.init({
|
||||
* [eruda-geolocation](https://github.com/liriliri/eruda-geolocation): Test geolocation.
|
||||
* [eruda-orientation](https://github.com/liriliri/eruda-orientation): Test orientation api.
|
||||
* [eruda-touches](https://github.com/liriliri/eruda-touches): Visualize screen touches.
|
||||
* [eruda-vue](https://github.com/liriliri/eruda-vue): Vue devtools.
|
||||
|
||||
If you want to create a plugin yourself, follow the guides [here](https://eruda.liriliri.io/docs/plugin.html).
|
||||
|
||||
|
||||
10
package.json
10
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "eruda",
|
||||
"version": "3.2.3",
|
||||
"version": "3.4.0",
|
||||
"description": "Console for Mobile Browsers",
|
||||
"main": "eruda.js",
|
||||
"browserslist": [
|
||||
@@ -45,7 +45,7 @@
|
||||
"autoprefixer": "^9.7.4",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-loader": "^8.2.5",
|
||||
"chobitsu": "^1.5.1",
|
||||
"chobitsu": "^1.8.1",
|
||||
"core-js": "^3.37.1",
|
||||
"css-loader": "^3.4.2",
|
||||
"es-check": "^6.2.1",
|
||||
@@ -61,11 +61,11 @@
|
||||
"karma-jquery": "^0.2.4",
|
||||
"karma-sourcemap-loader": "^0.3.7",
|
||||
"karma-webpack": "^5.0.0",
|
||||
"licia": "^1.41.0",
|
||||
"luna-box-model": "^0.1.0",
|
||||
"licia": "^1.42.0",
|
||||
"luna-box-model": "^1.0.0",
|
||||
"luna-console": "^1.3.4",
|
||||
"luna-data-grid": "^0.6.0",
|
||||
"luna-dom-viewer": "^1.3.0",
|
||||
"luna-dom-viewer": "^1.4.0",
|
||||
"luna-modal": "^1.2.3",
|
||||
"luna-notification": "^0.3.2",
|
||||
"luna-object-viewer": "^0.3.1",
|
||||
|
||||
@@ -15,6 +15,7 @@ import extend from 'licia/extend'
|
||||
import isStr from 'licia/isStr'
|
||||
import startWith from 'licia/startWith'
|
||||
import ready from 'licia/ready'
|
||||
import pointerEvent from 'licia/pointerEvent'
|
||||
import evalCss from '../lib/evalCss'
|
||||
import emitter from '../lib/emitter'
|
||||
import { isDarkTheme } from '../lib/themes'
|
||||
@@ -23,7 +24,6 @@ import LunaModal from 'luna-modal'
|
||||
import LunaTab from 'luna-tab'
|
||||
import {
|
||||
classPrefix as c,
|
||||
drag,
|
||||
eventClient,
|
||||
hasSafeArea,
|
||||
safeStorage,
|
||||
@@ -358,8 +358,8 @@ export default class DevTools extends Emitter {
|
||||
|
||||
$resizer.css('height', '100%')
|
||||
|
||||
$document.on(drag('move'), moveListener)
|
||||
$document.on(drag('end'), endListener)
|
||||
$document.on(pointerEvent('move'), moveListener)
|
||||
$document.on(pointerEvent('up'), endListener)
|
||||
}
|
||||
const moveListener = (e) => {
|
||||
if (!this._isResizing) {
|
||||
@@ -385,11 +385,11 @@ export default class DevTools extends Emitter {
|
||||
|
||||
$resizer.css('height', 10)
|
||||
|
||||
$document.off(drag('move'), moveListener)
|
||||
$document.off(drag('end'), endListener)
|
||||
$document.off(pointerEvent('move'), moveListener)
|
||||
$document.off(pointerEvent('up'), endListener)
|
||||
}
|
||||
$resizer.css('height', 10)
|
||||
$resizer.on(drag('start'), startListener)
|
||||
$resizer.on(pointerEvent('down'), startListener)
|
||||
|
||||
$navBar.on('contextmenu', (e) => e.preventDefault())
|
||||
this.$container.on('click', (e) => e.stopPropagation())
|
||||
|
||||
@@ -17,6 +17,7 @@ import isBool from 'licia/isBool'
|
||||
import safeGet from 'licia/safeGet'
|
||||
import $ from 'licia/$'
|
||||
import h from 'licia/h'
|
||||
import extend from 'licia/extend'
|
||||
import MutationObserver from 'licia/MutationObserver'
|
||||
import CssStore from './CssStore'
|
||||
import Settings from '../Settings/Settings'
|
||||
@@ -31,10 +32,10 @@ export default class Detail {
|
||||
this._$container = $container
|
||||
this._devtools = devtools
|
||||
this._curEl = document.documentElement
|
||||
this._bindEvent()
|
||||
this._initObserver()
|
||||
this._initCfg()
|
||||
this._initTpl()
|
||||
this._bindEvent()
|
||||
}
|
||||
show(el) {
|
||||
this._curEl = el
|
||||
@@ -42,18 +43,7 @@ export default class Detail {
|
||||
this._computedStyleSearchKeyword = ''
|
||||
this._enableObserver()
|
||||
this._render()
|
||||
|
||||
const { nodeId } = chobitsu.domain('DOM').getNodeId({ node: el })
|
||||
chobitsu.domain('Overlay').highlightNode({
|
||||
nodeId,
|
||||
highlightConfig: {
|
||||
showInfo: true,
|
||||
contentColor: 'rgba(111, 168, 220, .66)',
|
||||
paddingColor: 'rgba(147, 196, 125, .55)',
|
||||
borderColor: 'rgba(255, 229, 153, .66)',
|
||||
marginColor: 'rgba(246, 178, 107, .66)',
|
||||
},
|
||||
})
|
||||
this._highlight()
|
||||
}
|
||||
hide = () => {
|
||||
this._$container.hide()
|
||||
@@ -87,6 +77,36 @@ export default class Detail {
|
||||
if (this._origAddEvent) winEventProto.addEventListener = this._origAddEvent
|
||||
if (this._origRmEvent) winEventProto.removeEventListener = this._origRmEvent
|
||||
}
|
||||
_highlight = (type) => {
|
||||
const el = this._curEl
|
||||
|
||||
const highlightConfig = {
|
||||
showInfo: false,
|
||||
}
|
||||
if (!type || type === 'all') {
|
||||
extend(highlightConfig, {
|
||||
showInfo: true,
|
||||
contentColor: 'rgba(111, 168, 220, .66)',
|
||||
paddingColor: 'rgba(147, 196, 125, .55)',
|
||||
borderColor: 'rgba(255, 229, 153, .66)',
|
||||
marginColor: 'rgba(246, 178, 107, .66)',
|
||||
})
|
||||
} else if (type === 'margin') {
|
||||
highlightConfig.marginColor = 'rgba(246, 178, 107, .66)'
|
||||
} else if (type === 'border') {
|
||||
highlightConfig.borderColor = 'rgba(255, 229, 153, .66)'
|
||||
} else if (type === 'padding') {
|
||||
highlightConfig.paddingColor = 'rgba(147, 196, 125, .55)'
|
||||
} else if (type === 'content') {
|
||||
highlightConfig.contentColor = 'rgba(111, 168, 220, .66)'
|
||||
}
|
||||
|
||||
const { nodeId } = chobitsu.domain('DOM').getNodeId({ node: el })
|
||||
chobitsu.domain('Overlay').highlightNode({
|
||||
nodeId,
|
||||
highlightConfig,
|
||||
})
|
||||
}
|
||||
_initTpl() {
|
||||
const $container = this._$container
|
||||
|
||||
@@ -257,7 +277,9 @@ export default class Detail {
|
||||
const events = el.erudaEvents
|
||||
if (events && keys(events).length !== 0) ret.listeners = events
|
||||
|
||||
if (needNoStyle(tagName)) return ret
|
||||
if (needNoStyle(tagName)) {
|
||||
return ret
|
||||
}
|
||||
|
||||
let computedStyle = cssStore.getComputedStyle()
|
||||
|
||||
@@ -321,6 +343,8 @@ export default class Detail {
|
||||
this._render()
|
||||
devtools.notify('Refreshed', { icon: 'success' })
|
||||
})
|
||||
|
||||
this._boxModel.on('highlight', this._highlight)
|
||||
}
|
||||
_initObserver() {
|
||||
this._observer = new MutationObserver((mutations) => {
|
||||
@@ -450,8 +474,9 @@ function rmDefComputedStyle(computedStyle, styles) {
|
||||
|
||||
const NO_STYLE_TAG = ['script', 'style', 'meta', 'title', 'link', 'head']
|
||||
|
||||
const needNoStyle = (tagName) =>
|
||||
const needNoStyle = (tagName) => {
|
||||
NO_STYLE_TAG.indexOf(tagName.toLowerCase()) > -1
|
||||
}
|
||||
|
||||
const wrapLink = (link) => `<a href="${link}" target="_blank">${link}</a>`
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import evalCss from '../lib/evalCss'
|
||||
import Detail from './Detail'
|
||||
import chobitsu from '../lib/chobitsu'
|
||||
import emitter from '../lib/emitter'
|
||||
import { formatNodeName } from './util'
|
||||
import { formatNodeName, isShadowRoot } from './util'
|
||||
|
||||
export default class Elements extends Tool {
|
||||
constructor() {
|
||||
@@ -118,7 +118,7 @@ export default class Elements extends Tool {
|
||||
if (this._curNode.nodeType === Node.ELEMENT_NODE) {
|
||||
this._detail.show(this._curNode)
|
||||
} else {
|
||||
this._detail.show(this._curNode.parentNode)
|
||||
this._detail.show(this._curNode.parentNode || this._curNode.host)
|
||||
}
|
||||
}
|
||||
_initTpl() {
|
||||
@@ -309,7 +309,14 @@ function getCrumbs(el) {
|
||||
idx: i++,
|
||||
})
|
||||
|
||||
el = el.parentElement
|
||||
if (isShadowRoot(el)) {
|
||||
el = el.host
|
||||
}
|
||||
if (!el.parentElement && isShadowRoot(el.parentNode)) {
|
||||
el = el.parentNode
|
||||
} else {
|
||||
el = el.parentElement
|
||||
}
|
||||
}
|
||||
|
||||
return ret.reverse()
|
||||
|
||||
@@ -7,6 +7,8 @@ export function formatNodeName(node, { noAttr = false } = {}) {
|
||||
return `<span class="${c('tag-name-color')}">(text)</span>`
|
||||
} else if (node.nodeType === Node.COMMENT_NODE) {
|
||||
return `<span class="${c('tag-name-color')}"><!--></span>`
|
||||
} else if (isShadowRoot(node)) {
|
||||
return `<span class="${c('tag-name-color')}">#shadow-root</span>`
|
||||
}
|
||||
|
||||
const { id, className, attributes } = node
|
||||
@@ -34,3 +36,11 @@ export function formatNodeName(node, { noAttr = false } = {}) {
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
export function isShadowRoot(node) {
|
||||
if (window.ShadowRoot) {
|
||||
return node instanceof ShadowRoot
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -4,7 +4,8 @@ import Emitter from 'licia/Emitter'
|
||||
import $ from 'licia/$'
|
||||
import nextTick from 'licia/nextTick'
|
||||
import orientation from 'licia/orientation'
|
||||
import { pxToNum, classPrefix as c, drag, eventClient } from '../lib/util'
|
||||
import pointerEvent from 'licia/pointerEvent'
|
||||
import { pxToNum, classPrefix as c, eventClient } from '../lib/util'
|
||||
import evalCss from '../lib/evalCss'
|
||||
|
||||
const $document = $(document)
|
||||
@@ -93,8 +94,8 @@ export default class EntryBtn extends Emitter {
|
||||
this._oldX = pxToNum($el.css('left'))
|
||||
this._oldY = pxToNum($el.css('top'))
|
||||
this._startY = eventClient('y', e)
|
||||
$document.on(drag('move'), this._onDragMove)
|
||||
$document.on(drag('end'), this._onDragEnd)
|
||||
$document.on(pointerEvent('move'), this._onDragMove)
|
||||
$document.on(pointerEvent('up'), this._onDragEnd)
|
||||
}
|
||||
_onDragMove = (e) => {
|
||||
const btnSize = this._$el.get(0).offsetWidth
|
||||
@@ -132,8 +133,8 @@ export default class EntryBtn extends Emitter {
|
||||
}
|
||||
|
||||
this._onDragMove(e)
|
||||
$document.off(drag('move'), this._onDragMove)
|
||||
$document.off(drag('end'), this._onDragEnd)
|
||||
$document.off(pointerEvent('move'), this._onDragMove)
|
||||
$document.off(pointerEvent('up'), this._onDragEnd)
|
||||
|
||||
const cfg = this.config
|
||||
|
||||
@@ -149,7 +150,7 @@ export default class EntryBtn extends Emitter {
|
||||
_bindEvent() {
|
||||
const $el = this._$el
|
||||
|
||||
$el.on(drag('start'), this._onDragStart)
|
||||
$el.on(pointerEvent('down'), this._onDragStart)
|
||||
|
||||
orientation.on('change', () => this._resetPos(true))
|
||||
window.addEventListener('resize', () => this._resetPos())
|
||||
|
||||
@@ -230,11 +230,10 @@ export default class Resources extends Tool {
|
||||
const imageState = getState('image', imageData.length)
|
||||
let imageDataHtml = '<li>Empty</li>'
|
||||
if (!isEmpty(imageData)) {
|
||||
// prettier-ignore
|
||||
imageDataHtml = map(imageData, (image) => {
|
||||
return `<li class="${c('image')}">
|
||||
<img src="${escape(image)}" data-exclude="true" class="${c(
|
||||
'img-link'
|
||||
)}"/>
|
||||
<img src="${escape(image)}" data-exclude="true" class="${c('img-link')}"/>
|
||||
</li>`
|
||||
}).join('')
|
||||
}
|
||||
|
||||
@@ -56,12 +56,19 @@
|
||||
font-size: $font-size-s;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: $padding !important;
|
||||
@include clear-float();
|
||||
padding-left: $padding;
|
||||
padding-top: $padding;
|
||||
&::after {
|
||||
content: '';
|
||||
flex-grow: 1000;
|
||||
}
|
||||
li {
|
||||
flex-grow: 1;
|
||||
cursor: pointer;
|
||||
overflow-y: hidden;
|
||||
margin-right: $padding;
|
||||
margin-bottom: $padding;
|
||||
border: 1px solid var(--border);
|
||||
&.image {
|
||||
height: 100px;
|
||||
font-size: 0;
|
||||
|
||||
@@ -93,6 +93,13 @@ export default [
|
||||
},
|
||||
desc: 'Scale down the whole page to fit screen',
|
||||
},
|
||||
{
|
||||
name: 'Load Vue Plugin',
|
||||
fn() {
|
||||
loadPlugin('vue')
|
||||
},
|
||||
desc: 'Vue devtools',
|
||||
},
|
||||
{
|
||||
name: 'Load Monitor Plugin',
|
||||
fn() {
|
||||
@@ -225,4 +232,5 @@ const pluginVersion = {
|
||||
geolocation: '2.1.0',
|
||||
orientation: '2.1.1',
|
||||
touches: '2.1.0',
|
||||
vue: '1.1.1',
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import isUndef from 'licia/isUndef'
|
||||
import last from 'licia/last'
|
||||
import map from 'licia/map'
|
||||
import memStorage from 'licia/memStorage'
|
||||
import root from 'licia/root'
|
||||
import toNum from 'licia/toNum'
|
||||
import trim from 'licia/trim'
|
||||
import html from 'licia/html'
|
||||
@@ -147,32 +146,6 @@ function processClass(str) {
|
||||
}).join(' ')
|
||||
}
|
||||
|
||||
const hasTouchSupport = 'ontouchstart' in root
|
||||
const hasPointerSupport = 'PointerEvent' in root
|
||||
const touchEvents = {
|
||||
start: 'touchstart',
|
||||
move: 'touchmove',
|
||||
end: 'touchend',
|
||||
}
|
||||
const mouseEvents = {
|
||||
start: 'mousedown',
|
||||
move: 'mousemove',
|
||||
end: 'mouseup',
|
||||
}
|
||||
const pointerEvents = {
|
||||
start: 'pointerdown',
|
||||
move: 'pointermove',
|
||||
end: 'pointerup',
|
||||
}
|
||||
|
||||
export function drag(name) {
|
||||
if (hasPointerSupport) {
|
||||
return pointerEvents[name]
|
||||
}
|
||||
|
||||
return hasTouchSupport ? touchEvents[name] : mouseEvents[name]
|
||||
}
|
||||
|
||||
export function eventClient(type, e) {
|
||||
const name = type === 'x' ? 'clientX' : 'clientY'
|
||||
|
||||
|
||||
@@ -449,9 +449,14 @@
|
||||
}
|
||||
|
||||
.luna-box-model {
|
||||
background: transparent;
|
||||
background: var(--background);
|
||||
}
|
||||
|
||||
.luna-box-model-position {
|
||||
.luna-box-model-position,
|
||||
.luna-box-model-margin,
|
||||
.luna-box-model-border,
|
||||
.luna-box-model-padding,
|
||||
.luna-box-model-content {
|
||||
color: var(--foreground);
|
||||
background: var(--background);
|
||||
}
|
||||
|
||||
@@ -116,5 +116,13 @@
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
color: inherit;
|
||||
font-size: 1em;
|
||||
font-style: inherit;
|
||||
font-variant: inherit;
|
||||
font-weight: inherit;
|
||||
line-height: inherit;
|
||||
text-decoration: inherit;
|
||||
white-space: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user