Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: third_party/WebKit/Source/core/html/LinkStyle.cpp

Issue 2426513003: Refactor LinkStyle out of HTMLLinkElement (Closed)
Patch Set: Review comment Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/html/LinkStyle.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 // Use of this source code is governed by a BSD-style license that can be
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 // found in the LICENSE file.
4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights
6 * reserved.
7 * Copyright (C) 2009 Rob Buis (rwlbuis@gmail.com)
8 * Copyright (C) 2011 Google Inc. All rights reserved.
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Library General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public License
21 * along with this library; see the file COPYING.LIB. If not, write to
22 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301, USA.
24 */
25 4
26 #include "core/html/HTMLLinkElement.h" 5 #include "core/html/LinkStyle.h"
27 6
28 #include "bindings/core/v8/ScriptEventListener.h"
29 #include "core/HTMLNames.h"
30 #include "core/css/MediaList.h"
31 #include "core/css/MediaQueryEvaluator.h"
32 #include "core/css/StyleSheetContents.h" 7 #include "core/css/StyleSheetContents.h"
33 #include "core/css/resolver/StyleResolver.h"
34 #include "core/dom/Attribute.h"
35 #include "core/dom/Document.h"
36 #include "core/dom/StyleEngine.h"
37 #include "core/dom/TaskRunnerHelper.h"
38 #include "core/events/Event.h"
39 #include "core/fetch/CSSStyleSheetResource.h" 8 #include "core/fetch/CSSStyleSheetResource.h"
40 #include "core/fetch/FetchRequest.h"
41 #include "core/fetch/ResourceFetcher.h"
42 #include "core/frame/FrameView.h"
43 #include "core/frame/LocalFrame.h" 9 #include "core/frame/LocalFrame.h"
44 #include "core/frame/SubresourceIntegrity.h" 10 #include "core/frame/SubresourceIntegrity.h"
45 #include "core/frame/UseCounter.h"
46 #include "core/frame/csp/ContentSecurityPolicy.h" 11 #include "core/frame/csp/ContentSecurityPolicy.h"
47 #include "core/html/CrossOriginAttribute.h" 12 #include "core/html/CrossOriginAttribute.h"
48 #include "core/html/LinkManifest.h" 13 #include "core/html/HTMLLinkElement.h"
49 #include "core/html/imports/LinkImport.h"
50 #include "core/inspector/ConsoleMessage.h"
51 #include "core/loader/FrameLoader.h"
52 #include "core/loader/FrameLoaderClient.h" 14 #include "core/loader/FrameLoaderClient.h"
53 #include "core/loader/NetworkHintsInterface.h"
54 #include "core/origin_trials/OriginTrials.h"
55 #include "core/style/StyleInheritedData.h"
56 #include "platform/ContentType.h" 15 #include "platform/ContentType.h"
57 #include "platform/Histogram.h" 16 #include "platform/Histogram.h"
58 #include "platform/MIMETypeRegistry.h" 17 #include "platform/MIMETypeRegistry.h"
59 #include "platform/RuntimeEnabledFeatures.h"
60 #include "public/platform/WebIconSizesParser.h"
61 #include "public/platform/WebSize.h"
62 #include "wtf/StdLibExtras.h"
63 18
64 namespace blink { 19 namespace blink {
65 20
66 using namespace HTMLNames; 21 using namespace HTMLNames;
67 22
68 static bool styleSheetTypeIsSupported(const String& type) { 23 static bool styleSheetTypeIsSupported(const String& type) {
69 String trimmedType = ContentType(type).type(); 24 String trimmedType = ContentType(type).type();
70 return trimmedType.isEmpty() || 25 return trimmedType.isEmpty() ||
71 MIMETypeRegistry::isSupportedStyleSheetMIMEType(trimmedType); 26 MIMETypeRegistry::isSupportedStyleSheetMIMEType(trimmedType);
72 } 27 }
73 28
74 inline HTMLLinkElement::HTMLLinkElement(Document& document,
75 bool createdByParser)
76 : HTMLElement(linkTag, document),
77 m_linkLoader(LinkLoader::create(this)),
78 m_sizes(DOMTokenList::create(this)),
79 m_relList(RelList::create(this)),
80 m_createdByParser(createdByParser) {}
81
82 HTMLLinkElement* HTMLLinkElement::create(Document& document,
83 bool createdByParser) {
84 return new HTMLLinkElement(document, createdByParser);
85 }
86
87 HTMLLinkElement::~HTMLLinkElement() {}
88
89 void HTMLLinkElement::parseAttribute(const QualifiedName& name,
90 const AtomicString& oldValue,
91 const AtomicString& value) {
92 if (name == relAttr) {
93 m_relAttribute = LinkRelAttribute(value);
94 m_relList->setRelValues(value);
95 process();
96 } else if (name == hrefAttr) {
97 // Log href attribute before logging resource fetching in process().
98 logUpdateAttributeIfIsolatedWorldAndInDocument("link", hrefAttr, oldValue,
99 value);
100 process();
101 } else if (name == typeAttr) {
102 m_type = value;
103 process();
104 } else if (name == asAttr) {
105 m_as = value;
106 process();
107 } else if (name == sizesAttr) {
108 m_sizes->setValue(value);
109 } else if (name == mediaAttr) {
110 m_media = value.lower();
111 process();
112 } else if (name == scopeAttr) {
113 m_scope = value;
114 process();
115 } else if (name == disabledAttr) {
116 UseCounter::count(document(), UseCounter::HTMLLinkElementDisabled);
117 if (LinkStyle* link = linkStyle())
118 link->setDisabledState(!value.isNull());
119 } else {
120 if (name == titleAttr) {
121 if (LinkStyle* link = linkStyle())
122 link->setSheetTitle(value, StyleEngine::UpdateActiveSheets);
123 }
124
125 HTMLElement::parseAttribute(name, oldValue, value);
126 }
127 }
128
129 bool HTMLLinkElement::shouldLoadLink() {
130 return isInDocumentTree() || (isConnected() && m_relAttribute.isStyleSheet());
131 }
132
133 bool HTMLLinkElement::loadLink(const String& type,
134 const String& as,
135 const String& media,
136 const KURL& url) {
137 return m_linkLoader->loadLink(
138 m_relAttribute,
139 crossOriginAttributeValue(fastGetAttribute(HTMLNames::crossoriginAttr)),
140 type, as, media, url, document(), NetworkHintsInterfaceImpl());
141 }
142
143 LinkResource* HTMLLinkElement::linkResourceToProcess() {
144 if (!shouldLoadLink()) {
145 DCHECK(!linkStyle() || !linkStyle()->hasSheet());
146 return nullptr;
147 }
148
149 if (!m_link) {
150 if (m_relAttribute.isImport()) {
151 m_link = LinkImport::create(this);
152 } else if (m_relAttribute.isManifest()) {
153 m_link = LinkManifest::create(this);
154 } else if (m_relAttribute.isServiceWorker() &&
155 OriginTrials::linkServiceWorkerEnabled(getExecutionContext())) {
156 if (document().frame())
157 m_link = document()
158 .frame()
159 ->loader()
160 .client()
161 ->createServiceWorkerLinkResource(this);
162 } else {
163 LinkStyle* link = LinkStyle::create(this);
164 if (fastHasAttribute(disabledAttr)) {
165 UseCounter::count(document(), UseCounter::HTMLLinkElementDisabled);
166 link->setDisabledState(true);
167 }
168 m_link = link;
169 }
170 }
171
172 return m_link.get();
173 }
174
175 LinkStyle* HTMLLinkElement::linkStyle() const {
176 if (!m_link || m_link->type() != LinkResource::Style)
177 return nullptr;
178 return static_cast<LinkStyle*>(m_link.get());
179 }
180
181 LinkImport* HTMLLinkElement::linkImport() const {
182 if (!m_link || m_link->type() != LinkResource::Import)
183 return nullptr;
184 return static_cast<LinkImport*>(m_link.get());
185 }
186
187 Document* HTMLLinkElement::import() const {
188 if (LinkImport* link = linkImport())
189 return link->importedDocument();
190 return nullptr;
191 }
192
193 void HTMLLinkElement::process() {
194 if (LinkResource* link = linkResourceToProcess())
195 link->process();
196 }
197
198 Node::InsertionNotificationRequest HTMLLinkElement::insertedInto(
199 ContainerNode* insertionPoint) {
200 HTMLElement::insertedInto(insertionPoint);
201 logAddElementIfIsolatedWorldAndInDocument("link", relAttr, hrefAttr);
202 if (!insertionPoint->isConnected())
203 return InsertionDone;
204 DCHECK(isConnected());
205 if (!shouldLoadLink()) {
206 DCHECK(isInShadowTree());
207 String message = "HTML element <link> is ignored in shadow tree.";
208 document().addConsoleMessage(
209 ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message));
210 return InsertionDone;
211 }
212
213 document().styleEngine().addStyleSheetCandidateNode(*this);
214
215 process();
216
217 if (m_link)
218 m_link->ownerInserted();
219
220 return InsertionDone;
221 }
222
223 void HTMLLinkElement::removedFrom(ContainerNode* insertionPoint) {
224 // Store the result of isConnected() here before Node::removedFrom(..) clears
225 // the flags.
226 bool wasConnected = isConnected();
227 HTMLElement::removedFrom(insertionPoint);
228 if (!insertionPoint->isConnected())
229 return;
230
231 m_linkLoader->released();
232
233 if (!wasConnected) {
234 DCHECK(!linkStyle() || !linkStyle()->hasSheet());
235 return;
236 }
237 document().styleEngine().removeStyleSheetCandidateNode(*this);
238
239 StyleSheet* removedSheet = sheet();
240
241 if (m_link)
242 m_link->ownerRemoved();
243
244 document().styleEngine().setNeedsActiveStyleUpdate(removedSheet,
245 FullStyleUpdate);
246 }
247
248 void HTMLLinkElement::finishParsingChildren() {
249 m_createdByParser = false;
250 HTMLElement::finishParsingChildren();
251 }
252
253 bool HTMLLinkElement::styleSheetIsLoading() const {
254 return linkStyle() && linkStyle()->styleSheetIsLoading();
255 }
256
257 void HTMLLinkElement::linkLoaded() {
258 dispatchEvent(Event::create(EventTypeNames::load));
259 }
260
261 void HTMLLinkElement::linkLoadingErrored() {
262 dispatchEvent(Event::create(EventTypeNames::error));
263 }
264
265 void HTMLLinkElement::didStartLinkPrerender() {
266 dispatchEvent(Event::create(EventTypeNames::webkitprerenderstart));
267 }
268
269 void HTMLLinkElement::didStopLinkPrerender() {
270 dispatchEvent(Event::create(EventTypeNames::webkitprerenderstop));
271 }
272
273 void HTMLLinkElement::didSendLoadForLinkPrerender() {
274 dispatchEvent(Event::create(EventTypeNames::webkitprerenderload));
275 }
276
277 void HTMLLinkElement::didSendDOMContentLoadedForLinkPrerender() {
278 dispatchEvent(Event::create(EventTypeNames::webkitprerenderdomcontentloaded));
279 }
280
281 void HTMLLinkElement::valueWasSet() {
282 setSynchronizedLazyAttribute(HTMLNames::sizesAttr, m_sizes->value());
283 WebVector<WebSize> webIconSizes =
284 WebIconSizesParser::parseIconSizes(m_sizes->value());
285 m_iconSizes.resize(webIconSizes.size());
286 for (size_t i = 0; i < webIconSizes.size(); ++i)
287 m_iconSizes[i] = webIconSizes[i];
288 process();
289 }
290
291 bool HTMLLinkElement::sheetLoaded() {
292 DCHECK(linkStyle());
293 return linkStyle()->sheetLoaded();
294 }
295
296 void HTMLLinkElement::notifyLoadedSheetAndAllCriticalSubresources(
297 LoadedSheetErrorStatus errorStatus) {
298 DCHECK(linkStyle());
299 linkStyle()->notifyLoadedSheetAndAllCriticalSubresources(errorStatus);
300 }
301
302 void HTMLLinkElement::dispatchPendingEvent(
303 std::unique_ptr<IncrementLoadEventDelayCount>) {
304 DCHECK(m_link);
305 if (m_link->hasLoaded())
306 linkLoaded();
307 else
308 linkLoadingErrored();
309 }
310
311 void HTMLLinkElement::scheduleEvent() {
312 TaskRunnerHelper::get(TaskType::DOMManipulation, &document())
313 ->postTask(
314 BLINK_FROM_HERE,
315 WTF::bind(&HTMLLinkElement::dispatchPendingEvent,
316 wrapPersistent(this),
317 passed(IncrementLoadEventDelayCount::create(document()))));
318 }
319
320 void HTMLLinkElement::startLoadingDynamicSheet() {
321 DCHECK(linkStyle());
322 linkStyle()->startLoadingDynamicSheet();
323 }
324
325 bool HTMLLinkElement::isURLAttribute(const Attribute& attribute) const {
326 return attribute.name().localName() == hrefAttr ||
327 HTMLElement::isURLAttribute(attribute);
328 }
329
330 bool HTMLLinkElement::hasLegalLinkAttribute(const QualifiedName& name) const {
331 return name == hrefAttr || HTMLElement::hasLegalLinkAttribute(name);
332 }
333
334 const QualifiedName& HTMLLinkElement::subResourceAttributeName() const {
335 // If the link element is not css, ignore it.
336 if (equalIgnoringCase(getAttribute(typeAttr), "text/css")) {
337 // FIXME: Add support for extracting links of sub-resources which
338 // are inside style-sheet such as @import, @font-face, url(), etc.
339 return hrefAttr;
340 }
341 return HTMLElement::subResourceAttributeName();
342 }
343
344 KURL HTMLLinkElement::href() const {
345 return document().completeURL(getAttribute(hrefAttr));
346 }
347
348 const AtomicString& HTMLLinkElement::rel() const {
349 return getAttribute(relAttr);
350 }
351
352 const AtomicString& HTMLLinkElement::type() const {
353 return getAttribute(typeAttr);
354 }
355
356 bool HTMLLinkElement::async() const {
357 return fastHasAttribute(HTMLNames::asyncAttr);
358 }
359
360 IconType HTMLLinkElement::getIconType() const {
361 return m_relAttribute.getIconType();
362 }
363
364 const Vector<IntSize>& HTMLLinkElement::iconSizes() const {
365 return m_iconSizes;
366 }
367
368 DOMTokenList* HTMLLinkElement::sizes() const {
369 return m_sizes.get();
370 }
371
372 DEFINE_TRACE(HTMLLinkElement) {
373 visitor->trace(m_link);
374 visitor->trace(m_sizes);
375 visitor->trace(m_linkLoader);
376 visitor->trace(m_relList);
377 HTMLElement::trace(visitor);
378 LinkLoaderClient::trace(visitor);
379 DOMTokenListObserver::trace(visitor);
380 }
381
382 DEFINE_TRACE_WRAPPERS(HTMLLinkElement) {
383 visitor->traceWrappers(m_relList);
384 HTMLElement::traceWrappers(visitor);
385 }
386
387 LinkStyle* LinkStyle::create(HTMLLinkElement* owner) { 29 LinkStyle* LinkStyle::create(HTMLLinkElement* owner) {
388 return new LinkStyle(owner); 30 return new LinkStyle(owner);
389 } 31 }
390 32
391 LinkStyle::LinkStyle(HTMLLinkElement* owner) 33 LinkStyle::LinkStyle(HTMLLinkElement* owner)
392 : LinkResource(owner), 34 : LinkResource(owner),
393 m_disabledState(Unset), 35 m_disabledState(Unset),
394 m_pendingSheetType(None), 36 m_pendingSheetType(None),
395 m_loading(false), 37 m_loading(false),
396 m_firedLoad(false), 38 m_firedLoad(false),
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 setSheetTitle(m_owner->title()); 155 setSheetTitle(m_owner->title());
514 setCrossOriginStylesheetStatus(m_sheet.get()); 156 setCrossOriginStylesheetStatus(m_sheet.get());
515 157
516 styleSheet->parseAuthorStyleSheet(cachedStyleSheet, 158 styleSheet->parseAuthorStyleSheet(cachedStyleSheet,
517 m_owner->document().getSecurityOrigin()); 159 m_owner->document().getSecurityOrigin());
518 160
519 m_loading = false; 161 m_loading = false;
520 styleSheet->notifyLoadedSheet(cachedStyleSheet); 162 styleSheet->notifyLoadedSheet(cachedStyleSheet);
521 styleSheet->checkLoaded(); 163 styleSheet->checkLoaded();
522 164
523 if (styleSheet->isCacheableForResource()) 165 if (styleSheet->isCacheableForResource()) {
524 const_cast<CSSStyleSheetResource*>(cachedStyleSheet) 166 const_cast<CSSStyleSheetResource*>(cachedStyleSheet)
525 ->saveParsedStyleSheet(styleSheet); 167 ->saveParsedStyleSheet(styleSheet);
168 }
526 clearResource(); 169 clearResource();
527 } 170 }
528 171
529 bool LinkStyle::sheetLoaded() { 172 bool LinkStyle::sheetLoaded() {
530 if (!styleSheetIsLoading()) { 173 if (!styleSheetIsLoading()) {
531 removePendingSheet(); 174 removePendingSheet();
532 return true; 175 return true;
533 } 176 }
534 return false; 177 return false;
535 } 178 }
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 292
650 if (m_owner->relAttribute().getIconType() != InvalidIcon && 293 if (m_owner->relAttribute().getIconType() != InvalidIcon &&
651 builder.url().isValid() && !builder.url().isEmpty()) { 294 builder.url().isValid() && !builder.url().isEmpty()) {
652 if (!m_owner->shouldLoadLink()) 295 if (!m_owner->shouldLoadLink())
653 return; 296 return;
654 if (!document().getSecurityOrigin()->canDisplay(builder.url())) 297 if (!document().getSecurityOrigin()->canDisplay(builder.url()))
655 return; 298 return;
656 if (!document().contentSecurityPolicy()->allowImageFromSource( 299 if (!document().contentSecurityPolicy()->allowImageFromSource(
657 builder.url())) 300 builder.url()))
658 return; 301 return;
659 if (document().frame() && document().frame()->loader().client()) 302 if (document().frame() && document().frame()->loader().client()) {
660 document().frame()->loader().client()->dispatchDidChangeIcons( 303 document().frame()->loader().client()->dispatchDidChangeIcons(
661 m_owner->relAttribute().getIconType()); 304 m_owner->relAttribute().getIconType());
305 }
662 } 306 }
663 307
664 if (!m_owner->loadLink(type, as, media, builder.url())) 308 if (!m_owner->loadLink(type, as, media, builder.url()))
665 return; 309 return;
666 310
667 if (m_disabledState != Disabled && m_owner->relAttribute().isStyleSheet() && 311 if (m_disabledState != Disabled && m_owner->relAttribute().isStyleSheet() &&
668 styleSheetTypeIsSupported(type) && shouldLoadResource() && 312 styleSheetTypeIsSupported(type) && shouldLoadResource() &&
669 builder.url().isValid()) { 313 builder.url().isValid()) {
670 if (resource()) { 314 if (resource()) {
671 removePendingSheet(); 315 removePendingSheet();
672 clearResource(); 316 clearResource();
673 clearFetchFollowingCORS(); 317 clearFetchFollowingCORS();
674 } 318 }
675 319
676 if (!m_owner->shouldLoadLink()) 320 if (!m_owner->shouldLoadLink())
677 return; 321 return;
678 322
679 m_loading = true; 323 m_loading = true;
680 324
681 String title = m_owner->title(); 325 String title = m_owner->title();
682 if (!title.isEmpty() && !m_owner->isAlternate() && 326 if (!title.isEmpty() && !m_owner->isAlternate() &&
683 m_disabledState != EnabledViaScript && m_owner->isInDocumentTree()) 327 m_disabledState != EnabledViaScript && m_owner->isInDocumentTree()) {
684 document().styleEngine().setPreferredStylesheetSetNameIfNotSet( 328 document().styleEngine().setPreferredStylesheetSetNameIfNotSet(
685 title, StyleEngine::DontUpdateActiveSheets); 329 title, StyleEngine::DontUpdateActiveSheets);
330 }
686 331
687 bool mediaQueryMatches = true; 332 bool mediaQueryMatches = true;
688 LocalFrame* frame = loadingFrame(); 333 LocalFrame* frame = loadingFrame();
689 if (!m_owner->media().isEmpty() && frame) { 334 if (!m_owner->media().isEmpty() && frame) {
690 MediaQuerySet* media = MediaQuerySet::create(m_owner->media()); 335 MediaQuerySet* media = MediaQuerySet::create(m_owner->media());
691 MediaQueryEvaluator evaluator(frame); 336 MediaQueryEvaluator evaluator(frame);
692 mediaQueryMatches = evaluator.eval(media); 337 mediaQueryMatches = evaluator.eval(media);
693 } 338 }
694 339
695 // Don't hold up layout tree construction and script execution on 340 // Don't hold up layout tree construction and script execution on
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 if (!m_owner->isInDocumentTree() || !m_owner->relAttribute().isStyleSheet()) 390 if (!m_owner->isInDocumentTree() || !m_owner->relAttribute().isStyleSheet())
746 return; 391 return;
747 392
748 if (m_sheet) 393 if (m_sheet)
749 m_sheet->setTitle(title); 394 m_sheet->setTitle(title);
750 395
751 if (title.isEmpty() || !isUnset() || m_owner->isAlternate()) 396 if (title.isEmpty() || !isUnset() || m_owner->isAlternate())
752 return; 397 return;
753 398
754 KURL href = m_owner->getNonEmptyURLAttribute(hrefAttr); 399 KURL href = m_owner->getNonEmptyURLAttribute(hrefAttr);
755 if (href.isValid() && !href.isEmpty()) 400 if (href.isValid() && !href.isEmpty()) {
756 document().styleEngine().setPreferredStylesheetSetNameIfNotSet( 401 document().styleEngine().setPreferredStylesheetSetNameIfNotSet(
757 title, updateActiveSheets); 402 title, updateActiveSheets);
403 }
758 } 404 }
759 405
760 void LinkStyle::ownerRemoved() { 406 void LinkStyle::ownerRemoved() {
761 if (m_sheet) 407 if (m_sheet)
762 clearSheet(); 408 clearSheet();
763 409
764 if (styleSheetIsLoading()) 410 if (styleSheetIsLoading())
765 removePendingSheet(); 411 removePendingSheet();
766 } 412 }
767 413
768 DEFINE_TRACE(LinkStyle) { 414 DEFINE_TRACE(LinkStyle) {
769 visitor->trace(m_sheet); 415 visitor->trace(m_sheet);
770 LinkResource::trace(visitor); 416 LinkResource::trace(visitor);
771 ResourceOwner<StyleSheetResource>::trace(visitor); 417 ResourceOwner<StyleSheetResource>::trace(visitor);
772 } 418 }
773 419
774 } // namespace blink 420 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/LinkStyle.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698