GNU Classpath (0.20) | |
Frames | No Frames |
1: /* StyleSheet.java -- 2: Copyright (C) 2005 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package javax.swing.text.html; 40: 41: import java.awt.Color; 42: import java.awt.Font; 43: import java.awt.Graphics; 44: 45: import java.io.IOException; 46: import java.io.Reader; 47: import java.io.Serializable; 48: import java.io.StringReader; 49: 50: import java.net.MalformedURLException; 51: import java.net.URL; 52: 53: import java.util.Enumeration; 54: import java.util.Vector; 55: 56: import javax.swing.text.AttributeSet; 57: import javax.swing.text.Element; 58: import javax.swing.text.MutableAttributeSet; 59: import javax.swing.text.SimpleAttributeSet; 60: import javax.swing.text.Style; 61: import javax.swing.text.StyleContext; 62: import javax.swing.text.View; 63: 64: 65: /** 66: * This class adds support for defining the visual characteristics of HTML views 67: * being rendered. This enables views to be customized by a look-and-feel, mulitple 68: * views over the same model can be rendered differently. Each EditorPane has its 69: * own StyleSheet, but by default one sheet will be shared by all of the HTMLEditorKit 70: * instances. An HTMLDocument can also have a StyleSheet, which holds specific CSS 71: * specs. 72: * 73: * In order for Views to store less state and therefore be more lightweight, 74: * the StyleSheet can act as a factory for painters that handle some of the 75: * rendering tasks. Since the StyleSheet may be used by views over multiple 76: * documents the HTML attributes don't effect the selector being used. 77: * 78: * The rules are stored as named styles, and other information is stored to 79: * translate the context of an element to a rule. 80: * 81: * @author Lillian Angel (langel@redhat.com) 82: */ 83: public class StyleSheet extends StyleContext 84: { 85: 86: /** The base URL */ 87: URL base; 88: 89: /** Base font size (int) */ 90: int baseFontSize; 91: 92: /** The style sheets stored. */ 93: StyleSheet[] styleSheet; 94: 95: /** 96: * Constructs a StyleSheet. 97: */ 98: public StyleSheet() 99: { 100: super(); 101: baseFontSize = 4; // Default font size from CSS 102: } 103: 104: /** 105: * Gets the style used to render the given tag. The element represents the tag 106: * and can be used to determine the nesting, where the attributes will differ 107: * if there is nesting inside of elements. 108: * 109: * @param t - the tag to translate to visual attributes 110: * @param e - the element representing the tag 111: * @return the set of CSS attributes to use to render the tag. 112: */ 113: public Style getRule(HTML.Tag t, Element e) 114: { 115: // FIXME: Not implemented. 116: return null; 117: } 118: 119: /** 120: * Gets the rule that best matches the selector. selector is a space 121: * separated String of element names. The attributes of the returned 122: * Style will change as rules are added and removed. 123: * 124: * @param selector - the element names separated by spaces 125: * @return the set of CSS attributes to use to render 126: */ 127: public Style getRule(String selector) 128: { 129: // FIXME: Not implemented. 130: return null; 131: } 132: 133: /** 134: * Adds a set if rules to the sheet. The rules are expected to be in valid 135: * CSS format. This is called as a result of parsing a <style> tag 136: * 137: * @param rule - the rule to add to the sheet 138: */ 139: public void addRule(String rule) 140: { 141: CssParser cp = new CssParser(); 142: try 143: { 144: cp.parse(base, new StringReader(rule), false, false); 145: } 146: catch (IOException io) 147: { 148: // Do nothing here. 149: } 150: } 151: 152: /** 153: * Translates a CSS declaration into an AttributeSet. This is called 154: * as a result of encountering an HTML style attribute. 155: * 156: * @param decl - the declaration to get 157: * @return the AttributeSet representing the declaration 158: */ 159: public AttributeSet getDeclaration(String decl) 160: { 161: if (decl == null) 162: return SimpleAttributeSet.EMPTY; 163: // FIXME: Not implemented. 164: return null; 165: } 166: 167: /** 168: * Loads a set of rules that have been specified in terms of CSS grammar. 169: * If there are any conflicts with existing rules, the new rule is added. 170: * 171: * @param in - the stream to read the CSS grammar from. 172: * @param ref - the reference URL. It is the location of the stream, it may 173: * be null. All relative URLs specified in the stream will be based upon this 174: * parameter. 175: * @throws IOException - For any IO error while reading 176: */ 177: public void loadRules(Reader in, URL ref) throws IOException 178: { 179: CssParser cp = new CssParser(); 180: cp.parse(ref, in, false, false); 181: } 182: 183: /** 184: * Gets a set of attributes to use in the view. This is a set of 185: * attributes that can be used for View.getAttributes 186: * 187: * @param v - the view to get the set for 188: * @return the AttributeSet to use in the view. 189: */ 190: public AttributeSet getViewAttributes(View v) 191: { 192: // FIXME: Not implemented. 193: return null; 194: } 195: 196: /** 197: * Removes a style previously added. 198: * 199: * @param nm - the name of the style to remove 200: */ 201: public void removeStyle(String nm) 202: { 203: // FIXME: Not implemented. 204: super.removeStyle(nm); 205: } 206: 207: /** 208: * Adds the rules from ss to those of the receiver. ss's rules will 209: * override the old rules. An added StyleSheet will never override the rules 210: * of the receiving style sheet. 211: * 212: * @param ss - the new StyleSheet. 213: */ 214: public void addStyleSheet(StyleSheet ss) 215: { 216: if (styleSheet == null) 217: styleSheet = new StyleSheet[] {ss}; 218: else 219: System.arraycopy(new StyleSheet[] {ss}, 0, styleSheet, 220: styleSheet.length, 1); 221: } 222: 223: /** 224: * Removes ss from those of the receiver 225: * 226: * @param ss - the StyleSheet to remove. 227: */ 228: public void removeStyleSheet(StyleSheet ss) 229: { 230: if (styleSheet.length == 1 && styleSheet[0].equals(ss)) 231: styleSheet = null; 232: else 233: { 234: for (int i = 0; i < styleSheet.length; i++) 235: { 236: StyleSheet curr = styleSheet[i]; 237: if (curr.equals(ss)) 238: { 239: StyleSheet[] tmp = new StyleSheet[styleSheet.length - 1]; 240: if (i != 0 && i != (styleSheet.length - 1)) 241: { 242: System.arraycopy(styleSheet, 0, tmp, 0, i); 243: System.arraycopy(styleSheet, i + 1, tmp, i, 244: styleSheet.length - i - 1); 245: } 246: else if (i == 0) 247: System.arraycopy(styleSheet, 1, tmp, 0, styleSheet.length - 1); 248: else 249: System.arraycopy(styleSheet, 0, tmp, 0, styleSheet.length - 1); 250: 251: styleSheet = tmp; 252: break; 253: } 254: } 255: } 256: } 257: 258: /** 259: * Returns an array of the linked StyleSheets. May return null. 260: * 261: * @return - An array of the linked StyleSheets. 262: */ 263: public StyleSheet[] getStyleSheets() 264: { 265: return styleSheet; 266: } 267: 268: /** 269: * Imports a style sheet from the url. The rules are directly added to the 270: * receiver. 271: * 272: * @param url - the URL to import the StyleSheet from. 273: */ 274: public void importStyleSheet(URL url) 275: { 276: // FIXME: Not implemented 277: } 278: 279: /** 280: * Sets the base url. All import statements that are relative, will be 281: * relative to base. 282: * 283: * @param base - 284: * the base URL. 285: */ 286: public void setBase(URL base) 287: { 288: this.base = base; 289: } 290: 291: /** 292: * Gets the base url. 293: * 294: * @return - the base 295: */ 296: public URL getBase() 297: { 298: return base; 299: } 300: 301: /** 302: * Adds a CSS attribute to the given set. 303: * 304: * @param attr - the attribute set 305: * @param key - the attribute to add 306: * @param value - the value of the key 307: */ 308: public void addCSSAttribute(MutableAttributeSet attr, CSS.Attribute key, 309: String value) 310: { 311: attr.addAttribute(key, value); 312: } 313: 314: /** 315: * Adds a CSS attribute to the given set. 316: * This method parses the value argument from HTML based on key. 317: * Returns true if it finds a valid value for the given key, 318: * and false otherwise. 319: * 320: * @param attr - the attribute set 321: * @param key - the attribute to add 322: * @param value - the value of the key 323: * @return true if a valid value was found. 324: */ 325: public boolean addCSSAttributeFromHTML(MutableAttributeSet attr, CSS.Attribute key, 326: String value) 327: { 328: // FIXME: Need to parse value from HTML based on key. 329: attr.addAttribute(key, value); 330: return attr.containsAttribute(key, value); 331: } 332: 333: /** 334: * Converts a set of HTML attributes to an equivalent set of CSS attributes. 335: * 336: * @param htmlAttrSet - the set containing the HTML attributes. 337: * @return the set of CSS attributes 338: */ 339: public AttributeSet translateHTMLToCSS(AttributeSet htmlAttrSet) 340: { 341: // FIXME: Not implemented. 342: return null; 343: } 344: 345: /** 346: * Adds an attribute to the given set and returns a new set. This is implemented 347: * to convert StyleConstants attributes to CSS before forwarding them to the superclass. 348: * The StyleConstants attribute do not have corresponding CSS entry, the attribute 349: * is stored (but will likely not be used). 350: * 351: * @param old - the old set 352: * @param key - the non-null attribute key 353: * @param value - the attribute value 354: * @return the updated set 355: */ 356: public AttributeSet addAttribute(AttributeSet old, Object key, 357: Object value) 358: { 359: // FIXME: Not implemented. 360: return super.addAttribute(old, key, value); 361: } 362: 363: /** 364: * Adds a set of attributes to the element. If any of these attributes are 365: * StyleConstants, they will be converted to CSS before forwarding to the 366: * superclass. 367: * 368: * @param old - the old set 369: * @param attr - the attributes to add 370: * @return the updated attribute set 371: */ 372: public AttributeSet addAttributes(AttributeSet old, AttributeSet attr) 373: { 374: // FIXME: Not implemented. 375: return super.addAttributes(old, attr); 376: } 377: 378: /** 379: * Removes an attribute from the set. If the attribute is a 380: * StyleConstants, it will be converted to CSS before forwarding to the 381: * superclass. 382: * 383: * @param old - the old set 384: * @param key - the non-null attribute key 385: * @return the updated set 386: */ 387: public AttributeSet removeAttribute(AttributeSet old, Object key) 388: { 389: // FIXME: Not implemented. 390: return super.removeAttribute(old, key); 391: } 392: 393: /** 394: * Removes an attribute from the set. If any of the attributes are 395: * StyleConstants, they will be converted to CSS before forwarding to the 396: * superclass. 397: * 398: * @param old - the old set 399: * @param attrs - the attributes to remove 400: * @return the updated set 401: */ 402: public AttributeSet removeAttributes(AttributeSet old, AttributeSet attrs) 403: { 404: // FIXME: Not implemented. 405: return super.removeAttributes(old, attrs); 406: } 407: 408: /** 409: * Removes a set of attributes for the element. If any of the attributes is a 410: * StyleConstants, they will be converted to CSS before forwarding to the 411: * superclass. 412: * 413: * @param old - the old attribute set 414: * @param names - the attribute names 415: * @return the update attribute set 416: */ 417: public AttributeSet removeAttributes(AttributeSet old, Enumeration names) 418: { 419: // FIXME: Not implemented. 420: return super.removeAttributes(old, names); 421: } 422: 423: /** 424: * Creates a compact set of attributes that might be shared. This is a hook 425: * for subclasses that want to change the behaviour of SmallAttributeSet. 426: * 427: * @param a - the set of attributes to be represented in the compact form. 428: * @return the set of attributes created 429: */ 430: protected StyleContext.SmallAttributeSet createSmallAttributeSet(AttributeSet a) 431: { 432: return super.createSmallAttributeSet(a); 433: } 434: 435: /** 436: * Creates a large set of attributes. This set is not shared. This is a hook 437: * for subclasses that want to change the behaviour of the larger attribute 438: * storage format. 439: * 440: * @param a - the set of attributes to be represented in the larger form. 441: * @return the large set of attributes. 442: */ 443: protected MutableAttributeSet createLargeAttributeSet(AttributeSet a) 444: { 445: return super.createLargeAttributeSet(a); 446: } 447: 448: /** 449: * Gets the font to use for the given set. 450: * 451: * @param a - the set to get the font for. 452: * @return the font for the set 453: */ 454: public Font getFont(AttributeSet a) 455: { 456: return super.getFont(a); 457: } 458: 459: /** 460: * Takes a set of attributes and turns it into a foreground 461: * color specification. This is used to specify things like, brigher, more hue 462: * etc. 463: * 464: * @param a - the set to get the foreground color for 465: * @return the foreground color for the set 466: */ 467: public Color getForeground(AttributeSet a) 468: { 469: return super.getForeground(a); 470: } 471: 472: /** 473: * Takes a set of attributes and turns it into a background 474: * color specification. This is used to specify things like, brigher, more hue 475: * etc. 476: * 477: * @param a - the set to get the background color for 478: * @return the background color for the set 479: */ 480: public Color getBackground(AttributeSet a) 481: { 482: return super.getBackground(a); 483: } 484: 485: /** 486: * Gets the box formatter to use for the given set of CSS attributes. 487: * 488: * @param a - the given set 489: * @return the box formatter 490: */ 491: public BoxPainter getBoxPainter(AttributeSet a) 492: { 493: return new BoxPainter(a); 494: } 495: 496: /** 497: * Gets the list formatter to use for the given set of CSS attributes. 498: * 499: * @param a - the given set 500: * @return the list formatter 501: */ 502: public ListPainter getListPainter(AttributeSet a) 503: { 504: return new ListPainter(a); 505: } 506: 507: /** 508: * Sets the base font size between 1 and 7. 509: * 510: * @param sz - the new font size for the base. 511: */ 512: public void setBaseFontSize(int sz) 513: { 514: if (sz <= 7 && sz >= 1) 515: baseFontSize = sz; 516: } 517: 518: /** 519: * Sets the base font size from the String. It can either identify 520: * a specific font size (between 1 and 7) or identify a relative 521: * font size such as +1 or -2. 522: * 523: * @param size - the new font size as a String. 524: */ 525: public void setBaseFontSize(String size) 526: { 527: size.trim(); 528: int temp = 0; 529: try 530: { 531: if (size.length() == 2) 532: { 533: int i = new Integer(size.substring(1)).intValue(); 534: if (size.startsWith("+")) 535: temp = baseFontSize + i; 536: else if (size.startsWith("-")) 537: temp = baseFontSize - i; 538: } 539: else if (size.length() == 1) 540: temp = new Integer(size.substring(0)).intValue(); 541: 542: if (temp <= 7 && temp >= 1) 543: baseFontSize = temp; 544: } 545: catch (NumberFormatException nfe) 546: { 547: // Do nothing here 548: } 549: } 550: 551: /** 552: * TODO 553: * 554: * @param pt - TODO 555: * @return TODO 556: */ 557: public static int getIndexOfSize(float pt) 558: { 559: // FIXME: Not implemented. 560: return 0; 561: } 562: 563: /** 564: * Gets the point size, given a size index. 565: * 566: * @param index - the size index 567: * @return the point size. 568: */ 569: public float getPointSize(int index) 570: { 571: // FIXME: Not implemented. 572: return 0; 573: } 574: 575: /** 576: * Given the string of the size, returns the point size value. 577: * 578: * @param size - the string representation of the size. 579: * @return - the point size value. 580: */ 581: public float getPointSize(String size) 582: { 583: // FIXME: Not implemented. 584: return 0; 585: } 586: 587: /** 588: * Converst a color string to a color. If it is not found, null is returned. 589: * 590: * @param color - the color string such as "RED" or "#NNNNNN" 591: * @return the Color, or null if not found. 592: */ 593: public Color stringToColor(String color) 594: { 595: color = color.toLowerCase(); 596: if (color.equals("black") || color.equals("#000000")) 597: return Color.BLACK; 598: else if (color.equals("aqua") || color.equals("#00FFFF")) 599: return new Color(127, 255, 212); 600: else if (color.equals("gray") || color.equals("#808080")) 601: return Color.GRAY; 602: else if (color.equals("navy") || color.equals("#000080")) 603: return new Color(0, 0, 128); 604: else if (color.equals("silver") || color.equals("#C0C0C0")) 605: return Color.LIGHT_GRAY; 606: else if (color.equals("green") || color.equals("#008000")) 607: return Color.GREEN; 608: else if (color.equals("olive") || color.equals("#808000")) 609: return new Color(128, 128, 0); 610: else if (color.equals("teal") || color.equals("#008080")) 611: return new Color(0, 128, 128); 612: else if (color.equals("blue") || color.equals("#0000FF")) 613: return Color.BLUE; 614: else if (color.equals("lime") || color.equals("#00FF00")) 615: return new Color(0, 255, 0); 616: else if (color.equals("purple") || color.equals("#800080")) 617: return new Color(128, 0, 128); 618: else if (color.equals("white") || color.equals("#FFFFFF")) 619: return Color.WHITE; 620: else if (color.equals("fuchsia") || color.equals("#FF00FF")) 621: return Color.MAGENTA; 622: else if (color.equals("maroon") || color.equals("#800000")) 623: return new Color(128, 0, 0); 624: else if (color.equals("Red") || color.equals("#FF0000")) 625: return Color.RED; 626: else if (color.equals("Yellow") || color.equals("#FFFF00")) 627: return Color.YELLOW; 628: return null; 629: } 630: 631: /** 632: * This class carries out some of the duties of CSS formatting. This enables views 633: * to present the CSS formatting while not knowing how the CSS values are cached. 634: * 635: * This object is reponsible for the insets of a View and making sure 636: * the background is maintained according to the CSS attributes. 637: * 638: * @author Lillian Angel (langel@redhat.com) 639: */ 640: public static class BoxPainter extends Object implements Serializable 641: { 642: 643: /** 644: * Attribute set for painter 645: */ 646: AttributeSet as; 647: 648: /** 649: * Package-private constructor. 650: * 651: * @param as - AttributeSet for painter 652: */ 653: BoxPainter(AttributeSet as) 654: { 655: this.as = as; 656: } 657: 658: /** 659: * Gets the inset needed on a given side to account for the margin, border 660: * and padding. 661: * 662: * @param size - the size of the box to get the inset for. View.TOP, View.LEFT, 663: * View.BOTTOM or View.RIGHT. 664: * @param v - the view making the request. This is used to get the AttributeSet, 665: * amd may be used to resolve percentage arguments. 666: * @return the inset 667: * @throws IllegalArgumentException - for an invalid direction. 668: */ 669: public float getInset(int size, View v) 670: { 671: // FIXME: Not implemented. 672: return 0; 673: } 674: 675: /** 676: * Paints the CSS box according to the attributes given. This should 677: * paint the border, padding and background. 678: * 679: * @param g - the graphics configuration 680: * @param x - the x coordinate 681: * @param y - the y coordinate 682: * @param w - the width of the allocated area 683: * @param h - the height of the allocated area 684: * @param v - the view making the request 685: */ 686: public void paint(Graphics g, float x, float y, float w, float h, View v) 687: { 688: // FIXME: Not implemented. 689: } 690: } 691: 692: /** 693: * This class carries out some of the CSS list formatting duties. Implementations 694: * of this class enable views to present the CSS formatting while not knowing anything 695: * about how the CSS values are being cached. 696: * 697: * @author Lillian Angel (langel@redhat.com) 698: */ 699: public static class ListPainter extends Object implements Serializable 700: { 701: 702: /** 703: * Attribute set for painter 704: */ 705: AttributeSet as; 706: 707: /** 708: * Package-private constructor. 709: * 710: * @param as - AttributeSet for painter 711: */ 712: ListPainter(AttributeSet as) 713: { 714: this.as = as; 715: } 716: 717: /** 718: * Paints the CSS list decoration according to the attributes given. 719: * 720: * @param g - the graphics configuration 721: * @param x - the x coordinate 722: * @param y - the y coordinate 723: * @param w - the width of the allocated area 724: * @param h - the height of the allocated area 725: * @param v - the view making the request 726: * @param item - the list item to be painted >=0. 727: */ 728: public void paint(Graphics g, float x, float y, float w, float h, View v, 729: int item) 730: { 731: // FIXME: Not implemented. 732: } 733: } 734: 735: /** 736: * The parser callback for the CSSParser. 737: */ 738: class CssParser implements CSSParser.CSSParserCallback 739: { 740: /** 741: * A vector of all the selectors. 742: * Each element is an array of all the selector tokens 743: * in a single rule. 744: */ 745: Vector selectors; 746: 747: /** A vector of all the selector tokens in a rule. */ 748: Vector selectorTokens; 749: 750: /** Name of the current property. */ 751: String propertyName; 752: 753: /** The set of CSS declarations */ 754: MutableAttributeSet declaration; 755: 756: /** 757: * True if parsing a declaration, that is the Reader will not 758: * contain a selector. 759: */ 760: boolean parsingDeclaration; 761: 762: /** True if the attributes are coming from a linked/imported style. */ 763: boolean isLink; 764: 765: /** The base URL */ 766: URL base; 767: 768: /** The parser */ 769: CSSParser parser; 770: 771: /** 772: * Constructor 773: */ 774: CssParser() 775: { 776: selectors = new Vector(); 777: selectorTokens = new Vector(); 778: parser = new CSSParser(); 779: base = StyleSheet.this.base; 780: declaration = new SimpleAttributeSet(); 781: } 782: 783: /** 784: * Parses the passed in CSS declaration into an AttributeSet. 785: * 786: * @param s - the declaration 787: * @return the set of attributes containing the property and value. 788: */ 789: public AttributeSet parseDeclaration(String s) 790: { 791: try 792: { 793: return parseDeclaration(new StringReader(s)); 794: } 795: catch (IOException e) 796: { 797: // Do nothing here. 798: } 799: return null; 800: } 801: 802: /** 803: * Parses the passed in CSS declaration into an AttributeSet. 804: * 805: * @param r - the reader 806: * @return the attribute set 807: * @throws IOException from the reader 808: */ 809: public AttributeSet parseDeclaration(Reader r) throws IOException 810: { 811: parse(base, r, true, false); 812: return declaration; 813: } 814: 815: /** 816: * Parse the given CSS stream 817: * 818: * @param base - the url 819: * @param r - the reader 820: * @param parseDec - True if parsing a declaration 821: * @param isLink - True if parsing a link 822: */ 823: public void parse(URL base, Reader r, boolean parseDec, boolean isLink) throws IOException 824: { 825: parsingDeclaration = parseDec; 826: this.isLink = isLink; 827: this.base = base; 828: 829: // flush out all storage 830: propertyName = null; 831: selectors.clear(); 832: selectorTokens.clear(); 833: declaration.removeAttributes(declaration); 834: 835: parser.parse(r, this, parseDec); 836: } 837: 838: /** 839: * Invoked when a valid @import is encountered, 840: * will call importStyleSheet if a MalformedURLException 841: * is not thrown in creating the URL. 842: * 843: * @param s - the string after @import 844: */ 845: public void handleImport(String s) 846: { 847: if (s != null) 848: { 849: try 850: { 851: if (s.startsWith("url(") && s.endsWith(")")) 852: s = s.substring(4, s.length() - 1); 853: if (s.indexOf("\"") >= 0) 854: s = s.replaceAll("\"",""); 855: 856: URL url = new URL(s); 857: if (url == null && base != null) 858: url = new URL(base, s); 859: 860: importStyleSheet(url); 861: } 862: catch (MalformedURLException e) 863: { 864: // Do nothing here. 865: } 866: } 867: } 868: 869: /** 870: * A selector has been encountered. 871: * 872: * @param s - a selector (e.g. P or UL or even P,) 873: */ 874: public void handleSelector(String s) 875: { 876: if (s.endsWith(",")) 877: s = s.substring(0, s.length() - 1); 878: 879: selectorTokens.addElement(s); 880: addSelector(); 881: } 882: 883: /** 884: * Invoked when the start of a rule is encountered. 885: */ 886: public void startRule() 887: { 888: addSelector(); 889: } 890: 891: /** 892: * Invoked when a property name is encountered. 893: * 894: * @param s - the property 895: */ 896: public void handleProperty(String s) 897: { 898: propertyName = s; 899: } 900: 901: /** 902: * Invoked when a property value is encountered. 903: * 904: * @param s - the value 905: */ 906: public void handleValue(String s) 907: { 908: // call addCSSAttribute 909: // FIXME: Not implemented 910: } 911: 912: /** 913: * Invoked when the end of a rule is encountered. 914: */ 915: public void endRule() 916: { 917: // FIXME: Not implemented 918: // add rules 919: propertyName = null; 920: } 921: 922: /** 923: * Adds the selector to the vector. 924: */ 925: private void addSelector() 926: { 927: int length = selectorTokens.size(); 928: if (length > 0) 929: { 930: Object[] sel = new Object[length]; 931: System.arraycopy(selectorTokens.toArray(), 0, sel, 0, length); 932: selectors.add(sel); 933: selectorTokens.clear(); 934: } 935: } 936: } 937: }
GNU Classpath (0.20) |