gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] /srv/bzr/gnash/trunk r11240: AS implementation of most of


From: Benjamin Wolsey
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r11240: AS implementation of most of ContextMenu.
Date: Thu, 09 Jul 2009 21:09:27 +0200
User-agent: Bazaar (1.13.1)

------------------------------------------------------------
revno: 11240
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Thu 2009-07-09 21:09:27 +0200
message:
  AS implementation of most of ContextMenu.
modified:
  libcore/asobj/flash/ui/ContextMenu_as.cpp
  testsuite/actionscript.all/ContextMenu.as
  testsuite/swfdec/PASSING
    ------------------------------------------------------------
    revno: 11239.1.1
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Thu 2009-07-09 16:49:13 +0200
    message:
      Remove the cruft from ContextMenu.
    modified:
      libcore/asobj/flash/ui/ContextMenu_as.cpp
    ------------------------------------------------------------
    revno: 11239.1.2
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Thu 2009-07-09 17:09:06 +0200
    message:
      Implement more of ContextMenu AS interface correctly.
    modified:
      libcore/asobj/flash/ui/ContextMenu_as.cpp
    ------------------------------------------------------------
    revno: 11239.1.3
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Thu 2009-07-09 17:09:26 +0200
    message:
      Passing tests.
    modified:
      testsuite/actionscript.all/ContextMenu.as
    ------------------------------------------------------------
    revno: 11239.1.4
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Thu 2009-07-09 17:29:30 +0200
    message:
      Check that ContextMenu.hideBuiltInItems isn't fussy.
    modified:
      testsuite/actionscript.all/ContextMenu.as
    ------------------------------------------------------------
    revno: 11239.1.5
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Thu 2009-07-09 17:37:27 +0200
    message:
      It doesn't even need a builtInItems object.
    modified:
      testsuite/actionscript.all/ContextMenu.as
    ------------------------------------------------------------
    revno: 11239.1.6
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Thu 2009-07-09 17:51:37 +0200
    message:
      Update totals.
    modified:
      testsuite/actionscript.all/ContextMenu.as
    ------------------------------------------------------------
    revno: 11239.1.7
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Thu 2009-07-09 17:52:36 +0200
    message:
      Passes in swfdec.
    modified:
      testsuite/swfdec/PASSING
    ------------------------------------------------------------
    revno: 11239.1.8
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Thu 2009-07-09 18:03:35 +0200
    message:
      Test copy().
    modified:
      testsuite/actionscript.all/ContextMenu.as
    ------------------------------------------------------------
    revno: 11239.1.9
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Thu 2009-07-09 18:24:29 +0200
    message:
      More tests.
    modified:
      testsuite/actionscript.all/ContextMenu.as
    ------------------------------------------------------------
    revno: 11239.1.10
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Thu 2009-07-09 18:24:50 +0200
    message:
      Pass hideBuiltInItems tests, not yet copy property.
    modified:
      libcore/asobj/flash/ui/ContextMenu_as.cpp
    ------------------------------------------------------------
    revno: 11239.1.11
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Thu 2009-07-09 18:27:52 +0200
    message:
      Drop ContextMenu_as class.
    modified:
      libcore/asobj/flash/ui/ContextMenu_as.cpp
    ------------------------------------------------------------
    revno: 11239.1.12
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Thu 2009-07-09 18:44:52 +0200
    message:
      Pass copy tests.
    modified:
      libcore/asobj/flash/ui/ContextMenu_as.cpp
    ------------------------------------------------------------
    revno: 11239.1.13
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Thu 2009-07-09 18:53:13 +0200
    message:
      Test more.
    modified:
      testsuite/actionscript.all/ContextMenu.as
    ------------------------------------------------------------
    revno: 11239.1.14
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Thu 2009-07-09 18:53:18 +0200
    message:
      Make a deep copy of values when they are objects.
    modified:
      libcore/asobj/flash/ui/ContextMenu_as.cpp
    ------------------------------------------------------------
    revno: 11239.1.15
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Thu 2009-07-09 19:54:57 +0200
    message:
      Add more tests for copying customItems.
    modified:
      testsuite/actionscript.all/ContextMenu.as
    ------------------------------------------------------------
    revno: 11239.1.16
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Thu 2009-07-09 19:58:39 +0200
    message:
      Totals and xcheck.
    modified:
      testsuite/actionscript.all/ContextMenu.as
    ------------------------------------------------------------
    revno: 11239.1.17
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Thu 2009-07-09 19:58:49 +0200
    message:
      Do a partial implementation of copy, which is enough to pass the swfdec
      tests but not actionscript.all.
    modified:
      libcore/asobj/flash/ui/ContextMenu_as.cpp
    ------------------------------------------------------------
    revno: 11239.1.18
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Thu 2009-07-09 20:00:59 +0200
    message:
      Update comments.
    modified:
      libcore/asobj/flash/ui/ContextMenu_as.cpp
=== modified file 'libcore/asobj/flash/ui/ContextMenu_as.cpp'
--- a/libcore/asobj/flash/ui/ContextMenu_as.cpp 2009-07-09 09:34:12 +0000
+++ b/libcore/asobj/flash/ui/ContextMenu_as.cpp 2009-07-09 18:00:59 +0000
@@ -30,189 +30,66 @@
 #include "GnashException.h" // for ActionException
 #include "Object.h" // for getObjectInterface
 #include "namedStrings.h"
+#include "Array_as.h"
 
 namespace gnash {
 
 // Forward declarations
 namespace {
     as_value contextmenu_hideBuiltInItems(const fn_call& fn);
-    as_value contextmenu_menuSelect(const fn_call& fn);
+    as_value contextmenu_copy(const fn_call& fn);
     as_value contextmenu_ctor(const fn_call& fn);
+
     void attachContextMenuInterface(as_object& o);
     void attachContextMenuStaticInterface(as_object& o);
     as_object* getContextMenuInterface();
-
-}
-
-class ContextMenu_as : public as_object
-{
-
-public:
-
-    ContextMenu_as()
-        :
-        as_object(getExportedInterface())
-    {}
-
-    ContextMenu_as(const as_value& callback)
-               :
-               as_object(getExportedInterface())
-       {
-               setCallback(callback);
-       }
-
-    ContextMenu_as(as_function* callback)
-               :
-               as_object(getExportedInterface())
-       {
-               setCallback(callback);
-       }
-
-       static void registerConstructor(as_object& global);
-
-       // override from as_object ?
-       //std::string get_text_value() const { return "ContextMenu"; }
-
-       // override from as_object ?
-       //double get_numeric_value() const { return 0; }
-
-private:
-
-       /// Get the callback to call when user invokes the context menu.
-       //
-       /// If NULL, no action will be taken on select.
-       ///
-       as_function* getCallback() 
-       {
-               as_value tmp;
-               if (get_member(NSV::PROP_ON_SELECT, &tmp))
-                       return tmp.to_as_function();
-               else return NULL;
-       }
-
-       /// Set the callback to call when user invokes the context menu.
-       //
-       /// @param callback
-       ///     The function to call. If the value is not a function, no
-       ///     action will be taken on select.
-       ///
-       void setCallback(const as_value& callback)
-       {
-               set_member(NSV::PROP_ON_SELECT, callback);
-       }
-
-       /// Attach the exported interface of this ActionScript class
-       /// to the given object.
-       static void attachExportedInterface(as_object& o);
-
-       /// Get the ContextMenu.prototype ActionScript object
-       static as_object* getExportedInterface();
-
-       static as_value ctor_method(const fn_call& fn);
-
-       static as_value hideBuiltInItems_method(const fn_call& fn);
-
-       static as_value copy_method(const fn_call& fn);
-
-};
-
-
-/* static private */
-void
-ContextMenu_as::attachExportedInterface(as_object& o)
-{
-       o.init_member("copy", new 
builtin_function(ContextMenu_as::copy_method));
-       o.init_member("hideBuiltInItems", new 
builtin_function(ContextMenu_as::hideBuiltInItems_method));
-}
-
-/* static private */
-as_object*
-ContextMenu_as::getExportedInterface()
-{
-       static boost::intrusive_ptr<as_object> o;
-       if ( ! o )
-       {
-               o = new as_object(getObjectInterface());
-               attachExportedInterface(*o);
-       }
-       return o.get();
-}
-
-
-/* static private */
-as_value
-ContextMenu_as::copy_method(const fn_call& fn)
-{
-       boost::intrusive_ptr<ContextMenu_as> ptr = 
ensureType<ContextMenu_as>(fn.this_ptr);
-       UNUSED(ptr);
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-/* static private */
-as_value
-ContextMenu_as::hideBuiltInItems_method(const fn_call& fn)
-{
-       boost::intrusive_ptr<ContextMenu_as> ptr = 
ensureType<ContextMenu_as>(fn.this_ptr);
-       UNUSED(ptr);
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-/* static private */
-as_value
-ContextMenu_as::ctor_method(const fn_call& fn)
-{
-       boost::intrusive_ptr<as_object> obj;
-       if ( fn.nargs > 0 )
-                       obj = new ContextMenu_as(fn.arg(0));
-       else
-               obj = new ContextMenu_as();
-       
-       return as_value(obj.get()); // will keep alive
-}
-
-/* static public */
-void
-ContextMenu_as::registerConstructor(as_object& global)
-{
-       // This is going to be the global ContextMenu "class"/"function"
+    as_object* setBuiltInItems();
+
+}
+
+// extern (used by Global.cpp)
+void
+contextmenu_class_init(as_object& global)
+{
        static boost::intrusive_ptr<builtin_function> cl;
 
-       if ( cl == NULL )
-       {
-               cl=new builtin_function(ContextMenu_as::ctor_method, 
ContextMenu_as::getExportedInterface());
-               // replicate all interface to class, to be able to access
-               // all methods as static functions
-               ContextMenu_as::attachExportedInterface(*cl);
-                    
+       if (cl == NULL) {
+               cl=new builtin_function(contextmenu_ctor, 
getContextMenuInterface());
        }
 
        // Register _global.ContextMenu
        global.init_member("ContextMenu", cl.get());
-
 }
 
-// extern (used by Global.cpp)
-void contextmenu_class_init(as_object& global)
+
+namespace {
+
+void
+setBuiltInItems(as_object& o, bool setting)
 {
-       ContextMenu_as::registerConstructor(global);
+    const int flags = 0;
+    string_table& st = o.getVM().getStringTable();
+    o.set_member(st.find("print"), setting, flags);
+    o.set_member(st.find("forward_back"), setting, flags);
+    o.set_member(st.find("rewind"), setting, flags);
+    o.set_member(st.find("loop"), setting, flags);
+    o.set_member(st.find("play"), setting, flags);
+    o.set_member(st.find("quality"), setting, flags);
+    o.set_member(st.find("zoom"), setting, flags);
+    o.set_member(st.find("save"), setting, flags);
 }
 
 
-namespace {
-
 void
 attachContextMenuInterface(as_object& o)
 {
-    o.init_member("hideBuiltInItems", new 
builtin_function(contextmenu_hideBuiltInItems));
-    o.init_member("menuSelect", new builtin_function(contextmenu_menuSelect));
-}
-
-void
-attachContextMenuStaticInterface(as_object& o)
-{
-
+    const int flags = as_prop_flags::dontDelete |
+                      as_prop_flags::dontEnum |
+                      as_prop_flags::onlySWF7Up;
+
+    o.init_member("hideBuiltInItems",
+            new builtin_function(contextmenu_hideBuiltInItems), flags);
+    o.init_member("copy", new builtin_function(contextmenu_copy), flags);
 }
 
 as_object*
@@ -220,8 +97,9 @@
 {
     static boost::intrusive_ptr<as_object> o;
     if ( ! o ) {
-        o = new as_object();
+        o = new as_object(getObjectInterface());
         attachContextMenuInterface(*o);
+        VM::get().addStatic(o.get());
     }
     return o.get();
 }
@@ -229,27 +107,67 @@
 as_value
 contextmenu_hideBuiltInItems(const fn_call& fn)
 {
-    boost::intrusive_ptr<ContextMenu_as> ptr =
-        ensureType<ContextMenu_as>(fn.this_ptr);
-    UNUSED(ptr);
-    LOG_ONCE( log_unimpl (__FUNCTION__) );
+    boost::intrusive_ptr<as_object> ptr = ensureType<as_object>(fn.this_ptr);
+    string_table& st = fn.getVM().getStringTable();
+    as_object* builtIns = new as_object;
+    setBuiltInItems(*builtIns, false);
+    ptr->set_member(st.find("builtInItems"), builtIns);
     return as_value();
 }
 
 as_value
-contextmenu_menuSelect(const fn_call& fn)
+contextmenu_copy(const fn_call& fn)
 {
-    boost::intrusive_ptr<ContextMenu_as> ptr =
-        ensureType<ContextMenu_as>(fn.this_ptr);
-    UNUSED(ptr);
-    LOG_ONCE( log_unimpl (__FUNCTION__) );
-    return as_value();
+    boost::intrusive_ptr<as_object> ptr = ensureType<as_object>(fn.this_ptr);
+    as_object* o = new as_object(getContextMenuInterface());
+    
+    string_table& st = ptr->getVM().getStringTable();
+    as_value onSelect, builtInItems;
+    as_value customItems = new Array_as;;
+
+    ptr->get_member(NSV::PROP_ON_SELECT, &onSelect);
+    ptr->get_member(st.find("builtInItems"), &builtInItems);
+    ptr->get_member(st.find("customItems"), &customItems);
+
+    // The onSelect and the builtInItems property are simple copies, which
+    // means the new object has a reference to the same object.
+    o->set_member(NSV::PROP_ON_SELECT, onSelect);
+    o->set_member(st.find("builtInItems"), builtInItems);
+
+    // The customItems object is a deep copy, but only of elements that are
+    // instances of ContextMenuItem (have its prototype as a __proto__ member).
+    as_object* nc = new Array_as;
+    as_object* customs;
+
+    if (customItems.is_object() && (customs = customItems.to_object().get())) {
+        // TODO: only copy properties that are ContextMenuItems.
+        nc->copyProperties(*customs);
+        customItems = nc;
+    }
+
+    o->set_member(st.find("customItems"), customItems);
+
+    return as_value(o);
 }
 
 as_value
 contextmenu_ctor(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> obj = new ContextMenu_as;
+    boost::intrusive_ptr<as_object> obj =
+        new as_object(getContextMenuInterface());
+
+    // There is always an onSelect member, but it may be undefined.
+    const as_value& callback = fn.nargs ? fn.arg(0) : as_value();
+    obj->set_member(NSV::PROP_ON_SELECT, callback);
+    
+    string_table& st = fn.getVM().getStringTable();
+    as_object* builtInItems = new as_object;
+    setBuiltInItems(*builtInItems, true);
+    obj->set_member(st.find("builtInItems"), builtInItems);
+
+    // There is an empty customItems array.
+    Array_as* customItems = new Array_as();
+    obj->set_member(st.find("customItems"), customItems);
 
     return as_value(obj.get()); // will keep alive
 }

=== modified file 'testsuite/actionscript.all/ContextMenu.as'
--- a/testsuite/actionscript.all/ContextMenu.as 2009-07-09 14:11:47 +0000
+++ b/testsuite/actionscript.all/ContextMenu.as 2009-07-09 17:58:39 +0000
@@ -56,20 +56,20 @@
   check_equals(typeof(cm.copy), "function");
   check_equals(typeof(cm.hideBuiltInItems), "function");
 
-  xcheck(cm.hasOwnProperty("builtInItems"));  
-  xcheck(cm.hasOwnProperty("customItems"));
-  xcheck(cm.hasOwnProperty("onSelect"));  
+  check(cm.hasOwnProperty("builtInItems"));  
+  check(cm.hasOwnProperty("customItems"));
+  check(cm.hasOwnProperty("onSelect"));  
 
-  xcheck_equals(typeof(cm.builtInItems), "object");  
+  check_equals(typeof(cm.builtInItems), "object");  
   check(!cm.builtInItems instanceof Array);
   check_equals(typeof(cm.builtInItems.length), 'undefined');
 
-  xcheck_equals(typeof(cm.customItems), "object");
-  xcheck(cm.customItems instanceof Array);
-  xcheck_equals(typeof(cm.customItems.length), 'number');
+  check_equals(typeof(cm.customItems), "object");
+  check(cm.customItems instanceof Array);
+  check_equals(typeof(cm.customItems.length), 'number');
 
   // There are no custom items by default.
-  xcheck_equals(cm.customItems.length, 0);
+  check_equals(cm.customItems.length, 0);
 
   check_equals(typeof(cm.onSelect), "undefined");
  
@@ -81,8 +81,119 @@
      check_equals(typeof(o[i]), "boolean");
      s += i + ",";
   }
-  xcheck_equals(s, "save,zoom,quality,play,loop,rewind,forward_back,print,");
-
+  check_equals(s, "save,zoom,quality,play,loop,rewind,forward_back,print,");
+
+
+  // Check that the hideBuiltInItems method isn't fussy.
+  e = {};
+  e.f = ContextMenu.prototype.hideBuiltInItems;
+  e.f();
+  s = "";
+  for (i in e.builtInItems) {
+      s += i + ":" + e.builtInItems[i] + ",";
+  };
+  check_equals(s, 
"save:false,zoom:false,quality:false,play:false,loop:false,rewind:false,forward_back:false,print:false,");
+
+  e.a = "string";
+  e.builtInItems.extraProp = "boo";
+
+  // Check the copy method. The original object has the following members:
+  // f : function
+  // builtInItems : object
+  // a : string
+  //
+  // The builtInItems has an extra property.
+
+  e.copy = ContextMenu.prototype.copy;
+  ee = e.copy();
+  check(!ee.hasOwnProperty("a"));
+  check(!ee.hasOwnProperty("f"));
+  check(ee.hasOwnProperty("onSelect"));
+  check(ee.hasOwnProperty("builtInItems"));
+  check(ee.hasOwnProperty("customItems"));
+
+  check_equals(typeof(ee.builtInItems), "object");
+  check_equals(typeof(ee.builtInItems.extraProp), "string");
+  check_equals(ee.builtInItems.extraProp, "boo");
+  check(ee instanceof ContextMenu);
+
+  // It will copy any expected properties, not only if they are objects, and
+  // add those that aren't there. The customItems array is cloned; if the
+  // original customItems member isn't an array, the new array is empty.
+  f = {};
+  f.builtInItems = 6;
+  f.copy = ContextMenu.prototype.copy;
+  ff = f.copy();
+  check(ff.hasOwnProperty("builtInItems"));
+  check(ff.hasOwnProperty("customItems"));
+  check(ff.hasOwnProperty("onSelect"));
+  check_equals(ff.builtInItems, 6);
+  check_equals(typeof(ff.customItems), "object");
+  check(ff.customItems instanceof Array);
+
+  f.customItems = 88;
+  ff = f.copy();
+  xcheck_equals(typeof(ff.customItems), "object");
+
+  f.customItems = {};
+  f.customItems.p = "hello";
+  ff = f.copy();
+  check_equals(ff.customItems.length, 0);
+  xcheck_equals(ff.customItems.p, undefined);
+
+  f.customItems = new Array;
+  f.customItems.push("hello");
+  ff = f.copy();
+  check_equals(ff.customItems.length, 1);
+  xcheck_equals(ff.customItems[0], undefined);
+
+  h = function() {};
+
+  cmi = new ContextMenuItem("hi", h);
+  f.customItems.push(cmi);
+  ff = f.copy();
+  check_equals(f.customItems.length, 2);
+  xcheck_equals(f.customItems[1].caption, "hi");
+  check_equals(ff.customItems.length, 2);
+  xcheck_equals(ff.customItems[1].caption, "hi");
+
+  c = {};
+  c.onSelect = h;
+  c.caption = "moo";
+  f.customItems.push(c);
+  check_equals(f.customItems.length, 3);
+  check_equals(f.customItems[2].caption, "moo");
+  ff = f.copy();
+  check_equals(ff.customItems.length, 3);
+  xcheck_equals(ff.customItems[2].caption, undefined);
+
+  // Properties are only copied properly if instanceOf ContextMenuItem;
+  // otherwise they are undefined.
+  c.__proto__ = ContextMenuItem.prototype;
+  xcheck_equals(ff.customItems[2].caption, undefined);
+  ff = f.copy();
+  check_equals(ff.customItems.length, 3);
+  check_equals(ff.customItems[2].caption, "moo");
+
+  // If builtInItems is undefined, it is copied as undefined. If it is an
+  // object, the new ContextMenu refers to the *same* object.
+  f.builtInItems = undefined;
+  ff = f.copy();
+  check(ff.hasOwnProperty("builtInItems"));
+  check_equals(typeof(ff.builtInItems), "undefined")
+  
+  delete f.builtInItems;
+  ff = f.copy();
+  check(ff.hasOwnProperty("builtInItems"));
+  check_equals(typeof(ff.builtInItems), "undefined")
+
+  o = {};
+  o.g = 5;
+  f.builtInItems = o;
+  ff = f.copy();
+  check_equals(ff.builtInItems.g, 5);
+  o.g = "string";
+  check_equals(ff.builtInItems.g, "string");
 
   // Test ContextMenuItem
   
@@ -132,7 +243,7 @@
 
   // Add a test object to the ContextMenu
   cm.customItems.push(it);
-  xcheck_equals(cm.customItems.length, 1);
+  check_equals(cm.customItems.length, 1);
   _root.menu = cm;
 
   // An object is added to the menu if:
@@ -190,6 +301,6 @@
   contextMenuObj2.onSelect = 4;
   check_equals(typeof(contextMenuObj2.onSelect), 'number');
   
-  xtotals(82);
+  totals(120);
 
 #endif

=== modified file 'testsuite/swfdec/PASSING'
--- a/testsuite/swfdec/PASSING  2009-04-23 15:51:18 +0000
+++ b/testsuite/swfdec/PASSING  2009-07-09 19:09:27 +0000
@@ -193,6 +193,10 @@
 constructor-madness-8.swf:5357273baf6b66f6af0223cb1d13b144
 constructor-prototype.swf:22505f0f8dd8440972a298110d697e3b
 constructor-relay-5.swf:2d1a814c37f55485d66624cb97c58e03
+context-menu-5.swf:867624e2cb2c3d47dc07270d756152db
+context-menu-6.swf:9124c06f1cc4725684717eb3641837bd
+context-menu-7.swf:fc22bea201998188714399c2de1ac1f5
+context-menu-8.swf:81cec364792b76914943847fe6ec9a1f
 conversion-functions-6.swf:29f141b5a2d03886c152342fdbea9b25
 conversion-functions-7.swf:8bc3951e61b7fefa82d24fb037929350
 conversion-functions-8.swf:4a68346aaa982e32b2882a49e34faa07


reply via email to

[Prev in Thread] Current Thread [Next in Thread]