瀏覽器探究——WebKit部分——支持WML



開啓宏定義

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需要解,這裏就不討論了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章