New RuleChain object to replace previous nested array within StyleChooser
[potlatch2.git] / net / systemeD / halcyon / styleparser / NestedCSSLoader.as
1 package net.systemeD.halcyon.styleparser {
2
3         import flash.events.*;
4         import flash.net.URLLoader;
5         import flash.net.URLLoaderDataFormat;
6         import flash.net.URLRequest;
7
8         /** A class permitting you to load CSS files containing 'import' rules, which will be 
9                 automatically replaced with the contents of the file.                                                                   <p>
10         
11                 Typical usage:                                                                                                                                                  </p><pre>
12         
13                         cssLoader=new NestedCSSLoader();
14                         cssLoader.addEventListener(Event.COMPLETE, doParseCSS);
15                         cssLoader.load("potlatch.css");                                                                                                         </pre><p>
16         
17                 doParseCSS can then access the CSS via event.target.css.                                                                </p>
18         */
19
20         public class NestedCSSLoader extends EventDispatcher {
21                 private var sourceCSS:String;
22                 public var css:String;
23                 private var url:String;
24                 private var count:int;
25
26                 private static const IMPORT:RegExp=/@import\s*[^'"]*['"]([^'"]+)['"][^;]*;/g;           // '
27
28                 public function NestedCSSLoader() {
29                 }
30                 
31                 public function load(url:String):void {
32                         this.url=url;
33                         var request:URLRequest=new URLRequest(url+"?d="+Math.random());
34                         var loader:URLLoader = new URLLoader();
35                         loader.dataFormat = URLLoaderDataFormat.TEXT;
36                         loader.addEventListener(Event.COMPLETE, fileLoaded);
37                         loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, fileError);
38                         loader.addEventListener(IOErrorEvent.IO_ERROR, fileError);
39                         loader.load(request);
40                 }
41                 
42                 private function fileLoaded(event:Event):void {
43                         sourceCSS=URLLoader(event.target).data;
44                         css=sourceCSS;
45                         count=0;
46
47                         var result:Object=IMPORT.exec(sourceCSS);
48                         while (result!=null) {
49                                 count++;
50                                 replaceCSS(result[1],result[0]);
51                                 result=IMPORT.exec(sourceCSS);
52                         }
53                         if (count==0) { fireComplete(); }
54                 }
55
56                 private function replaceCSS(filename:String, toReplace:String):void {
57                         var cssLoader:NestedCSSLoader=new NestedCSSLoader();
58                         var replaceText:String=toReplace;
59                         cssLoader.addEventListener(Event.COMPLETE, function(event:Event):void {
60                                 css=css.replace(replaceText,event.target.css);
61                                 decreaseCount();
62                         });
63                         cssLoader.load(filename+"?d="+Math.random());
64                 }
65
66                 private function fileError(event:Event):void {
67                         // just fire a complete event so we don't get an error dialogue
68                         trace("Error while trying to load "+url);
69                         fireComplete();
70                 }
71                 
72                 private function decreaseCount():void {
73                         count--; if (count>0) return;
74                         fireComplete();
75                 }
76                 
77                 private function fireComplete():void {
78                         var event:Event=new Event(Event.COMPLETE);
79                         dispatchEvent(event);
80                 }
81         }
82 }