Research methods:
- In the xcode project of WebKit, global search is performed with widgets as the keyword to view the related function names and comments.
- Create a project that uses uiwebview. during runtime, the image lookup class in lldb is related to the widget.
Exploration:
The following comments are provided in widget. h:
// The Widget class serves as a base class for three kinds of objects: // (1) Scrollable areas (ScrollView) // (2) Scrollbars (Scrollbar) // (3) Plugins (PluginView) // // A widget may or may not be backed by a platform-specific object (e.g., HWND on Windows, NSView on Mac, QWidget on Qt). // // Widgets are connected in a hierarchy, with the restriction that plugins and scrollbars are always leaves of the // tree. Only ScrollViews can have children (and therefore the Widget class has no concept of children). // // The rules right now for which widgets get platform-specific objects are as follows: // ScrollView - Mac // Scrollbar - Mac, Gtk // Plugin - Mac, Windows (windowed only), Qt (windowed only, widget is an HWND on windows), Gtk (windowed only)
I understand this as follows:
Widgets are encapsulation of system controls on different platforms. There are three types of widgets: Scroll areas, scroll bars, and plug-ins. These three things can be implemented differently on different platforms (or even different browsers. More intuitively, these widgets can have different appearances. For example, Chrome has different scroll bars on the Right of windows and OS X.
You can see some clues in the widget constructor:
#if PLATFORM(MAC) OBJC_CLASS NSView; OBJC_CLASS NSWindow; typedef NSView *PlatformWidget; #endif #if PLATFORM(WIN) typedef struct HWND__* HWND; typedef HWND PlatformWidget; #endif class Widget : public RefCounted<Widget> { public: explicit Widget(PlatformWidget = 0);
In lldb search, there will be:
WebCore::Widget::Widget(WAKView*) WebCore::Widget::setPlatformWidget(WAKView*)
In iOS, wakview is used instead of nsview. The inheritance relationship diagram of wakview is as follows:
Wakview is an nsobject, not a uiview. Member variable declaration of wakview:
@interface WAKView : WAKResponder { struct _WKViewContext viewContext; struct WKView *viewRef; NSMutableSet *subviewReferences; BOOL _isHidden; BOOL _drawsOwnDescendants; }
The two struct types are:
struct _WKViewContext { void *notificationCallback; void *notificationUserInfo; void *responderCallback; void *responderUserInfo; void *willRemoveSubviewCallback; void *invalidateGStateCallback; }; struct WKView { struct _WKObject _field1; struct _WKViewContext *_field2; struct WKWindow *_field3; struct WKView *_field4; struct __CFArray *_field5; struct CGPoint _field6; struct CGRect _field7; unsigned int _field8; float _field9; void *_field10; };
Wakview has 77 functions, most of which are also available in nsview, such as addsubview and setframe. For nsview, there is a uiview in iOS, but the uiview does not have as many functions and functions as the nsview.
The parent class wakresponder of wakview is similar to nsresponder. Corresponding to nsresponder, there is uiresponder in iOS, but uiresponder does not have as many functions and functions as nsresponder; wakresponder is like nsresponder that deletes functions not available in uiresponder, for example, wakresponder and nsresponder have the following functions that are identical but not available in uiresponder:
- (void)mouseDown:(id)arg1; - (void)mouseUp:(id)arg1; - (void)moveUpAndModifySelection:(id)arg1; - (void)moveUp:(id)arg1; - (void)moveRightAndModifySelection:(id)arg1; - (void)moveRight:(id)arg1; - (void)moveLeftAndModifySelection:(id)arg1; - (void)moveLeft:(id)arg1; - (void)moveDownAndModifySelection:(id)arg1; - (void)moveDown:(id)arg1;
Wkview's declaration in the webkit2 project:
WK_EXPORT @interface WKView : NSView <NSTextInputClient> { @private WKViewData *_data; unsigned _unused; }
The representation of wkview on Mac and iOS is different. One is the objective-C Class and the other is the struct.
Run uiwebview on iOS and search wkview by lldb
(lldb) image lookup -r -s WKView
We will get 44 Results, almost all of which are C functions. That is, wkview operations on IOS are all in C mode.
Search WebKit Wiki
Http://trac.webkit.org/wiki/webkit2:
Why is it named webkit2? The somewhat pedestrian reason is that it's an incompatible API change from the original WebKit, so it will probably be installed as something like/system/library/webkit2.framework on Mac. C API Webkit2 will provide a stable C-based non-blocking API that is mostly platform agnostic. in order to achieve the goal of a non-blocking API, several techniques are used to make the API usable while still Providing a comprehensive set of features to the embedder. These techniques include:
- Notification style client callbacks (e.g. didfinishloadforframe) These inform the embedder that something has happened, but do not give them the chance to do anything about it.
- Policy style clients callbacks (e.g. decidepolicyfornavigationaction) These allow the embedder to decide on an action at their leisure, policying the page through a listener object.
- Policy settings (e.g. attributes, attributes) These allow the embedder to opt into a predefined policy without any callbacks into the uiprocess. These can either be an enumerated set of specific policies, or something
More fine-grained, such as a list of strings with wildcards.
- Injected code (e.g. webbundle) code can be loaded into the webprocess for cases where all the other options fail. this can useful when access to the Dom is required. [planned, but not currently implemented]
The major API classes are: Wkcontextref
- Encapsulates all pages related to specific use of WebKit. All pages in this context share the same visited link set, local storage set, and preferences.
Wkpagenamespaceref
- Encapsulates all pages that can script each other.
Wkpageref
- Basic Unit of browsing. stays the same as the main frame changes.
Wkview [ref]
- Native view that hooks into the platform's toolkit. On Windows, this wraps a hwnd. on the Mac, it inherits from nsview.
Note that the requirement to be fully non-blocking requires an incompatible API break-aware features of most existing WebKit APIs cannot be fulfilled in a non-blocking manner. since we needed the API break anyway, we also took advantage of Opportunity to clean up and simplify the API. |
Based on the above information, we can conclude that:
1. The widget encapsulates the platform control. You can obtain the information (mainly the size) of the platform control through the widget and transmit the user event information (such as mousedown) to the widget.
2. IOS's uiwebview adopts a dual-thread architecture, which imitates Mac safari's dual-process architecture and makes many adaptations. wakview is a substitute for Imitating nsview on IOS, this allows some code to be reused on Mac and IOS. Wak should be the abbreviation of web app kit, because it corresponds to the uikit of uiview on iOS, and is the appkit of nsview on Mac. This layer is the intermediate layer for inter-thread communication, and mainly serves to store status information and transfer messages.
In addition, the following information is available in debugging practices:
1. when plugin is implemented by a system control and does not allow it to receive or process events on its own, for example, disabling the video control panel mpmovieplayercontroller. controlstyle = mpmoviecontrolstylenone: The mouse/key event is passed directly to the htmlelement to which the plugin belongs.
2. In drag and drop, plugin has special behaviors. For example, videos may support dragging. Of course, IOS does not.
3. WebCore can manage widgets in a unified manner, such as attach and dettach. widgets also have tree structures.
4. The processing logic in eventhandler. When it is found that the event is clicked on the widget, the event can be passed separately without clicking. For the widget focus, the widget may have special behaviors, such as entering the Mode
// Many AppKit widgets run their own event loops and consume events while the mouse is down. // When they finish, currentEvent is the mouseUp that they exited on. We need to update // the EventHandler state with this mouseUp, which we never saw. // If this event isn't a mouseUp, we assume that the mouseUp will be coming later. There // is a hole here if the widget consumes both the mouseUp and subsequent events.
The long-pressed menu is an example. When a synchronous message is initiated by webthread, websheet is displayed as a mode and an eventloop is created.
5. widgets have special logic on Mac, which may be different from those on IOS. The following is an example.
/* A hack for the benefit of AK's PopUpButton, which uses the Carbon menu manager, which thus eats all subsequent events after it is starts its modal tracking loop. After the interaction is done, this routine is used to fix things up. When a mouse down started us tracking in the widget, we post a fake mouse up to balance the mouse down we started with. When a key down started us tracking in the widget, we post a fake key up to balance things out. In addition, we post a fake mouseMoved to get the cursor in sync with whatever we happen to be over after the tracking is done. */ void EventHandler::sendFakeEventsAfterWidgetTracking(NSEvent *initiatingEvent)
6. The plugin_proxy_for_video macro of htmlmediaelement enables media to be opened by plugin as a widget. These labels also create widgets: htmlobjectelement, htmlembedelement, and htmlappletelement.