Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    bug: ClassFactory.mixInInterface() adds initInterface methods into super class

    I am using ClassFactory.mixInInterface to introduce custom initialization code into all Canvases and into DynamicForms.

    But SmartClient calls wrong initInterface method for wrong classes. See sample code and explanation below.

    Reproducible on SmartClient version 9.0 and 9.0a feature explorer with this sample code.

    Code:
    isc.defineInterface("CanvasIFace").addInterfaceProperties({
        initInterface : function() {
        	//a method which is called before init of all Canvases
        	//... in my real implementation there is some code of course
        }
    });
    isc.ClassFactory.mixInInterface("Canvas", "CanvasIFace");
    isc.defineInterface("TestIFace").addInterfaceProperties({
        initInterface : function() {
        	alert("TestIFace.initInterface called");
        }
    });
    isc.ClassFactory.mixInInterface("DynamicForm", "TestIFace");
    
    //The HLayout initialization should call only CanvasIFace.initInterface, but because alert is displayed you can see that it by mistake calls also TestIFace.initInterface
    isc.HLayout.create();
    In the sample above I do this:
    1) define interface "CanvasIFace" with custom initInterface method.
    2) mix in interface "CanvasIFace" into "Canvas" class and sub classes. So the CanvasIFace.initInterface method is called before init of Canvas and all sub classes.
    3) define interface "TestIFace" with custom initInterface method.
    4) mix in interface "TestIFace" into "DynamicForm" class and all sub classes. So the TestIFace.initInterface method should be called before init of DynamicForm and all sub classes.
    5) I create HLayout instance. It is sub class of Canvas so CanvasIFace.initInterface is called - OK.
    bug: HLayout is not a sub class of DynamicForm so TestIFace.initInterface should NOT be called ... but it is called as alert is displayed.

    Fix:
    The ClassFactory._mixInProperties have to duplicate content of _initInterfaceMethods and _destroyInterfaceMethods, which are inherited from superclass.

    isc.addMethods(isc.ClassFactory, {
    //...
    _mixInProperties : function (source, destination, asClassProperties) {
    //... exising code ...
    if (propName == this._initInterfaceMethodName && !asClassProperties) {
    // patch any initInterface() methods onto a special array on the classObject to
    // be called at class creation.
    if (destinationClass._initInterfaceMethods == null) {
    destinationClass._initInterfaceMethods = []
    } else {
    destinationClass._initInterfaceMethods = destinationClass._initInterfaceMethods.duplicate();
    };
    destinationClass._initInterfaceMethods[destinationClass._initInterfaceMethods.length] = propValue;
    } else if (propName == this._destroyInterfaceMethodName && !asClassProperties) {
    // patch any destroyInterface() methods onto a special array on the classObject to
    // be called at class destruction.
    if (destinationClass._destroyInterfaceMethods == null) {
    destinationClass._destroyInterfaceMethods = [];
    } else {
    destinationClass._destroyInterfaceMethods = destinationClass._destroyInterfaceMethods.duplicate();
    }
    destinationClass._destroyInterfaceMethods[destinationClass._destroyInterfaceMethods.length] = propValue;
    }

    Thank You for fixing the code :-)

    #2
    This is deep in undocumented territory, but regardless we appreciate the attempted patch.

    It looks like it still has a flaw however. Say that after you mixed TestIFace into DynamicForm, you now mixed in a second interface into Canvas with another initInterface method. That initInterface method would not be called for DynamicForm, since it now has a distinct Array instance.

    Comment

    Working...
    X