GenericControls.template.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. <?php
  2. /**
  3. * Simple Machines Forum (SMF)
  4. *
  5. * @package SMF
  6. * @author Simple Machines
  7. * @copyright 2011 Simple Machines
  8. * @license http://www.simplemachines.org/about/smf/license.php BSD
  9. *
  10. * @version 2.1 Alpha 1
  11. */
  12. // This function displays all the stuff you get with a richedit box - BBC, smileys etc.
  13. function template_control_richedit($editor_id, $smileyContainer = null, $bbcContainer = null)
  14. {
  15. global $context, $settings, $options, $txt, $modSettings, $scripturl, $boardurl;
  16. $editor_context = &$context['controls']['richedit'][$editor_id];
  17. echo '
  18. <div>
  19. <textarea class="editor" name="', $editor_id, '" id="', $editor_id, '" rows="', $editor_context['rows'], '" cols="600" onselect="storeCaret(this);" onclick="storeCaret(this);" onkeyup="storeCaret(this);" onchange="storeCaret(this);" tabindex="', $context['tabindex']++, '" style="height: ', $editor_context['height'], '; ', isset($context['post_error']['no_message']) || isset($context['post_error']['long_message']) ? 'border: 1px solid red;' : '', '">', $editor_context['value'], '</textarea>
  20. </div>
  21. <input type="hidden" name="', $editor_id, '_mode" id="', $editor_id, '_mode" value="0" />
  22. <script type="text/javascript"><!-- // --><![CDATA[
  23. var bbc_quote_from = \'', $txt['quote_from'], '\'
  24. var bbc_quote = \'', $txt['quote'], '\'
  25. var bbc_search_on = \'', $txt['search_on'], '\';
  26. (function($) {
  27. var extensionMethods = {
  28. InsertText: function(text, bClear) {
  29. var bIsSource = this.inSourceMode();
  30. // @TODO make it put the quote close to the current selection
  31. if (!bIsSource)
  32. this.toggleTextMode();
  33. var current_value = bClear ? text + "\n" : this.getTextareaValue(false) + "\n" + text + "\n";
  34. this.setTextareaValue(current_value);
  35. if (!bIsSource)
  36. this.toggleTextMode();
  37. },
  38. getText: function() {
  39. if(this.inSourceMode())
  40. var current_value = this.getTextareaValue(false);
  41. else
  42. var current_value = this.getWysiwygEditorValue();
  43. return current_value;
  44. },
  45. appendEmoticon: function (code, emoticon) {
  46. if (code == \'\')
  47. line.append($(\'<br />\'));
  48. else
  49. line.append($(\'<img />\')
  50. .attr({
  51. src: emoticon,
  52. alt: code,
  53. })
  54. .click(function (e) {
  55. var start = \'\', end = \'\';
  56. if (base.options.emoticonsCompat)
  57. {
  58. start = \'<span> \';
  59. end = \' </span>\';
  60. }
  61. if (base.inSourceMode())
  62. base.textEditorInsertText(\' \' + $(this).attr(\'alt\') + \' \');
  63. else
  64. base.wysiwygEditorInsertHtml(start + \'<img src="\' + $(this).attr("src") +
  65. \'" data-sceditor-emoticon="\' + $(this).attr(\'alt\') + \'" />\' + end);
  66. e.preventDefault();
  67. })
  68. );
  69. if (line.children().length > 0)
  70. content.append(line);
  71. $(".sceditor-toolbar").append(content);
  72. },
  73. setTextMode: function () {
  74. if (!this.inSourceMode())
  75. this.toggleTextMode();
  76. },
  77. createPermanentDropDown: function() {
  78. var emoticons = $.extend({}, this.options.emoticons.dropdown);
  79. var popup_exists = false;
  80. content = $(\'<div />\').attr({class: "sceditor-insertemoticon"});
  81. line = $(\'<div />\');
  82. base = this;
  83. for (smiley_popup in this.options.emoticons.popup)
  84. {
  85. popup_exists = true;
  86. break;
  87. }
  88. if (popup_exists)
  89. {
  90. this.options.emoticons.more = this.options.emoticons.popup;
  91. moreButton = $(\'<div />\').attr({class: "sceditor-more"}).text(', JavaScriptEscape('[' . $txt['more'] . ']'), ').click(function () {
  92. if ($(".sceditor-smileyPopup").length > 0)
  93. {
  94. $(".sceditor-smileyPopup").fadeIn(\'fast\');
  95. }
  96. else
  97. {
  98. var emoticons = $.extend({}, base.options.emoticons.popup);
  99. var basement = $(\'<div />\').attr({class: "sceditor-popup"});
  100. allowHide = true;
  101. popupContent = $(\'<div />\');
  102. line = $(\'<div />\');
  103. closeButton = $(\'<span />\').text(', JavaScriptEscape('[' . $txt['find_close'] . ']'), ').click(function () {
  104. $(".sceditor-smileyPopup").fadeOut(\'fast\');
  105. });
  106. $.each(emoticons, base.appendEmoticon);
  107. if (line.children().length > 0)
  108. popupContent.append(line);
  109. if (typeof closeButton !== "undefined")
  110. popupContent.append(closeButton);
  111. // IE needs unselectable attr to stop it from unselecting the text in the editor.
  112. // The editor can cope if IE does unselect the text it\'s just not nice.
  113. if(base.ieUnselectable !== false) {
  114. content = $(content);
  115. content.find(\':not(input,textarea)\').filter(function() { return this.nodeType===1; }).attr(\'unselectable\', \'on\');
  116. }
  117. $dropdown = $(\'<div class="sceditor-dropdown sceditor-smileyPopup" />\').append(popupContent);
  118. $dropdown.appendTo($(\'body\'));
  119. dropdownIgnoreLastClick = true;
  120. $dropdown.css({
  121. position: "fixed",
  122. top: $(window).height() * 0.2,
  123. left: $(window).width() * 0.5 - ($dropdown.width() / 2),
  124. "max-width": "50%"
  125. });
  126. // stop clicks within the dropdown from being handled
  127. $dropdown.click(function (e) {
  128. e.stopPropagation();
  129. });
  130. }
  131. });
  132. }
  133. $.each(emoticons, base.appendEmoticon);
  134. if (typeof moreButton !== "undefined")
  135. content.append(moreButton);
  136. }
  137. };
  138. $.extend(true, $[\'sceditor\'].prototype, extensionMethods);
  139. })(jQuery);
  140. $(document).ready(function() {
  141. $.sceditor.setCommand(
  142. \'ftp\',
  143. function (caller) {
  144. var editor = this,
  145. content = $(this._(\'<form><div><label for="link">{0}</label> <input type="text" id="link" value="ftp://" /></div>\' +
  146. \'<div><label for="des">{1}</label> <input type="text" id="des" value="" /></div></form>\',
  147. this._("URL:"),
  148. this._("Description (optional):")
  149. ))
  150. .submit(function () {return false;});
  151. content.append($(
  152. this._(\'<div><input type="button" class="button" value="{0}" /></div>\',
  153. this._("Insert")
  154. )).click(function (e) {
  155. var val = $(this).parent("form").find("#link").val(),
  156. description = $(this).parent("form").find("#des").val();
  157. if(val !== "" && val !== "ftp://") {
  158. // needed for IE to reset the last range
  159. editor.focus();
  160. if(!editor.getRangeHelper().selectedHtml() || description)
  161. {
  162. if(!description)
  163. description = val;
  164. editor.wysiwygEditorInsertHtml(\'<a href="\' + val + \'">\' + description + \'</a>\');
  165. }
  166. else
  167. editor.execCommand("createlink", val);
  168. }
  169. editor.closeDropDown(true);
  170. e.preventDefault();
  171. }));
  172. editor.createDropDown(caller, "insertlink", content);
  173. },
  174. ', javaScriptEscape($txt['ftp']), '
  175. );
  176. $.sceditor.setCommand(
  177. \'glow\',
  178. function () {
  179. this.wysiwygEditorInsertHtml(\'[glow=red,2,300]\', \'[/glow]\');
  180. },
  181. ', javaScriptEscape($txt['glow']), '
  182. );
  183. $.sceditor.setCommand(
  184. \'shadow\',
  185. function () {
  186. this.wysiwygEditorInsertHtml(\'[shadow=red,left]\', \'[/shadow]\');
  187. },
  188. ', javaScriptEscape($txt['shadow']), '
  189. );
  190. $.sceditor.setCommand(
  191. \'tt\',
  192. function () {
  193. this.wysiwygEditorInsertHtml(\'<tt>\', \'</tt>\');
  194. },
  195. ', javaScriptEscape($txt['teletype']), '
  196. );
  197. $("#', $editor_id, '").sceditorBBCodePlugin({
  198. style: "', $settings['default_theme_url'], '/css/jquery.sceditor.default.css",
  199. emoticonsCompat: true,
  200. supportedWysiwyg: (((is_ie5up && !is_ie50) || is_ff || is_opera95up || is_safari || is_chrome) && !(is_iphone || is_android)),
  201. colors: "black,red,yellow,pink,green,orange,purple,blue,beige,brown,teal,navy,maroon,limegreen,white"';
  202. // Show the smileys.
  203. if ((!empty($context['smileys']['postform']) || !empty($context['smileys']['popup'])) && !$editor_context['disable_smiley_box'] && $smileyContainer !== null)
  204. {
  205. echo ',
  206. emoticons:
  207. {';
  208. $countLocations = count($context['smileys']);
  209. foreach ($context['smileys'] as $location => $smileyRows)
  210. {
  211. $countLocations--;
  212. if ($location == 'postform')
  213. echo '
  214. dropdown:
  215. {';
  216. elseif ($location == 'popup')
  217. echo '
  218. popup:
  219. {';
  220. $numRows = count($smileyRows);
  221. foreach ($smileyRows as $smileyRow)
  222. {
  223. foreach ($smileyRow['smileys'] as $smiley)
  224. {
  225. echo '
  226. ', JavaScriptEscape($smiley['code']), ': ', JavaScriptEscape(str_replace($boardurl . '/', '', $settings['smileys_url'] . '/' . $smiley['filename'])), empty($smiley['isLast']) ? ',' : '';
  227. }
  228. if (empty($smileyRow['isLast']) && $numRows != 1)
  229. echo ',
  230. \'\': \'\',';
  231. }
  232. echo '
  233. }', $countLocations != 0 ? ',' : '';
  234. }
  235. echo '
  236. }';
  237. }
  238. if ($context['show_bbc'] && $bbcContainer !== null)
  239. {
  240. echo ',
  241. toolbar: "emoticon,';
  242. $count_tags = count($context['bbc_tags']);
  243. foreach ($context['bbc_toolbar'] as $i => $buttonRow)
  244. {
  245. echo implode('|', $buttonRow);
  246. $count_tags--;
  247. if (!empty($count_tags))
  248. echo '||';
  249. }
  250. echo '",';
  251. }
  252. else
  253. echo ',
  254. toolbar: "emoticon,source",';
  255. echo '
  256. });
  257. $("#', $editor_id, '").data("sceditor").createPermanentDropDown();
  258. $(".sceditor-container").width("100%").height("100%");',
  259. $editor_context['rich_active'] ? '' : '
  260. $("#' . $editor_id . '").data("sceditor").setTextMode();', '
  261. if (!(((is_ie5up && !is_ie50) || is_ff || is_opera95up || is_safari || is_chrome) && !(is_iphone || is_android)))
  262. {
  263. $("#' . $editor_id . '").data("sceditor").setTextMode();
  264. $(".sceditor-button-source").hide();
  265. }
  266. });';
  267. // Now for backward compatibility let's collect few infos in the good ol' style
  268. echo '
  269. var oEditorHandle_', $editor_id, ' = new smc_Editor({
  270. sSessionId: smf_session_id,
  271. sSessionVar: smf_session_var,
  272. sFormId: ', JavaScriptEscape($editor_context['form']), ',
  273. sUniqueId: ', JavaScriptEscape($editor_id), ',
  274. bRTL: ', $txt['lang_rtl'] ? 'true' : 'false', ',
  275. bWysiwyg: ', $editor_context['rich_active'] ? 'true' : 'false', ',
  276. sText: ', JavaScriptEscape($editor_context['rich_active'] ? $editor_context['rich_value'] : ''), ',
  277. sEditWidth: ', JavaScriptEscape($editor_context['width']), ',
  278. sEditHeight: ', JavaScriptEscape($editor_context['height']), ',
  279. bRichEditOff: ', empty($modSettings['disable_wysiwyg']) ? 'false' : 'true', ',
  280. oSmileyBox: null,
  281. oBBCBox: null
  282. });
  283. smf_editorArray[smf_editorArray.length] = oEditorHandle_', $editor_id, ';
  284. // ]]></script>';
  285. }
  286. function template_control_richedit_buttons($editor_id)
  287. {
  288. global $context, $settings, $options, $txt, $modSettings, $scripturl;
  289. $editor_context = &$context['controls']['richedit'][$editor_id];
  290. echo '
  291. <input type="submit" value="', isset($editor_context['labels']['post_button']) ? $editor_context['labels']['post_button'] : $txt['post'], '" tabindex="', $context['tabindex']++, '" onclick="return submitThisOnce(this);" accesskey="s" class="button_submit" />';
  292. if ($editor_context['preview_type'])
  293. echo '
  294. <input type="submit" name="preview" value="', isset($editor_context['labels']['preview_button']) ? $editor_context['labels']['preview_button'] : $txt['preview'], '" tabindex="', $context['tabindex']++, '" onclick="', $editor_context['preview_type'] == 2 ? 'return event.ctrlKey || previewPost();' : 'return submitThisOnce(this);', '" accesskey="p" class="button_submit" />';
  295. if ($context['show_spellchecking'])
  296. echo '
  297. <input type="button" value="', $txt['spell_check'], '" tabindex="', $context['tabindex']++, '" onclick="oEditorHandle_', $editor_id, '.spellCheckStart();" class="button_submit" />';
  298. }
  299. // What's this, verification?!
  300. function template_control_verification($verify_id, $display_type = 'all', $reset = false)
  301. {
  302. global $context, $settings, $options, $txt, $modSettings;
  303. $verify_context = &$context['controls']['verification'][$verify_id];
  304. // Keep track of where we are.
  305. if (empty($verify_context['tracking']) || $reset)
  306. $verify_context['tracking'] = 0;
  307. // How many items are there to display in total.
  308. $total_items = count($verify_context['questions']) + ($verify_context['show_visual'] ? 1 : 0);
  309. // If we've gone too far, stop.
  310. if ($verify_context['tracking'] > $total_items)
  311. return false;
  312. // Loop through each item to show them.
  313. for ($i = 0; $i < $total_items; $i++)
  314. {
  315. // If we're after a single item only show it if we're in the right place.
  316. if ($display_type == 'single' && $verify_context['tracking'] != $i)
  317. continue;
  318. if ($display_type != 'single')
  319. echo '
  320. <div id="verification_control_', $i, '" class="verification_control">';
  321. // Do the actual stuff - image first?
  322. if ($i == 0 && $verify_context['show_visual'])
  323. {
  324. if ($context['use_graphic_library'])
  325. echo '
  326. <img src="', $verify_context['image_href'], '" alt="', $txt['visual_verification_description'], '" id="verification_image_', $verify_id, '" />';
  327. else
  328. echo '
  329. <img src="', $verify_context['image_href'], ';letter=1" alt="', $txt['visual_verification_description'], '" id="verification_image_', $verify_id, '_1" />
  330. <img src="', $verify_context['image_href'], ';letter=2" alt="', $txt['visual_verification_description'], '" id="verification_image_', $verify_id, '_2" />
  331. <img src="', $verify_context['image_href'], ';letter=3" alt="', $txt['visual_verification_description'], '" id="verification_image_', $verify_id, '_3" />
  332. <img src="', $verify_context['image_href'], ';letter=4" alt="', $txt['visual_verification_description'], '" id="verification_image_', $verify_id, '_4" />
  333. <img src="', $verify_context['image_href'], ';letter=5" alt="', $txt['visual_verification_description'], '" id="verification_image_', $verify_id, '_5" />
  334. <img src="', $verify_context['image_href'], ';letter=6" alt="', $txt['visual_verification_description'], '" id="verification_image_', $verify_id, '_6" />';
  335. if (WIRELESS)
  336. echo '<br />
  337. <input type="text" name="', $verify_id, '_vv[code]" value="', !empty($verify_context['text_value']) ? $verify_context['text_value'] : '', '" size="30" tabindex="', $context['tabindex']++, '" class="input_text" />';
  338. else
  339. echo '
  340. <div class="smalltext" style="margin: 4px 0 8px 0;">
  341. <a href="', $verify_context['image_href'], ';sound" id="visual_verification_', $verify_id, '_sound" rel="nofollow">', $txt['visual_verification_sound'], '</a> / <a href="#visual_verification_', $verify_id, '_refresh" id="visual_verification_', $verify_id, '_refresh">', $txt['visual_verification_request_new'], '</a>', $display_type != 'quick_reply' ? '<br />' : '', '<br />
  342. ', $txt['visual_verification_description'], ':', $display_type != 'quick_reply' ? '<br />' : '', '
  343. <input type="text" name="', $verify_id, '_vv[code]" value="', !empty($verify_context['text_value']) ? $verify_context['text_value'] : '', '" size="30" tabindex="', $context['tabindex']++, '" class="input_text" />
  344. </div>';
  345. }
  346. else
  347. {
  348. // Where in the question array is this question?
  349. $qIndex = $verify_context['show_visual'] ? $i - 1 : $i;
  350. echo '
  351. <div class="smalltext">
  352. ', $verify_context['questions'][$qIndex]['q'], ':<br />
  353. <input type="text" name="', $verify_id, '_vv[q][', $verify_context['questions'][$qIndex]['id'], ']" size="30" value="', $verify_context['questions'][$qIndex]['a'], '" ', $verify_context['questions'][$qIndex]['is_error'] ? 'style="border: 1px red solid;"' : '', ' tabindex="', $context['tabindex']++, '" class="input_text" />
  354. </div>';
  355. }
  356. if ($display_type != 'single')
  357. echo '
  358. </div>';
  359. // If we were displaying just one and we did it, break.
  360. if ($display_type == 'single' && $verify_context['tracking'] == $i)
  361. break;
  362. }
  363. // Assume we found something, always,
  364. $verify_context['tracking']++;
  365. // Tell something displaying piecemeal to keep going.
  366. if ($display_type == 'single')
  367. return true;
  368. }
  369. ?>