Skip to content

Commit afc3b78

Browse files
committed
Implemented Map
1 parent e913fb6 commit afc3b78

File tree

5 files changed

+586
-0
lines changed

5 files changed

+586
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ https://commons.wikimedia.org/wiki/File:Wikibase_JavaScript_Data_Model_1.0.svg
3939
* Added Group.
4040
* Added GroupableCollection.
4141
* Added List.
42+
* Added Map.
4243
* Added MultiTerm.
4344
* Added MultiTermSet.
4445
* Added ReferenceList.

resources.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,15 @@
186186
),
187187
),
188188

189+
'wikibase.datamodel.Map' => $moduleTemplate + array(
190+
'scripts' => array(
191+
'Map.js',
192+
),
193+
'dependencies' => array(
194+
'wikibase.datamodel.__namespace',
195+
),
196+
),
197+
189198
'wikibase.datamodel.MultiTerm' => $moduleTemplate + array(
190199
'scripts' => array(
191200
'MultiTerm.js',

resources.test.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,15 @@
133133
),
134134
),
135135

136+
'wikibase.datamodel.Map.tests' => $moduleTemplate + array(
137+
'scripts' => array(
138+
'Map.tests.js',
139+
),
140+
'dependencies' => array(
141+
'wikibase.datamodel.Map',
142+
),
143+
),
144+
136145
'wikibase.datamodel.MultiTerm.tests' => $moduleTemplate + array(
137146
'scripts' => array(
138147
'MultiTerm.tests.js',

src/Map.js

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
/**
2+
* @licence GNU GPL v2+
3+
* @author H. Snater < mediawiki@snater.com >
4+
*/
5+
( function( wb, $ ) {
6+
'use strict';
7+
8+
/**
9+
* @constructor
10+
* @since 1.0
11+
*
12+
* @param {Function} ItemConstructor
13+
* @param {Object} [map]
14+
*/
15+
var SELF = wb.datamodel.Map = function( ItemConstructor, map ) {
16+
map = map || {};
17+
18+
if( !$.isFunction( ItemConstructor ) ) {
19+
throw new Error( 'Item constructor needs to be a Function' );
20+
} else if( !$.isFunction( ItemConstructor.prototype.equals ) ) {
21+
throw new Error( 'Map item prototype needs equals() method' );
22+
}
23+
24+
this._ItemConstructor = ItemConstructor;
25+
this._map = {};
26+
27+
for( var key in map ) {
28+
this.setItem( key, map[key] );
29+
}
30+
};
31+
32+
$.extend( SELF.prototype, {
33+
/**
34+
* @type {Function}
35+
*/
36+
_ItemConstructor: null,
37+
38+
/**
39+
* @type {Object}
40+
*/
41+
_map: null,
42+
43+
/**
44+
* @type {number}
45+
*/
46+
length: 0,
47+
48+
/**
49+
* @see jQuery.fn.each
50+
*/
51+
each: function( fn ) {
52+
$.each.call( null, this._map, fn );
53+
},
54+
55+
/**
56+
* @param {string} key
57+
* @param {Object} item
58+
* @return {boolean}
59+
*/
60+
hasItem: function( key, item ) {
61+
this._assertIsItem( item );
62+
return this._map[key] && this._map[key].equals( item );
63+
},
64+
65+
/**
66+
* @param {string} key
67+
* @param {Object} item
68+
*/
69+
addItem: function( key, item ) {
70+
this._assertIsItem( item );
71+
72+
if( this.hasItemForKey( key ) ) {
73+
throw new Error( 'Item for key ' + key + ' exists already' );
74+
}
75+
76+
this.setItem( key, item );
77+
},
78+
79+
/**
80+
* @param {string} key
81+
* @param {Object} item
82+
*/
83+
removeItem: function( key, item ) {
84+
if( !this.hasItem( key, item ) ) {
85+
throw new Error( 'Item for key ' + key + ' to be removed does not exist' );
86+
}
87+
this.removeItemByKey( key );
88+
},
89+
90+
/**
91+
* @return {string[]}
92+
*/
93+
getKeys: function() {
94+
var keys = [];
95+
96+
for( var key in this._map ) {
97+
keys.push( key );
98+
}
99+
100+
return keys;
101+
},
102+
103+
/**
104+
* @param {string} key
105+
* @return {*|null}
106+
*/
107+
getItemByKey: function( key ) {
108+
return this._map[key] || null;
109+
},
110+
111+
/**
112+
* @param {string} key
113+
*/
114+
removeItemByKey: function( key ) {
115+
if( this._map[key] ) {
116+
this.length--;
117+
}
118+
delete this._map[key];
119+
},
120+
121+
/**
122+
* @param {string} key
123+
* @return {boolean}
124+
*/
125+
hasItemForKey: function( key ) {
126+
return !!this._map[key];
127+
},
128+
129+
/**
130+
* @param {string} key
131+
* @param {Object} item
132+
*/
133+
setItem: function( key, item ) {
134+
this._assertIsItem( item );
135+
136+
if( !this.hasItemForKey( key ) ) {
137+
this.length++;
138+
}
139+
140+
this._map[key] = item;
141+
},
142+
143+
/**
144+
* @return {boolean}
145+
*/
146+
isEmpty: function() {
147+
return this.length === 0;
148+
},
149+
150+
/**
151+
* @param {wikibase.datamodel.Map} map
152+
* @return {boolean}
153+
*/
154+
equals: function( map ) {
155+
if( !( map instanceof SELF ) || map.length !== this.length ) {
156+
return false;
157+
}
158+
159+
for( var key in this._map ) {
160+
if( !map.hasItem( key, this._map[key] ) ) {
161+
return false;
162+
}
163+
}
164+
165+
return true;
166+
},
167+
168+
/**
169+
* @param {*} item
170+
* @return {boolean}
171+
*/
172+
_assertIsItem: function( item ) {
173+
if( !( item instanceof this._ItemConstructor ) ) {
174+
throw new Error( 'Item is not an instance of the constructor set on the map' );
175+
}
176+
}
177+
} );
178+
179+
}( wikibase, jQuery ) );

0 commit comments

Comments
 (0)