KParts

scriptableextension.h
1 /*
2  This file is part of the KDE project
3  SPDX-FileCopyrightText: 2010 Maksim Orlovich <[email protected]>
4  SPDX-FileCopyrightText: 2002 Koos Vriezen <[email protected]>
5 
6  SPDX-License-Identifier: LGPL-2.0-or-later
7 */
8 
9 #ifndef kparts_scriptableextension_h
10 #define kparts_scriptableextension_h
11 
12 #include <kparts/part.h>
13 
14 #include <QObject>
15 #include <QVariant>
16 #include <memory>
17 
18 namespace KParts
19 {
20 class ScriptableExtension;
21 struct ScriptableExtensionPrivate;
22 class LiveConnectExtension;
23 
24 /**
25  * @class ScriptableExtension scriptableextension.h <KParts/ScriptableExtension>
26  *
27  * @short An extension class that permits KParts to be scripted (such as when embedded
28  * inside a KHTMLPart) and to access the host's scriptable objects as well.
29  *
30  * See @ref ScriptValueTypes for how values are passed to/from various methods here.
31  *
32  * @since 4.5
33  * \nosubgrouping
34  */
35 class KPARTS_EXPORT ScriptableExtension : public QObject
36 {
37  Q_OBJECT
38 public:
39  /** @defgroup ScriptValueTypes Script Value Types
40  * @{
41  * Values are passed to and from scriptable methods or properties as QVariants.
42  * Valid values may be bools, strings, and numbers (doubles), as well as the
43  * following custom types:
44  * \li @ref Null
45  * \li @ref Undefined
46  * \li @ref Exception
47  * \li @ref Object
48  * \li @ref FunctionRef
49  */
50 
51  /// Corresponds to 'null' in JavaScript
52  struct Null {
53  };
54 
55  /// Corresponds to 'undefined' in JavaScript
56  struct Undefined {
57  };
58 
59  /// Returned from operations to denote a failure. May not be passed in as
60  /// a parameter, only returned
61  struct Exception {
62  /// Error message returned from the callee. This should be assumed to be
63  /// low-level (in particular, it might not be translated) and should
64  /// only be displayed in low-level debugging tools and the like.
66 
67  Exception()
68  {
69  }
70  Exception(const QString &msg)
71  : message(msg)
72  {
73  }
74  };
75 
76  /// Objects are abstracted away as a pair of the ScriptableExtension
77  /// the performs operations on it, and an implementation-specific Id,
78  /// which gets passed to the extension's methods.
79  ///
80  /// Objects are reference-counted, with the following protocol:
81  /// 1) Return values from methods, rootObject(), enclosingObject(),
82  /// and get() are already acquired by the producer, so the consumer
83  /// should release them when done.
84  /// 2) During a call, the caller guarantees that all the arguments
85  /// will be live for the calls duration, but the callee must
86  /// acquire them if it stores it for longer than that.
87  ///
88  /// @see acquire, acquireValue, release, releaseValue
89  struct Object {
90  ScriptableExtension *owner;
91  quint64 objId;
92 
93  Object()
94  : owner(nullptr)
95  , objId(0)
96  {
97  }
98  Object(ScriptableExtension *o, quint64 id)
99  : owner(o)
100  , objId(id)
101  {
102  }
103  bool operator==(const Object &other) const
104  {
105  return owner == other.owner && objId == other.objId;
106  }
107  };
108 
109  /// Function references are a pair of an object and a field in it.
110  /// Essentially, if you have a base.field(something) call, the
111  /// 'base' needs to be passed as the 'this' to the function, and
112  /// these references can be used to resolve that.
113  struct FunctionRef {
114  Object base;
115  QString field;
116 
117  FunctionRef()
118  {
119  }
120  FunctionRef(const Object &b, const QString &f)
121  : base(b)
122  , field(f)
123  {
124  }
125  bool operator==(const FunctionRef &other) const
126  {
127  return base == other.base && field == other.field;
128  }
129  };
130 
131  //@}
132 
133  ///@name lifetime
134  //@{
135 protected:
136  ScriptableExtension(QObject *parent);
137 
138 public:
139  ~ScriptableExtension() override;
140 
141  /**
142  * Queries @p obj for a child object which inherits from this
143  * ScriptableExtension class. Convenience method.
144  */
145  static ScriptableExtension *childObject(QObject *obj);
146 
147  /**
148  * This returns a bridge object that permits KParts implementing the older
149  * LiveConnectExtension to be used via the ScriptableExtension API.
150  * The bridge's parent will be the @p parentObj.
151  */
152  static ScriptableExtension *adapterFromLiveConnect(QObject *parentObj, LiveConnectExtension *oldApi);
153 
154  //@}
155 
156  ///@name Object Hierarchy
157  //@{
158 
159  /**
160  * Reports the hosting ScriptableExtension to a child. It's the responsibility
161  * of a parent part to call this method on all of its kids' ScriptableExtensions
162  * as soon as possible.
163  */
164  void setHost(ScriptableExtension *host);
165 
166  /**
167  * Returns any registered parent scripting context. May be 0 if setHost
168  * was not called (or not call yet).
169  */
170  ScriptableExtension *host() const;
171 
172  /**
173  * Return the root scriptable object of this KPart.
174  * For example for an HTML part, it would represent a Window object.
175  * May be undefined or null
176  */
177  virtual QVariant rootObject();
178 
179  /**
180  * Returns an object that represents the host()'s view of us.
181  * For example, if the host is an HTML part, it would return
182  * a DOM node of an &lt;object&gt; handled by this part.
183  * May be undefined or null
184  *
185  * Implemented in terms of objectForKid
186  *
187  */
188  QVariant enclosingObject();
189  //@}
190 
191  ///@name Object Operations
192  /// All these methods share the following conventions:
193  /// \li Values are passed and returned encoded as defined in
194  /// @ref ScriptValueTypes
195  /// \li All methods may return an exception if unsupported
196  /// \li All callers \b must provide an accurate callerPrincipal
197  /// argument describing which ScriptableExtension (and hence which KPart)
198  /// they're acting as. This is used to implement <b>security checks</b>. This
199  /// is \b not the same as the owner of an object. For example, if a plugin is
200  /// calling an operation on a KHTMLPart object,
201  /// then the 'this' parameter would be the object owner, a ScriptableExtension
202  /// provided by the KHTMLPart, while the callerPrincipal would be the
203  /// ScriptableExtension of the \em plugin. The extension is expected
204  /// to do appropriate cross-site scripting checks on this argument
205  /// if it is acting as a host.
206  //@{
207 
208  typedef QList<QVariant> ArgList;
209 
210  /**
211  Try to use the object @p objId associated with 'this' as a function.
212  */
213  virtual QVariant callAsFunction(ScriptableExtension *callerPrincipal, quint64 objId, const ArgList &args);
214 
215  /**
216  Try to use a function reference to field @p f of object @objId as a function
217  */
218  virtual QVariant callFunctionReference(ScriptableExtension *callerPrincipal, quint64 objId, const QString &f, const ArgList &args);
219 
220  /**
221  Try to use the object @p objId associated with 'this' as a constructor
222  (corresponding to ECMAScript's new foo(bar, baz, glarch) expression).
223  */
224  virtual QVariant callAsConstructor(ScriptableExtension *callerPrincipal, quint64 objId, const ArgList &args);
225 
226  /**
227  Returns true if the object @p objId associated with 'this' has the property
228  @p propName.
229  */
230  virtual bool hasProperty(ScriptableExtension *callerPrincipal, quint64 objId, const QString &propName);
231 
232  /**
233  Tries to get field @p propName from object @p objId associated with 'this'.
234  */
235  virtual QVariant get(ScriptableExtension *callerPrincipal, quint64 objId, const QString &propName);
236 
237  /**
238  Tries to set the field @p propName from object @p objId associated with 'this'
239  to @p value. Returns true on success
240  */
241  virtual bool put(ScriptableExtension *callerPrincipal, quint64 objId, const QString &propName, const QVariant &value);
242 
243  /**
244  Tries to remove the field d @p propName from object @p objId associated with 'this'.
245  Returns true on success
246  */
247  virtual bool removeProperty(ScriptableExtension *callerPrincipal, quint64 objId, const QString &propName);
248 
249  /**
250  Tries to enumerate all fields of object @p objId associated with this to
251  @p result. Returns true on success
252  */
253  virtual bool enumerateProperties(ScriptableExtension *callerPrincipal, quint64 objId, QStringList *result);
254 
255  /**
256  Tries to raise an exception with given message in this extension's scripting
257  context. Returns true on success
258  */
259  virtual bool setException(ScriptableExtension *callerPrincipal, const QString &message);
260 
262  ECMAScript, /// < also known as JavaScript
263  EnumLimit = 0xFFFF,
264  };
265 
266  /**
267  Tries to evaluate a script @p code with the given object as its context.
268  The parameter @p language specifies the language to execute it as.
269  Use isScriptLanguageSupported to check for support.
270  */
271  virtual QVariant evaluateScript(ScriptableExtension *callerPrincipal, quint64 contextObjectId, const QString &code, ScriptLanguage language = ECMAScript);
272 
273  /** returns true if this extension can execute scripts in the given
274  language */
275  virtual bool isScriptLanguageSupported(ScriptLanguage lang) const;
276 
277  /**
278  increases reference count of object @p objId
279  */
280  virtual void acquire(quint64 objid);
281 
282  /**
283  Helper that calls @ref acquire on any object or function reference base
284  stored in @p v.
285 
286  @return a copy of the passed in value
287  */
288  static QVariant acquireValue(const QVariant &v);
289 
290  /**
291  decreases reference count of object @p objId
292  */
293  virtual void release(quint64 objid);
294 
295  /**
296  Helper that calls @ref release on any object or function reference base
297  stored in @p v.
298 
299  @return a copy of the passed in value
300  */
301  static QVariant releaseValue(const QVariant &v);
302 
303  //@}
304 private:
305  /**
306  * If this extension is a host that provides an object corresponding
307  * to each kid, override this method to provide it.
308  * @see enclosingObject
309  */
310  virtual QVariant encloserForKid(KParts::ScriptableExtension *kid);
311 
312 private:
313  std::unique_ptr<ScriptableExtensionPrivate> const d;
314 };
315 
316 KPARTS_EXPORT unsigned int qHash(const KParts::ScriptableExtension::Object &o, uint seed = 0);
317 
318 KPARTS_EXPORT unsigned int qHash(const KParts::ScriptableExtension::FunctionRef &f);
319 
320 } // namespace KParts
321 
322 Q_DECLARE_METATYPE(KParts::ScriptableExtension::Null)
323 Q_DECLARE_METATYPE(KParts::ScriptableExtension::Undefined)
324 Q_DECLARE_METATYPE(KParts::ScriptableExtension::Exception)
325 Q_DECLARE_METATYPE(KParts::ScriptableExtension::Object)
327 
328 #endif
An extension class that permits KParts to be scripted (such as when embedded inside a KHTMLPart) and ...
Function references are a pair of an object and a field in it.
An extension class for LiveConnect, i.e. a call from JavaScript from a HTML page which embeds this pa...
KCALENDARCORE_EXPORT uint qHash(const KCalendarCore::Period &key)
Objects are abstracted away as a pair of the ScriptableExtension the performs operations on it,...
Returned from operations to denote a failure.
Corresponds to 'null' in JavaScript.
Corresponds to 'undefined' in JavaScript.
QString message
Error message returned from the callee.
The KParts namespace,.
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Wed Aug 17 2022 04:19:18 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.