1 /*
2 * Copyright (C) 2008 Emweb bv, Herent, Belgium.
3 *
4 * See the LICENSE file for terms of use.
5 */
6 #include "Wt/WApplication.h"
7 #include "Wt/WException.h"
8 #include "Wt/WJavaScriptSlot.h"
9 #include "Wt/WStatelessSlot.h"
10 #include "Wt/WWidget.h"
11
12 namespace Wt {
13
14 #if defined(WT_THREADED) || defined(WT_TARGET_JAVA)
15 std::atomic<unsigned> JSlot::nextFid_(0);
16 #else
17 unsigned JSlot::nextFid_ = 0;
18 #endif
19
20 class WStatelessSlotImpl : public WStatelessSlot {
21 public:
WStatelessSlotImpl(WObject * target,WObjectMethod method,const std::string & javaScript)22 WStatelessSlotImpl(WObject *target, WObjectMethod method,
23 const std::string& javaScript) :
24 WStatelessSlot(target, method, javaScript) { }
25 };
26
JSlot(WWidget * parent)27 JSlot::JSlot(WWidget *parent)
28 : widget_(parent),
29 fid_(nextFid_++),
30 nbArgs_(0)
31 {
32 create();
33 }
34
JSlot(const std::string & javaScript,WWidget * parent)35 JSlot::JSlot(const std::string& javaScript, WWidget *parent)
36 : widget_(parent),
37 fid_(nextFid_++),
38 nbArgs_(0)
39 {
40 create();
41 setJavaScript(javaScript);
42 }
43
JSlot(int nbArgs,WWidget * parent)44 JSlot::JSlot(int nbArgs, WWidget *parent)
45 : widget_(parent),
46 fid_(nextFid_++),
47 nbArgs_(nbArgs)
48 {
49 if (nbArgs_ < 0 || nbArgs_ > 6) {
50 throw WException("The number of arguments given must be between 0 and 6.");
51 }
52 create();
53 }
54
JSlot(const std::string & javaScript,int nbArgs,WWidget * parent)55 JSlot::JSlot(const std::string& javaScript, int nbArgs, WWidget *parent)
56 : widget_(parent),
57 fid_(nextFid_++),
58 nbArgs_(nbArgs)
59 {
60 if (nbArgs_ < 0 || nbArgs_ > 6) {
61 throw WException("The number of arguments given must be between 0 and 6.");
62 }
63 create();
64 setJavaScript(javaScript, nbArgs_);
65 }
66
create()67 void JSlot::create()
68 {
69 std::stringstream ss;
70
71 if (widget_) {
72 WApplication *app = WApplication::instance();
73 if (app) {
74 ss << WApplication::instance()->javaScriptClass() << "."
75 << jsFunctionName() << "(o,e";
76 for (int i = 1; i <= nbArgs_; ++i) {
77 ss << ",a" << i;
78 }
79 ss << ");";
80 }
81 }
82
83 imp_ = new WStatelessSlotImpl(widget_, nullptr, ss.str());
84 }
85
~JSlot()86 JSlot::~JSlot()
87 {
88 delete imp_;
89 }
90
jsFunctionName()91 std::string JSlot::jsFunctionName() const
92 {
93 return "sf" + std::to_string(fid_);
94 }
95
setJavaScript(const std::string & js,int nbArgs)96 void JSlot::setJavaScript(const std::string& js, int nbArgs)
97 {
98 if (nbArgs < 0 || nbArgs > 6) {
99 throw WException("The number of arguments given must be between 0 and 6.");
100 }
101 nbArgs_ = nbArgs;
102 WApplication *app = WApplication::instance();
103 if (widget_ && app)
104 WApplication::instance()->declareJavaScriptFunction(jsFunctionName(), js);
105 else {
106 std::stringstream ss;
107 ss << "{var f=" << js << ";f(o,e";
108 for (int i = 1; i <= nbArgs; ++i) {
109 ss << ",a" << i;
110 }
111 ss << ");}";
112 imp_->setJavaScript(ss.str());
113 }
114 }
115
slotimp()116 WStatelessSlot* JSlot::slotimp()
117 {
118 return imp_;
119 }
120
execJs(const std::string & object,const std::string & event,const std::string & arg1,const std::string & arg2,const std::string & arg3,const std::string & arg4,const std::string & arg5,const std::string & arg6)121 std::string JSlot::execJs(const std::string& object,
122 const std::string& event,
123 const std::string& arg1,
124 const std::string& arg2,
125 const std::string& arg3,
126 const std::string& arg4,
127 const std::string& arg5,
128 const std::string& arg6)
129 {
130 std::stringstream result;
131 result << "{var o=" << object;
132 result << ",e=" << event;
133 for (int i = 0; i < nbArgs_; ++i) {
134 result << ",a" << (i+1) << "=";
135 switch (i) {
136 case 0:
137 result << arg1;
138 break;
139 case 1:
140 result << arg2;
141 break;
142 case 2:
143 result << arg3;
144 break;
145 case 3:
146 result << arg4;
147 break;
148 case 4:
149 result << arg5;
150 break;
151 case 5:
152 result << arg6;
153 break;
154 }
155 }
156 result << ";" << imp_->javaScript() + "}";
157 return result.str();
158 }
159
exec(const std::string & object,const std::string & event,const std::string & arg1,const std::string & arg2,const std::string & arg3,const std::string & arg4,const std::string & arg5,const std::string & arg6)160 void JSlot::exec(const std::string& object,
161 const std::string& event,
162 const std::string& arg1,
163 const std::string& arg2,
164 const std::string& arg3,
165 const std::string& arg4,
166 const std::string& arg5,
167 const std::string& arg6)
168 {
169 WApplication::instance()->doJavaScript(execJs(object, event, arg1, arg2, arg3, arg4, arg5, arg6));
170 }
171
172 #ifndef WT_TARGET_JAVA
disconnectFrom(EventSignalBase * signal)173 void JSlot::disconnectFrom(EventSignalBase *signal)
174 {
175 imp_->disconnectFrom(signal);
176 }
177 #endif
178
179 }
180