📄 stylesheet.java
字号:
} return retStyle; } /** * Returns the resolved style for <code>selector</code>. This will * create the resolved style, if necessary. */ private synchronized Style getResolvedStyle(String selector) { Style retStyle = (Style)resolvedStyles.get(selector); if (retStyle == null) { retStyle = createResolvedStyle(selector); } return retStyle; } /** * Adds <code>mapping</code> to <code>elements</code>. It is added * such that <code>elements</code> will remain ordered by * specificity. */ private void addSortedStyle(SelectorMapping mapping, Vector elements) { int size = elements.size(); if (size > 0) { int specificity = mapping.getSpecificity(); for (int counter = 0; counter < size; counter++) { if (specificity >= ((SelectorMapping)elements.elementAt (counter)).getSpecificity()) { elements.insertElementAt(mapping, counter); return; } } } elements.addElement(mapping); } /** * Adds <code>parentMapping</code> to <code>styles</code>, and * recursively calls this method if <code>parentMapping</code> has * any child mappings for any of the Elements in <code>elements</code>. */ private synchronized void getStyles(SelectorMapping parentMapping, Vector styles, String[] tags, String[] ids, String[] classes, int index, int numElements, Hashtable alreadyChecked) { // Avoid desending the same mapping twice. if (alreadyChecked.contains(parentMapping)) { return; } alreadyChecked.put(parentMapping, parentMapping); Style style = parentMapping.getStyle(); if (style != null) { addSortedStyle(parentMapping, styles); } for (int counter = index; counter < numElements; counter++) { String tagString = tags[counter]; if (tagString != null) { SelectorMapping childMapping = parentMapping. getChildSelectorMapping(tagString, false); if (childMapping != null) { getStyles(childMapping, styles, tags, ids, classes, counter + 1, numElements, alreadyChecked); } if (classes[counter] != null) { String className = classes[counter]; childMapping = parentMapping.getChildSelectorMapping( tagString + "." + className, false); if (childMapping != null) { getStyles(childMapping, styles, tags, ids, classes, counter + 1, numElements, alreadyChecked); } childMapping = parentMapping.getChildSelectorMapping( "." + className, false); if (childMapping != null) { getStyles(childMapping, styles, tags, ids, classes, counter + 1, numElements, alreadyChecked); } } if (ids[counter] != null) { String idName = ids[counter]; childMapping = parentMapping.getChildSelectorMapping( tagString + "#" + idName, false); if (childMapping != null) { getStyles(childMapping, styles, tags, ids, classes, counter + 1, numElements, alreadyChecked); } childMapping = parentMapping.getChildSelectorMapping( "#" + idName, false); if (childMapping != null) { getStyles(childMapping, styles, tags, ids, classes, counter + 1, numElements, alreadyChecked); } } } } } /** * Creates and returns a Style containing all the rules that match * <code>selector</code>. */ private synchronized Style createResolvedStyle(String selector, String[] tags, String[] ids, String[] classes) { SearchBuffer sb = SearchBuffer.obtainSearchBuffer(); Vector tempVector = sb.getVector(); Hashtable tempHashtable = sb.getHashtable(); // Determine all the Styles that are appropriate, placing them // in tempVector try { SelectorMapping mapping = getRootSelectorMapping(); int numElements = tags.length; String tagString = tags[0]; SelectorMapping childMapping = mapping.getChildSelectorMapping( tagString, false); if (childMapping != null) { getStyles(childMapping, tempVector, tags, ids, classes, 1, numElements, tempHashtable); } if (classes[0] != null) { String className = classes[0]; childMapping = mapping.getChildSelectorMapping( tagString + "." + className, false); if (childMapping != null) { getStyles(childMapping, tempVector, tags, ids, classes, 1, numElements, tempHashtable); } childMapping = mapping.getChildSelectorMapping( "." + className, false); if (childMapping != null) { getStyles(childMapping, tempVector, tags, ids, classes, 1, numElements, tempHashtable); } } if (ids[0] != null) { String idName = ids[0]; childMapping = mapping.getChildSelectorMapping( tagString + "#" + idName, false); if (childMapping != null) { getStyles(childMapping, tempVector, tags, ids, classes, 1, numElements, tempHashtable); } childMapping = mapping.getChildSelectorMapping( "#" + idName, false); if (childMapping != null) { getStyles(childMapping, tempVector, tags, ids, classes, 1, numElements, tempHashtable); } } // Create a new Style that will delegate to all the matching // Styles. int numLinkedSS = (linkedStyleSheets != null) ? linkedStyleSheets.size() : 0; int numStyles = tempVector.size(); AttributeSet[] attrs = new AttributeSet[numStyles + numLinkedSS]; for (int counter = 0; counter < numStyles; counter++) { attrs[counter] = ((SelectorMapping)tempVector. elementAt(counter)).getStyle(); } // Get the AttributeSet from linked style sheets. for (int counter = 0; counter < numLinkedSS; counter++) { AttributeSet attr = ((StyleSheet)linkedStyleSheets. elementAt(counter)).getRule(selector); if (attr == null) { attrs[counter + numStyles] = SimpleAttributeSet.EMPTY; } else { attrs[counter + numStyles] = attr; } } ResolvedStyle retStyle = new ResolvedStyle(selector, attrs, numStyles); resolvedStyles.put(selector, retStyle); return retStyle; } finally { SearchBuffer.releaseSearchBuffer(sb); } } /** * Creates and returns a Style containing all the rules that * matches <code>selector</code>. * * @param elements a Vector of all the Elements * the style is being asked for. The * first Element is the deepest Element, with the last Element * representing the root. * @param t the Tag to use for * the first Element in <code>elements</code> */ private Style createResolvedStyle(String selector, Vector elements, HTML.Tag t) { int numElements = elements.size(); // Build three arrays, one for tags, one for class's, and one for // id's String tags[] = new String[numElements]; String ids[] = new String[numElements]; String classes[] = new String[numElements]; for (int counter = 0; counter < numElements; counter++) { Element e = (Element)elements.elementAt(counter); AttributeSet attr = e.getAttributes(); if (counter == 0 && e.isLeaf()) { // For leafs, we use the second tier attributes. Object testAttr = attr.getAttribute(t); if (testAttr instanceof AttributeSet) { attr = (AttributeSet)testAttr; } else { attr = null; } } if (attr != null) { HTML.Tag tag = (HTML.Tag)attr.getAttribute(StyleConstants. NameAttribute); if (tag != null) { tags[counter] = tag.toString(); } else { tags[counter] = null; } if (attr.isDefined(HTML.Attribute.CLASS)) { classes[counter] = attr.getAttribute (HTML.Attribute.CLASS).toString(); } else { classes[counter] = null; } if (attr.isDefined(HTML.Attribute.ID)) { ids[counter] = attr.getAttribute(HTML.Attribute.ID). toString(); } else { ids[counter] = null; } } else { tags[counter] = ids[counter] = classes[counter] = null; } } tags[0] = t.toString(); return createResolvedStyle(selector, tags, ids, classes); } /** * Creates and returns a Style containing all the rules that match * <code>selector</code>. It is assumed that each simple selector * in <code>selector</code> is separated by a space. */ private Style createResolvedStyle(String selector) { SearchBuffer sb = SearchBuffer.obtainSearchBuffer(); // Will contain the tags, ids, and classes, in that order. Vector elements = sb.getVector(); try { boolean done; int dotIndex = 0; int spaceIndex = 0; int poundIndex = 0; int lastIndex = 0; int length = selector.length(); while (lastIndex < length) { if (dotIndex == lastIndex) { dotIndex = selector.indexOf('.', lastIndex); } if (poundIndex == lastIndex) { poundIndex = selector.indexOf('#', lastIndex); } spaceIndex = selector.indexOf(' ', lastIndex); if (spaceIndex == -1) { spaceIndex = length; } if (dotIndex != -1 && poundIndex != -1 && dotIndex < spaceIndex && poundIndex < spaceIndex) { if (poundIndex < dotIndex) { // #. if (lastIndex == poundIndex) { elements.addElement(""); } else { elements.addElement(selector.substring(lastIndex, poundIndex)); } if ((dotIndex + 1) < spaceIndex) { elements.addElement(selector.substring (dotIndex + 1, spaceIndex)); } else { elements.addElement(null); } if ((poundIndex + 1) == dotIndex) { elements.addElement(null); } else { elements.addElement(selector.substring (poundIndex + 1, dotIndex)); } } else if(poundIndex < spaceIndex) { // .# if (lastIndex == dotIndex) { elements.addElement(""); } else { elements.addElement(selector.substring(lastIndex, dotIndex)); } if ((dotIndex + 1) < poundIndex) { elements.addElement(selector.substring (dotIndex + 1, poundIndex)); } else { elements.addElement(null); } if ((poundIndex + 1) == spaceIndex) { elements.addElement(null); } else { elements.addElement(selector.substring (poundIndex + 1, spaceIndex)); } } dotIndex = poundIndex = spaceIndex + 1; } else if (dotIndex != -1 && dotIndex < spaceIndex) { // . if (dotIndex == lastIndex) { elements.addElement(""); } else { elements.addElement(selector.substring(lastIndex, dotIndex)); } if ((dotIndex + 1) == spaceIndex) { elements.addElement(null); } else { elements.addElement(selector.substring(dotIndex + 1, spaceIndex)); } elements.addElement(null); dotIndex = spaceIndex + 1; } else if (poundIndex != -1 && poundIndex < spaceIndex) { // # if (poundIndex == lastIndex) { elements.addElement(""); } else { elements.addElement(selector.substring(lastIndex, poundIndex)); } elements.addElement(null); if ((poundIndex + 1) == spaceIndex) { elements.addElement(null); } else { elements.addElement(selector.substring(poundIndex + 1, spaceIndex)); } poundIndex = spaceIndex + 1; } else { // id elements.addElement(selector.substring(lastIndex, spaceIndex)); elements.addElement(null); elements.addElement(null); } lastIndex = spaceIndex + 1; } // Create the tag, id, and class arrays. int total = elements.size(); int numTags = total / 3; String[] tags = new String[numTags]; String[] ids = new String[numTags]; String[] classes = new String[numTags]; for (int index = 0, eIndex = total - 3; index < numTags; index++, eIndex -= 3) { tags[index] = (String)elements.elementAt(eIndex); ids[index] = (String)elements.elementAt(eIndex + 1); classes[index] = (String)elements.elementAt(eIndex + 2); } return createResolvedStyle(selector, tags, ids, classes); } finally { SearchBuffer.releaseSearchBuffer(sb); } } /** * Should be invoked when a new rule is added that did not previously * exist. Goes through and refreshes the necessary resolved * rules. */ private synchronized void refreshResolvedRules(String selectorName, String[] selector, Style newStyle, int specificity) { if (resolvedStyles.size() > 0) { Enumeration values = resolvedStyles.elements(); while (values.hasMoreElements()) { ResolvedStyle style = (ResolvedStyle)values.nextElement(); if (style.matches(selectorName)) { style.insertStyle(newStyle, specificity);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -