diff --git a/docs/docs/interactive-mip/event-and-action.md b/docs/docs/interactive-mip/event-and-action.md index fd9bbbf6..f7aa68a3 100644 --- a/docs/docs/interactive-mip/event-and-action.md +++ b/docs/docs/interactive-mip/event-and-action.md @@ -10,7 +10,7 @@ MIP 提供了 `on` 属性来定义对组件的事件绑定与事件触发时的 class="example-button" on="tap: top-example.hide, - MIP.scrollTo(id='mip-scrollto-button', duration=500, position='center')" + MIP.scrollTo({id: 'mip-scrollto-button', duration: 500, position: 'center'})" >点击返回原示例 @@ -46,7 +46,7 @@ MIP 提供了 `on` 属性来定义对组件的事件绑定与事件触发时的
点我
-
+
``` ### 多事件绑定与多行为触发 @@ -57,7 +57,7 @@ MIP 提供了 `on` 属性来定义对组件的事件绑定与事件触发时的 无法显示文字 - +

文字2

``` @@ -223,7 +225,7 @@ MIP 为所有元素(包括普通 HTML 和 MIP 元素)都提供了一些默 - +

文字2

@@ -232,7 +234,7 @@ MIP 为所有元素(包括普通 HTML 和 MIP 元素)都提供了一些默 ```html - + ``` 效果如下所示: @@ -240,7 +242,7 @@ MIP 为所有元素(包括普通 HTML 和 MIP 元素)都提供了一些默
@@ -271,12 +273,14 @@ MIP 为所有元素(包括普通 HTML 和 MIP 元素)都提供了一些默 |行为|描述| |---|---| |setData({
  [name]: Expression
}) |将数据合并到到全局状态树中,结合数据绑定,写入数据时允许写有限的计算表达式进行运算。
更多内容请参考[数据绑定](./data-binding/mip-bind.md)
如:`MIP.setData({ a: 1 + 1, b: 'hello' })`| -|navigateTo(
  url=STRING,
  target=STRING,
  opener=BOOLEAN
) |跳转到指定 `url` 页面。
参数 `url` 为必填参数,要跳转到的目标页面 URL
参数 `target` 为必填参数,只可取 `_top` 或 `_blank`。
`opener` 为可选参数,用于指定在 `target=_blank` 时新打开的页面能否访问到 `window.opener`。
如:`MIP.navigateTo(url='https://www.baidu.com', target='_blank')`| -|closeOrNavigateTo(
  url=STRING,
  target=STRING,
  opener=BOOLEAN
)|关闭当前页面,如果失败则如 `navigateTo` 跳转。一般用作新打开页面的后退操作。
参数说明与示例用法同上。| -|scrollTo(
  id=STRING,
  duration=INTEGER,
  position=STRING
) |视口滚动到 `id` 元素的位置,类似于全局元素方法 `element-id.scrollTo`。
参数 `id` 为必填参数,用于指定要滚动到的元素
参数 `duration` 为可选参数
参数 `position` 为可选参数。| +|navigateTo({
  url: STRING,
  target: STRING,
  opener: BOOLEAN
}) |跳转到指定 `url` 页面。
参数 `url` 为必填参数,要跳转到的目标页面 URL
参数 `target` 为必填参数,只可取 `_top` 或 `_blank`。
`opener` 为可选参数,用于指定在 `target=_blank` 时新打开的页面能否访问到 `window.opener`。
如:`MIP.navigateTo({ url: 'https://www.baidu.com', target: '_blank' })`| +|closeOrNavigateTo({
  url: STRING,
  target: STRING,
  opener: BOOLEAN
})|关闭当前页面,如果失败则如 `navigateTo` 跳转。一般用作新打开页面的后退操作。
参数说明与示例用法同上。| +|scrollTo({
  id: STRING,
  duration: INTEGER,
  position: STRING
}) |视口滚动到 `id` 元素的位置,类似于全局元素方法 `element-id.scrollTo`。
参数 `id` 为必填参数,用于指定要滚动到的元素
参数 `duration` 为可选参数
参数 `position` 为可选参数。| |goBack |返回上一个页面,效果等同于 `window.history.back()`
如:`MIP.goBack`| |print |打开当前页面的打印对话框
如:`MIP.print`| +[info] 在参数写法上,我们兼容了 AMP 的语法,因此也可以使用类似 AMP 的书写方式传入参数:`MIP.navigateTo(url='https://www.baidu.com', target='_blank')` + 下面是一些 MIP 方法的一些使用示例: #### MIP.setData @@ -316,14 +320,14 @@ MIP 为所有元素(包括普通 HTML 和 MIP 元素)都提供了一些默 需要说明的是,在通常情况下,应优先使用 `` 的形式实现页面跳转,因为 a 链的形式更有利于搜索引擎的抓取和分析。 ```html - - + + ``` 效果如下所示:
- - + +
@@ -331,7 +335,7 @@ MIP 为所有元素(包括普通 HTML 和 MIP 元素)都提供了一些默 ```html - + ``` 效果如下所示: @@ -342,7 +346,7 @@ MIP 为所有元素(包括普通 HTML 和 MIP 元素)都提供了一些默 id="mip-scrollto-button" on="tap: top-example.show, - MIP.scrollTo(id='top-button', duration=500, position='center')" + MIP.scrollTo({ id: 'top-button', duration: 500, position: 'center' })" >滚动到顶部 id 为 top-button 的按钮处 @@ -392,11 +396,11 @@ mip-action-macro 主要提供的功能包括: - - + + ``` 效果如下所示: @@ -416,11 +420,11 @@ mip-action-macro 主要提供的功能包括: - - + + @@ -431,7 +435,7 @@ mip-action-macro 主要提供的功能包括: class="example-button" on="tap: bottom-example.hide, - scroll-button.scrollTo(duration=500, position='center')" + scroll-button.scrollTo({ duration: 500, position: 'center' })" >点击返回原示例 diff --git a/docs/docs/interactive-mip/expression.md b/docs/docs/interactive-mip/expression.md index 77309038..935fe5f9 100644 --- a/docs/docs/interactive-mip/expression.md +++ b/docs/docs/interactive-mip/expression.md @@ -77,7 +77,8 @@ MIP 支持有限的运算符,利用这些运算符的相互组合,基本能 |类型|说明|示例| |---|----|---| |`( expr )`| 分组运算符(小括号) | `1 + (2 - 3)` | -| `{ attr: vaue }` | 字面量对象 | `{a: 1, b: 2, c: 3 + 4}` | +| `{ attr: value }` | 字面量对象 | `{a: 1, b: 2, c: 3 + 4}` | +| `{ [ expr ]: value }` | 可计算属性名的字面量对象 | `{ ['a' + 'bc']: 3 + 4}` | | `[ item, item ]` | 字面量数组 | `[2, 1, 3]` | |`expr . attr`| 属性运算符(点运算符) | `userInfo.name` | |`expr[ expr ]`| 计算属性 | `userInfo['name']` | @@ -118,7 +119,7 @@ MIP 还支持使用部分原型链方法,比如下面举例的一些常见的 |----|----|----| |Array|concat
filter
indexOf
join
lastIndexOf
map
reduce
slice
some
every
find
sort(修改)
splice(修改)| 为了提升 MIP 表达式中的数组操作体验,我们修改了 sort 和 splice 方法,这两个方法将不会对原数组造成影响。
其中 sort 将返回排序后的新数组;
同时 splice 返回进行插入或删除操作之后的新数组。
`// 返回新的对象 [1, 2, 3]`
`[2, 1, 3].sort()`
`// 返回新的对象 [1, 3]`
`[1, 2, 3].splice(1, 1)`
`// false`
`[1, 2, 3].some(num => num > 4)`
| |Number|toExponential
toFixed
toPrecision
toString| `// 返回 1.2`
`(1.23).toFixed(1)`| -|String|charAt
charCodeAt
concat
indexOf
lastIndexOf
slice
split
substr
substring
toLowerCase
toUpperCase | `// 返回 ['1', '2', '3']`
`'123'.split()` | +|String|charAt
charCodeAt
concat
indexOf
lastIndexOf
slice
split
substr
substring
toLowerCase
toUpperCase
trim| `// 返回 ['1', '2', '3']`
`'123'.split()` | ## 函数表达式 @@ -170,18 +171,3 @@ MIP 还支持使用部分原型链方法,比如下面举例的一些常见的 [1, 2, 3].map(item => item++) ``` - - - - - - - - - - - - - - - diff --git a/docs/docs/interactive-mip/introduction.md b/docs/docs/interactive-mip/introduction.md index b30d3798..965fa085 100644 --- a/docs/docs/interactive-mip/introduction.md +++ b/docs/docs/interactive-mip/introduction.md @@ -41,11 +41,11 @@ MIP 提供了为数众多的官方组件来满足开发者的需求。这些组 ```html ``` @@ -54,13 +54,13 @@ MIP 提供了为数众多的官方组件来满足开发者的需求。这些组
@@ -205,10 +205,7 @@ MIP 交互机制旨在提升 MIP 页面的可交互性,在 MIP 核心机制和

您已滚动至页面底部

- - - diff --git a/packages/mip/src/util/event-action/grammar/basic.js b/packages/mip/src/util/event-action/grammar/basic.js index 2cb527d2..fd16fce1 100644 --- a/packages/mip/src/util/event-action/grammar/basic.js +++ b/packages/mip/src/util/event-action/grammar/basic.js @@ -223,10 +223,29 @@ export const $variable = lex.set({ } }) +export const $computedProperty = lex.set({ + type: 'ComputedProperty', + rule: () => [ + $leftBracket, + _, + $conditional, + _, + $rightBracket + ], + match (args) { + return { + type: 'Member', + computed: true, + property: args[2] + } + } +}) + export const $property = lex.set({ type: 'Property', rule: () => [ [or, [ + $computedProperty, $identifier, $string, $number @@ -237,10 +256,23 @@ export const $property = lex.set({ $conditional ], match (args) { - return { - key: args[0], + let key = args[0] + let result = { value: args[4] } + + if (key.computed) { + result.computed = true + result.key = key.property + } else { + result.key = key + } + + return result + // return { + // key: args[0], + // value: args[4] + // } } }) @@ -310,24 +342,6 @@ export const $primary = lex.set({ ]] }) -export const $computedProperty = lex.set({ - type: 'ComputedProperty', - rule: () => [ - $leftBracket, - _, - $conditional, - _, - $rightBracket - ], - match (args) { - return { - type: 'Member', - computed: true, - property: args[2] - } - } -}) - export const $identifierProperty = lex.set({ type: 'IdentifierProperty', rule: [ diff --git a/packages/mip/src/util/event-action/grammar/event-argument.js b/packages/mip/src/util/event-action/grammar/event-argument.js index ad2e9c91..79f36c89 100644 --- a/packages/mip/src/util/event-action/grammar/event-argument.js +++ b/packages/mip/src/util/event-action/grammar/event-argument.js @@ -8,8 +8,6 @@ import { or, any, opt - // , - // def } from '../../parser/lexer' import { @@ -20,6 +18,7 @@ import { import { $conditional, + $object, $number, $literal, $variable, @@ -162,12 +161,23 @@ export const $mipActionOldArguments = lex.set({ } }) +export const $mipActionObjectArguments = lex.set({ + type: 'MIPActionObjectArguments', + rule: $object, + match (args) { + return { + arguments: [args] + } + } +}) + export const $mipActionArguments = lex.set({ type: 'MIPActionArguments', rule: [ _, [opt, [or, [ + $mipActionObjectArguments, $mipActionOldArguments, $mipActionNewArguments ]] diff --git a/packages/mip/src/util/event-action/whitelist/basic.js b/packages/mip/src/util/event-action/whitelist/basic.js index ed394452..e0594826 100644 --- a/packages/mip/src/util/event-action/whitelist/basic.js +++ b/packages/mip/src/util/event-action/whitelist/basic.js @@ -77,7 +77,8 @@ export const PROTOTYPE = { substr: String.prototype.substr, substring: String.prototype.substring, toLowerCase: String.prototype.toLowerCase, - toUpperCase: String.prototype.toUpperCase + toUpperCase: String.prototype.toUpperCase, + trim: String.prototype.trim } } diff --git a/packages/mip/test/specs/util/parser/basic.spec.js b/packages/mip/test/specs/util/parser/basic.spec.js index dfc62f23..9536e18f 100644 --- a/packages/mip/test/specs/util/parser/basic.spec.js +++ b/packages/mip/test/specs/util/parser/basic.spec.js @@ -207,7 +207,7 @@ describe('Test Grammar', function () { describe('Test Object', function () { let fn = (walker) => run(walker, lexer.$object) - it('should be equal', function () { + it('Computed Value', function () { let str = `{ a: 1, '$asdf' : 1 + (2 - 3) * 4 @@ -219,12 +219,25 @@ describe('Test Grammar', function () { expect(result.properties[1].key.value).to.be.equal('$asdf') }) - it('should be equal', function () { + it('Empty Value', function () { let str = `{}` let walker = new Walker(str) let result = fn(walker) expect(result.properties).to.be.deep.equal([]) }) + + it('Computed Key', function () { + let str = `{ + abc: 123, + ['a' + 'cd']: true ? 2 : 3, + [3 -2]: 12345 + }` + let walker = new Walker(str) + let result = fn(walker) + expect(result.properties.length).to.be.equal(3) + expect(result.properties[1].key.type).to.be.equal('Binary') + expect(result.properties[2].key.type).to.be.equal('Binary') + }) }) describe('Test MemberExpression', function () { diff --git a/packages/mip/test/specs/util/parser/event-argument.spec.js b/packages/mip/test/specs/util/parser/event-argument.spec.js index 2d259ff6..672ad1e4 100644 --- a/packages/mip/test/specs/util/parser/event-argument.spec.js +++ b/packages/mip/test/specs/util/parser/event-argument.spec.js @@ -29,6 +29,20 @@ describe('MIP Argument', () => { expect(ast.arguments[0].properties[2].value.value).to.be.equal('this is a string with \" and \'\' ') }) + it('Object Argument Expression', () => { + let str = `{ + abc: 1, + def: null, + someStr: \"this is a string with \\\" and '' \", + useEvent: event.a + }` + let ast = fn(str) + expect(ast.arguments[0].properties.length).to.be.equal(4) + expect(ast.arguments[0].properties[3].value.type).to.be.equal('Member') + expect(ast.arguments[0].properties[2].value.value).to.be.equal('this is a string with \" and \'\' ') + }) + + it('Old Argument Expression', () => { let str = `123, null, diff --git a/packages/mip/test/specs/util/parser/parse.spec.js b/packages/mip/test/specs/util/parser/parse.spec.js index 80b4eaee..ddcb3562 100644 --- a/packages/mip/test/specs/util/parser/parse.spec.js +++ b/packages/mip/test/specs/util/parser/parse.spec.js @@ -33,6 +33,12 @@ describe('parser', () => { expect(result).to.be.equal(false) }) + it('Computed Object Name', function () { + const str = `{[1 + 2]: 3 + 4, [1 + '2']: 5 + 6, '7': 8}` + let fn = parser.transform(str, 'ObjectLiteral') + let result = fn() + expect(result).to.be.deep.equal({'3': 7, '12': 11, '7': 8}) + }) it('Sort Array', function () { const str = `[3,1,4,1,5].sort()` let fn = parser.transform(str, 'Conditional') @@ -221,6 +227,43 @@ describe('parser', () => { }) describe('MIPAction', () => { + it('Object style', () => { + const str = `{a : -12345.6,b : event.data,c : DOM.dataset.value}` + let fn = parser.transform(str, 'MIPActionArguments') + let result = fn({ + event: { + data: '\'"' + }, + target: { + dataset: { + value: -3456.7 + } + } + }) + // console.log(result) + expect(result[0].a).to.be.equal(-12345.6) + expect(result[0].b).to.be.equal('\'"') + expect(result[0].c).to.be.equal(-3456.7) + }) + + it('Object Style With Expression', () => { + const str = `{a: 1 + 2 + 3, b:( 2 *event.data), c:((DOM.dataset.value/event.data))}` + let fn = parser.transform(str, 'MIPActionArguments') + let result = fn({ + event: { + data: 100 + }, + target: { + dataset: { + value: -10 + } + } + }) + expect(result[0].a).to.be.equal(6) + expect(result[0].b).to.be.equal(200) + expect(result[0].c).to.be.equal(-0.1) + }) + it('new style', () => { const str = `a = -12345.6,b = event.data,c = DOM.dataset.value` let fn = parser.transform(str, 'MIPActionArguments') @@ -258,6 +301,7 @@ describe('parser', () => { expect(result[0].c).to.be.equal(-0.1) }) + it('old style', () => { const str = `-123.4, event.a.b, DOM.value`