CSS 样式规则的匹配算法实现
CSS 的完整英文名称是: Cascading Style Sheets, 级联样式表. 除了可以定义丰富的样式, 以及进行界面控件布局外, CSS 最重要的特性便是名字中的"级联(Cascading)"一词. 级联代表了父子关联, 天生便是和数据结构中的"树"相关的.
我创建的 CocoaUI iOS UI 框架, 是一个使用 CSS 进行 iOS 上流式布局的开发框架, 极大地方便了 iOS 应用的界面开发, 轻松适配多种屏幕. 因为 CocoaUI 使用 CSS 来进行界面布局和定义界面样式, 所以需要对 CSS 的样式规则进行匹配, 将某一条 CSS 样式作用到某一个 UIView(IView) 上面.
例如, 下面这条常见的 CSS 样式定义:
.a .b{ background: #f00; }
这条样式定义表示, 对于具有名为"a"的 class 属性某个节点(界面控件), 他的所有带有"b" class 属性的子控件, 背景都设置为红色(#f00).
在代码中, 要怎么实现这样的逻辑呢? 因为, 程序 = 数据结构 + 算法, 所以, 数据结构是这样定义的:
class Style { array elements[]; string css; bool match(Dom node); }
Elements 就是以 .a, .b 作为元素的数组.
接下来, 要实现 match() 方法, 该方法传入一个控件, 然后判断这个控件是否被这条样式规则命中.
我们讨论样式规则时, 是从左到右(Left To Right), 但代码中实现时, 其实是从右到左(Right To Left), 也就是说, elements 要倒序来判断.
首先, 我样要判断最后一个 element(也就是关键 element) 是否匹配传入的 node. 如果不匹配, 那就是不匹配了, 不需要再做额外的判断. 这也是为什么称之为"关键"的原因.
接着, 再判断 node 的父节点 parent 和倒数第 2 个 element. 如果匹配呢, 接着判断父节点的父节点(parent.parent) 和倒数第 3 个 element. 如果不匹配呢? 倒数第二个节点不动, 让倒数第二个节点和 parent.parent 匹配.
如果 Dom 节点已经到顶了, 而 element 还没匹配到第 1 个, 那么, match() 返回 false. 另一种情况, 如果 element 先匹配完, 那么 match() 返回 true.
相关代码可以看这里: https://github.com/ideawu/cocoaui/blob/master/IKit/IKit/css/IStyleRule.m#L65
建议继续学习:
- 字符串匹配那些事(一) (阅读:5831)
- 利用vim(gvim)的正则表达式实现代码自动匹配完成(等号两边数据交换) (阅读:3270)
- [正则优化] CSS选择符匹配 (阅读:2482)
- [正则优化] CSS属性选择符的匹配 (阅读:2403)
- [一道面试题]含有*的字符串匹配问题 (阅读:2088)
- 设计模式-自动完成 (阅读:1845)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:ideawu 来源: idea's blog
- 标签: 匹配
- 发布时间:2016-02-16 20:38:37
- [70] Twitter/微博客的学习摘要
- [65] find命令的一点注意事项
- [64] 如何拿下简短的域名
- [64] IOS安全–浅谈关于IOS加固的几种方法
- [63] android 开发入门
- [62] 流程管理与用户研究
- [62] Go Reflect 性能
- [60] Oracle MTS模式下 进程地址与会话信
- [59] 读书笔记-壹百度:百度十年千倍的29条法则
- [59] 图书馆的世界纪录