void GamepadManager::makeGamepadVisible(PlatformGamepad& platformGamepad, HashSet<NavigatorGamepad*>& navigatorSet, HashSet<DOMWindow*>& domWindowSet) { if (navigatorSet.isEmpty() && domWindowSet.isEmpty()) return; for (auto* navigator : navigatorSet) navigator->gamepadConnected(platformGamepad); Vector<WeakPtr<DOMWindow>> weakWindows; for (auto* domWindow : m_domWindows) weakWindows.append(domWindow->createWeakPtr()); for (auto& window : weakWindows) { // Event dispatch might have made this window go away. if (!window) continue; // This DOMWindow's Navigator might not be accessible. e.g. The DOMWindow might be in the back/forward cache. // If this happens the DOMWindow will not get this gamepadconnected event. // The new gamepad will still be visibile to it once it is restored from the back/forward cache. NavigatorGamepad* navigator = navigatorGamepadFromDOMWindow(window.get()); if (!navigator) continue; Ref<Gamepad> gamepad(navigator->gamepadFromPlatformGamepad(platformGamepad)); window->dispatchEvent(GamepadEvent::create(eventNames().gamepadconnectedEvent, gamepad.get()), window->document()); } }
static bool elementMatchesSelectorScopes(const Element* element, const HashSet<StringImpl*>& idScopes, const HashSet<StringImpl*>& classScopes) { if (!idScopes.isEmpty() && element->hasID() && idScopes.contains(element->idForStyleResolution().impl())) return true; if (classScopes.isEmpty() || !element->hasClass()) return false; const SpaceSplitString& classNames = element->classNames(); for (unsigned i = 0; i < classNames.size(); ++i) { if (classScopes.contains(classNames[i].impl())) return true; } return false; }
static void webProcessTestRunnerFinalize(JSObjectRef object) { g_object_unref(JSObjectGetPrivate(object)); if (s_watchedObjects.isEmpty()) return; g_print("Leaked objects in WebProcess:"); for (const auto object : s_watchedObjects) g_print(" %s(%p)", g_type_name_from_instance(reinterpret_cast<GTypeInstance*>(object)), object); g_print("\n"); g_assert(s_watchedObjects.isEmpty()); }
HashSet<String, CaseFoldingHash>* XMLHttpRequest::forbiddenHeadersList() { static HashSet<String, CaseFoldingHash> forbiddenHeaders; if (forbiddenHeaders.isEmpty()) { m_st_iIsEmpty = 0; forbiddenHeaders.add("accept-charset"); forbiddenHeaders.add("accept-encoding"); forbiddenHeaders.add("connection"); forbiddenHeaders.add("content-length"); forbiddenHeaders.add("content-transfer-encoding"); forbiddenHeaders.add("date"); forbiddenHeaders.add("expect"); forbiddenHeaders.add("host"); forbiddenHeaders.add("keep-alive"); forbiddenHeaders.add("referer"); forbiddenHeaders.add("te"); forbiddenHeaders.add("trailer"); forbiddenHeaders.add("transfer-encoding"); forbiddenHeaders.add("upgrade"); forbiddenHeaders.add("via"); } return &forbiddenHeaders; }
JSValue* JSClipboard::getValueProperty(ExecState* exec, int token) const { Clipboard* clipboard = impl(); switch (token) { case DropEffect: ASSERT(clipboard->isForDragging() || clipboard->dropEffect().isNull()); return jsStringOrUndefined(clipboard->dropEffect()); case EffectAllowed: ASSERT(clipboard->isForDragging() || clipboard->effectAllowed().isNull()); return jsStringOrUndefined(clipboard->effectAllowed()); case Types: { HashSet<String> types = clipboard->types(); if (types.isEmpty()) return jsNull(); else { List list; HashSet<String>::const_iterator end = types.end(); for (HashSet<String>::const_iterator it = types.begin(); it != end; ++it) list.append(jsString(UString(*it))); return exec->lexicalInterpreter()->builtinArray()->construct(exec, list); } } default: return 0; } }
void RadioButtonGroup::remove(HTMLInputElement* button) { ASSERT(button->isRadioButton()); HashSet<HTMLInputElement*>::iterator it = m_members.find(button); if (it == m_members.end()) return; bool wasValid = isValid(); m_members.remove(it); if (button->isRequired()) { ASSERT(m_requiredCount); --m_requiredCount; } if (m_checkedButton) { button->setNeedsStyleRecalc(); if (m_checkedButton == button) { m_checkedButton = nullptr; setNeedsStyleRecalcForAllButtons(); } } if (m_members.isEmpty()) { ASSERT(!m_requiredCount); ASSERT(!m_checkedButton); } else if (wasValid != isValid()) updateValidityForAllButtons(); if (!wasValid) { // A radio button not in a group is always valid. We need to make it // valid only if the group was invalid. button->updateValidity(); } }
void SVGStyledElement::updateElementInstance(SVGDocumentExtensions* extensions) const { SVGStyledElement* nonConstThis = const_cast<SVGStyledElement*>(this); HashSet<SVGElementInstance*>* set = extensions->instancesForElement(nonConstThis); if (!set || set->isEmpty()) return; // We need to be careful here, as the instancesForElement // hash set may be modified after we call updateInstance! HashSet<SVGElementInstance*> localCopy; // First create a local copy of the hashset HashSet<SVGElementInstance*>::const_iterator it1 = set->begin(); const HashSet<SVGElementInstance*>::const_iterator end1 = set->end(); for (; it1 != end1; ++it1) localCopy.add(*it1); // Actually nofify instances to update HashSet<SVGElementInstance*>::const_iterator it2 = localCopy.begin(); const HashSet<SVGElementInstance*>::const_iterator end2 = localCopy.end(); for (; it2 != end2; ++it2) (*it2)->updateInstance(nonConstThis); }
static void addToHash(HashSet<T>& toHash, HashSet<T>&& fromHash) { if (toHash.isEmpty()) toHash = WTFMove(fromHash); else toHash.add(fromHash.begin(), fromHash.end()); }
static bool isSafeRequestHeader(const String& name) { static HashSet<String, CaseFoldingHash> forbiddenHeaders; static String proxyString("proxy-"); static String secString("sec-"); if (forbiddenHeaders.isEmpty()) { forbiddenHeaders.add("accept-charset"); forbiddenHeaders.add("accept-encoding"); forbiddenHeaders.add("connection"); forbiddenHeaders.add("content-length"); forbiddenHeaders.add("content-transfer-encoding"); forbiddenHeaders.add("date"); forbiddenHeaders.add("expect"); forbiddenHeaders.add("host"); forbiddenHeaders.add("keep-alive"); forbiddenHeaders.add("referer"); forbiddenHeaders.add("te"); forbiddenHeaders.add("trailer"); forbiddenHeaders.add("transfer-encoding"); forbiddenHeaders.add("upgrade"); forbiddenHeaders.add("via"); } return !forbiddenHeaders.contains(name) && !name.startsWith(proxyString, false) && !name.startsWith(secString, false); }
void SVGDocumentExtensions::removeAnimationElementFromTarget(SVGSMILElement* animationElement, SVGElement* targetElement) { ASSERT(targetElement); ASSERT(animationElement); HashMap<SVGElement*, HashSet<SVGSMILElement*>* >::iterator it = m_animatedElements.find(targetElement); ASSERT(it != m_animatedElements.end()); HashSet<SVGSMILElement*>* animationElementsForTarget = it->value; ASSERT(!animationElementsForTarget->isEmpty()); animationElementsForTarget->remove(animationElement); if (animationElementsForTarget->isEmpty()) { m_animatedElements.remove(it); delete animationElementsForTarget; } }
void SVGResourcesCycleSolver::resolveCycles() { ASSERT(m_allResources.isEmpty()); #if DEBUG_CYCLE_DETECTION > 0 fprintf(stderr, "\nBefore cycle detection:\n"); m_resources.dump(&m_renderer); #endif // Stash all resources into a HashSet for the ease of traversing. HashSet<RenderSVGResourceContainer*> localResources; m_resources.buildSetOfResources(localResources); ASSERT(!localResources.isEmpty()); // Add all parent resource containers to the HashSet. HashSet<RenderSVGResourceContainer*> ancestorResources; for (auto& resource : ancestorsOfType<RenderSVGResourceContainer>(m_renderer)) ancestorResources.add(&resource); #if DEBUG_CYCLE_DETECTION > 0 fprintf(stderr, "\nDetecting wheter any resources references any of following objects:\n"); { fprintf(stderr, "Local resources:\n"); for (auto* resource : localResources) fprintf(stderr, "|> %s: object=%p (node=%p)\n", resource->renderName(), resource, resource->node()); fprintf(stderr, "Parent resources:\n"); for (auto* resource : ancestorResources) fprintf(stderr, "|> %s: object=%p (node=%p)\n", resource->renderName(), resource, resource->node()); } #endif // Build combined set of local and parent resources. m_allResources = localResources; for (auto* resource : ancestorResources) m_allResources.add(resource); // If we're a resource, add ourselves to the HashSet. if (m_renderer.isSVGResourceContainer()) m_allResources.add(&toRenderSVGResourceContainer(m_renderer)); ASSERT(!m_allResources.isEmpty()); // The job of this function is to determine wheter any of the 'resources' associated with the given 'renderer' // references us (or wheter any of its kids references us) -> that's a cycle, we need to find and break it. for (auto* resource : localResources) { if (ancestorResources.contains(resource) || resourceContainsCycles(*resource)) breakCycle(*resource); } #if DEBUG_CYCLE_DETECTION > 0 fprintf(stderr, "\nAfter cycle detection:\n"); m_resources.dump(m_renderer); #endif m_allResources.clear(); }
static bool stringMatchesGlyphName(const String& glyphName, const HashSet<String>& glyphValues) { if (glyphName.isEmpty()) return false; if (!glyphValues.isEmpty()) return glyphValues.contains(glyphName); return false; }
static bool isNodeTypeName(const String& name) { static HashSet<String> nodeTypeNames; if (nodeTypeNames.isEmpty()) { nodeTypeNames.add("comment"); nodeTypeNames.add("text"); nodeTypeNames.add("processing-instruction"); nodeTypeNames.add("node"); } return nodeTypeNames.contains(name); }
void MediaSession::safelyIterateActiveMediaElements(std::function<void(HTMLMediaElement*)> handler) { ASSERT(!m_iteratedActiveParticipatingElements); HashSet<HTMLMediaElement*> activeParticipatingElementsCopy = m_activeParticipatingElements; m_iteratedActiveParticipatingElements = &activeParticipatingElementsCopy; while (!activeParticipatingElementsCopy.isEmpty()) handler(activeParticipatingElementsCopy.takeAny()); m_iteratedActiveParticipatingElements = nullptr; }
void SVGRenderSupport::layoutChildren(RenderObject* start, bool selfNeedsLayout) { bool layoutSizeChanged = layoutSizeOfNearestViewportChanged(start); bool transformChanged = transformToRootChanged(start); HashSet<RenderObject*> notlayoutedObjects; for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) { bool needsLayout = selfNeedsLayout; if (transformChanged) { // If the transform changed we need to update the text metrics (note: this also happens for layoutSizeChanged=true). if (child->isSVGText()) toRenderSVGText(child)->setNeedsTextMetricsUpdate(); needsLayout = true; } if (layoutSizeChanged) { // When selfNeedsLayout is false and the layout size changed, we have to check whether this child uses relative lengths if (SVGElement* element = child->node()->isSVGElement() ? static_cast<SVGElement*>(child->node()) : 0) { if (element->isStyled() && static_cast<SVGStyledElement*>(element)->hasRelativeLengths()) { // When the layout size changed and when using relative values tell the RenderSVGShape to update its shape object if (child->isSVGShape()) toRenderSVGShape(child)->setNeedsShapeUpdate(); needsLayout = true; } } } if (needsLayout) { child->setNeedsLayout(true, false); child->layout(); } else { if (child->needsLayout()) child->layout(); else if (layoutSizeChanged) notlayoutedObjects.add(child); } ASSERT(!child->needsLayout()); } if (!layoutSizeChanged) { ASSERT(notlayoutedObjects.isEmpty()); return; } // If the layout size changed, invalidate all resources of all children that didn't go through the layout() code path. HashSet<RenderObject*>::iterator end = notlayoutedObjects.end(); for (HashSet<RenderObject*>::iterator it = notlayoutedObjects.begin(); it != end; ++it) invalidateResourcesOfChildren(*it); }
TEST(WTF_HashSet, MoveOnly) { HashSet<MoveOnly> hashSet; for (size_t i = 0; i < 100; ++i) { MoveOnly moveOnly(i + 1); hashSet.add(WTF::move(moveOnly)); } for (size_t i = 0; i < 100; ++i) EXPECT_TRUE(hashSet.contains(MoveOnly(i + 1))); for (size_t i = 0; i < 100; ++i) EXPECT_TRUE(hashSet.remove(MoveOnly(i + 1))); EXPECT_TRUE(hashSet.isEmpty()); for (size_t i = 0; i < 100; ++i) hashSet.add(MoveOnly(i + 1)); for (size_t i = 0; i < 100; ++i) EXPECT_TRUE(hashSet.take(MoveOnly(i + 1)) == MoveOnly(i + 1)); EXPECT_TRUE(hashSet.isEmpty()); for (size_t i = 0; i < 100; ++i) hashSet.add(MoveOnly(i + 1)); HashSet<MoveOnly> secondSet; for (size_t i = 0; i < 100; ++i) secondSet.add(hashSet.takeAny()); EXPECT_TRUE(hashSet.isEmpty()); for (size_t i = 0; i < 100; ++i) EXPECT_TRUE(secondSet.contains(MoveOnly(i + 1))); }
void JavaScriptDebugServer::removeBreakpoint(int sourceID, unsigned lineNumber) { HashSet<unsigned>* lines = m_breakpoints.get(sourceID); if (!lines) return; lines->remove(lineNumber); if (!lines->isEmpty()) return; m_breakpoints.remove(sourceID); delete lines; }
static bool isOnAccessControlResponseHeaderWhitelist(const String& name) { static HashSet<String, CaseFoldingHash> allowedHeaders; if (allowedHeaders.isEmpty()) { allowedHeaders.add("cache-control"); allowedHeaders.add("content-language"); allowedHeaders.add("content-type"); allowedHeaders.add("expires"); allowedHeaders.add("last-modified"); allowedHeaders.add("pragma"); } return allowedHeaders.contains(name); }
JSValuePtr JSClipboard::types(ExecState* exec) const { Clipboard* clipboard = impl(); HashSet<String> types = clipboard->types(); if (types.isEmpty()) return jsNull(); ArgList list; HashSet<String>::const_iterator end = types.end(); for (HashSet<String>::const_iterator it = types.begin(); it != end; ++it) list.append(jsString(exec, UString(*it))); return constructArray(exec, list); }
Vector<SVGGlyph> SVGFontElement::buildGlyphList(const UnicodeRanges& unicodeRanges, const HashSet<String>& unicodeNames, const HashSet<String>& glyphNames) const { Vector<SVGGlyph> glyphs; if (!unicodeRanges.isEmpty()) { const UnicodeRanges::const_iterator end = unicodeRanges.end(); for (UnicodeRanges::const_iterator it = unicodeRanges.begin(); it != end; ++it) m_glyphMap.collectGlyphsForUnicodeRange(*it, glyphs); } if (!unicodeNames.isEmpty()) { const HashSet<String>::const_iterator end = unicodeNames.end(); for (HashSet<String>::const_iterator it = unicodeNames.begin(); it != end; ++it) m_glyphMap.collectGlyphsForStringExact(*it, glyphs); } if (!glyphNames.isEmpty()) { const HashSet<String>::const_iterator end = glyphNames.end(); for (HashSet<String>::const_iterator it = glyphNames.begin(); it != end; ++it) { const SVGGlyph& glyph = m_glyphMap.glyphIdentifierForGlyphName(*it); if (glyph.tableEntry) glyphs.append(glyph); } } return glyphs; }
void SVGElementInstance::invalidateAllInstancesOfElement(SVGElement* element) { if (!element) return; HashSet<SVGElementInstance*> set = element->instancesForElement(); if (set.isEmpty()) return; // Find all use elements referencing the instances - ask them _once_ to rebuild. HashSet<SVGElementInstance*>::const_iterator it = set.begin(); const HashSet<SVGElementInstance*>::const_iterator end = set.end(); for (; it != end; ++it) (*it)->setNeedsUpdate(true); }
void Worklist::removeDeadPlans(VM& vm) { { LockHolder locker(m_lock); HashSet<CompilationKey> deadPlanKeys; for (PlanMap::iterator iter = m_plans.begin(); iter != m_plans.end(); ++iter) { Plan* plan = iter->value.get(); if (&plan->vm != &vm) continue; if (plan->isKnownToBeLiveDuringGC()) continue; RELEASE_ASSERT(plan->stage != Plan::Cancelled); // Should not be cancelled, yet. ASSERT(!deadPlanKeys.contains(plan->key())); deadPlanKeys.add(plan->key()); } if (!deadPlanKeys.isEmpty()) { for (HashSet<CompilationKey>::iterator iter = deadPlanKeys.begin(); iter != deadPlanKeys.end(); ++iter) m_plans.take(*iter)->cancel(); Deque<RefPtr<Plan>> newQueue; while (!m_queue.isEmpty()) { RefPtr<Plan> plan = m_queue.takeFirst(); if (plan->stage != Plan::Cancelled) newQueue.append(plan); } m_queue.swap(newQueue); for (unsigned i = 0; i < m_readyPlans.size(); ++i) { if (m_readyPlans[i]->stage != Plan::Cancelled) continue; m_readyPlans[i] = m_readyPlans.last(); m_readyPlans.removeLast(); } } } // No locking needed for this part, see comment in visitWeakReferences(). for (unsigned i = m_threads.size(); i--;) { ThreadData* data = m_threads[i].get(); Safepoint* safepoint = data->m_safepoint; if (!safepoint) continue; if (&safepoint->vm() != &vm) continue; if (safepoint->isKnownToBeLiveDuringGC()) continue; safepoint->cancel(); } }
void DisplayRefreshMonitor::displayDidRefresh() { double monotonicAnimationStartTime; { MutexLocker lock(m_mutex); if (!m_scheduled) ++m_unscheduledFireCount; else m_unscheduledFireCount = 0; m_scheduled = false; monotonicAnimationStartTime = m_monotonicAnimationStartTime; } // The call back can cause all our clients to be unregistered, so we need to protect // against deletion until the end of the method. Ref<DisplayRefreshMonitor> protect(*this); // Copy the hash table and remove clients from it one by one so we don't notify // any client twice, but can respond to removal of clients during the delivery process. HashSet<DisplayRefreshMonitorClient*> clientsToBeNotified = m_clients; m_clientsToBeNotified = &clientsToBeNotified; while (!clientsToBeNotified.isEmpty()) { // Take a random client out of the set. Ordering doesn't matter. // FIXME: Would read more cleanly if HashSet had a take function. auto it = clientsToBeNotified.begin(); DisplayRefreshMonitorClient* client = *it; clientsToBeNotified.remove(it); client->fireDisplayRefreshIfNeeded(monotonicAnimationStartTime); // This checks if this function was reentered. In that case, stop iterating // since it's not safe to use the set any more. if (m_clientsToBeNotified != &clientsToBeNotified) break; } if (m_clientsToBeNotified == &clientsToBeNotified) m_clientsToBeNotified = nullptr; { MutexLocker lock(m_mutex); m_previousFrameDone = true; } DisplayRefreshMonitorManager::sharedManager()->displayDidRefresh(this); }
v8::Handle<v8::Value> V8Clipboard::typesAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { INC_STATS("DOM.Clipboard.types()"); Clipboard* clipboard = V8Clipboard::toNative(info.Holder()); HashSet<String> types = clipboard->types(); if (types.isEmpty()) return v8::Null(); v8::Local<v8::Array> result = v8::Array::New(types.size()); HashSet<String>::const_iterator end = types.end(); int index = 0; for (HashSet<String>::const_iterator it = types.begin(); it != end; ++it, ++index) result->Set(v8::Integer::New(index), v8String(*it)); return result; }
static bool stringMatchesUnicodeRange(const String& unicodeString, const UnicodeRanges& ranges, const HashSet<String>& unicodeValues) { if (unicodeString.isEmpty()) return false; if (!ranges.isEmpty()) { UChar firstChar = unicodeString[0]; const UnicodeRanges::const_iterator end = ranges.end(); for (UnicodeRanges::const_iterator it = ranges.begin(); it != end; ++it) { if (firstChar >= it->first && firstChar <= it->second) return true; } } if (!unicodeValues.isEmpty()) return unicodeValues.contains(unicodeString); return false; }
void SVGDocumentExtensions::removeAllTargetReferencesForElement(SVGElement* referencingElement) { Vector<SVGElement*> toBeRemoved; HashMap<SVGElement*, OwnPtr<HashSet<SVGElement*> > >::iterator end = m_elementDependencies.end(); for (HashMap<SVGElement*, OwnPtr<HashSet<SVGElement*> > >::iterator it = m_elementDependencies.begin(); it != end; ++it) { SVGElement* referencedElement = it->key; HashSet<SVGElement*>* referencingElements = it->value.get(); HashSet<SVGElement*>::iterator setIt = referencingElements->find(referencingElement); if (setIt == referencingElements->end()) continue; referencingElements->remove(setIt); if (referencingElements->isEmpty()) toBeRemoved.append(referencedElement); } m_elementDependencies.removeAll(toBeRemoved); }
static bool isOnAccessControlResponseHeaderWhitelist(const String& name) { //+ 4/28/09 CSidhall - Removed as static for not called often and only 6 strings. // Original code: //static HashSet<String, CaseFoldingHash> allowedHeaders; // New code: HashSet<String, CaseFoldingHash> allowedHeaders; //- CS if (allowedHeaders.isEmpty()) { allowedHeaders.add("cache-control"); allowedHeaders.add("content-language"); allowedHeaders.add("content-type"); allowedHeaders.add("expires"); allowedHeaders.add("last-modified"); allowedHeaders.add("pragma"); } return allowedHeaders.contains(name); }
void WMLTemplateElement::registerTemplatesInDocument(Document* doc) { ASSERT(doc); // Build list of cards in document RefPtr<NodeList> nodeList = doc->getElementsByTagName("card"); if (!nodeList) return; unsigned length = nodeList->length(); if (length < 1) return; HashSet<WMLCardElement*> cards; for (unsigned i = 0; i < length; ++i) cards.add(static_cast<WMLCardElement*>(nodeList->item(i))); if (cards.isEmpty()) return; // Register template element to all cards nodeList = doc->getElementsByTagName("template"); if (!nodeList) return; length = nodeList->length(); if (length < 1) return; // Only one template element should be allowed in a document // Calling setTemplateElement() twice on a WMLCardElement, will result in a tokenizer error. for (unsigned i = 0; i < length; ++i) { WMLTemplateElement* temp = static_cast<WMLTemplateElement*>(nodeList->item(i)); HashSet<WMLCardElement*>::iterator it = cards.begin(); HashSet<WMLCardElement*>::iterator end = cards.end(); for (; it != end; ++it) (*it)->setTemplateElement(temp); } }
void AbstractDatabase::closeDatabase() { if (!m_opened) return; m_sqliteDatabase.close(); m_opened = false; { MutexLocker locker(guidMutex()); HashSet<AbstractDatabase*>* hashSet = guidToDatabaseMap().get(m_guid); ASSERT(hashSet); ASSERT(hashSet->contains(this)); hashSet->remove(this); if (hashSet->isEmpty()) { guidToDatabaseMap().remove(m_guid); delete hashSet; guidToVersionMap().remove(m_guid); } } }
// Helper function static bool isSupportedJavaScriptLanguage(const String& language) { static HashSet<String, CaseFoldingHash> languages; if (languages.isEmpty()) { languages.add("javascript"); languages.add("javascript"); languages.add("javascript1.0"); languages.add("javascript1.1"); languages.add("javascript1.2"); languages.add("javascript1.3"); languages.add("javascript1.4"); languages.add("javascript1.5"); languages.add("javascript1.6"); languages.add("javascript1.7"); languages.add("livescript"); languages.add("ecmascript"); languages.add("jscript"); } return languages.contains(language); }