1 /** 2 * Copyright (C) 2012 KO GmbH <aditya.bhatt@kogmbh.com> 3 * 4 * @licstart 5 * This file is part of WebODF. 6 * 7 * WebODF is free software: you can redistribute it and/or modify it 8 * under the terms of the GNU Affero General Public License (GNU AGPL) 9 * as published by the Free Software Foundation, either version 3 of 10 * the License, or (at your option) any later version. 11 * 12 * WebODF is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU Affero General Public License for more details. 16 * 17 * You should have received a copy of the GNU Affero General Public License 18 * along with WebODF. If not, see <http://www.gnu.org/licenses/>. 19 * @licend 20 * 21 * @source: http://www.webodf.org/ 22 * @source: https://github.com/kogmbh/WebODF/ 23 */ 24 25 /*global core*/ 26 27 /** 28 * A collection of useful utility functions 29 * @constructor 30 */ 31 core.Utils = function Utils() { 32 "use strict"; 33 34 /** 35 * Simple string hash 36 * Based off http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery 37 * @param {!string} value 38 * @return {!number} 39 */ 40 function hashString(value) { 41 var hash = 0, i, l; 42 for (i = 0, l = value.length; i < l; i += 1) { 43 /*jslint bitwise:true*/ 44 hash = ((hash << 5) - hash) + value.charCodeAt(i); 45 hash |= 0; // Convert to 32bit integer 46 /*jslint bitwise:false*/ 47 } 48 return hash; 49 } 50 this.hashString = hashString; 51 52 var mergeObjects; 53 /** 54 * @param {*} destination 55 * @param {*} source 56 * @return {*} 57 */ 58 function mergeItems(destination, source) { 59 // Property in destination object set; update its value. 60 if (source && Array.isArray(source)) { 61 // create destination array if it does not exist yet 62 destination = destination || []; 63 if (!Array.isArray(destination)) { 64 throw "Destination is not an array."; 65 } 66 // An array will report as a type of object, but this is not able to 67 // mapped using mergeObjects 68 // The following will clone each individual item in the source array 69 // and append them to the end of the destination array 70 destination = /**@type{!Array.<*>}*/(destination).concat( 71 /**@type{!Array.<*>}*/(source).map(function (obj) { 72 return mergeItems(null, obj); 73 }) 74 ); 75 } else if (source && typeof source === 'object') { 76 destination = destination || {}; 77 if (typeof destination !== 'object') { 78 throw "Destination is not an object."; 79 } 80 Object.keys(/**@type{!Object}*/(source)).forEach(function (p) { 81 destination[p] = mergeItems(destination[p], source[p]); 82 }); 83 } else { 84 destination = source; 85 } 86 return destination; 87 } 88 /** 89 * Recursively merge properties of two objects 90 * Merge behaviours for the object members are: 91 * array => array - Append clones of source array onto the end of the 92 * destination array 93 * object => object - Map each individual key from source onto destination 94 * (recursive, so these are clones) 95 * primitive => primitive - return primitive value 96 * 97 * @param {!Object.<string,*>} destination 98 * @param {!Object.<string,*>} source 99 * @return {!Object.<string,*>} 100 */ 101 mergeObjects = function (destination, source) { 102 Object.keys(source).forEach(function (p) { 103 destination[p] = mergeItems(destination[p], source[p]); 104 }); 105 return destination; 106 }; 107 this.mergeObjects = mergeObjects; 108 }; 109 110