1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Lack of Interest JavaScript System Improvement

Discussion in 'Closed Suggestions' started by Uniphix, Apr 10, 2014.

  1. Uniphix

    Uniphix Active Member

    Hello,

    Lately, i've been needing to create some intense JavaScript code that would basically wrap around jQuery, and my custom 'framework'. Something that may help improve the development speed of creating objects in a XenForo Framework. It has been known to work well, and the thing is it will reduce one less line of code if not more depending on the structure you want to do.

    First of all I am sure XenForo developers have known something like this, and it brings the OOP (Object Orientated Programming) into a more structured XenForo Environment.

    First of all XenForo would need to create the base structure to handle all of it...

    Code:
    XenForo.Class = function () { };
    XenForo.Class.prototype.__construct = function () { };
    
    Then from this method we would create a helper to inherit these classes allowing inheriting possible.

    Code:
    XenForo.Class.inherit = function (definition) {
        var __construct = function () {
            if (arguments[0] !== XenForo.Class) { this.__construct .apply(this, arguments); }
        };
    
        var proto = new this(XenForo.Class);
        var superClass = this.prototype;
    
        var n;
        for (n in definition) {
            var defItem = definition[n];
            var subitem = superClass[n];
    
            if (defItem instanceof Function && subitem instanceof Function) {
                defItem.base = subitem;
            }
    
            proto[n] = defItem;
        }
    
        __construct .prototype = proto;
        __construct .inherit = this.inherit;
    
        return __construct ;
    };
    From here you can see that we are now making everything just like XenForo already does... Why?

    Well here we go how to use this.

    I would actually create a parent class structure to handle all the

    Code:
    XenForo.MyObject = function($element) { this.__construct($element); }
    XenForo.MyObject.prototype {
       __construct: function($element) {
       }
    };
    
    The code above is basically what XenForo does... Mine would be replacing it with something like this

    Code:
    XenForo.Element = XenForo.Class.inhert({
       __construct: function($element) {
             arguments.callee.base.call(this);
    
             // your initialization here...
       },
    
       render: function(e) { }
    });
    
    Something like this could help make perfect wrappers plus allowing base methods, and base properties to be accessible easily...

    Lets take AutoComplete and convert it to my structure that I have above...

    Code:
    XenForo.AutoComplete = function($element) { this.__construct($element); };
    XenForo.AutoComplete.prototype =
    {
        __construct: function($input)
        {
            this.$input = $input;
    
            // ...
        },
       
        keystroke: function(e)
        {
            // ...
        }
    
       // ...
    };
    
    Inheriting only XenForo.Class, basically we don't need to inheirt customized functions from XenForo.Element

    Code:
    XenForo.AutoComplete = XenForo.Class.inheirt(
    {
        __construct: function($input)
        {
            arguments.callee.base.call(this);
            this.$input = $input;
    
            // ...
        },
       
        keystroke: function(e)
        {
            // ...
        }
    });
    
    Suppose we actually want to inherit from the Element class we created that has "Render" function in it..

    Code:
    XenForo.AutoComplete = XenForo.Element.inheirt(
    {
        __construct: function($input)
        {
            arguments.callee.base.call(this, $input);
            this.$input = $input;
    
            // ...
        },
       
        keystroke: function(e)
        {
            // ...
        },
       
        render: function(e) {
            arguments.callee.base.call(this, e); // this calls the parent base class of the Element class
           
            // ... we do our logic here
        }
    });
    
    Now you may think that is pointless but what does this actually really open the door?

    How about I need and want to override the default functions of AutoComplete!


    Only way possible is to convert the XenForo.AutoComplete with the method I made possible above.

    Then from there we can do stuff like this...

    Code:
    XenForo.MyCustomAutoComplete = XenForo.AutoComplete.inheirt(
    {
        __construct: function($input)
        {
            arguments.callee.base.call(this, $input);
        },
       
        keystroke: function(e)
        {
            //arguments.callee.base.call(this, e); // i decided i don't want to inherit the base so therefore I handle it completely new
           
            // Copying the code I decided to add something
            var code = e.keyCode || e.charCode, prevent = true;
    
            switch(code)
            {
                case 40: this.results.selectResult(1); break; // down
                case 38: this.results.selectResult(-1); break; // up
                case 27: this.results.hideResults(); break; // esc
                case 13: // enter
                    if (this.results.isVisible())
                    {
                        this.results.insertSelectedResult();
                    }
                    else
                    {
                        prevent = false;
                    }
                    break;
    
                case 73: // i (I want to do something when i is pressed
                    alert('Hello World!');
                    break;
                   
                default:
                    prevent = false;
                    if (this.loadTimer)
                    {
                        clearTimeout(this.loadTimer);
                    }
                    this.loadTimer = setTimeout($.context(this, 'load'), 200);
    
                    this.results.hideResults();
            }
    
            if (prevent)
            {
                e.preventDefault();
            }
            this.preventKey = prevent;
        }
       
        // ...
    });
    
    // Below where you normally register XenForo.register

    Code:
    XenForo.register('.MyCustomAutoComplete', 'XenForo.MyCustomAutoComplete');
    
    Let me know what you think :)
     
  2. Uniphix

    Uniphix Active Member

    The one of the biggest benefit of these changes to allow customized flexiability and being able to extend the XenForo javascript framework. I think what would be cool is to be able to override an entire "register" that was created for, so for example....

    Code:
    XenForo.overrideRegister('.AutoComplete', 'XenForo.MyCustomAutoComplete');
     
  3. Uniphix

    Uniphix Active Member

    I have other methods such as

    Code:
    Class.global = function(args, obj){
        for (var key in args) {
            if (args.hasOwnProperty(key)) {
                obj[key] = args[key];
            }
        }
        return obj;
    };
    
    //static methods
    Class.addSetters = function (ctor, attributes) {
        for (var i = 0; i < attributes.length; i++) {
            var attribute = attributes[i];
            this._addSetter(ctor, attribute);
        }
    };
    
    Class._addSetter = function (ctor, attribute) {
        var method = 'set' + attribute.charAt(0).toUpperCase() + attribute.slice(1);
        ctor.prototype[method] = function () {
            if (arguments.length == 1) {
                arg = arguments[0];
            }
            else {
                arg = Array.prototype.slice.call(arguments);
            }
            var obj = {};
            obj[attr] = arg;
            this.setAttributes(obj);
        };
    };
    
    Class.addGetters = function (ctor, attributes) {
        for (var i = 0; i < attributes.length; i++) {
            var attribute = attributes[i];
            this._addGetter(ctor, attribute);
        }
    };
    
    Class._addGetter = function (ctor, attribute) {
        var method = 'get' + attribute.charAt(0).toUpperCase() + attribute.slice(1);
        ctor.prototype[method] = function (attr) {
            return this.attributes[attr];
        };
    };
    
    Class.addGettersSetters = function (ctor, attributes) {
        this.addSetters(ctor, attributes);
        this.addGetters(ctor, attributes);
    };
    
    Which basically as an example

    Code:
    var MyAddonHandler = Class.global({
        CONSTANT_VALUE: 50234,
        staticMethod: function() {
            // My Static Method
        }
    }, Class.inherit({
        __construct: function($element) {
            // do stuff
        }
    }));
    
    XenForo.register('.MyAddonHandler', 'MyAddonHandler');
    You can then basically access CONSTANT_VALUE by doing MyAddonHandler.CONSTANT_VALUE or a static method by doing MyAddonHandler.staticMethod();

    As for the addSetters, addGetters and addGettersSetters functions they will add properties into a class that can be accessed via by doing

    Code:
    var MyAddonHandler = Class.inherit({
        __construct: function($element) {
            // do stuff
            Class.addGettersSetters(this, ['name','addonId']);
        },
       
        sometMethod: function() {
            this.setName('Uniphix');
            var name = this.getName();
           
            this.setAddonId('myaddon');
            var addonId = this.getAddonId();
        }
    });
    Let me know what you guys think...
     
    Jeremy P likes this.

Share This Page