OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "core/css/PropertyRegistration.h" |
| 6 |
| 7 #include "core/css/CSSSyntaxDescriptor.h" |
| 8 #include "core/css/CSSVariableReferenceValue.h" |
| 9 #include "core/css/PropertyDescriptor.h" |
| 10 #include "core/css/PropertyRegistry.h" |
| 11 #include "core/css/parser/CSSVariableParser.h" |
| 12 #include "core/dom/Document.h" |
| 13 #include "core/dom/ExceptionCode.h" |
| 14 #include "core/dom/StyleChangeReason.h" |
| 15 |
| 16 namespace blink { |
| 17 |
| 18 static bool computationallyIdempotent(const CSSValue& value) |
| 19 { |
| 20 // TODO(timloh): Implement this |
| 21 return true; |
| 22 } |
| 23 |
| 24 void PropertyRegistration::registerProperty(ExecutionContext* executionContext,
const PropertyDescriptor& descriptor, ExceptionState& exceptionState) |
| 25 { |
| 26 // Bindings code ensures these are set. |
| 27 DCHECK(descriptor.hasName()); |
| 28 DCHECK(descriptor.hasInherits()); |
| 29 DCHECK(descriptor.hasSyntax()); |
| 30 |
| 31 String name = descriptor.name(); |
| 32 if (!CSSVariableParser::isValidVariableName(name)) { |
| 33 exceptionState.throwDOMException(SyntaxError, "The name provided is not
a valid custom property name."); |
| 34 return; |
| 35 } |
| 36 AtomicString atomicName(name); |
| 37 Document* document = toDocument(executionContext); |
| 38 PropertyRegistry& registry = *document->propertyRegistry(); |
| 39 if (registry.registration(atomicName)) { |
| 40 exceptionState.throwDOMException(InvalidModificationError, "The name pro
vided has already been registered."); |
| 41 return; |
| 42 } |
| 43 |
| 44 CSSSyntaxDescriptor syntaxDescriptor(descriptor.syntax()); |
| 45 if (!syntaxDescriptor.isValid()) { |
| 46 exceptionState.throwDOMException(SyntaxError, "The syntax provided is no
t a valid custom property syntax."); |
| 47 return; |
| 48 } |
| 49 |
| 50 if (descriptor.hasInitialValue()) { |
| 51 const CSSValue* initial = syntaxDescriptor.parse(descriptor.initialValue
()); |
| 52 if (!initial) { |
| 53 exceptionState.throwDOMException(SyntaxError, "The initial value pro
vided does not parse for the given syntax."); |
| 54 return; |
| 55 } |
| 56 if (!computationallyIdempotent(*initial)) { |
| 57 exceptionState.throwDOMException(SyntaxError, "The initial value pro
vided is not computationally idempotent."); |
| 58 return; |
| 59 } |
| 60 registry.registerProperty(atomicName, syntaxDescriptor, descriptor.inher
its(), initial); |
| 61 } else { |
| 62 if (!syntaxDescriptor.isTokenStream()) { |
| 63 exceptionState.throwDOMException(SyntaxError, "An initial value must
be provided if the syntax is not '*'"); |
| 64 return; |
| 65 } |
| 66 registry.registerProperty(atomicName, syntaxDescriptor, descriptor.inher
its(), nullptr); |
| 67 } |
| 68 |
| 69 // TODO(timloh): Invalidate only elements with this custom property set |
| 70 document->setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracin
g::create(StyleChangeReason::PropertyRegistration)); |
| 71 } |
| 72 |
| 73 void PropertyRegistration::unregisterProperty(ExecutionContext* executionContext
, const String& property, ExceptionState& exceptionState) |
| 74 { |
| 75 Document* document = toDocument(executionContext); |
| 76 PropertyRegistry& registry = *document->propertyRegistry(); |
| 77 AtomicString atomicProperty(property); |
| 78 if (!registry.registration(atomicProperty)) { |
| 79 exceptionState.throwDOMException(NotFoundError, "CSS.unregisterProperty(
) called with non-registered property " + property); |
| 80 return; |
| 81 } |
| 82 registry.unregisterProperty(atomicProperty); |
| 83 |
| 84 document->setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracin
g::create(StyleChangeReason::PropertyUnregistration)); |
| 85 } |
| 86 |
| 87 } // namespace blink |
OLD | NEW |