Coverage Report

Created: 2026-07-15 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wt/src/Wt/WAnchor.h
Line
Count
Source
1
// This may look like C code, but it's really -*- C++ -*-
2
/*
3
 * Copyright (C) 2008 Emweb bv, Herent, Belgium.
4
 *
5
 * See the LICENSE file for terms of use.
6
 */
7
#ifndef WANCHOR_H_
8
#define WANCHOR_H_
9
10
#include <Wt/WContainerWidget.h>
11
#include <Wt/WJavaScript.h>
12
#include <Wt/WImage.h>
13
#include <Wt/WLink.h>
14
15
namespace Wt {
16
17
  namespace Impl {
18
    class AreaWidget;
19
  }
20
21
/*! \class WAnchor Wt/WAnchor.h Wt/WAnchor.h
22
 *  \brief A widget that represents an HTML anchor (to link to other documents).
23
 *
24
 * Use an anchor to link to another web page, document, internal
25
 * application path or a resource (which specifies
26
 * application-dependent content that may be generated by your
27
 * application on demand). The anchor may contain a label text, an
28
 * image, or any other widget (as it inherits from
29
 * WContainerWidget).
30
 *
31
 * If you link to a document or external url, and do not want the
32
 * application to terminate when the user follows the anchor, you must
33
 * use \link WLink.setTarget(LinkTarget)
34
 * link.setTarget(LinkTarget::NewWindow)\endlink. Even for non-HTML
35
 * documents, this may be important since pending Ajax requests are
36
 * cancelled if documents are not served within the browser window in
37
 * certain browsers.
38
 *
39
 * \if cpp
40
 * Usage example:
41
 * \code
42
 * WAnchor *a;
43
 *
44
 * // Create an anchor that links to a URL
45
 * a = addWidget(std::make_unique<Wt::WAnchor>("https://www.webtoolkit.eu/", "Wt web toolkit"));
46
 *
47
 * // Create an anchor that links to an internal path
48
 * a = addWidget(std::make_unique<Wt::WAnchor>(
49
 *       WLink(LinkType::InternalPath, "/docs/" + myDocName()), "Doc"));
50
 * //   and listen to the corresponding change in internal path
51
 * WApplication::instance()->internalPathChanged().connect(this, &DocsListWidget::onInternalPathChange);
52
 *
53
 * // Create an anchor that links to a resource
54
 * WResource *r = addChild(std::make_unique<PdfResource>()); // serializes to a PDF file.
55
 * a = addWidget(std::make_unique<Wt::WAnchor>(r, "PDF version"));
56
 * \endcode
57
 * \endif
58
 *
59
 * %WAnchor is an \link WWidget::setInline(bool) inline \endlink widget.
60
 *
61
 * <h3>CSS</h3>
62
 *
63
 * The widget corresponds to the HTML <tt>&lt;a&gt;</tt> tag and does
64
 * not provide styling. It can be styled using inline or external CSS
65
 * as appropriate.
66
 */
67
class WT_API WAnchor : public WContainerWidget
68
{
69
public:
70
  /*! \brief Creates an anchor.
71
   */
72
  WAnchor();
73
74
  /*! \brief Creates an anchor for the given link.
75
   *
76
   * The \p link may point to a URL, a dynamic resource, or an
77
   * internal path.
78
   *
79
   * \sa setLink()
80
   */
81
  WAnchor(const WLink& link);
82
83
  /*! \brief Creates an anchor for the given link with a text.
84
   *
85
   * The \p link may point to a URL, a dynamic resource, or an
86
   * internal path.
87
   *
88
   * \sa setLink(), setText()
89
   */
90
  WAnchor(const WLink& link, const WString& text);
91
92
  /*! \brief Creates an anchor for the given link with an image.
93
   *
94
   * \if cpp
95
   * Ownership of the image is transferred to the anchor.
96
   * \endif
97
   *
98
   * \sa setLink(), setImage()
99
   */
100
  WAnchor(const WLink& link, std::unique_ptr<WImage> image);
101
102
  /*! \brief Sets the link.
103
   *
104
   * The link may hold a URL, a resource, or an internal path.
105
   *
106
   * When the link points to a \link LinkType::Resource resource\endlink,
107
   * the contents of the link may be generated by your application on
108
   * demand.
109
   *
110
   * When the link points to an \link LinkType::InternalPath internal
111
   * path\endlink, activating the anchor will change the \link
112
   * WApplication::internalPath() application's internal path\endlink
113
   * or open a new session with the given path as \link
114
   * WEnvironment::internalPath() initial path\endlink). This is the
115
   * easiest way to let the application participate in browser
116
   * history, and generate URLs that are bookmarkable and search
117
   * engine friendly.
118
   */
119
  void setLink(const WLink& link);
120
121
  /*! \brief Returns the link.
122
   *
123
   * \sa setLink()
124
   */
125
0
  const WLink& link() const { return linkState_.link; }
126
127
  /*! \brief Sets the label text
128
   *
129
   * If no text was previously set, a new WText widget is added using
130
   * addWidget().
131
   */
132
  void setText(const WString& text);
133
134
  /*! \brief Returns the label text.
135
   *
136
   * Returns an empty string if no label was set.
137
   *
138
   * \sa setText()
139
   */
140
  const WString& text() const;
141
142
  /*! \brief Configures text word wrapping.
143
   *
144
   * When \p wordWrap is \c true, the text set with setText() may be
145
   * broken up over multiple lines. When \p wordWrap is \c false, the
146
   * text will displayed on a single line, unless the text contains
147
   * <tt>&lt;br /&gt;</tt> tags or other block-level tags.
148
   *
149
   * The default value is \c true.
150
   *
151
   * \sa wordWrap()
152
   */
153
  void setWordWrap(bool wordWrap);
154
155
  /*! \brief Configures the text format.
156
   *
157
   * The default text format is TextFormat::XHTML.
158
   *
159
   * \sa WText::setTextFormat()
160
   */
161
  void setTextFormat(TextFormat format);
162
163
  /*! \brief Returns the text format.
164
   *
165
   * \sa setTextFormat()
166
   */
167
  TextFormat textFormat() const;
168
169
  /*! \brief Returns whether the widget may break lines.
170
   *
171
   * \sa setWordWrap(bool)
172
   */
173
  bool wordWrap() const;
174
175
  /*! \brief Sets an image.
176
   *
177
   * If an image was previously set, it is deleted. The \p image
178
   * is added using addWidget().
179
   */
180
  void setImage(std::unique_ptr<WImage> image);
181
182
  /*! \brief Returns the image.
183
   *
184
   * Returns \c 0 if no image is set.
185
   *
186
   * \sa setImage()
187
   */
188
0
  WImage *image() const { return image_.get(); }
189
190
  virtual bool canReceiveFocus() const override;
191
  virtual int tabIndex() const override;
192
  virtual bool setFirstFocus() override;
193
194
private:
195
  static const int BIT_LINK_CHANGED = 0;
196
  static const int BIT_TARGET_CHANGED = 1;
197
198
  struct WT_API LinkState {
199
    LinkState();
200
    ~LinkState();
201
202
    WLink link;
203
    JSlot *clickJS;
204
  };
205
206
  LinkState linkState_;
207
208
  observing_ptr<WText> text_;
209
  observing_ptr<WImage> image_;
210
  std::bitset<2> flags_;
211
212
  void resourceChanged();
213
214
  static bool renderHRef(WInteractWidget *widget,
215
                         LinkState& linkState, DomElement& element);
216
  static void renderHTarget(LinkState& linkState, DomElement& element,
217
                            bool all);
218
  static void renderUrlResolution(WWidget *widget, DomElement& element,
219
                                  bool all);
220
221
protected:
222
  virtual void updateDom(DomElement& element, bool all) override;
223
  virtual DomElementType domElementType() const override;
224
  virtual void propagateRenderOk(bool deep) override;
225
  virtual void propagateSetEnabled(bool enabled) override;
226
  virtual void enableAjax() override;
227
228
  friend class WAbstractArea;
229
  friend class WPushButton;
230
  friend class Impl::AreaWidget;
231
};
232
233
}
234
235
#endif // WANCHOR_H_