[BUGFIX] URL-encoded title in link wizard
[Packages/TYPO3.CMS.git] / typo3 / sysext / rtehtmlarea / Classes / BrowseLinks.php
1 <?php
2 namespace TYPO3\CMS\Rtehtmlarea;
3
4 use TYPO3\CMS\Core\Utility\GeneralUtility;
5
6 /**
7 * Script class for the Element Browser window.
8 *
9 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
10 */
11 class BrowseLinks extends \TYPO3\CMS\Recordlist\Browser\ElementBrowser {
12
13 public $editorNo;
14 /**
15 * TYPO3 language code of the content language
16 */
17 public $contentTypo3Language;
18
19 public $contentTypo3Charset = 'utf-8';
20 /**
21 * Language service object for localization to the content language
22 */
23 protected $contentLanguageService;
24
25 public $additionalAttributes = array();
26
27 public $buttonConfig = array();
28
29 public $RTEProperties = array();
30
31 public $anchorTypes = array('page', 'url', 'file', 'mail', 'spec');
32
33 public $classesAnchorDefault = array();
34
35 public $classesAnchorDefaultTitle = array();
36
37 public $classesAnchorClassTitle = array();
38
39 public $classesAnchorDefaultTarget = array();
40
41 public $classesAnchorJSOptions = array();
42
43 protected $defaultLinkTarget;
44
45 public $allowedItems;
46
47 /**
48 * Constructor:
49 * Initializes a lot of variables, setting JavaScript functions in header etc.
50 *
51 * @return void
52 * @todo Define visibility
53 */
54 public function init() {
55 $this->initVariables();
56 // Create content laguage service
57 $this->contentLanguageService = GeneralUtility::makeInstance('TYPO3\\CMS\\Lang\\LanguageService');
58 $this->contentLanguageService->init($this->contentTypo3Language);
59 $this->initConfiguration();
60 // init fileProcessor
61 $this->fileProcessor = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Utility\\File\\BasicFileUtility');
62 $this->fileProcessor->init($GLOBALS['FILEMOUNTS'], $GLOBALS['TYPO3_CONF_VARS']['BE']['fileExtensions']);
63 // Creating backend template object:
64 $this->doc = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Template\\DocumentTemplate');
65 $this->doc->backPath = $GLOBALS['BACK_PATH'];
66 // Loading the Prototype library and browse_links.js
67 $this->doc->getPageRenderer()->loadPrototype();
68 $this->doc->loadJavascriptLib('js/tree.js');
69 $this->doc->loadJavascriptLib('js/browse_links.js');
70 // Adding context menu code
71 $this->doc->getContextMenuCode();
72 // Initializing hooking browsers
73 $this->initHookObjects('ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php');
74 // CurrentUrl - the current link url must be passed around if it exists
75 $this->curUrlArray = GeneralUtility::_GP('curUrl');
76 if ($this->curUrlArray['all']) {
77 $this->curUrlArray = GeneralUtility::get_tag_attributes($this->curUrlArray['all']);
78 $this->curUrlArray['href'] = htmlspecialchars_decode($this->curUrlArray['href']);
79 }
80 // Note: parseCurUrl will invoke the hooks
81 $this->curUrlInfo = $this->parseCurUrl($this->curUrlArray['href'], $this->siteURL);
82 if (isset($this->curUrlArray['data-htmlarea-external']) && $this->curUrlInfo['act'] != 'mail') {
83 $this->curUrlInfo['act'] = 'url';
84 $this->curUrlInfo['info'] = $this->curUrlArray['href'];
85 }
86 // Determine nature of current url:
87 $this->act = GeneralUtility::_GP('act');
88 if (!$this->act) {
89 $this->act = $this->curUrlInfo['act'];
90 }
91 // Setting intial values for link attributes
92 $this->initLinkAttributes();
93 // Apply the same styles as those of the base script
94 $this->doc->bodyTagId = 'typo3-browse-links-php';
95 $this->doc->getPageRenderer()->addCssFile($this->doc->backPath . \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('t3skin') . 'rtehtmlarea/htmlarea.css');
96 // Add attributes to body tag. Note: getBodyTagAdditions will invoke the hooks
97 $this->doc->bodyTagAdditions = $this->getBodyTagAdditions();
98 // Adding RTE JS code
99 $this->doc->JScodeArray['rtehtmlarea'] = $this->getJSCode();
100 }
101
102 /**
103 * Initialize class variables
104 *
105 * @return void
106 */
107 public function initVariables() {
108 // Main GPvars:
109 $this->pointer = GeneralUtility::_GP('pointer');
110 $this->bparams = GeneralUtility::_GP('bparams');
111 $this->P = GeneralUtility::_GP('P');
112 $this->expandPage = GeneralUtility::_GP('expandPage');
113 $this->expandFolder = GeneralUtility::_GP('expandFolder');
114 $this->PM = GeneralUtility::_GP('PM');
115 // Process bparams
116 $pArr = explode('|', $this->bparams);
117 $pRteArr = explode(':', $pArr[1]);
118 $this->editorNo = $pRteArr[0];
119 $this->contentTypo3Language = $pRteArr[1];
120 $this->RTEtsConfigParams = $pArr[2];
121 if (!$this->editorNo) {
122 $this->editorNo = GeneralUtility::_GP('editorNo');
123 $this->contentTypo3Language = GeneralUtility::_GP('contentTypo3Language');
124 $this->RTEtsConfigParams = GeneralUtility::_GP('RTEtsConfigParams');
125 }
126 $pArr[1] = implode(':', array($this->editorNo, $this->contentTypo3Language, $this->contentTypo3Charset));
127 $pArr[2] = $this->RTEtsConfigParams;
128 $this->bparams = implode('|', $pArr);
129 // Find "mode"
130 $this->mode = GeneralUtility::_GP('mode');
131 if (!$this->mode) {
132 $this->mode = 'rte';
133 }
134 // Current site url
135 $this->siteURL = GeneralUtility::getIndpEnv('TYPO3_SITE_URL');
136 // the script to link to
137 $this->thisScript = GeneralUtility::getIndpEnv('SCRIPT_NAME');
138 }
139
140 /**
141 * Initializes the configuration variables
142 *
143 * @return void
144 */
145 public function initConfiguration() {
146 $this->thisConfig = $this->getRTEConfig();
147 $this->buttonConfig = $this->getButtonConfig('link');
148 }
149
150 /**
151 * Get the RTE configuration from Page TSConfig
152 *
153 * @return array RTE configuration array
154 */
155 protected function getRTEConfig() {
156 $RTEtsConfigParts = explode(':', $this->RTEtsConfigParams);
157 $RTEsetup = $GLOBALS['BE_USER']->getTSConfig('RTE', \TYPO3\CMS\Backend\Utility\BackendUtility::getPagesTSconfig($RTEtsConfigParts[5]));
158 $this->RTEProperties = $RTEsetup['properties'];
159 return \TYPO3\CMS\Backend\Utility\BackendUtility::RTEsetup($this->RTEProperties, $RTEtsConfigParts[0], $RTEtsConfigParts[2], $RTEtsConfigParts[4]);
160 }
161
162 /**
163 * Get the configuration of the button
164 *
165 * @param string $buttonName: the name of the button
166 * @return array the configuration array of the image button
167 */
168 protected function getButtonConfig($buttonName) {
169 return is_array($this->thisConfig['buttons.']) && is_array($this->thisConfig['buttons.'][$buttonName . '.']) ? $this->thisConfig['buttons.'][$buttonName . '.'] : array();
170 }
171
172 /**
173 * Initialize hook objects implementing the interface
174 *
175 * @param string $hookKey: the hook key
176 * @return void
177 */
178 protected function initHookObjects($hookKey) {
179 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'][$hookKey]['browseLinksHook'])) {
180 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'][$hookKey]['browseLinksHook'] as $classData) {
181 $processObject = GeneralUtility::getUserObj($classData);
182 if (!$processObject instanceof \TYPO3\CMS\Core\ElementBrowser\ElementBrowserHookInterface) {
183 throw new \UnexpectedValueException('$processObject must implement interface TYPO3\\CMS\\Core\\ElementBrowser\\ElementBrowserHookInterface', 1195115653);
184 }
185 $parameters = array();
186 $processObject->init($this, $parameters);
187 $this->hookObjects[] = $processObject;
188 }
189 }
190 }
191
192 /**
193 * Initialize the current or default values of the link attributes
194 *
195 * @return void
196 */
197 protected function initLinkAttributes() {
198 // Initializing the title value
199 $this->setTitle = $this->curUrlArray['title'];
200 // Processing the classes configuration
201 $classSelected = array();
202 if ($this->buttonConfig['properties.']['class.']['allowedClasses']) {
203 $this->setClass = $this->curUrlArray['class'];
204 $classesAnchorArray = GeneralUtility::trimExplode(',', $this->buttonConfig['properties.']['class.']['allowedClasses'], TRUE);
205 $classesAnchorConfigArray = array();
206 // Collecting allowed classes and configured default values
207 $classesAnchor = array();
208 $classesAnchor['all'] = array();
209 $titleReadOnly = $this->buttonConfig['properties.']['title.']['readOnly'] || $this->buttonConfig[$this->act . '.']['properties.']['title.']['readOnly'];
210 if (is_array($this->RTEProperties['classesAnchor.'])) {
211 foreach ($this->RTEProperties['classesAnchor.'] as $label => $conf) {
212 if (in_array($conf['class'], $classesAnchorArray)) {
213 $classesAnchor['all'][] = $conf['class'];
214 if (in_array($conf['type'], $this->anchorTypes)) {
215 $classesAnchor[$conf['type']][] = $conf['class'];
216 if ($this->buttonConfig[$conf['type'] . '.']['properties.']['class.']['default'] == $conf['class']) {
217 $this->classesAnchorDefault[$conf['type']] = $conf['class'];
218 if ($conf['titleText']) {
219 $this->classesAnchorDefaultTitle[$conf['type']] = $this->getLLContent(trim($conf['titleText']));
220 }
221 if ($conf['target']) {
222 $this->classesAnchorDefaultTarget[$conf['type']] = trim($conf['target']);
223 }
224 }
225 }
226 if ($titleReadOnly && $conf['titleText']) {
227 $this->classesAnchorClassTitle[$conf['class']] = ($this->classesAnchorDefaultTitle[$conf['type']] = $this->getLLContent(trim($conf['titleText'])));
228 }
229 }
230 }
231 }
232 // Constructing the class selector options
233 foreach ($this->anchorTypes as $anchorType) {
234 foreach ($classesAnchorArray as $class) {
235 if (!in_array($class, $classesAnchor['all']) || in_array($class, $classesAnchor['all']) && is_array($classesAnchor[$anchorType]) && in_array($class, $classesAnchor[$anchorType])) {
236 $selected = '';
237 if ($this->setClass == $class || !$this->setClass && $this->classesAnchorDefault[$anchorType] == $class) {
238 $selected = 'selected="selected"';
239 $classSelected[$anchorType] = TRUE;
240 }
241 $classLabel = is_array($this->RTEProperties['classes.']) && is_array($this->RTEProperties['classes.'][$class . '.']) && $this->RTEProperties['classes.'][$class . '.']['name'] ? $this->getPageConfigLabel($this->RTEProperties['classes.'][$class . '.']['name'], 0) : $class;
242 $classStyle = is_array($this->RTEProperties['classes.']) && is_array($this->RTEProperties['classes.'][$class . '.']) && $this->RTEProperties['classes.'][$class . '.']['value'] ? $this->RTEProperties['classes.'][$class . '.']['value'] : '';
243 $this->classesAnchorJSOptions[$anchorType] .= '<option ' . $selected . ' value="' . $class . '"' . ($classStyle ? ' style="' . $classStyle . '"' : '') . '>' . $classLabel . '</option>';
244 }
245 }
246 if ($this->classesAnchorJSOptions[$anchorType] && !($this->buttonConfig['properties.']['class.']['required'] || $this->buttonConfig[$this->act . '.']['properties.']['class.']['required'])) {
247 $selected = '';
248 if (!$this->setClass && !$this->classesAnchorDefault[$anchorType]) {
249 $selected = 'selected="selected"';
250 }
251 $this->classesAnchorJSOptions[$anchorType] = '<option ' . $selected . ' value=""></option>' . $this->classesAnchorJSOptions[$anchorType];
252 }
253 }
254 }
255 // Initializing the target value
256 // Unset the target if it is set to a value different than default and if no class is selected and the target field is not displayed
257 // In other words, do not forward the target if we changed tab and the target field is not displayed
258 $this->defaultLinkTarget = isset($this->buttonConfig['properties.']['target.']['default']) ? $this->buttonConfig['properties.']['target.']['default'] : '';
259 $this->setTarget = '';
260 if (isset($this->curUrlArray['target']) && !($this->curUrlArray['target'] != $this->defaultLinkTarget && !$classSelected[$this->act] && is_array($this->buttonConfig['targetSelector.']) && $this->buttonConfig['targetSelector.']['disabled'] && is_array($this->buttonConfig['popupSelector.']) && $this->buttonConfig['popupSelector.']['disabled'])) {
261 $this->setTarget = $this->curUrlArray['target'];
262 }
263 if ($this->defaultLinkTarget && !isset($this->curUrlArray['target'])) {
264 $this->setTarget = $this->defaultLinkTarget;
265 }
266 // Initializing additional attributes
267 if ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['rtehtmlarea']['plugins']['TYPO3Link']['additionalAttributes']) {
268 $addAttributes = GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['rtehtmlarea']['plugins']['TYPO3Link']['additionalAttributes'], TRUE);
269 foreach ($addAttributes as $attribute) {
270 $this->additionalAttributes[$attribute] = isset($this->curUrlArray[$attribute]) ? $this->curUrlArray[$attribute] : '';
271 }
272 }
273 }
274
275 /**
276 * Provide the additional parameters to be included in the template body tag
277 *
278 * @return string the body tag additions
279 */
280 public function getBodyTagAdditions() {
281 $bodyTagAdditions = array();
282 // call hook for extra additions
283 foreach ($this->hookObjects as $hookObject) {
284 if (method_exists($hookObject, 'addBodyTagAdditions')) {
285 $bodyTagAdditions = $hookObject->addBodyTagAdditions($bodyTagAdditions);
286 }
287 }
288 return GeneralUtility::implodeAttributes($bodyTagAdditions, TRUE);
289 }
290
291 /**
292 * Generate JS code to be used on the link insert/modify dialogue
293 *
294 * @return string the generated JS code
295 * @todo Define visibility
296 */
297 public function getJSCode() {
298 // BEGIN accumulation of header JavaScript:
299 $JScode = '';
300 $JScode .= '
301 var plugin = window.parent.RTEarea["' . $this->editorNo . '"].editor.getPlugin("TYPO3Link");
302 var HTMLArea = window.parent.HTMLArea;
303 var add_href=' . GeneralUtility::quoteJSvalue(($this->curUrlArray['href'] ? '&curUrl[href]=' . rawurlencode($this->curUrlArray['href']) : '')) . ';
304 var add_target=' . GeneralUtility::quoteJSvalue(($this->setTarget ? '&curUrl[target]=' . rawurlencode($this->setTarget) : '')) . ';
305 var add_class=' . GeneralUtility::quoteJSvalue(($this->setClass ? '&curUrl[class]=' . rawurlencode($this->setClass) : '')) . ';
306 var add_title=' . GeneralUtility::quoteJSvalue(($this->setTitle ? '&curUrl[title]=' . rawurlencode($this->setTitle) : '')) . ';
307 var add_params=' . GeneralUtility::quoteJSvalue(($this->bparams ? '&bparams=' . rawurlencode($this->bparams) : '')) . ';
308 var additionalValues = ' . (count($this->additionalAttributes) ? json_encode($this->additionalAttributes, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) : '{}') . ';';
309 // Attributes setting functions
310 $JScode .= '
311 var cur_href="' . GeneralUtility::quoteJSvalue($this->curUrlArray['href'] ? ($this->curUrlInfo['query'] ? substr($this->curUrlArray['href'], 0, -strlen($this->curUrlInfo['query'])) : $this->curUrlArray['href']) : '') . '";
312 var cur_target="' . GeneralUtility::quoteJSvalue($this->setTarget ?: '') . '";
313 var cur_class="' . GeneralUtility::quoteJSvalue($this->setClass ?: '') . '";
314 var cur_title="' . GeneralUtility::quoteJSvalue($this->setTitle ?: '') . '";
315
316 function browse_links_setTarget(value) {
317 cur_target=value;
318 add_target="&curUrl[target]="+encodeURIComponent(value);
319 }
320 function browse_links_setClass(value) {
321 cur_class=value;
322 add_class="&curUrl[class]="+encodeURIComponent(value);
323 }
324 function browse_links_setTitle(value) {
325 cur_title=value;
326 add_title="&curUrl[title]="+encodeURIComponent(value);
327 }
328 function browse_links_setHref(value) {
329 cur_href=value;
330 add_href="&curUrl[href]="+value;
331 }
332 function browse_links_setAdditionalValue(name, value) {
333 additionalValues[name] = value;
334 }
335 ';
336 // Link setting functions
337 $JScode .= '
338 function link_typo3Page(id,anchor) {
339 var parameters = (document.ltargetform.query_parameters && document.ltargetform.query_parameters.value) ? (document.ltargetform.query_parameters.value.charAt(0) == "&" ? "" : "&") + document.ltargetform.query_parameters.value : "";
340 var theLink = \'' . $this->siteURL . '?id=\' + id + parameters + (anchor ? anchor : "");
341 if (document.ltargetform.anchor_title) browse_links_setTitle(document.ltargetform.anchor_title.value);
342 if (document.ltargetform.anchor_class) browse_links_setClass(document.ltargetform.anchor_class.value);
343 if (document.ltargetform.ltarget) browse_links_setTarget(document.ltargetform.ltarget.value);
344 if (document.ltargetform.lrel) browse_links_setAdditionalValue("rel", document.ltargetform.lrel.value);
345 browse_links_setAdditionalValue("data-htmlarea-external", "");
346 plugin.createLink(theLink,cur_target,cur_class,cur_title,additionalValues);
347 return false;
348 }
349 function link_folder(folder) {
350 if (folder && folder.substr(0, 5) == "file:") {
351 var theLink = \'' . $this->siteURL . '?file:\' + encodeURIComponent(folder.substr(5));
352 } else {
353 var theLink = \'' . $this->siteURL . '?\' + folder;
354 }
355 if (document.ltargetform.anchor_title) browse_links_setTitle(document.ltargetform.anchor_title.value);
356 if (document.ltargetform.anchor_class) browse_links_setClass(document.ltargetform.anchor_class.value);
357 if (document.ltargetform.ltarget) browse_links_setTarget(document.ltargetform.ltarget.value);
358 if (document.ltargetform.lrel) browse_links_setAdditionalValue("rel", document.ltargetform.lrel.value);
359 browse_links_setAdditionalValue("data-htmlarea-external", "");
360 plugin.createLink(theLink,cur_target,cur_class,cur_title,additionalValues);
361 return false;
362 }
363 function link_spec(theLink) {
364 if (document.ltargetform.anchor_title) browse_links_setTitle(document.ltargetform.anchor_title.value);
365 if (document.ltargetform.anchor_class) browse_links_setClass(document.ltargetform.anchor_class.value);
366 if (document.ltargetform.ltarget) browse_links_setTarget(document.ltargetform.ltarget.value);
367 browse_links_setAdditionalValue("data-htmlarea-external", "");
368 plugin.createLink(theLink,cur_target,cur_class,cur_title,additionalValues);
369 return false;
370 }
371 function link_current() {
372 var parameters = (document.ltargetform.query_parameters && document.ltargetform.query_parameters.value) ? (document.ltargetform.query_parameters.value.charAt(0) == "&" ? "" : "&") + document.ltargetform.query_parameters.value : "";
373 if (document.ltargetform.anchor_title) browse_links_setTitle(document.ltargetform.anchor_title.value);
374 if (document.ltargetform.anchor_class) browse_links_setClass(document.ltargetform.anchor_class.value);
375 if (document.ltargetform.ltarget) browse_links_setTarget(document.ltargetform.ltarget.value);
376 if (document.ltargetform.lrel) browse_links_setAdditionalValue("rel", document.ltargetform.lrel.value);
377 if (cur_href!="http://" && cur_href!="mailto:") {
378 plugin.createLink(cur_href + parameters,cur_target,cur_class,cur_title,additionalValues);
379 }
380 return false;
381 }
382 ';
383 // General "jumpToUrl" and launchView functions:
384 $JScode .= '
385 function jumpToUrl(URL,anchor) {
386 var add_editorNo = URL.indexOf("editorNo=")==-1 ? "&editorNo=' . $this->editorNo . '" : "";
387 var add_contentTypo3Language = URL.indexOf("contentTypo3Language=")==-1 ? "&contentTypo3Language=' . $this->contentTypo3Language . '" : "";
388 var add_act = URL.indexOf("act=")==-1 ? "&act=' . $this->act . '" : "";
389 var add_mode = URL.indexOf("mode=")==-1 ? "&mode=' . $this->mode . '" : "";
390 var add_additionalValues = "";
391 if (plugin.pageTSConfiguration && plugin.pageTSConfiguration.additionalAttributes) {
392 var additionalAttributes = plugin.pageTSConfiguration.additionalAttributes.split(",");
393 for (var i = additionalAttributes.length; --i >= 0;) {
394 if (additionalValues[additionalAttributes[i]] != "") {
395 add_additionalValues += "&curUrl[" + additionalAttributes[i] + "]=" + encodeURIComponent(additionalValues[additionalAttributes[i]]);
396 }
397 }
398 }
399 var theLocation = URL+add_act+add_editorNo+add_contentTypo3Language+add_mode+add_href+add_target+add_class+add_title+add_additionalValues+add_params+(anchor?anchor:"");
400 window.location.href = theLocation;
401 return false;
402 }
403 function launchView(url) {
404 var thePreviewWindow="";
405 thePreviewWindow = window.open("' . $GLOBALS['BACK_PATH'] . 'show_item.php?table="+url,"ShowItem","height=300,width=410,status=0,menubar=0,resizable=0,location=0,directories=0,scrollbars=1,toolbar=0");
406 if (thePreviewWindow && thePreviewWindow.focus) {
407 thePreviewWindow.focus();
408 }
409 }
410 ';
411 // Hook to overwrite or extend javascript functions
412 if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php']['extendJScode']) && is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php']['extendJScode'])) {
413 $conf = array();
414 $_params = array(
415 'conf' => &$conf
416 );
417 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php']['extendJScode'] as $objRef) {
418 $processor =& GeneralUtility::getUserObj($objRef);
419 $JScode .= $processor->extendJScode($_params, $this);
420 }
421 }
422 return $JScode;
423 }
424
425 /******************************************************************
426 *
427 * Main functions
428 *
429 ******************************************************************/
430 /**
431 * Rich Text Editor (RTE) link selector (MAIN function)
432 * Generates the link selector for the Rich Text Editor.
433 * Can also be used to select links for the TCEforms (see $wiz)
434 *
435 * @param boolean If set, the "remove link" is not shown in the menu: Used for the "Select link" wizard which is used by the TCEforms
436 * @return string Modified content variable.
437 * @todo Define visibility
438 */
439 public function main_rte($wiz = 0) {
440 // Starting content:
441 $content = $this->doc->startPage($GLOBALS['LANG']->getLL('Insert/Modify Link', TRUE));
442 // Default allowed values
443 $this->allowedItems = explode(',', 'page,file,folder,url,mail,spec');
444 // Calling hook for extra options
445 foreach ($this->hookObjects as $hookObject) {
446 $this->allowedItems = $hookObject->addAllowedItems($this->allowedItems);
447 }
448 // Removing items as per configuration
449 if (is_array($this->buttonConfig['options.']) && $this->buttonConfig['options.']['removeItems']) {
450 $this->allowedItems = array_diff($this->allowedItems, GeneralUtility::trimExplode(',', $this->buttonConfig['options.']['removeItems'], TRUE));
451 }
452 reset($this->allowedItems);
453 if (!in_array($this->act, $this->allowedItems)) {
454 $this->act = current($this->allowedItems);
455 }
456 // Making menu in top:
457 $menuDef = array();
458 if (!$wiz && $this->curUrlArray['href']) {
459 $menuDef['removeLink']['isActive'] = $this->act == 'removeLink';
460 $menuDef['removeLink']['label'] = $GLOBALS['LANG']->getLL('removeLink', TRUE);
461 $menuDef['removeLink']['url'] = '#';
462 $menuDef['removeLink']['addParams'] = 'onclick="plugin.unLink();return false;"';
463 }
464 if (in_array('page', $this->allowedItems)) {
465 $menuDef['page']['isActive'] = $this->act == 'page';
466 $menuDef['page']['label'] = $GLOBALS['LANG']->getLL('page', TRUE);
467 $menuDef['page']['url'] = '#';
468 $menuDef['page']['addParams'] = 'onclick="jumpToUrl(\'' . htmlspecialchars(('?act=page&mode=' . $this->mode . '&bparams=' . $this->bparams)) . '\');return false;"';
469 }
470 if (in_array('file', $this->allowedItems)) {
471 $menuDef['file']['isActive'] = $this->act == 'file';
472 $menuDef['file']['label'] = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_browse_links.xlf:file', TRUE);
473 $menuDef['file']['url'] = '#';
474 $menuDef['file']['addParams'] = 'onclick="jumpToUrl(\'' . htmlspecialchars(('?act=file&mode=' . $this->mode . '&bparams=' . $this->bparams)) . '\');return false;"';
475 }
476 if (in_array('folder', $this->allowedItems)) {
477 $menuDef['folder']['isActive'] = $this->act == 'folder';
478 $menuDef['folder']['label'] = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_browse_links.xlf:folder', TRUE);
479 $menuDef['folder']['url'] = '#';
480 $menuDef['folder']['addParams'] = 'onclick="jumpToUrl(\'' . htmlspecialchars(('?act=folder&mode=' . $this->mode . '&bparams=' . $this->bparams)) . '\');return false;"';
481 }
482 if (in_array('url', $this->allowedItems)) {
483 $menuDef['url']['isActive'] = $this->act == 'url';
484 $menuDef['url']['label'] = $GLOBALS['LANG']->getLL('extUrl', TRUE);
485 $menuDef['url']['url'] = '#';
486 $menuDef['url']['addParams'] = 'onclick="jumpToUrl(\'' . htmlspecialchars(('?act=url&mode=' . $this->mode . '&bparams=' . $this->bparams)) . '\');return false;"';
487 }
488 if (in_array('mail', $this->allowedItems)) {
489 $menuDef['mail']['isActive'] = $this->act == 'mail';
490 $menuDef['mail']['label'] = $GLOBALS['LANG']->getLL('email', TRUE);
491 $menuDef['mail']['url'] = '#';
492 $menuDef['mail']['addParams'] = 'onclick="jumpToUrl(\'' . htmlspecialchars(('?act=mail&mode=' . $this->mode . '&bparams=' . $this->bparams)) . '\');return false;"';
493 }
494 if (is_array($this->thisConfig['userLinks.']) && in_array('spec', $this->allowedItems)) {
495 $menuDef['spec']['isActive'] = $this->act == 'spec';
496 $menuDef['spec']['label'] = $GLOBALS['LANG']->getLL('special', TRUE);
497 $menuDef['spec']['url'] = '#';
498 $menuDef['spec']['addParams'] = 'onclick="jumpToUrl(\'' . htmlspecialchars(('?act=spec&mode=' . $this->mode . '&bparams=' . $this->bparams)) . '\');return false;"';
499 }
500 // call hook for extra options
501 foreach ($this->hookObjects as $hookObject) {
502 $menuDef = $hookObject->modifyMenuDefinition($menuDef);
503 }
504 $content .= $this->doc->getTabMenuRaw($menuDef);
505 // Adding the menu and header to the top of page:
506 $content .= $this->printCurrentUrl($this->curUrlInfo['info']) . '<br />';
507 // Depending on the current action we will create the actual module content for selecting a link:
508 switch ($this->act) {
509 case 'mail':
510 $extUrl = '
511 <!--
512 Enter mail address:
513 -->
514 <tr>
515 <td><label>' . $GLOBALS['LANG']->getLL('emailAddress', TRUE) . ':</label></td>
516 <td><input type="text" name="lemail"' . $this->doc->formWidth(20) . ' value="' . htmlspecialchars(($this->curUrlInfo['act'] == 'mail' ? $this->curUrlInfo['info'] : '')) . '" /> ' . '<input type="submit" value="' . $GLOBALS['LANG']->getLL('setLink', TRUE) . '" onclick="browse_links_setTarget(\'\');browse_links_setHref(\'mailto:\'+document.ltargetform.lemail.value);browse_links_setAdditionalValue(\'data-htmlarea-external\', \'\');return link_current();" /></td>
517 </tr>';
518 //$content .= $extUrl;
519 $content .= $this->addAttributesForm($extUrl);
520 break;
521 case 'url':
522 $extUrl = '
523 <!--
524 Enter External URL:
525 -->
526 <tr>
527 <td><label>URL:</label></td>
528 <td colspan="3"><input type="text" name="lurl"' . $this->doc->formWidth(20) . ' value="' . htmlspecialchars(($this->curUrlInfo['act'] == 'url' ? $this->curUrlInfo['info'] : 'http://')) . '" /> ' . '<input type="submit" value="' . $GLOBALS['LANG']->getLL('setLink', TRUE) . '" onclick="if (/^[A-Za-z0-9_+]{1,8}:/.test(document.ltargetform.lurl.value)) { browse_links_setHref(document.ltargetform.lurl.value); } else { browse_links_setHref(\'http://\'+document.ltargetform.lurl.value); }; browse_links_setAdditionalValue(\'data-htmlarea-external\', \'1\'); return link_current();" /></td>
529 </tr>';
530 $content .= $this->addAttributesForm($extUrl);
531 break;
532 case 'file':
533 case 'folder':
534 $content .= $this->addAttributesForm();
535 // Create folder tree:
536 $this->doc->JScode .= $this->doc->wrapScriptTags('
537 Tree.ajaxID = "SC_alt_file_navframe::expandCollapse";
538 ');
539 $foldertree = GeneralUtility::makeInstance('TYPO3\\CMS\\Rtehtmlarea\\FolderTree');
540 $foldertree->thisScript = $this->thisScript;
541 $tree = $foldertree->getBrowsableTree();
542 if (!$this->curUrlInfo['value'] || $this->curUrlInfo['act'] != $this->act) {
543 $cmpPath = '';
544 } else {
545 $cmpPath = $this->curUrlInfo['value'];
546 if (!isset($this->expandFolder)) {
547 $this->expandFolder = $cmpPath;
548 }
549 }
550 // Get the selected folder
551 $selectedFolder = FALSE;
552 if ($this->expandFolder) {
553 try {
554 $fileOrFolderObject = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->retrieveFileOrFolderObject($this->expandFolder);
555 } catch (\Exception $e) {
556 // No path is selected
557 }
558 if ($fileOrFolderObject instanceof \TYPO3\CMS\Core\Resource\Folder) {
559 // It's a folder
560 $selectedFolder = $fileOrFolderObject;
561 } elseif ($fileOrFolderObject instanceof \TYPO3\CMS\Core\Resource\FileInterface) {
562 // It's a file
563 $selectedFolder = $fileOrFolderObject->getParentFolder();
564 }
565 }
566 // If no folder is selected, get the user's default upload folder
567 if (!$selectedFolder) {
568 try {
569 $selectedFolder = $GLOBALS['BE_USER']->getDefaultUploadFolder();
570 } catch (\Exception $e) {
571 // The configured default user folder does not exist
572 }
573 }
574 // Build the file upload and folder creation forms
575 $uploadForm = '';
576 $createFolder = '';
577 if ($selectedFolder) {
578 $uploadForm = ($this->act === 'file') ? $this->uploadForm($selectedFolder) : '';
579 $createFolder = $this->createFolder($selectedFolder);
580 }
581 // Insert the upload form on top, if so configured
582 if ($GLOBALS['BE_USER']->getTSConfigVal('options.uploadFieldsInTopOfEB')) {
583 $content .= $uploadForm;
584 }
585 // Render the filelist if there is a folder selected
586 if ($selectedFolder) {
587 $files = $this->expandFolder($selectedFolder, $this->P['params']['allowedExtensions']);
588 }
589 $content .= '
590
591 <!--
592 Wrapper table for folder tree / file/folder list:
593 -->
594 <table border="0" cellpadding="0" cellspacing="0" id="typo3-linkFiles">
595 <tr>
596 <td class="c-wCell" valign="top">' . $this->barheader(($GLOBALS['LANG']->getLL('folderTree') . ':')) . $tree . '</td>
597 <td class="c-wCell" valign="top">' . $files . '</td>
598 </tr>
599 </table>
600 ';
601 // Adding create folder + upload form if applicable
602 if (!$GLOBALS['BE_USER']->getTSConfigVal('options.uploadFieldsInTopOfEB')) {
603 $content .= $uploadForm;
604 }
605 $content .= '<br />';
606 $content .= $createFolder;
607 $content .= '<br />';
608 break;
609 case 'spec':
610 if (is_array($this->thisConfig['userLinks.'])) {
611 $subcats = array();
612 $v = $this->thisConfig['userLinks.'];
613 foreach ($v as $k2 => $dummyValue) {
614 $k2i = (int)$k2;
615 if (substr($k2, -1) == '.' && is_array($v[$k2i . '.'])) {
616 // Title:
617 $title = trim($v[$k2i]);
618 if (!$title) {
619 $title = $v[$k2i . '.']['url'];
620 } else {
621 $title = $GLOBALS['LANG']->sL($title);
622 }
623 // Description:
624 $description = $v[$k2i . '.']['description'] ? $GLOBALS['LANG']->sL($v[($k2i . '.')]['description'], TRUE) . '<br />' : '';
625 // URL + onclick event:
626 $onClickEvent = '';
627 if (isset($v[$k2i . '.']['target'])) {
628 $onClickEvent .= 'TYPO3\\CMS\\Recordlist\\Browser\\ElementBrowser_setTarget(\'' . $v[($k2i . '.')]['target'] . '\');';
629 }
630 $v[$k2i . '.']['url'] = str_replace('###_URL###', $this->siteURL, $v[$k2i . '.']['url']);
631 if (substr($v[$k2i . '.']['url'], 0, 7) == 'http://' || substr($v[$k2i . '.']['url'], 0, 7) == 'mailto:') {
632 $onClickEvent .= 'cur_href=' . GeneralUtility::quoteJSvalue($v[($k2i . '.')]['url']) . ';link_current();';
633 } else {
634 $onClickEvent .= 'link_spec(' . GeneralUtility::quoteJSvalue($this->siteURL . $v[($k2i . '.')]['url']) . ');';
635 }
636 // Link:
637 $A = array('<a href="#" onclick="' . htmlspecialchars($onClickEvent) . 'return false;">', '</a>');
638 // Adding link to menu of user defined links:
639 $subcats[$k2i] = '
640 <tr>
641 <td class="bgColor4">' . $A[0] . '<strong>' . htmlspecialchars($title) . ($this->curUrlInfo['info'] == $v[$k2i . '.']['url'] ? '<img' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/blinkarrow_right.gif', 'width="5" height="9"') . ' class="c-blinkArrowR" alt="" />' : '') . '</strong><br />' . $description . $A[1] . '</td>
642 </tr>';
643 }
644 }
645 // Sort by keys:
646 ksort($subcats);
647 // Add menu to content:
648 $content .= '
649 <!--
650 Special userdefined menu:
651 -->
652 <table border="0" cellpadding="1" cellspacing="1" id="typo3-linkSpecial">
653 <tr>
654 <td class="bgColor5" class="c-wCell" valign="top"><strong>' . $GLOBALS['LANG']->getLL('special', TRUE) . '</strong></td>
655 </tr>
656 ' . implode('', $subcats) . '
657 </table>
658 ';
659 }
660 break;
661 case 'page':
662 $content .= $this->addAttributesForm();
663 $pagetree = GeneralUtility::makeInstance('TYPO3\\CMS\\Rtehtmlarea\\PageTree');
664 $pagetree->ext_showNavTitle = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showNavTitle');
665 $pagetree->ext_showPageId = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showPageIdWithTitle');
666 $pagetree->addField('nav_title');
667 $tree = $pagetree->getBrowsableTree();
668 $cElements = $this->expandPage();
669 // Outputting Temporary DB mount notice:
670 if ((int)$GLOBALS['BE_USER']->getSessionData('pageTree_temporaryMountPoint')) {
671 $link = '<a href="' . htmlspecialchars(GeneralUtility::linkThisScript(array('setTempDBmount' => 0))) . '">' . $GLOBALS['LANG']->sl('LLL:EXT:lang/locallang_core.xlf:labels.temporaryDBmount', TRUE) . '</a>';
672 $flashMessage = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Messaging\\FlashMessage', $link, '', \TYPO3\CMS\Core\Messaging\FlashMessage::INFO);
673 $dbmount = $flashMessage->render();
674 }
675 $content .= '
676 <!--
677 Wrapper table for page tree / record list:
678 -->
679 <table border="0" cellpadding="0" cellspacing="0" id="typo3-linkPages">
680 <tr>
681 <td class="c-wCell" valign="top">' . $this->barheader(($GLOBALS['LANG']->getLL('pageTree') . ':')) . $dbmount . $tree . '</td>
682 <td class="c-wCell" valign="top">' . $cElements . '</td>
683 </tr>
684 </table>
685 ';
686 break;
687 default:
688 // call hook
689 foreach ($this->hookObjects as $hookObject) {
690 $content .= $hookObject->getTab($this->act);
691 }
692 }
693 // End page, return content:
694 $content .= $this->doc->endPage();
695 $content = $this->doc->insertStylesAndJS($content);
696 return $content;
697 }
698
699 /**
700 * Creates a form for link attributes
701 *
702 * @param string $rows: html code for some initial rows of the table to be wrapped in form
703 * @return string The HTML code of the form
704 */
705 public function addAttributesForm($rows = '') {
706 $ltargetForm = '';
707 $additionalAttributeFields = '';
708 // Add page id, target, class selector box, title and parameters fields:
709 $lpageId = $this->addPageIdSelector();
710 $queryParameters = $this->addQueryParametersSelector();
711 $ltarget = $this->addTargetSelector();
712 $lclass = $this->addClassSelector();
713 $ltitle = $this->addTitleSelector();
714 $rel = $this->addRelField();
715 // additional fields for links
716 if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php']['addAttributeFields']) && is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php']['addAttributeFields'])) {
717 $conf = array();
718 $_params = array(
719 'conf' => &$conf
720 );
721 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php']['addAttributeFields'] as $objRef) {
722 $processor =& GeneralUtility::getUserObj($objRef);
723 $additionalAttributeFields .= $processor->getAttributefields($_params, $this);
724 }
725 }
726 if ($rows || $lpageId || $queryParameters || $lclass || $ltitle || $ltarget || $rel) {
727 $ltargetForm = $this->wrapInForm($rows . $lpageId . $queryParameters . $lclass . $ltitle . $ltarget . $rel . $additionalAttributeFields);
728 }
729 return $ltargetForm;
730 }
731
732 /**
733 * @todo Define visibility
734 */
735 public function wrapInForm($string) {
736 $form = '
737 <!--
738 Selecting target for link:
739 -->
740 <form action="" name="ltargetform" id="ltargetform">
741 <table id="typo3-linkTarget" class="htmlarea-window-table">' . $string;
742 if ($this->act == $this->curUrlInfo['act'] && $this->act != 'mail' && $this->curUrlArray['href']) {
743 $form .= '
744 <tr>
745 <td>
746 </td>
747 <td colspan="3">
748 <input type="submit" value="' . $GLOBALS['LANG']->getLL('update', TRUE) . '" onclick="' . ($this->act == 'url' ? 'browse_links_setAdditionalValue(\'data-htmlarea-external\', \'1\'); ' : '') . 'return link_current();" />
749 </td>
750 </tr>';
751 }
752 $form .= '
753 </table>
754 </form>';
755 return $form;
756 }
757
758 /**
759 * @todo Define visibility
760 */
761 public function addPageIdSelector() {
762 return $this->act == 'page' && $this->buttonConfig && is_array($this->buttonConfig['pageIdSelector.']) && $this->buttonConfig['pageIdSelector.']['enabled'] ? '
763 <tr>
764 <td><label>' . $GLOBALS['LANG']->getLL('page_id', TRUE) . ':</label></td>
765 <td colspan="3">
766 <input type="text" size="6" name="luid" />&nbsp;<input type="submit" value="' . $GLOBALS['LANG']->getLL('setLink', TRUE) . '" onclick="return link_typo3Page(document.ltargetform.luid.value);" />
767 </td>
768 </tr>' : '';
769 }
770
771 /**
772 * @todo Define visibility
773 */
774 public function addRelField() {
775 return ($this->act == 'page' || $this->act == 'url' || $this->act == 'file') && $this->buttonConfig && is_array($this->buttonConfig['relAttribute.']) && $this->buttonConfig['relAttribute.']['enabled'] ? '
776 <tr>
777 <td><label>' . $GLOBALS['LANG']->getLL('linkRelationship', TRUE) . ':</label></td>
778 <td colspan="3">
779 <input type="text" name="lrel" value="' . $this->additionalAttributes['rel'] . '" ' . $this->doc->formWidth(30) . ' />
780 </td>
781 </tr>' : '';
782 }
783
784 /**
785 * @todo Define visibility
786 */
787 public function addQueryParametersSelector() {
788 return $this->act == 'page' && $this->buttonConfig && is_array($this->buttonConfig['queryParametersSelector.']) && $this->buttonConfig['queryParametersSelector.']['enabled'] ? '
789 <tr>
790 <td><label>' . $GLOBALS['LANG']->getLL('query_parameters', TRUE) . ':</label></td>
791 <td colspan="3">
792 <input type="text" name="query_parameters" value="' . ($this->curUrlInfo['query'] ?: '') . '" ' . $this->doc->formWidth(30) . ' />
793 </td>
794 </tr>' : '';
795 }
796
797 /**
798 * @todo Define visibility
799 */
800 public function addTargetSelector() {
801 $targetSelectorConfig = array();
802 $popupSelectorConfig = array();
803 if (is_array($this->buttonConfig['targetSelector.'])) {
804 $targetSelectorConfig = $this->buttonConfig['targetSelector.'];
805 }
806 if (is_array($this->buttonConfig['popupSelector.'])) {
807 $popupSelectorConfig = $this->buttonConfig['popupSelector.'];
808 }
809 $ltarget = '';
810 if ($this->act != 'mail') {
811 $ltarget .= '
812 <tr id="ltargetrow"' . ($targetSelectorConfig['disabled'] && $popupSelectorConfig['disabled'] ? ' style="display: none;"' : '') . '>
813 <td><label>' . $GLOBALS['LANG']->getLL('target', TRUE) . ':</label></td>
814 <td><input type="text" name="ltarget" onchange="browse_links_setTarget(this.value);" value="' . htmlspecialchars(($this->setTarget ? $this->setTarget : ($this->setClass || !$this->classesAnchorDefault[$this->act] ? '' : $this->classesAnchorDefaultTarget[$this->act]))) . '"' . $this->doc->formWidth(10) . ' /></td>';
815 $ltarget .= '
816 <td colspan="2">';
817 if (!$targetSelectorConfig['disabled']) {
818 $ltarget .= '
819 <select name="ltarget_type" onchange="browse_links_setTarget(this.options[this.selectedIndex].value);document.ltargetform.ltarget.value=this.options[this.selectedIndex].value;this.selectedIndex=0;">
820 <option></option>
821 <option value="_top">' . $GLOBALS['LANG']->getLL('top', TRUE) . '</option>
822 <option value="_blank">' . $GLOBALS['LANG']->getLL('newWindow', TRUE) . '</option>
823 </select>';
824 }
825 $ltarget .= '
826 </td>
827 </tr>';
828 if (!$popupSelectorConfig['disabled']) {
829 $selectJS = 'if (document.ltargetform.popup_width.options[document.ltargetform.popup_width.selectedIndex].value>0 && document.ltargetform.popup_height.options[document.ltargetform.popup_height.selectedIndex].value>0) {
830 document.ltargetform.ltarget.value = document.ltargetform.popup_width.options[document.ltargetform.popup_width.selectedIndex].value+\'x\'+document.ltargetform.popup_height.options[document.ltargetform.popup_height.selectedIndex].value;
831 browse_links_setTarget(document.ltargetform.ltarget.value);
832 document.ltargetform.popup_width.selectedIndex=0;
833 document.ltargetform.popup_height.selectedIndex=0;
834 }';
835 $ltarget .= '
836 <tr>
837 <td><label>' . $GLOBALS['LANG']->getLL('target_popUpWindow', TRUE) . ':</label></td>
838 <td colspan="3">
839 <select name="popup_width" onchange="' . $selectJS . '">
840 <option value="0">' . $GLOBALS['LANG']->getLL('target_popUpWindow_width', TRUE) . '</option>
841 <option value="300">300</option>
842 <option value="400">400</option>
843 <option value="500">500</option>
844 <option value="600">600</option>
845 <option value="700">700</option>
846 <option value="800">800</option>
847 </select>
848 x
849 <select name="popup_height" onchange="' . $selectJS . '">
850 <option value="0">' . $GLOBALS['LANG']->getLL('target_popUpWindow_height', TRUE) . '</option>
851 <option value="200">200</option>
852 <option value="300">300</option>
853 <option value="400">400</option>
854 <option value="500">500</option>
855 <option value="600">600</option>
856 </select>
857 </td>
858 </tr>';
859 }
860 }
861 return $ltarget;
862 }
863
864 /**
865 * Return html code for the class selector
866 *
867 * @return string the html code to be added to the form
868 */
869 public function addClassSelector() {
870 $selectClass = '';
871 if ($this->classesAnchorJSOptions[$this->act]) {
872 $selectClass = '
873 <tr>
874 <td><label>' . $GLOBALS['LANG']->getLL('anchor_class', TRUE) . ':</label></td>
875 <td colspan="3">
876 <select name="anchor_class" onchange="' . $this->getClassOnChangeJS() . '">
877 ' . $this->classesAnchorJSOptions[$this->act] . '
878 </select>
879 </td>
880 </tr>';
881 }
882 return $selectClass;
883 }
884
885 /**
886 * Return JS code for the class selector onChange event
887 *
888 * @return string class selector onChange JS code
889 */
890 public function getClassOnChangeJS() {
891 return '
892 if (document.ltargetform.anchor_class) {
893 document.ltargetform.anchor_class.value = document.ltargetform.anchor_class.options[document.ltargetform.anchor_class.selectedIndex].value;
894 if (document.ltargetform.anchor_class.value && HTMLArea.classesAnchorSetup) {
895 for (var i = HTMLArea.classesAnchorSetup.length; --i >= 0;) {
896 var anchorClass = HTMLArea.classesAnchorSetup[i];
897 if (anchorClass[\'name\'] == document.ltargetform.anchor_class.value) {
898 if (anchorClass[\'titleText\'] && document.ltargetform.anchor_title) {
899 document.ltargetform.anchor_title.value = anchorClass[\'titleText\'];
900 document.getElementById(\'rtehtmlarea-browse-links-title-readonly\').innerHTML = anchorClass[\'titleText\'];
901 browse_links_setTitle(anchorClass[\'titleText\']);
902 }
903 if (anchorClass[\'target\']) {
904 if (document.ltargetform.ltarget) {
905 document.ltargetform.ltarget.value = anchorClass[\'target\'];
906 }
907 browse_links_setTarget(anchorClass[\'target\']);
908 } else if (document.ltargetform.ltarget && document.getElementById(\'ltargetrow\').style.display == \'none\') {
909 // Reset target to default if field is not displayed and class has no configured target
910 document.ltargetform.ltarget.value = \'' . ($this->defaultLinkTarget ?: '') . '\';
911 browse_links_setTarget(document.ltargetform.ltarget.value);
912 }
913 break;
914 }
915 }
916 }
917 browse_links_setClass(document.ltargetform.anchor_class.value);
918 }
919 ';
920 }
921
922 /**
923 * @todo Define visibility
924 */
925 public function addTitleSelector() {
926 $title = $this->setTitle ?: ($this->setClass || !$this->classesAnchorDefault[$this->act] ? '' : $this->classesAnchorDefaultTitle[$this->act]);
927 $readOnly = $this->buttonConfig['properties.']['title.']['readOnly'] || $this->buttonConfig[$this->act . '.']['properties.']['title.']['readOnly'];
928 if ($readOnly) {
929 $title = $this->setClass ? $this->classesAnchorClassTitle[$this->setClass] : $this->classesAnchorDefaultTitle[$this->act];
930 }
931 return '
932 <tr>
933 <td><label for="rtehtmlarea-browse-links-anchor_title" id="rtehtmlarea-browse-links-title-label">' . $GLOBALS['LANG']->getLL('anchor_title', TRUE) . ':</label></td>
934 <td colspan="3">
935 <span id="rtehtmlarea-browse-links-title-input" style="display: ' . ($readOnly ? 'none' : 'inline') . ';">
936 <input type="text" id="rtehtmlarea-browse-links-anchor_title" name="anchor_title" value="' . $title . '" ' . $this->doc->formWidth(30) . ' />
937 </span>
938 <span id="rtehtmlarea-browse-links-title-readonly" style="display: ' . ($readOnly ? 'inline' : 'none') . ';">' . $title . '</span>
939 </td>
940 </tr>';
941 }
942
943 /**
944 * Localize a string using the language of the content element rather than the language of the BE interface
945 *
946 * @param string string: the label to be localized
947 * @return string Localized string.
948 */
949 public function getLLContent($string) {
950 return $this->contentLanguageService->sL($string);
951 }
952
953 /**
954 * Localize a label obtained from Page TSConfig
955 *
956 * @param string $string The label to be localized
957 * @param boolean $JScharCode If needs to be converted to a array of char numbers
958 * @return string Localized string.
959 */
960 public function getPageConfigLabel($string, $JScharCode = 1) {
961 if (substr($string, 0, 4) !== 'LLL:') {
962 $label = $string;
963 } else {
964 $label = $GLOBALS['LANG']->sL(trim($string));
965 }
966 $label = str_replace('"', '\\"', str_replace('\\\'', '\'', $label));
967 $label = $JScharCode ? GeneralUtility::quoteJSvalue($label) : $label;
968 return $label;
969 }
970
971 }