Changeset 13810 in josm for trunk/src/org/openstreetmap/josm/gui
- Timestamp:
- 2018-05-21T20:42:27+02:00 (6 years ago)
- Location:
- trunk/src/org/openstreetmap/josm/gui/mappaint
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java
r13636 r13810 12 12 import java.util.Optional; 13 13 14 import org.openstreetmap.josm.data.osm.IPrimitive; 14 15 import org.openstreetmap.josm.data.osm.Node; 15 import org.openstreetmap.josm.data.osm.OsmPrimitive;16 16 import org.openstreetmap.josm.data.osm.Relation; 17 17 import org.openstreetmap.josm.data.osm.Way; … … 45 45 * There are several steps to derive the list of elements for display: 46 46 * <ol> 47 * <li>{@link #generateStyles( OsmPrimitive, double, boolean)} applies the47 * <li>{@link #generateStyles(IPrimitive, double, boolean)} applies the 48 48 * {@link StyleSource}s one after another to get a key-value map of MapCSS 49 49 * properties. Then a preliminary set of StyleElements is derived from the 50 50 * properties map.</li> 51 * <li>{@link #getImpl( OsmPrimitive, double, NavigatableComponent)} handles the51 * <li>{@link #getImpl(IPrimitive, double, NavigatableComponent)} handles the 52 52 * different forms of multipolygon tagging.</li> 53 * <li>{@link #getStyleCacheWithRange( OsmPrimitive, double, NavigatableComponent)}53 * <li>{@link #getStyleCacheWithRange(IPrimitive, double, NavigatableComponent)} 54 54 * adds a default StyleElement for primitives that would be invisible otherwise. 55 55 * (For example untagged nodes and ways.)</li> … … 131 131 * @param nc display component 132 132 * @return list of styles 133 */ 134 public StyleElementList get(OsmPrimitive osm, double scale, NavigatableComponent nc) { 133 * @since 13810 (signature) 134 */ 135 public StyleElementList get(IPrimitive osm, double scale, NavigatableComponent nc) { 135 136 return getStyleCacheWithRange(osm, scale, nc).a; 136 137 } … … 145 146 * @param nc navigatable component 146 147 * @return pair containing style list and range 147 */ 148 public Pair<StyleElementList, Range> getStyleCacheWithRange(OsmPrimitive osm, double scale, NavigatableComponent nc) { 148 * @since 13810 (signature) 149 */ 150 public Pair<StyleElementList, Range> getStyleCacheWithRange(IPrimitive osm, double scale, NavigatableComponent nc) { 149 151 if (!osm.isCachedStyleUpToDate() || scale <= 0) { 150 152 osm.setCachedStyle(StyleCache.EMPTY_STYLECACHE); … … 232 234 * @return pair containing style list and range 233 235 */ 234 private Pair<StyleElementList, Range> getImpl( OsmPrimitive osm, double scale, NavigatableComponent nc) {236 private Pair<StyleElementList, Range> getImpl(IPrimitive osm, double scale, NavigatableComponent nc) { 235 237 if (osm instanceof Node) 236 238 return generateStyles(osm, scale, false); … … 242 244 243 245 // FIXME: Maybe in the future outer way styles apply to outers ignoring the multipolygon? 244 for ( OsmPrimitive referrer : osm.getReferrers()) {246 for (IPrimitive referrer : osm.getReferrers()) { 245 247 Relation r = (Relation) referrer; 246 248 if (!drawMultipolygon || !r.isMultipolygon() || !r.isUsable()) { … … 310 312 if (!isDefaultLines()) return p; 311 313 312 for ( OsmPrimitive referrer : osm.getReferrers()) {314 for (IPrimitive referrer : osm.getReferrers()) { 313 315 Relation ref = (Relation) referrer; 314 316 if (!drawMultipolygon || !ref.isMultipolygon() || !ref.isUsable()) { … … 362 364 * outer ways of a multipolygon. 363 365 * @return the generated styles and the valid range as a pair 364 */ 365 public Pair<StyleElementList, Range> generateStyles(OsmPrimitive osm, double scale, boolean pretendWayIsClosed) { 366 * @since 13810 (signature) 367 */ 368 public Pair<StyleElementList, Range> generateStyles(IPrimitive osm, double scale, boolean pretendWayIsClosed) { 366 369 367 370 List<StyleElement> sl = new ArrayList<>(); … … 522 525 * outer ways of a multipolygon. 523 526 * @return first AreaElement found or {@code null}. 524 */ 525 public static AreaElement getAreaElemStyle(OsmPrimitive p, boolean pretendWayIsClosed) { 527 * @since 13810 (signature) 528 */ 529 public static AreaElement getAreaElemStyle(IPrimitive p, boolean pretendWayIsClosed) { 526 530 MapCSSStyleSource.STYLE_SOURCE_LOCK.readLock().lock(); 527 531 try { … … 545 549 * outer ways of a multipolygon. 546 550 * @return {@code true} if primitive has an AreaElement 547 */ 548 public static boolean hasAreaElemStyle(OsmPrimitive p, boolean pretendWayIsClosed) { 551 * @since 13810 (signature) 552 */ 553 public static boolean hasAreaElemStyle(IPrimitive p, boolean pretendWayIsClosed) { 549 554 return getAreaElemStyle(p, pretendWayIsClosed) != null; 550 555 } … … 558 563 * @return {@code true} if primitive has area elements, but no line elements 559 564 * @since 12700 560 */ 561 public static boolean hasOnlyAreaElements(OsmPrimitive p) { 565 * @since 13810 (signature) 566 */ 567 public static boolean hasOnlyAreaElements(IPrimitive p) { 562 568 MapCSSStyleSource.STYLE_SOURCE_LOCK.readLock().lock(); 563 569 try { -
trunk/src/org/openstreetmap/josm/gui/mappaint/Environment.java
r12378 r13810 2 2 package org.openstreetmap.josm.gui.mappaint; 3 3 4 import org.openstreetmap.josm.data.osm. OsmPrimitive;4 import org.openstreetmap.josm.data.osm.IPrimitive; 5 5 import org.openstreetmap.josm.data.osm.Relation; 6 6 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition.Context; … … 18 18 * The primitive that is currently evaluated 19 19 */ 20 public OsmPrimitive osm;20 public IPrimitive osm; 21 21 22 22 /** … … 43 43 * is evaluated in a {@link LinkSelector} (within a child selector) 44 44 */ 45 public OsmPrimitive parent;45 public IPrimitive parent; 46 46 47 47 /** 48 48 * The same for parent selector. Only one of the 2 fields (parent or child) is not null in any environment. 49 49 */ 50 public OsmPrimitive child;50 public IPrimitive child; 51 51 52 52 /** … … 71 71 * @param osm OSM primitive 72 72 * @since 8415 73 */ 74 public Environment(OsmPrimitive osm) { 73 * @since 13810 (signature) 74 */ 75 public Environment(IPrimitive osm) { 75 76 this.osm = osm; 76 77 } … … 82 83 * @param layer layer 83 84 * @param source style source 84 */ 85 public Environment(OsmPrimitive osm, MultiCascade mc, String layer, StyleSource source) { 85 * @since 13810 (signature) 86 */ 87 public Environment(IPrimitive osm, MultiCascade mc, String layer, StyleSource source) { 86 88 this.osm = osm; 87 89 this.mc = mc; … … 114 116 * @return A clone of this environment, with the specified primitive 115 117 * @see #osm 116 */ 117 public Environment withPrimitive(OsmPrimitive osm) { 118 * @since 13810 (signature) 119 */ 120 public Environment withPrimitive(IPrimitive osm) { 118 121 Environment e = new Environment(this); 119 122 e.osm = osm; … … 126 129 * @return A clone of this environment, with the specified parent 127 130 * @see #parent 128 */ 129 public Environment withParent(OsmPrimitive parent) { 131 * @since 13810 (signature) 132 */ 133 public Environment withParent(IPrimitive parent) { 130 134 Environment e = new Environment(this); 131 135 e.parent = parent; … … 142 146 * @see #index 143 147 * @since 6175 144 */ 145 public Environment withParentAndIndexAndLinkContext(OsmPrimitive parent, int index, int count) { 148 * @since 13810 (signature) 149 */ 150 public Environment withParentAndIndexAndLinkContext(IPrimitive parent, int index, int count) { 146 151 Environment e = new Environment(this); 147 152 e.parent = parent; … … 157 162 * @return A clone of this environment, with the specified child 158 163 * @see #child 159 */ 160 public Environment withChild(OsmPrimitive child) { 164 * @since 13810 (signature) 165 */ 166 public Environment withChild(IPrimitive child) { 161 167 Environment e = new Environment(this); 162 168 e.child = child; … … 173 179 * @see #index 174 180 * @since 6175 175 */ 176 public Environment withChildAndIndexAndLinkContext(OsmPrimitive child, int index, int count) { 181 * @since 13810 (signature) 182 */ 183 public Environment withChildAndIndexAndLinkContext(IPrimitive child, int index, int count) { 177 184 Environment e = new Environment(this); 178 185 e.child = child; -
trunk/src/org/openstreetmap/josm/gui/mappaint/StyleSource.java
r13647 r13810 20 20 import javax.swing.ImageIcon; 21 21 22 import org.openstreetmap.josm.data.osm. OsmPrimitive;22 import org.openstreetmap.josm.data.osm.IPrimitive; 23 23 import org.openstreetmap.josm.data.preferences.sources.SourceEntry; 24 24 import org.openstreetmap.josm.data.preferences.sources.SourceType; … … 94 94 * we pretend it is. This is useful for generating area styles from the (segmented) 95 95 * outer ways of a multipolygon. 96 */ 97 public abstract void apply(MultiCascade mc, OsmPrimitive osm, double scale, boolean pretendWayIsClosed); 96 * @since 13810 (signature) 97 */ 98 public abstract void apply(MultiCascade mc, IPrimitive osm, double scale, boolean pretendWayIsClosed); 98 99 99 100 /** -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ConditionFactory.java
r13046 r13810 15 15 import java.util.regex.PatternSyntaxException; 16 16 17 import org.openstreetmap.josm.data.osm.IPrimitive; 17 18 import org.openstreetmap.josm.data.osm.Node; 18 19 import org.openstreetmap.josm.data.osm.OsmPrimitive; … … 681 682 * @param e MapCSS environment 682 683 * @return {@code true} if the object has an area style 683 * @see ElemStyles#hasAreaElemStyle( OsmPrimitive, boolean)684 * @see ElemStyles#hasAreaElemStyle(IPrimitive, boolean) 684 685 */ 685 686 static boolean areaStyle(Environment e) { // NO_UCD (unused code) … … 749 750 */ 750 751 static boolean inDownloadedArea(Environment e) { // NO_UCD (unused code) 751 return IN_DOWNLOADED_AREA.test(e.osm);752 return e.osm instanceof OsmPrimitive && IN_DOWNLOADED_AREA.test((OsmPrimitive) e.osm); 752 753 } 753 754 -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java
r13640 r13810 460 460 if (env.osm != null) { 461 461 // we don't have a matched parent, so just search all referrers 462 for ( OsmPrimitive parent : env.osm.getReferrers()) {462 for (IPrimitive parent : env.osm.getReferrers()) { 463 463 String value = parent.get(key); 464 464 if (value != null) { … … 485 485 final Collection<String> tags = new TreeSet<>(AlphanumComparator.getInstance()); 486 486 // we don't have a matched parent, so just search all referrers 487 for ( OsmPrimitive parent : env.osm.getReferrers()) {487 for (IPrimitive parent : env.osm.getReferrers()) { 488 488 String value = parent.get(key); 489 489 if (value != null) { -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java
r13800 r13810 30 30 31 31 import org.openstreetmap.josm.data.Version; 32 import org.openstreetmap.josm.data.osm.IPrimitive; 32 33 import org.openstreetmap.josm.data.osm.KeyValueVisitor; 33 34 import org.openstreetmap.josm.data.osm.Node; … … 357 358 * @param osm the primitive to match 358 359 * @return An iterator over possible rules in the right order. 359 */ 360 public Iterator<MapCSSRule> getRuleCandidates(OsmPrimitive osm) { 360 * @since 13810 (signature) 361 */ 362 public Iterator<MapCSSRule> getRuleCandidates(IPrimitive osm) { 361 363 final BitSet ruleCandidates = new BitSet(rules.size()); 362 364 ruleCandidates.or(remaining); … … 638 640 639 641 @Override 640 public void apply(MultiCascade mc, OsmPrimitive osm, double scale, boolean pretendWayIsClosed) {642 public void apply(MultiCascade mc, IPrimitive osm, double scale, boolean pretendWayIsClosed) { 641 643 MapCSSRuleIndex matchingRuleIndex; 642 644 if (osm instanceof Node) { -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
r12986 r13810 14 14 import java.util.regex.PatternSyntaxException; 15 15 16 import org.openstreetmap.josm.data.osm.INode; 17 import org.openstreetmap.josm.data.osm.IPrimitive; 18 import org.openstreetmap.josm.data.osm.IRelation; 19 import org.openstreetmap.josm.data.osm.IRelationMember; 20 import org.openstreetmap.josm.data.osm.IWay; 16 21 import org.openstreetmap.josm.data.osm.Node; 17 22 import org.openstreetmap.josm.data.osm.OsmPrimitive; … … 19 24 import org.openstreetmap.josm.data.osm.OsmUtils; 20 25 import org.openstreetmap.josm.data.osm.Relation; 21 import org.openstreetmap.josm.data.osm.RelationMember;22 26 import org.openstreetmap.josm.data.osm.Way; 23 import org.openstreetmap.josm.data.osm.visitor. OsmPrimitiveVisitor;27 import org.openstreetmap.josm.data.osm.visitor.PrimitiveVisitor; 24 28 import org.openstreetmap.josm.data.osm.visitor.paint.relations.MultipolygonCache; 25 29 import org.openstreetmap.josm.gui.mappaint.Environment; … … 145 149 * 146 150 */ 147 private class MatchingReferrerFinder implements OsmPrimitiveVisitor {151 private class MatchingReferrerFinder implements PrimitiveVisitor { 148 152 private final Environment e; 149 153 … … 157 161 158 162 @Override 159 public void visit( Node n) {163 public void visit(INode n) { 160 164 // node should never be a referrer 161 165 throw new AssertionError(); 162 166 } 163 167 164 private <T extends OsmPrimitive> void doVisit(T parent, IntSupplier counter, IntFunction<OsmPrimitive> getter) {168 private <T extends IPrimitive> void doVisit(T parent, IntSupplier counter, IntFunction<IPrimitive> getter) { 165 169 // If e.parent is already set to the first matching referrer. 166 170 // We skip any following referrer injected into the visitor. … … 187 191 188 192 @Override 189 public void visit( Wayw) {193 public void visit(IWay<?> w) { 190 194 doVisit(w, w::getNodesCount, w::getNode); 191 195 } 192 196 193 197 @Override 194 public void visit( Relationr) {198 public void visit(IRelation<?> r) { 195 199 doVisit(r, r::getMembersCount, i -> r.getMember(i).getMember()); 196 200 } 197 201 } 198 202 199 private abstract static class AbstractFinder implements OsmPrimitiveVisitor {203 private abstract static class AbstractFinder implements PrimitiveVisitor { 200 204 protected final Environment e; 201 205 … … 205 209 206 210 @Override 207 public void visit( Node n) {208 } 209 210 @Override 211 public void visit( Wayw) {212 } 213 214 @Override 215 public void visit( Relationr) {216 } 217 218 public void visit(Collection<? extends OsmPrimitive> primitives) {219 for ( OsmPrimitive p : primitives) {211 public void visit(INode n) { 212 } 213 214 @Override 215 public void visit(IWay<?> w) { 216 } 217 218 @Override 219 public void visit(IRelation<?> r) { 220 } 221 222 public void visit(Collection<? extends IPrimitive> primitives) { 223 for (IPrimitive p : primitives) { 220 224 if (e.child != null) { 221 225 // abort if first match has been found … … 227 231 } 228 232 229 public boolean isPrimitiveUsable( OsmPrimitive p) {233 public boolean isPrimitiveUsable(IPrimitive p) { 230 234 return !e.osm.equals(p) && p.isUsable(); 231 235 } … … 235 239 236 240 @Override 237 public void visit( Wayw) {241 public void visit(IWay<?> w) { 238 242 w.visitReferrers(innerVisitor); 239 243 } … … 243 247 } 244 248 245 private final OsmPrimitiveVisitor innerVisitor = new AbstractFinder(e) {249 private final PrimitiveVisitor innerVisitor = new AbstractFinder(e) { 246 250 @Override 247 public void visit( Relationr) {248 if ( left.matches(e.withPrimitive(r))) {249 final List<Node> openEnds = MultipolygonCache.getInstance().get( r).getOpenEnds();251 public void visit(IRelation<?> r) { 252 if (r instanceof Relation && left.matches(e.withPrimitive(r))) { 253 final List<Node> openEnds = MultipolygonCache.getInstance().get((Relation) r).getOpenEnds(); 250 254 final int openEndIndex = openEnds.indexOf(e.osm); 251 255 if (openEndIndex >= 0) { … … 265 269 private CrossingFinder(Environment e) { 266 270 super(e); 267 CheckParameterUtil.ensureThat(e.osm instanceof Way, "Only ways are supported");271 CheckParameterUtil.ensureThat(e.osm instanceof IWay, "Only ways are supported"); 268 272 layer = OsmUtils.getLayer(e.osm); 269 273 } 270 274 271 275 @Override 272 public void visit( Wayw) {276 public void visit(IWay<?> w) { 273 277 if (e.child == null && Objects.equals(layer, OsmUtils.getLayer(w)) 274 278 && left.matches(new Environment(w).withParent(e.osm)) 275 && e.osm instanceof Way && Geometry.PolygonIntersection.CROSSING.equals(279 && e.osm instanceof IWay && Geometry.PolygonIntersection.CROSSING.equals( 276 280 Geometry.polygonIntersection(w.getNodes(), ((Way) e.osm).getNodes()))) { 277 281 e.child = w; … … 283 287 protected ContainsFinder(Environment e) { 284 288 super(e); 285 CheckParameterUtil.ensureThat(!(e.osm instanceof Node), "Nodes not supported");286 } 287 288 @Override 289 public void visit( Node n) {289 CheckParameterUtil.ensureThat(!(e.osm instanceof INode), "Nodes not supported"); 290 } 291 292 @Override 293 public void visit(INode n) { 290 294 if (e.child == null && left.matches(new Environment(n).withParent(e.osm)) 291 && ((e.osm instanceof Way && Geometry.nodeInsidePolygon(n, ((Way) e.osm).getNodes()))295 && ((e.osm instanceof IWay && Geometry.nodeInsidePolygon(n, ((Way) e.osm).getNodes())) 292 296 || (e.osm instanceof Relation && ( 293 297 (Relation) e.osm).isMultipolygon() && Geometry.isNodeInsideMultiPolygon(n, (Relation) e.osm, null)))) { … … 297 301 298 302 @Override 299 public void visit( Wayw) {303 public void visit(IWay<?> w) { 300 304 if (e.child == null && left.matches(new Environment(w).withParent(e.osm)) 301 && ((e.osm instanceof Way && Geometry.PolygonIntersection.FIRST_INSIDE_SECOND.equals(305 && ((e.osm instanceof IWay && Geometry.PolygonIntersection.FIRST_INSIDE_SECOND.equals( 302 306 Geometry.polygonIntersection(w.getNodes(), ((Way) e.osm).getNodes()))) 303 307 || (e.osm instanceof Relation && ( … … 317 321 if (ChildOrParentSelectorType.ELEMENT_OF.equals(type)) { 318 322 319 if (e.osm instanceof Node || e.osm.getDataSet() == null) {323 if (e.osm instanceof INode || e.osm.getDataSet() == null) { 320 324 // nodes cannot contain elements 321 325 return false; … … 326 330 // if right selector also matches relations and if matched primitive is a way which is part of a multipolygon, 327 331 // use the multipolygon for further analysis 328 if (!(e.osm instanceof Way)332 if (!(e.osm instanceof IWay) 329 333 || (right instanceof OptimizedGeneralSelector 330 334 && !((OptimizedGeneralSelector) right).matchesBase(OsmPrimitiveType.RELATION))) { … … 338 342 containsFinder = new ContainsFinder(new Environment(multipolygon)) { 339 343 @Override 340 public boolean isPrimitiveUsable( OsmPrimitive p) {344 public boolean isPrimitiveUsable(IPrimitive p) { 341 345 return super.isPrimitiveUsable(p) && !members.contains(p); 342 346 } … … 362 366 return e.child != null; 363 367 364 } else if (ChildOrParentSelectorType.CROSSING.equals(type) && e.osm instanceof Way) {368 } else if (ChildOrParentSelectorType.CROSSING.equals(type) && e.osm instanceof IWay) { 365 369 e.parent = e.osm; 366 370 final CrossingFinder crossingFinder = new CrossingFinder(e); … … 371 375 return e.child != null; 372 376 } else if (ChildOrParentSelectorType.SIBLING.equals(type)) { 373 if (e.osm instanceof Node) { 374 for (Way w : Utils.filteredCollection(e.osm.getReferrers(true), Way.class)) { 375 final int i = w.getNodes().indexOf(e.osm); 376 if (i - 1 >= 0) { 377 final Node n = w.getNode(i - 1); 378 final Environment e2 = e.withPrimitive(n).withParent(w).withChild(e.osm); 379 if (left.matches(e2) && link.matches(e2.withLinkContext())) { 380 e.child = n; 381 e.index = i; 382 e.count = w.getNodesCount(); 383 e.parent = w; 384 return true; 377 if (e.osm instanceof INode) { 378 for (IPrimitive ref : e.osm.getReferrers(true)) { 379 if (ref instanceof IWay) { 380 IWay<?> w = (IWay<?>) ref; 381 final int i = w.getNodes().indexOf(e.osm); 382 if (i - 1 >= 0) { 383 final INode n = w.getNode(i - 1); 384 final Environment e2 = e.withPrimitive(n).withParent(w).withChild(e.osm); 385 if (left.matches(e2) && link.matches(e2.withLinkContext())) { 386 e.child = n; 387 e.index = i; 388 e.count = w.getNodesCount(); 389 e.parent = w; 390 return true; 391 } 385 392 } 386 393 } … … 390 397 && link.conds != null && !link.conds.isEmpty() 391 398 && link.conds.get(0) instanceof OpenEndPseudoClassCondition) { 392 if (e.osm instanceof Node) {399 if (e.osm instanceof INode) { 393 400 e.osm.visitReferrers(new MultipolygonOpenEndFinder(e)); 394 401 return e.parent != null; … … 400 407 return true; 401 408 } else if (ChildOrParentSelectorType.PARENT.equals(type)) { 402 if (e.osm instanceof Way) {403 List< Node> wayNodes = ((Way) e.osm).getNodes();409 if (e.osm instanceof IWay) { 410 List<? extends INode> wayNodes = ((IWay<?>) e.osm).getNodes(); 404 411 for (int i = 0; i < wayNodes.size(); i++) { 405 Node n = wayNodes.get(i);412 INode n = wayNodes.get(i); 406 413 if (left.matches(e.withPrimitive(n)) 407 414 && link.matches(e.withChildAndIndexAndLinkContext(n, i, wayNodes.size()))) { … … 412 419 } 413 420 } 414 } else if (e.osm instanceof Relation) {415 List< RelationMember> members = ((Relation) e.osm).getMembers();421 } else if (e.osm instanceof IRelation) { 422 List<? extends IRelationMember<?>> members = ((IRelation<?>) e.osm).getMembers(); 416 423 for (int i = 0; i < members.size(); i++) { 417 OsmPrimitive member = members.get(i).getMember();424 IPrimitive member = members.get(i).getMember(); 418 425 if (left.matches(e.withPrimitive(member)) 419 426 && link.matches(e.withChildAndIndexAndLinkContext(member, i, members.size()))) { … … 624 631 } 625 632 626 public boolean matchesBase( OsmPrimitive p) {633 public boolean matchesBase(IPrimitive p) { 627 634 if (!matchesBase(p.getType())) { 628 635 return false; 629 636 } else { 630 if (p instanceof Relation) {637 if (p instanceof IRelation) { 631 638 if ("area".equals(base)) { 632 return (( Relation) p).isMultipolygon();639 return ((IRelation<?>) p).isMultipolygon(); 633 640 } else if ("canvas".equals(base)) { 634 641 return p.get("#canvas") != null;
Note:
See TracChangeset
for help on using the changeset viewer.