コード例 #1
0
        /// <summary>Expected to almost never occur - this performs a full DOM scan in order to
        /// find the element at the given offscreen location.</summary>
        internal Element elementFromPointOffScreen(float x, float y)
        {
            // Get the root node:
            Node node = documentElement;

            if (node == null)
            {
                // Empty document.
                return(null);
            }

            // We'll always return something - we don't need to check node's box (it must match the screen anyway).

            // Get kids ref:
            NodeList kids = node.childNodes_;

            while (kids != null)
            {
                // Loop backwards because the 'deepest' element is the one we want.
                // As soon as we find something that contains our point, we essentially stop.
                for (int i = kids.length - 1; i >= 0; i--)
                {
                    // Get the child node:
                    Node child = kids[i];

                    if (!(child is Element))
                    {
                        // Must be an element (unless it's a document).
                        // Ignore text, doctype, comment etc.
                        if (child is ReflowDocument)
                        {
                            // Step into this though!
                            child = (child as ReflowDocument).documentElement;

                            if (child == null)
                            {
                                // Not loaded yet
                                continue;
                            }
                        }
                        else
                        {
                            continue;
                        }
                    }

                    // Unlike on screen we can't rely on the fast screen region
                    // (which is only available for all on screen elements).
                    // We'll need to always test the boxes.

                    // Get the render data:
                    RenderableData renderData = (child as IRenderableNode).RenderData;
                    LayoutBox      box        = renderData.FirstBox;

                    // Must be contained in one of them.
                    bool notActuallyContained = true;

                    while (box != null)
                    {
                        if (box.Contains(x, y))
                        {
                            // Ok!
                            notActuallyContained = false;
                            break;
                        }

                        // Advance to next one:
                        box = box.NextInElement;
                    }

                    if (notActuallyContained)
                    {
                        // Not actually inside the element - continue as if nothing happened:
                        continue;
                    }

                    // The child contains our point! Step into it.
                    // - If it has no kids, or none of the kids are elements, we'll end up returning child.
                    // Note that we could trigger the event capture phase here to squeeze a tiny bit of extra performance.

                    node = child;
                    kids = child.childNodes_;
                    goto SteppedNode;
                }

                // Didn't step into anything; stop here.
                break;

SteppedNode:
                continue;
            }

            // 'Node' is our result:
            return(node as Element);
        }