1 | <?php |
||
43 | class Element { |
||
44 | const ELEMENT_TERM = 0; |
||
45 | const ELEMENT_DEFINITION = 1; |
||
46 | const ELEMENT_SOURCE = 2; |
||
47 | const ELEMENT_LINK = 3; |
||
48 | const ELEMENT_STYLE = 4; |
||
49 | |||
50 | const ELEMENT_FIELDCOUNT = 5; // number of fields stored for each element; (last field's index) + 1 |
||
51 | |||
52 | const LINK_TEMPLATE_ID = 'LingoLink'; |
||
53 | |||
54 | private $mFullDefinition = null; |
||
55 | private $mDefinitions = array(); |
||
56 | private $mTerm = null; |
||
57 | private $mHasBeenDisplayed = false; |
||
58 | |||
59 | /** |
||
60 | * Lingo\Element constructor. |
||
61 | * @param $term |
||
62 | * @param $definition |
||
63 | */ |
||
64 | 1 | public function __construct( &$term, &$definition = null ) { |
|
65 | |||
66 | 1 | $this->mTerm = $term; |
|
67 | |||
68 | 1 | if ( $definition ) { |
|
69 | 1 | $this->addDefinition( $definition ); |
|
70 | } |
||
71 | 1 | } |
|
72 | |||
73 | /** |
||
74 | * @param $definition |
||
75 | */ |
||
76 | public function addDefinition( &$definition ) { |
||
79 | |||
80 | /** |
||
81 | * @param StashingDOMDocument $doc |
||
82 | * @return DOMNode|DOMText |
||
83 | */ |
||
84 | public function getFullDefinition( StashingDOMDocument &$doc ) { |
||
97 | |||
98 | /** |
||
99 | * @param StashingDOMDocument $doc |
||
100 | */ |
||
101 | private function buildFullDefinition( StashingDOMDocument &$doc ) { |
||
102 | |||
103 | // only create if not yet created |
||
104 | if ( $this->mFullDefinition === null || $this->mFullDefinition->ownerDocument !== $doc ) { |
||
105 | |||
106 | if ( $this->isSimpleLink() ) { |
||
107 | $this->mFullDefinition = $this->getFullDefinitionAsLink( $doc ); |
||
108 | } else { |
||
109 | $this->mFullDefinition = $this->getFullDefinitionAsTooltip( $doc ); |
||
110 | } |
||
111 | } |
||
112 | } |
||
113 | |||
114 | /** |
||
115 | * @return bool |
||
116 | */ |
||
117 | private function isSimpleLink() { |
||
122 | |||
123 | /** |
||
124 | * @param StashingDOMDocument $doc |
||
125 | * @return DOMElement |
||
126 | * @throws \MWException |
||
127 | */ |
||
128 | protected function getFullDefinitionAsLink( StashingDOMDocument &$doc ) { |
||
152 | |||
153 | /** |
||
154 | * @param $target |
||
155 | * @param $link |
||
156 | * @return mixed |
||
157 | */ |
||
158 | protected function &addClassAttributeToLink( $target, &$link ) { |
||
159 | |||
160 | // TODO: should this be more elaborate? See Linker::linkAttribs |
||
161 | // Cleanest would probably be to use Linker::link and parse it |
||
162 | // back into a DOMElement, but we are in a somewhat time-critical |
||
163 | // part here. |
||
164 | |||
165 | // set style |
||
166 | $classes = string( $this->mDefinitions[ 0 ][ self::ELEMENT_STYLE ] ); |
||
167 | |||
168 | if ( !$target->isKnown() ) { |
||
169 | $classes .= ' new'; |
||
170 | } |
||
171 | |||
172 | if ( $target->isExternal() ) { |
||
173 | $classes .= ' extiw'; |
||
174 | } |
||
175 | |||
176 | $classes = trim( $classes ); |
||
177 | |||
178 | if ( $classes !== '' ) { |
||
179 | $link->setAttribute( 'class', $classes ); |
||
180 | } |
||
181 | |||
182 | return $link; |
||
183 | } |
||
184 | |||
185 | /** |
||
186 | * @param $target |
||
187 | * @param $link |
||
188 | * @return mixed |
||
189 | */ |
||
190 | protected function &addTitleAttributeToLink( $target, &$link ) { |
||
191 | |||
192 | if ( $target->getPrefixedText() === '' ) { |
||
193 | // A link like [[#Foo]]. This used to mean an empty title |
||
194 | // attribute, but that's silly. Just don't output a title. |
||
195 | } elseif ( $target->isKnown() ) { |
||
196 | $link->setAttribute( 'title', $target->getPrefixedText() ); |
||
197 | } else { |
||
198 | $link->setAttribute( 'title', wfMessage( 'red-link-title', $target->getPrefixedText() )->text() ); |
||
199 | } |
||
200 | |||
201 | return $link; |
||
202 | } |
||
203 | |||
204 | /** |
||
205 | * @param StashingDOMDocument $doc |
||
206 | * @return string |
||
207 | * @throws \MWException |
||
208 | */ |
||
209 | protected function getFullDefinitionAsTooltip( StashingDOMDocument &$doc ) { |
||
210 | |||
211 | // Wrap term and definition in <span> tags |
||
212 | $span = $doc->createElement( 'span' ); |
||
213 | $span->setAttribute( 'class', 'mw-lingo-tooltip ' . $this->mDefinitions[ 0 ][ self::ELEMENT_STYLE ] ); |
||
214 | |||
215 | // Wrap term in <span> tag, hidden |
||
216 | \MediaWiki\suppressWarnings(); |
||
217 | $spanTerm = $doc->createElement( 'span', htmlentities( $this->mTerm, ENT_COMPAT, 'UTF-8' ) ); |
||
218 | \MediaWiki\restoreWarnings(); |
||
219 | |||
220 | $spanTerm->setAttribute( 'class', 'mw-lingo-tooltip-abbr' ); |
||
221 | |||
222 | // Wrap definition in a <span> tag |
||
223 | $spanDefinition = $doc->createElement( 'span' ); |
||
224 | $spanDefinition->setAttribute( 'class', 'mw-lingo-tooltip-tip ' . $this->mDefinitions[ 0 ][ self::ELEMENT_STYLE ] ); |
||
225 | |||
226 | foreach ( $this->mDefinitions as $definition ) { |
||
227 | |||
228 | \MediaWiki\suppressWarnings(); |
||
229 | $element = $doc->createElement( 'span', htmlentities( $definition[ self::ELEMENT_DEFINITION ], ENT_COMPAT, 'UTF-8' ) ); |
||
230 | $element->setAttribute( 'class', 'mw-lingo-tooltip-definition ' . $this->mDefinitions[ 0 ][ self::ELEMENT_STYLE ] ); |
||
231 | \MediaWiki\restoreWarnings(); |
||
232 | |||
233 | if ( $definition[ self::ELEMENT_LINK ] ) { |
||
234 | $linkedTitle = Title::newFromText( $definition[ self::ELEMENT_LINK ] ); |
||
235 | if ( $linkedTitle ) { |
||
236 | $link = $this->getLinkTemplate( $doc ); |
||
237 | $link->setAttribute( 'href', $linkedTitle->getFullURL() ); |
||
238 | $element->appendChild( $link ); |
||
239 | } |
||
240 | } |
||
241 | $spanDefinition->appendChild( $element ); |
||
242 | } |
||
243 | |||
244 | // insert term and definition |
||
245 | $span->appendChild( $spanTerm ); |
||
246 | $span->appendChild( $spanDefinition ); |
||
247 | return $span; |
||
248 | } |
||
249 | |||
250 | /** |
||
251 | * @param StashingDOMDocument $doc |
||
252 | * @return DOMNode |
||
253 | */ |
||
254 | private function getLinkTemplate( StashingDOMDocument &$doc ) { |
||
255 | |||
256 | $mLinkTemplate = $doc->stashGet( self::LINK_TEMPLATE_ID ); |
||
257 | |||
258 | // create template if it does not yet exist |
||
259 | if ( $mLinkTemplate === null ) { |
||
260 | global $wgScriptPath; |
||
261 | |||
262 | $linkimage = $doc->createElement( 'img' ); |
||
263 | $linkimage->setAttribute( 'src', $wgScriptPath . '/extensions/Lingo/styles/linkicon.png' ); |
||
264 | |||
265 | $mLinkTemplate = $doc->createElement( 'a' ); |
||
266 | $mLinkTemplate->appendChild( $linkimage ); |
||
267 | |||
268 | $doc->stashSet( $mLinkTemplate, self::LINK_TEMPLATE_ID ); |
||
269 | } |
||
270 | |||
271 | return $mLinkTemplate->cloneNode( true ); |
||
272 | } |
||
273 | |||
274 | /** |
||
275 | * @return mixed |
||
276 | */ |
||
277 | public function getCurrentKey() { |
||
280 | |||
281 | /** |
||
282 | * @param $key |
||
283 | * @return mixed |
||
284 | */ |
||
285 | public function getTerm( $key ) { |
||
288 | |||
289 | /** |
||
290 | * @param $key |
||
291 | * @return mixed |
||
292 | */ |
||
293 | public function getSource( &$key ) { |
||
296 | |||
297 | /** |
||
298 | * @param $key |
||
299 | * @return mixed |
||
300 | */ |
||
301 | public function getDefinition( &$key ) { |
||
304 | |||
305 | /** |
||
306 | * @param $key |
||
307 | * @return mixed |
||
308 | */ |
||
309 | public function getLink( &$key ) { |
||
312 | |||
313 | /** |
||
314 | * @param $key |
||
315 | * @return mixed |
||
316 | */ |
||
317 | public function getStyle( &$key ) { |
||
320 | |||
321 | public function next() { |
||
324 | |||
325 | } |
||
326 |
Instead of relying on
global
state, we recommend one of these alternatives:1. Pass all data via parameters
2. Create a class that maintains your state