Sizzle: A Lightweight CSS Selector Engine

 
Sizzle
引擎研究
 
By zhangpeng12@baidu.com
 
什么是
sizzle
 
         A pure-JavaScript CSS selector engine (power jQuery)
 
Standalone(no dependencies)
Competitive performance
Only 4kB with gzipped
Easy to use
Css3 support
Bla bla ……
 
为什么需要
sizzle
                                            Bugs
1. Id
IE<=8
不区分大小写,混淆
iuput
name
id
2. class
IE        getAttribute 
,混淆
html
attribute
dom
property
IE    getElementsByClassName
3.Tag
getElementsByTagName(*)
混淆注释节点
                                                   
性能
考虑如下选择器:
           div.container li:last-of-child a,div.container ul+a
           var mySelector = function(){
                        bla bla…….
       
 
  There gone be at least 
100
 lines here…….
        
 
  bla bla…….
             }
 
高版本浏览器
(querySelector)
 
Sizzle
概览
词法解析
过滤函数
种子集
编译函数匹配
结果集
 
词法解析
 
词法分析器又称扫描器,词法分析是指将我们编写的文本代码流解
析为一个一个的记号,分析得到的记号以供后续语法分析使用
div.aaron  input[name=ttt]
   {matches: ["div"],type: "
TAG
",value: "div“ },
   {matches: ["aaron"], type: "
CLASS
", value: ".aaron"},
   {match:[“”], type: "
 
", value: " "},
   
{matches: ["input"], type: "
TAG
", value: "input"},
   {matches: ["name"], type: "
ATTR
", value: "[name=ttt]"}
 
词法解析
(
模式
)
 
词法解析
(
代码
)
  
//
分组
  
var rcomma = /^[\x20\t\r\n\f]*,[\x20\t\r\n\f]*/;
  
//
层级
  
var rcombinators =
 /^[\x20\t\r\n\f]*([>+~]|[\x20\t\r\n\f])[\x20\t\r\n\f]*/
  
//
选择器
  
var TAG = /^((?:\\.|[\w*-]|[^\x00-\xa0])+)/;
  var matchExpr = {
      CLASS: /^\.((?:\\.|[\w-]|[^\x00-\xa0])+)/,
      TAG: /^((?:\\.|[\w*-]|[^\x00-\xa0])+)/
  }
while (selector) {
      
//
分组
      
if (match = rcomma.exec(selector)) {
          selector = selector.slice(match[0].length)
          groups.push((tokens = []));
      }
      
//
层级关系
      
if ((match = rcombinators.exec(selector))) {
          matched = match.shift();
          tokens.push({
              value: matched,
              type: match[0].replace(rtrim, " ")
          });
          selector = selector.slice(matched.length);
      }
      
//
选择器
      
for (type in matchExpr) {
          if ((match = matchExpr[type].exec(selector))) {
              matched = match.shift();
              tokens.push({
                  value: matched,
                  type: type,
                  matches: match
              });
              selector = selector.slice(matched.length);
          }
      }
  }
 
过滤函数
//
各种类型的
token
的过滤器,全部返回闭包函数
Expr.filter = {
    ATTR   : function (name, operator, check) {return 
function
}
    CHILD  : function (type, what, argument, first, last) {return 
function
}
    CLASS  : function (className) {return 
function
}
    ID     : function (id) {return 
function
}
    PSEUDO : function (pseudo, argument) {return 
function
}
    TAG    : function (nodeNameSelector) {return 
function
}
}
//tag
类型的过滤器,判断
nodeName
是否匹配,返回闭包函数
TAG: function(nodeNameSelector) {
              return function(elem) {
 
return elem.nodeName && elem.nodeName.toLowerCase() ===
nodeNameSelector;
              };
}
 
结果集
div.aaron  
input
[name=ttt]
div.aaron [name=ttt]
 
TAG
过滤
Input
标签种子集合
   { matches: ["div"],type: "TAG",value: "div“ },
   {matches: ["aaron"], type: "CLASS", value: ".aaron"},
   {match:[“”], type: " ", value: " "},
   {matches: ["input"], type: "TAG", value: "input"},
   {matches: ["name"], type: "ATTR", value: "[name=ttt]"}
   { matches: ["div"],type: "TAG",value: "div“ },
   {matches: ["aaron"], type: "CLASS", value: ".aaron"},
   {match:[“”], type: " ", value: " "},
   {matches: ["name"], type: "ATTR", value: "[name=ttt]"}
 
Token
集简化
 
编译原理
                          
过滤后的
token
   { matches: ["div"],type: "TAG",value: "div“ },
   {matches: ["aaron"], type: "CLASS", value: ".aaron"},
   {match:[“”], type: " ", value: " "},
   {matches: ["name"], type: "ATTR", value: "[name=ttt]"}
        
过滤后的选择器
div.aaron [name=ttt]
 
  
过滤函数
Expr.filter = {
    ATTR   : function (name, operator, check) {return 
function
}
    CHILD  : function (type, what, argument, first, last) {return 
function
}
    CLASS  : function (className) {return 
function
}
    ID     : function (id) {return 
function
}
    PSEUDO : function (pseudo, argument) {return 
function
}
    TAG    : function (nodeNameSelector) {return 
function
}
}
                   
超级匹配函数
 function(){
       
层次很深的闭包
…..
 }
 
编译过程
 div [name=ttt]
 
     Function(elem){
       //tag filter
     }
( )[name=ttt]
 
遇到关系
token(+> ~)
则依次出栈合并匿名函数,其他情况压入对应的
token
处理函数
 
Function(elem){
   elem=elem[‘parentNode’];
   return Function(elem){
         tag filter
   }
}
Matchers
集合
[name=ttt]
 
Function(elem){
   elem=elem[‘parentNode’];
   return Function(elem){
         //tag filter
   }
}
 
Function(elem){
     //attribute filter
}
Function(elem){
while(matcher=matchrs.pop()){
          if(!matcher(elem)){
                return false;
          }
     }
     return true;
}
超级匹配器
选择器表达式
 
超级匹配器
for
 
item in seed
      if(superMatcher(item )){
               resultSet.push(item);
      }
return resultSet
Slide Note
Embed
Share

Sizzle is a pure JavaScript CSS selector engine, powered by jQuery and designed to be standalone with no dependencies. It boasts competitive performance in a small 4kB package. This tool makes selecting elements in the DOM easier with CSS3 support and efficient handling of various browser bugs and issues.

  • JavaScript
  • CSS Selector
  • jQuery
  • Lightweight Engine

Uploaded on Aug 01, 2024 | 1 Views


Download Presentation

Please find below an Image/Link to download the presentation.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.

You are allowed to download the files provided on this website for personal or commercial use, subject to the condition that they are used lawfully. All files are the property of their respective owners.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.

E N D

Presentation Transcript


  1. Sizzle By zhangpeng12@baidu.com

  2. sizzle A pure-JavaScript CSS selector engine (power jQuery) Standalone(no dependencies) Competitive performance Only 4kB with gzipped Easy to use Css3 support Bla bla

  3. sizzle Bugs 1. Id div.container li:last-of-child a,div.container ul+a IE<=8 iuput name id var mySelector = function(){ 2. class bla bla . IE getAttribute html attribute dom property There gone be at least 100 lines here . IE getElementsByClassName bla bla . 3.Tag } getElementsByTagName(*)

  4. (querySelector)

  5. Sizzle

  6. {matches: ["div"],type: "TAG",value: "div }, {matches: ["aaron"], type: "CLASS", value: ".aaron"}, {match:[ ], type: " ", value: " "}, {matches: ["input"], type: "TAG", value: "input"}, {matches: ["name"], type: "ATTR", value: "[name=ttt]"} div.aaron input[name=ttt]

  7. () (,) /^[\x20\t\r\n\f]*,[\x20\t\r\n\f]*/ ( >+~) /^[\x20\t\r\n\f]*([>+~]|[\x20\t\r\n\f])[\x20\t\r\n\f]*/ Id Tag Class Attribute var characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+" var ID = new RegExp("^#(" + characterEncoding + ")") var TAG = new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ) var Class = new RegExp( "^\\.(" + characterEncoding + ")" ) .

  8. while (selector) { // if (match = rcomma.exec(selector)) { selector = selector.slice(match[0].length) groups.push((tokens = [])); } // if ((match = rcombinators.exec(selector))) { matched = match.shift(); tokens.push({ value: matched, type: match[0].replace(rtrim, " ") }); selector = selector.slice(matched.length); } // for (type in matchExpr) { if ((match = matchExpr[type].exec(selector))) { matched = match.shift(); tokens.push({ value: matched, type: type, matches: match }); selector = selector.slice(matched.length); } } } ( ) // var rcomma = /^[\x20\t\r\n\f]*,[\x20\t\r\n\f]*/; // var rcombinators = /^[\x20\t\r\n\f]*([>+~]|[\x20\t\r\n\f])[\x20\t\r\n\f]*/ // var TAG = /^((?:\\.|[\w*-]|[^\x00-\xa0])+)/; var matchExpr = { CLASS: /^\.((?:\\.|[\w-]|[^\x00-\xa0])+)/, TAG: /^((?:\\.|[\w*-]|[^\x00-\xa0])+)/ }

  9. // token Expr.filter = { ATTR : function (name, operator, check) {return function} CHILD : function (type, what, argument, first, last) {return function} CLASS : function (className) {return function} ID : function (id) {return function} PSEUDO : function (pseudo, argument) {return function} TAG : function (nodeNameSelector) {return function} } //tag nodeName TAG: function(nodeNameSelector) { return function(elem) { return elem.nodeName && elem.nodeName.toLowerCase() === nodeNameSelector; }; }

  10. TAG div.aaron input[name=ttt] div.aaron [name=ttt] Input { matches: ["div"],type: "TAG",value: "div }, {matches: ["aaron"], type: "CLASS", value: ".aaron"}, {match:[ ], type: " ", value: " "}, {matches: ["input"], type: "TAG", value: "input"}, {matches: ["name"], type: "ATTR", value: "[name=ttt]"} { matches: ["div"],type: "TAG",value: "div }, {matches: ["aaron"], type: "CLASS", value: ".aaron"}, {match:[ ], type: " ", value: " "}, {matches: ["name"], type: "ATTR", value: "[name=ttt]"} Token

  11. token { matches: ["div"],type: "TAG",value: "div }, {matches: ["aaron"], type: "CLASS", value: ".aaron"}, {match:[ ], type: " ", value: " "}, {matches: ["name"], type: "ATTR", value: "[name=ttt]"} div.aaron [name=ttt] function(){ .. } Expr.filter = { ATTR : function (name, operator, check) {return function} CHILD : function (type, what, argument, first, last) {return function} CLASS : function (className) {return function} ID : function (id) {return function} PSEUDO : function (pseudo, argument) {return function} TAG : function (nodeNameSelector) {return function} }

  12. token(+> ~) token div [name=ttt] ( )[name=ttt] [name=ttt] Function(elem){ //attribute filter } Function(elem){ while(matcher=matchrs.pop()){ if(!matcher(elem)){ return false; } } return true; } Function(elem){ elem=elem[ parentNode ]; return Function(elem){ tag filter } } Function(elem){ //tag filter } Function(elem){ elem=elem[ parentNode ]; return Function(elem){ //tag filter } } Matchers

  13. for item in seed if(superMatcher(item )){ resultSet.push(item); } return resultSet

  14. Thanks & Regards

More Related Content

giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#