2002/08/18 05:30:45
[org.ibex.core.git] / src / org / xwt / Template.java
index e2eb037..f345718 100644 (file)
@@ -90,6 +90,8 @@ public class Template {
     /** number of lines in <tt>content</tt> */
     private int content_lines = 0;
 
+    /** the line number that this element starts on */
+    private int startLine = -1;
 
     // Static data/methods ///////////////////////////////////////////////////////////////////
 
@@ -137,10 +139,12 @@ public class Template {
 
     // Methods to apply templates ////////////////////////////////////////////////////////
 
-    private Template() { } 
-    private Template(InputStream is, String nodeName) throws XML.SAXException, IOException {
+    private Template(String nodeName) {
         this.nodeName = nodeName;
         cache.put(nodeName, this);
+    }
+    private Template(InputStream is, String nodeName) throws XML.SAXException, IOException {
+        this(nodeName);
         new TemplateHelper().parseit(is, this);
     }
 
@@ -161,7 +165,9 @@ public class Template {
      *  @param pboxes a vector of all box parents on which to put $-references
      *  @param ptemplates a vector of the nodeNames to recieve private references on the pboxes
      */
-    void apply(Box b, Vec pboxes, Vec ptemplates) {
+    void apply(Box b, Vec pboxes, Vec ptemplates, Function callback, int numerator, int denominator) {
+
+        int original_numerator = numerator;
 
         if (pboxes == null) {
             pboxes = new Vec();
@@ -185,10 +191,15 @@ public class Template {
         link();
 
         for(int i=0; _preapply != null && i<_preapply.length; i++)
-            if (_preapply[i] != null) _preapply[i].apply(b, null, null);
+            if (_preapply[i] != null) {
+                _preapply[i].apply(b, null, null, callback, numerator, denominator);
+                numerator += _preapply[i].numUnits();
+            }
 
-        for (int i=0; children != null && i<children.length; i++)
-            b.put(Integer.MAX_VALUE, null, new Box(children[i], pboxes, ptemplates));
+        for (int i=0; children != null && i<children.length; i++) {
+            b.put(Integer.MAX_VALUE, null, new Box(children[i], pboxes, ptemplates, callback, numerator, denominator));
+            numerator += children[i].numUnits();
+        }
 
         // whom to redirect to; doesn't take effect until after script runs
         Box redir = null;
@@ -206,29 +217,49 @@ public class Template {
             if (Log.on) Log.log(this, "         thrown while instantiating " + nodeName + " at " + e.sourceFile + ":" + e.line);
         }
 
-        for(int i=0; keys != null && i<keys.length; i++)
+        for(int i=0; keys != null && i<keys.length; i++) {
+            Context.enter().interpreterSourceFile = nodeName;
+            Context.enter().interpreterLine = startLine;
             if (keys[i] == null) { }
-            else if (keys[i].equals("border") || keys[i].equals("image")) {
-                if (vals[i].startsWith("http://") || vals[i].startsWith("https://")) {
-                    b.put(keys[i], null, s.substring(0, s.length() - 4));
-                } else {
-                    String s = Resources.resolve(vals[i].toString() + ".png", importlist);
-                    if (s != null) b.put(keys[i], null, s.substring(0, s.length() - 4));
-                    else if (Log.on) Log.log(this, "unable to resolve image " + vals[i].toString() + " referenced in attributes of " + nodeName); 
-                }
+            else if (keys[i].equals("border") || keys[i].equals("image") &&
+                     !vals[i].toString().startsWith("http://") && !vals[i].toString().startsWith("https://")) {
+                String s = Resources.resolve(vals[i].toString() + ".png", importlist);
+                if (s != null) b.put(keys[i], null, s.substring(0, s.length() - 4));
+                else if (Log.on) Log.log(this, "unable to resolve image " + vals[i].toString() + " referenced in attributes of " + nodeName); 
             }
             else b.put(keys[i], null, vals[i]);
+        }
 
         if (redirect != null && !"self".equals(redirect)) b.redirect = redir;
 
         for(int i=0; _postapply != null && i<_postapply.length; i++)
-            if (_postapply[i] != null) _postapply[i].apply(b, null, null);
+            if (_postapply[i] != null) {
+                _postapply[i].apply(b, null, null, callback, numerator, denominator);
+                numerator += _postapply[i].numUnits();
+            }
 
         pboxes.setSize(numids);
         ptemplates.setSize(numids);
 
-        Main.instantiatedUnits += 1 + (script == null ? 0 : 10) + (keys == null ? 0 : keys.length);
-        Main.updateSplashScreen();
+        numerator = original_numerator + numUnits();
+
+        if (callback != null)
+            try {
+                callback.call(Context.enter(), null, null, new Object[] { new Double(numerator), new Double(denominator) });
+            } catch (EcmaError e) {
+                if (Log.on) Log.log(this, "WARNING: uncaught interpreter exception: " + e.getMessage());
+                if (Log.on) Log.log(this, "         thrown from within progress callback at " + e.getSourceName() + ":" + e.getLineNumber());
+            } catch (JavaScriptException e) {
+                if (Log.on) Log.log(this, "WARNING: uncaught ecmascript exception: " + e.getMessage());
+                if (Log.on) Log.log(this, "         thrown from within progress callback at " + e.sourceFile + ":" + e.line);
+            }
+
+        if (Thread.currentThread() instanceof ThreadMessage) try {
+            XWT.yield.call(Context.enter(), null, null, null);
+        } catch (JavaScriptException e) {
+            if (Log.on) Log.log(this, "WARNING: uncaught ecmascript exception: " + e.getMessage());
+            if (Log.on) Log.log(this, "         thrown from within yield at " + e.sourceFile + ":" + e.line);
+        }
     }
 
 
@@ -274,8 +305,7 @@ public class Template {
             if (t != b.template) retemplatize = true;
             b.template = t;
         }
-        if (b.template != null && b.template.changed)
-            retemplatize = true;
+        if (b.template != null && b.template.changed) retemplatize = true;
 
         if (retemplatize) {
 
@@ -310,7 +340,7 @@ public class Template {
             Trap.removeAllTrapsByBox(b);
             
             // Ref 7.5.7: "Apply the template to the box according to the usual application procedure"
-            b.template.apply(b, null, null);
+            b.template.apply(b, null, null, null, 0, 1);
             
             // Ref 7.5.8: "Re-add the saved children which were removed in step 3"
             for(int i=0; kids != null && i<kids.length; i++) b.put(Integer.MAX_VALUE, null, kids[i]);
@@ -330,7 +360,7 @@ public class Template {
     private void link(boolean force) {
 
         if (staticscript != null) try { 
-            Scriptable s = Static.getStatic(nodeName);
+            Scriptable s = Static.createStatic(nodeName, false);
             if (staticscript != null) {
                 Script temp = staticscript;
                 ((InterpretedScript)temp).setParentScope(s);     // so we know how to handle Static.get("xwt")
@@ -479,6 +509,7 @@ public class Template {
 
                 } else if (name.equals("template")) {
                     // finalize importlist/preapply/postapply, since they can't change from here on
+                    t.startLine = line;
                     importlist.toArray(t.importlist = new String[importlist.size()]);
                     if (preapply.size() > 0) preapply.copyInto(t.preapply = new String[preapply.size()]);
                     if (postapply.size() > 0) postapply.copyInto(t.postapply = new String[postapply.size()]);
@@ -496,9 +527,9 @@ public class Template {
                 nodeStack.addElement(t);
 
                 // instantiate a new node, and set its nodeName/importlist/preapply
-                Template t2 = new Template();
-                t2.nodeName = t.nodeName + "." + t.childvect.size();
+                Template t2 = new Template(t.nodeName + "." + t.childvect.size());
                 t2.importlist = t.importlist;
+                t2.startLine = line;
                 if (!name.equals("box")) t2.preapply = new String[] { name };
 
                 // make the new node the current node