summaryrefslogtreecommitdiffstats
path: root/install/ui/src/freeipa/_base/construct.js
blob: ce675e5885e27a8457f91336a32030c4d311a619 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*  Authors:
 *    Petr Vobornik <pvoborni@redhat.com>
 *
 * Copyright (C) 2012 Red Hat
 * see file 'COPYING' for use and warranty information
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

define(['dojo/_base/declare',
        'dojo/_base/array',
        'dojo/_base/lang'
        ], function(declare, array, lang) {

    /**
     * Helper module
     * @class _base.construct
     * @singleton
     */
    var construct = {

        /**
         * Checks if supplied object is a constructor function.
         * It can recognize only classes declared by `dojo/_base/declare`.
         * @param {Object} obj
         */
        is_ctor: function(obj) {

            return typeof obj === 'function' && typeof obj.extend === 'function';
        },

        /**
         * Finds out if object is a spec object.
         *
         * Object is not a spec object when any of following applies:
         *
         * - has `__fw_obj === true`
         * - has `isInstanceOf` function - basically tells if it's a instance of
         *                                   dojo-based class
         * @param {Object} obj
         */
        is_spec: function(obj) {
            var ret = false;
            if (typeof obj === 'object') {
                ret = obj.__fw_obj === true ||
                      typeof obj.isInstanceOf === 'function';
            }
            return !ret;
        },

        /**
         * Deep clone
         *
         * - does not clone framework objects
         * - fails on cyclic non-framework objects
         *
         * based on `dojo/_base/lang.clone`
         *
         * @param {Mixed} src object to clone
         */
        clone: function(src) {

            if(!src || typeof src != "object" || lang.isFunction(src)) {
                // null, undefined, any non-object, or function
                return src; // anything
            }
            if(src.nodeType && "cloneNode" in src) {
                // DOM Node
                return src.cloneNode(true); // Node
            }
            if (!construct.is_spec(src)) {
                // framework object
                return src;
            }
            if (src instanceof Date) {
                // Date
                return new Date(src.getTime()); // Date
            }
            if (src instanceof RegExp) {
                // RegExp
                return new RegExp(src);   // RegExp
            }
            var r, i, l;
            if (lang.isArray(src)){
                // array
                r = [];
                for (i = 0, l = src.length; i < l; ++i) {
                    if (i in src){
                        r.push(construct.clone(src[i]));
                    }
                }
            } else {
                // generic objects
                r = src.constructor ? new src.constructor() : {};
            }
            return lang._mixin(r, src, construct.clone);
        },

        no_cs_for_type_error: function(type) {
            return {
                error: 'No construction specification for given type',
                type: type
            };
        }
    };
    return construct;
});