浏览器探究——WebKit部分——支持WML

来源:互联网 发布:淘宝客服技巧和话术 编辑:程序博客网 时间:2024/05/17 03:58


开启宏定义

Android的代码中本身已经对WML做了一定的支持了,但是默认情况下并没有开启,这些支持都在一个ENABLE_WML的宏定义中括起来了,可以grep下源代码看下有很多ENABLE(WML)括起来的代码。

代码中需要的宏

这个ENABLE的宏定义我查的在Source/JavaScriptCore/wtf/Platform.h中被定义的,不知道为什么在这个目录下。#defineENABLE(WTF_FEATURE) (defined ENABLE_##WTF_FEATURE  && ENABLE_##WTF_FEATURE)

由以上ENABLE(WML)对应的宏定义就是ENABLE_WML。

注意这里的##是C语言宏的连接符,即把ENABLE_与WTF_FEATURE(传入的是WML)的内容连接起来,这样就连接成了ENABLE_WML。

这样#if ENABLE(WML) 会被预处理成 #if (defined ENABLE_WML && ENABLE_WML)

由此可见,我们首先要做的就是开启这个ENABLE_WML宏定义。

编译环境中变量定义

在external/webkit/Android.mk中加入下面代码开启宏的设置,我们需要让他的值为true,这里的含义是,如果ENABLE_WML环境值没有被定义过,则我们定义它为true。

ifeq ($(ENABLE_WML), )

   ENABLE_WML := true

endif

在编译脚本中定义代码中的宏

但是经过上述的内容,只是定义了编译环境里的变量,代码中的宏定义还没有被定义的,那么需要主动来设置下宏定义了,通过下面的方式

ifeq ($(ENABLE_WML), true)

   LOCAL_CFLAGS += -DENABLE_WML=1

endif

这里的-D编译选项是用来定义代码中的宏的,即设置c/c++中的DENABLE_WML宏的值为1。就相当于代码中的#define ENABLE_WML 1

通过上述两步,c/c++的宏被成功的定义了。

另外说下Source/JavaScriptCore/wtf/Platform.h这里有很多#defineENABLE_XXX的宏,这里可以修改一些宏的值来修改配置。

总结下上述的过程。有一个编译的环境变量叫ENABLE_WML,(你也可以命名为其他的名字),在判断这个环境变量如果没有被定义的话,那么在该脚本中定义它的值为true。

然后在脚本的后面,判断该环境变量值是否为true,如果为true那么就在编译配置LOCAL_CFLAGS中加入c/c++中的宏定义DENABLE_WML=1,(这里的宏定义命名必须是DENABLE_WML了。)

经过以上的配置,然后编译发现会有错误的。编译不过。

头文件的包含

刚才编译不过的原因是很多头文件和源文件并没有被编译,那么find下wml的文件在哪里。可以发现他们在./Source/WebCore/wml这个目录下,在./Source/WebCore/下还有html的目录,那么这里我们就模仿下html在Android.mk中的包含的方式。

在Android.mk中加入如下:

ifeq ($(ENABLE_WML), true)

LOCAL_C_INCLUDES := $(LOCAL_C_INCLUDES) \

   $(WEBCORE_PATH)/wml

endif

ifeq ($(ENABLE_WML), true)

LOCAL_C_INCLUDES := $(LOCAL_C_INCLUDES) \

   $(WEBCORE_INTERMEDIATES_PATH)/wml

endif

这里看下$(WEBCORE_PATH),这个路径就是external/webkit/Source/WebCore

而$(WEBCORE_INTERMEDIATES_PATH)则对应out/target/product/XXX/obj/STATIC_LIBRARIES/libwebcore_intermediates/Source/WebCore

源文件的包含

经过以上的加入还不够,以上只是加入了头文件。看下./Source/WebCore,发现这里还有个Android.mk。看看该文件发现里面有对源文件的包含,那么继续模仿html的方式加入wml的支持吧。

ifeq ($(ENABLE_WML), true)

LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \

   wml/WMLAccessElement.cpp \

    .......(这里把wml目录下所有的源文件都写上)

    wml/WMLVariables.cpp

endif

添加wml的style sheets

在./Source/WebCore/css/下有XXX.css文件,这些貌似定义了不少的css,对css我也不怎么懂,但是看下是有html.css的。

另外需要看一个重要的文件,./Source/WebCore/DerivedSource.mk中有如下的语句

ifeq ($(findstring ENABLE_WML,$(FEATURE_DEFINES)),ENABLE_WML)

USER_AGENT_STYLE_SHEETS := $(USER_AGENT_STYLE_SHEETS)$(WebCore)/css/wml.css

endif

即它告诉我们如果我们需要使能WML那么需要添加对这个的支持,这个就是用于环境变量USER_AGENT_STYLE_SHEETS上。

而在./Source/WebCore/Android.derived.mk中有对html.css的包含。那么继续效仿添加对wml.css的支持。

ifeq ($(ENABLE_WML), true)

style_sheets := $(style_sheets)$(LOCAL_PATH)/css/wml.css

endif

添加生成WMLName.cpp(.h)和WMLElementFactory.cpp(.h)的支持

经过以上的包含后执行编译发现还是编译不过。提示没有WMLNames.h这个文件。

查看网上的内容,发现WMLName.h这个并不是源码本身提供的,在./Source/WebCore/wml/下有WMLTagName.in和WMLAttributeNames.in。但是并没有WMLNames.h和WMLNames.cpp,这两个文件时生成的并且生成在out/target/product/XXX/obj/STATIC_LIBRARIES/libwebcore_intermediates/Source/WebCore/wml下

再看下./Source/WebCore/DerivedSource.mk文件,这里还有对这两个的描述并且也有对WMLNames的描述。

# --------

# WML tag and attribute names, and elementfactory

ifeq ($(findstringENABLE_WML,$(FEATURE_DEFINES)), ENABLE_WML)

WMLElementFactory.cpp WMLNames.cpp :dom/make_names.pl wml/WMLTagNames.in wml/WMLAttributeNames.in

   perl -I $(WebCore)/bindings/scripts $< --tags$(WebCore)/wml/WMLTagNames.in --attrs $(WebCore)/wml/WMLAttributeNames.in--factory --wrapperFactory

else

WMLElementFactory.cpp :

   echo > $@

WMLNames.cpp :

   echo > $@

endif

# --------

不清楚这段描述是什么意思,但是可以看到WMLNames.cpp和WMLElementFactory.cpp应该是生成出来的,并且会利用到wml/WMLTagNames.in wml/WMLAttributeNames.in。另外在./Source/WebCore/CodeGenerators.pri中也有一些对WMLNames的描述可以做参考。

参照网上对这块的支持方法,是在./Source/WebCore/Android.derived.mk中添加如下:

参考XMLNames.cpp的生成方式,生成wml对应的WMLNames.cpp .h等

ifeq ($(ENABLE_WML), true) 
GEN:= $(intermediates)/WMLNames.cpp $(intermediates)/WMLNames.h$(intermediates)/WMLElementFactory.cpp $(intermediates)/WMLElementFactory.h 
$(GEN): PRIVATE_PATH := $(LOCAL_PATH) 
$(GEN): PRIVATE_CUSTOM_TOOL = perl -I $(PRIVATE_PATH)/bindings/scripts $<--tags $(wml_tag) --attrs $(wml_attrs) --factory --wrapperFactory --output$(dir $@) 
$(GEN): wml_tag := $(LOCAL_PATH)/wml/WMLTagNames.in 
$(GEN): wml_attrs := $(LOCAL_PATH)/wml/WMLAttributeNames.in 
$(GEN): $(LOCAL_PATH)/dom/make_names.pl $(wml_tag) $(wml_attrs) 
$(transform-generated-source) 
LOCAL_GENERATED_SOURCES += $(GEN) 
endif 

对WML的MimeType的支持

获取到服务器返回的数据中的content-type字段值后,会调用DOMImplementation::isXMLMIMEType(constString& mimeType)方法来判断是否按照XML格式来解析。

Wml页面的MimeType是”text/vnd.wap.wml”,在这个函数里并没有对这个MimeType进行判断,那么我们需要加上

#ifENABLE(WML)

    if (mimeType =="text/vnd.wap.wml")

        return true;

#endif

经过以上的这些操作,终于可以编译通过并且可以打开一个wml的页面了,但是android上对wml的支持并不完善还有不少的bug需要解,这里就不讨论了。

0 0
原创粉丝点击