Various rendering/CSS parsing improvements. Tagged-nodes-in-ways still needs looking...
[potlatch2.git] / net / systemeD / halcyon / styleparser / Style.as
1 package net.systemeD.halcyon.styleparser {
2
3         import flash.utils.ByteArray;
4         import flash.net.*;
5         import net.systemeD.halcyon.Globals;
6
7         public class Style {
8
9                 public var merged:Boolean=false;
10                 public var edited:Boolean=false;                // true once a property has been set from a string
11                 public var sublayer:uint=5;
12                 public var evals:Object={};                             // compiled SWFs for each eval. We keep it here, not in the property 
13                                                                                                 //  | itself, so that we can retain typing for each property
14
15                 // Return an exact copy of this object
16                 // ** this needs some benchmarking - may be quicker to iterate over .properties, copying each one
17
18                 public function deepCopy():* {
19                         registerClassAlias("net.systemeD.halcyon.styleparser.ShapeStyle",ShapeStyle);
20                         registerClassAlias("net.systemeD.halcyon.styleparser.TextStyle",TextStyle);
21                         registerClassAlias("net.systemeD.halcyon.styleparser.PointStyle",PointStyle);
22                         registerClassAlias("net.systemeD.halcyon.styleparser.ShieldStyle",ShieldStyle);
23                         registerClassAlias("net.systemeD.halcyon.styleparser.InstructionStyle",InstructionStyle);
24                         var a:ByteArray=new ByteArray();
25                         a.writeObject(this);
26                         a.position=0;
27                         return (a.readObject());
28                 }
29
30                 // Add properties from another object
31
32                 public function mergeWith(additional:Style):void {
33                         for each (var prop:String in properties) {
34                                 if (additional[prop]) {
35                                         this[prop]=additional[prop];
36                                 }
37                         }
38                         this.merged=true;
39                 }
40
41                 // Getter (to be overridden) for property list
42
43                 public function get properties():Array {
44                         return [];
45                 }
46                 
47                 // Eval handling
48                 
49                 public function hasEvals():Boolean {
50                         for (var k:String in evals) { return true; }
51                         return false;
52                 }
53                 
54                 public function runEvals(tags:Object):void {
55                         for (var k:String in evals) {
56                                 // ** Do we need to do typing here?
57                                 this[k]=evals[k].exec(tags);
58                         }
59                 }
60
61                 // Set property and cast as correct type (used in stylesheet imports)
62                 
63                 public function setPropertyFromString(k:String,v:*):Boolean {
64                         if (!this.hasOwnProperty(k)) { return false; }
65                         if (v is Eval) { evals[k]=v; v=1; }
66
67                         // Arrays don't return a proper typeof, so check manually
68                         // Note that undefined class variables always have typeof=object,
69                         // so we need to declare them as empty arrays (cf ShapeStyle)
70                         if (this[k] is Array) {
71                                 // Split comma-separated array and coerce as numbers
72                                 this[k]=v.split(',').map(function(el:Object,index:int,array:Array):Number { return Number(el); });
73                                 edited=true; return true;
74                         }
75
76                         // Check for other object types
77                         switch (typeof(this[k])) {
78                                 case "number":  this[k]=Number(v) ; edited=true; return true;
79                                 case "object":  // **for now, just assume objects are undefined strings
80                                                                 // We'll probably need to fix this in future if we have more complex
81                                                                 // properties
82                                 case "string":  this[k]=String(v) ; edited=true; return true;
83                                 case "boolean": this[k]=Boolean(v); edited=true; return true;
84                         }
85                         return false;
86                 }
87         }
88 }