OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). | 2 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
3 * | 3 * |
4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
8 * | 8 * |
9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 * Library General Public License for more details. | 12 * Library General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU Library General Public License | 14 * You should have received a copy of the GNU Library General Public License |
15 * along with this library; see the file COPYING.LIB. If not, write to | 15 * along with this library; see the file COPYING.LIB. If not, write to |
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
17 * Boston, MA 02110-1301, USA. | 17 * Boston, MA 02110-1301, USA. |
18 * | 18 * |
19 */ | 19 */ |
20 | 20 |
21 #include "core/html/HTMLMeterElement.h" | 21 #include "core/html/HTMLMeterElement.h" |
22 | 22 |
23 #include "bindings/core/v8/ExceptionMessages.h" | 23 #include "bindings/core/v8/ExceptionMessages.h" |
24 #include "bindings/core/v8/ExceptionState.h" | 24 #include "bindings/core/v8/ExceptionState.h" |
25 #include "bindings/core/v8/ExceptionStatePlaceholder.h" | 25 #include "bindings/core/v8/ExceptionStatePlaceholder.h" |
26 #include "core/HTMLNames.h" | 26 #include "core/HTMLNames.h" |
| 27 #include "core/dom/NodeComputedStyle.h" |
27 #include "core/dom/shadow/ShadowRoot.h" | 28 #include "core/dom/shadow/ShadowRoot.h" |
28 #include "core/frame/UseCounter.h" | 29 #include "core/frame/UseCounter.h" |
| 30 #include "core/html/HTMLContentElement.h" |
29 #include "core/html/HTMLDivElement.h" | 31 #include "core/html/HTMLDivElement.h" |
30 #include "core/html/parser/HTMLParserIdioms.h" | 32 #include "core/html/parser/HTMLParserIdioms.h" |
31 #include "core/layout/LayoutObject.h" | 33 #include "core/layout/LayoutObject.h" |
32 #include "core/style/ComputedStyle.h" | 34 #include "core/style/ComputedStyle.h" |
33 | 35 |
34 namespace blink { | 36 namespace blink { |
35 | 37 |
36 using namespace HTMLNames; | 38 using namespace HTMLNames; |
37 | 39 |
| 40 // ---------------------------------------------------------------- |
| 41 |
| 42 class MeterFallbackElement final : public HTMLDivElement { |
| 43 public: |
| 44 DECLARE_NODE_FACTORY(MeterFallbackElement); |
| 45 |
| 46 private: |
| 47 explicit MeterFallbackElement(Document& doc) |
| 48 : HTMLDivElement(doc) |
| 49 { |
| 50 setHasCustomStyleCallbacks(); |
| 51 } |
| 52 |
| 53 PassRefPtr<ComputedStyle> customStyleForLayoutObject() override |
| 54 { |
| 55 // We can't use setInlineStyleProperty() because it updates the DOM |
| 56 // tree. We shouldn't do it during style calculation. |
| 57 // TODO(tkent): Injecting a CSS variable by host is a better approach? |
| 58 Element* host = shadowHost(); |
| 59 RefPtr<ComputedStyle> style = originalStyleForLayoutObject(); |
| 60 if (!host || !host->computedStyle() || host->computedStyle()->appearance
() != MeterPart || style->display() == NONE) |
| 61 return style.release(); |
| 62 RefPtr<ComputedStyle> newStyle = ComputedStyle::clone(*style); |
| 63 newStyle->setDisplay(NONE); |
| 64 newStyle->setUnique(); |
| 65 return newStyle.release(); |
| 66 } |
| 67 }; |
| 68 |
| 69 DEFINE_NODE_FACTORY(MeterFallbackElement) |
| 70 |
| 71 // ---------------------------------------------------------------- |
| 72 |
| 73 class MeterInnerElement final : public HTMLDivElement { |
| 74 public: |
| 75 DECLARE_NODE_FACTORY(MeterInnerElement); |
| 76 |
| 77 private: |
| 78 explicit MeterInnerElement(Document& doc) |
| 79 : HTMLDivElement(doc) |
| 80 { |
| 81 setHasCustomStyleCallbacks(); |
| 82 } |
| 83 |
| 84 PassRefPtr<ComputedStyle> customStyleForLayoutObject() override |
| 85 { |
| 86 // We can't use setInlineStyleProperty() because it updates the DOM |
| 87 // tree. We shouldn't do it during style calculation. |
| 88 // TODO(tkent): Injecting a CSS variable by host is a better approach? |
| 89 Element* host = shadowHost(); |
| 90 RefPtr<ComputedStyle> style = originalStyleForLayoutObject(); |
| 91 if (!host || !host->computedStyle() || host->computedStyle()->appearance
() == MeterPart || style->display() == NONE) |
| 92 return style.release(); |
| 93 RefPtr<ComputedStyle> newStyle = ComputedStyle::clone(*style); |
| 94 newStyle->setDisplay(NONE); |
| 95 newStyle->setUnique(); |
| 96 return newStyle.release(); |
| 97 } |
| 98 }; |
| 99 |
| 100 DEFINE_NODE_FACTORY(MeterInnerElement) |
| 101 |
| 102 // ---------------------------------------------------------------- |
| 103 |
38 HTMLMeterElement::HTMLMeterElement(Document& document) | 104 HTMLMeterElement::HTMLMeterElement(Document& document) |
39 : LabelableElement(meterTag, document) | 105 : LabelableElement(meterTag, document) |
40 { | 106 { |
41 UseCounter::count(document, UseCounter::MeterElement); | 107 UseCounter::count(document, UseCounter::MeterElement); |
42 } | 108 } |
43 | 109 |
44 HTMLMeterElement::~HTMLMeterElement() | 110 HTMLMeterElement::~HTMLMeterElement() |
45 { | 111 { |
46 } | 112 } |
47 | 113 |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 | 251 |
186 void HTMLMeterElement::didElementStateChange() | 252 void HTMLMeterElement::didElementStateChange() |
187 { | 253 { |
188 updateValueAppearance(valueRatio() * 100); | 254 updateValueAppearance(valueRatio() * 100); |
189 } | 255 } |
190 | 256 |
191 void HTMLMeterElement::didAddUserAgentShadowRoot(ShadowRoot& root) | 257 void HTMLMeterElement::didAddUserAgentShadowRoot(ShadowRoot& root) |
192 { | 258 { |
193 ASSERT(!m_value); | 259 ASSERT(!m_value); |
194 | 260 |
195 HTMLDivElement* inner = HTMLDivElement::create(document()); | 261 MeterInnerElement* inner = MeterInnerElement::create(document()); |
196 inner->setShadowPseudoId(AtomicString("-webkit-meter-inner-element")); | 262 inner->setShadowPseudoId(AtomicString("-webkit-meter-inner-element")); |
197 root.appendChild(inner); | 263 root.appendChild(inner); |
198 | 264 |
199 HTMLDivElement* bar = HTMLDivElement::create(document()); | 265 HTMLDivElement* bar = HTMLDivElement::create(document()); |
200 bar->setShadowPseudoId(AtomicString("-webkit-meter-bar")); | 266 bar->setShadowPseudoId(AtomicString("-webkit-meter-bar")); |
201 | 267 |
202 m_value = HTMLDivElement::create(document()); | 268 m_value = HTMLDivElement::create(document()); |
203 updateValueAppearance(0); | 269 updateValueAppearance(0); |
204 bar->appendChild(m_value); | 270 bar->appendChild(m_value); |
205 | 271 |
206 inner->appendChild(bar); | 272 inner->appendChild(bar); |
| 273 |
| 274 MeterFallbackElement* fallback = MeterFallbackElement::create(document()); |
| 275 fallback->appendChild(HTMLContentElement::create(document())); |
| 276 root.appendChild(fallback); |
207 } | 277 } |
208 | 278 |
209 void HTMLMeterElement::updateValueAppearance(double percentage) | 279 void HTMLMeterElement::updateValueAppearance(double percentage) |
210 { | 280 { |
211 DEFINE_STATIC_LOCAL(AtomicString, optimumPseudoId, ("-webkit-meter-optimum-v
alue")); | 281 DEFINE_STATIC_LOCAL(AtomicString, optimumPseudoId, ("-webkit-meter-optimum-v
alue")); |
212 DEFINE_STATIC_LOCAL(AtomicString, suboptimumPseudoId, ("-webkit-meter-subopt
imum-value")); | 282 DEFINE_STATIC_LOCAL(AtomicString, suboptimumPseudoId, ("-webkit-meter-subopt
imum-value")); |
213 DEFINE_STATIC_LOCAL(AtomicString, evenLessGoodPseudoId, ("-webkit-meter-even
-less-good-value")); | 283 DEFINE_STATIC_LOCAL(AtomicString, evenLessGoodPseudoId, ("-webkit-meter-even
-less-good-value")); |
214 | 284 |
215 m_value->setInlineStyleProperty(CSSPropertyWidth, percentage, CSSPrimitiveVa
lue::UnitType::Percentage); | 285 m_value->setInlineStyleProperty(CSSPropertyWidth, percentage, CSSPrimitiveVa
lue::UnitType::Percentage); |
216 switch (getGaugeRegion()) { | 286 switch (getGaugeRegion()) { |
217 case GaugeRegionOptimum: | 287 case GaugeRegionOptimum: |
218 m_value->setShadowPseudoId(optimumPseudoId); | 288 m_value->setShadowPseudoId(optimumPseudoId); |
219 break; | 289 break; |
220 case GaugeRegionSuboptimal: | 290 case GaugeRegionSuboptimal: |
221 m_value->setShadowPseudoId(suboptimumPseudoId); | 291 m_value->setShadowPseudoId(suboptimumPseudoId); |
222 break; | 292 break; |
223 case GaugeRegionEvenLessGood: | 293 case GaugeRegionEvenLessGood: |
224 m_value->setShadowPseudoId(evenLessGoodPseudoId); | 294 m_value->setShadowPseudoId(evenLessGoodPseudoId); |
225 break; | 295 break; |
226 } | 296 } |
227 } | 297 } |
228 | 298 |
| 299 bool HTMLMeterElement::canContainRangeEndPoint() const |
| 300 { |
| 301 document().updateLayoutTreeForNode(this); |
| 302 return computedStyle() && !computedStyle()->hasAppearance(); |
| 303 } |
| 304 |
229 DEFINE_TRACE(HTMLMeterElement) | 305 DEFINE_TRACE(HTMLMeterElement) |
230 { | 306 { |
231 visitor->trace(m_value); | 307 visitor->trace(m_value); |
232 LabelableElement::trace(visitor); | 308 LabelableElement::trace(visitor); |
233 } | 309 } |
234 | 310 |
235 } // namespace blink | 311 } // namespace blink |
OLD | NEW |