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

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

Issue 2426513003: Refactor LinkStyle out of HTMLLinkElement (Closed)
Patch Set: 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 reserv ed.
6 * Copyright (C) 2009 Rob Buis (rwlbuis@gmail.com)
7 * Copyright (C) 2011 Google Inc. All rights reserved.
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU Library General Public License
20 * along with this library; see the file COPYING.LIB. If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23 */
24 4
25 #include "core/html/HTMLLinkElement.h" 5 #include "core/html/LinkStyle.h"
26 6
27 #include "bindings/core/v8/ScriptEventListener.h"
28 #include "core/HTMLNames.h"
29 #include "core/css/MediaList.h"
30 #include "core/css/MediaQueryEvaluator.h"
31 #include "core/css/StyleSheetContents.h" 7 #include "core/css/StyleSheetContents.h"
32 #include "core/css/resolver/StyleResolver.h"
33 #include "core/dom/Attribute.h"
34 #include "core/dom/Document.h"
35 #include "core/dom/StyleEngine.h"
36 #include "core/dom/TaskRunnerHelper.h"
37 #include "core/events/Event.h"
38 #include "core/fetch/CSSStyleSheetResource.h" 8 #include "core/fetch/CSSStyleSheetResource.h"
39 #include "core/fetch/FetchRequest.h"
40 #include "core/fetch/ResourceFetcher.h"
41 #include "core/frame/FrameView.h"
42 #include "core/frame/LocalFrame.h" 9 #include "core/frame/LocalFrame.h"
43 #include "core/frame/SubresourceIntegrity.h" 10 #include "core/frame/SubresourceIntegrity.h"
44 #include "core/frame/UseCounter.h"
45 #include "core/frame/csp/ContentSecurityPolicy.h" 11 #include "core/frame/csp/ContentSecurityPolicy.h"
46 #include "core/html/CrossOriginAttribute.h" 12 #include "core/html/CrossOriginAttribute.h"
47 #include "core/html/LinkManifest.h" 13 #include "core/html/HTMLLinkElement.h"
48 #include "core/html/imports/LinkImport.h"
49 #include "core/inspector/ConsoleMessage.h"
50 #include "core/loader/FrameLoader.h"
51 #include "core/loader/FrameLoaderClient.h" 14 #include "core/loader/FrameLoaderClient.h"
52 #include "core/loader/NetworkHintsInterface.h"
53 #include "core/origin_trials/OriginTrials.h"
54 #include "core/style/StyleInheritedData.h"
55 #include "platform/ContentType.h" 15 #include "platform/ContentType.h"
56 #include "platform/Histogram.h" 16 #include "platform/Histogram.h"
57 #include "platform/MIMETypeRegistry.h" 17 #include "platform/MIMETypeRegistry.h"
58 #include "platform/RuntimeEnabledFeatures.h"
59 #include "public/platform/WebIconSizesParser.h"
60 #include "public/platform/WebSize.h"
61 #include "wtf/StdLibExtras.h"
62 18
63 namespace blink { 19 namespace blink {
64 20
65 using namespace HTMLNames; 21 using namespace HTMLNames;
66 22
67 static bool styleSheetTypeIsSupported(const String& type) { 23 static bool styleSheetTypeIsSupported(const String& type) {
68 String trimmedType = ContentType(type).type(); 24 String trimmedType = ContentType(type).type();
69 return trimmedType.isEmpty() || 25 return trimmedType.isEmpty() ||
70 MIMETypeRegistry::isSupportedStyleSheetMIMEType(trimmedType); 26 MIMETypeRegistry::isSupportedStyleSheetMIMEType(trimmedType);
71 } 27 }
72 28
73 inline HTMLLinkElement::HTMLLinkElement(Document& document,
74 bool createdByParser)
75 : HTMLElement(linkTag, document),
76 m_linkLoader(LinkLoader::create(this)),
77 m_sizes(DOMTokenList::create(this)),
78 m_relList(RelList::create(this)),
79 m_createdByParser(createdByParser) {}
80
81 HTMLLinkElement* HTMLLinkElement::create(Document& document,
82 bool createdByParser) {
83 return new HTMLLinkElement(document, createdByParser);
84 }
85
86 HTMLLinkElement::~HTMLLinkElement() {}
87
88 void HTMLLinkElement::parseAttribute(const QualifiedName& name,
89 const AtomicString& oldValue,
90 const AtomicString& value) {
91 if (name == relAttr) {
92 m_relAttribute = LinkRelAttribute(value);
93 m_relList->setRelValues(value);
94 process();
95 } else if (name == hrefAttr) {
96 // Log href attribute before logging resource fetching in process().
97 logUpdateAttributeIfIsolatedWorldAndInDocument("link", hrefAttr, oldValue,
98 value);
99 process();
100 } else if (name == typeAttr) {
101 m_type = value;
102 process();
103 } else if (name == asAttr) {
104 m_as = value;
105 process();
106 } else if (name == sizesAttr) {
107 m_sizes->setValue(value);
108 } else if (name == mediaAttr) {
109 m_media = value.lower();
110 process();
111 } else if (name == scopeAttr) {
112 m_scope = value;
113 process();
114 } else if (name == disabledAttr) {
115 UseCounter::count(document(), UseCounter::HTMLLinkElementDisabled);
116 if (LinkStyle* link = linkStyle())
117 link->setDisabledState(!value.isNull());
118 } else {
119 if (name == titleAttr) {
120 if (LinkStyle* link = linkStyle())
121 link->setSheetTitle(value, StyleEngine::UpdateActiveSheets);
122 }
123
124 HTMLElement::parseAttribute(name, oldValue, value);
125 }
126 }
127
128 bool HTMLLinkElement::shouldLoadLink() {
129 return isInDocumentTree() || (isConnected() && m_relAttribute.isStyleSheet());
130 }
131
132 bool HTMLLinkElement::loadLink(const String& type,
133 const String& as,
134 const String& media,
135 const KURL& url) {
136 return m_linkLoader->loadLink(
137 m_relAttribute,
138 crossOriginAttributeValue(fastGetAttribute(HTMLNames::crossoriginAttr)),
139 type, as, media, url, document(), NetworkHintsInterfaceImpl());
140 }
141
142 LinkResource* HTMLLinkElement::linkResourceToProcess() {
143 if (!shouldLoadLink()) {
144 DCHECK(!linkStyle() || !linkStyle()->hasSheet());
145 return nullptr;
146 }
147
148 if (!m_link) {
149 if (m_relAttribute.isImport()) {
150 m_link = LinkImport::create(this);
151 } else if (m_relAttribute.isManifest()) {
152 m_link = LinkManifest::create(this);
153 } else if (m_relAttribute.isServiceWorker() &&
154 OriginTrials::linkServiceWorkerEnabled(getExecutionContext())) {
155 if (document().frame())
156 m_link = document()
157 .frame()
158 ->loader()
159 .client()
160 ->createServiceWorkerLinkResource(this);
161 } else {
162 LinkStyle* link = LinkStyle::create(this);
163 if (fastHasAttribute(disabledAttr)) {
164 UseCounter::count(document(), UseCounter::HTMLLinkElementDisabled);
165 link->setDisabledState(true);
166 }
167 m_link = link;
168 }
169 }
170
171 return m_link.get();
172 }
173
174 LinkStyle* HTMLLinkElement::linkStyle() const {
175 if (!m_link || m_link->type() != LinkResource::Style)
176 return nullptr;
177 return static_cast<LinkStyle*>(m_link.get());
178 }
179
180 LinkImport* HTMLLinkElement::linkImport() const {
181 if (!m_link || m_link->type() != LinkResource::Import)
182 return nullptr;
183 return static_cast<LinkImport*>(m_link.get());
184 }
185
186 Document* HTMLLinkElement::import() const {
187 if (LinkImport* link = linkImport())
188 return link->importedDocument();
189 return nullptr;
190 }
191
192 void HTMLLinkElement::process() {
193 if (LinkResource* link = linkResourceToProcess())
194 link->process();
195 }
196
197 Node::InsertionNotificationRequest HTMLLinkElement::insertedInto(
198 ContainerNode* insertionPoint) {
199 HTMLElement::insertedInto(insertionPoint);
200 logAddElementIfIsolatedWorldAndInDocument("link", relAttr, hrefAttr);
201 if (!insertionPoint->isConnected())
202 return InsertionDone;
203 DCHECK(isConnected());
204 if (!shouldLoadLink()) {
205 DCHECK(isInShadowTree());
206 String message = "HTML element <link> is ignored in shadow tree.";
207 document().addConsoleMessage(
208 ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message));
209 return InsertionDone;
210 }
211
212 document().styleEngine().addStyleSheetCandidateNode(*this);
213
214 process();
215
216 if (m_link)
217 m_link->ownerInserted();
218
219 return InsertionDone;
220 }
221
222 void HTMLLinkElement::removedFrom(ContainerNode* insertionPoint) {
223 // Store the result of isConnected() here before Node::removedFrom(..) clears the flags.
224 bool wasConnected = isConnected();
225 HTMLElement::removedFrom(insertionPoint);
226 if (!insertionPoint->isConnected())
227 return;
228
229 m_linkLoader->released();
230
231 if (!wasConnected) {
232 DCHECK(!linkStyle() || !linkStyle()->hasSheet());
233 return;
234 }
235 document().styleEngine().removeStyleSheetCandidateNode(*this);
236
237 StyleSheet* removedSheet = sheet();
238
239 if (m_link)
240 m_link->ownerRemoved();
241
242 document().styleEngine().setNeedsActiveStyleUpdate(removedSheet,
243 FullStyleUpdate);
244 }
245
246 void HTMLLinkElement::finishParsingChildren() {
247 m_createdByParser = false;
248 HTMLElement::finishParsingChildren();
249 }
250
251 bool HTMLLinkElement::styleSheetIsLoading() const {
252 return linkStyle() && linkStyle()->styleSheetIsLoading();
253 }
254
255 void HTMLLinkElement::linkLoaded() {
256 dispatchEvent(Event::create(EventTypeNames::load));
257 }
258
259 void HTMLLinkElement::linkLoadingErrored() {
260 dispatchEvent(Event::create(EventTypeNames::error));
261 }
262
263 void HTMLLinkElement::didStartLinkPrerender() {
264 dispatchEvent(Event::create(EventTypeNames::webkitprerenderstart));
265 }
266
267 void HTMLLinkElement::didStopLinkPrerender() {
268 dispatchEvent(Event::create(EventTypeNames::webkitprerenderstop));
269 }
270
271 void HTMLLinkElement::didSendLoadForLinkPrerender() {
272 dispatchEvent(Event::create(EventTypeNames::webkitprerenderload));
273 }
274
275 void HTMLLinkElement::didSendDOMContentLoadedForLinkPrerender() {
276 dispatchEvent(Event::create(EventTypeNames::webkitprerenderdomcontentloaded));
277 }
278
279 void HTMLLinkElement::valueWasSet() {
280 setSynchronizedLazyAttribute(HTMLNames::sizesAttr, m_sizes->value());
281 WebVector<WebSize> webIconSizes =
282 WebIconSizesParser::parseIconSizes(m_sizes->value());
283 m_iconSizes.resize(webIconSizes.size());
284 for (size_t i = 0; i < webIconSizes.size(); ++i)
285 m_iconSizes[i] = webIconSizes[i];
286 process();
287 }
288
289 bool HTMLLinkElement::sheetLoaded() {
290 DCHECK(linkStyle());
291 return linkStyle()->sheetLoaded();
292 }
293
294 void HTMLLinkElement::notifyLoadedSheetAndAllCriticalSubresources(
295 LoadedSheetErrorStatus errorStatus) {
296 DCHECK(linkStyle());
297 linkStyle()->notifyLoadedSheetAndAllCriticalSubresources(errorStatus);
298 }
299
300 void HTMLLinkElement::dispatchPendingEvent(
301 std::unique_ptr<IncrementLoadEventDelayCount>) {
302 DCHECK(m_link);
303 if (m_link->hasLoaded())
304 linkLoaded();
305 else
306 linkLoadingErrored();
307 }
308
309 void HTMLLinkElement::scheduleEvent() {
310 TaskRunnerHelper::get(TaskType::DOMManipulation, &document())
311 ->postTask(
312 BLINK_FROM_HERE,
313 WTF::bind(&HTMLLinkElement::dispatchPendingEvent,
314 wrapPersistent(this),
315 passed(IncrementLoadEventDelayCount::create(document()))));
316 }
317
318 void HTMLLinkElement::startLoadingDynamicSheet() {
319 DCHECK(linkStyle());
320 linkStyle()->startLoadingDynamicSheet();
321 }
322
323 bool HTMLLinkElement::isURLAttribute(const Attribute& attribute) const {
324 return attribute.name().localName() == hrefAttr ||
325 HTMLElement::isURLAttribute(attribute);
326 }
327
328 bool HTMLLinkElement::hasLegalLinkAttribute(const QualifiedName& name) const {
329 return name == hrefAttr || HTMLElement::hasLegalLinkAttribute(name);
330 }
331
332 const QualifiedName& HTMLLinkElement::subResourceAttributeName() const {
333 // If the link element is not css, ignore it.
334 if (equalIgnoringCase(getAttribute(typeAttr), "text/css")) {
335 // FIXME: Add support for extracting links of sub-resources which
336 // are inside style-sheet such as @import, @font-face, url(), etc.
337 return hrefAttr;
338 }
339 return HTMLElement::subResourceAttributeName();
340 }
341
342 KURL HTMLLinkElement::href() const {
343 return document().completeURL(getAttribute(hrefAttr));
344 }
345
346 const AtomicString& HTMLLinkElement::rel() const {
347 return getAttribute(relAttr);
348 }
349
350 const AtomicString& HTMLLinkElement::type() const {
351 return getAttribute(typeAttr);
352 }
353
354 bool HTMLLinkElement::async() const {
355 return fastHasAttribute(HTMLNames::asyncAttr);
356 }
357
358 IconType HTMLLinkElement::getIconType() const {
359 return m_relAttribute.getIconType();
360 }
361
362 const Vector<IntSize>& HTMLLinkElement::iconSizes() const {
363 return m_iconSizes;
364 }
365
366 DOMTokenList* HTMLLinkElement::sizes() const {
367 return m_sizes.get();
368 }
369
370 DEFINE_TRACE(HTMLLinkElement) {
371 visitor->trace(m_link);
372 visitor->trace(m_sizes);
373 visitor->trace(m_linkLoader);
374 visitor->trace(m_relList);
375 HTMLElement::trace(visitor);
376 LinkLoaderClient::trace(visitor);
377 DOMTokenListObserver::trace(visitor);
378 }
379
380 DEFINE_TRACE_WRAPPERS(HTMLLinkElement) {
381 visitor->traceWrappers(m_relList);
382 HTMLElement::traceWrappers(visitor);
383 }
384
385 LinkStyle* LinkStyle::create(HTMLLinkElement* owner) { 29 LinkStyle* LinkStyle::create(HTMLLinkElement* owner) {
386 return new LinkStyle(owner); 30 return new LinkStyle(owner);
387 } 31 }
388 32
389 LinkStyle::LinkStyle(HTMLLinkElement* owner) 33 LinkStyle::LinkStyle(HTMLLinkElement* owner)
390 : LinkResource(owner), 34 : LinkResource(owner),
391 m_disabledState(Unset), 35 m_disabledState(Unset),
392 m_pendingSheetType(None), 36 m_pendingSheetType(None),
393 m_loading(false), 37 m_loading(false),
394 m_firedLoad(false), 38 m_firedLoad(false),
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 setSheetTitle(m_owner->title()); 131 setSheetTitle(m_owner->title());
488 setCrossOriginStylesheetStatus(m_sheet.get()); 132 setCrossOriginStylesheetStatus(m_sheet.get());
489 133
490 styleSheet->parseAuthorStyleSheet(cachedStyleSheet, 134 styleSheet->parseAuthorStyleSheet(cachedStyleSheet,
491 m_owner->document().getSecurityOrigin()); 135 m_owner->document().getSecurityOrigin());
492 136
493 m_loading = false; 137 m_loading = false;
494 styleSheet->notifyLoadedSheet(cachedStyleSheet); 138 styleSheet->notifyLoadedSheet(cachedStyleSheet);
495 styleSheet->checkLoaded(); 139 styleSheet->checkLoaded();
496 140
497 if (styleSheet->isCacheableForResource()) 141 if (styleSheet->isCacheableForResource()) {
498 const_cast<CSSStyleSheetResource*>(cachedStyleSheet) 142 const_cast<CSSStyleSheetResource*>(cachedStyleSheet)
499 ->saveParsedStyleSheet(styleSheet); 143 ->saveParsedStyleSheet(styleSheet);
144 }
500 clearResource(); 145 clearResource();
501 } 146 }
502 147
503 bool LinkStyle::sheetLoaded() { 148 bool LinkStyle::sheetLoaded() {
504 if (!styleSheetIsLoading()) { 149 if (!styleSheetIsLoading()) {
505 removePendingSheet(); 150 removePendingSheet();
506 return true; 151 return true;
507 } 152 }
508 return false; 153 return false;
509 } 154 }
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 267
623 if (m_owner->relAttribute().getIconType() != InvalidIcon && 268 if (m_owner->relAttribute().getIconType() != InvalidIcon &&
624 builder.url().isValid() && !builder.url().isEmpty()) { 269 builder.url().isValid() && !builder.url().isEmpty()) {
625 if (!m_owner->shouldLoadLink()) 270 if (!m_owner->shouldLoadLink())
626 return; 271 return;
627 if (!document().getSecurityOrigin()->canDisplay(builder.url())) 272 if (!document().getSecurityOrigin()->canDisplay(builder.url()))
628 return; 273 return;
629 if (!document().contentSecurityPolicy()->allowImageFromSource( 274 if (!document().contentSecurityPolicy()->allowImageFromSource(
630 builder.url())) 275 builder.url()))
631 return; 276 return;
632 if (document().frame() && document().frame()->loader().client()) 277 if (document().frame() && document().frame()->loader().client()) {
633 document().frame()->loader().client()->dispatchDidChangeIcons( 278 document().frame()->loader().client()->dispatchDidChangeIcons(
634 m_owner->relAttribute().getIconType()); 279 m_owner->relAttribute().getIconType());
280 }
635 } 281 }
636 282
637 if (!m_owner->loadLink(type, as, media, builder.url())) 283 if (!m_owner->loadLink(type, as, media, builder.url()))
638 return; 284 return;
639 285
640 if (m_disabledState != Disabled && m_owner->relAttribute().isStyleSheet() && 286 if (m_disabledState != Disabled && m_owner->relAttribute().isStyleSheet() &&
641 styleSheetTypeIsSupported(type) && shouldLoadResource() && 287 styleSheetTypeIsSupported(type) && shouldLoadResource() &&
642 builder.url().isValid()) { 288 builder.url().isValid()) {
643 if (resource()) { 289 if (resource()) {
644 removePendingSheet(); 290 removePendingSheet();
645 clearResource(); 291 clearResource();
646 clearFetchFollowingCORS(); 292 clearFetchFollowingCORS();
647 } 293 }
648 294
649 if (!m_owner->shouldLoadLink()) 295 if (!m_owner->shouldLoadLink())
650 return; 296 return;
651 297
652 m_loading = true; 298 m_loading = true;
653 299
654 String title = m_owner->title(); 300 String title = m_owner->title();
655 if (!title.isEmpty() && !m_owner->isAlternate() && 301 if (!title.isEmpty() && !m_owner->isAlternate() &&
656 m_disabledState != EnabledViaScript && m_owner->isInDocumentTree()) 302 m_disabledState != EnabledViaScript && m_owner->isInDocumentTree()) {
657 document().styleEngine().setPreferredStylesheetSetNameIfNotSet( 303 document().styleEngine().setPreferredStylesheetSetNameIfNotSet(
658 title, StyleEngine::DontUpdateActiveSheets); 304 title, StyleEngine::DontUpdateActiveSheets);
305 }
659 306
660 bool mediaQueryMatches = true; 307 bool mediaQueryMatches = true;
661 LocalFrame* frame = loadingFrame(); 308 LocalFrame* frame = loadingFrame();
662 if (!m_owner->media().isEmpty() && frame) { 309 if (!m_owner->media().isEmpty() && frame) {
663 MediaQuerySet* media = MediaQuerySet::create(m_owner->media()); 310 MediaQuerySet* media = MediaQuerySet::create(m_owner->media());
664 MediaQueryEvaluator evaluator(frame); 311 MediaQueryEvaluator evaluator(frame);
665 mediaQueryMatches = evaluator.eval(media); 312 mediaQueryMatches = evaluator.eval(media);
666 } 313 }
667 314
668 // Don't hold up layout tree construction and script execution on stylesheet s 315 // Don't hold up layout tree construction and script execution on stylesheet s
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 if (!m_owner->isInDocumentTree() || !m_owner->relAttribute().isStyleSheet()) 361 if (!m_owner->isInDocumentTree() || !m_owner->relAttribute().isStyleSheet())
715 return; 362 return;
716 363
717 if (m_sheet) 364 if (m_sheet)
718 m_sheet->setTitle(title); 365 m_sheet->setTitle(title);
719 366
720 if (title.isEmpty() || !isUnset() || m_owner->isAlternate()) 367 if (title.isEmpty() || !isUnset() || m_owner->isAlternate())
721 return; 368 return;
722 369
723 KURL href = m_owner->getNonEmptyURLAttribute(hrefAttr); 370 KURL href = m_owner->getNonEmptyURLAttribute(hrefAttr);
724 if (href.isValid() && !href.isEmpty()) 371 if (href.isValid() && !href.isEmpty()) {
725 document().styleEngine().setPreferredStylesheetSetNameIfNotSet( 372 document().styleEngine().setPreferredStylesheetSetNameIfNotSet(
726 title, updateActiveSheets); 373 title, updateActiveSheets);
374 }
727 } 375 }
728 376
729 void LinkStyle::ownerRemoved() { 377 void LinkStyle::ownerRemoved() {
730 if (m_sheet) 378 if (m_sheet)
731 clearSheet(); 379 clearSheet();
732 380
733 if (styleSheetIsLoading()) 381 if (styleSheetIsLoading())
734 removePendingSheet(); 382 removePendingSheet();
735 } 383 }
736 384
737 DEFINE_TRACE(LinkStyle) {
Charlie Harrison 2016/10/17 21:26:35 I think you still need this?
Yoav Weiss 2016/10/18 21:03:22 Yeah, it stayed on HTMLLinkElement, which doesn't
738 visitor->trace(m_sheet);
739 LinkResource::trace(visitor);
740 ResourceOwner<StyleSheetResource>::trace(visitor);
741 }
742
743 } // namespace blink 385 } // 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