日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

浅谈WebKit之Port

發布時間:2024/4/15 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅谈WebKit之Port 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
WebKit作為一個瀏覽器引擎,其相對于Gecko而言一個較大的特點就是便于移植,嵌入到其他程序中,目前大家已了解使用WebKit引擎的應用包括Safari、iPhone、Chrome、Android、Nokia S60 Browser及KDE QT4.4等,同時還有其他方面的移植如Gtk、wxWidget、3D等,可以說WebKit從架構上講其Port移植方面的設計及應用,是非常優秀的。這一點相對于Gecko有相當大的優勢,有時間可以參考一下淺談Gecko關鍵部分之十二Embedding。為了更深入的了解WebKit,我們現在就從WebKit有關Ports方面入手,了解其有關Port方面的設計,從而了解究竟如何能移植WebKit到自己的應用中。

一、有關Port方面的概述
在通過了解 淺談WebKit之WebCore 之后,應該說WebKitPort方面的內容是可以很廣的,例如可將不同的圖形庫、網絡庫與WebCore集成,提供不同的Port接口供外部程序使用等,例如同樣在windows平臺上可以運行的Google Chrome和Safari就是針對WebKit的不同移植。

我們想了解有關Port方面的主要內容在于提供不同的Port接口供外部程序使用以及如何與外部程序交互,因為WebKit中的其它兩部分WebCore、Javascript實現,從邏輯上講是不直接提供接口給外部程序使用的。同時為了完成瀏覽器的核心功能,WebKit也需要從外部程序中通過Port接口的方式獲取一些支持。

從這個角度講WebKit作為一個相對獨立的整體,它與外部程序之間的交互也就有一組相對固定的接口來定義及維護它們之間的關系,它們之間的關系與插件跟瀏覽器引擎之間的關系完全類似,接口相當一組協議,有的是由WebKit來實現,而供外部程序調用;有的的正好相反。

通過前面的了解我們知道WebKit的主要功能集中在分析Html、渲染布局Web內容以及Javascript實現方面等,而這些Web內容顯示在哪個窗口及消息處理的啟動循環等都需要由外部程序來提供。

二、初步分析已有WebKit Port移植實現

1、與WebCore交互接口的實現?
? ? ? ? 在WebKit源代碼目錄結構中WebKit目錄下分別包含gtk、mac、qt、win、wx目錄,其分別對應不同的Port移植方式,在每一個目錄下面都包括 WebCoreSupport目錄,而在不同的WebCoreSupport目錄下分別包含有對類接口WebCore::ChromeClient、 WebCore::ContextMenuClient、WebCore::DragClient、WebCore::EditorClient、 WebCore::FrameLoaderClient、WebCore::InspectorClient等的實現,它們代表外部程序提供給 WebKit內部使用的接口實現,其中WebCore::ChromeClient、WebCore::FrameLoaderClient非常重要。

? ? ??

初步了解其接口定義能基本了解其對應的含義,這些接口往往需要由Port移植部分來提供實現,往往由WebKit內部根據一定的條件來調用。下面初步來了解幾個主要接口:

WebCore::ChromeClient接口:

[cpp]?view plaincopy
  • //往往在運行window.open腳本時調用,以便由外部程序決定如何打開一個新頁面如新建一個窗口、新建一個Tab頁簽等;??
  • virtual?WebCore::Page*?createWindow(WebCore::Frame*,?const?WebCore::FrameLoadRequest&,?const?WebCore::WindowFeatures&);??
  • ??
  • //通知外部程序顯示頁面;??
  • virtual?void?show();??
  • ??
  • virtual?bool?canRunModal();??
  • ??
  • //通知外部程序以Modal的方式顯示頁面;??
  • virtual?void?runModal();??
  • ??
  • //通知外部程序顯示JS警告提示窗口;??
  • virtual?void?runJavaScriptAlert(WebCore::Frame*,?const?WebCore::String&);??
  • ??
  • //通知外部程序顯示JS警告確認窗口;??
  • virtual?bool?runJavaScriptConfirm(WebCore::Frame*,?const?WebCore::String&);??
  • ??
  • WebCore::FrameLoaderClient接口:??
  • //檢查是否擁有主頁面窗口;??
  • virtual?bool?hasWebView()?const;??
  • //檢查是否擁有頁面窗口;??
  • virtual?bool?hasFrameView()?const;??
  • ??
  • //通知外部程序有關http請求開始、結束、獲取數據等,如通常瀏覽器狀態欄顯示的信息;??
  • virtual?void?dispatchDidReceiveResponse(WebCore::DocumentLoader*,?unsigned?long?identifier,?const?WebCore::ResourceResponse&);??
  • virtual?void?dispatchDidReceiveContentLength(WebCore::DocumentLoader*,?unsigned?long?identifier,?int?lengthReceived);??
  • virtual?void?dispatchDidFinishLoading(WebCore::DocumentLoader*,?unsigned?long?identifier);??
  • virtual?void?dispatchDidFailLoading(WebCore::DocumentLoader*,?unsigned?long?identifier,?const?WebCore::ResourceError&);??
  • ??
  • //通知外部程序WebKit內部主要事件處理,以便外部程序及時響應或創建維護數據等??
  • virtual?void?dispatchDidHandleOnloadEvents();??
  • virtual?void?dispatchDidReceiveServerRedirectForProvisionalLoad();??
  • virtual?void?dispatchDidCancelClientRedirect();??
  • virtual?void?dispatchWillPerformClientRedirect(const?WebCore::KURL&,?double?interval,?double?fireDate);??
  • virtual?void?dispatchDidChangeLocationWithinPage();??
  • virtual?void?dispatchWillClose();??
  • virtual?void?dispatchDidReceiveIcon();??
  • virtual?void?dispatchDidStartProvisionalLoad();??
  • virtual?void?dispatchDidReceiveTitle(const?WebCore::String&);??
  • virtual?void?dispatchDidCommitLoad();??
  • virtual?void?dispatchDidFinishDocumentLoad();??
  • virtual?void?dispatchDidFinishLoad();??
  • virtual?void?dispatchDidFirstLayout();??
  • ??
  • //告訴外部程序需要提供切換到一個新頁面狀態。此時外部程序往往會新建FrameView,并將FrameView與Frame關聯,設置原生窗口句柄及其消息處理機制等等;??
  • virtual?void?transitionToCommittedForNewPage();??
  • ??
  • //告訴外部程序創建一個新的Frame,如遇到html中iframe標簽時,需要外部程序創建一個新的Frame及原生窗口句柄等;??
  • virtual?PassRefPtr?createFrame(const?WebCore::KURL&?url,?const?WebCore::String&?name,?WebCore::HTMLFrameOwnerElement*?ownerElement,??
  • const?WebCore::String&?referrer,?bool?allowsScrolling,?int?marginWidth,?int?marginHeight);??
  • ??
  • //告訴外部程序需要創建一個Plugin實例,從而創建其原生窗口等等;??
  • virtual?WebCore::Widget*?createPlugin(const?WebCore::IntSize&,?WebCore::Element*,?const?WebCore::KURL&,?const?Vector&,?const?Vector&,?const?WebCore::String&,?bool?loadManually);??

  • 2、對WebCore中的page/loader等方面的類提供對應Port的實現支持?
    ? ? ? 如EventHandlerWin.cpp、FrameLoaderWin.cpp、DocumentLoaderWin.cpp、DocumentLoaderWin.cpp、WidgetWin.cpp、KeyEventWin.cpp等

    3、實現WebView及WebFrame等以便外部程序嵌入WebKit?
    ? ? ? 不同的Port移植對WebView及WebFrame的定義及實現有所不同,但其與WebCore中的Page、Frame之間的關系大致與淺談WebKit之WebCore篇圖一描述相一致。

    ? ? ? 具體關于WebView、WebFrame的定義與實現,特別是初始化時的動作可根據不同的Port移植而有所不同,同時初始化時會將上面提到的WebCore Port接口實現告訴WebKit內部。主要示例代碼如下:

    [cpp]?view plaincopy
  • static?void?webkit_web_view_init(WebKitWebView*?webView)??
  • {??
  • WebKitWebViewPrivate*?priv?=?WEBKIT_WEB_VIEW_GET_PRIVATE(webView);??
  • webView->priv?=?priv;??
  • priv->corePage?=?new?Page(new?WebKit::ChromeClient(webView),?new?WebKit::ContextMenuClient(webView),?new?WebKit::EditorClient(webView),?new?WebKit::DragClient,?new?WebKit::InspectorClient);??
  • priv->mainFrame?=?WEBKIT_WEB_FRAME(webkit_web_frame_new(webView));??
  • priv->lastPopupXPosition?=?priv->lastPopupYPosition?=?-1;??
  • priv->editable?=?false;??
  • ................................??
  • ??
  • priv->webSettings?=?webkit_web_settings_new();??
  • webkit_web_view_update_settings(webView);??
  • ..................................??
  • }??
  • ??
  • WebKitWebFrame*?webkit_web_frame_new(WebKitWebView*?webView)??
  • {??
  • g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView),?NULL);??
  • ??
  • WebKitWebFrame*?frame?=?WEBKIT_WEB_FRAME(g_object_new(WEBKIT_TYPE_WEB_FRAME,?NULL));??
  • WebKitWebFramePrivate*?priv?=?frame->priv;??
  • WebKitWebViewPrivate*?viewPriv?=?WEBKIT_WEB_VIEW_GET_PRIVATE(webView);??
  • ??
  • priv->webView?=?webView;??
  • priv->client?=?new?WebKit::FrameLoaderClient(frame);??
  • priv->coreFrame?=?Frame::create(viewPriv->corePage,?0,?priv->client).get();??
  • priv->coreFrame->init();??
  • ??
  • return?frame;??
  • }??

  • 4、Chrome中對Port移植方面的實現?
    ? ? ? ? 其基本上與其他Port移植類似,其主要代碼在webkit/glue目錄中,可重點關注帶client_impl.cc后綴的文件、 webview_impl.cc、webwidget_impl.cc等;但是其究竟如何創建原生windows窗口、如何創建Render進程、 Render進程與創建的原生windows窗口的關系如何等需要更進一步深入研究Chrome,如果能從上面提到的Port部分入手也許很快就可得到答案,這一點以后有機會單獨研究。

    5、Android中對Port移植方面的實現
    其實現有點特殊,由于Andriod將WebKit以一個Java類接口的方式提供給Java環境使用(不像上面提到的Chrome、Safari等都是將WebKit以 一個C++動態或靜態庫的方式供C/C++外部程序調用),這樣WebKit內部與外部即JavaVM的交互(如上面提到的ChromeClient、 FrameLoaderClient接口實現)需要一個Bridge類來協調處理,同時WebView、WebFrame接口綁定給JavaVM的jni接口實現也需要通過這個Bridge來支持協調處理。具體可詳細參考android源碼代碼中WebCore\platform\android目錄下的源文件。

    6、通過進一步了解WebCore Port接口及其實現,可以加深這樣一個認識:
    如果從MVC的角度來看整個基于WebKit的瀏覽器(當然不盡合理),WebKit的Port部分相當于V部分,它提供顯示頁面內容及其輔助信息(如提示狀態)的場所(即原生窗口)以及控制該顯示場所的狀態變化及消息響應(如改變大小、鼠標移動等);而M部分往往由WebCore來實現,至于WebCore如何組織DOM則往往由htmlparser部分根據DOM定義來組織,如何在提供的顯示場所顯示Web內容則往往由WebCore中的layout部分來實現,其中充分利用了Css定義來布局顯示該顯示的內容;一旦涉及控制或動態處理往往由Port部分發起而由Javascript腳本來實現處理,其任務由JavascriptCore或V8來完成。

    一般說來新打開一個頁面,Port部分需要提供一個主顯示場所(即原生窗口),如果頁面中含有iframe標簽,則需要在主顯示場所內創建一個子顯示場所,以顯示iframe標簽對應src的內容;如果頁面中含有embed/object等插件標簽同樣往往也需要在主顯示場所內創建一個子顯示場所(除非windowless),以交由插件實現在提供的顯示場所中顯示內容。

    特別需要說明的是我們通常看到的頁面表單元素input text field、textArea、button、radiobutton等往往不像window圖形庫中的按鈕、菜單、輸入框等會對應一個原生窗口,頁面中的表單元素在一個顯示場所(即原生窗口)中完全是利用Css等通過layout方式來達到我們所看到的類似原生按鈕、輸入框、列表框、滾動條等效果,其中特別是能準確定位元素大小、設置focus、光標顯示、響應事件等,這充分的說明了瀏覽器引擎內部布局部分的威力所在。

    從另外一個角度來看一個頁面一般說來(除非遇到iframe或插件需要另外提供一塊子畫布)相當于一塊畫布,瀏覽器引擎能在其精確的位置繪制不同顏色的文字、圖片、圖標等,同時根據當前的鼠標及一個模擬的輸入提示光標位置,接收鍵盤輸入操作。頁面中的絕大多數元素與原生的窗口元素幾乎沒有關聯,完全通過組合、布局、準確定位來處理一切。。。

    三、如何利用WebKit?
    了解WebKit Port部分,對我們如何利用WebKit有非常現實的意義,目前已經將WebKit移植到多種平臺如windows、qt、gtk、mac、wx、java、framebuffer等,甚至移植到python、ruby及3D等環境中去。通過借鑒或利用這些已有的WebKit Port實現,完全可以將WebKit發揚廣大。

    前一階段正好得到一個網友抓取網頁的需求,試想目前移植利用WebKit基本都用來顯示頁面,往往涉及圖形顯示方面,但隨著ajax及動態頁面的廣泛使用,未來動態生成的頁面越來越多,傳統的搜索引擎僅僅抓取靜態的頁面內容顯然是不夠的,現代化的搜索引擎應該能抓取動態的頁面內容,這樣它從某種意義講相當于一個能獲取對應的動態頁面但不真正顯示出其內容的瀏覽器,這樣一個搜索引擎不僅能分析DOM樹,同時能運行Javascript腳本(如運行ajax),以真正完整獲取頁面內容,其實這樣一個搜索引擎如果利用WebKit來實現的話,應該是個不錯的選擇,在我們了解WebKit Port部分之后,我們是否可以來模擬一個不真正具備圖形顯示方面的Port,進而充分利用WebKit中的WebCore及Javascript實現方面的功能呢?一點想法,今后有機會可以試試,或許Google、Yahoo的搜索引擎已經有了相關的實現,不知是否使用的就是WebKit?應該不會,有誰清楚的話,煩請通知一聲。

    但愿我們也能利用利用WebKit整出一個象模象樣的東東如機頂盒瀏覽器、手機瀏覽器等等。。

    四、參考資源
    The WebKit Open Source Project
    Google Chrome Home
    Android - An Open Handset Alliance Project

    總結

    以上是生活随笔為你收集整理的浅谈WebKit之Port的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。