Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

新增 modifier 来控制「将捕获内容写入结果」的过程 #34

Merged
merged 6 commits into from
Jul 22, 2018

Conversation

feichao93
Copy link
Owner

@feichao93 feichao93 commented Jul 21, 2018

该 PR 将新增 modifier,可以用来控制「将捕获内容写入结果」的过程,能够配合已有的 filter,增强数据捕获的表达能力。

modifier 的一个典型用例如下(参考了 #33 ):

// 下面这行代码是 cheerio 代码
let title = $el.find('.res-title').text()
  || $el.find('.mh-title').text()
  || $el.find('.os-title').text()
  || 'no title'

// 有了 modifer 之后,我们可以使用 temme 来改写上述 cheerio 代码
const temmeSelect = `
  .res-title{$title!whenFalsy};
  .mh-title {$title!whenFalsy};
  .os-title {$title!whenFalsy};
  $title!whenFalsy = 'no title';
`

// modifer `whenFalsy` 的定义如下
function whenFalsy(result: CaptureResult, key: string, value: any) {
  const oldValue = result.get(key)
  if (!Boolean(oldValue)) {
    result.set(key, value)
  }
}

上述例子中 whenFalsy 的含义是「捕获新的 (key, value) 时,若该字段已有值对应布尔假,则将新的值写入到捕获结果中」。

modifier 的语法和用法:

语法 含义
$foo!modifer 将 modifier 应用到 value-capture 上
$!modifer 将 modifier 应用到 default-value-capture 上。此时 modifier 函数获取的参数 key 为 DEFAULT_CAPTURE_KEY (一个字符串常量,可以从 temme 导出)
@arrayCapture!modifier 将 modifier 应用在 array-capture 上
$field!modifier = true; 将 modifier 应用在 assignment 上
$bar|someFilter!modifier modifier 可以和 filter 连用,捕获的值先经过 filter 的处理,然后再传递给 modifier
$foo!modifier(arg) 带参数的 modifier
$foo!mod1!mod2 不能同时使用多个 modifier
$foo!modifier|filter modifier 必须放置在 filter 后面

用 modifier 来解释目前的默认行为

有了 modifier 这个概念之后,目前默认的行为也可以用 modifier 来进行解释,目前默认行为分为两类:

第一类对应值捕获和数组捕获的情况,其 modifier 可以用下面的 add 函数来表示:

function add(result, key, value) {
  if (value != null && !isEmptyObject(value)) {
    result.set(key, value)
  }
}

另一类对应赋值的情况,其 modifier 可以用下面的 forceAdd 函数来表示:

function forceAdd(result, key, value) {
  result.set(key, value)
}

该 PR 将新增两种内置的 modifier:add / forceAdd(这两个 modifier 的行为都和目前保持一致)。当用户没有显式地指定 modifier 时,将默认使用 add 或 forceAdd 作为 modifier。

@feichao93
Copy link
Owner Author

另外一个不错的用例,用下面的 array modifier 可以将多次捕获的结果放到同一个字段中。

function array(result, key, value) {
  const array = result.get(key) || []
  array.push(value)
  result.set(key, array)
}

const selector = `
  div.foo{$content!array};
  div.bar{$content!array};
  div.buzz{$content!array};
`

temme(html, selector, {}, { array })
// => { content: ['foo-content', 'bar-content', 'buzz-content'] }

@feichao93
Copy link
Owner Author

@qgy18 你觉得 modifier 怎么样?

我更偏向于 modifier,语法上面也比「逗号分隔的选择器」更容易实现一些。

@feichao93 feichao93 changed the title WIP 新增 modifier 来控制「将捕获内容写入结果」的逻辑 WIP 新增 modifier 来控制「将捕获内容写入结果」的过程 Jul 21, 2018
@feichao93 feichao93 self-assigned this Jul 21, 2018
@coveralls
Copy link

coveralls commented Jul 22, 2018

Coverage Status

Coverage decreased (-0.03%) to 99.307% when pulling ceb247f on capture-modifier into 3ef290e on master.

@feichao93 feichao93 changed the title WIP 新增 modifier 来控制「将捕获内容写入结果」的过程 新增 modifier 来控制「将捕获内容写入结果」的过程 Jul 22, 2018
@feichao93 feichao93 merged commit fab32f4 into master Jul 22, 2018
@feichao93 feichao93 deleted the capture-modifier branch July 22, 2018 12:09
This was referenced Jul 22, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants