From 9f0188684fc970404d660b85e557135d103c3e73 Mon Sep 17 00:00:00 2001 From: Petr Vobornik Date: Fri, 12 Apr 2013 17:19:52 +0200 Subject: Handle built object in spec https://fedorahosted.org/freeipa/ticket/3235 --- install/ui/src/freeipa/_base/Builder.js | 6 +-- install/ui/src/freeipa/_base/Construct_registry.js | 2 +- install/ui/src/freeipa/_base/construct.js | 50 ++++++++++++++++++---- 3 files changed, 46 insertions(+), 12 deletions(-) (limited to 'install/ui/src/freeipa/_base') diff --git a/install/ui/src/freeipa/_base/Builder.js b/install/ui/src/freeipa/_base/Builder.js index d01f86f17..bcd607158 100644 --- a/install/ui/src/freeipa/_base/Builder.js +++ b/install/ui/src/freeipa/_base/Builder.js @@ -200,7 +200,7 @@ define(['dojo/_base/declare', if (this.registry) { var cs = this.registry.get(type); if (!cs) throw construct.no_cs_for_type_error(type); - cs = construct.copy_cs(cs); + cs = construct.clone(cs); return cs; } else { throw { @@ -215,8 +215,8 @@ define(['dojo/_base/declare', var cs = construction_spec, obj = null; - // here we should clone cs.spec to prevent modification of original - // by pre_ops + // deep clone to prevent modification of original spec by preops + cs.spec = construct.clone(cs.spec); cs.spec = this._run_preops(this.pre_ops, cs.spec, context); if (cs.pre_ops) { diff --git a/install/ui/src/freeipa/_base/Construct_registry.js b/install/ui/src/freeipa/_base/Construct_registry.js index 7f8db2596..7184c1442 100644 --- a/install/ui/src/freeipa/_base/Construct_registry.js +++ b/install/ui/src/freeipa/_base/Construct_registry.js @@ -99,7 +99,7 @@ define(['dojo/_base/declare', var def_cs = construct_spec; var old_cs = this._check_get(org_type); - var cs = construct.copy_cs(old_cs); + var cs = construct.clone(old_cs); cs.type = new_type; if (def_cs.pre_ops) cs.pre_ops.push.call(cs.pre_ops, def_cs.pre_ops); diff --git a/install/ui/src/freeipa/_base/construct.js b/install/ui/src/freeipa/_base/construct.js index e44c66b1e..960596da2 100644 --- a/install/ui/src/freeipa/_base/construct.js +++ b/install/ui/src/freeipa/_base/construct.js @@ -56,16 +56,50 @@ define(['dojo/_base/declare', }, /** - * Creates copy of construction specification + * Deep clone. + * - does not clone framework objects + * - fails on cyclic non-framework objects * - * It makes sure that pre_ops, post_ops and spec are new Arrays/Object + * based on dojo/_base/lang.clone + * + * @param {anything} object to clone */ - copy_cs: function(org_cs) { - var cs = lang.mixin({}, org_cs); - if (cs.spec) cs.spec = lang.mixin({}, cs.spec); - cs.pre_ops = cs.pre_ops.slice(0); - cs.post_ops = cs.pre_ops.slice(0); - return cs; + 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) { -- cgit