Java tutorial
// Copyright 2012 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this css except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.codenvy.ide.ext.web.css.editor; import elemental.js.util.JsMapFromStringToBoolean; import com.codenvy.ide.collections.Jso; import com.codenvy.ide.collections.js.JsoArray; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArray; import com.google.gwt.core.client.JsArrayString; import com.google.gwt.regexp.shared.RegExp; /** * Based on the complete property list for CSS2, this partial parser parses * already existing values and proposes code assistant for the slot where the * cursor currently is. */ public class CssPartialParser { /** Singleton instance. */ private static CssPartialParser instance; // TODO: What about "-.5"? private static final String NUMBER_PATTERN = "(-|\\+)?\\d+(\\.\\d+)?"; private static final String PERCENTAGE_PATTERN = "(\\d|[1-9]\\d|100)%"; private static final String BYTE_PATTERN = "(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])"; private static final String LENGTH_PATTERN = NUMBER_PATTERN + "(em|ex|in|cm|mm|pt|pc|px)"; private static final RegExp REGEXP_INTEGER = compileRegExp("(-|\\+)?\\d+"); private static final RegExp REGEXP_PERCENTAGE = compileRegExp(PERCENTAGE_PATTERN); private static final RegExp REGEXP_3_HEX = compileRegExp("#[0-9a-fA-F]{3}"); private static final RegExp REGEXP_6_HEX = compileRegExp("#[0-9a-fA-F]{6}"); private static final RegExp REGEXP_RGB_BYTES = compileRegExp( "rgb\\(" + BYTE_PATTERN + "\\,\\s*" + BYTE_PATTERN + "\\,\\s*" + BYTE_PATTERN + "\\)"); private static final RegExp REGEXP_RGB_PERCENTS = compileRegExp("rgb\\(" + PERCENTAGE_PATTERN + "\\,\\s*" + PERCENTAGE_PATTERN + "\\,\\s*" + PERCENTAGE_PATTERN + "\\)"); private static final RegExp REGEXP_ANGLE = compileRegExp(NUMBER_PATTERN + "(deg|grad|rad)"); private static final RegExp REGEXP_NUMBER = compileRegExp(NUMBER_PATTERN); private static final RegExp REGEXP_FREQUENCY = compileRegExp(NUMBER_PATTERN + "k?Hz"); private static final RegExp REGEXP_LENGTH = compileRegExp(LENGTH_PATTERN); private static final RegExp REGEXP_RECT = compileRegExp( "rect\\(\\s*(" + LENGTH_PATTERN + "|auto)\\s*\\,\\s*(" + LENGTH_PATTERN + "|auto)\\s*\\,\\s*(" + LENGTH_PATTERN + "|auto)\\s*\\,\\s*(" + LENGTH_PATTERN + "|auto)\\s*\\)"); private static final String ANGLE = "<angle>"; private static final String NUMBER = "<number>"; private static final String INTEGER = "<integer>"; private static final String URI = "<uri>"; private static final String PERCENTAGE = "<percentage>"; private static final String STRING = "<string>"; private static final String COUNTER = "<counter>"; private static final String IDENTIFIER = "<identifier>"; private static final String FREQUENCY = "<frequency>"; private static final String COLOR = "<color>"; private static final String LENGTH = "<length>"; private static final String SHAPE = "<shape>"; private final JavaScriptObject allProperties; private final JavaScriptObject specialValueProposals; private final JsMapFromStringToBoolean repeatingProperties = JsMapFromStringToBoolean.create(); public static CssPartialParser getInstance() { if (instance == null) { instance = new CssPartialParser(); } return instance; } /** * Creates {@link RegExp} instance by given pattern that matches the * whole string. */ private static RegExp compileRegExp(String pattern) { return RegExp.compile("^" + pattern + "$"); } private CssPartialParser() { allProperties = setupAllProperties(); specialValueProposals = setupSpecialValueProposals(); setupRepeatingProperties(repeatingProperties); } private boolean checkIfAngle(String maybeSpecialValue) { return REGEXP_ANGLE.test(maybeSpecialValue); } private boolean checkIfNumber(String maybeSpecialValue) { return REGEXP_NUMBER.test(maybeSpecialValue); } private boolean checkIfInteger(String maybeSpecialValue) { return REGEXP_INTEGER.test(maybeSpecialValue); } private boolean checkIfUri(String maybeSpecialValue) { // TODO: This is an oversimplification. return (maybeSpecialValue.startsWith("http://") || maybeSpecialValue.startsWith("https://")); } private boolean checkIfPercentage(String maybeSpecialValue) { return REGEXP_PERCENTAGE.test(maybeSpecialValue); } private boolean checkIfString(String maybeSpecialValue) { return (((maybeSpecialValue.charAt(0) == '"') && (maybeSpecialValue.charAt(maybeSpecialValue.length() - 1) == '"')) || ((maybeSpecialValue.charAt(0) == '\'') && (maybeSpecialValue.charAt(maybeSpecialValue.length() - 1) == '\''))); } private boolean checkIfCounter(String maybeSpecialValue) { // TODO: This is a simplification. return maybeSpecialValue.startsWith("counter("); } private boolean checkIfIdentifier(String maybeSpecialValue) { // TODO: Implement this. return false; } private boolean checkIfFrequency(String maybeSpecialValue) { return REGEXP_FREQUENCY.test(maybeSpecialValue); } private boolean checkIfColor(String maybeSpecialValue) { return maybeSpecialValue.equals("aqua") || maybeSpecialValue.equals("black") || maybeSpecialValue.equals("blue") || maybeSpecialValue.equals("fuchsia") || maybeSpecialValue.equals("gray") || maybeSpecialValue.equals("green") || maybeSpecialValue.equals("lime") || maybeSpecialValue.equals("maroon") || maybeSpecialValue.equals("navy") || maybeSpecialValue.equals("olive") || maybeSpecialValue.equals("orange") || maybeSpecialValue.equals("purple") || maybeSpecialValue.equals("red") || maybeSpecialValue.equals("silver") || maybeSpecialValue.equals("teal") || maybeSpecialValue.equals("white") || maybeSpecialValue.equals("yellow") || REGEXP_3_HEX.test(maybeSpecialValue) || REGEXP_6_HEX.test(maybeSpecialValue) || REGEXP_RGB_BYTES.test(maybeSpecialValue) || REGEXP_RGB_PERCENTS.test(maybeSpecialValue); } private boolean checkIfLength(String maybeSpecialValue) { return REGEXP_LENGTH.test(maybeSpecialValue); } private boolean checkIfShape(String maybeSpecialValue) { // Note: the syntax for shape is rect(<top>, <right>, <bottom>, <left>) return REGEXP_RECT.test(maybeSpecialValue); } /** * Checks whether the passed-in string matches the format of the special value * type in question. If it does, it returns a list of proposals that should be * shown to the user for this query. * * @param maybeSpecialValue * @param specialValueType * a special value type, e.g., <integer>. This method * can be called with a specialValueType value that is not one of those * special values, in which case the method returns an empty array. * @return an array of strings corresponding to the proposals that should be * shown for the special value type */ public JsArrayString checkIfSpecialValueAndGetSpecialValueProposals(String maybeSpecialValue, String specialValueType) { JsArrayString specialValues = getSpecialValues(maybeSpecialValue); for (int i = 0; i < specialValues.length(); i++) { if (specialValues.get(i).equals(specialValueType)) { return specialValueProposals.<Jso>cast().getJsObjectField(specialValueType).cast(); } } return JavaScriptObject.createArray().cast(); } public JsoArray<CssCompletionProposal> getAutocompletions(String property, JsArrayString valuesBefore, String incomplete, JsArrayString valuesAfter) { incomplete = incomplete.toLowerCase(); boolean isRepeatingProperty = repeatingProperties.hasKey(property); JsArrayString valuesAndSpecialValuesAfter = getValuesAndSpecialValues(valuesAfter); JsArrayString valuesAndSpecialValuesBefore = getValuesAndSpecialValues(valuesBefore); JsoArray<CssCompletionProposal> proposals = JsoArray.create(); JsArray<JavaScriptObject> valuesForAllSlots = getPropertyValues(property); if (valuesForAllSlots == null) { return proposals; } int numSlots = valuesForAllSlots.length(); if (numSlots == 0) { return proposals; } int slot = valuesBefore.length(); // slots use 0-based counting if (slot >= numSlots) { // before giving up, see if the last entry is +, in which case we just // adjust the slot number JavaScriptObject lastSlotValues = valuesForAllSlots.get(numSlots - 1); JsArrayString keySet = getKeySet(lastSlotValues); if ((keySet.length() == 1) && (keySet.get(0).equals("+"))) { slot = numSlots - 1; } else { return proposals; } } JavaScriptObject valuesForSlotInQuestion = valuesForAllSlots.get(slot); valuesForSlotInQuestion.<Jso>cast().removeGwtObjectId(); JsArrayString keySet = getKeySet(valuesForSlotInQuestion); if ((keySet.length() == 1) && (keySet.get(0).equals("+"))) { valuesForSlotInQuestion = valuesForAllSlots.get(slot - 1); keySet = getKeySet(valuesForSlotInQuestion); } if (valuesForSlotInQuestion != null) { if (keySet.length() == 0) { return proposals; } for (int keyCt = 0; keyCt < keySet.length(); keyCt++) { String currentValue = keySet.get(keyCt); Boolean shouldBeIncluded = false; // TODO: Avoid using untyped native collections. JavaScriptObject triggers = valuesForSlotInQuestion.<Jso>cast().getJsObjectField(currentValue) .cast(); triggers.<Jso>cast().removeGwtObjectId(); JsArrayString keyTriggerSet = getKeySet(triggers); if (keyTriggerSet.length() == 0) { if (currentValue.charAt(0) == '<') { JsArrayString valueProposals = specialValueProposals.<Jso>cast() .getJsObjectField(currentValue).cast(); if (valueProposals != null && valueProposals.length() != 0) { shouldBeIncluded = false; for (int i = 0; i < valueProposals.length(); i++) { if (valueProposals.get(i).startsWith(incomplete) && (isRepeatingProperty || !inExistingValues(currentValue, valuesAndSpecialValuesBefore, valuesAndSpecialValuesAfter))) { proposals.add( new CssCompletionProposal(valueProposals.get(i), CompletionType.VALUE)); } } } } else { shouldBeIncluded = true; } } else { for (int keyTriggerCt = 0; keyTriggerCt < keyTriggerSet.length(); keyTriggerCt++) { String triggerValue = keyTriggerSet.get(keyTriggerCt); int triggerSlot = triggers.<Jso>cast().getIntField(triggerValue); if (triggerValue.charAt(0) == '<') { JsArrayString specialValueProposalsAfterCheck = checkIfSpecialValueAndGetSpecialValueProposals( valuesBefore.get(triggerSlot), triggerValue); if (specialValueProposalsAfterCheck.length() != 0) { shouldBeIncluded = false; for (int i = 0; i < specialValueProposalsAfterCheck.length(); i++) { if (specialValueProposalsAfterCheck.get(i).startsWith(incomplete) && (isRepeatingProperty || !inExistingValues(triggerValue, valuesAndSpecialValuesBefore, valuesAndSpecialValuesAfter))) { proposals.add(new CssCompletionProposal( specialValueProposalsAfterCheck.get(i), CompletionType.VALUE)); } } } } else if (valuesBefore.get(triggerSlot).compareTo(triggerValue) == 0) { shouldBeIncluded = true; } } } if (shouldBeIncluded) { if (currentValue.startsWith(incomplete) && (isRepeatingProperty || !inExistingValues(currentValue, valuesAndSpecialValuesBefore, valuesAndSpecialValuesAfter))) { proposals.add(new CssCompletionProposal(currentValue, CompletionType.VALUE)); } } } } return proposals; } private boolean inExistingValues(String currentValue, JsArrayString valuesAndSpecialValuesAfter, JsArrayString valuesAndSpecialValuesBefore) { for (int i = 0; i < valuesAndSpecialValuesAfter.length(); i++) { if (valuesAndSpecialValuesAfter.get(i).equals(currentValue)) { return true; } } for (int i = 0; i < valuesAndSpecialValuesBefore.length(); i++) { if (valuesAndSpecialValuesBefore.get(i).equals(currentValue)) { return true; } } return false; } private JsArrayString getValuesAndSpecialValues(JsArrayString existingValues) { JsArrayString valuesAndSpecialValuesAfter = JavaScriptObject.createArray().cast(); for (int i = 0; i < existingValues.length(); i++) { String value = existingValues.get(i); JsArrayString specialValues = getSpecialValues(value); if (specialValues.length() == 0) { valuesAndSpecialValuesAfter.push(value); } for (int j = 0; j < specialValues.length(); j++) { valuesAndSpecialValuesAfter.push(specialValues.get(j)); } } return valuesAndSpecialValuesAfter; } private JsArrayString getSpecialValues(String value) { JsArrayString specialValues = JavaScriptObject.createArray().cast(); if (value.isEmpty()) { return specialValues; } if (checkIfAngle(value)) { specialValues.push(ANGLE); } if (checkIfInteger(value)) { specialValues.push(INTEGER); } if (checkIfNumber(value)) { specialValues.push(NUMBER); } if (checkIfUri(value)) { specialValues.push(URI); } if (checkIfPercentage(value)) { specialValues.push(PERCENTAGE); } if (checkIfString(value)) { specialValues.push(STRING); } if (checkIfCounter(value)) { specialValues.push(COUNTER); } if (checkIfIdentifier(value)) { specialValues.push(IDENTIFIER); } if (checkIfFrequency(value)) { specialValues.push(FREQUENCY); } if (checkIfColor(value)) { specialValues.push(COLOR); } if (checkIfLength(value)) { specialValues.push(LENGTH); } if (checkIfShape(value)) { specialValues.push(SHAPE); } return specialValues; } public JsArray<JavaScriptObject> getPropertyValues(String property) { return allProperties.<Jso>cast().getJsObjectField(property).cast(); } private native JsArrayString getKeySet(JavaScriptObject jso) /*-{ var accumulator = []; for (var propertyName in jso) { accumulator.push(propertyName); } return accumulator; }-*/; private native JavaScriptObject setupAllProperties() /*-{ return { 'azimuth': [ { 'left-side': {}, 'far-left': {}, 'center-left': {}, 'center': {}, 'center-right': {}, 'right': {}, 'far-right': {}, 'right-side': {}, '<angle>': {}, 'leftwards': {}, 'rightwards': {}, 'inherit': {} }, { 'behind': { 'left-side': 0, 'far-left': 0, 'center-left': 0, 'center': 0, 'center-right': 0, 'right': 0, 'far-right': 0, 'right-side': 0, '<angle>': 0 } } ], 'background': [ { '<color>': {}, 'transparent': {}, 'inherit': {} }, { '<uri>': {}, 'none': {}, 'inherit': {} }, { 'repeat': {}, 'repeat-x': {}, 'repeat-y': {}, 'no-repeat': {}, 'inherit': {} }, { 'scroll': {}, 'fixed': {}, 'inherit': {} }, { '<percentage>': {}, '<length>': {}, 'left': {}, 'center': {}, 'right': {}, 'inherit': {} }, { '<percentage>': { '<percentage>': 0, '<length>': 0, 'left': 0, 'center': 0, 'right': 0 }, '<length>': { '<percentage>': 0, '<length>': 0, 'left': 0, 'center': 0, 'right': 0 }, 'top': { '<percentage>': 0, '<length>': 0, 'left': 0, 'center': 0, 'right': 0 }, 'center': { '<percentage>': 0, '<length>': 0, 'left': 0, 'center': 0, 'right': 0 }, 'bottom': { '<percentage>': 0, '<length>': 0, 'left': 0, 'center': 0, 'right': 0 } } ], 'background-attachment': [ { 'scroll': {}, 'fixed': {}, 'inherit': {} } ], 'background-color': [ { '<color>': {}, 'transparent': {}, 'inherit': {} } ], 'background-image': [ { '<uri>': {}, 'none': {}, 'inherit': {} } ], 'background-position': [ { '<percentage>': {}, '<length>': {}, 'left': {}, 'center': {}, 'right': {}, 'inherit': {} }, { '<percentage>': { '<percentage>': 0, '<length>': 0, 'left': 0, 'center': 0, 'right': 0 }, '<length>': { '<percentage>': 0, '<length>': 0, 'left': 0, 'center': 0, 'right': 0 }, 'top': { '<percentage>': 0, '<length>': 0, 'left': 0, 'center': 0, 'right': 0 }, 'center': { '<percentage>': 0, '<length>': 0, 'left': 0, 'center': 0, 'right': 0 }, 'bottom': { '<percentage>': 0, '<length>': 0, 'left': 0, 'center': 0, 'right': 0 } } ], 'background-repeat': [ { 'repeat': {}, 'repeat-x': {}, 'repeat-y': {}, 'no-repeat': {}, 'inherit': {} } ], 'border-collapse': [ { 'collapse': {}, 'separate': {}, 'inherit': {} } ], 'border-color': [ { '<color>': {}, 'transparent': {}, 'inherit': {} }, { '<color>': { '<color>': 0, 'transparent': 0 }, 'transparent': { '<color>': 0, 'transparent': 0 } }, { '<color>': { '<color>': 1, 'transparent': 1 }, 'transparent': { '<color>': 1, 'transparent': 1 } }, { '<color>': { '<color>': 2, 'transparent': 2 }, 'transparent': { '<color>': 2, 'transparent': 2 } } ], 'border-spacing': [ { '<length>': {}, 'inherit': {} }, { '<length>': { '<length>': 0 } } ], 'border-style': [ { 'none': {}, 'hidden': {}, 'dotted': {}, 'dashed': {}, 'solid': {}, 'double': {}, 'groove': {}, 'ridge': {}, 'inset': {}, 'outset': {}, 'inherit': {} }, { 'none': { 'none': 0, 'hidden': 0, 'dotted': 0, 'dashed': 0, 'solid': 0, 'double': 0, 'groove': 0, 'ridge': 0, 'inset': 0, 'outset': 0 }, 'hidden': { 'none': 0, 'hidden': 0, 'dotted': 0, 'dashed': 0, 'solid': 0, 'double': 0, 'groove': 0, 'ridge': 0, 'inset': 0, 'outset': 0 }, 'dotted': { 'none': 0, 'hidden': 0, 'dotted': 0, 'dashed': 0, 'solid': 0, 'double': 0, 'groove': 0, 'ridge': 0, 'inset': 0, 'outset': 0 }, 'dashed': { 'none': 0, 'hidden': 0, 'dotted': 0, 'dashed': 0, 'solid': 0, 'double': 0, 'groove': 0, 'ridge': 0, 'inset': 0, 'outset': 0 }, 'solid': { 'none': 0, 'hidden': 0, 'dotted': 0, 'dashed': 0, 'solid': 0, 'double': 0, 'groove': 0, 'ridge': 0, 'inset': 0, 'outset': 0 }, 'double': { 'none': 0, 'hidden': 0, 'dotted': 0, 'dashed': 0, 'solid': 0, 'double': 0, 'groove': 0, 'ridge': 0, 'inset': 0, 'outset': 0 }, 'groove': { 'none': 0, 'hidden': 0, 'dotted': 0, 'dashed': 0, 'solid': 0, 'double': 0, 'groove': 0, 'ridge': 0, 'inset': 0, 'outset': 0 }, 'ridge': { 'none': 0, 'hidden': 0, 'dotted': 0, 'dashed': 0, 'solid': 0, 'double': 0, 'groove': 0, 'ridge': 0, 'inset': 0, 'outset': 0 }, 'inset': { 'none': 0, 'hidden': 0, 'dotted': 0, 'dashed': 0, 'solid': 0, 'double': 0, 'groove': 0, 'ridge': 0, 'inset': 0, 'outset': 0 }, 'outset': { 'none': 0, 'hidden': 0, 'dotted': 0, 'dashed': 0, 'solid': 0, 'double': 0, 'groove': 0, 'ridge': 0, 'inset': 0, 'outset': 0 } }, { 'none': { 'none': 1, 'hidden': 1, 'dotted': 1, 'dashed': 1, 'solid': 1, 'double': 1, 'groove': 1, 'ridge': 1, 'inset': 1, 'outset': 1 }, 'hidden': { 'none': 1, 'hidden': 1, 'dotted': 1, 'dashed': 1, 'solid': 1, 'double': 1, 'groove': 1, 'ridge': 1, 'inset': 1, 'outset': 1 }, 'dotted': { 'none': 1, 'hidden': 1, 'dotted': 1, 'dashed': 1, 'solid': 1, 'double': 1, 'groove': 1, 'ridge': 1, 'inset': 1, 'outset': 1 }, 'dashed': { 'none': 1, 'hidden': 1, 'dotted': 1, 'dashed': 1, 'solid': 1, 'double': 1, 'groove': 1, 'ridge': 1, 'inset': 1, 'outset': 1 }, 'solid': { 'none': 1, 'hidden': 1, 'dotted': 1, 'dashed': 1, 'solid': 1, 'double': 1, 'groove': 1, 'ridge': 1, 'inset': 1, 'outset': 1 }, 'double': { 'none': 1, 'hidden': 1, 'dotted': 1, 'dashed': 1, 'solid': 1, 'double': 1, 'groove': 1, 'ridge': 1, 'inset': 1, 'outset': 1 }, 'groove': { 'none': 1, 'hidden': 1, 'dotted': 1, 'dashed': 1, 'solid': 1, 'double': 1, 'groove': 1, 'ridge': 1, 'inset': 1, 'outset': 1 }, 'ridge': { 'none': 1, 'hidden': 1, 'dotted': 1, 'dashed': 1, 'solid': 1, 'double': 1, 'groove': 1, 'ridge': 1, 'inset': 1, 'outset': 1 }, 'inset': { 'none': 1, 'hidden': 1, 'dotted': 1, 'dashed': 1, 'solid': 1, 'double': 1, 'groove': 1, 'ridge': 1, 'inset': 1, 'outset': 1 }, 'outset': { 'none': 1, 'hidden': 1, 'dotted': 1, 'dashed': 1, 'solid': 1, 'double': 1, 'groove': 1, 'ridge': 1, 'inset': 1, 'outset': 1 } }, { 'none': { 'none': 2, 'hidden': 2, 'dotted': 2, 'dashed': 2, 'solid': 2, 'double': 2, 'groove': 2, 'ridge': 2, 'inset': 2, 'outset': 2 }, 'hidden': { 'none': 2, 'hidden': 2, 'dotted': 2, 'dashed': 2, 'solid': 2, 'double': 2, 'groove': 2, 'ridge': 2, 'inset': 2, 'outset': 2 }, 'dotted': { 'none': 2, 'hidden': 2, 'dotted': 2, 'dashed': 2, 'solid': 2, 'double': 2, 'groove': 2, 'ridge': 2, 'inset': 2, 'outset': 2 }, 'dashed': { 'none': 2, 'hidden': 2, 'dotted': 2, 'dashed': 2, 'solid': 2, 'double': 2, 'groove': 2, 'ridge': 2, 'inset': 2, 'outset': 2 }, 'solid': { 'none': 2, 'hidden': 2, 'dotted': 2, 'dashed': 2, 'solid': 2, 'double': 2, 'groove': 2, 'ridge': 2, 'inset': 2, 'outset': 2 }, 'double': { 'none': 2, 'hidden': 2, 'dotted': 2, 'dashed': 2, 'solid': 2, 'double': 2, 'groove': 2, 'ridge': 2, 'inset': 2, 'outset': 2 }, 'groove': { 'none': 2, 'hidden': 2, 'dotted': 2, 'dashed': 2, 'solid': 2, 'double': 2, 'groove': 2, 'ridge': 2, 'inset': 2, 'outset': 2 }, 'ridge': { 'none': 2, 'hidden': 2, 'dotted': 2, 'dashed': 2, 'solid': 2, 'double': 2, 'groove': 2, 'ridge': 2, 'inset': 2, 'outset': 2 }, 'inset': { 'none': 2, 'hidden': 2, 'dotted': 2, 'dashed': 2, 'solid': 2, 'double': 2, 'groove': 2, 'ridge': 2, 'inset': 2, 'outset': 2 }, 'outset': { 'none': 2, 'hidden': 2, 'dotted': 2, 'dashed': 2, 'solid': 2, 'double': 2, 'groove': 2, 'ridge': 2, 'inset': 2, 'outset': 2 } } ], 'border-top': [ { 'thin': {}, 'medium': {}, 'thick': {}, '<length>': {}, 'inherit': {} }, { 'none': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'hidden': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'dotted': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'dashed': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'solid': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'double': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'groove': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'ridge': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'inset': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'outset': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'inherit': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 } }, { '<color>': { 'none': 1, 'hidden': 1, 'dotted': 1, 'dashed': 1, 'solid': 1, 'double': 1, 'groove': 1, 'ridge': 1, 'inset': 1, 'outset': 1 }, 'transparent': { 'none': 1, 'hidden': 1, 'dotted': 1, 'dashed': 1, 'solid': 1, 'double': 1, 'groove': 1, 'ridge': 1, 'inset': 1, 'outset': 1 }, 'inherit': { 'none': 1, 'hidden': 1, 'dotted': 1, 'dashed': 1, 'solid': 1, 'double': 1, 'groove': 1, 'ridge': 1, 'inset': 1, 'outset': 1 } } ], 'border-bottom': [ { 'thin': {}, 'medium': {}, 'thick': {}, '<length>': {}, 'inherit': {} }, { 'none': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'hidden': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'dotted': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'dashed': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'solid': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'double': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'groove': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'ridge': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'inset': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'outset': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'inherit': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 } }, { '<color>': { 'none': 1, 'hidden': 1, 'dotted': 1, 'dashed': 1, 'solid': 1, 'double': 1, 'groove': 1, 'ridge': 1, 'inset': 1, 'outset': 1 }, 'transparent': { 'none': 1, 'hidden': 1, 'dotted': 1, 'dashed': 1, 'solid': 1, 'double': 1, 'groove': 1, 'ridge': 1, 'inset': 1, 'outset': 1 }, 'inherit': { 'none': 1, 'hidden': 1, 'dotted': 1, 'dashed': 1, 'solid': 1, 'double': 1, 'groove': 1, 'ridge': 1, 'inset': 1, 'outset': 1 } } ], 'border-left': [ { 'thin': {}, 'medium': {}, 'thick': {}, '<length>': {}, 'inherit': {} }, { 'none': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'hidden': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'dotted': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'dashed': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'solid': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'double': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'groove': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'ridge': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'inset': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'outset': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'inherit': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 } }, { '<color>': { 'none': 1, 'hidden': 1, 'dotted': 1, 'dashed': 1, 'solid': 1, 'double': 1, 'groove': 1, 'ridge': 1, 'inset': 1, 'outset': 1 }, 'transparent': { 'none': 1, 'hidden': 1, 'dotted': 1, 'dashed': 1, 'solid': 1, 'double': 1, 'groove': 1, 'ridge': 1, 'inset': 1, 'outset': 1 }, 'inherit': { 'none': 1, 'hidden': 1, 'dotted': 1, 'dashed': 1, 'solid': 1, 'double': 1, 'groove': 1, 'ridge': 1, 'inset': 1, 'outset': 1 } } ], 'border-right': [ { 'thin': {}, 'medium': {}, 'thick': {}, '<length>': {}, 'inherit': {} }, { 'none': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'hidden': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'dotted': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'dashed': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'solid': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'double': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'groove': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'ridge': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'inset': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'outset': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'inherit': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 } }, { '<color>': { 'none': 1, 'hidden': 1, 'dotted': 1, 'dashed': 1, 'solid': 1, 'double': 1, 'groove': 1, 'ridge': 1, 'inset': 1, 'outset': 1 }, 'transparent': { 'none': 1, 'hidden': 1, 'dotted': 1, 'dashed': 1, 'solid': 1, 'double': 1, 'groove': 1, 'ridge': 1, 'inset': 1, 'outset': 1 }, 'inherit': { 'none': 1, 'hidden': 1, 'dotted': 1, 'dashed': 1, 'solid': 1, 'double': 1, 'groove': 1, 'ridge': 1, 'inset': 1, 'outset': 1 } } ], 'border-top-color': [ { '<color>': {}, 'transparent': {}, 'inherit': {} } ], 'border-bottom-color': [ { '<color>': {}, 'transparent': {}, 'inherit': {} } ], 'border-left-color': [ { '<color>': {}, 'transparent': {}, 'inherit': {} } ], 'border-right-color': [ { '<color>': {}, 'transparent': {}, 'inherit': {} } ], 'border-top-style': [ { 'none': {}, 'hidden': {}, 'dotted': {}, 'dashed': {}, 'solid': {}, 'double': {}, 'groove': {}, 'ridge': {}, 'inset': {}, 'outset': {}, 'inherit': {} } ], 'border-bottom-style': [ { 'none': {}, 'hidden': {}, 'dotted': {}, 'dashed': {}, 'solid': {}, 'double': {}, 'groove': {}, 'ridge': {}, 'inset': {}, 'outset': {}, 'inherit': {} } ], 'border-left-style': [ { 'none': {}, 'hidden': {}, 'dotted': {}, 'dashed': {}, 'solid': {}, 'double': {}, 'groove': {}, 'ridge': {}, 'inset': {}, 'outset': {}, 'inherit': {} } ], 'border-right-style': [ { 'none': {}, 'hidden': {}, 'dotted': {}, 'dashed': {}, 'solid': {}, 'double': {}, 'groove': {}, 'ridge': {}, 'inset': {}, 'outset': {}, 'inherit': {} } ], 'border-top-width': [ { 'thin': {}, 'medium': {}, 'thick': {}, '<length>': {}, 'inherit': {} } ], 'border-bottom-width': [ { 'thin': {}, 'medium': {}, 'thick': {}, '<length>': {}, 'inherit': {} } ], 'border-left-width': [ { 'thin': {}, 'medium': {}, 'thick': {}, '<length>': {}, 'inherit': {} } ], 'border-right-width': [ { 'thin': {}, 'medium': {}, 'thick': {}, '<length>': {}, 'inherit': {} } ], 'border-width': [ { 'thin': {}, 'medium': {}, 'thick': {}, '<length>': {}, 'inherit': {} }, { 'thin': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'medium': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, 'thick': { 'thin': 0, 'medium': 0, 'thick': 0, '<length>': 0 }, '<length>': { 'thin': 1, 'medium': 1, 'thick': 1, '<length>': 1 } } ], 'border': [ { '<length>': {}, 'inherit': {}, 'transparent': {}, 'none': {}, 'hidden': {}, 'dotted': {}, 'dashed': {}, 'solid': {}, 'double': {}, 'groove': {}, 'ridge': {}, 'inset': {}, 'outset': {}, 'thin': {}, 'medium': {}, 'thick': {}, '<color>': {} }, { '+': {} } ], 'bottom': [ { '<length>': {}, '<percentage>': {}, 'auto': {}, 'inherit': {} } ], 'caption-side': [ { 'top': {}, 'bottom': {}, 'inherit': {} } ], 'clear': [ { 'none': {}, 'left': {}, 'right': {}, 'both': {}, 'inherit': {} } ], 'clip': [ { '<shape>': {}, 'auto': {}, 'inherit': {} } ], 'color': [ { '<color>': {}, 'inherit': {} } ], 'content': [ { 'normal': {}, 'none': {}, '<string>': {}, '<uri>': {}, '<counter>': {}, 'attr(<identifier>)': {}, 'open-quote': {}, 'close-quote': {}, 'no-open-quote': {}, 'no-close-quote': {}, 'inherit': {} }, { '<string>': {}, '<uri>': {}, '<counter>': {}, 'attr(<identifier>)': {}, 'open-quote': {}, 'close-quote': {}, 'no-open-quote': {}, 'no-close-quote': {} }, { '+': {} } ], 'counter-increment': [ { '<identifier>': {}, '<identifierWithInteger>': {}, 'none': {}, 'inherit': {} }, { '<identifier>': { '<identifier>': 0, '<identifierWithInteger>': 0 }, '<identifierWithInteger>': { '<identifier>': 0, '<identifierWithInteger>': 0 } }, { '+': {} } ], 'counter-reset': [ { '<identifier>': {}, '<identifierWithInteger>': {}, 'none': {}, 'inherit': {} }, { '<identifier>': { '<identifier>': 0, '<identifierWithInteger>': 0 }, '<identifierWithInteger>': { '<identifier>': 0, '<identifierWithInteger>': 0 } }, { '+': {} } ], 'cue-after': [ { '<uri>': {}, 'none': {}, 'inherit': {} } ], 'cue-before': [ { '<uri>': {}, 'none': {}, 'inherit': {} } ], 'cue': [ { 'cue-before': {}, 'inherit': {} }, { 'cue-after': { 'cue-before': 0 } } ], 'cursor': [ { '<uri> ,': {}, 'auto': {}, 'crosshair': {}, 'default': {}, 'pointer': {}, 'move': {}, 'e-resize': {}, 'ne-resize': {}, 'nw-resize': {}, 'n-resize': {}, 'se-resize': {}, 'sw-resize': {}, 's-resize': {}, 'w-resize': {}, 'text': {}, 'wait': {}, 'help': {}, 'progress': {}, 'inherit': {} }, { '<uri> ,': { '<uri>': 0 } }, { '+': {} } ], 'direction': [ { 'ltr': {}, 'rtl': {}, 'inherit': {} } ], 'display': [ { 'inline': {}, 'block': {}, 'list-item': {}, 'run-in': {}, 'inline-block': {}, 'table': {}, 'inline-table': {}, 'table-row-group': {}, 'table-header-group': {}, 'table-footer-group': {}, 'table-row': {}, 'table-column-group': {}, 'table-column': {}, 'table-cell': {}, 'table-caption': {}, 'none': {}, 'inherit': {} } ], 'elevation': [ { '<angle>': {}, 'below': {}, 'level': {}, 'above': {}, 'higher': {}, 'lower': {}, 'inherit': {} } ], 'empty-cells': [ { 'show': {}, 'hide': {}, 'inherit': {} } ], 'float': [ { 'left': {}, 'right': {}, 'none': {}, 'inherit': {} } ], 'font-family': [ { '<family-name>': {}, 'serif': {}, 'sans-serif': {}, 'cursive': {}, 'fantasy': {}, 'monospace': {}, inherit: {} }, { ', <family-name>': { '<family-name>': 0, 'serif': 0, 'sans-serif': 0, 'cursive': 0, 'fantasy': 0, 'monospace': 0 }, ', serif': { '<family-name>': 0, 'serif': 0, 'sans-serif': 0, 'cursive': 0, 'fantasy': 0, 'monospace': 0 }, ', sans-serif': { '<family-name>': 0, 'serif': 0, 'sans-serif': 0, 'cursive': 0, 'fantasy': 0, 'monospace': 0 }, ', cursive': { '<family-name>': 0, 'serif': 0, 'sans-serif': 0, 'cursive': 0, 'fantasy': 0, 'monospace': 0 }, ', fantasy': { '<family-name>': 0, 'serif': 0, 'sans-serif': 0, 'cursive': 0, 'fantasy': 0, 'monospace': 0 }, ', monospace': { '<family-name>': 0, 'serif': 0, 'sans-serif': 0, 'cursive': 0, 'fantasy': 0, 'monospace': 0 } }, { '+': {} } ], 'font-size': [ { '<absolute-size>': {}, '<relative-size>': {}, '<length>': {}, '<percentage>': {}, 'inherit': {} } ], 'font-style': [ { 'normal': {}, 'italic': {}, 'oblique': {}, 'inherit': {} } ], 'font-variant': [ { 'normal': {}, 'small-caps': {}, 'inherit': {} } ], 'font-weight': [ { 'normal': {}, 'bold': {}, 'bolder': {}, 'lighter': {}, '100': {}, '200': {}, '300': {}, '400': {}, '500': {}, '600': {}, '700': {}, '800': {}, '900': {}, 'inherit': {} } ], 'font': [ { 'serif': {}, 'sans-serif': {}, 'cursive': {}, 'fantasy': {}, 'monospace': {}, '<family-name>': {}, 'inherit': {}, 'xx-small': {}, 'x-small': {}, 'small': {}, 'medium': {}, 'large': {}, 'x-large': {}, 'xx-large': {}, '<length>': {}, 'larger': {}, 'smaller': {}, 'italic': {}, 'normal': {}, 'oblique': {}, 'small-caps': {}, '100': {}, '200': {}, '300': {}, '400': {}, '500': {}, '600': {}, '700': {}, '800': {}, '900': {}, 'bold': {}, 'bolder': {}, 'lighter': {}, '<number>': {}, '<percentage>': {}, 'caption': {}, 'icon': {}, 'menu': {}, 'message-box': {}, 'small-caption': {}, 'status-bar': {} }, { '+': {} } ], 'height': [ { '<length>': {}, '<percentage>': {}, 'auto': {}, 'inherit': {} } ], 'left': [ { '<length>': {}, '<percentage>': {}, 'auto': {}, 'inherit': {} } ], 'letter-spacing': [ { 'normal': {}, '<length>': {}, 'inherit': {} } ], 'line-height': [ { 'normal': {}, '<number>': {}, '<length>': {}, '<percentage>': {}, 'inherit': {} } ], 'list-style-image': [ { '<uri>': {}, 'none': {}, 'inherit': {} } ], 'list-style-position': [ { 'inside': {}, 'outside': {}, 'inherit': {} } ], 'list-style-type': [ { 'disc': {}, 'circle': {}, 'square': {}, 'decimal': {}, 'decimal-leading-zero': {}, 'lower-roman': {}, 'upper-roman': {}, 'lower-greek': {}, 'lower-latin': {}, 'upper-latin': {}, 'armenian': {}, 'georgian': {}, 'lower-alpha': {}, 'upper-alpha': {}, 'none': {}, 'inherit': {} } ], 'list-style': [ { 'disc': {}, 'circle': {}, 'square': {}, 'decimal': {}, 'decimal-leading-zero': {}, 'lower-roman': {}, 'upper-roman': {}, 'lower-greek': {}, 'lower-latin': {}, 'upper-latin': {}, 'armenian': {}, 'georgian': {}, 'lower-alpha': {}, 'upper-alpha': {}, 'none': {}, 'inherit': {} }, { 'inside': {}, 'outside': {}, 'inherit': {} }, { '<uri>': {}, 'none': {}, 'inherit': {} } ], 'margin-top': [ { '<length>': {}, '<percentage>': {}, 'auto': {}, 'inherit': {} } ], 'margin-bottom': [ { '<length>': {}, '<percentage>': {}, 'auto': {}, 'inherit': {} } ], 'margin-left': [ { '<length>': {}, '<percentage>': {}, 'auto': {}, 'inherit': {} } ], 'margin-right': [ { '<length>': {}, '<percentage>': {}, 'auto': {}, 'inherit': {} } ], 'margin': [ { '<length>': {}, '<percentage>': {}, 'none': {}, 'inherit': {} }, { '<length>': {}, '<percentage>': {}, 'none': {}, 'inherit': {} }, { '<length>': {}, '<percentage>': {}, 'none': {}, 'inherit': {} }, { '<length>': {}, '<percentage>': {}, 'none': {}, 'inherit': {} } ], 'max-height': [ { '<length>': {}, '<percentage>': {}, 'none': {}, 'inherit': {} } ], 'max-width': [ { '<length>': {}, '<percentage>': {}, 'none': {}, 'inherit': {} } ], 'min-height': [ { '<length>': {}, '<percentage>': {}, 'inherit': {} } ], 'min-width': [ { '<length>': {}, '<percentage>': {}, 'inherit': {} } ], 'orphans': [ { '<integer>': {}, 'inherit': {} } ], 'outline-color': [ { '<color>': {}, 'invert': {}, 'inherit': {} } ], 'outline-style': [ { 'none': {}, 'hidden': {}, 'dotted': {}, 'dashed': {}, 'solid': {}, 'double': {}, 'groove': {}, 'ridge': {}, 'inset': {}, 'outset': {}, 'inherit': {} } ], 'outline-width': [ { 'thin': {}, 'medium': {}, 'thick': {}, '<length>': {}, 'inherit': {} } ], 'outline': [ { '<color>': {}, 'invert': {}, 'inherit': {} }, { 'none': {}, 'hidden': {}, 'dotted': {}, 'dashed': {}, 'solid': {}, 'double': {}, 'groove': {}, 'ridge': {}, 'inset': {}, 'outset': {}, 'inherit': {} }, { 'thin': {}, 'medium': {}, 'thick': {}, '<length>': {}, 'inherit': {} } ], 'overflow': [ { 'visible': {}, 'hidden': {}, 'scroll': {}, 'auto': {}, 'inherit': {} } ], 'padding-top': [ { '<length>': {}, '<percentage>': {}, 'inherit': {} } ], 'padding-bottom': [ { '<length>': {}, '<percentage>': {}, 'inherit': {} } ], 'padding-left': [ { '<length>': {}, '<percentage>': {}, 'inherit': {} } ], 'padding-right': [ { '<length>': {}, '<percentage>': {}, 'inherit': {} } ], 'padding': [ { '<length>': {}, '<percentage>': {}, 'inherit': {} }, { '<length>': {}, '<percentage>': {}, 'inherit': {} }, { '<length>': {}, '<percentage>': {}, 'inherit': {} }, { '<length>': {}, '<percentage>': {}, 'inherit': {} } ], 'page-break-after': [ { 'auto': {}, 'always': {}, 'avoid': {}, 'left': {}, 'right': {}, 'inherit': {} } ], 'page-break-before': [ { 'auto': {}, 'always': {}, 'avoid': {}, 'left': {}, 'right': {}, 'inherit': {} } ], 'page-break-inside': [ { 'avoid': {}, 'auto': {}, 'inherit': {} } ], 'pause-after': [ { '<time>': {}, '<percentage>': {}, 'inherit': {} } ], 'pause-before': [ { '<time>': {}, '<percentage>': {}, 'inherit': {} } ], 'pause': [ { '<time>': {}, '<percentage>': {}, 'inherit': {} }, { '<time>': { '<time>': 0, '<percentage>': 0 }, '<percentage>': { '<time>': 0, '<percentage>': 0 } } ], 'pitch-range': [ { '<number>': {}, 'inherit': {} } ], 'pitch': [ { '<frequency>': {}, 'x-low': {}, 'low': {}, 'medium': {}, 'high': {}, 'x-high': {}, 'inherit': {} } ], 'play-during': [ { '<uri>': {}, 'auto': {}, 'none': {}, 'inherit': {} }, { 'mix': { '<uri>': 0 }, 'repeat': { '<uri>': 0 } } ], 'position': [ { 'static': {}, 'relative': {}, 'absolute': {}, 'fixed': {}, 'inherit': {} } ], 'quotes': [ { '<string>': {}, 'none': {}, 'inherit': {} }, { '<string>': { '<string>': 0 } }, { '+': {} } ], 'richness': [ { '<number>': {}, 'inherit': {} } ], 'right': [ { '<length>': {}, '<percentage>': {}, 'auto': {}, 'inherit': {} } ], 'speak-header': [ { 'once': {}, 'always': {}, 'inherit': {} } ], 'speak-numeral': [ { 'digits': {}, 'continuous': {}, 'inherit': {} } ], 'speak-punctuation': [ { 'code': {}, 'none': {}, 'inherit': {} } ], 'speak': [ { 'normal': {}, 'none': {}, 'spell-out': {}, 'inherit': {} } ], 'speech-rate': [ { '<number>': {}, 'x-slow': {}, 'slow': {}, 'medium': {}, 'fast': {}, 'x-fast': {}, 'faster': {}, 'slower': {}, 'inherit': {} } ], 'stress': [ { '<number>': {}, 'inherit': {} } ], 'table-layout': [ { 'auto': {}, 'fixed': {}, 'inherit': {} } ], 'text-align': [ { 'left': {}, 'right': {}, 'center': {}, 'justify': {}, 'inherit': {} } ], 'text-decoration': [ { 'none': {}, 'underline': {}, 'inherit': {} }, { 'overline': { 'underline': 0 } }, { 'line-through': { 'overline': 1 } }, { 'blink': { 'line-through': 2 } } ], 'text-indent': [ { '<length>': {}, '<percentage>': {}, 'inherit': {} } ], 'text-transform': [ { 'capitalize': {}, 'uppercase': {}, 'lowercase': {}, 'none': {}, 'inherit': {} } ], 'top': [ { '<length>': {}, '<percentage>': {}, 'auto': {}, 'inherit': {} } ], 'unicode-bidi': [ { 'normal': {}, 'embed': {}, 'bidi-override': {}, 'inherit': {} } ], 'vertical-align': [ { 'baseline': {}, 'sub': {}, 'super': {}, 'top': {}, 'text-top': {}, 'middle': {}, 'bottom': {}, 'text-bottom': {}, '<percentage>': {}, '<length>': {}, 'inherit': {} } ], 'visibility': [ { 'visible': {}, 'hidden': {}, 'collapse': {}, 'inherit': {} } ], 'voice-family': [ { 'comedian': {}, 'trinoids': {}, 'carlos': {}, 'lani': {}, 'male': {}, 'female': {}, 'child': {}, 'comedian,': {}, 'trinoids,': {}, 'carlos,': {}, 'lani,': {}, 'male,': {}, 'female,': {}, 'child,': {}, 'inherit': {} }, { 'comedian': { 'comedian,': {}, 'trinoids,': {}, 'carlos,': {}, 'lani,': {}, 'male,': {}, 'female,': {}, 'child,': {} }, 'trinoids': { 'comedian,': 0, 'trinoids,': 0, 'carlos,': 0, 'lani,': 0, 'male,': 0, 'female,': 0, 'child,': 0 }, 'carlos': { 'comedian,': 0, 'trinoids,': 0, 'carlos,': 0, 'lani,': 0, 'male,': 0, 'female,': 0, 'child,': 0 }, 'lani': { 'comedian,': 0, 'trinoids,': 0, 'carlos,': 0, 'lani,': 0, 'male,': 0, 'female,': 0, 'child,': 0 }, 'male': { 'comedian,': 0, 'trinoids,': 0, 'carlos,': 0, 'lani,': 0, 'male,': 0, 'female,': 0, 'child,': 0 }, 'female': { 'comedian,': 0, 'trinoids,': 0, 'carlos,': 0, 'lani,': 0, 'male,': 0, 'female,': 0, 'child,': 0 }, 'child': { 'comedian,': 0, 'trinoids,': 0, 'carlos,': 0, 'lani,': 0, 'male,': 0, 'female,': 0, 'child,': 0 }, 'comedian,': { 'comedian,': 0, 'trinoids,': 0, 'carlos,': 0, 'lani,': 0, 'male,': 0, 'female,': 0, 'child,': 0 }, 'trinoids,': { 'comedian,': 0, 'trinoids,': 0, 'carlos,': 0, 'lani,': 0, 'male,': 0, 'female,': 0, 'child,': 0 }, 'carlos,': { 'comedian,': 0, 'trinoids,': 0, 'carlos,': 0, 'lani,': 0, 'male,': 0, 'female,': 0, 'child,': 0 }, 'lani,': { 'comedian,': 0, 'trinoids,': 0, 'carlos,': 0, 'lani,': 0, 'male,': 0, 'female,': 0, 'child,': 0 }, 'male,': { 'comedian,': 0, 'trinoids,': 0, 'carlos,': 0, 'lani,': 0, 'male,': 0, 'female,': 0, 'child,': 0 }, 'female,': { 'comedian,': 0, 'trinoids,': 0, 'carlos,': 0, 'lani,': 0, 'male,': 0, 'female,': 0, 'child,': 0 }, 'child,': { 'comedian,': 0, 'trinoids,': 0, 'carlos,': 0, 'lani,': 0, 'male,': 0, 'female,': 0, 'child,': 0 } }, { '+': {} } ], 'volume': [ { '<number>': {}, '<percentage>': {}, 'silent': {}, 'x-soft': {}, 'soft': {}, 'medium': {}, 'loud': {}, 'x-loud': {}, 'inherit': {} } ], 'white-space': [ { 'normal': {}, 'pre': {}, 'nowrap': {}, 'pre-wrap': {}, 'pre-line': {}, 'inherit': {} } ], 'widows': [ { '<integer>': {}, 'inherit': {} } ], 'width': [ { '<length>': {}, '<percentage>': {}, 'auto': {}, 'inherit': {} } ], 'word-spacing': [ { 'normal': {}, '<length>': {}, 'inherit': {} } ], 'z-index': [ { 'auto': {}, '<integer>': {}, 'inherit': {} } ] }; }-*/; private native JavaScriptObject setupSpecialValueProposals() /*-{ return { '<angle>': [ '<number>deg', '<number>grad', '<number>rad' ], '<family-name>': [ '<family-name>' ], '<number>': [ '<number>' ], '<integer>': [ '<integer>' ], '<color>': [ 'black', 'blue', 'fuchsia', 'gray', 'green', 'lime', 'maroon', 'navy', 'olive', 'orange', 'purple', 'red', 'silver', 'teal', 'white', 'yellow', 'rgb(<number>, <number>, <number>)', 'rgb(<percentage>, <percentage>, <percentage>)', '#rgb', '#rrggbb' ], '<uri>': [ '<uri>' ], '<length>': [ '<number>em', '<number>ex', '<number>in', '<number>cm', '<number>mm', '<number>pt', '<number>pc', '<number>px' ], '<percentage>': [ '<number>%' ], '<relative-size>': [ '<relative-size>' ], '<absolute-size>': [ '<absolute-size>' ], '<shape>': [ '<shape>' ], '<string>': [ '<string>' ], '<counter>': [ '<counter>' ], '<identifier>': [ '<identifer>' ], '<frequency>': [ '<frequency>' ] }; }-*/; // TODO: Make this a bit smarter by allowing only for repetition up // to a certain number. private void setupRepeatingProperties(JsMapFromStringToBoolean repeatingProperties) { repeatingProperties.put("border-color", true); repeatingProperties.put("border-style", true); repeatingProperties.put("border-width", true); repeatingProperties.put("margin", true); repeatingProperties.put("quotes", true); repeatingProperties.put("padding", true); repeatingProperties.put("pause", true); } }