Go to WebKit-open a new tab (1)

Source: Internet
Author: User
Tags blank page

Based on safari

In webkit2

Open a new tab, first call

 

void WebProcess::createWebPage(uint64_t pageID, const WebPageCreationParameters& parameters){    // It is necessary to check for page existence here since during a window.open() (or targeted    // link) the WebPage gets created both in the synchronous handler and through the normal way.     HashMap<uint64_t, RefPtr<WebPage> >::AddResult result = m_pageMap.add(pageID, 0);    if (result.isNewEntry) {        ASSERT(!result.iterator->value);        result.iterator->value = WebPage::create(pageID, parameters);

 

 

Create webpage

 

 

PassRefPtr<WebPage> WebPage::create(uint64_t pageID, const WebPageCreationParameters& parameters){    RefPtr<WebPage> page = adoptRef(new WebPage(pageID, parameters));

 

Next, go to the webpage constructor and create pageclients, webchromeclient, webcontextmenuclient, webeditorclient, webdragclient, webbackforwardlistproxy, webinspectorclient, webpluginclient, and page object in the constructor.

 

 

WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters)    Settings::setDefaultMinDOMTimerInterval(0.004);    Page::PageClients pageClients;    pageClients.chromeClient = new WebChromeClient(this);    pageClients.contextMenuClient = new WebContextMenuClient(this);    pageClients.editorClient = new WebEditorClient(this);    pageClients.dragClient = new WebDragClient(this);    pageClients.backForwardClient = WebBackForwardListProxy::create(this);    m_inspectorClient = new WebInspectorClient(this);    pageClients.inspectorClient = m_inspectorClient;   pageClients.plugInClient = new WebPlugInClient(this);    m_page = adoptPtr(new Page(pageClients));...

 

Create a chrome object, dragcaretcontroller object, focuscontroller, contextmenucontroller,

Inspectorcontroller, settings, etc.

// WebCore

 

Page::Page(PageClients& pageClients)    : m_chrome(Chrome::create(this, pageClients.chromeClient))    , m_dragCaretController(DragCaretController::create())#if ENABLE(DRAG_SUPPORT)    , m_dragController(DragController::create(this, pageClients.dragClient))#endif    , m_focusController(FocusController::create(this))#if ENABLE(CONTEXT_MENUS)    , m_contextMenuController(ContextMenuController::create(this, pageClients.contextMenuClient))#endif#if ENABLE(INSPECTOR)    , m_inspectorController(InspectorController::create(this, pageClients.inspectorClient))#endif    , m_settings(Settings::create(this))    , m_progress(ProgressTracker::create())    , m_backForwardController(BackForwardController::create(this, pageClients.backForwardClient))

After the page object is created, webpage will create the following objects:

 

// Webkit2

 

#if ENABLE(GEOLOCATION)    WebCore::provideGeolocationTo(m_page.get(), new WebGeolocationClient(this));#endif#if ENABLE(NETWORK_INFO)    WebCore::provideNetworkInfoTo(m_page.get(), new WebNetworkInfoClient(this));#endif#if ENABLE(VIBRATION)    WebCore::provideVibrationTo(m_page.get(), new WebVibrationClient(this));#endif#if ENABLE(PROXIMITY_EVENTS)    WebCore::provideDeviceProximityTo(m_page.get(), new WebDeviceProximityClient(this));#endif    m_page->setCanStartMedia(false);    m_mayStartMediaWhenInWindow = parameters.mayStartMediaWhenInWindow;    m_pageGroup = WebProcess::shared().webPageGroup(parameters.pageGroupData);    m_page->setGroupName(m_pageGroup->identifier());    m_page->setDeviceScaleFactor(parameters.deviceScaleFactor);    m_drawingArea = DrawingArea::create(this, parameters);    m_drawingArea->setPaintingEnabled(false);    updatePreferences(parameters.store);    platformInitialize();    m_mainFrame = WebFrame::createMainFrame(this);

Here, let's take a look at webframe: createmainframe (this), create a webframe, and initialize the frame.

 

 

Passrefptr <webframe> webframe: createmainframe (webpage * Page) {refptr <webframe> frame = create (); page-> send (messages: webpageproxy :: didcreatemainframe (frame-> frameid (); frame-> Init (page, string (), 0); Return frame. release (); // This release only reduces the reference count}

The INIT process of the frame creates the frame object.

 

 

void WebFrame::init(WebPage* page, const String& frameName, HTMLFrameOwnerElement* ownerElement){    RefPtr<Frame> frame = Frame::create(page->corePage(), ownerElement, &m_frameLoaderClient);

 

Set the created frame to mainframe. For the relationships between mainframe, frame, page, and document, refer to "entering WebKit-".

// WebCore

 

PassRefPtr<Frame> Frame::create(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* client){    RefPtr<Frame> frame = adoptRef(new Frame(page, ownerElement, client));    if (!ownerElement)        page->setMainFrame(frame);    return frame.release();}

Assign values to member variables in sequence in the frame constructor.

 

 

Page * m_page;

Mutable frametree m_treenode; // used to help manage the parent and child frames. The common difference is between the main frame and IFRAME.

MutableFrameloaderM_loader; // used to load the frame

MutableNavigationschedulerM_navigationsched; // page Jump Scheduler

Htmlframeownerelement * m_ownerelement;

Refptr <frameview> m_view; // used for frame Layout

Refptr <document> m_doc; // used to manage DOM nodes

Scriptcontroller m_script; // script Controller

Mutable editor m_editor; // process page editing

Mutable frameselection m_selection; // select

Mutable eventhandler m_eventhandler; // process UI Interaction Events such as mouse events and button events

Mutable animationcontroller m_animationcontroller;

 

inline Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* frameLoaderClient)    : m_page(page)    , m_treeNode(this, parentFromOwnerElement(ownerElement))    , m_loader(this, frameLoaderClient) //    , m_navigationScheduler(this) //    , m_ownerElement(ownerElement)    , m_script(this)    , m_editor(this) //    , m_selection(this) //    , m_eventHandler(this) //    , m_animationController(this)    , m_pageZoomFactor(parentPageZoomFactor(this))    , m_textZoomFactor(parentTextZoomFactor(this))#if ENABLE(ORIENTATION_EVENTS)    , m_orientation(0)#endif    , m_inViewSourceMode(false)    , m_activeDOMObjectsAndAnimationsSuspendedCount(0){    ASSERT(page);    AtomicString::init();    HTMLNames::init();    QualifiedName::init();    MediaFeatureNames::init();    SVGNames::init();    XLinkNames::init();    MathMLNames::init();    XMLNSNames::init();    XMLNames::init();    WebKitFontFamilyNames::init();

 

Initialize member variables in the frameloader constructor.

 

FrameLoader::FrameLoader(Frame* frame, FrameLoaderClient* client)    : m_frame(frame)    , m_client(client)    , m_policyChecker(frame)    , m_history(frame)    , m_notifer(frame)    , m_subframeLoader(frame)    , m_icon(frame)    , m_mixedContentChecker(frame)    , m_state(FrameStateProvisional)    , m_loadType(FrameLoadTypeStandard)    , m_delegateIsHandlingProvisionalLoadError(false)    , m_quickRedirectComing(false)    , m_sentRedirectNotification(false)    , m_inStopAllLoaders(false)    , m_isExecutingJavaScriptFormAction(false)    , m_didCallImplicitClose(true)    , m_wasUnloadEventEmitted(false)    , m_pageDismissalEventBeingDispatched(NoDismissal)    , m_isComplete(false)    , m_needsClear(false)    , m_checkTimer(this, &FrameLoader::checkTimerFired)    , m_shouldCallCheckCompleted(false)    , m_shouldCallCheckLoadComplete(false)    , m_opener(0)#if PLATFORM(CHROMIUM)    , m_didAccessInitialDocument(false)    , m_didAccessInitialDocumentTimer(this, &FrameLoader::didAccessInitialDocumentTimerFired)#endif    , m_didPerformFirstNavigation(false)    , m_loadingFromCachedPage(false)    , m_suppressOpenerInNewFrame(false)    , m_forcedSandboxFlags(SandboxNone){}

Webframe: After init is complete, frame-> Init () will be called for initialization.

void WebFrame::init(WebPage* page, const String& frameName, HTMLFrameOwnerElement* ownerElement){    RefPtr<Frame> frame = Frame::create(page->corePage(), ownerElement, &m_frameLoaderClient);    m_coreFrame = frame.get();    frame->tree()->setName(frameName);    if (ownerElement) {        ASSERT(ownerElement->document()->frame());        ownerElement->document()->frame()->tree()->appendChild(frame);    }    frame->init();}

In fact, only one thing is done, initializing frameloader

 

 

    inline void Frame::init()    {        m_loader.init();    }

 

void FrameLoader::init(){    // This somewhat odd set of steps gives the frame an initial empty document.    setPolicyDocumentLoader(m_client->createDocumentLoader(ResourceRequest(KURL(ParsedURLString, emptyString())), SubstituteData()).get());    setProvisionalDocumentLoader(m_policyDocumentLoader.get());    m_provisionalDocumentLoader->startLoadingMainResource();    m_frame->document()->cancelParsing();    m_stateMachine.advanceTo(FrameLoaderStateMachine::DisplayingInitialEmptyDocument);    m_networkingContext = m_client->createNetworkingContext();    m_progressTracker = FrameProgressTracker::create(m_frame);}

 

 

Cachedresourceloader and documentwriter will be created during documentloader creation.

The newly created documentloader is set to m_policydocumentloader by setpolicydocumentloader, and then

Setprovisionaldocumentloader is set to m_provisionaldocumentloader

Frameloader maintains three documentloader objects for three different stages. Perform further analysis during subsequent Loading

Refptr <documentloader> m_documentloader;

Refptr <documentloader> m_provisionaldocumentloader;

Refptr <documentloader> m_policydocumentloader;

M_provisionaldocumentloader-> startloadingmainresource (); in fact, only checks whether a blank page is loaded and returns.

 

   if (maybeLoadEmpty())        return;

 

The key call stack in maybeloadempty () is as follows: maybeloadempty () calls finishedloading (), finishedloading () calls commitifready (), and completes submission in commitprovisionalload.

 

 

 

 frame #0: 0x0000000103e402e5 WebCore`WebCore::FrameLoader::transitionToCommitted(this=0x000000010c121080, cachedPage=0x00007fff5fbfc5e8)     frame #1: WebCore`WebCore::FrameLoader::commitProvisionalLoad(this=0x000000010c121080)     frame #2: WebCore`WebCore::DocumentLoader::commitIfReady(this=0x000000010b94d400)     frame #3: WebCore`WebCore::DocumentLoader::finishedLoading(this=0x000000010b94d400)    frame #4: WebCore`WebCore::DocumentLoader::maybeLoadEmpty(this=0x000000010b94d400) 

In transitiontocommittedM_provisionaldocumentloaderAssignedM_documentloader, Set m_provisionaldocumentloader to null, and set

 

M_state is set from framestateprovisional at initialization to framestatecommittedpage, and mimetype of documentwriter is set to "text/html". At this time, documentstatemachine or creatinginitialemptydocument status

M_committed = true;

 

 

    setDocumentLoader(m_provisionalDocumentLoader.get());    setProvisionalDocumentLoader(0);    setState(FrameStateCommittedPage);    m_documentLoader->writer()->setMIMEType(dl->responseMIMEType());     if (m_stateMachine.creatingInitialEmptyDocument())        return;

Returned to finishedloading ()

 

void DocumentLoader::finishedLoading(){    commitIfReady();    if (!frameLoader())        return;    if (!maybeCreateArchive()) {        // If this is an empty document, it will not have actually been created yet. Commit dummy data so that        // DocumentWriter::begin() gets called and creates the Document.        if (!m_gotFirstByte)            commitData(0, 0);        frameLoader()->client()->finishedLoading(this);    }    m_writer.end();    if (!m_mainDocumentError.isNull())        return;    clearMainResourceLoader();    if (!frameLoader()->stateMachine()->creatingInitialEmptyDocument())        frameLoader()->checkLoadComplete();}

Note that the above annotation is the initialization process. Commitdata () is called to documentwriter
: Begin (), create document and domwindow in it, Get documentparser from document, and set writerstate to startedwritingstate

 

Commitdata will be called later

frameLoader()->client()->finishedLoading(this);m_writer.end();

 

M_writer.end () will change writerstate to finishedwritingstate, and thenMaintained by documentwriterThe documentparser object is cleared,

void DocumentWriter::end(){    ASSERT(m_frame->page());    ASSERT(m_frame->document());    // The parser is guaranteed to be released after this point. begin() would    // have to be called again before we can start writing more data.    m_state = FinishedWritingState;    // http://bugs.webkit.org/show_bug.cgi?id=10854    // The frame's last ref may be removed and it can be deleted by checkCompleted(),     // so we'll add a protective refcount    RefPtr<Frame> protector(m_frame);    if (!m_parser)        return;    // FIXME: m_parser->finish() should imply m_parser->flush().    m_parser->flush(this);    if (!m_parser)        return;    m_parser->finish();    m_parser = 0;}

 

Now the documentwriter status has completed the transition:

Documentwriter () Begin, end

|

Writerstate: notstartedwritingstate-> startedwritingstate-> finishedwritingstate

 

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.