2006-02-11 Eric Seidel <eseidel@apple.com>
[WebKit-https.git] / WebCore / ksvg2 / ecma / Ecma.cpp
1 /*
2     Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org>
3                   2004, 2005 Rob Buis <buis@kde.org>
4
5     This file is part of the KDE project
6
7     This library is free software; you can redistribute it and/or
8     modify it under the terms of the GNU Library General Public
9     License as published by the Free Software Foundation; either
10     version 2 of the License, or (at your option) any later version.
11
12     This library is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15     Library General Public License for more details.
16
17     You should have received a copy of the GNU Library General Public License
18     along with this library; see the file COPYING.LIB.  If not, write to
19     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20     Boston, MA 02111-1307, USA.
21 */
22
23 #include "config.h"
24 #if SVG_SUPPORT
25 #include <kdom/Namespace.h>
26 #include "css_valueimpl.h"
27 #include <kdom/events/Event.h>
28 #include <kdom/core/NodeImpl.h>
29 #include <kdom/events/EventImpl.h>
30
31 #include "ksvg.h"
32 #include "Ecma.h"
33 #include "SVGPaint.h"
34 #include "SVGEvent.h"
35 #include "SVGColor.h"
36 #include "SVGPathSeg.h"
37 #include "SVGAElement.h"
38 #include "SVGDocument.h"
39 #include "SVGGElement.h"
40 #include "SVGPaintImpl.h"
41 #include "GlobalObject.h"
42 #include "SVGColorImpl.h"
43 #include "SVGZoomEvent.h"
44 #include "SVGUseElement.h"
45 #include "SVGSVGElement.h"
46 #include "SVGPathSegArc.h"
47 #include "SVGSetElement.h"
48 #include "EcmaInterface.h"
49 #include "SVGDescElement.h"
50 #include "SVGRectElement.h"
51 #include "SVGDefsElement.h"
52 #include "SVGStopElement.h"
53 #include "SVGPathElement.h"
54 #include "SVGLineElement.h"
55 #ifdef TEXTSUPPORT
56 #include "SVGTextElement.h"
57 #include "SVGTSpanElement.h"
58 #endif
59 #include "SVGViewElement.h"
60 #include "SVGImageElement.h"
61 #include "SVGTitleElement.h"
62 #include "SVGFilterElement.h"
63 #include "SVGFEBlendElement.h"
64 #include "SVGFEFloodElement.h"
65 #include "SVGFEOffsetElement.h"
66 #include "SVGFEImageElement.h"
67 #include "SVGFEMergeElement.h"
68 #include "SVGFEMergeNodeElement.h"
69 #include "SVGStyleElement.h"
70 #include "SVGPathSegMoveto.h"
71 #include "SVGPathSegLineto.h"
72 #include "SVGSwitchElement.h"
73 #include "SVGScriptElement.h"
74 #include "SVGCircleElement.h"
75 #include "SVGSymbolElement.h"
76 #include "SVGZoomEventImpl.h"
77 #include "SVGMarkerElement.h"
78 #include "SVGEllipseElement.h"
79 #include "SVGAnimateElement.h"
80 #include "SVGPolygonElement.h"
81 #include "SVGPatternElement.h"
82 #include "SVGMaskElement.h"
83 #include "SVGPolylineElement.h"
84 #include "SVGClipPathElement.h"
85 #include "SVGPathSegClosePath.h"
86 #include "SVGStyledElementImpl.h"
87 #include "SVGFECompositeElement.h"
88 #include "SVGFEColorMatrixElement.h"
89 #include "SVGFEGaussianBlurElement.h"
90 #include "SVGAnimateColorElement.h"
91 #include "SVGPathSegCurvetoCubic.h"
92 #include "SVGLinearGradientElement.h"
93 #include "SVGRadialGradientElement.h"
94 #include "SVGPathSegLinetoVertical.h"
95 #include "SVGPathSegLinetoHorizontal.h"
96 #include "SVGPathSegCurvetoQuadratic.h"
97 #include "SVGAnimateTransformElement.h"
98 #include "SVGPathSegCurvetoCubicSmooth.h"
99 #include "SVGPathSegCurvetoQuadraticSmooth.h"
100
101 using namespace WebCore;
102
103 Ecma::Ecma(DocumentImpl *doc) : Ecma(doc)
104 {
105 }
106
107 Ecma::~Ecma()
108 {
109 }
110
111 void Ecma::setupDocument(DocumentImpl *document)
112 {
113     ASSERT(DOMString(document->namespaceURI()) == NS_SVG)
114     SVGDocumentImpl *svgDocument = static_cast<SVGDocumentImpl *>(document);
115     
116     // Create base bridge for document
117     SVGDocument docObj(svgDocument);
118
119     KJS::JSObject *kjsObj = docObj.bridge(interpreter()->globalExec());
120
121     interpreter()->putDOMObject(svgDocument, kjsObj);
122     svgDocument->deref();
123 }
124
125 KJS::JSObject *Ecma::inheritedGetDOMNode(KJS::ExecState *exec, Node n)
126 {
127     // Use svg element ids to distinguish between svg elements.
128     KJS::JSObject *ret = 0;
129
130     NodeImpl *nodeImpl = static_cast<NodeImpl *>(n.handle());
131     if(!nodeImpl)
132         return ret;
133
134     if(nodeImpl->namespaceURI() != NS_SVG)
135         return ret;
136
137     // Special case for our document
138     if(n.nodeType() == DOCUMENT_NODE)
139         return SVGDocument(n).bridge(exec);
140
141     switch(nodeImpl->getIDAttribute())
142     {
143         // TODO: Add all remaining nodes here...
144         case ID_SVG:
145         {
146             ret = SVGSVGElement(n).bridge(exec);
147             break;
148         }
149         case ID_STYLE:
150         {
151             ret = SVGStyleElement(n).bridge(exec);
152             break;
153         }
154         case ID_SCRIPT:
155         {
156             ret = SVGScriptElement(n).bridge(exec);
157             break;
158         }
159         case ID_RECT:
160         {
161             ret = SVGRectElement(n).bridge(exec);
162             break;
163         }
164         case ID_CIRCLE:
165         {
166             ret = SVGCircleElement(n).bridge(exec);
167             break;
168         }
169         case ID_ELLIPSE:
170         {
171             ret = SVGEllipseElement(n).bridge(exec);
172             break;
173         }
174         case ID_POLYLINE:
175         {
176             ret = SVGPolylineElement(n).bridge(exec);
177             break;
178         }
179         case ID_POLYGON:
180         {
181             ret = SVGPolygonElement(n).bridge(exec);
182             break;
183         }
184         case ID_G:
185         {
186             ret = SVGGElement(n).bridge(exec);
187             break;
188         }
189         case ID_SWITCH:
190         {
191             ret = SVGSwitchElement(n).bridge(exec);
192             break;
193         }
194         case ID_DEFS:
195         {
196             ret = SVGDefsElement(n).bridge(exec);
197             break;
198         }
199         case ID_STOP:
200         {
201             ret = SVGStopElement(n).bridge(exec);
202             break;
203         }
204         case ID_PATH:
205         {
206             ret = SVGPathElement(n).bridge(exec);
207             break;
208         }
209         case ID_IMAGE:
210         {
211             ret = SVGImageElement(n).bridge(exec);
212             break;
213         }
214         case ID_CLIPPATH:
215         {
216             ret = SVGClipPathElement(n).bridge(exec);
217             break;
218         }
219         case ID_A:
220         {
221             ret = SVGAElement(n).bridge(exec);
222             break;
223         }
224         case ID_LINE:
225         {
226             ret = SVGLineElement(n).bridge(exec);
227             break;
228         }
229         case ID_LINEARGRADIENT:
230         {
231             ret = SVGLinearGradientElement(n).bridge(exec);
232             break;
233         }
234         case ID_RADIALGRADIENT:
235         {
236             ret = SVGRadialGradientElement(n).bridge(exec);
237             break;
238         }
239         case ID_TITLE:
240         {
241             ret = SVGTitleElement(n).bridge(exec);
242             break;
243         }
244         case ID_DESC:
245         {
246             ret = SVGDescElement(n).bridge(exec);
247             break;
248         }
249         case ID_SYMBOL:
250         {
251             ret = SVGSymbolElement(n).bridge(exec);
252             break;
253         }
254         case ID_USE:
255         {
256             ret = SVGUseElement(n).bridge(exec);
257             break;
258         }
259         case ID_PATTERN:
260         {
261             ret = SVGPatternElement(n).bridge(exec);
262             break;
263         }
264         case ID_MASK:
265         {
266             ret = SVGMaskElement(n).bridge(exec);
267             break;
268         }
269         case ID_ANIMATECOLOR:
270         {
271             ret = SVGAnimateColorElement(n).bridge(exec);
272             break;
273         }
274         case ID_ANIMATETRANSFORM:
275         {
276             ret = SVGAnimateTransformElement(n).bridge(exec);
277             break;
278         }
279         case ID_SET:
280         {
281             ret = SVGSetElement(n).bridge(exec);
282             break;
283         }
284         case ID_ANIMATE:
285         {
286             ret = SVGAnimateElement(n).bridge(exec);
287             break;
288         }
289         case ID_MARKER:
290         {
291             ret = SVGMarkerElement(n).bridge(exec);
292             break;
293         }
294         case ID_VIEW:
295         {
296             ret = SVGViewElement(n).bridge(exec);
297             break;
298         }
299         case ID_FILTER:
300         {
301             ret = SVGFilterElement(n).bridge(exec);
302             break;
303         }
304         case ID_FEGAUSSIANBLUR:
305         {
306             ret = SVGFEGaussianBlurElement(n).bridge(exec);
307             break;
308         }
309         case ID_FEFLOOD:
310         {
311             ret = SVGFEFloodElement(n).bridge(exec);
312             break;
313         }
314         case ID_FEBLEND:
315         {
316             ret = SVGFEBlendElement(n).bridge(exec);
317             break;
318         }
319         case ID_FEOFFSET:
320         {
321             ret = SVGFEOffsetElement(n).bridge(exec);
322             break;
323         }
324         case ID_FECOMPOSITE:
325         {
326             ret = SVGFECompositeElement(n).bridge(exec);
327             break;
328         }
329         case ID_FECOLORMATRIX:
330         {
331             ret = SVGFEColorMatrixElement(n).bridge(exec);
332             break;
333         }
334         case ID_FEIMAGE:
335         {
336             ret = SVGFEImageElement(n).bridge(exec);
337             break;
338         }
339         case ID_FEMERGE:
340         {
341             ret = SVGFEMergeElement(n).bridge(exec);
342             break;
343         }
344         case ID_FEMERGENODE:
345         {
346             ret = SVGFEMergeNodeElement(n).bridge(exec);
347             break;
348         }
349 #ifdef TEXTSUPPORT
350         case ID_TEXT:
351         {
352             ret = SVGTextElement(n).bridge(exec);
353             break;
354         }
355         case ID_TSPAN:
356         {
357             ret = SVGTSpanElement(n).bridge(exec);
358             break;
359         }
360 #endif
361         default: // Maybe it's an SVG?Element, w/o ecma bindings so far...
362             ret = SVGElement(n).bridge(exec);
363     }
364
365     return ret;
366 }
367
368 KJS::JSObject *Ecma::inheritedGetDOMEvent(KJS::ExecState *exec, Event e)
369 {
370     EventImpl *eventImpl = e.handle();
371     if(!eventImpl)
372         return 0;
373
374     EventImplType identifier = eventImpl->identifier();
375     if(identifier != TypeLastEvent)
376         return 0;
377
378     SVGEventImpl *test1 = dynamic_cast<SVGEventImpl *>(eventImpl);
379     if(test1)
380         return SVGEvent(test1).bridge(exec);
381
382     SVGZoomEventImpl *test2 = dynamic_cast<SVGZoomEventImpl *>(eventImpl);
383     if(test2)
384         return SVGZoomEvent(test2).bridge(exec);
385
386     return 0;
387 }
388
389 KJS::JSObject *Ecma::inheritedGetDOMCSSValue(KJS::ExecState *exec, CSSValue c)
390 {
391     CSSValueImpl *impl = c.handle();
392
393     // Keep the order, as SVGPaintImpl inherits from SVGColorImpl...
394     SVGPaintImpl *test1 = dynamic_cast<SVGPaintImpl *>(impl);
395     if(test1)
396         return SVGPaint(test1).bridge(exec);
397
398     SVGColorImpl *test2 = dynamic_cast<SVGColorImpl *>(impl);
399     if(test2)
400         return SVGColor(test2).bridge(exec);
401
402     return 0;
403 }
404
405 KJS::JSValue *KSVG::getSVGPathSeg(KJS::ExecState *exec, SVGPathSeg s)
406 {
407     if(s == SVGPathSeg::null)
408         return KJS::jsNull();
409
410     ScriptInterpreter *interpreter = static_cast<ScriptInterpreter *>(exec->interpreter());
411     if(!interpreter)
412         return KJS::jsNull();
413     
414     // Reuse existing bridge, if possible
415     KJS::JSObject *request = interpreter->getDOMObject(s.handle());
416     if(request)
417         return request;
418     
419     KJS::JSObject *ret = 0;
420     unsigned short type = s.pathSegType();
421
422     switch(type)
423     {
424         case PATHSEG_CLOSEPATH:
425         {
426             ret = SVGPathSegClosePath(s).bridge(exec);
427             break;
428         }
429         case PATHSEG_MOVETO_ABS:
430         {
431             ret = SVGPathSegMovetoAbs(s).bridge(exec);
432             break;
433         }
434         case PATHSEG_MOVETO_REL:
435         {
436             ret = SVGPathSegMovetoRel(s).bridge(exec);
437             break;
438         }
439         case PATHSEG_LINETO_ABS:
440         {
441             ret = SVGPathSegLinetoAbs(s).bridge(exec);
442             break;
443         }
444         case PATHSEG_LINETO_REL:
445         {
446             ret = SVGPathSegLinetoRel(s).bridge(exec);
447             break;
448         }
449         case PATHSEG_CURVETO_CUBIC_ABS:
450         {
451             ret = SVGPathSegCurvetoCubicAbs(s).bridge(exec);
452             break;
453         }
454         case PATHSEG_CURVETO_CUBIC_REL:
455         {
456             ret = SVGPathSegCurvetoCubicRel(s).bridge(exec);
457             break;
458         }
459         case PATHSEG_CURVETO_QUADRATIC_ABS:
460         {
461             ret = SVGPathSegCurvetoQuadraticAbs(s).bridge(exec);
462             break;
463         }
464         case PATHSEG_CURVETO_QUADRATIC_REL:
465         {
466             ret = SVGPathSegCurvetoQuadraticRel(s).bridge(exec);
467             break;
468         }
469         case PATHSEG_ARC_ABS:
470         {
471             ret = SVGPathSegArcAbs().bridge(exec);
472             break;
473         }
474         case PATHSEG_ARC_REL:
475         {
476             ret = SVGPathSegArcRel(s).bridge(exec);
477             break;
478         }
479         case PATHSEG_LINETO_HORIZONTAL_ABS:
480         {
481             ret = SVGPathSegLinetoHorizontalAbs(s).bridge(exec);
482             break;
483         }
484         case PATHSEG_LINETO_HORIZONTAL_REL:
485         {
486             ret = SVGPathSegLinetoHorizontalRel(s).bridge(exec);
487             break;
488         }
489         case PATHSEG_LINETO_VERTICAL_ABS:
490         {
491             ret = SVGPathSegLinetoVerticalAbs(s).bridge(exec);
492             break;
493         }
494         case PATHSEG_LINETO_VERTICAL_REL:
495         {
496             ret = SVGPathSegLinetoVerticalRel(s).bridge(exec);
497             break;
498         }
499         case PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
500         {
501             ret = SVGPathSegCurvetoCubicSmoothAbs(s).bridge(exec);
502             break;
503         }
504         case PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
505         {
506             ret = SVGPathSegCurvetoCubicSmoothRel(s).bridge(exec);
507             break;
508         }
509         case PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
510         {
511             ret = SVGPathSegCurvetoQuadraticSmoothAbs(s).bridge(exec);
512             break;
513         }
514         case PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
515         {
516             ret = SVGPathSegCurvetoQuadraticSmoothRel(s).bridge(exec);
517             break;
518         }
519         default:
520             ret = s.bridge(exec);
521     }
522
523     interpreter->putDOMObject(s.handle(), ret);
524     return ret;
525 }
526
527
528
529 // vim:ts=4:noet
530 #endif // SVG_SUPPORT
531