深入Liferay 当页面请求css资源利用parseSass()方法解析

简介:

前面已经用了几篇文章详细的讲解了DynamicCSSFilter,现在我们来看他们是如何应用到加载css资源文件的。


前提:

假定我们开发了一个theme叫platform-In-theme,它其中我们写了一个main.css,并且在其中我们用@import url()语法包含了若干个其他css,其中有一个是forms.css,并且这个css是用Sass的语法规则写的,我们来深入研究下加载这个2个css文件的异同。


调试分析:

首先,当页面请求main.css的时候,因为它满足DynamicCSSFilter的模式,所以进入processFilter()方法,由前面几篇文章,很快的拿到requestURI,requestPath,contextPath等信息,

从这图上可以很清楚的看到,这个realPath是在我们的tomcat服务器上的webapps目录下的theme部署子目录,所以说这个是正确的,我们的自定义theme都是部署在这个目录上。


现在我们可以看下原始还没有被解析的main.css长什么样子:

很显然,和我们设想的一样,它就是作为一个总的css用来包含其他的css文件。


现在开始解析这个css 文件,调用的是DynamicCSSUtil类的parseSass()方法.


首先它在第用98行利用theme=_getTheme(request,cssRealPath)来

获取当前theme,因为我们的站点使用了platform-In-theme,所以返回这个theme.



然后,它利用_isThemeCssFastLoad(request,themeDisplay)方法获取我们是否启用了fast load ,因为这里我们没有启用fast load,所以返回false.


然后在115行获取cssRealFile的File对象,刚才讲过了,这个theme在服务器的webapps的相应theme目录中。


然后调用SassToCssBuilder.getCacheFile(cssRealPath)方法

来获取这个css资源文件对应的缓存文件,它首先吧真实css资源文件的反斜杠"\\"全部替换成正斜杠"/",然后获取最后一个正斜杠位置,这是用来区分文件路径部分和文件名部分,然后它在中间插入.sass_cache.

(千万注意,这次和上次说的$CATALINA_HOME/TMPDIR 下面的缓存数据文件完全不同,那个文件是用于直接返回到客户端(如果存在并且最新)的最终css文件,如果使用那个文件,就压根不会调用parseSass()方法,而这个缓存的是原始的css资源文件,它是在parseSass()方法中被调用的,所以用途不同)


所以获得的缓存文件的路径就是如下图:


这里有个判断,如果这个缓存文件存在并且是最新的,那么就不用调用jRuby解析,而是直接把这个缓存文件的内容作为最终parseSass()的返回值,也就是作为最终解析完的普通css文件输出,但是我们是第一次,所以没有这个资源文件,只好老老实实走jRuby解析的过程。


(1)正式解析的第一步是调用SassToCssBuilder.parseStaticTokens(content)方法来吧一些静态的符号替换掉:

很容易理解,就是把Sass中的一些特殊内容替换掉,比如文本的宽度,高度,和输入框的高度宽度。

在这一步完结后,我们的main.css不受到影响。


(2)正式解析的第二步是先通过getQueryString方法获得请求字符串。

然后调用_propagateQueryString()方法进行操作:

这步骤的作用是对于每一个@import(url ...)导入的资源文件,都在后面加上请求字符串。所以在这一步之后,我们的main.css变为:

和我们设想的一样,所有的@import url 的url后面都附加了请求字符串。这是为了保证请求一致性(我猜的)


(3)正式解析的第三步就进入了jRuby解析引擎的内核了,这是通过_parseSass私有方法来完成的:

从这里我们可以看出,它首先会构造一个HashMap对象,然后把我们要解析必要的参数,比如被解析的Sass内容(content),css的真实路径(cssRealPath),在当前应用使用的Theme的css路径(cssThemePath),sass的缓存位置(sassCachePath)都放在HashMap中,然后在第295行使用_rubyExecutor.eval()方法调用jRuby解析器(位于/webapps/ROOT/WEB-INF/lib/jruby.jar中)来解析这个Sass文件:


最后解析完的结果通过unsyncPrintWriter输出而返回,对于我们的main.css来说,经过这一步之后,结果还是一样的。因为这文件大多数都是引入其他文件,并没有Sass的语法,所以不受到jRuby解析引擎的 影响。


(4)正式解析的第四步是吧@portal_ctx@和@theme_image_path@注解都替换成相应的字符串,这个工作代码如下:

我们的main.css中没有这些标识符,所以不受到影响。


经过以上4步之后,这个方法就返回了dynamicContent,我们可以看到,它最终 返回到浏览器后的结果和正式解析第二步的一样:



以上我们讲解的是对于main.css的资源访问,我们现在来看下对于其中包含的某个用Sass写的文件,比如说上面的forms.css,这个流程又是这么样的。


其实大体上流程都一致:

我这里也想省略去多数重复的调试流程了,反正最终不一样的就是正式解析的第3步,它会去调用jruby.jar中的解析引擎去完成具体的解析,所以我们开始这个forms.css文件的内容是:

解析完成之后,这个文件内容变为:




总结:

(1)当单个加载Sass资源文件的时候,这种Sass资源文件都有可能有解析完的文件缓存在服务器上,并且缓存文件的位置一定在原始资源文件的上级目录下的.sass_cache目录下,并且文件名和原始Sass资源文件名字相同。

(2)正式解析的第一步是解析Sass文件中的静态符号,比如@model_hints_contant....@

(3) 正式解析的第二步是吧所有Sass中的以@import url()形式给出的外部引入,其被引入的资源文件后面都加上请求字符串,这是为了保证其请求的一致性。

(4)正式解析的第三步是调用jRuby的解析引擎根据解析语法进行解析,它会吧所有的Sass语法替换为普通的css语法,这个解析引擎位于webapps/ROOT/WEB-INF/lib/jruby.jar jar包中

(5)正式解析的第四步是做一些收尾工作,吧一些静态标识符@portal_ctx@和@theme_image_path@解析为字符串,因为在css文件中经常会用到一些外部图片参与到样式中。

(6)对于main.css ,主要影响的是(3)

(7)对于main.css包含的某个css,如果它是用Sass语法写的,那么主要受到影响的是(4)

(8)一般的css,如果页面上有一些特殊的记号,那么受到(2)和 (5)影响。





本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/1283396,如需转载请自行联系原作者
目录
相关文章
|
7月前
|
前端开发 算法 Java
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
伪类:伪类这个叫法源自于它们跟类相似,但实际上并没有类会附加到标记中的标签上。 伪类分为两种(以及新增的伪类选择器): UI伪类:会在HTML元素处于某种状态时(例如:鼠标指针位于连接上),为该元素应用CSS样式。 :hover 结构化伪类:会在标记中存在某种结构上的关系时 例如: 某元素是一组元素中的第一个或最后一个,为该元素应用CSS样式。 :not和:target(CSS3新增的两个特殊的伪类选择器)
788 2
|
前端开发 JavaScript
如何使用CSS过渡实现页面元素的淡入淡出效果?
如何使用CSS过渡实现页面元素的淡入淡出效果?
629 79
|
编解码 缓存 Prometheus
「ximagine」业余爱好者的非专业显示器测试流程规范,同时也是本账号输出内容的数据来源!如何测试显示器?荒岛整理总结出多种测试方法和注意事项,以及粗浅的原理解析!
本期内容为「ximagine」频道《显示器测试流程》的规范及标准,我们主要使用Calman、DisplayCAL、i1Profiler等软件及CA410、Spyder X、i1Pro 2等设备,是我们目前制作内容数据的重要来源,我们深知所做的仍是比较表面的活儿,和工程师、科研人员相比有着不小的差距,测试并不复杂,但是相当繁琐,收集整理测试无不花费大量时间精力,内容不完善或者有错误的地方,希望大佬指出我们好改进!
1111 16
「ximagine」业余爱好者的非专业显示器测试流程规范,同时也是本账号输出内容的数据来源!如何测试显示器?荒岛整理总结出多种测试方法和注意事项,以及粗浅的原理解析!
|
JSON 监控 网络协议
Bilibili直播信息流:连接方法与数据解析
本文详细介绍了自行实现B站直播WebSocket连接的完整流程。解析了基于WebSocket的应用层协议结构,涵盖认证包构建、心跳机制维护及数据包解析步骤,为开发者定制直播数据监控提供了完整技术方案。
1935 9
|
安全 IDE Java
重学Java基础篇—Java Object类常用方法深度解析
Java中,Object类作为所有类的超类,提供了多个核心方法以支持对象的基本行为。其中,`toString()`用于对象的字符串表示,重写时应包含关键信息;`equals()`与`hashCode()`需成对重写,确保对象等价判断的一致性;`getClass()`用于运行时类型识别;`clone()`实现对象复制,需区分浅拷贝与深拷贝;`wait()/notify()`支持线程协作。此外,`finalize()`已过时,建议使用更安全的资源管理方式。合理运用这些方法,并遵循最佳实践,可提升代码质量与健壮性。
458 1
|
数据采集 存储 数据库连接
Requests与BeautifulSoup:高效解析网页并下载资源
Requests与BeautifulSoup:高效解析网页并下载资源
|
传感器 监控 Java
Java代码结构解析:类、方法、主函数(1分钟解剖室)
### Java代码结构简介 掌握Java代码结构如同拥有程序世界的建筑蓝图,类、方法和主函数构成“黄金三角”。类是独立的容器,承载成员变量和方法;方法实现特定功能,参数控制输入环境;主函数是程序入口。常见错误包括类名与文件名不匹配、忘记static修饰符和花括号未闭合。通过实战案例学习电商系统、游戏角色控制和物联网设备监控,理解类的作用、方法类型和主函数任务,避免典型错误,逐步提升编程能力。 **脑图速记法**:类如太空站,方法即舱段;main是发射台,static不能换;文件名对仗,括号要成双;参数是坐标,void不返航。
545 5
|
存储 人工智能 并行计算
2025年阿里云弹性裸金属服务器架构解析与资源配置方案
🚀 核心特性与技术创新:提供100%物理机性能输出,支持NVIDIA A100/V100 GPU直通,无虚拟化层损耗。网络与存储优化,400万PPS吞吐量,ESSD云盘IOPS达100万,RDMA延迟<5μs。全球部署覆盖华北、华东、华南及海外节点,支持跨地域负载均衡。典型应用场景包括AI训练、科学计算等,支持分布式训练和并行计算框架。弹性裸金属服务器+OSS存储+高速网络综合部署,满足高性能计算需求。
|
前端开发 JavaScript
|
11月前
|
存储 前端开发 JavaScript
仿真银行app下载安装, 银行卡虚拟余额制作app,用html+css+js实现逼真娱乐工具
这是一个简单的银行账户模拟器项目,用于学习前端开发基础。用户可进行存款、取款操作,所有数据存储于浏览器内存中

推荐镜像

更多
  • DNS