Esempio n. 1
0
static void activateObserver(PassRefPtr<MutationObserver> observer)
{
    if (activeMutationObservers().isEmpty())
        Microtask::enqueueMicrotask(base::Bind(&MutationObserver::deliverMutations));

    activeMutationObservers().add(observer);
}
Esempio n. 2
0
void MutationObserver::notifyMutationObservers()
{
    // https://dom.spec.whatwg.org/#notify-mutation-observers
    // 1. Unset mutation observer compound microtask queued flag.
    mutationObserverCompoundMicrotaskQueuedFlag = false;

    ASSERT(isMainThread());
    static bool deliveryInProgress = false;
    if (deliveryInProgress)
        return;
    deliveryInProgress = true;

    if (!suspendedMutationObservers().isEmpty()) {
        Vector<RefPtr<MutationObserver>> suspended;
        copyToVector(suspendedMutationObservers(), suspended);
        for (auto& observer : suspended) {
            if (!observer->canDeliver())
                continue;

            suspendedMutationObservers().remove(observer);
            activeMutationObservers().add(observer);
        }
    }

    while (!activeMutationObservers().isEmpty() || !signalSlotList().isEmpty()) {
        // 2. Let notify list be a copy of unit of related similar-origin browsing contexts' list of MutationObserver objects.
        Vector<RefPtr<MutationObserver>> notifyList;
        copyToVector(activeMutationObservers(), notifyList);
        activeMutationObservers().clear();
        std::sort(notifyList.begin(), notifyList.end(), [](auto& lhs, auto& rhs) {
            return lhs->m_priority < rhs->m_priority;
        });

        // 3. Let signalList be a copy of unit of related similar-origin browsing contexts' signal slot list.
        // 4. Empty unit of related similar-origin browsing contexts' signal slot list.
        Vector<RefPtr<HTMLSlotElement>> slotList;
        if (!signalSlotList().isEmpty()) {
            slotList.swap(signalSlotList());
            for (auto& slot : slotList)
                slot->didRemoveFromSignalSlotList();
        }

        // 5. For each MutationObserver object mo in notify list, execute a compound microtask subtask
        for (auto& observer : notifyList) {
            if (observer->canDeliver())
                observer->deliver();
            else
                suspendedMutationObservers().add(observer);
        }

        // 6. For each slot slot in signalList, in order, fire an event named slotchange, with its bubbles attribute set to true, at slot.
        for (auto& slot : slotList)
            slot->dispatchSlotChangeEvent();
    }

    deliveryInProgress = false;
}
Esempio n. 3
0
void MutationObserver::deliverMutations() {
  DCHECK(isMainThread());
  MutationObserverVector observers;
  copyToVector(activeMutationObservers(), observers);
  activeMutationObservers().clear();
  std::sort(observers.begin(), observers.end(), ObserverLessThan());
  for (size_t i = 0; i < observers.size(); ++i) {
    if (observers[i]->shouldBeSuspended())
      suspendedMutationObservers().add(observers[i]);
    else
      observers[i]->deliver();
  }
}
Esempio n. 4
0
void MutationObserver::setHasTransientRegistration()
{
    ASSERT(isMainThread());
    activeMutationObservers().add(this);

    queueMutationObserverCompoundMicrotask();
}
Esempio n. 5
0
void MutationObserver::enqueueMutationRecord(Ref<MutationRecord>&& mutation)
{
    ASSERT(isMainThread());
    m_records.append(WTFMove(mutation));
    activeMutationObservers().add(this);

    queueMutationObserverCompoundMicrotask();
}
Esempio n. 6
0
static void activateObserver(MutationObserver* observer) {
  if (activeMutationObservers().isEmpty())
    Microtask::enqueueMicrotask(WTF::bind(&MutationObserver::deliverMutations));

  activeMutationObservers().add(observer);
}