首页 webkit自带谷歌浏览器实例分析

webkit自带谷歌浏览器实例分析

举报
开通vip

webkit自带谷歌浏览器实例分析Webkit自带谷歌浏览器实例分析(1) 先看下这个简单浏览器的图片效果 我这个程序源代码是用source insight阅读的,,,source insight怎一个强字了得?! 从main函数开始分析: int main (int argc, char* argv[]) { gtk_init (&argc, &argv); /*初始化gtk整个实例,每个gtk中必有的*/ if (!g_thread_supported ()) g_thread_init (NULL); GtkWidget* vbox = gt...

webkit自带谷歌浏览器实例分析
Webkit自带谷歌浏览器实例分析(1) 先看下这个简单浏览器的图片效果 我这个程序源代码是用source insight阅读的,,,source insight怎一个强字了得?! 从main 关于工期滞后的函关于工程严重滞后的函关于工程进度滞后的回复函关于征求同志党风廉政意见的函关于征求廉洁自律情况的复函 数开始分析: int main (int argc, char* argv[]) { gtk_init (&argc, &argv); /*初始化gtk整个实例,每个gtk中必有的*/ if (!g_thread_supported ()) g_thread_init (NULL); GtkWidget* vbox = gtk_vbox_new (FALSE, 0); /*创建一个垂直的box来存放下列 部件,创建并添加工具栏(toolbar)、浏览器(browser)、状态栏(statusbar)*/ gtk_box_pack_start (GTK_BOX (vbox), create_toolbar (), FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), create_browser (), TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (vbox), create_statusbar (), FALSE, FALSE, 0); main_window = create_window ();/*创建主窗口,放置vbox*/ gtk_container_add (GTK_CONTAINER (main_window), vbox); /*将vbox放入主窗口*/ /*判断是否输入网址也就是命令行参数,有的话将值给uri,没有的话设为默认*/ gchar* uri = (gchar*) (argc > 1 ? argv[1] : "http://www.google.com/"); webkit_web_view_load_uri (web_view, uri);/*调用webkit库函数加载uri网址*/ gtk_widget_grab_focus (GTK_WIDGET (web_view));/抓取web_view上的焦点?*/ /*现实整个主窗口,也就是浏览器窗口*/ gtk_widget_show_all (main_window); gtk_main (); return 0; } 主函数从前到后读下来基本没什么问题,只是对web_view有点困惑,于是找到定义的地方 static WebKitWebView* web_view; /*很显然是一个全局静态变量*/ 在webkit的源码包中的gtk目录下的webkit下的Webkitwebview.h查找WebKitWebView: 发现typedef struct _WebKitWebView WebKitWebView; struct _WebKitWebView的结构为: struct _WebKitWebView { GtkContainer parent_instance; /*< private >*/ WebKitWebViewPrivate *priv; }; 依然不大懂,继续挖掘WebKitWebViewPrivate:真是有种取之不尽挖之不绝的感觉 O(∩_∩)O typedef struct _WebKitWebViewPrivate WebKitWebViewPrivate; 再往下看终于看到曙光了: struct _WebKitWebViewPrivate { WebCore::Page* corePage; /*这个应该是核心页面吧*/ WebKitWebSettings* webSettings; /*页面有关的设置木有细挖,水太深*/ WebKitWebInspector* webInspector; /*什么检查员?*/ WebKitWebWindowFeatures* webWindowFeatures; /*Window的特性*/ WebKitWebFrame* mainFrame; /*web主框架*/ WebKitWebBackForwardList* backForwardList; /*保存前进后退的链 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf */ gint lastPopupXPosition; /*不太懂*/ gint lastPopupYPosition; /*依然不太懂*/ 此处也省略很多 }; WebCore::Page*?是什么东东?真是一波未平一波又起,杯具之情油然而生,究竟何时是尽头,,,?放弃or继续走下去?其实本来想放弃的,但是想想都挖了这么深了,放弃了可惜哇,,,go ahead!继续挖: 何为命名空间?据《c++primer》传言,一般大型程序或者库文件有很多全局变量,这些变量重名的概率是相当的高,所以就会引起名字冲突,《C++primer》起了个洋气的名字,叫“命名空间污染”,其实就是重名引起冲突而已。为了避免这种污染,就有了命名空间。 namespace WebCore { AccessibilityARIAGrid::AccessibilityARIAGrid(RenderObject* renderer) : AccessibilityTable(renderer) { #if ACCESSIBILITY_TABLES m_isAccessibilityTable = true; #else m_isAccessibilityTable = false; #endif }/*擦……无穷尽呐~*/ 挖了半天,还是没有看到page,原来是文件找错了⊙﹏⊙b汗,,,继续挖,,,终于在WebKit-r47011\WebCore\page\gtk下面的EventHandlerGtk.cpp中发现了这个东东,但是凭我的智商,暂时这块还是先不挖了,为啥?请注意看……见证历史的时刻到了 namespace WebCore { class Chrome; class Page : public Noncopyable { public: static void setNeedsReapplyStyles(); Page(ChromeClient*, ContextMenuClient*, EditorClient*, DragClient*, InspectorClient*); ~Page(); RenderTheme* theme() const { return m_theme.get(); }; static void refreshPlugins(bool reload); PluginData* pluginData() const; void setCanStartPlugins(bool); bool canStartPlugins() const { return m_canStartPlugins; } void addUnstartedPlugin(PluginView*); void removeUnstartedPlugin(PluginView*); EditorClient* editorClient() const { return m_editorClient; } void setMainFrame(PassRefPtr); Frame* mainFrame() const { return m_mainFrame.get(); } BackForwardList* backForwardList(); ………… 此处省略n多行个……,n>100 }?end Page?/*貌似这个是webkit特有的注释( ⊙o⊙ )哇,经查证是SI的风格*/ } ?end WebCore? 至此 本文件的WebCore命名空间总算是完成了,,,我这里贴过来的代码大概是十分之一左右,,,╭(╯^╰)╮,知道我为啥不挖了吧,,,挖不完(⊙o⊙)!,大概知道就行了嘛!Page是干嘛的?与页面相关的风格、主题、框架的设置、插件、前进后退的链表,等等等等。整个文件就先不挖了,,,现在挖完以后就没事干了 看到这里,,,懵懵懂懂的貌似知道了web_view是什么东东了,,,应该就是浏览器显示网站的那部分视图哇,其中就包含page,不管了先这么理解,等真正理解了再反过来看 现在,main函数中依然朦胧的函数就是下面的两个了,,,哇!挖!马上挖完了 webkit_web_view_load_uri (web_view, uri); gtk_widget_grab_focus (GTK_WIDGET (web_view)); 这个可比web_view好挖多了,,,WebKit-r47011\WebKit\gtk\webkit的webkitwebview.h下面,一目了然! void webkit_web_view_load_uri(WebKitWebView* webView, const gchar* uri) { g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));/*这里应该是错误检测机制*/ g_return_if_fail(uri); WebKitWebFrame* frame = webView->priv->mainFrame; webkit_web_frame_load_uri(frame, uri); } void webkit_web_frame_load_uri(WebKitWebFrame* frame, const gchar* uri) { g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame)); g_return_if_fail(uri); Frame* coreFrame = core(frame); if (!coreFrame) return; coreFrame->loader()->load(ResourceRequest(KURL(KURL(), String::fromUTF8(uri))), false); } 意思就是Frame类型的coreFrame对象的loader()成员函数的返回值是FrameLoader类型的对象,然后FrameLoader类又有load(x,x,x)成员函数,,,(好纠结)我估计webkkit是将“->”运算符重载了。反正就是要加载网址uri在webview中显示。 ⊙﹏⊙b汗,,,说来杯具,,,我是用GTK作为开发工具,,,所以一直以为webkit是用GObject实现的,,,知道看到现在才发现webkit是用C++实现的,,,我勒个去!我说这个webkit模仿C++也模仿的忒像了吧,啊哦,杯具…… 下面看下gtk_widget_grab_focus (GTK_WIDGET (web_view)),这个是Gtk的函数,比webkit好多了,,,嘎嘎~ Void gtk_widget_grab_focus (GtkWidget *widget)我是这样理解的:让widget能够为整个窗口捕获键盘的焦点。 那么整个main函数以及第二层(接口函数)现在我们就走通了,,,咱是不是也可以写一个简单的浏览器了呐?嘎嘎O(∩_∩)O,,,欲知后事如何,且看下回分解。。。 Webkit自带谷歌浏览器实例分析(2) 上篇说到,咱们把main函数走了一遍了,是不是可以写个基于webkit简单的浏览器了呢? 非也,,,其实即便是这么简单的浏览器,代码也还没完。Main函数只是整个程序的一个入口而已,也就是说只是个门口,,,~~~~(>_<)~~~~ 好辛苦啊……里边东西多着哩! 还有三个创建整个浏览器界面的函数,不过我认为对了解Gtk的人来说应该不是很麻烦,只是核心部分是与webkit的接口,是不是还是像上节那样一直挖下去呢?快来看看吧~ 还是先找重点的那三个函数。。。 /*严格来说这个例子很懒,直接定义在main函数之前了,有点乱是不?*/ static GtkWidget* create_toolbar (){} /*返回个工具栏,,,有点废话哈~*/ static GtkWidget* create_browser (){}/*返回个browser,,,依然废话哈~,这个browser是什么哇?有点犯嘀咕*/ static GtkWidget* create_statusbar (){} /*这个好理解多了*/ /*Come on baby!创建工具栏啦*/ static GtkWidget* create_toolbar () { GtkWidget* toolbar = gtk_toolbar_new (); /*创建一个工具栏部件*/ #if GTK_CHECK_VERSION(2,15,0) /*检查GTK+的版本,版本要比括号中的新才好*/ gtk_orientable_set_orientation (GTK_ORIENTABLE (toolbar), GTK_ORIENTATION_HORIZONTAL); #else gtk_toolbar_set_orientation (GTK_TOOLBAR (toolbar), /*设置工具箱是水平显示还是垂直显示*/ GTK_ORIENTATION_HORIZONTAL); #endif /*设置toolbar风格GTK_TOOLBAR_BOTH_HORIZ 是自定义的*/ gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH_HORIZ); GtkToolItem* item; /*新建一个小家伙,准备暂存工具栏的控件*/ /* 后退按钮下边红色部分函数是从储存库中得到GTK_STOCK_GO_BACK图标*/ item = gtk_tool_button_new_from_stock (GTK_STOCK_GO_BACK); /*将信号click与item部件绑定,点击按钮时候调用go_back_cb ,null是要传给回调函数的参数,这里为空。一会再分析回调函数,回调函数一般cb结尾*/ g_signal_connect (G_OBJECT (item), "clicked", G_CALLBACK (go_back_cb), NULL); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);/*负1表示从工具栏的最后第一个位置追加*/ /* 前进按钮,同上,就不罗嗦了 */ item = gtk_tool_button_new_from_stock (GTK_STOCK_GO_FORWARD); g_signal_connect (G_OBJECT (item), "clicked", G_CALLBACK (go_forward_cb), NULL); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);/*追加到最后一个*/ /* 地址输入栏,,,注意了啊,含金量的地方!O(∩_∩)O */ item = gtk_tool_item_new (); gtk_tool_item_set_expand (item, TRUE);/*将item放大占据额外的控件*/ uri_entry = gtk_entry_new ();/*创建一个网址输入框直接加到工具栏可否?*/ gtk_container_add (GTK_CONTAINER (item), uri_entry);/*放到item中去*/ g_signal_connect (G_OBJECT (uri_entry), "activate", G_CALLBACK (activate_uri_entry_cb), NULL); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1); /* The go button */ item = gtk_tool_button_new_from_stock (GTK_STOCK_OK); /* g_signal_connect_swapped 与g_signal_connect 意思一样,只不过前者的回调函数有一个参数,也就是g_signal_connect_swapped的第四个参数,这次非空了噶 */ g_signal_connect_swapped (G_OBJECT (item), "clicked", G_CALLBACK (activate_uri_entry_cb), (gpointer)uri_entry); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1); return toolbar; }/*工具栏创建完毕,,,先把这三个函数看完,待会去看回调函数去*/ /*创建browser,何为browser,,,我也不知道,不过一会就知道了*/ static GtkWidget* create_browser () { /*先创建一个带滚动条的滚动窗,原来如此,滚动条是滚动窗的一部分啊*/ GtkWidget* scrolled_window = gtk_scrolled_window_new (NULL, NULL); /*为滚动条设置一个策略,GTK_POLICY_AUTOMATIC 意思是需要时候才显示*/ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); /*这个是全局变量,相当于一个view就是(标题栏+页面)视图,然后放入滚动窗*/ web_view = WEBKIT_WEB_VIEW (webkit_web_view_new ()); gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET (web_view)); g_signal_connect (web_view, "title-changed", G_CALLBACK (title_change_cb), web_view);/* title-changed信号与web_view绑定.时间发生调用title_change_cb回调函数改变标题*/ g_signal_connect (web_view, "notify::load-status", G_CALLBACK (notify_load_status_cb), web_view);/*加载状态,分为正在提交,加载完成,未加载三个状态*/ g_signal_connect (web_view, "notify::progress", G_CALLBACK (notify_progress_cb), web_view);/*加载进度*/ g_signal_connect (web_view, "hovering-over-link", G_CALLBACK (link_hover_cb), web_view); return scrolled_window; } /*至此带滚动条的窗口创建完毕,,,回调函数与信号回头一起研究*/ static GtkWidget* create_statusbar () { main_statusbar = GTK_STATUSBAR (gtk_statusbar_new ()); status_context_id = gtk_statusbar_get_context_id (main_statusbar, "Link Hover"); return (GtkWidget*)main_statusbar; }/*创建状态栏*/ /*下面该创建个东西放这三个:工具栏、状态栏、browser了,创建mainwindow*/ static GtkWidget* create_window () { /*创建一个主窗口*/ GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL); /*设置默认大小*/ gtk_window_set_default_size (GTK_WINDOW (window), 800, 600); gtk_widget_set_name (window, "GtkLauncher");/*设置窗口名字*/ /*绑定销毁回调函数,一般来说都会有这个函数的*/ g_signal_connect (window, "destroy", G_CALLBACK (destroy_cb), NULL); return window; }/*主窗口创建完毕*/ 目前为止,整个程序基本上走完了一遍,程序的第二个层次也已分析完毕,,,剩下的回调函数部分是与webkit接触最为紧密的一部分,且听下回细细道来 Webkit自带谷歌浏览器实例分析(3) 第二节我们几个重要函数的实现涉及到的回调函数都没有过多的解释,是因为我想单独的拿出来品味,慢慢享用。 /*这是上边用到的几个全局变量*/ static GtkWidget* main_window; static GtkWidget* uri_entry; static GtkStatusbar* main_statusbar; static WebKitWebView* web_view; /*这里就是指的我们平常看到的浏览器(标题+页面)视图*/ static gchar* main_title; static gdouble load_progress; static guint status_context_id; /*注意了,,,,,,回调函数开始啦……*/ static void activate_uri_entry_cb (GtkWidget* entry, gpointer data) {/*往地址栏里边输入地址时候触发事件发出*/ const gchar* uri = gtk_entry_get_text (GTK_ENTRY (entry)); g_assert (uri); /*这里是个断言,就像c语言中的一样*/ webkit_web_view_load_uri (web_view, uri);/*如果uri没错,加载*/ } static void update_title (GtkWindow* window)/*这个不是回调函数,,,因为它没cb(*^__^*) */ { /*新建一个GString对象,并用main_title初始化*/ GString* string = g_string_new (main_title); /* g_string_append 往string里边追加字符串*/ g_string_append (string, " - WebKit Launcher"); /*加载进度小于100%的话,在整个window标题栏以数字形式打印进度。如果难以理解可以看看上边的图*/ if (load_progress < 100) /*下面的函数有点像sprintf()*/ g_string_append_printf (string, " (%f%%)", load_progress); gchar* title = g_string_free (string, FALSE); /*为FALSE的时候,并不删除string的所指向的实际数据,而是把它返回给title 。如果为true,则也将内存中的数据一并释放,就无法显示在window上了,不过我感觉这里比较赘余*/ gtk_window_set_title (window, title); g_free (title); } /*Hover英文是徘徊的意思,,,而这里就是说链接(link)在状态栏里边徘徊来徘徊去的意思,看一下运行实例,是不是很有意思O(∩_∩)O~*/ static void link_hover_cb (WebKitWebView* page, const gchar* title, const gchar* link, gpointer data) { /*gtk_statusbar_pop() 删除在栈中给定上下文标识符的最上面的一条消息因为要显示新的link了,所以要删除旧的。*/ gtk_statusbar_pop (main_statusbar, status_context_id); /*如果link存在,则把它加入到状态栏的栈中,同时status_context_id 是标示在不通状态下的显示内容的id*/ if (link) gtk_statusbar_push (main_statusbar, status_context_id, link); } static void title_change_cb (WebKitWebView* web_view, WebKitWebFrame* web_frame, const gchar* title, gpointer data) { if (main_title) g_free (main_title); main_title = g_strdup (title);/*得到title的一个副本,不用时候会被释放*/ update_title (GTK_WINDOW (main_window));/*调用函数,改变窗口标题*/ } static void /* notify::load-status 信号产生时候调用*/ notify_load_status_cb (WebKitWebView* web_view, GParamSpec* pspec, gpointer data) { /*如果浏览器显示状态时正在加载提交的话,得到uri并放入entry框*/ if (webkit_web_view_get_load_status (web_view) == WEBKIT_LOAD_COMMITTED) { WebKitWebFrame* frame = webkit_web_view_get_main_frame (web_view); const gchar* uri = webkit_web_frame_get_uri (frame); if (uri) gtk_entry_set_text (GTK_ENTRY (uri_entry), uri); } } static void /* notify::progress 这些信号貌似都是自定义的信号*/ notify_progress_cb (WebKitWebView* web_view, GParamSpec* pspec, gpointer data) { load_progress = webkit_web_view_get_progress (web_view) * 100; update_title (GTK_WINDOW (main_window)); } static void /*销毁信号产生时被调用*/ destroy_cb (GtkWidget* widget, gpointer data) { gtk_main_quit (); } static void /*直接调用webkit的后退函数实现*/ go_back_cb (GtkWidget* widget, gpointer data) { webkit_web_view_go_back (web_view); } static void /*直接调用webkit的前进函数实现*/ go_forward_cb (GtkWidget* widget, gpointer data) { webkit_web_view_go_forward (web_view); } 关于这里边的自定义的几个信号,是webkit自定义的信号,我们直接用就是就不说那么多了,走远了,好了,差不多这个简单的浏览器分析就完成了
本文档为【webkit自带谷歌浏览器实例分析】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_449718
暂无简介~
格式:doc
大小:328KB
软件:Word
页数:12
分类:互联网
上传时间:2011-04-18
浏览量:25