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