void RenderFlowThread::regionLayoutUpdateEventTimerFired(Timer<RenderFlowThread>*)
{
    // Create a copy of region nodes, to protect them for being destroyed in the event listener
    Vector<RefPtr<Node> > regionNodes;
    regionNodes.reserveCapacity(m_regionList.size());
    for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
        RenderRegion* region = *iter;
        ASSERT(region->node() && region->node()->isElementNode());
        // dispatch the event only for marked regions and only for those who have a listener
        if (region->shouldDispatchRegionLayoutUpdateEvent()) {
            regionNodes.append(region->node());
            // clear the dispatch flag here, as it is possible to be set again due to event listeners
            region->setDispatchRegionLayoutUpdateEvent(false);
        }
    }
    for (Vector<RefPtr<Node> >::const_iterator it = regionNodes.begin(); it != regionNodes.end(); ++it) {
        RefPtr<Node> node = *it;
        RefPtr<Document> document = node->document();
        if (!document)
            continue;
        RenderObject* renderer = node->renderer();
        if (renderer && renderer->isRenderRegion()) {
            node->dispatchRegionLayoutUpdateEvent();
            // Layout needs to be uptodate after each event listener
            document->updateLayoutIgnorePendingStylesheets();
        }
    }
}
void RenderFlowThread::computeOverflowStateForRegions(LayoutUnit oldClientAfterEdge)
{
    LayoutUnit height = oldClientAfterEdge;
    // FIXME: the visual overflow of middle region (if it is the last one to contain any content in a render flow thread)
    // might not be taken into account because the render flow thread height is greater that that regions height + its visual overflow
    // because of how computeLogicalHeight is implemented for RenderFlowThread (as a sum of all regions height).
    // This means that the middle region will be marked as fit (even if it has visual overflow flowing into the next region)
    if (hasRenderOverflow())
        height = isHorizontalWritingMode() ? visualOverflowRect().maxY() : visualOverflowRect().maxX();

    for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
        RenderRegion* region = *iter;
        if (!region->isValid()) {
            region->setRegionState(RenderRegion::RegionUndefined);
            continue;
        }
        LayoutUnit flowMin = height - (isHorizontalWritingMode() ? region->regionRect().y() : region->regionRect().x());
        LayoutUnit flowMax = height - (isHorizontalWritingMode() ? region->regionRect().maxY() : region->regionRect().maxX());
        RenderRegion::RegionState previousState = region->regionState();
        RenderRegion::RegionState state = RenderRegion::RegionFit;
        if (flowMin <= 0)
            state = RenderRegion::RegionEmpty;
        if (flowMax > 0)
            state = RenderRegion::RegionOverflow;
        region->setRegionState(state);
        // determine whether this region should dispatch a regionLayoutUpdate event
        // FIXME: currently it cannot determine whether a region whose regionOverflow state remained either "fit" or "overflow" has actually
        // changed, so it just assumes that those region should dispatch the event
        if (previousState != state
            || state == RenderRegion::RegionFit
            || state == RenderRegion::RegionOverflow)
            region->setDispatchRegionLayoutUpdateEvent(true);
    }

    // With the regions overflow state computed we can also set the overflow for the named flow.
    RenderRegion* lastReg = lastRegion();
    m_overflow = lastReg && (lastReg->regionState() == RenderRegion::RegionOverflow);
}