jquerysvg 1.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,406 @@
1
+ /* http://keith-wood.name/svg.html
2
+ jQuery DOM compatibility for jQuery SVG v1.4.5.
3
+ Written by Keith Wood (kbwood{at}iinet.com.au) April 2009.
4
+ Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
5
+ MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
6
+ Please attribute the author if you use it. */
7
+
8
+ (function($) { // Hide scope, no $ conflict
9
+
10
+ /* Support adding class names to SVG nodes. */
11
+ $.fn.addClass = function(origAddClass) {
12
+ return function(classNames) {
13
+ classNames = classNames || '';
14
+ return this.each(function() {
15
+ if ($.svg.isSVGElem(this)) {
16
+ var node = this;
17
+ $.each(classNames.split(/\s+/), function(i, className) {
18
+ var classes = (node.className ? node.className.baseVal : node.getAttribute('class'));
19
+ if ($.inArray(className, classes.split(/\s+/)) == -1) {
20
+ classes += (classes ? ' ' : '') + className;
21
+ (node.className ? node.className.baseVal = classes :
22
+ node.setAttribute('class', classes));
23
+ }
24
+ });
25
+ }
26
+ else {
27
+ origAddClass.apply($(this), [classNames]);
28
+ }
29
+ });
30
+ };
31
+ }($.fn.addClass);
32
+
33
+ /* Support removing class names from SVG nodes. */
34
+ $.fn.removeClass = function(origRemoveClass) {
35
+ return function(classNames) {
36
+ classNames = classNames || '';
37
+ return this.each(function() {
38
+ if ($.svg.isSVGElem(this)) {
39
+ var node = this;
40
+ $.each(classNames.split(/\s+/), function(i, className) {
41
+ var classes = (node.className ? node.className.baseVal : node.getAttribute('class'));
42
+ classes = $.grep(classes.split(/\s+/), function(n, i) { return n != className; }).
43
+ join(' ');
44
+ (node.className ? node.className.baseVal = classes :
45
+ node.setAttribute('class', classes));
46
+ });
47
+ }
48
+ else {
49
+ origRemoveClass.apply($(this), [classNames]);
50
+ }
51
+ });
52
+ };
53
+ }($.fn.removeClass);
54
+
55
+ /* Support toggling class names on SVG nodes. */
56
+ $.fn.toggleClass = function(origToggleClass) {
57
+ return function(className, state) {
58
+ return this.each(function() {
59
+ if ($.svg.isSVGElem(this)) {
60
+ if (typeof state !== 'boolean') {
61
+ state = !$(this).hasClass(className);
62
+ }
63
+ $(this)[(state ? 'add' : 'remove') + 'Class'](className);
64
+ }
65
+ else {
66
+ origToggleClass.apply($(this), [className, state]);
67
+ }
68
+ });
69
+ };
70
+ }($.fn.toggleClass);
71
+
72
+ /* Support checking class names on SVG nodes. */
73
+ $.fn.hasClass = function(origHasClass) {
74
+ return function(className) {
75
+ className = className || '';
76
+ var found = false;
77
+ this.each(function() {
78
+ if ($.svg.isSVGElem(this)) {
79
+ var classes = (this.className ? this.className.baseVal :
80
+ this.getAttribute('class')).split(/\s+/);
81
+ found = ($.inArray(className, classes) > -1);
82
+ }
83
+ else {
84
+ found = (origHasClass.apply($(this), [className]));
85
+ }
86
+ return !found;
87
+ });
88
+ return found;
89
+ };
90
+ }($.fn.hasClass);
91
+
92
+ /* Support attributes on SVG nodes. */
93
+ $.fn.attr = function(origAttr) {
94
+ return function(name, value, type) {
95
+ if (typeof name === 'string' && value === undefined) {
96
+ var val = origAttr.apply(this, [name]);
97
+ if (val && val.baseVal && val.baseVal.numberOfItems != null) { // Multiple values
98
+ value = '';
99
+ val = val.baseVal;
100
+ if (name == 'transform') {
101
+ for (var i = 0; i < val.numberOfItems; i++) {
102
+ var item = val.getItem(i);
103
+ switch (item.type) {
104
+ case 1: value += ' matrix(' + item.matrix.a + ',' + item.matrix.b + ',' +
105
+ item.matrix.c + ',' + item.matrix.d + ',' +
106
+ item.matrix.e + ',' + item.matrix.f + ')';
107
+ break;
108
+ case 2: value += ' translate(' + item.matrix.e + ',' + item.matrix.f + ')'; break;
109
+ case 3: value += ' scale(' + item.matrix.a + ',' + item.matrix.d + ')'; break;
110
+ case 4: value += ' rotate(' + item.angle + ')'; break; // Doesn't handle new origin
111
+ case 5: value += ' skewX(' + item.angle + ')'; break;
112
+ case 6: value += ' skewY(' + item.angle + ')'; break;
113
+ }
114
+ }
115
+ val = value.substring(1);
116
+ }
117
+ else {
118
+ val = val.getItem(0).valueAsString;
119
+ }
120
+ }
121
+ return (val && val.baseVal ? val.baseVal.valueAsString : val);
122
+ }
123
+
124
+ var options = name;
125
+ if (typeof name === 'string') {
126
+ options = {};
127
+ options[name] = value;
128
+ }
129
+ return this.each(function() {
130
+ if ($.svg.isSVGElem(this)) {
131
+ for (var n in options) {
132
+ var val = ($.isFunction(options[n]) ? options[n]() : options[n]);
133
+ (type ? this.style[n] = val : this.setAttribute(n, val));
134
+ }
135
+ }
136
+ else {
137
+ origAttr.apply($(this), [name, value, type]);
138
+ }
139
+ });
140
+ };
141
+ }($.fn.attr);
142
+
143
+ /* Support removing attributes on SVG nodes. */
144
+ $.fn.removeAttr = function(origRemoveAttr) {
145
+ return function(name) {
146
+ return this.each(function() {
147
+ if ($.svg.isSVGElem(this)) {
148
+ (this[name] && this[name].baseVal ? this[name].baseVal.value = '' :
149
+ this.setAttribute(name, ''));
150
+ }
151
+ else {
152
+ origRemoveAttr.apply($(this), [name]);
153
+ }
154
+ });
155
+ };
156
+ }($.fn.removeAttr);
157
+
158
+ /* Add numeric only properties. */
159
+ $.extend($.cssNumber, {
160
+ 'stopOpacity': true,
161
+ 'strokeMitrelimit': true,
162
+ 'strokeOpacity': true
163
+ });
164
+
165
+ /* Support retrieving CSS/attribute values on SVG nodes. */
166
+ if ($.cssProps) {
167
+ $.css = function(origCSS) {
168
+ return function(elem, name, extra) {
169
+ var value = (name.match(/^svg.*/) ? $(elem).attr($.cssProps[name] || name) : '');
170
+ return value || origCSS(elem, name, extra);
171
+ };
172
+ }($.css);
173
+ }
174
+
175
+ /* Determine if any nodes are SVG nodes. */
176
+ function anySVG(checkSet) {
177
+ for (var i = 0; i < checkSet.length; i++) {
178
+ if (checkSet[i].nodeType == 1 && checkSet[i].namespaceURI == $.svg.svgNS) {
179
+ return true;
180
+ }
181
+ }
182
+ return false;
183
+ }
184
+
185
+ /* Update Sizzle selectors. */
186
+
187
+ $.expr.relative['+'] = function(origRelativeNext) {
188
+ return function(checkSet, part, isXML) {
189
+ origRelativeNext(checkSet, part, isXML || anySVG(checkSet));
190
+ };
191
+ }($.expr.relative['+']);
192
+
193
+ $.expr.relative['>'] = function(origRelativeChild) {
194
+ return function(checkSet, part, isXML) {
195
+ origRelativeChild(checkSet, part, isXML || anySVG(checkSet));
196
+ };
197
+ }($.expr.relative['>']);
198
+
199
+ $.expr.relative[''] = function(origRelativeDescendant) {
200
+ return function(checkSet, part, isXML) {
201
+ origRelativeDescendant(checkSet, part, isXML || anySVG(checkSet));
202
+ };
203
+ }($.expr.relative['']);
204
+
205
+ $.expr.relative['~'] = function(origRelativeSiblings) {
206
+ return function(checkSet, part, isXML) {
207
+ origRelativeSiblings(checkSet, part, isXML || anySVG(checkSet));
208
+ };
209
+ }($.expr.relative['~']);
210
+
211
+ $.expr.find.ID = function(origFindId) {
212
+ return function(match, context, isXML) {
213
+ return ($.svg.isSVGElem(context) ?
214
+ [context.ownerDocument.getElementById(match[1])] :
215
+ origFindId(match, context, isXML));
216
+ };
217
+ }($.expr.find.ID);
218
+
219
+ var div = document.createElement('div');
220
+ div.appendChild(document.createComment(''));
221
+ if (div.getElementsByTagName('*').length > 0) { // Make sure no comments are found
222
+ $.expr.find.TAG = function(match, context) {
223
+ var results = context.getElementsByTagName(match[1]);
224
+ if (match[1] === '*') { // Filter out possible comments
225
+ var tmp = [];
226
+ for (var i = 0; results[i] || results.item(i); i++) {
227
+ if ((results[i] || results.item(i)).nodeType === 1) {
228
+ tmp.push(results[i] || results.item(i));
229
+ }
230
+ }
231
+ results = tmp;
232
+ }
233
+ return results;
234
+ };
235
+ }
236
+
237
+ $.expr.preFilter.CLASS = function(match, curLoop, inplace, result, not, isXML) {
238
+ match = ' ' + match[1].replace(/\\/g, '') + ' ';
239
+ if (isXML) {
240
+ return match;
241
+ }
242
+ for (var i = 0, elem = {}; elem != null; i++) {
243
+ elem = curLoop[i];
244
+ if (!elem) {
245
+ try {
246
+ elem = curLoop.item(i);
247
+ }
248
+ catch (e) {
249
+ // Ignore
250
+ }
251
+ }
252
+ if (elem) {
253
+ var className = (!$.svg.isSVGElem(elem) ? elem.className :
254
+ (elem.className ? elem.className.baseVal : '') || elem.getAttribute('class'));
255
+ if (not ^ (className && (' ' + className + ' ').indexOf(match) > -1)) {
256
+ if (!inplace)
257
+ result.push(elem);
258
+ }
259
+ else if (inplace) {
260
+ curLoop[i] = false;
261
+ }
262
+ }
263
+ }
264
+ return false;
265
+ };
266
+
267
+ $.expr.filter.CLASS = function(elem, match) {
268
+ var className = (!$.svg.isSVGElem(elem) ? elem.className :
269
+ (elem.className ? elem.className.baseVal : elem.getAttribute('class')));
270
+ return (' ' + className + ' ').indexOf(match) > -1;
271
+ };
272
+
273
+ $.expr.filter.ATTR = function(origFilterAttr) {
274
+ return function(elem, match) {
275
+ var handler = null;
276
+ if ($.svg.isSVGElem(elem)) {
277
+ handler = match[1];
278
+ $.expr.attrHandle[handler] = function(elem){
279
+ var attr = elem.getAttribute(handler);
280
+ return attr && attr.baseVal || attr;
281
+ };
282
+ }
283
+ var filter = origFilterAttr(elem, match);
284
+ if (handler) {
285
+ $.expr.attrHandle[handler] = null;
286
+ }
287
+ return filter;
288
+ };
289
+ }($.expr.filter.ATTR);
290
+
291
+ /*
292
+ In the removeData function (line 1881, v1.7.2):
293
+
294
+ if ( jQuery.support.deleteExpando ) {
295
+ delete elem[ internalKey ];
296
+ } else {
297
+ try { // SVG
298
+ elem.removeAttribute( internalKey );
299
+ } catch (e) {
300
+ elem[ internalKey ] = null;
301
+ }
302
+ }
303
+
304
+ In the event.add function (line 2985, v1.7.2):
305
+
306
+ if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
307
+ // Bind the global event handler to the element
308
+ try { // SVG
309
+ elem.addEventListener( type, eventHandle, false );
310
+ } catch(e) {
311
+ if ( elem.attachEvent ) {
312
+ elem.attachEvent( "on" + type, eventHandle );
313
+ }
314
+ }
315
+ }
316
+
317
+ In the event.remove function (line 3074, v1.7.2):
318
+
319
+ if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
320
+ try { // SVG
321
+ elem.removeEventListener(type, elemData.handle, false);
322
+ }
323
+ catch (e) {
324
+ if (elem.detachEvent) {
325
+ elem.detachEvent("on" + type, elemData.handle);
326
+ }
327
+ }
328
+ }
329
+
330
+ In the event.fix function (line 3394, v1.7.2):
331
+
332
+ if (event.target.namespaceURI == 'http://www.w3.org/2000/svg') { // SVG
333
+ event.button = [1, 4, 2][event.button];
334
+ }
335
+
336
+ // Add which for click: 1 === left; 2 === middle; 3 === right
337
+ // Note: button is not normalized, so don't use it
338
+ if ( !event.which && button !== undefined ) {
339
+ event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
340
+ }
341
+
342
+ In the Sizzle function (line 4083, v1.7.2):
343
+
344
+ if ( toString.call(checkSet) === "[object Array]" ) {
345
+ if ( !prune ) {
346
+ results.push.apply( results, checkSet );
347
+
348
+ } else if ( context && context.nodeType === 1 ) {
349
+ for ( i = 0; checkSet[i] != null; i++ ) {
350
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
351
+ results.push( set[i] || set.item(i) ); // SVG
352
+ }
353
+ }
354
+
355
+ } else {
356
+ for ( i = 0; checkSet[i] != null; i++ ) {
357
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
358
+ results.push( set[i] || set.item(i) ); // SVG
359
+ }
360
+ }
361
+ }
362
+ } else {...
363
+
364
+ In the fallback for the Sizzle makeArray function (line 4877, v1.7.2):
365
+
366
+ if ( toString.call(array) === "[object Array]" ) {
367
+ Array.prototype.push.apply( ret, array );
368
+
369
+ } else {
370
+ if ( typeof array.length === "number" ) {
371
+ for ( var l = array.length; i &lt; l; i++ ) {
372
+ ret.push( array[i] || array.item(i) ); // SVG
373
+ }
374
+
375
+ } else {
376
+ for ( ; array[i]; i++ ) {
377
+ ret.push( array[i] );
378
+ }
379
+ }
380
+ }
381
+
382
+ In the jQuery.cleandata function (line 6538, v1.7.2):
383
+
384
+ if ( deleteExpando ) {
385
+ delete elem[ jQuery.expando ];
386
+
387
+ } else {
388
+ try { // SVG
389
+ elem.removeAttribute( jQuery.expando );
390
+ } catch (e) {
391
+ // Ignore
392
+ }
393
+ }
394
+
395
+ In the fallback getComputedStyle function (line 6727, v1.7.2):
396
+
397
+ defaultView = (elem.ownerDocument ? elem.ownerDocument.defaultView : elem.defaultView); // SVG
398
+ if ( defaultView &&
399
+ (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
400
+
401
+ ret = computedStyle.getPropertyValue( name );
402
+ ...
403
+
404
+ */
405
+
406
+ })(jQuery);
@@ -0,0 +1,402 @@
1
+ /* http://keith-wood.name/svg.html
2
+ SVG filters for jQuery v1.4.5.
3
+ Written by Keith Wood (kbwood{at}iinet.com.au) August 2007.
4
+ Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
5
+ MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
6
+ Please attribute the author if you use it. */
7
+
8
+ (function($) { // Hide scope, no $ conflict
9
+
10
+ $.svg.addExtension('filters', SVGFilter);
11
+
12
+ $.extend($.svg._wrapperClass.prototype, {
13
+
14
+ /* Add a filter definition.
15
+ @param parent (element or jQuery) the parent node for the new filter (optional)
16
+ @param id (string) the ID for this filter
17
+ @param x (number) the x-coordinate for the left edge of the filter
18
+ @param y (number) the y-coordinate for the top edge of the filter
19
+ @param width (number) the width of the filter
20
+ @param height (number) the height of the filter
21
+ @param settings (object) additional settings for the filter (optional)
22
+ @return (element) the new filter node */
23
+ filter: function(parent, id, x, y, width, height, settings) {
24
+ var args = this._args(arguments, ['id', 'x', 'y', 'width', 'height']);
25
+ return this._makeNode(args.parent, 'filter', $.extend(
26
+ {id: args.id, x: args.x, y: args.y, width: args.width, height: args.height},
27
+ args.settings || {}));
28
+ }
29
+ });
30
+
31
+ /* Extension point for SVG filters.
32
+ Access through svg.filters. */
33
+ function SVGFilter(wrapper) {
34
+ this._wrapper = wrapper; // The attached SVG wrapper object
35
+ }
36
+
37
+ $.extend(SVGFilter.prototype, {
38
+
39
+ /* Add a distant light filter.
40
+ @param parent (element or jQuery) the parent node for the new filter (optional)
41
+ @param result (string) the ID of this filter
42
+ @param azimuth (number) the angle (degrees) in the XY plane for the light source
43
+ @param elevation (number) the angle (degrees) in the YZ plane for the light source
44
+ @param settings (object) additional settings for the filter (optional)
45
+ @return (element) the new filter node */
46
+ distantLight: function(parent, result, azimuth, elevation, settings) {
47
+ var args = this._wrapper._args(arguments, ['result', 'azimuth', 'elevation']);
48
+ return this._wrapper._makeNode(args.parent, 'feDistantLight', $.extend(
49
+ {result: args.result, azimuth: args.azimuth, elevation: args.elevation},
50
+ args.settings || {}));
51
+ },
52
+
53
+ /* Add a point light filter.
54
+ @param parent (element or jQuery) the parent node for the new filter (optional)
55
+ @param result (string) the ID of this filter
56
+ @param x (number) the x-coordinate for the light source
57
+ @param y (number) the y-coordinate for the light source
58
+ @param z (number) the z-coordinate for the light source
59
+ @param settings (object) additional settings for the filter (optional)
60
+ @return (element) the new filter node */
61
+ pointLight: function(parent, result, x, y, z, settings) {
62
+ var args = this._wrapper._args(arguments, ['result', 'x', 'y', 'z']);
63
+ return this._wrapper._makeNode(args.parent, 'fePointLight', $.extend(
64
+ {result: args.result, x: args.x, y: args.y, z: args.z}, args.settings || {}));
65
+ },
66
+
67
+ /* Add a spot light filter.
68
+ Specify all of toX, toY, toZ or none of them.
69
+ @param parent (element or jQuery) the parent node for the new filter (optional)
70
+ @param result (string) the ID of this filter
71
+ @param x (number) the x-coordinate for the light source
72
+ @param y (number) the y-coordinate for the light source
73
+ @param z (number) the z-coordinate for the light source
74
+ @param toX (number) the x-coordinate for where the light is pointing (optional)
75
+ @param toY (number) the y-coordinate for where the light is pointing (optional)
76
+ @param toZ (number) the z-coordinate for where the light is pointing (optional)
77
+ @param settings (object) additional settings for the filter (optional)
78
+ @return (element) the new filter node */
79
+ spotLight: function(parent, result, x, y, z, toX, toY, toZ, settings) {
80
+ var args = this._wrapper._args(arguments,
81
+ ['result', 'x', 'y', 'z', 'toX', 'toY', 'toZ'], ['toX']);
82
+ var sets = $.extend({result: args.result, x: args.x, y: args.y, z: args.z},
83
+ (args.toX != null ? {pointsAtX: args.toX, pointsAtY: args.toY,
84
+ pointsAtZ: args.toZ} : {}));
85
+ return this._wrapper._makeNode(args.parent, 'feSpotLight',
86
+ $.extend(sets, args.settings || {}));
87
+ },
88
+
89
+ /* Add a blend filter.
90
+ @param parent (element or jQuery) the parent node for the new filter (optional)
91
+ @param result (string) the ID of this filter
92
+ @param mode (string) normal | multiply | screen | darken | lighten
93
+ @param in1 (string) the first image to blend
94
+ @param in2 (string) the second image to blend
95
+ @param settings (object) additional settings for the filter (optional)
96
+ @return (element) the new filter node */
97
+ blend: function(parent, result, mode, in1, in2, settings) {
98
+ var args = this._wrapper._args(arguments, ['result', 'mode', 'in1', 'in2']);
99
+ return this._wrapper._makeNode(args.parent, 'feBlend', $.extend(
100
+ {result: args.result, mode: args.mode, in_: args.in1, in2: args.in2},
101
+ args.settings || {}));
102
+ },
103
+
104
+ /* Add a colour matrix filter.
105
+ @param parent (element or jQuery) the parent node for the new filter (optional)
106
+ @param result (string) the ID of this filter
107
+ @param in1 (string) the source to colour
108
+ @param type (string) matrix | saturate | hueRotate | luminanceToAlpha
109
+ @param values (number[][]) for 'matrix' the matrix (5x4) values to apply
110
+ (number) for 'saturate' 0.0 to 1.0
111
+ (number) for 'hueRotate' degrees
112
+ (void) for 'luminanceToAlpha'
113
+ @param settings (object) additional settings for the filter (optional)
114
+ @return (element) the new filter node */
115
+ colorMatrix: function(parent, result, in1, type, values, settings) {
116
+ var args = this._wrapper._args(arguments, ['result', 'in1', 'type', 'values']);
117
+ if (isArray(args.values)) {
118
+ var vs = '';
119
+ for (var i = 0; i < args.values.length; i++) {
120
+ vs += (i == 0 ? '' : ' ') + args.values[i].join(' ');
121
+ }
122
+ args.values = vs;
123
+ }
124
+ else if (typeof args.values == 'object') {
125
+ args.settings = args.values;
126
+ args.values = null;
127
+ }
128
+ var sets = $.extend({result: args.result, in_: args.in1, type: args.type},
129
+ (args.values != null ? {values: args.values} : {}));
130
+ return this._wrapper._makeNode(args.parent, 'feColorMatrix',
131
+ $.extend(sets, args.settings || {}));
132
+ },
133
+
134
+ /* Add a component transfer filter.
135
+ @param parent (element or jQuery) the parent node for the new filter (optional)
136
+ @param result (string) the ID of this filter
137
+ @param functions (object[]) one for each of RGB and A (alpha, optional)
138
+ for each entry:
139
+ [0] is (string) identity | table | discrete | linear | gamma
140
+ [1] is (number[]) for 'table' or 'discrete' the list of
141
+ interpolation or step values OR
142
+ (number) for 'linear' the slope, for 'gamma' the amplitude,
143
+ [2] is (number) for 'linear' the intercept, for 'gamma' the exponent,
144
+ [3] is (number) for 'gamma' the offset
145
+ @param settings (object) additional settings for the filter (optional)
146
+ @return (element) the new filter node */
147
+ componentTransfer: function(parent, result, functions, settings) {
148
+ var args = this._wrapper._args(arguments, ['result', 'functions']);
149
+ var node = this._wrapper._makeNode(args.parent, 'feComponentTransfer',
150
+ $.extend({result: args.result}, args.settings || {}));
151
+ var rgba = ['R', 'G', 'B', 'A'];
152
+ for (var i = 0; i < Math.min(4, args.functions.length); i++) {
153
+ var props = args.functions[i];
154
+ var sets = $.extend({type: props[0]},
155
+ (props[0] == 'table' || props[0] == 'discrete' ? {tableValues: props[1].join(' ')} :
156
+ (props[0] == 'linear' ? {slope: props[1], intercept: props[2]} :
157
+ (props[0] == 'gamma' ? {amplitude: props[1],
158
+ exponent: props[2], offset: props[3]} : {}))));
159
+ this._wrapper._makeNode(node, 'feFunc' + rgba[i], sets);
160
+ }
161
+ return node;
162
+ },
163
+
164
+ /* Add a composite filter.
165
+ Specify all of k1, k2, k3, k4 or none of them.
166
+ @param parent (element or jQuery) the parent node for the new filter (optional)
167
+ @param result (string) the ID of this filter
168
+ @param operator (string) over | in | out | atop | xor | arithmetic
169
+ @param in1 (string) the first filter to compose
170
+ @param in2 (string) the second filter to compose
171
+ @param k1 (number) for 'arithmetic' (optional)
172
+ @param k2 (number) for 'arithmetic' (optional)
173
+ @param k3 (number) for 'arithmetic' (optional)
174
+ @param k4 (number) for 'arithmetic' (optional)
175
+ @param settings (object) additional settings for the filter (optional)
176
+ @return (element) the new filter node */
177
+ composite: function(parent, result, operator, in1, in2, k1, k2, k3, k4, settings) {
178
+ var args = this._wrapper._args(arguments, ['result', 'operator',
179
+ 'in1', 'in2', 'k1', 'k2', 'k3', 'k4'], ['k1']);
180
+ var sets = $.extend({result: args.result, operator: args.operator,
181
+ 'in': args.in1, in2: args.in2},
182
+ (args.k1 != null ? {k1: args.k1, k2: args.k2, k3: args.k3, k4: args.k4} : {}));
183
+ return this._wrapper._makeNode(args.parent, 'feComposite',
184
+ $.extend(sets, args.settings || {}));
185
+ },
186
+
187
+ /* Add a convolve matrix filter.
188
+ @param parent (element or jQuery) the parent node for the new filter (optional)
189
+ @param result (string) the ID of this filter
190
+ @param order (int or 'int int') the size(s) of the matrix
191
+ @param matrix (number[][]) the kernel matrix for the convolution
192
+ @param settings (object) additional settings for the filter (optional)
193
+ @return (element) the new filter node */
194
+ convolveMatrix: function(parent, result, order, matrix, settings) {
195
+ var args = this._wrapper._args(arguments, ['result', 'order', 'matrix']);
196
+ var mx = '';
197
+ for (var i = 0; i < args.matrix.length; i++) {
198
+ mx += (i == 0 ? '' : ' ') + args.matrix[i].join(' ');
199
+ }
200
+ args.matrix = mx;
201
+ return this._wrapper._makeNode(args.parent, 'feConvolveMatrix', $.extend(
202
+ {result: args.result, order: args.order, kernelMatrix: args.matrix},
203
+ args.settings || {}));
204
+ },
205
+
206
+ /* Add a diffuse lighting filter.
207
+ @param parent (element or jQuery) the parent node for the new filter (optional)
208
+ @param result (string) the ID of this filter
209
+ @param colour (string) the lighting colour (optional)
210
+ @param settings (object) additional settings for the filter (optional)
211
+ @return (element) the new filter node */
212
+ diffuseLighting: function(parent, result, colour, settings) {
213
+ var args = this._wrapper._args(arguments, ['result', 'colour'], ['colour']);
214
+ return this._wrapper._makeNode(args.parent, 'feDiffuseLighting',
215
+ $.extend($.extend({result: args.result},
216
+ (args.colour ? {lightingColor: args.colour} : {})), args.settings || {}));
217
+ },
218
+
219
+ /* Add a displacement map filter.
220
+ @param parent (element or jQuery) the parent node for the new filter (optional)
221
+ @param result (string) the ID of this filter
222
+ @param in1 (string) the source image
223
+ @param in2 (string) the displacement image
224
+ @param settings (object) additional settings for the filter (optional)
225
+ @return (element) the new filter node */
226
+ displacementMap: function(parent, result, in1, in2, settings) {
227
+ var args = this._wrapper._args(arguments, ['result', 'in1', 'in2']);
228
+ return this._wrapper._makeNode(args.parent, 'feDisplacementMap',
229
+ $.extend({result: args.result, in_: args.in1, in2: args.in2},
230
+ args.settings || {}));
231
+ },
232
+
233
+ /* Add a flood filter.
234
+ Specify all of x, y, width, height or none of them.
235
+ @param parent (element or jQuery) the parent node for the new filter (optional)
236
+ @param result (string) the ID of this filter
237
+ @param x (number) the left coordinate of the rectangle (optional)
238
+ @param y (number) the top coordinate of the rectangle (optional)
239
+ @param width (number) the width of the rectangle (optional)
240
+ @param height (number) the height of the rectangle (optional)
241
+ @param colour (string) the colour to fill with
242
+ @param opacity (number) the opacity 0.0-1.0
243
+ @param settings (object) additional settings for the filter (optional)
244
+ @return (element) the new filter node */
245
+ flood: function(parent, result, x, y, width, height, colour, opacity, settings) {
246
+ var args = this._wrapper._args(arguments,
247
+ ['result', 'x', 'y', 'width', 'height', 'colour', 'opacity']);
248
+ if (arguments.length < 6) {
249
+ args.colour = args.x;
250
+ args.opacity = args.y;
251
+ args.settings = args.width;
252
+ args.x = null;
253
+ }
254
+ var sets = $.extend({result: args.result, floodColor: args.colour,
255
+ floodOpacity: args.opacity}, (args.x != null ?
256
+ {x: args.x, y: args.y, width: args.width, height: args.height} : {}));
257
+ return this._wrapper._makeNode(args.parent, 'feFlood',
258
+ $.extend(sets, args.settings || {}));
259
+ },
260
+
261
+ /* Add a Gaussian blur filter.
262
+ @param parent (element or jQuery) the parent node for the new filter (optional)
263
+ @param result (string) the ID of this filter
264
+ @param in1 (string) the source filter
265
+ @param stdDevX (number) the standard deviation along the x-axis
266
+ @param stdDevY (number) the standard deviation along the y-axis (optional)
267
+ @param settings (object) additional settings for the filter (optional)
268
+ @return (element) the new filter node */
269
+ gaussianBlur: function(parent, result, in1, stdDevX, stdDevY, settings) {
270
+ var args = this._wrapper._args(arguments,
271
+ ['result', 'in1', 'stdDevX', 'stdDevY'], ['stdDevY']);
272
+ return this._wrapper._makeNode(args.parent, 'feGaussianBlur', $.extend(
273
+ {result: args.result, in_: args.in1, stdDeviation: args.stdDevX +
274
+ (args.stdDevY ? ' ' + args.stdDevY : '')}, args.settings || {}));
275
+ },
276
+
277
+ /* Add an image filter.
278
+ @param parent (element or jQuery) the parent node for the new filter (optional)
279
+ @param result (string) the ID of this filter
280
+ @param href (string) the URL of the image
281
+ @param settings (object) additional settings for the filter (optional)
282
+ @return (element) the new filter node */
283
+ image: function(parent, result, href, settings) {
284
+ var args = this._wrapper._args(arguments, ['result', 'href']);
285
+ var node = this._wrapper._makeNode(args.parent, 'feImage', $.extend(
286
+ {result: args.result}, args.settings || {}));
287
+ node.setAttributeNS($.svg.xlinkNS, 'href', args.href);
288
+ return node;
289
+ },
290
+
291
+ /* Add a merge filter.
292
+ @param parent (element or jQuery) the parent node for the new filter (optional)
293
+ @param result (string) the ID of this filter
294
+ @param refs (string[]) the IDs of the filters to merge
295
+ @param settings (object) additional settings for the filter (optional)
296
+ @return (element) the new filter node */
297
+ merge: function(parent, result, refs, settings) {
298
+ var args = this._wrapper._args(arguments, ['result', 'refs']);
299
+ var node = this._wrapper._makeNode(args.parent, 'feMerge', $.extend(
300
+ {result: args.result}, args.settings || {}));
301
+ for (var i = 0; i < args.refs.length; i++) {
302
+ this._wrapper._makeNode(node, 'feMergeNode', {in_: args.refs[i]});
303
+ }
304
+ return node;
305
+ },
306
+
307
+ /* Add a morphology filter.
308
+ @param parent (element or jQuery) the parent node for the new filter (optional)
309
+ @param result (string) the ID of this filter
310
+ @param in1 (string) the source filter
311
+ @param operator (string) erode | dilate
312
+ @param radiusX (number) the size of the operation in the x-axis
313
+ @param radiusY (number) the size of the operation in the y-axis (optional)
314
+ @param settings (object) additional settings for the filter (optional)
315
+ @return (element) the new filter node */
316
+ morphology: function(parent, result, in1, operator, radiusX, radiusY, settings) {
317
+ var args = this._wrapper._args(arguments, ['result', 'in1',
318
+ 'operator', 'radiusX', 'radiusY'], ['radiusY']);
319
+ return this._wrapper._makeNode(args.parent, 'feMorphology', $.extend(
320
+ {result: args.result, in_: args.in1, operator: args.operator,
321
+ radius: args.radiusX + (args.radiusY ? ' ' + args.radiusY : '')},
322
+ args.settings || {}));
323
+ },
324
+
325
+ /* Add an offset filter.
326
+ @param parent (element or jQuery) the parent node for the new filter (optional)
327
+ @param result (string) the ID of this filter
328
+ @param in1 (string) the source filter
329
+ @param dX (number) the offset in the x-axis
330
+ @param dY (number) the offset in the y-axis
331
+ @param settings (object) additional settings for the filter (optional)
332
+ @return (element) the new filter node */
333
+ offset: function(parent, result, in1, dx, dy, settings) {
334
+ var args = this._wrapper._args(arguments, ['result', 'in1', 'dx', 'dy']);
335
+ return this._wrapper._makeNode(args.parent, 'feOffset', $.extend(
336
+ {result: args.result, in_: args.in1, dx: args.dx, dy: args.dy},
337
+ args.settings || {}));
338
+ },
339
+
340
+ /* Add a specular lighting filter.
341
+ Numeric params are only optional if following numeric params are also omitted.
342
+ @param parent (element or jQuery) the parent node for the new filter (optional)
343
+ @param result (string) the ID of this filter
344
+ @param in1 (string) the source filter
345
+ @param surfaceScale (number) the surface height when Ain = 1 (optional)
346
+ @param specularConstant (number) the ks in Phong lighting model (optional)
347
+ @param specularExponent (number) the shininess 1.0-128.0 (optional)
348
+ @param settings (object) additional settings for the filter (optional)
349
+ @return (element) the new filter node */
350
+ specularLighting: function(parent, result, in1, surfaceScale,
351
+ specularConstant, specularExponent, settings) {
352
+ var args = this._wrapper._args(arguments, ['result', 'in1',
353
+ 'surfaceScale', 'specularConstant', 'specularExponent'],
354
+ ['surfaceScale', 'specularConstant', 'specularExponent']);
355
+ return this._wrapper._makeNode(args.parent, 'feSpecularLighting', $.extend(
356
+ {result: args.result, in_: args.in1, surfaceScale: args.surfaceScale,
357
+ specularConstant: args.specularConstant, specularExponent: args.specularExponent},
358
+ args.settings || {}));
359
+ },
360
+
361
+ /* Add a tile filter.
362
+ @param parent (element or jQuery) the parent node for the new filter (optional)
363
+ @param result (string) the ID of this filter
364
+ @param in1 (string) the source filter
365
+ @param x (number) the left coordinate of the rectangle
366
+ @param y (number) the top coordinate of the rectangle
367
+ @param width (number) the width of the rectangle
368
+ @param height (number) the height of the rectangle
369
+ @param settings (object) additional settings for the filter (optional)
370
+ @return (element) the new filter node */
371
+ tile: function(parent, result, in1, x, y, width, height, settings) {
372
+ var args = this._wrapper._args(arguments,
373
+ ['result', 'in1', 'x', 'y', 'width', 'height']);
374
+ return this._wrapper._makeNode(args.parent, 'feTile', $.extend(
375
+ {result: args.result, in_: args.in1, x: args.x, y: args.y,
376
+ width: args.width, height: args.height}, args.settings || {}));
377
+ },
378
+
379
+ /* Add a turbulence filter.
380
+ @param parent (element or jQuery) the parent node for the new filter (optional)
381
+ @param result (string) the ID of this filter
382
+ @param type (string) fractalNoise | turbulence
383
+ @param baseFreq (number or 'number number') the base frequency,
384
+ optionally separated into x- and y-components
385
+ @param octaves (number) the amount of turbulence (optional)
386
+ @param settings (object) additional settings for the filter (optional)
387
+ @return (element) the new filter node */
388
+ turbulence: function(parent, result, type, baseFreq, octaves, settings) {
389
+ var args = this._wrapper._args(arguments, ['result', 'type',
390
+ 'baseFreq', 'octaves'], ['octaves']);
391
+ return this._wrapper._makeNode(args.parent, 'feTurbulence', $.extend(
392
+ {result: args.result, type: args.type, baseFrequency: args.baseFreq,
393
+ numOctaves: args.octaves}, args.settings || {}));
394
+ }
395
+ });
396
+
397
+ /* Determine whether an object is an array. */
398
+ function isArray(a) {
399
+ return (a && a.constructor == Array);
400
+ }
401
+
402
+ })(jQuery)