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