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