Skip to content

Commit

Permalink
feat(runtime): 静态 html 解析器支持解析 style 标签 (#8413)
Browse files Browse the repository at this point in the history
* feat(runtime): 静态 html 解析器支持解析 style 标签

目前能支持:标签、id、class、属性、分组选择器,后代、子代、一般兄弟、紧邻兄弟组合器

* fix: ci
  • Loading branch information
Chen-jj authored Jan 4, 2021
1 parent 3f48a63 commit 0602643
Show file tree
Hide file tree
Showing 19 changed files with 635 additions and 2,464 deletions.
2 changes: 2 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ module.exports = {
'rules': {
'no-unused-vars': 'off',
'@typescript-eslint/explicit-function-return-type': 0,
"indent": "off",
'@typescript-eslint/indent': ['error', 2],
'@typescript-eslint/explicit-module-boundary-types': 0,
'@typescript-eslint/no-unused-vars': ['error', { 'argsIgnorePattern': '^_', 'args': 'after-used', }],
'@typescript-eslint/no-empty-function': 0,
'@typescript-eslint/no-use-before-define': 0,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"release:lerna": "lerna version --exact --no-git-tag-version",
"release:beta": "lerna publish --force-publish=* --exact --skip-temp-tag --preid=beta --npm-tag=beta",
"release": "npm-run-all build release:lerna && npm run changelog && node ./build/docs-version.js",
"test": "lerna run --parallel --scope babel-preset-taro --scope @tarojs/components --scope @tarojs/loader --scope @tarojs/react --scope @tarojs/webpack-runner --scope @tarojs/mini-runner test:ci"
"test": "lerna run --parallel --scope babel-preset-taro --scope @tarojs/components --scope @tarojs/loader --scope @tarojs/react --scope @tarojs/webpack-runner --scope @tarojs/mini-runner --scope @tarojs/runtime test:ci"
},
"repository": {
"type": "git",
Expand Down
13 changes: 0 additions & 13 deletions packages/taro-runtime/__tests__/html.spec.js

This file was deleted.

8 changes: 6 additions & 2 deletions packages/taro-runtime/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ module.exports = {
transform: {
...tsjPreset.transform
},
transformIgnorePatterns: [
'node_modules/(?!(lodash-es)/)'
],
testURL: 'http://localhost/',
collectCoverage: true,
collectCoverage: false,
coveragePathIgnorePatterns: [
'nerv.js',
'vue.js',
Expand Down Expand Up @@ -37,7 +40,8 @@ module.exports = {
'utils'
],
moduleNameMapper: {
'@tarojs/shared': path.resolve(__dirname, '..', '..', 'packages/shared/src/index.ts')
'@tarojs/shared': path.resolve(__dirname, '..', '..', 'packages/shared/src/index.ts'),
'@tarojs/react': path.resolve(__dirname, '..', '..', 'packages/taro-react/dist/index.js')
},
// setupFiles: ['<rootDir>/__tests__/setup.js'],
testMatch: ['**/__tests__/?(*.)+(spec|test).[jt]s?(x)']
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
describe('DOM', () => {
process.env.FRAMEWORK = 'nerv'
const runtime = require('../dist/runtime.esm')
const runtime = require('../../dist/runtime.esm')
const document = runtime.document
global.document = runtime.document
global.window = runtime.window
global.navigator = runtime.navigator
const React = require('./nerv')
// eslint-disable-next-line no-use-before-define
const React = require('react')
const ReactDOM = require('@tarojs/react')

afterAll(() => {
process.env.FRAMEWORK = ''
Expand Down Expand Up @@ -247,7 +249,7 @@ describe('DOM', () => {

const div = document.createElement('div')
// eslint-disable-next-line react/no-deprecated
React.render(<App />, div)
ReactDOM.render(<App />, div)
expect(div.textContent).toBe(' a bc')
})
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
describe('event', () => {
const runtime = require('../dist/runtime.esm')
const runtime = require('../../dist/runtime.esm')
const document = runtime.document

afterAll(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
describe('style', () => {
const runtime = require('../dist/runtime.esm')
const runtime = require('../../dist/runtime.esm')

afterAll(() => {
process.env.FRAMEWORK = ''
Expand Down
289 changes: 289 additions & 0 deletions packages/taro-runtime/src/__tests__/html.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,289 @@
// import { Scaner } from '../src/html/scaner'
// import { parser } from '../src/html/oparser'
import { parser } from '../dom/html/parser'
import { isElement } from '../utils'

// 测试还没写完,先跳过
describe.skip('html', () => {
test('tt', () => {
const s = '<h1 style="color:red" class="fork">This is a Heading</h1>'
// const tokens = new Scaner(s).scan()
// debugger
// const html = parser(tokens)

parser(s)
})
})

describe('html with <style>', () => {
it('tag selector', () => {
const html = `
<style>
span {
color: red;
font-size: 10;
}
</style>
<div class="parent">
<span></span>
<span></span>
</div>
`
const res = parser(html)
const el0 = res[0].children[0]
const el1 = res[0].children[0]
expect(el0.style.cssText).toBe('color: red;font-size: 10;')
expect(el1.style.cssText).toBe('color: red;font-size: 10;')
})

it('id selector', () => {
const html = `
<style>
#foo {
color: red;
font-size: 10;
}
</style>
<div class="parent">
<div></div>
<div id="foo"></div>
</div>
`
const res = parser(html)
const el = res[0].children[1]
expect(el.style.cssText).toBe('color: red;font-size: 10;')
})

it('class selector', () => {
const html = `
<style>
.parent {
background: red
}
.item {
font-weight: bold;
}
.child-1 {
color: red;
font-size: 10;
}
.item.child-2 {
margin: 10px;
}
</style>
<div class="parent" style="border: 1px;padding: 10px;">
<div class="item child-1"></div>
<div class="item child-2"></div>
</div>
`
const res = parser(html)
const el0 = res[0]
const el1 = res[0].children[0]
const el2 = res[0].children[1]
expect(el0.style.cssText).toBe('background: red;border: 1px;padding: 10px;')
expect(el1.style.cssText).toBe('font-weight: bold;color: red;font-size: 10;')
expect(el2.style.cssText).toBe('font-weight: bold;margin: 10px;')
})

it('attributes selector', () => {
const html = `
<style>
[name="title"] {
color: red;
}
[name="body"][content='hello-world'] {
font-size: 10;
}
</style>
<div>
<div name="title"></div>
<div name="body" content="hello-world"></div>
</div>
`
const res = parser(html)
const el0 = res[0].children[0]
const el1 = res[0].children[1]
expect(el0.style.cssText).toBe('color: red;')
expect(el1.style.cssText).toBe('font-size: 10;')
})

it('combination', () => {
const html = `
<style>
div[name="top"].wrapper#foo.title.fixed[size="large"] {
background: red
}
</style>
<div id="foo" class="wrapper title fixed" name="top" size="large"></div>
`
const res = parser(html)
const el0 = res[0]
expect(el0.style.cssText).toBe('background: red;')
})

it('selector list', () => {
const html = `
<style>
.item.child-1, #foo {
color: red;
}
</style>
<div class="parent">
<div class="item child-1"></div>
<div class="item child-2"></div>
<div id="foo"></div>
</div>
`
const res = parser(html)
const el0 = res[0].children[0]
const el1 = res[0].children[2]
expect(el0.style.cssText).toBe('color: red;')
expect(el1.style.cssText).toBe('color: red;')
})

it('descendant combinator', () => {
const html = `
<style>
div.parent span.item {
background: red
}
.parent .inner[name='title'] {
color: blue;
}
.ul .li {
width: 100%;
}
</style>
<div class="parent" id="body">
<span class="item child-1"></span>
<div class="item child-2">
<div name='title' class='inner'></div>
</div>
<div class='ul'>
<div class="li"></div>
<div class="li"></div>
</div>
</div>
<div>
<div name='title' class='inner'></div>
<div class="li"></div>
</div>
`
const res = parser(html).filter(isElement)
const el0 = res[0].children[0]
const el1 = res[0].children[1]
const el2 = res[0].children[1].children[0]
const el3 = res[1].children[0]
const el4 = res[0].children[2].children[0]
const el5 = res[0].children[2].children[1]
const el6 = res[1].children[1]
expect(el0.style.cssText).toBe('background: red;')
expect(el1.style.cssText).toBe('')
expect(el2.style.cssText).toBe('color: blue;')
expect(el3.style.cssText).toBe('')
expect(el4.style.cssText).toBe('width: 100%;')
expect(el5.style.cssText).toBe('width: 100%;')
expect(el6.style.cssText).toBe('')
})

it('child combinator', () => {
const html = `
<style>
.ul>.li {
width: 100%;
}
.inner .ul > .li {
color: red;
}
</style>
<div class='ul'>
<div class="li"></div>
<div class='inner'>
<div class="li">
<div class='ul'>
<div class="li"></div>
</div>
</div>
</div>
<div>
<div class="ul li">
<div class='li'></div>
</div>
</div>
</div>
`
const res = parser(html).filter(isElement)
const el1 = res[0].children[0]
const el2 = res[0].children[1].children[0]
const el3 = res[0].children[1].children[0].children[0].children[0]
const el4 = res[0].children[2].children[0].children[0]
expect(el1.style.cssText).toBe('width: 100%;')
expect(el2.style.cssText).toBe('')
expect(el3.style.cssText).toBe('width: 100%;color: red;')
expect(el4.style.cssText).toBe('width: 100%;')
})

it('adjacent sibling combinator', () => {
const html = `
<style>
.first+.li.second #inner {
width: 100%;
}
.first + .third {
color: red;
}
.second + .third {
color: blue;
}
</style>
<div class='ul'>
<div class="li first"></div>
<div class='li second'>
<div id='inner'></div>
</div>
<div class='li third'></div>
</div>
`
const res = parser(html).filter(isElement)
const el1 = res[0].children[0]
const el2 = res[0].children[1]
const el3 = res[0].children[1].children[0]
const el4 = res[0].children[2]
expect(el1.style.cssText).toBe('')
expect(el2.style.cssText).toBe('')
expect(el3.style.cssText).toBe('width: 100%;')
expect(el4.style.cssText).toBe('color: blue;')
})

it('general sibling combinator', () => {
const html = `
<style>
.third ~ .second {
font-size: 10px;
}
.first ~ .third {
color: red;
}
.first~.li.third #inner {
width: 100%;
}
</style>
<div class='ul'>
<div class="li first"></div>
<div class='li second'></div>
<div class='li third'>
<div id='inner'></div>
</div>
</div>
`
const res = parser(html).filter(isElement)
const el1 = res[0].children[0]
const el2 = res[0].children[1]
const el3 = res[0].children[2]
const el4 = res[0].children[2].children[0]
expect(el1.style.cssText).toBe('')
expect(el2.style.cssText).toBe('')
expect(el3.style.cssText).toBe('color: red;')
expect(el4.style.cssText).toBe('width: 100%;')
})
})
Loading

0 comments on commit 0602643

Please sign in to comment.