精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

說說如何用JavaScript實現一個模板引擎

開發 前端
不知不覺就很長時間沒造過什么輪子了,以前一直想自己實現一個模板引擎,只是沒付諸于行動,最近終于在業余時間里抽了點時間寫了一下。因為我們的項目大部分用的是 swig 或者 nunjucks ,于是就想實現一個類似的模板引擎。

前言

不知不覺就很長時間沒造過什么輪子了,以前一直想自己實現一個模板引擎,只是沒付諸于行動,最近終于在業余時間里抽了點時間寫了一下。因為我們的項目大部分用的是 swig 或者 nunjucks ,于是就想實現一個類似的模板引擎。

至于為什么要做這么一個東西?基本上每一個做前端的人都會有自己的一個框架夢,而一個成熟的前端框架,模板編譯能力就是其中很重要的一環,雖然目前市面上的大部分框架 vue、angular 這些都是屬于 dom base 的,而 swig nunjucks ejs這些都是屬于 string base 的,但是其實實現起來都是差不多的。不外乎都是 Template =parse=> Ast =render=>String

再者,做一個模板引擎,個人感覺還是對自身的編碼能力的提升還是很有幫助的,在性能優化、正則、字符解析上尤為明顯。在日后的業務需求中,如果有一些需要解析字符串相關的需求,也會更得心應手。

功能分析

一個模板引擎,在我看來,就是由兩塊核心功能組成,一個是用來將模板語言解析為 ast(抽象語法樹)。還有一個就是將 ast 再編譯成 html。

先說明一下 ast 是什么,已知的可以忽略。

抽象語法樹(abstract syntax tree或者縮寫為AST),或者語法樹(syntax tree),是源代碼的抽象語法結構的樹狀表現形式,這里特指編程語言的源代碼。樹上的每個節點都表示源代碼中的一種結構。之所以說語法是“抽象”的,是因為這里的語法并不會表示出真實語法中出現的每個細節。比如,嵌套括號被隱含在樹的結構中,并沒有以節點的形式呈現;而類似于if-condition-then這樣的條件跳轉語句,可以使用帶有兩個分支的節點來表示。

在實現具體邏輯之前,先決定要實現哪幾種 tag 的功能,在我看來,forif elsesetraw還有就是基本的變量輸出,有了這幾種,模板引擎基本上也就夠用了。除了 tag,還有就是 filter 功能也是必須的。

構建 AST

我們需要把模板語言解析成一個又一個的語法節點,比如下面這段模板語言:

<div>
    {% if test > 1 %}
        {{ test }}
    {% endif %}
</div>

很明顯,div 將會被解析為一個文本節點,然后接著是一個塊級節點 if ,然后 if 節點下又有一個變量子節點,再之后有是一個 的文本節點,用 json 來表示這個模板解析成的 ast 就可以表示為:

[
    {
        type: 1,
        text: '<div>'
    },
    {
        type: 2,
        tag: 'if',
        item: 'test > 1',
        children: [{
           type: 3,
           item: 'test'
        }]
    },
    {
        type: 1,
        text: '</div>'
    }
]

基本上就分成三種類型了,一種是普通文本節點,一種是塊級節點,一種是變量節點。那么實現的話,就只需要找到各個節點的文本,并且抽象成對象即可。一般來說找節點都是根據模板語法來找,比如上面的塊級節點以及變量節點的開始肯定是{%或者{{,那么就可以從這兩個關鍵字符下手:

...
const matches = str.match(/{{|{%/);
const isBlock = matches[0] === '{%';
const endIndex = matches.index;
...

通過上面一段代碼,就可以獲取到處于文本最前面的{{或者{%位置了。

既然獲取到了***個非文本類節點的位置,那么該節點位置以前的,就都是文本節點了,因此就已經可以得到***個節點,也就是上面的<div>了。

獲取到 div 文本節點后,我們也可以知道獲取到的***個關鍵字符是{%,也就是上面的endIndex是我們要的索引,記得要更新剩余的字符,直接通過 slice 更新即可:

// 2 是 {% 的長度
str = str.slice(endIndex + 2);

而此時我們就可以知道匹配到的當前關鍵字符是{%,那么他的閉合處就肯定是%},因此就可以再通過

const expression = str.slice(0, str.indexOf('%}'))

獲取到 if test > 1 這個字符串了。然后我們再通過正則/^if\s+([\s\S]+)$/匹配,就可以知道這個字符串是 if 的標簽,同時可以獲得test > 1這一個捕獲組,然后就可以創建我們的第二個節點,if 的塊級節點了。

因為 if 是個塊級節點,那么繼續往下匹配的時候,在遇到 {% endif %} 之前的所有節點,都是屬于 if 節點的子節點,所以我們在創建節點時要給它一個children數組屬性,用來保存子節點。

緊接著再重復上面的操作,獲取下一個{%以及{{的位置,跟上面的邏輯差不多,獲取到{{的位置后再判斷}}的位置,就可以創建第三個節點,test 的變量節點,并且 push 到 if 節點的子節點列表中。

創建完變量節點后繼續重復上述操作,就能夠獲取到{% endif %}這個閉合節點,當遇到該節點之后的節點,就不能保存到 if 節點的子節點列表中了。緊接著就又是一個文本節點。

相對比較完整的實現如下:

const root = [];
let parent;
function parse(str){
    const matches = str.match(/{{|{%/);
    const isBlock = matches[0] === '{%';
    const endIndex = matches.index;

    const chars = str.slice(0, matches ? endIndex : str.length);
    if(chars.length) {
     ...創建文本節點 
    }

    if(!matches) return;

    str = str.slice(endIndex + 2);
    const leftStart = matches[0];
    const rightEnd = isBlock ? '%}' : '}}';
    const rightEndIndex = str.indexOf(rightEnd);
    const expression = str.slice(0, rightEndIndex)

    if(isBlock) {
        ...創建塊級節點 el

        parent = el;
    } else {
        ...創建變量節點 el
    }

    (parent ? parent.children : root).push(el);
    parse(str.slice(rightEndIndex + 2));
}

當然,具體實現起來還是有其他東西要考慮的,比如一個文本是{% {{ test }},就要考慮到{%的干擾等。還有比如 else 還有 elseif 節點的處理,這兩個是需要關聯到 if 標簽上的,這個也是需要特殊處理的。不過大概邏輯基本上就是以上。

組合 html

創建好 ast 后,要渲染 html 的時候,就只需要遍歷語法樹,根據節點類型做出不同的處理即可。

比如,如果是文本節點,就直接html += el.text即可。如果是if節點,則判斷表達式,比如上面的test > 1,有兩種辦法可以實現表達式的計算,一種就是eval,還有一種就是new Function了,eval 會有安全性問題,因此就不考慮了,而是使用new Function的方式來實現。變量節點的計算也一樣,用new Function來實現。

封裝后具體實現如下:

function computedExpression(obj, expression) {
  const methodBody = `return (${expression})`;
  const funcString = obj ? `with(__obj__){ ${methodBody} }` : methodBody;
  const func = new Function('__obj__', funcString);
  try {
    let result = func(obj);
    return (result === undefined || result === null) ? '' : result;
  } catch (e) {
    return '';
  }
}

使用 with ,可以讓在 function 中執行的語句關聯對象,比如

with({ a: '123' }) {
    console.log(a); // 123
}

雖然 with 不推薦在編寫代碼的時候使用,因為會讓 js 引擎無法對代碼進行優化,但是卻很適合用來做這種模板編譯,會方便很多。包括 vue 中的 render function 也是用 with 包裹起來的。不過 nunjucks 是沒有用 with 的,它是自己來解析表達式的,因此在 nunjucks 的模板語法中,需要遵循它的規范,比如最簡單的條件表達式,如果用 with 的話,直接寫{{ test ? 'good' : 'bad' }},但是在 nunjucks 中卻要寫成�{{ 'good' if test else 'bad' }}

anyway,各有各的好吧。

實現多級作用域

在將 ast 轉換成 html 的時候,有一個很常見的場景就是多級作用域,比如在一個 for 循環中再嵌套一個 for 循環。而如何在做這個作用域分割,其實也是很簡單,就是通過遞歸。

比如我的對一個 ast 樹的處理方法命名為:processAst(ast, scope),再比如最初的 scope 是

{ 
  list: [
   { subs: [1, 2, 3] },
   { subs: [4, 5, 6] } 
  ] 
 }

那么 processAst 就可以這么實現:

function processAst(ast, scope) {
    ...
    if(ast.for) {
        const list = scope[ast.item]; // ast.item 自然就是列表的 key ,比如上面的 list
        list.forEach(item => {
            processAst(ast.children, Object.assign({}, scope, {
                [ast.key]: item,  // ast.key 則是 for key in list 中的 key
            }))
        })
    }
    ...
}

就簡單通過一個遞歸,就可以把作用域一直傳遞下去了。

Filter 功能實現

實現上面功能后,組件就已經具備基本的模板渲染能力,不過在用模板引擎的時候,還有一個很常用的功能就是 filter 。一般來說 filter 的使用方式都是這這樣 {{ test | filter1 | filter2 }},這個的實現也說一下,這一塊的實現我參考了 vue 的解析的方式,還是蠻有意思的。

還是舉個例子:

{{ test | filter1 | filter2 }}

在構建 AST 的時候,就可以獲取到其中的test | filter1 | filter2,然后我們可以很簡單的就獲取到 filter1 和 filter2 這兩個字符串。起初我的實現方式,是把這些 filter 字符串扔進 ast 節點的 filters 數組中,在渲染的時候再一個一個拿出來處理。

不過后來又覺得為了性能考慮,能夠在 AST 階段就能做完的工作就不要放到渲染階段了。因此就改成 vue 的方法組合方式。也就是把上面字符串變成:

_$f('filter2', _$f('filter1', test))

預先用個方法包裹起來,在渲染的時候,就不需要再通過循環去獲取 filter 并且執行了。具體實現如下:

const filterRE = /(?:\|\s*\w+\s*)+$/;
const filterSplitRE = /\s*\|\s*/;
function processFilter(expr, escape) {
  let result = expr;
  const matches = expr.match(filterRE);
  if (matches) {
    const arr = matches[0].trim().split(filterSplitRE);
    result = expr.slice(0, matches.index);

    // add filter method wrapping
    utils.forEach(arr, name => {
      if (!name) {
        return;
      }

      // do not escape if has safe filter
      if (name === 'safe') {
        escape = false;
        return;
      }

      result = `_$f('${name}', ${result})`;
    });
  }

  return escape ? `_$f('escape', ${result})` : result;
}

上面還有一個就是對 safe 的處理,如果有 safe 這個 filter ,就不做 escape 了。完成這個之后,有 filter 的 variable 都會變成_$f('filter2', _$f('filter1', test))這種形式了。因此,此前的 computedExpression 方法也要做一些改造了。

function processFilter(filterName, str) {
  const filter = filters[filterName] || globalFilters[filterName];

  if (!filter) {
    throw new Error(`unknown filter ${filterName}`);
  }

  return filter(str);
}

function computedExpression(obj, expression) {
  const methodBody = `return (${expression})`;
  const funcString = obj ? `with(_$o){ ${methodBody} }` : methodBody;
  const func = new Function('_$o', '_$f', funcString);
  try {
    const result = func(obj, processFilter);
    return (result === undefined || result === null) ? '' : result;
  } catch (e) {
    // only catch the not defined error
    if (e.message.indexOf('is not defined') >= 0) {
      return '';
    } else {
      throw e;
    }
  }
}

其實也是很簡單,就是在 new Function 的時候,多傳入一個獲取 filter 的方法即可,然后有 filter 的 variable 就能被正常識別解析了。

至此,AST 構建、AST 到 html 的轉換、多級作用域以及 Filter 的實現,都已經基本講解完成。

貼一下自己實現的一個模板引擎輪子:https://github.com/whxaxes/mus

算是實現了大部分模板引擎該有的功能,歡迎各路豪杰 star 。

責任編輯:王雪燕 來源: whxaxes
相關推薦

2017-03-20 17:59:19

JavaScript模板引擎

2017-08-11 17:55:48

前端JavaScript模板引擎

2021-09-13 06:03:42

CSS 技巧搜索引擎

2024-05-28 10:14:31

JavaScrip模板引擎

2017-05-02 11:30:44

JavaScript數組惰性求值庫

2023-02-26 01:37:57

goORM代碼

2016-09-06 19:45:18

javascriptVue前端

2019-11-13 09:01:48

開源JavaScript模板引擎

2020-10-26 08:19:53

算法隊列

2022-04-14 20:43:24

JavaScript原型鏈

2018-06-22 10:30:56

C語言虛擬機編譯器

2023-12-30 13:33:36

Python解析器JSON

2017-07-19 13:27:44

前端Javascript模板引擎

2014-01-22 09:19:57

JavaScript引擎

2021-06-09 07:55:19

NodeEventEmitte驅動

2022-11-30 15:15:48

2012-04-13 09:45:53

JavaScriptjQuery

2018-03-23 10:00:34

PythonTensorFlow神經網絡

2023-10-26 11:03:50

C語言宏定義

2017-10-27 22:03:35

javascrip
點贊
收藏

51CTO技術棧公眾號

一区中文字幕| 国产在线一二三区| 在线播放不卡| 亚洲午夜久久久久久久| 天天综合网久久| 高h视频在线观看| 成人亚洲一区二区一| 国产91精品黑色丝袜高跟鞋| youjizz亚洲女人| www.成人网| 色成人在线视频| 精品一区二区三区毛片| 深夜福利在线看| 精品亚洲成av人在线观看| 欧美精品福利在线| 亚洲AV无码成人精品区明星换面| 亚洲最大的免费视频网站| 亚洲超碰97人人做人人爱| 日韩av不卡播放| 亚洲精品久久久久久久久久| 日韩精品欧美精品| 久久久久久国产三级电影| 一区二区三区伦理片| 免费欧美网站| 欧美日韩免费在线视频| 国产69精品久久久久久久| 永久免费在线观看视频| av成人老司机| 亚洲a在线观看| 老熟妇一区二区三区| 欧美久久九九| 自拍亚洲一区欧美另类| 国产精品边吃奶边做爽| 日本一区二区乱| 欧美性色黄大片手机版| 国产精品久久中文字幕| av网址在线播放| 亚洲国产成人午夜在线一区| 国产喷水在线观看| 免费看一级黄色| 丁香一区二区| 欧美丰满高潮xxxx喷水动漫| 日韩精品视频久久| 免费网站在线观看人| 国产精品人成在线观看免费 | 中文天堂资源在线| 卡通动漫国产精品| 欧美一区二区三区四区高清 | 欧美高清视频一区二区三区| 欧美日一区二区| 精品夜色国产国偷在线| 动漫美女无遮挡免费| 中文字幕日韩亚洲| 欧美日韩中字一区| 国产精品拍拍拍| 日韩伦理三区| 亚洲激情国产| 欧美理论电影在线观看| 香蕉成人在线视频| 青青草成人影院| 亚洲午夜色婷婷在线| 国产全是老熟女太爽了| 亚洲日本三级| 日韩激情av在线播放| 欧美xxxx日本和非洲| 日韩精品一区二区三区中文在线 | 91丨porny丨在线中文| 日韩高清欧美激情| 国产精品 欧美在线| 五月婷婷激情视频| 丝瓜av网站精品一区二区| 日本免费在线精品| 日本视频免费观看| 日韩成人午夜电影| 国产日本欧美一区二区三区在线| 一区二区三区在线免费观看视频| 蜜桃久久av一区| 成人午夜一级二级三级| 精品国产无码AV| 国产91精品露脸国语对白| 丁香婷婷久久久综合精品国产| 亚洲高清视频网站| 成人性生交大片免费看中文| 狠狠色噜噜狠狠色综合久| 黄色视屏网站在线免费观看| 中文一区在线播放| 日韩国产精品毛片| 日皮视频在线观看| 精品久久久久久久久久| 久久久久国产精品熟女影院| 欧美性www| 欧美一级国产精品| 国产精品福利导航| 欧美午夜精彩| 欧美国产日韩精品| 色老头一区二区| 国产专区综合网| 国产在线精品日韩| aiai在线| 午夜精品久久久久久久| mm131国产精品| 99re6热只有精品免费观看| 97se亚洲国产综合自在线| 亚洲日本va在线观看| 亚洲电影免费| 欧美人动性xxxxz0oz| 欧美网站在线观看| 亚洲欧洲三级| 麻豆av在线免费观看| 色一情一乱一乱一91av| 男生和女生一起差差差视频| 精品在线播放| 九九精品在线视频| 一级做a爰片久久毛片| 国产福利91精品| 色播五月综合| 涩涩av在线| 精品伦理精品一区| 青青操在线播放| 久久裸体视频| 国产欧美日韩一区| 中文字幕中文字幕在线十八区 | 岛国av中文字幕| 国产成a人亚洲| 日韩精品福利视频| 久久男人天堂| 欧美mv日韩mv| 久久精品黄色片| 久久精品久久综合| 欧美三级电影在线播放| 77thz桃花论族在线观看| 欧美高清精品3d| 国产午夜福利一区| 免费亚洲视频| 国产成人精品福利一区二区三区 | 风间由美一区二区三区在线观看| 日韩精品不卡| 日韩av影片| 欧美电影精品一区二区| 山东少妇露脸刺激对白在线| 久久在线91| 久久波多野结衣| 欧美家庭影院| 欧美一区二区啪啪| 精品丰满少妇一区二区三区| 黄色亚洲在线| 99久久精品无码一区二区毛片 | 亚洲精品一区中文| 亚洲天堂日韩av| 国产91在线看| 中国黄色录像片| 欧美videos粗暴| 亚洲色图在线观看| 亚洲天堂一区在线观看| 成人免费观看视频| 91精品国产毛片武则天| 中文字幕日韩亚洲| 日韩有码片在线观看| 国产乱码在线观看| 欧美国产一区视频在线观看| av免费在线播放网站| 欧美人体视频| 69久久夜色精品国产69| 婷婷丁香一区二区三区| 亚洲风情在线资源站| 一区二区免费在线观看视频| 午夜精品久久99蜜桃的功能介绍| 成人自拍性视频| 色大18成网站www在线观看| 欧美亚洲日本国产| 国产精品酒店视频| 精品一区二区三区欧美| 日本一区二区三区四区五区六区| 国产精品久久久久久久久久辛辛| 日韩一区在线视频| 国产一区二区在线网站| 你懂的免费在线观看| 亚洲无人区一区| 日本道中文字幕| 亚洲全部视频| 久久久久久欧美精品色一二三四| 亚洲男人av| 亚洲精品99久久久久中文字幕| 国产成人在线播放视频| 久久综合久久综合亚洲| 91在线视频观看免费| 日本一二区不卡| 成人激情综合网| 91桃色在线观看| 亚洲人成网站免费播放| 91久久精品无码一区二区| 亚洲美女免费视频| www.啪啪.com| 日韩视频在线一区二区三区| 日本一区视频在线观看| 日韩五码电影| 久久久久久久久国产| 无码h黄肉3d动漫在线观看| 欧美午夜久久久| 中文字幕av久久爽一区| 国产福利精品一区二区| 欧美牲交a欧美牲交| 成人羞羞网站入口| 91九色对白| 欧美7777| 久久天堂电影网| 天天综合网天天综合| 精品视频在线免费| 久草免费在线观看视频| 久久亚区不卡日本| 能看的毛片网站| 国产欧美高清| 一级黄色免费在线观看| 卡通动漫精品一区二区三区| 国产精品丝袜高跟| 日韩 国产 一区| 国产一区二区三区日韩精品| 粉嫩av免费一区二区三区| 日韩大尺度黄色| 欧美韩国理论所午夜片917电影| 你懂的视频在线| 2023国产精品久久久精品双| 国产欧美精品一区二区| brazzers在线观看| 一二美女精品欧洲| 好男人www在线视频| 欧美私人免费视频| 国产午夜精品一区二区理论影院| 国产精品私房写真福利视频| 这里只有精品在线观看视频 | 91麻豆精品国产综合久久久 | 亚洲xxxx3d动漫| 99r国产精品| 毛片毛片毛片毛片毛| 亚洲欧美日本日韩| av久久久久久| 亚洲最好看的视频| 国产视频一区二区不卡| 精品国产伦一区二区三区观看说明 | 麻豆av免费看| 美女任你摸久久| 日本a√在线观看| 午夜影院日韩| 亚洲人精品午夜射精日韩 | 日本在线观看视频网站| 国产精品国产三级国产有无不卡| www..com.cn蕾丝视频在线观看免费版 | 精品视频一区二区在线| 在线中文字幕第一区| youjizz.com亚洲| 日韩电影免费网站| 日本欧美精品久久久| 人人精品视频| 国产有色视频色综合| 婷婷激情久久| 九色视频成人porny| 久久久久观看| 国内一区在线| 九色丨蝌蚪丨成人| 久久偷看各类wc女厕嘘嘘偷窃 | 97中文在线| 亚洲色图图片| 91久久精品久久国产性色也91| 国产视频一区二| 99精彩视频在线观看免费| 欧美高清一级片| 91网免费观看| 麻豆国产一区| 国产日韩三区| 中文字幕精品影院| 日本不卡一区| 日韩影院二区| 天天做天天爱天天高潮| 欧美一区视频| 日本福利视频一区| 午夜亚洲伦理| 激情视频免费网站| 蜜臀av在线播放一区二区三区| 午夜视频在线网站| 国产福利一区在线| 星空大象在线观看免费播放| 久久美女艺术照精彩视频福利播放| 中文字幕一区二区久久人妻网站| 久久女同性恋中文字幕| 卡一卡二卡三在线观看| 亚洲三级久久久| 99久久99久久精品国产| 亚洲一区二区高清| 国产无遮挡呻吟娇喘视频| 色婷婷激情综合| 一本久道久久综合无码中文| 538prom精品视频线放| 可以免费观看的毛片| 亚洲精品自拍视频| jizz亚洲| 欧美精品亚州精品| 精精国产xxxx视频在线| 18久久久久久| 日韩毛片网站| 国产精品一区二区三区四区五区| 一区二区导航| 国产91porn| 性欧美videos另类喷潮| 婷婷六月天在线| 懂色av中文一区二区三区| 成人性生活免费看| 亚洲婷婷在线视频| 天堂网一区二区三区| 欧美日韩和欧美的一区二区| 亚洲国产精品久久久久爰性色| 一区二区成人精品| 波多野结衣在线高清| 国产精品电影网| 一区二区在线视频观看| 中文字幕中文字幕在线中心一区| 影音先锋在线一区| 在线观看国产福利| av不卡免费在线观看| 免费网站在线高清观看| 婷婷综合另类小说色区| 国产又黄又爽视频| 日韩av网站大全| 中文字幕中文字幕在线十八区| 国产精品视频一区二区高潮| 久久香蕉精品香蕉| 免费观看中文字幕| 午夜亚洲视频| 给我免费观看片在线电影的| 亚洲天堂免费看| 午夜精品一区二| 精品捆绑美女sm三区 | 国产电影一区二区三区| 懂色av粉嫩av蜜臀av一区二区三区| 五月激情丁香一区二区三区| 国产熟女一区二区丰满| 一区二区三区四区精品| 男人天堂亚洲| 成人av免费在线看| 色中色综合网| 无码人妻精品一区二区三区66| 不卡视频在线看| 日本妇女毛茸茸| 欧美久久婷婷综合色| 国产黄在线播放| 2020欧美日韩在线视频| 日本欧美三级| 国产成a人亚洲精v品在线观看| 久久精品99国产精品日本| 美女100%无挡| 欧美性xxxxxxxx| 激情小说 在线视频| 啪一啪鲁一鲁2019在线视频| 秋霞影院一区二区三区| 18禁男女爽爽爽午夜网站免费 | 怡红院一区二区| 樱桃国产成人精品视频| 亚洲AV无码精品色毛片浪潮| 久久综合电影一区| 国产精品视频首页| 一区二区精品国产| 日本亚洲三级在线| 丰满的亚洲女人毛茸茸| 91国产视频在线观看| 全色精品综合影院| 国产精品99久久久久久人| 美女精品一区最新中文字幕一区二区三区 | 欧美不卡在线观看| 69精品丰满人妻无码视频a片| 国产一区二区成人久久免费影院 | 精品国产一区二区三区香蕉沈先生 | av丝袜天堂网| 国产免费久久精品| 91 中文字幕| 久久综合免费视频影院| 国产在线视频欧美一区| 毛片av在线播放| 91女厕偷拍女厕偷拍高清| 免费污污视频在线观看| 国产一区二区三区中文 | 波多野结衣一区| 美女在线视频一区二区| 国产精品短视频| 不卡的日韩av| 日本国产精品视频| 水蜜桃精品av一区二区| 一级片黄色免费| 精品久久久视频| av资源种子在线观看| 成人激情在线播放| 亚洲精品123区| 蜜桃av免费在线观看| 欧美一激情一区二区三区| 黄页在线观看免费| 国产精品av一区| 美女视频第一区二区三区免费观看网站| 色婷婷在线视频观看| 亚洲二区中文字幕| 婷婷六月国产精品久久不卡| 亚洲欧美日韩在线综合| 粉嫩aⅴ一区二区三区四区|