LinkHash visitedLinkHash(const KURL& base, const AtomicString& attributeURL) { const UChar* characters = attributeURL.characters(); unsigned length = attributeURL.length(); if (!length) return 0; // This is a poor man's completeURL. Faster with less memory allocation. // FIXME: It's missing a lot of what completeURL does and a lot of what KURL does. // For example, it does not handle international domain names properly. // FIXME: It is wrong that we do not do further processing on strings that have "://" in them: // 1) The "://" could be in the query or anchor. // 2) The URL's path could have a "/./" or a "/../" or a "//" sequence in it. // FIXME: needsTrailingSlash does not properly return true for a URL that has no path, but does // have a query or anchor. bool hasColonSlashSlash = containsColonSlashSlash(characters, length); if (hasColonSlashSlash && !needsTrailingSlash(characters, length)) return visitedLinkHash(attributeURL.characters(), attributeURL.length()); Vector<UChar, 512> buffer; if (hasColonSlashSlash) { // FIXME: This is incorrect for URLs that have a query or anchor; the "/" needs to go at the // end of the path, *before* the query or anchor. buffer.append(characters, length); buffer.append('/'); return visitedLinkHash(buffer.data(), buffer.size()); } switch (characters[0]) { case '/': buffer.append(base.string().characters(), base.pathStart()); break; case '#': buffer.append(base.string().characters(), base.pathEnd()); break; default: buffer.append(base.string().characters(), base.pathAfterLastSlash()); break; } buffer.append(characters, length); cleanPath(buffer); if (needsTrailingSlash(buffer.data(), buffer.size())) { // FIXME: This is incorrect for URLs that have a query or anchor; the "/" needs to go at the // end of the path, *before* the query or anchor. buffer.append('/'); } return visitedLinkHash(buffer.data(), buffer.size()); }
void PageGroup::addVisitedLink(const KURL& url) { if (!shouldTrackVisitedLinks) return; ASSERT(!url.isEmpty()); addVisitedLink(visitedLinkHash(url.string())); }
static inline LinkHash linkHashForElement(const Element& element, const AtomicString& attribute = AtomicString()) { DCHECK(attribute.isNull() || linkAttribute(element) == attribute); if (isHTMLAnchorElement(element)) return toHTMLAnchorElement(element).visitedLinkHash(); return visitedLinkHash(element.document().baseURL(), attribute.isNull() ? linkAttribute(element) : attribute); }
static inline void addVisitedLink(Page* page, const KURL& url) { #if USE(PLATFORM_STRATEGIES) platformStrategies()->visitedLinkStrategy()->addVisitedLink(page, visitedLinkHash(url.string().characters(), url.string().length())); #else page->group().addVisitedLink(url); #endif }
LinkHash visitedLinkHash(const KURL& base, const AtomicString& attributeURL) { Vector<UChar, 512> url; visitedURL(base, attributeURL, url); if (url.isEmpty()) return 0; return visitedLinkHash(url.data(), url.size()); }
void PageGroup::removeVisitedLink(const URL& url) { LinkHash hash = visitedLinkHash(url.string()); ASSERT(m_visitedLinkHashes.contains(hash)); m_visitedLinkHashes.remove(hash); // FIXME: Why can't we just invalidate the single visited link hash here? for (auto& page : m_pages) page->invalidateStylesForAllLinks(); pageCache()->markPagesForVistedLinkStyleRecalc(); }
void PageGroup::addVisitedLink(const UChar* characters, size_t length) { if (!shouldTrackVisitedLinks) return; addVisitedLink(visitedLinkHash(characters, length)); }
static inline void addVisitedLink(Page& page, const URL& url) { page.visitedLinkStore().addVisitedLink(page, visitedLinkHash(url.string())); }
static inline void addVisitedLink(Page* page, const KURL& url) { platformStrategies()->visitedLinkStrategy()->addVisitedLink(page, visitedLinkHash(url.string())); }