void CPushAppHandlerEx::RunL() { __LOG_PTR_DEBUG("CPushAppHandlerEx:: RunL Called"); // TODO Create a State Machine for specific actions switch (iState) { case EParsing : iState = EProcessing; ParsePushMsgL(); break; case EProcessing: iState = EDone; ProcessPushMsgL(); break; case EDone: Done(KErrNone); break; default: break; } }
VOID CRWLock::WriteDone() { CSEM* pSem = nullptr; LONG lCount = 0; { CSpinLock locallock(m_cs); ASSERT(m_nActive < 0); if(++m_nActive == 0) { DetachOwner(); Done(&pSem, lCount); } else ASSERT(IsOwner()); } if(pSem != nullptr) pSem->Release(lCount); }
void StorageCache::CloneFrom(const StorageCache* aThat) { // This will never be called on anything else than SessionStorage. // This means mData will never be touched on any other thread than // the main thread and it never went through the loading process. MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(!mPersistent); MOZ_ASSERT(!(bool)aThat->mLoaded); mLoaded = false; mInitialized = aThat->mInitialized; mPersistent = false; mSessionOnlyDataSetActive = aThat->mSessionOnlyDataSetActive; for (uint32_t i = 0; i < kDataSetCount; ++i) { for (auto it = aThat->mData[i].mKeys.ConstIter(); !it.Done(); it.Next()) { mData[i].mKeys.Put(it.Key(), it.UserData()); } ProcessUsageDelta(i, aThat->mData[i].mOriginQuotaUsage); } }
VOID CRWLock::ReadDone() { CSEM* pSem = nullptr; LONG lCount = 0; { CSpinLock locallock(m_cs); ASSERT(m_nActive != 0); if(m_nActive > 0) { if(--m_nActive == 0) Done(&pSem, lCount); } else ASSERT(IsOwner()); } if(pSem != nullptr) pSem->Release(lCount); }
void plDistribComponent_old::Preview() { if( !NumTargets() ) return; GetCOREInterface()->DisableSceneRedraw(); plDistribInstTab replicants; plExportProgressBar bar; bar.Start("Preview", NumTargets() << 4); plDistTree distTree; Distribute(replicants, bar, &distTree); IMakeOne(replicants); Done(); GetCOREInterface()->EnableSceneRedraw(); GetCOREInterface()->ForceCompleteRedraw(FALSE); }
nsresult VariableLengthPrefixSet::WritePrefixes(nsIOutputStream* out) { uint32_t written; uint32_t writelen = sizeof(uint32_t); uint32_t magic = PREFIXSET_VERSION_MAGIC; nsresult rv = out->Write(reinterpret_cast<char*>(&magic), writelen, &written); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(written == writelen, NS_ERROR_FAILURE); uint32_t count = mVLPrefixSet.Count(); rv = out->Write(reinterpret_cast<char*>(&count), writelen, &written); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(written == writelen, NS_ERROR_FAILURE); // Store PrefixSize, Length of Prefix String and then Prefix String for (auto iter = mVLPrefixSet.ConstIter(); !iter.Done(); iter.Next()) { const nsCString& vlPrefixes = *iter.Data(); uint8_t prefixSize = iter.Key(); writelen = sizeof(uint8_t); rv = out->Write(reinterpret_cast<char*>(&prefixSize), writelen, &written); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(written == writelen, NS_ERROR_FAILURE); uint32_t stringLength = vlPrefixes.Length(); writelen = sizeof(uint32_t); rv = out->Write(reinterpret_cast<char*>(&stringLength), writelen, &written); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(written == writelen, NS_ERROR_FAILURE); rv = out->Write(const_cast<char*>(vlPrefixes.BeginReading()), stringLength, &written); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(stringLength == written, NS_ERROR_FAILURE); } return NS_OK; }
Boolean shelf_goto(int i) { char path[MAXPATHLEN+1]; root_modified = cur_modified = cur_changed = shelf_modified = False; if (i == shelf_no && dirIsReadable(shelfdir)) return True; Wait(); shelf_modified = True; dirFree(shelfdir); shelf_no = i; if (shelf_dir(shelf_no)) pathname(path, save_shelf_path, shelf_dir(shelf_no)); else if (shelf_label(shelf_no)) pathname(path, save_shelf_path, shelf_label(shelf_no)); else strcpy(path, save_shelf_path); update_shelf_path(path); shelfdir = dirCreate(path, NULL, save_shelf_options); Done(); return dirReadFileInfo(shelfdir) != NULL; }
/////////////////////////////////////////////////////////////////////////////// // SetData /////////////////////////////////////////////////////////////////////////////// void cHierDatabaseIter::SetData(int8* pData, int32 length) //throw (eArchive, eHierDatabase) { ASSERT( ! Done() ); ASSERT( ! HasData() ); // remove the item's data, if there is any... // if( HasData() ) { RemoveData(); } // // add the data and set the entry's data pointer appropriately // cBlockRecordFile::tAddr addr = mpDb->AddItem( pData, length ); mIter->mData = cHierAddr( addr.mBlockNum, addr.mIndex ); // // update the entry on disk... // util_RewriteObject( mpDb, &(*mIter), GetCurrentAddr() ); }
already_AddRefed<TabParent> ContentProcessManager::GetTabParentByProcessAndTabId(const ContentParentId& aChildCpId, const TabId& aChildTabId) { MOZ_ASSERT(NS_IsMainThread()); auto iter = mContentParentMap.find(aChildCpId); if (NS_WARN_IF(iter == mContentParentMap.end())) { ASSERT_UNLESS_FUZZING(); return nullptr; } const ManagedContainer<PBrowserParent>& browsers = iter->second.mCp->ManagedPBrowserParent(); for (auto iter = browsers.ConstIter(); !iter.Done(); iter.Next()) { RefPtr<TabParent> tab = TabParent::GetFrom(iter.Get()->GetKey()); if (tab->GetTabId() == aChildTabId) { return tab.forget(); } } return nullptr; }
static void cool_heels(void) { int status; /* * At this point our only job is to wait for the child process. * If we hang out for a bit longer, that's okay. * By delaying before turning off the fault signals, * we increase the chance that the child process has completed * its exec and has turned on the fault traps. Nonetheless, * we can't guarantee a zero chance of missing a fault. * (We don't want to keep trapping the signals because the * interface program is likely to have a better way to handle * them; this process provides only rudimentary handling.) * * Note that on a very busy system, or with a very fast interface * program, the tables could be turned: Our sleep below (coupled * with a delay in the kernel scheduling us) may cause us to * detect the fault instead of the interface program. * * What we need is a way to synchronize with the child process. */ sleep (1); ignore_fault_signals (); WaitedChildPid = 0; while ((WaitedChildPid = wait(&status)) != ChildPid) ; if ( EXITED(status) > EXEC_EXIT_USER && EXITED(status) != EXEC_EXIT_FAULT ) Done (EXEC_EXIT_EXIT, EXITED(status)); done (status, 0); /* Don't use Done() */ /*NOTREACHED*/ }
NS_IMETHODIMP AudioContext::CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData, bool aAnonymize) { const nsLiteralCString nodeDescription("Memory used by AudioNode DOM objects (Web Audio)."); for (auto iter = mAllNodes.ConstIter(); !iter.Done(); iter.Next()) { AudioNode* node = iter.Get()->GetKey(); int64_t amount = node->SizeOfIncludingThis(MallocSizeOf); nsPrintfCString domNodePath("explicit/webaudio/audio-node/%s/dom-nodes", node->NodeType()); aHandleReport->Callback(EmptyCString(), domNodePath, KIND_HEAP, UNITS_BYTES, amount, nodeDescription, aData); } int64_t amount = SizeOfIncludingThis(MallocSizeOf); MOZ_COLLECT_REPORT( "explicit/webaudio/audiocontext", KIND_HEAP, UNITS_BYTES, amount, "Memory used by AudioContext objects (Web Audio)."); return NS_OK; }
void Compositor::DrawDiagnostics(DiagnosticFlags aFlags, const nsIntRegion& aVisibleRegion, const gfx::IntRect& aClipRect, const gfx::Matrix4x4& aTransform, uint32_t aFlashCounter) { if (!ShouldDrawDiagnostics(aFlags)) { return; } if (aVisibleRegion.GetNumRects() > 1) { for (auto iter = aVisibleRegion.RectIter(); !iter.Done(); iter.Next()) { DrawDiagnostics(aFlags | DiagnosticFlags::REGION_RECT, IntRectToRect(iter.Get()), aClipRect, aTransform, aFlashCounter); } } DrawDiagnostics(aFlags, IntRectToRect(aVisibleRegion.GetBounds()), aClipRect, aTransform, aFlashCounter); }
PromiseId MediaKeys::StorePromise(DetailedPromise* aPromise) { static uint32_t sEMEPromiseCount = 1; MOZ_ASSERT(aPromise); uint32_t id = sEMEPromiseCount++; EME_LOG("MediaKeys[%p]::StorePromise() id=%d", this, id); // Keep MediaKeys alive for the lifetime of its promises. Any still-pending // promises are rejected in Shutdown(). AddRef(); #ifdef DEBUG // We should not have already stored this promise! for (auto iter = mPromises.ConstIter(); !iter.Done(); iter.Next()) { MOZ_ASSERT(iter.Data() != aPromise); } #endif mPromises.Put(id, aPromise); return id; }
NS_IMETHODIMP IndexedDatabaseManager::Notify(nsITimer* aTimer) { MOZ_ASSERT(IsMainProcess()); MOZ_ASSERT(NS_IsMainThread()); for (auto iter = mPendingDeleteInfos.ConstIter(); !iter.Done(); iter.Next()) { auto key = iter.Key(); auto value = iter.Data(); MOZ_ASSERT(!value->IsEmpty()); RefPtr<DeleteFilesRunnable> runnable = new DeleteFilesRunnable(mBackgroundThread, key, *value); MOZ_ASSERT(value->IsEmpty()); runnable->Dispatch(); } mPendingDeleteInfos.Clear(); return NS_OK; }
void ImageLoader::ClearFrames(nsPresContext* aPresContext) { for (auto iter = mRequestToFrameMap.ConstIter(); !iter.Done(); iter.Next()) { auto request = static_cast<imgIRequest*>(iter.Key()); #ifdef DEBUG { nsCOMPtr<imgIRequest> debugRequest = do_QueryInterface(request); NS_ASSERTION(debugRequest == request, "This is bad"); } #endif if (aPresContext) { nsLayoutUtils::DeregisterImageRequest(aPresContext, request, nullptr); } } mRequestToFrameMap.Clear(); mFrameToRequestMap.Clear(); }
static bool AppendRequestsToArray(PLDHashTable* aTable, nsTArray<nsIRequest*> *aArray) { for (auto iter = aTable->Iter(); !iter.Done(); iter.Next()) { auto e = static_cast<RequestMapEntry*>(iter.Get()); nsIRequest *request = e->mKey; NS_ASSERTION(request, "What? Null key in PLDHashTable entry?"); bool ok = !!aArray->AppendElement(request); if (!ok) { break; } NS_ADDREF(request); } if (aArray->Length() != aTable->EntryCount()) { for (uint32_t i = 0, len = aArray->Length(); i < len; ++i) { NS_RELEASE((*aArray)[i]); } return false; } return true; }
void CheckChr(struct connection *c, char Chr) { if (Chr < 32 && Chr != 9 && Chr != 10) return; strncat(curline, &Chr, 1); // newline has come if (Chr == 10) { // this is a f*****g hack to handle unwanted interactivity (session in use) if (strstr(curline, "SESSION REJECTED") && strstr(curline, "IN USE")) { if (force_login) { SendChar('+'); SendChar(13); SendChar(10); } else { Done(105); } } if (!verbose) { if (strstr(curline, "<") == curline || strstr(curline, ":::") == curline || strstr(curline, "SESSION REJECTED") == curline || strstr(curline, "RE-OPEN SUCCESSFUL. NEW SESSION ESTABLISHED.") == curline || (curline[0] == 10 && (lastline[0] == 10 || lastline[0] == 0))) { curline[0] = 0; } } fprintf(stdout, "%s", curline); fflush(stdout); if (curline[0]) { strcpy(lastline, curline); curline[0] = 0; } } }
NS_IMETHODIMP mozPersonalDictionary::Save() { nsCOMPtr<nsIFile> theFile; nsresult res; WaitForSave(); mSavePending = true; //FIXME Deinst -- get dictionary name from prefs; res = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(theFile)); if(NS_FAILED(res)) return res; if(!theFile)return NS_ERROR_FAILURE; res = theFile->Append(NS_LITERAL_STRING(MOZ_PERSONAL_DICT_NAME)); if(NS_FAILED(res)) return res; nsCOMPtr<nsIEventTarget> target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &res); if (NS_WARN_IF(NS_FAILED(res))) { return res; } nsTArray<nsString> array; nsString* elems = array.AppendElements(mDictionaryTable.Count()); for (auto iter = mDictionaryTable.Iter(); !iter.Done(); iter.Next()) { elems->Assign(iter.Get()->GetKey()); elems++; } nsCOMPtr<nsIRunnable> runnable = new mozPersonalDictionarySave(this, theFile, mozilla::Move(array)); res = target->Dispatch(runnable, NS_DISPATCH_NORMAL); if (NS_WARN_IF(NS_FAILED(res))) { return res; } return res; }
void ServiceWorkerManagerService::PropagateUnregister( uint64_t aParentID, const PrincipalInfo& aPrincipalInfo, const nsAString& aScope) { AssertIsOnBackgroundThread(); if (ServiceWorkerParentInterceptEnabled()) { return; } RefPtr<dom::ServiceWorkerRegistrar> service = dom::ServiceWorkerRegistrar::Get(); MOZ_ASSERT(service); // It's possible that we don't have any ServiceWorkerManager managing this // scope but we still need to unregister it from the ServiceWorkerRegistrar. service->UnregisterServiceWorker(aPrincipalInfo, NS_ConvertUTF16toUTF8(aScope)); DebugOnly<bool> parentFound = false; for (auto iter = mAgents.Iter(); !iter.Done(); iter.Next()) { RefPtr<ServiceWorkerManagerParent> parent = iter.Get()->GetKey(); MOZ_ASSERT(parent); if (parent->ID() != aParentID) { nsString scope(aScope); Unused << parent->SendNotifyUnregister(aPrincipalInfo, scope); #ifdef DEBUG } else { parentFound = true; #endif } } #ifdef DEBUG MOZ_ASSERT(parentFound); #endif }
void readenvE(const unsigned char * buf, const unsigned char * len, size_t lenlen, const char * name) { if(lenlen == 0) { proxy_fail("readenvE: you certainly don't want lenlen = 0\n"); } Env(name); assume_intype("bitstring"); Dup(); Len(); BS(false, lenlen); Done(); // Assume that variable length fits in its bitstring representation. assume_intype("bitstring"); if(len != NULL) StoreBuf(len); else Clear(1); StoreBuf(buf); }
NS_IMETHODIMP nsPerformanceStatsService::GetSnapshot(JSContext* cx, nsIPerformanceSnapshot * *aSnapshot) { RefPtr<nsPerformanceSnapshot> snapshot = new nsPerformanceSnapshot(); snapshot->SetProcessStats(GetStatsForGroup(mTopGroup)); for (auto iter = mGroups.Iter(); !iter.Done(); iter.Next()) { auto* entry = iter.Get(); nsPerformanceGroup* group = entry->GetKey(); if (group->isActive()) { snapshot->AppendComponentsStats(GetStatsForGroup(group)); } } js::GetPerfMonitoringTestCpuRescheduling(JS_GetRuntime(cx), &mProcessStayed, &mProcessMoved); if (++mProcessUpdateCounter % 10 == 0) { mozilla::unused << UpdateTelemetry(); } snapshot.forget(aSnapshot); return NS_OK; }
static void Fork2(void) { switch ((ChildPid = fork())) { case -1: Done (EXEC_EXIT_NFORK, errno); /*NOTREACHED*/ case 0: return; default: /* * Delay calling "ignore_fault_signals()" as long * as possible, to give the child a chance to exec * the interface program and turn on traps. */ cool_heels (); /*NOTREACHED*/ } }
// // Init // // Setup with a footprint type // void Placement::Init(Type *placeType, Team *teamIn) { ASSERT(placeType); // Make sure we're shutdown Done(); // Save the setup data type = placeType; team = teamIn; // Setup array sizes (includes border around footprint size.x = type->Size().x + 2; size.z = type->Size().z + 2; // Allocate the cell array array = new Cell[size.x * size.z]; // Allocate thumped data thumped.Init(size); // Set default values Reset(); }
void main(void) { SINT16 k; /* initialize FFT object */ fft.ipcbptr = (int *)RIFFT16_128p_in_data + 0; fft.workptr = (int *)fft_work_buffer + 0; fft.init(&fft); /* complex input IFFT */ rifft16(&fft); #if 1 /* Check error */ for (k=0; k<DATA_LENGTH; k++) { if (abs(RIFFT16_128p_out_data[k]-RIFFT16_128p_in_data[k])>2) err++; } #endif Done(); }
void IDBDatabase::AbortTransactions(bool aShouldWarn) { AssertIsOnOwningThread(); class MOZ_STACK_CLASS Helper final { typedef nsAutoTArray<RefPtr<IDBTransaction>, 20> StrongTransactionArray; typedef nsAutoTArray<IDBTransaction*, 20> WeakTransactionArray; public: static void AbortTransactions(IDBDatabase* aDatabase, const bool aShouldWarn) { MOZ_ASSERT(aDatabase); aDatabase->AssertIsOnOwningThread(); nsTHashtable<nsPtrHashKey<IDBTransaction>>& transactionTable = aDatabase->mTransactions; if (!transactionTable.Count()) { return; } StrongTransactionArray transactionsToAbort; transactionsToAbort.SetCapacity(transactionTable.Count()); for (auto iter = transactionTable.Iter(); !iter.Done(); iter.Next()) { IDBTransaction* transaction = iter.Get()->GetKey(); MOZ_ASSERT(transaction); transaction->AssertIsOnOwningThread(); // Transactions that are already done can simply be ignored. Otherwise // there is a race here and it's possible that the transaction has not // been successfully committed yet so we will warn the user. if (!transaction->IsDone()) { transactionsToAbort.AppendElement(transaction); } } MOZ_ASSERT(transactionsToAbort.Length() <= transactionTable.Count()); if (transactionsToAbort.IsEmpty()) { return; } // We want to abort transactions as soon as possible so we iterate the // transactions once and abort them all first, collecting the transactions // that need to have a warning issued along the way. Those that need a // warning will be a subset of those that are aborted, so we don't need // additional strong references here. WeakTransactionArray transactionsThatNeedWarning; for (RefPtr<IDBTransaction>& transaction : transactionsToAbort) { MOZ_ASSERT(transaction); MOZ_ASSERT(!transaction->IsDone()); if (aShouldWarn) { switch (transaction->GetMode()) { // We ignore transactions that could not have written any data. case IDBTransaction::READ_ONLY: break; // We warn for any transactions that could have written data. case IDBTransaction::READ_WRITE: case IDBTransaction::READ_WRITE_FLUSH: case IDBTransaction::VERSION_CHANGE: transactionsThatNeedWarning.AppendElement(transaction); break; default: MOZ_CRASH("Unknown mode!"); } } transaction->Abort(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); } static const char kWarningMessage[] = "IndexedDBTransactionAbortNavigation"; for (IDBTransaction* transaction : transactionsThatNeedWarning) { MOZ_ASSERT(transaction); nsString filename; uint32_t lineNo, column; transaction->GetCallerLocation(filename, &lineNo, &column); aDatabase->LogWarning(kWarningMessage, filename, lineNo, column); } }
void SigDone(int nonsense) { Done(0, NULL); SIGNAL_RETURN; }
void Restart(int nonsense) { Done(1, *g_argv); SIGNAL_RETURN; }
SpanningCellSorter::Item* SpanningCellSorter::GetNext(int32_t *aColSpan) { NS_ASSERTION(mState != DONE, "done enumerating, stop calling"); switch (mState) { case ADDING: /* prepare to enumerate the array */ mState = ENUMERATING_ARRAY; mEnumerationIndex = 0; /* fall through */ case ENUMERATING_ARRAY: while (mEnumerationIndex < ARRAY_SIZE && !mArray[mEnumerationIndex]) ++mEnumerationIndex; if (mEnumerationIndex < ARRAY_SIZE) { Item *result = mArray[mEnumerationIndex]; *aColSpan = IndexToSpan(mEnumerationIndex); NS_ASSERTION(result, "logic error"); #ifdef DEBUG_SPANNING_CELL_SORTER printf("SpanningCellSorter[%p]:" " returning list for colspan=%d from array\n", static_cast<void*>(this), *aColSpan); #endif ++mEnumerationIndex; return result; } /* prepare to enumerate the hash */ mState = ENUMERATING_HASH; mEnumerationIndex = 0; if (mHashTable.EntryCount() > 0) { HashTableEntry **sh = new HashTableEntry*[mHashTable.EntryCount()]; int32_t j = 0; for (auto iter = mHashTable.Iter(); !iter.Done(); iter.Next()) { sh[j++] = static_cast<HashTableEntry*>(iter.Get()); } NS_QuickSort(sh, mHashTable.EntryCount(), sizeof(sh[0]), SortArray, nullptr); mSortedHashTable = sh; } /* fall through */ case ENUMERATING_HASH: if (mEnumerationIndex < mHashTable.EntryCount()) { Item *result = mSortedHashTable[mEnumerationIndex]->mItems; *aColSpan = mSortedHashTable[mEnumerationIndex]->mColSpan; NS_ASSERTION(result, "holes in hash table"); #ifdef DEBUG_SPANNING_CELL_SORTER printf("SpanningCellSorter[%p]:" " returning list for colspan=%d from hash\n", static_cast<void*>(this), *aColSpan); #endif ++mEnumerationIndex; return result; } mState = DONE; /* fall through */ case DONE: ; } return nullptr; }
virtual void OnAck(unsigned id) override { printf("received ack %u\n", id); Done(); }
void DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time) { Element* root = nullptr; nsIFrame* rootFrame = nullptr; nsRect rootRect; if (mRoot) { root = mRoot; rootFrame = root->GetPrimaryFrame(); if (rootFrame) { if (rootFrame->GetType() == nsGkAtoms::scrollFrame) { nsIScrollableFrame* scrollFrame = do_QueryFrame(rootFrame); rootRect = nsLayoutUtils::TransformFrameRectToAncestor( rootFrame, rootFrame->GetContentRectRelativeToSelf(), scrollFrame->GetScrolledFrame()); } else { rootRect = nsLayoutUtils::GetAllInFlowRectsUnion(rootFrame, nsLayoutUtils::GetContainingBlockForClientRect(rootFrame), nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS); } } } else { nsCOMPtr<nsIPresShell> presShell = aDocument->GetShell(); if (presShell) { rootFrame = presShell->GetRootScrollFrame(); if (rootFrame) { nsPresContext* presContext = rootFrame->PresContext(); while (!presContext->IsRootContentDocument()) { presContext = presContext->GetParentPresContext(); if (!presContext) { break; } rootFrame = presContext->PresShell()->GetRootScrollFrame(); } root = rootFrame->GetContent()->AsElement(); nsIScrollableFrame* scrollFrame = do_QueryFrame(rootFrame); rootRect = scrollFrame->GetScrollPortRect(); } } } nsMargin rootMargin; NS_FOR_CSS_SIDES(side) { nscoord basis = side == eSideTop || side == eSideBottom ? rootRect.height : rootRect.width; nsCSSValue value = mRootMargin.*nsCSSRect::sides[side]; nsStyleCoord coord; if (value.IsPixelLengthUnit()) { coord.SetCoordValue(value.GetPixelLength()); } else if (value.IsPercentLengthUnit()) { coord.SetPercentValue(value.GetPercentValue()); } else { MOZ_ASSERT_UNREACHABLE("invalid length unit"); } rootMargin.Side(side) = nsLayoutUtils::ComputeCBDependentValue(basis, coord); } for (auto iter = mObservationTargets.Iter(); !iter.Done(); iter.Next()) { Element* target = iter.Get()->GetKey(); nsIFrame* targetFrame = target->GetPrimaryFrame(); nsRect targetRect; Maybe<nsRect> intersectionRect; if (rootFrame && targetFrame) { // If mRoot is set we are testing intersection with a container element // instead of the implicit root. if (mRoot) { // Skip further processing of this target if it is not in the same // Document as the intersection root, e.g. if root is an element of // the main document and target an element from an embedded iframe. if (target->GetComposedDoc() != root->GetComposedDoc()) { continue; } // Skip further processing of this target if is not a descendant of the // intersection root in the containing block chain. E.g. this would be // the case if the target is in a position:absolute element whose // containing block is an ancestor of root. if (!nsLayoutUtils::IsAncestorFrameCrossDoc(rootFrame, targetFrame)) { continue; } } targetRect = nsLayoutUtils::GetAllInFlowRectsUnion( targetFrame, nsLayoutUtils::GetContainingBlockForClientRect(targetFrame), nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS ); intersectionRect = Some(targetFrame->GetVisualOverflowRect()); nsIFrame* containerFrame = nsLayoutUtils::GetCrossDocParentFrame(targetFrame); while (containerFrame && containerFrame != rootFrame) { if (containerFrame->GetType() == nsGkAtoms::scrollFrame) { nsIScrollableFrame* scrollFrame = do_QueryFrame(containerFrame); nsRect subFrameRect = scrollFrame->GetScrollPortRect(); nsRect intersectionRectRelativeToContainer = nsLayoutUtils::TransformFrameRectToAncestor(targetFrame, intersectionRect.value(), containerFrame); intersectionRect = EdgeInclusiveIntersection(intersectionRectRelativeToContainer, subFrameRect); if (!intersectionRect) { break; } targetFrame = containerFrame; } // TODO: Apply clip-path. containerFrame = nsLayoutUtils::GetCrossDocParentFrame(containerFrame); } } nsRect rootIntersectionRect = rootRect; bool isInSimilarOriginBrowsingContext = rootFrame && targetFrame && CheckSimilarOrigin(root, target); if (isInSimilarOriginBrowsingContext) { rootIntersectionRect.Inflate(rootMargin); } if (intersectionRect.isSome()) { nsRect intersectionRectRelativeToRoot = nsLayoutUtils::TransformFrameRectToAncestor( targetFrame, intersectionRect.value(), nsLayoutUtils::GetContainingBlockForClientRect(rootFrame) ); intersectionRect = EdgeInclusiveIntersection( intersectionRectRelativeToRoot, rootIntersectionRect ); if (intersectionRect.isSome()) { intersectionRect = Some(nsLayoutUtils::TransformFrameRectToAncestor( nsLayoutUtils::GetContainingBlockForClientRect(rootFrame), intersectionRect.value(), targetFrame->PresContext()->PresShell()->GetRootScrollFrame() )); } } double targetArea = targetRect.width * targetRect.height; double intersectionArea = !intersectionRect ? 0 : intersectionRect->width * intersectionRect->height; double intersectionRatio = targetArea > 0.0 ? intersectionArea / targetArea : 0.0; size_t threshold = -1; if (intersectionRatio > 0.0) { if (intersectionRatio >= 1.0) { intersectionRatio = 1.0; threshold = mThresholds.Length(); } else { for (size_t k = 0; k < mThresholds.Length(); ++k) { if (mThresholds[k] <= intersectionRatio) { threshold = k + 1; } else { break; } } } } else if (intersectionRect.isSome()) { threshold = 0; } if (target->UpdateIntersectionObservation(this, threshold)) { QueueIntersectionObserverEntry( target, time, isInSimilarOriginBrowsingContext ? Some(rootIntersectionRect) : Nothing(), targetRect, intersectionRect, intersectionRatio ); } } }