OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | |
4 * (C) 2001 Dirk Mueller (mueller@kde.org) | |
5 * Copyright (C) 2003, 2010 Apple Inc. All rights reserved. | |
6 * Copyright (C) 2013 Intel Corporation. All rights reserved. | |
7 * | |
8 * This library is free software; you can redistribute it and/or | |
9 * modify it under the terms of the GNU Library General Public | |
10 * License as published by the Free Software Foundation; either | |
11 * version 2 of the License, or (at your option) any later version. | |
12 * | |
13 * This library is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 * Library General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU Library General Public License | |
19 * along with this library; see the file COPYING.LIB. If not, write to | |
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
21 * Boston, MA 02110-1301, USA. | |
22 */ | |
23 | |
24 #include "config.h" | |
25 #include "core/html/HTMLMetaElement.h" | |
26 | |
27 #include "HTMLNames.h" | |
28 #include "RuntimeEnabledFeatures.h" | |
29 #include "core/css/CSSStyleSheet.h" | |
30 #include "core/css/CSSValuePool.h" | |
31 #include "core/css/MediaList.h" | |
32 #include "core/css/StylePropertySet.h" | |
33 #include "core/css/StyleSheetContents.h" | |
34 #include "core/dom/Document.h" | |
35 #include "core/dom/DocumentStyleSheetCollection.h" | |
36 #include "wtf/text/TextPosition.h" | |
37 | |
38 namespace WebCore { | |
39 | |
40 using namespace HTMLNames; | |
41 using namespace std; | |
42 | |
43 inline HTMLMetaElement::HTMLMetaElement(const QualifiedName& tagName, Document* document) | |
44 : HTMLElement(tagName, document) | |
45 { | |
46 ASSERT(hasTagName(metaTag)); | |
47 ScriptWrappable::init(this); | |
48 } | |
49 | |
50 HTMLMetaElement::~HTMLMetaElement() | |
51 { | |
52 removeStyleSheet(); | |
53 } | |
54 | |
55 PassRefPtr<HTMLMetaElement> HTMLMetaElement::create(Document* document) | |
56 { | |
57 return adoptRef(new HTMLMetaElement(metaTag, document)); | |
58 } | |
59 | |
60 PassRefPtr<HTMLMetaElement> HTMLMetaElement::create(const QualifiedName& tagName , Document* document) | |
61 { | |
62 return adoptRef(new HTMLMetaElement(tagName, document)); | |
63 } | |
64 | |
65 void HTMLMetaElement::removedFrom(ContainerNode* insertionPoint) | |
66 { | |
67 HTMLElement::removedFrom(insertionPoint); | |
68 removeStyleSheet(); | |
69 } | |
70 | |
71 Node::InsertionNotificationRequest HTMLMetaElement::insertedInto(ContainerNode* insertionPoint) | |
72 { | |
73 HTMLElement::insertedInto(insertionPoint); | |
74 if (insertionPoint->inDocument()) | |
75 process(); | |
76 return InsertionDone; | |
77 } | |
78 | |
79 | |
80 static inline bool isValueSeparator(UChar c, bool* ok) | |
81 { | |
82 if (ok && c == ';') | |
83 *ok = false; | |
84 // Though isspace() considers \t and \v to be whitespace, Win IE doesn't. | |
85 return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '=' || c == ' ,' || c == '\0'; | |
86 } | |
87 | |
88 static inline bool isPropertySeparator(UChar c, bool* ok) | |
89 { | |
90 if (ok && c == ';') | |
91 *ok = false; | |
92 return c == ','; | |
93 } | |
94 | |
95 float HTMLMetaElement::parsePositiveNumber(const String& property, const String& value, float minValue, float maxValue) | |
96 { | |
97 size_t parsedLength; | |
98 float rawValue; | |
99 float fValue; | |
100 if (value.is8Bit()) | |
101 rawValue = charactersToFloat(value.characters8(), value.length(), parsed Length); | |
102 else | |
103 rawValue = charactersToFloat(value.characters16(), value.length(), parse dLength); | |
104 | |
105 if (!parsedLength || rawValue < 0) { | |
106 reportError(InvalidValueError, property, value); | |
107 return -1; | |
108 } | |
109 | |
110 if (parsedLength < value.length()) | |
111 reportError(TruncatedValueError, property, value); | |
112 | |
113 fValue = min(maxValue, max(rawValue, minValue)); | |
114 if (fValue != rawValue) | |
115 reportError(OutOfBoundsValueError, property, value); | |
116 | |
117 return fValue; | |
118 } | |
119 | |
120 void HTMLMetaElement::reportError(ErrorType error, const String& property, const String& value) | |
121 { | |
122 StringBuilder builder; | |
123 | |
124 switch (error) { | |
125 case NoError: | |
126 return; | |
127 | |
128 case InvalidPropertySeparatorError: | |
129 builder.appendLiteral("Note that ';' is not a property separator. The li st should be comma-separated."); | |
130 break; | |
131 | |
132 case InvalidPropertyError: | |
133 builder.appendLiteral("Property \""); | |
134 builder.append(property); | |
135 builder.appendLiteral("\" not recognized and ignored."); | |
136 break; | |
137 | |
138 case InvalidValueError: | |
139 case OutOfBoundsValueError: | |
140 case TruncatedValueError: | |
141 if (!value.isEmpty()) { | |
142 builder.appendLiteral("The value \""); | |
143 builder.append(value); | |
144 builder.append('\"'); | |
145 } else { | |
146 builder.appendLiteral("The empty value"); | |
147 } | |
148 | |
149 if (!property.isNull()) { | |
150 builder.appendLiteral(" for property \""); | |
151 builder.append(property); | |
152 builder.append('\"'); | |
153 } | |
154 | |
155 if (error == InvalidValueError) | |
156 builder.appendLiteral(" is invalid and the property has been ignored ."); | |
157 else if (error == OutOfBoundsValueError) | |
158 builder.appendLiteral(" is out of bounds and the value has been clam ped."); | |
159 else | |
160 builder.appendLiteral(" was truncated to its numeric prefix."); | |
161 break; | |
162 | |
163 default: | |
164 ASSERT_NOT_REACHED(); | |
165 } | |
166 | |
167 document()->addConsoleMessage(MetaContentMessageSource, WarningMessageLevel, builder.toString()); | |
168 } | |
169 | |
170 void HTMLMetaElement::parseContentAttribute(MutableStylePropertySet* properties, const String& content, PropertyCollector callback) | |
171 { | |
172 bool ok = true; | |
173 | |
174 // Tread lightly in this code -- it was specifically designed to mimic Win I E's parsing behavior. | |
175 int keyBegin, keyEnd; | |
176 int valueBegin, valueEnd; | |
177 | |
178 int i = 0; | |
179 int length = content.length(); | |
180 String buffer = content.lower(); | |
181 while (i < length) { | |
182 // Skip to first non-separator, but don't skip past the end of the strin g. | |
183 while (isValueSeparator(buffer[i], &ok)) { | |
184 if (i >= length) | |
185 break; | |
186 i++; | |
187 } | |
188 keyBegin = i; | |
189 | |
190 // skip to first separator | |
191 while (!isValueSeparator(buffer[i], &ok)) | |
192 i++; | |
193 keyEnd = i; | |
194 | |
195 // Skip to first '=', but don't skip past a ',' or the end of the string . | |
196 while (buffer[i] != '=') { | |
197 if (isPropertySeparator(buffer[i], &ok) || i >= length) | |
198 break; | |
199 i++; | |
200 } | |
201 | |
202 // Skip to first non-separator, but don't skip past a ',' or the end of the string. | |
203 while (isValueSeparator(buffer[i], &ok)) { | |
204 if (isPropertySeparator(buffer[i], &ok) || i >= length) | |
205 break; | |
206 i++; | |
207 } | |
208 valueBegin = i; | |
209 | |
210 // Skip to first separator. | |
211 while (!isValueSeparator(buffer[i], &ok)) | |
212 i++; | |
213 valueEnd = i; | |
214 | |
215 ASSERT_WITH_SECURITY_IMPLICATION(i <= length); | |
216 | |
217 String propertyString = buffer.substring(keyBegin, keyEnd - keyBegin); | |
218 String valueString = buffer.substring(valueBegin, valueEnd - valueBegin) ; | |
219 | |
220 callback(this, properties, propertyString, valueString); | |
221 } | |
222 if (!ok) | |
223 reportError(InvalidPropertySeparatorError, String(), String()); | |
224 } | |
225 | |
226 PassRefPtr<CSSValue> HTMLMetaElement::parseViewportValueAsLength(const String& p ropertyString, const String& valueString) | |
227 { | |
228 const UChar* characters; | |
229 unsigned valueLength = valueString.length(); | |
230 | |
231 const unsigned longestValueLength = 13; | |
232 UChar characterBuffer[longestValueLength]; | |
233 if (valueString.is8Bit()) { | |
234 unsigned length = std::min(longestValueLength, valueLength); | |
235 const LChar* characters8 = valueString.characters8(); | |
236 for (unsigned i = 0; i < length; ++i) | |
237 characterBuffer[i] = characters8[i]; | |
238 characters = characterBuffer; | |
239 } else { | |
240 characters = valueString.characters16(); | |
241 } | |
242 | |
243 SWITCH(characters, valueLength) { | |
244 CASE("device-width") { | |
245 return cssValuePool().createValue(100, CSSPrimitiveValue::CSS_PERCEN TAGE); | |
246 } | |
247 CASE("device-height") { | |
248 return cssValuePool().createValue(100, CSSPrimitiveValue::CSS_PERCEN TAGE); | |
249 } | |
250 } | |
251 | |
252 // Other keywords and unknown values translate to 1px. | |
253 float value = parsePositiveNumber(propertyString, valueString, float(1), flo at(10000)); | |
254 if (value >= 0) | |
255 return cssValuePool().createValue(value, CSSPrimitiveValue::CSS_PX); | |
256 | |
257 return 0; | |
258 } | |
259 | |
260 PassRefPtr<CSSValue> HTMLMetaElement::parseViewportValueAsZoom(const String& pro pertyString, const String& valueString) | |
261 { | |
262 const UChar* characters; | |
263 unsigned valueLength = valueString.length(); | |
264 | |
265 const unsigned longestValueLength = 13; | |
266 UChar characterBuffer[longestValueLength]; | |
267 if (valueString.is8Bit()) { | |
268 unsigned length = std::min(longestValueLength, valueLength); | |
269 const LChar* characters8 = valueString.characters8(); | |
270 for (unsigned i = 0; i < length; ++i) | |
271 characterBuffer[i] = characters8[i]; | |
272 characters = characterBuffer; | |
273 } else { | |
274 characters = valueString.characters16(); | |
275 } | |
276 | |
277 float value = -1; | |
278 SWITCH(characters, valueLength) { | |
279 CASE("yes") { | |
280 value = 1; | |
281 } | |
282 CASE("no") { | |
283 value = 0.1; | |
284 } | |
285 CASE("device-width") { | |
286 value = 10; | |
287 } | |
288 CASE("device-height") { | |
289 value = 10; | |
290 } | |
291 } | |
292 | |
293 if (value < 0) | |
294 value = parsePositiveNumber(propertyString, valueString, float(0.1), flo at(10)); | |
295 if (value >= 0) | |
296 return cssValuePool().createValue(value, CSSPrimitiveValue::CSS_NUMBER); | |
297 | |
298 return 0; | |
299 } | |
300 | |
301 CSSValueID HTMLMetaElement::parseViewportValueAsUserZoom(const String& propertyS tring, const String& valueString) | |
302 { | |
303 const UChar* characters; | |
304 unsigned valueLength = valueString.length(); | |
305 | |
306 const unsigned longestValueLength = 13; | |
307 UChar characterBuffer[longestValueLength]; | |
308 if (valueString.is8Bit()) { | |
309 unsigned length = std::min(longestValueLength, valueLength); | |
310 const LChar* characters8 = valueString.characters8(); | |
311 for (unsigned i = 0; i < length; ++i) | |
312 characterBuffer[i] = characters8[i]; | |
313 characters = characterBuffer; | |
314 } else { | |
315 characters = valueString.characters16(); | |
316 } | |
317 | |
318 SWITCH(characters, valueLength) { | |
319 CASE("yes") { | |
320 return CSSValueZoom; | |
321 } | |
322 CASE("no") { | |
323 return CSSValueFixed; | |
324 } | |
325 CASE("device-width") { | |
326 return CSSValueZoom; | |
327 } | |
328 CASE("device-height") { | |
329 return CSSValueZoom; | |
330 } | |
331 } | |
332 | |
333 float value = parsePositiveNumber(propertyString, valueString, float(0), flo at(1)); | |
334 // Numbers in the range <-1, 1>, and unknown values (represented as 0), are mapped to "fixed". | |
apavlov
2013/07/30 12:06:45
You should use (-1, 1) to denote the open interval
| |
335 // Numbers >= 1, numbers <= -1 are mapped to "zoom" | |
336 return (value > -1 && value < 1) ? CSSValueFixed : CSSValueZoom; | |
337 } | |
338 | |
339 PassRefPtr<CSSValue> HTMLMetaElement::parseViewportValueAsDPI(const String& prop ertyString, const String& valueString) | |
340 { | |
341 const UChar* characters; | |
342 unsigned valueLength = valueString.length(); | |
343 | |
344 const unsigned longestValueLength = 10; | |
345 UChar characterBuffer[longestValueLength]; | |
346 if (valueString.is8Bit()) { | |
347 unsigned length = std::min(longestValueLength, valueLength); | |
348 const LChar* characters8 = valueString.characters8(); | |
349 for (unsigned i = 0; i < length; ++i) | |
350 characterBuffer[i] = characters8[i]; | |
351 characters = characterBuffer; | |
352 } else { | |
353 characters = valueString.characters16(); | |
354 } | |
355 | |
356 CSSValueID id = CSSValueAuto; // Fallback for invalid. | |
357 SWITCH(characters, valueLength) { | |
358 CASE("device-dpi") { | |
359 id = CSSValueDevice; | |
360 } | |
361 CASE("low-dpi") { | |
362 id = CSSValueSmall; | |
363 } | |
364 CASE("medium-dpi") { | |
365 id = CSSValueMedium; | |
366 } | |
367 CASE("high-dpi") { | |
368 id = CSSValueLarge; | |
369 } | |
370 } | |
371 | |
372 if (id == CSSValueAuto) { | |
373 float value = parsePositiveNumber(propertyString, valueString, float(70) , float(400)); | |
374 | |
375 if (value >= 70 && value <= 400) | |
376 return cssValuePool().createValue(value, CSSPrimitiveValue::CSS_NUMB ER); | |
377 } | |
378 | |
379 return cssValuePool().createIdentifierValue(id); | |
380 } | |
381 | |
382 void HTMLMetaElement::viewportPropertyCollector(HTMLMetaElement* self, MutableSt ylePropertySet* properties, const String& propertyString, const String& valueStr ing) | |
383 { | |
384 const UChar* characters; | |
385 unsigned propertyLength = propertyString.length(); | |
386 | |
387 const unsigned longestPropertyLength = 17; | |
388 UChar characterBuffer[longestPropertyLength]; | |
389 if (propertyString.is8Bit()) { | |
390 unsigned length = std::min(longestPropertyLength, propertyLength); | |
391 const LChar* characters8 = propertyString.characters8(); | |
392 for (unsigned i = 0; i < length; ++i) | |
393 characterBuffer[i] = characters8[i]; | |
394 characters = characterBuffer; | |
395 } else { | |
396 characters = propertyString.characters16(); | |
397 } | |
398 | |
399 SWITCH(characters, propertyLength) { | |
400 CASE("width") { | |
401 RefPtr<CSSValue> value = self->parseViewportValueAsLength(propertySt ring, valueString); | |
402 if (!value) | |
403 return; | |
404 properties->setProperty(CSSPropertyMinWidth, CSSValueExtendToZoom); | |
405 properties->setProperty(CSSPropertyMaxWidth, value); | |
406 return; | |
407 } | |
408 CASE("height") { | |
409 RefPtr<CSSValue> value = self->parseViewportValueAsLength(propertySt ring, valueString); | |
410 if (!value) | |
411 return; | |
412 properties->setProperty(CSSPropertyMinHeight, CSSValueExtendToZoom); | |
413 properties->setProperty(CSSPropertyMaxHeight, value); | |
414 return; | |
415 } | |
416 CASE("initial-scale") { | |
417 if (RefPtr<CSSValue> value = self->parseViewportValueAsZoom(property String, valueString)) | |
418 properties->setProperty(CSSPropertyZoom, value); | |
419 return; | |
420 } | |
421 CASE("minimum-scale") { | |
422 if (RefPtr<CSSValue> value = self->parseViewportValueAsZoom(property String, valueString)) | |
423 properties->setProperty(CSSPropertyMinZoom, value); | |
424 return; | |
425 } | |
426 CASE("maximum-scale") { | |
427 if (RefPtr<CSSValue> value = self->parseViewportValueAsZoom(property String, valueString)) | |
428 properties->setProperty(CSSPropertyMaxZoom, value); | |
429 return; | |
430 } | |
431 CASE("user-scalable") { | |
432 CSSValueID value = self->parseViewportValueAsUserZoom(propertyString , valueString); | |
433 properties->setProperty(CSSPropertyUserZoom, value); | |
434 return; | |
435 } | |
436 CASE("target-densitydpi") { | |
437 RefPtr<CSSValue> value = self->parseViewportValueAsDPI(propertyStrin g, valueString); | |
438 properties->setProperty(CSSPropertyInternalTargetDensity, value); | |
439 return; | |
440 } | |
441 } | |
442 self->reportError(InvalidPropertyError, propertyString, String()); | |
443 } | |
444 | |
445 PassRefPtr<StyleRuleBase> HTMLMetaElement::parseViewportContent(const String& co ntentValue) | |
446 { | |
447 RefPtr<StyleRuleViewport> rule = StyleRuleViewport::create(); | |
448 RefPtr<MutableStylePropertySet> properties = MutableStylePropertySet::create (CSSStrictMode); | |
449 parseContentAttribute(properties.get(), contentValue, &HTMLMetaElement::view portPropertyCollector); | |
450 | |
451 // For a viewport META element that translates into an @viewport rule with a | |
452 // non-"auto" "zoom" declaration and no "width" declaration: | |
453 // If it adds a "height" descriptor, add: width: auto; Otherwise, add: width : extend-to-zoom; | |
454 RefPtr<CSSValue> widthValue = properties->getPropertyCSSValue(CSSPropertyMin Width); | |
455 RefPtr<CSSValue> zoomValue = properties->getPropertyCSSValue(CSSPropertyZoom ); | |
456 | |
457 if (!widthValue && zoomValue) { | |
458 RefPtr<CSSValue> heightValue = properties->getPropertyCSSValue(CSSProper tyMinHeight); | |
459 CSSValueID commonHeightValue = heightValue ? CSSValueAuto : CSSValueExte ndToZoom; | |
460 properties->setProperty(CSSPropertyMinWidth, commonHeightValue); | |
461 properties->setProperty(CSSPropertyMaxWidth, commonHeightValue); | |
462 } | |
463 | |
464 rule->setProperties(properties); | |
465 | |
466 return rule.release(); | |
467 } | |
468 | |
469 PassRefPtr<StyleRuleBase> HTMLMetaElement::parseHandheldFriendlyContent(const St ring& contentValue) | |
470 { | |
471 RefPtr<StyleRuleViewport> rule = StyleRuleViewport::create(); | |
472 RefPtr<MutableStylePropertySet> properties = MutableStylePropertySet::create (CSSStrictMode); | |
473 properties->setProperty(CSSPropertyInternalPriority, cssValuePool().createVa lue(2, CSSPrimitiveValue::CSS_NUMBER)); | |
474 | |
475 if (equalIgnoringCase(contentValue, "true")) { | |
476 properties->setProperty(CSSPropertyMinWidth, cssValuePool().createValue( 100, CSSPrimitiveValue::CSS_PERCENTAGE)); | |
477 properties->setProperty(CSSPropertyMaxWidth, cssValuePool().createValue( 100, CSSPrimitiveValue::CSS_PERCENTAGE)); | |
478 } | |
479 | |
480 rule->setProperties(properties); | |
481 return rule.release(); | |
482 } | |
483 | |
484 PassRefPtr<StyleRuleBase> HTMLMetaElement::parseMobileOptimizedContent(const Str ing& contentValue) | |
485 { | |
486 RefPtr<StyleRuleViewport> rule = StyleRuleViewport::create(); | |
487 RefPtr<MutableStylePropertySet> properties = MutableStylePropertySet::create (CSSStrictMode); | |
488 properties->setProperty(CSSPropertyInternalPriority, cssValuePool().createVa lue(3, CSSPrimitiveValue::CSS_NUMBER)); | |
489 | |
490 float value = parsePositiveNumber(String(), contentValue, float(0), float(10 000)); | |
491 RefPtr<CSSValue> widthValue; | |
492 if (value > 0) | |
493 widthValue = cssValuePool().createValue(value, CSSPrimitiveValue::CSS_PX ); | |
494 else | |
495 widthValue = cssValuePool().createValue(100, CSSPrimitiveValue::CSS_PERC ENTAGE); | |
496 | |
497 properties->setProperty(CSSPropertyMinWidth, CSSValueAuto); | |
498 properties->setProperty(CSSPropertyMaxWidth, widthValue); | |
499 | |
500 rule->setProperties(properties); | |
501 return rule.release(); | |
502 } | |
503 | |
504 void HTMLMetaElement::parseAttribute(const QualifiedName& name, const AtomicStri ng& value) | |
505 { | |
506 if (name == http_equivAttr || name == contentAttr) { | |
507 process(); | |
508 } else if (name == nameAttr) { | |
509 // Do nothing. | |
510 } else { | |
511 HTMLElement::parseAttribute(name, value); | |
512 } | |
513 } | |
514 | |
515 void HTMLMetaElement::process() | |
516 { | |
517 // We always need to clear rules as the meta tag could have been modified. | |
518 removeStyleSheet(); | |
519 | |
520 if (!inDocument()) | |
521 return; | |
522 | |
523 // All below situations requires a content attribute (which can be the empty string). | |
524 const AtomicString& contentValue = fastGetAttribute(contentAttr); | |
525 if (contentValue.isNull()) | |
526 return; | |
527 | |
528 const AtomicString& nameValue = fastGetAttribute(nameAttr); | |
529 | |
530 if (nameValue.isNull()) { | |
531 // Get the document to process the tag, but only if we're actually part of DOM tree (changing a meta tag while | |
532 // it's not in the tree shouldn't have any effect on the document) | |
533 const AtomicString& httpEquivValue = fastGetAttribute(http_equivAttr); | |
534 if (!httpEquivValue.isNull()) | |
535 document()->processHttpEquiv(httpEquivValue, contentValue); | |
536 return; | |
537 } | |
538 | |
539 if (equalIgnoringCase(nameValue, "viewport")) { | |
540 addStyleSheetForRule(parseViewportContent(contentValue)); | |
541 } else if (equalIgnoringCase(name(), "handheldfriendly")) { | |
542 addStyleSheetForRule(parseHandheldFriendlyContent(contentValue)); | |
543 } else if (equalIgnoringCase(name(), "mobileoptimized")) { | |
544 addStyleSheetForRule(parseMobileOptimizedContent(contentValue)); | |
545 } else if (equalIgnoringCase(name(), "referrer")) { | |
546 document()->processReferrerPolicy(contentValue); | |
547 } | |
548 } | |
549 | |
550 void HTMLMetaElement::addStyleSheetForRule(PassRefPtr<StyleRuleBase> rule) | |
551 { | |
552 ASSERT(inDocument()); | |
553 ASSERT(!m_sheet); | |
554 | |
555 document()->styleSheetCollection()->addStyleSheetCandidateNode(this, false); | |
556 | |
557 document()->styleSheetCollection()->addPendingSheet(); | |
558 | |
559 // As the stylesheet has no source URL, the position makes no difference. | |
560 TextPosition startPosition = TextPosition::minimumPosition(); | |
561 | |
562 m_sheet = CSSStyleSheet::createInline(this, KURL(), startPosition, document( )->inputEncoding()); | |
563 | |
564 m_sheet->setMediaQueries(MediaQuerySet::create("screen")); | |
565 m_sheet->setTitle(title()); | |
566 | |
567 m_sheet->contents()->parserAppendRule(rule); | |
568 | |
569 document()->styleSheetCollection()->removePendingSheet(); | |
570 } | |
571 | |
572 void HTMLMetaElement::removeStyleSheet() | |
573 { | |
574 if (m_sheet) { | |
575 document()->styleSheetCollection()->removeStyleSheetCandidateNode(this); | |
576 m_sheet.release()->clearOwnerNode(); | |
577 } | |
578 | |
579 // No need to resolve style during teardown. | |
580 if (document()->renderer()) | |
581 document()->styleResolverChanged(DeferRecalcStyle); | |
582 } | |
583 | |
584 String HTMLMetaElement::content() const | |
585 { | |
586 return getAttribute(contentAttr); | |
587 } | |
588 | |
589 String HTMLMetaElement::httpEquiv() const | |
590 { | |
591 return getAttribute(http_equivAttr); | |
592 } | |
593 | |
594 String HTMLMetaElement::name() const | |
595 { | |
596 return getNameAttribute(); | |
597 } | |
598 | |
599 } | |
OLD | NEW |