2002/07/16 00:39:23
[org.ibex.core.git] / src / org / xwt / Template.java
index 74eceee..859c39e 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 ///////////////////////////////////////////////////////////////////
 
@@ -161,7 +163,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 +189,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,7 +215,9 @@ 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") &&
                      !vals[i].toString().startsWith("http://") && !vals[i].toString().startsWith("https://")) {
@@ -215,17 +226,38 @@ public class Template {
                 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);
+        }
     }
 
 
@@ -307,7 +339,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]);
@@ -327,7 +359,7 @@ public class Template {
     private void link(boolean force) {
 
         if (staticscript != null) try { 
-            Scriptable s = Static.getStatic(nodeName);
+            Scriptable s = Static.createStatic(nodeName);
             if (staticscript != null) {
                 Script temp = staticscript;
                 ((InterpretedScript)temp).setParentScope(s);     // so we know how to handle Static.get("xwt")
@@ -476,6 +508,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,6 +529,7 @@ public class Template {
                 Template t2 = new Template();
                 t2.nodeName = 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