Gitweb links:
...log
http://git.netsurf-browser.org/netsurf.git/shortlog/fe95004d2a44100c2650694a37e2243d14323eb4
...commit
http://git.netsurf-browser.org/netsurf.git/commit/fe95004d2a44100c2650694a37e2243d14323eb4
...tree
http://git.netsurf-browser.org/netsurf.git/tree/fe95004d2a44100c2650694a37e2243d14323eb4
The branch, jmb/bm has been created
at fe95004d2a44100c2650694a37e2243d14323eb4 (commit)
- Log -----------------------------------------------------------------
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=fe95004d2a44100c2650694a37e2243d14323eb4
commit fe95004d2a44100c2650694a37e2243d14323eb4
Author: John-Mark Bell <[email protected]>
Commit: John-Mark Bell <[email protected]>
Docs: add some
diff --git a/docs/ideas/boxes.txt b/docs/ideas/boxes.txt
new file mode 100644
index 000000000..f1fa2360a
--- /dev/null
+++ b/docs/ideas/boxes.txt
@@ -0,0 +1,493 @@
+Box tree dynamism
+=================
+
+The first building block needed for event-driven layout is for the box tree
+construction and subsequent maintenance to become event driven and for the
+box tree management implementation to emit events marking parts of the tree
+changed so that the layout calculator can react to them.
+
+We expect the box tree to be in normal form at all times (and certainly
+whenever an event is emitted). The box tree manager must ensure that this is
+the case.
+
+[Note: the box tree manager could be plumbed into the existing content handler
+with a little effort: have the box tree constructed dynamically during the
+parse, but ignore box tree events and perform layout computation at the same
+place as currently. As box tree events are ignored, subsequent changes to the
+tree will not result in updated layout computations -- this might produce weird
+effects, so an option might be to forcibly relayout the entire tree on receipt
+of box tree change events received after the initial layout has been performed.
+This would not be substantially different from the existing reformatting on
+viewport dimension changes, and similarly heavyweight]
+
+The box tree manager needs to know when any of the various inputs that
+determine the shape of the box tree changes. These inputs comprise:
+
+ 1. Style changes
+ 2. DOM changes
+ 3. Dynamic pseudo classes
+ 4. Other non-DOM changes (predominantly Media Queries)
+
+The following sections consider the each of these inputs and attempts to scope
+out the impact of changes made to them.
+
+
+Style changes
+-------------
+
+Style information can change as the source document is parsed and as external
+stylesheets are fetched. Script may also modify style information via the CSS
+Object Model or simply injecting its own style attribute values into Elements.
+Changes to any of this information has the potential to cause wide-ranging
+ripples across the box tree structure.
+
+
+DOM changes
+-----------
+
+Given CSS 3 selectors and combinators, the impact of DOM changes is thus:
+
+ 1. Adding a new Element node:
+ Selection must be re-run for all children of the new node's parent
+ and their descendants (i.e. all trees derived from the new node and
+ its siblings).
+ [XXX: is this correct?] If it is known that neither the
:nth-last-child()/:nth-last-of-type()
+ pseudo-classes nor the sibling combinators are in use, the selection
+ re-run can be limited to the preceding siblings and the new node (and
+ their descendants).
+ 2. Removing a new Element node:
+ Selection must be re-run for all children of the node's former parent
+ and their descendants (i.e. all trees derived from the node's siblings)
+ 3. Moving an Element node:
+ This is effectively a removal (see: 2) followed by an addition (see: 1)
+ There is an optimisation to be had if the node is attached to one of
+ its ancestors: in that case, selection need not be re-run on removal
+ (as all of the affected nodes will be in a subtree of the node's
+ siblings on re-insertion).
+ 4. Addition/Removal/Modification of an Element node's Attributes:
+ Selection must be re-run for all children of the Element node's parent
+ and their descendants (i.e. all trees derived from the node and its
+ siblings).
+
+
+Dynamic pseudo classes
+----------------------
+
+These require dynamic re-selection based on user activity. The most
+aggressive of which is :hover (as, in theory, causes changes whenever the
+user moves the mouse). So this probably requires the presence of some
+debouncing logic to avoid excessive reselection every time the mouse
+pointer moves 1px in any direction.
+
+The set of affected nodes is as for node addition (where the directly
+affected node serves as the added node).
+
+
+Other Non-DOM changes
+---------------------
+
+Media queries will require re-selection to happen whenever any of the
+queries properties (e.g. viewport dimension) changes. The impact in this
+case, however, is completely unconstrained -- potentially the entire document
+tree may require reselection.
+
+
+
+Change detection
+----------------
+
+In general we want, wherever possible, to minimise the amount of work performed
+to make the box tree reflect reality. This will be achieved through aggressive
+filtering out of unnecessary work and reuse of existing results where possible.
+
+The following sections consider change detection for each of the information
+sources.
+
+
+Detecting selection context changes
+-----------------------------------
+
+Style selection for a node is performed using a selection context
+(simplistically: an ordered list of stylesheets). If a suitable hashing
+scheme can be devised such that we can detect:
+
+ a. changes to the contents of a stylesheet (e.g. as a result of rules
+ or properties being added/removed/changed via the CSS Object Model)
+ b. addition/removal/reordering of stylesheets within a selection context
+
+and we record the aggregation of this information as a single hash value
+within the selection context and also record this hash value alongside the
+computed style for a node, then it becomes trivial to compare the recorded
+value with the live value within the selection context to determine if there
+is any need to do any work.
+
+If work is necessary, and assuming no ability to determine the differences
+between the prior and current set of input styles, a change to the selection
+context effectively invalidates the computed styles for the entire tree. This
+may require further optimisation, however.
+
+
+Detecting DOM changes
+---------------------
+
+Changes to a given Element node that might affect style selection rules are:
+
+ 1. The Element's QName
+ 2. The Attributes associated with the Element
+
+Assuming a suitable hashing scheme for this information exists, then we can
+compute a hash for the Element whenever any of these items change. This
+"Node Hash" value is stored on the Element itself.
+
+As described above, the position of a node within the DOM also affects the set
+of selection rules that apply to it. Specifically, there are two sets of
+relevant information:
+
+ a. the chain of ancestor nodes up to the document root (and details of any
+ attributes attached to them)
+ b. the ordered set of children of a node's parent (and details of any
+ attributes attached to them) -- i.e. the node and its siblings
+
+If a suitable hashing scheme for an ordered list of Node Hashes (the
+"Positional Node Hash") can be devised then, on insertion of a node into the
+DOM we can compute:
+
+ 1. The hash of the parent node's children, including the inserted node
+ (the "Children Hash")
+ 2. The parent node's (if any -- we may be the document root Element)
+ ancestor chain hash plus the hash of the inserted node (the "Ancestor
+ Chain Hash")
+ 3. Recursively, the Ancestor Chain Hash of the inserted node's descendants
+ (taking the inserted node as the initial parent and applying (2) to the
+ children, and updating the parent as we recurse down the tree).
+
+The Children Hash is stored on the inserted node's parent.
+The Ancestor Chain Hash is stored on the inserted node itself.
+
+Note that the positional hashing scheme MUST take the Element order into
+account.
+
+On removal of a node from the DOM we must compute:
+
+ 1. The (former) parent node's Children Hash, excluding the removed
+ node.
+ 2. An invalidation of the stored Ancestor Chain Hash values on the subtree
+ rooted at the removed node (the Children Hashes are unaffected until
+ nodes within the subtree are moved or altered)
+
+As for insertion, the Children Hash is stored on the former parent of the
+removed node.
+
+If, at the point of selection, we record alongside the computed style for the
+target element:
+
+ a. the target Element's Node Hash
+ b. the target Element's Ancestor Chain Hash
+ c. the target Element's parent node's Children Hash
+
+then, when asked to reselect style information for the target node we can
+compare the recorded values with those found on the live DOM tree to determine
+if anything has changed. [Implementation Note: we can save storage space by
+combining the three separate hash values here into a single value by treating
+them as a list of Node Hashes and feeding them to the Positional Node Hash
+function].
+
+
+Detecting changes to pseudo classes
+-----------------------------------
+
+Changes to structural pseudo classes should fall out of the generic DOM change
+detection described above: the DOM tree will have to change for these to do so.
+
+Dynamic pseudo classes, however, are a right pain, particularly in the case
+where you have rules containing selectors that include combinators in
+conjunction with pseudo classes. In these cases, the pseudo class might become
+engaged on any other element in the tree (be that ancestral or siblings, or
+both) surrounding the target element. Thus, there's no trivial way to
+pre-compute an answer and test against it efficiently.
+
+Consider something like this:
+
+div:first-child + :hover wibble :last-child > foo { ... }
+
+This will match a "foo" element whose parent is the last child of "foo"'s
+grandparent and "foo"'s parent has an ancestor element, "wibble" and "wibble"
+has an ancestor element that the user is hovering over and that ancestor
+element is immediately preceded by a "div" that is the first child of their
+parent. If the user isn't hovering over the intermediate ancestor, this rule
+will not match, regardless of the shape of the document tree.
+
+To make matters even more involved, the user may be considered to be hovering
+over the intermediate ancestor as a result of hovering over some other
+descendant of that ancestor. Also, because any ancestor of "wibble" with a
+preceding first child "div" will do, the identity of that ancestor could
+equally well change but the rule still match.
+
+Perhaps, therefore, it becomes necessary to gather the set of nodes for which
+each dynamic pseudo class is active and record this on the document element.
+Then, for each subsequent selection, gather the set of nodes to which these
+pseudo classes apply at that time. This gives two sets:
+
+ a. The previous set of nodes for which each dynamic pseudo class was active
+ b. The current set of nodes for which each dynamic pseudo class is active
+
+The disjunctive union of these two sets produces a set of nodes for which the
+active state of each dynamic pseudo class has changed between selections. Any
+descendant of any node in this set, or of any sibling of any node in this set,
+will require reselection.
+
+The current set of nodes for which each dynamic pseudo class is active will be
+recorded on the document element each time. [Note: it may be possible to
+minimise the set sizes by taking account of the rules involving the relevant
+pseudo class -- in the extreme case, no rules use the relevant pseudo class and
+so the set will always be empty].
+
+
+Detecting other non-DOM changes
+-------------------------------
+
+Media Queries Level 4 permits testing against a variety of mostly-static
+properties of the rendering device. Some properties may change dynamically
+(e.g. viewport width/height when the window is resized). Assuming that all
+property values are always provided and they do not change regularly, the
+simple approach would be to hash the information provided (i.e. property
+names and values) and store the hash alongside computed styles. If the
+hash value changes, then reselection must occur.
+
+If the hash value changes, a more granular additional test would be to apply
+the input properties to all known media queries and cache the results, thus
+ensuring that range-based properties continue to match until they don't even
+if there are slight changes to their declared values. The assumption is that
+this matching will be performant (if it is not, more intelligence is likely
+required).
+
+
+Construction nuances
+--------------------
+
+Avoiding repetitious selection during document construction (assuming no
+scripting causing DOM changes) would be desireable. Given the rules above,
+performing selection for the Element node children of a node is best done
+after the last child of the parent has been added to the document (i.e. when
+the parser encounters the parent Element's closing tag in well-formed
+document source).
+
+This may, however, be difficult to detect reliably from the DOM event stream
+(where only node insertion/removal events are emitted). In a well-formed
+document, we know that a node's subtree is complete once either:
+
+ a) a subsequent sibling is inserted into the node's parent; or
+ b) a subsequent relation is inserted into one of the node's ancestors
+
+In the case of the document root node, the completion of the parse is the
+relevant point (as, until then, children may be changing).
+
+Where the source document is not well-formed (i.e. the likes of the HTML5
+adoption agency are in play), it is possible for nodes to be moved around
+the tree or inserted in unlikely locations in the first place. Where this
+happens, it will be difficult to avoid repetitious selection in a reliable
+manner.
+
+In either case, if repetitious selection is avoided at all, the box tree
+will not be complete until the entire document parse has ended (and the
+event-based box tree builder must take great care to ensure the tree is
+in normal form at all times).
+
+Assuming a well-formed input, all stylesheet references and inline styles
+should be known when the Body Element is inserted into the document. There
+is no point attempting to build any part of the box tree until all the style
+information is available, so waiting until all of the external stylesheets
+have been fetched is probably sensible (perhaps with some timeout to avoid
+waiting forever -- if style information arrives late, then too bad, you get
+to enjoy a load of repetitious selection).
+
+
+Migration considerations
+------------------------
+
+The existing box tree structure conflates a variety of things. Specifically,
+the box tree is not "just" a structure containing nodes to be laid out but it
+also contains large swathes of information that is already stored in the DOM,
+and also pieces of information that have no bearing on how the document is
+laid out or displayed (e.g. form gadgets, which really belong on the DOM, and
+object parameters).
+
+Additionally, there are special-case box types for floated boxes (even using
+different types to distinguish between left and right floated boxes),
+linebreaks, and flex-layout boxes. There are also custom INLINE_CONTAINER
+boxes (which serve as a transparent container for INLINE boxes when the
+containing block only contains INLINE children, but act as a BLOCK box when
+the containing block has both BLOCK and INLINE children). There's also the
+magical INLINE_END box type which represents the far end of a fragmented
+INLINE box.
+
+Retaining the myriad box types (including the special cases) is possible, but
+care will need to be taken to ensure that the box tree remains in normal form
+as and when the type of a box changes (i.e. because the display or float
+property values change).
+
+Boxes also contain various pieces of information created by the layout
+calculator and stashed away for future use. Some generic mechanism to permit
+the layout calculator to associate state with a box is is probably needed
+(with such information being invalidated whenever the relevant section of the
+tree changes).
+
+There is some magic handling of trailing space characters in text elements
+(simplistically: they're flagged on the preceding text box). This was probably
+an optimisation at the time (as the box structure is relatively large), but
+makes many things more complex. This optimisation should be removed entirely
+and, instead, the boxes should reference the underlying text data attached to
+the source DOM nodes (Note: some consideration needs to be given to whitespace
+squashing here, to ensure that continues to happen in a sensible way,
+preferably without duplicating the entire textual contents of the DOM into the
+box tree).
+
+Ideally, then, the box tree contents will be reduced to solely the information
+needed to lay the document out and render it. Where possible, anything that is
+already stored on the DOM should not be duplicated (as it is easy to obtain the
+corresponding DOM node from the box and then query that).
+
+It would be nice to retire talloc, too, as object lifetimes are now
+well-defined.
+
+
+Outwith the HTML content handler, there are several parts of the code that
+expect to be able to access box objects and their contents:
+
+ 1. iframe handling
+
+ This involves unpleasant collusion between the HTML content handler and
+ the desktop UI. This layering violation should be cleaned up by
+ introducing a proper orthogonal interface (if needed, or something else,
+ if not). The public "html_redraw_a_box" API should die with it.
+
+ 2. save as text
+
+ This is a similar layering violation -- the code is simply in the wrong
+ place. It should be moved down into the HTML content handler and the
+ higher level code should simply dispatch the operation through the content
+ system.
+
+There are also the following things that grub around inside the DOM to fish
+out the box pointer:
+
+ 1. The JavaScript Canvas binding
+
+ This is done so it can then call html__redraw_a_box, which is an API
+ private to the HTML content implementation. Bad Daniel, no biscuit.
+
+ The fix here is probably to have the binding fire a "redraw needed" event
+ at the canvas dom_node (which it already knows) and for that to be caught
+ and handled by the HTML content handler itself.
+
+Additionally there are a few places that leak box pointers through APIs:
+
+ 1. The content_html_object struct contains the box pointer
+
+ This is used by:
+
+ a. save complete
+
+ This simply checks that the pointer is non-NULL to determine whether
+ to save the corresponding content for the object. Like save as text
+ (described above), this arises as a result of a layering violation.
+ The implementation should be pushed down into the HTML content
+ handler and the higher level code should simply dispatch the
+ operation through the content system. (This would also permit
+ retirement of the similarly anachronistic html_get_document API).
+
+ b. reload
+
+ This cares not about the box pointer, but does process the objects to
+ invalidate their caching status. Again, a layering violation: push
+ the implementation down and invoke it via the content system.
+
+ 2. The textsearch_bounds content interface accepts box pointers (as does
+ content_textsearch_add_match)
+
+ While this is internal to the content infrastructure it would be better
+ all round for the exposure of box pointers here to go away and be replaced
+ with something more orthogonal.
+
+There are also places where box pointers might once have been used and no
+longer are, but where vestiges remain:
+
+ 1. The core text selection object contains a pointless box pointer field
+ (it is initialised to NULL and never used)
+ 2. The Windows frontend's browser_mouse object contains a pointless box
+ pointer field (it is never used).
+
+ These should just be cleaned up.
+
+
+Layout calculation
+------------------
+
+The layout calculators will be notified about changes to the box tree. Change
+events will report the containing block-boxes in which the alterations were
+made. This is analogous to the DOM's SubtreeModified event which is targetted
+at the parent Element containing the modified subtree. (TBD whether one event
+per containing block or one fat event, or some combination of the two -- in the
+situation where positioned and/or floated boxes are involved, changes to the
+in-flow box tree structure may result in *multiple* parent containing blocks
+being affected).
+
+The layout calculators will operate on the box tree to lay it out for a given
+viewport width (where possible, only needing to reflow the altered containing
+block contents, thus performing the minimal amount of work). The resulting
+layout information should be cached on each box tree element (potentially with
+some magic for inlines, as they get (de)fragmented depending upon available
+space).
+
+Once the position and dimensions of all boxes have been determined, the entire
+document should be rendered *unclipped* to produce the intermediate structure
+used for redraw. We expect this step to produce a stack of device-independent
+render operations (one stack level per layer).
+
+"Pictorally":
+
+ [canvas] -> [command, ...]
+ [ 1] -> [command, ...]
+ [ 2] -> [command, ...]
+ [ 3] -> [command, ...]
+ [ 4] -> [command, ...]
+
+where the document is then drawn layer-by-layer (canonically: starting at the
+canvas and moving down the stack, overdrawing each layer on top of what has
+been drawn before). [Note: the layers in this structure may not directly
+reflect the z-indexes specified in the source stylesheets in part as a result
+of the magical handling of elements which can create new stack levels -- see
+Appendix E of CSS2.1 for the gory details].
+
+With the exception of text plotting commands, the render operations are
+entirely independent of the originating document and box tree. Text commands
+will necessarily reference the source text data by holding references to the
+relevant DOM string data, and whatever metadata is needed to index into it.
+(As this data is referenced, if the DOM changes, the old text will continue
+to be rendered safely until the redraw stack is updated).
+
+To ensure that the document may be redrawn at any time, regardless of the
+underlying state of the DOM, box tree, or layout calculation, and to ensure
+that redraw output is consistent the redraw stack must be updated atomically
+(simplistically: build a new one, flip the old and new pointers, and destroy
+the old one; more optimised solutions are likely available).
+
+[Note: we omit the precise detail about how the layout calculation is perfomed
+as this is left for future work. The overall event flow and decoupling of
+layout from rendering is, however, important to record].
+
+
+Redraw
+------
+
+Redraw operates solely using the render stack. This is the point that clipping
+is applied (e.g. to skip over any commands that would render outside the clip
+boundary). Additionally, if output scaling is desired, it can be applied at
+this point, too (i.e. by transforming the device-independent render operations
+into device-dependent ones -- just apply a transformation matrix, right?).
+
+Multiple buffering, if desired, is left up to the plotter implementation
+provided by the client (as different frontends may wish to do things
+differently).
+
+[Note: again, the precise detail is omitted here].
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=4edb140c98c8f8918f43c2b670d1a89badf92277
commit 4edb140c98c8f8918f43c2b670d1a89badf92277
Author: John-Mark Bell <[email protected]>
Commit: John-Mark Bell <[email protected]>
HTML: skeletal box tree manager
diff --git a/content/handlers/html/Makefile b/content/handlers/html/Makefile
index e41cc1d22..4662c0571 100644
--- a/content/handlers/html/Makefile
+++ b/content/handlers/html/Makefile
@@ -1,6 +1,7 @@
# HTML content handler sources
-S_HTML := box_construct.c \
+S_HTML := box/manager.c \
+ box_construct.c \
box_inspect.c \
box_manipulate.c \
box_normalise.c \
diff --git a/content/handlers/html/box/manager.c
b/content/handlers/html/box/manager.c
new file mode 100644
index 000000000..9fe5269d6
--- /dev/null
+++ b/content/handlers/html/box/manager.c
@@ -0,0 +1,175 @@
+#include <stdlib.h>
+
+#include "desktop/gui_internal.h"
+#include "html/box/manager.h"
+#include "netsurf/misc.h"
+#include "utils/corestrings.h"
+
+struct box_manager
+{
+ dom_document *doc;
+ dom_event_listener *listener;
+
+ /* Whether we have been told that stylesheets are available */
+ bool have_styles;
+ /* Whether there is an outstanding callback pending */
+ bool callback_pending;
+
+ dom_node **pending_queue;
+ size_t pending_queue_idx;
+ size_t pending_queue_slots;
+};
+
+static void
+box_manager_process_events(void *pw)
+{
+ box_manager *mgr = pw;
+
+ mgr->callback_pending = false;
+
+ //XXX: implement
+
+ /* Just release references for now */
+ while (mgr->pending_queue_idx > 0) {
+ mgr->pending_queue_idx--;
+ dom_node_unref(mgr->pending_queue[mgr->pending_queue_idx]);
+ }
+
+ // 1. Eliminate nodes which are no longer in our document, or in a
detached tree (we expect to have received a corresponding event for their
parent)
+ // 2. Eliminate duplicate nodes from the list
+ // 3. Eliminate nodes which are descendants of other nodes in the list
+ // 4. For every remaining node: (re)build the structural box tree
segment rooted at each of node's children
+ // 5. For each modified box tree segment:
+ // a. find the immediate containing block(s) for the segment
+ // (there may be more than one if posititioned/out-of-flow
elements are in play)
+ // b. emit (a) "box tree modified" event(s) referencing the
containing block(s)
+ //
+ // The box tree must always be in normal form so it may be necessary to
insert (or remove?) elements between the segment root and its parent box
+ // Layout calculators will receive the "box tree modified" events and
deal with them
+
+ // XXX: need an API for stylesheet change notifications
+ // On receipt, mark entire tree invalid (synthesise a subtree modified
event? -- not fired at DOM, for obvious reasons, but could be thrown at our
event handler)
+}
+
+static void
+box_manager_capture_event(box_manager *mgr, dom_event *evt)
+{
+ dom_exception exc;
+ dom_event_target *target = NULL;
+
+ if (mgr->pending_queue_idx == mgr->pending_queue_slots) {
+ dom_node **tmp;
+ if (mgr->pending_queue == NULL) {
+ tmp = malloc(sizeof(*tmp) * 32);
+ } else {
+ tmp = realloc(mgr->pending_queue,
+ sizeof(*tmp) * (mgr->pending_queue_slots + 32));
+ }
+ if (tmp == NULL) {
+ /* ENOMEM, but no way to deal with it? */
+ return;
+ }
+
+ mgr->pending_queue = tmp;
+ mgr->pending_queue_slots += 32;
+ }
+
+ exc = dom_event_get_target(evt, &target);
+ if (exc != DOM_NO_ERR || target == NULL) {
+ /* DOM error, but no way to deal with it? */
+ return;
+ }
+
+ mgr->pending_queue[mgr->pending_queue_idx++] = (dom_node *) target;
+}
+
+static void
+box_manager_handle_dom_event(dom_event *evt, void *pw)
+{
+ box_manager *mgr = pw;
+
+ /* 0. During DOM construction, ignore events until we have all
+ * known stylesheets */
+ if (mgr->have_styles == false) {
+ return;
+ }
+
+ /* 1. Ignore non subtree modified events; ignore events for non-Element
+ * targets (these should be a no-op, by construction) */
+
+ /* 2. Capture event target (ensuring we keep a ref) into list of
+ * pending events */
+ box_manager_capture_event(mgr, evt);
+
+ /* 3. Schedule a callback to process the list (if no callback already
+ * scheduled) */
+ if (mgr->callback_pending == false) {
+ // XXX: 20ms ~= 50Hz -- enough?
+ guit->misc->schedule(20, box_manager_process_events, mgr);
+ mgr->callback_pending = true;
+ }
+}
+
+nserror
+box_manager_create(dom_document *doc, box_manager **manager)
+{
+ box_manager *mgr;
+ dom_exception exc;
+
+ mgr = malloc(sizeof(*mgr));
+ if (mgr == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ exc = dom_event_listener_create(box_manager_handle_dom_event, mgr,
+ &mgr->listener);
+ if (exc != DOM_NO_ERR) {
+ free(mgr);
+ return NSERROR_DOM;
+ }
+
+ //XXX: do we need to care about other mutation events?
+ //XXX: or need to do this via the default handlers?
+ exc = dom_event_target_add_event_listener(doc,
+ corestring_dom_DOMSubtreeModified,
+ mgr->listener,
+ true);
+ if (exc != DOM_NO_ERR) {
+ dom_event_listener_unref(mgr->listener);
+ free(mgr);
+ return NSERROR_DOM;
+ }
+
+ mgr->doc = (dom_document *) dom_node_ref(doc);
+ mgr->have_styles = false;
+ mgr->callback_pending = false;
+ mgr->pending_queue = NULL;
+ mgr->pending_queue_idx = mgr->pending_queue_slots = 0;
+
+ *manager = mgr;
+
+ return NSERROR_OK;
+}
+
+nserror
+box_manager_destroy(box_manager *manager)
+{
+ if (manager->callback_pending) {
+ guit->misc->schedule(-1, box_manager_process_events, manager);
+ }
+ while (manager->pending_queue_idx > 0) {
+ manager->pending_queue_idx--;
+ dom_node_unref(
+ manager->pending_queue[manager->pending_queue_idx]);
+ }
+ free(manager->pending_queue);
+ (void) dom_event_target_remove_event_listener(manager->doc,
+ corestring_dom_DOMSubtreeModified,
+ manager->listener,
+ true);
+ dom_event_listener_unref(manager->listener);
+ dom_node_unref(manager->doc);
+ free(manager);
+
+ return NSERROR_OK;
+}
diff --git a/content/handlers/html/box/manager.h
b/content/handlers/html/box/manager.h
new file mode 100644
index 000000000..7a98d2182
--- /dev/null
+++ b/content/handlers/html/box/manager.h
@@ -0,0 +1,21 @@
+#ifndef BOX_H_
+#define BOX_H_
+
+#include <dom/dom.h>
+
+#include "utils/errors.h"
+
+typedef struct box_manager box_manager;
+
+//XXX: presumably, this will be a library, so can't use NS types
+nserror box_manager_create(dom_document *doc, box_manager **manager);
+
+nserror box_manager_destroy(box_manager *manager);
+
+//XXX: sane? or should the box manager register its own handlers directly?
+//XXX: if registering, then will only reliably receive events in the CAPTURE
phase
+//XXX: if not (i.e. using the default handler), will reliably get
START/FINISHED
+//void box_manager_handle_dom_event(box_manager *manager,
+// const dom_event *event);
+
+#endif
diff --git a/content/handlers/html/css.c b/content/handlers/html/css.c
index 0bc38844f..ccc78548f 100644
--- a/content/handlers/html/css.c
+++ b/content/handlers/html/css.c
@@ -115,6 +115,7 @@ html_convert_css_callback(hlcache_handle *css,
nsurl_access(hlcache_handle_get_url(css)));
parent->base.active--;
NSLOG(netsurf, INFO, "%d fetches active", parent->base.active);
+ //XXX: tell box tree manager styles have changed?
break;
case CONTENT_MSG_ERROR:
diff --git a/content/handlers/html/html.c b/content/handlers/html/html.c
index 82f5f1388..e53b94af9 100644
--- a/content/handlers/html/html.c
+++ b/content/handlers/html/html.c
@@ -64,6 +64,7 @@
#include "html/object.h"
#include "html/html_save.h"
#include "html/interaction.h"
+#include "html/box/manager.h"
#include "html/box.h"
#include "html/box_construct.h"
#include "html/box_inspect.h"
@@ -473,6 +474,7 @@ html_create_html_data(html_content *c, const http_parameter
*params)
c->refresh = false;
c->reflowing = false;
c->title = NULL;
+ c->box_manager = NULL;
c->bctx = NULL;
c->layout = NULL;
c->background_colour = NS_TRANSPARENT;
@@ -569,11 +571,29 @@ html_create_html_data(html_content *c, const
http_parameter *params)
return libdom_hubbub_error_to_nserror(error);
}
+ nerror = box_manager_create(c->document, &c->box_manager);
+ if (nerror != NSERROR_OK) {
+ dom_hubbub_parser_destroy(c->parser);
+ c->parser = NULL;
+ nsurl_unref(c->base_url);
+ c->base_url = NULL;
+
+ lwc_string_unref(c->universal);
+ c->universal = NULL;
+ lwc_string_unref(c->media.prefers_color_scheme);
+ c->media.prefers_color_scheme = NULL;
+
+ return nerror;
+ }
+
err = dom_node_set_user_data(c->document,
corestring_dom___ns_key_html_content_data,
c, html_document_user_data_handler,
(void *) &old_node_data);
if (err != DOM_NO_ERR) {
+ (void) box_manager_destroy(c->box_manager);
+ c->box_manager = NULL;
+
dom_hubbub_parser_destroy(c->parser);
c->parser = NULL;
nsurl_unref(c->base_url);
@@ -656,6 +676,7 @@ html_process_encoding_change(struct content *c,
const char *encoding;
const uint8_t *source_data;
size_t source_size;
+ nserror nerror;
/* Retrieve new encoding */
encoding = dom_hubbub_parser_get_encoding(html->parser,
@@ -677,10 +698,12 @@ html_process_encoding_change(struct content *c,
/* Destroy binding */
dom_hubbub_parser_destroy(html->parser);
html->parser = NULL;
-
if (html->document != NULL) {
dom_node_unref(html->document);
}
+ if (html->box_manager != NULL) {
+ box_manager_destroy(html->box_manager);
+ }
parse_params.enc = html->encoding;
parse_params.fix_enc = true;
@@ -714,6 +737,11 @@ html_process_encoding_change(struct content *c,
}
+ nerror = box_manager_create(html->document, &html->box_manager);
+ if (nerror != NSERROR_OK) {
+ return nerror;
+ }
+
source_data = content__get_source_data(c, &source_size);
/* Reprocess all the data. This is safe because
@@ -1248,6 +1276,11 @@ static void html_destroy(struct content *c)
html->document = NULL;
}
+ if (html->box_manager != NULL) {
+ box_manager_destroy(html->box_manager);
+ html->box_manager = NULL;
+ }
+
if (html->title != NULL) {
dom_node_unref(html->title);
html->title = NULL;
diff --git a/content/handlers/html/private.h b/content/handlers/html/private.h
index 56cd957d5..d31b0a885 100644
--- a/content/handlers/html/private.h
+++ b/content/handlers/html/private.h
@@ -31,6 +31,7 @@
#include "content/handlers/css/utils.h"
+struct box_manager;
struct gui_layout_table;
struct scrollbar_msg_data;
struct content_redraw_data;
@@ -130,6 +131,9 @@ typedef struct html_content {
/* Title element node */
dom_node *title;
+ /** Box tree manager */
+ struct box_manager *box_manager;
+
/** A talloc context purely for the render box tree */
int *bctx;
/** A context pointer for the box conversion, NULL if no conversion
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=0b28c94f4f8d14c09fcd5396698c791c506286ad
commit 0b28c94f4f8d14c09fcd5396698c791c506286ad
Author: John-Mark Bell <[email protected]>
Commit: John-Mark Bell <[email protected]>
Clean up redundant includes
diff --git a/desktop/print.c b/desktop/print.c
index e90e322ac..118e2e0b6 100644
--- a/desktop/print.c
+++ b/desktop/print.c
@@ -34,7 +34,6 @@
#include "netsurf/plotters.h"
#include "content/hlcache.h"
#include "css/utils.h"
-#include "html/box.h"
#include "desktop/print.h"
#include "desktop/printer.h"
diff --git a/desktop/save_complete.c b/desktop/save_complete.c
index e4fadd274..62c8bf5c6 100644
--- a/desktop/save_complete.c
+++ b/desktop/save_complete.c
@@ -43,7 +43,6 @@
#include "netsurf/content.h"
#include "content/hlcache.h"
#include "css/css.h"
-#include "html/box.h"
#include "html/html_save.h"
#include "html/html.h"
diff --git a/frontends/amiga/dt_sound.c b/frontends/amiga/dt_sound.c
index 16b4f7c62..11d5e79d5 100644
--- a/frontends/amiga/dt_sound.c
+++ b/frontends/amiga/dt_sound.c
@@ -35,7 +35,6 @@
#include "utils/messages.h"
#include "netsurf/plotters.h"
#include "netsurf/content.h"
-#include "html/box.h"
#include "content/llcache.h"
#include "content/content_protected.h"
#include "content/content_factory.h"
-----------------------------------------------------------------------
--
NetSurf Browser
_______________________________________________
netsurf-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]