1(function ($, peepso, peepsodata) { 2 const { observer, util, ContentEditable } = peepso; 3 const { backgrounds: backgroundsData = {} } = peepsodata; 4 5 // Configurations. 6 const POST_MAX_LENGTH = +backgroundsData.post_max_length || 0; 7 8 class PostboxBackground { 9 constructor($postbox) { 10 this.$postbox = $postbox; 11 this.$postboxTab = this.$postbox.$posttabs; 12 this.$postboxBtnPreview = this.$postbox.find('.ps-js-btn-preview'); 13 this.$postboxStatusTextarea = this.$postbox.$textarea; 14 this.$postboxStatus = this.$postboxStatusTextarea.closest('.ps-postbox-status'); 15 this.$postboxBackground = this.$postbox.find( 16 '.ps-postbox-tabs [data-tab-id=post_backgrounds]' 17 ); 18 this.$postboxBackgroundShortcut = this.$postbox.find('#post_backgrounds'); 19 20 this.$presets = this.$postboxBackground.find('.peepso-background-item'); 21 this.$background = this.$postboxBackground.find('.ps-js-post-background'); 22 this.$text = this.$postboxBackground.find('.ps-js-post-background-text'); 23 this.$warning = this.$postboxBackground.find('.ps-js-activity-background-warning'); 24 25 this.$postboxTab.on('peepso_posttabs_show-post_backgrounds', () => this.show()); 26 this.$postboxTab.on('peepso_posttabs_cancel-post_backgrounds', () => this.cancel()); 27 this.$postboxTab.on('peepso_posttabs_submit-post_backgrounds', () => this.post()); 28 this.$postboxBackgroundShortcut.on('click', () => { 29 this.$postboxTab.find('[data-tab=post_backgrounds]').click(); 30 }); 31 32 this.$presets.on('click', e => this.select(e.currentTarget)); 33 34 this.editor = new ContentEditable(this.$text[0], { 35 onChange: this.onChange.bind(this), 36 transform: this.contentTransform.bind(this) 37 }); 38 39 observer.addAction( 40 'postbox_type_set', 41 ($postbox, type) => { 42 if ($postbox === this.$postbox && type === 'post_backgrounds') { 43 this.$postboxBackgroundShortcut.trigger('click'); 44 } 45 }, 46 10, 47 2 48 ); 49 50 observer.addFilter( 51 'peepso_postbox_can_submit', 52 (flags, $postbox) => { 53 if ($postbox === this.$postbox) { 54 let type = this.$postbox.$posttabs.current_tab_id; 55 if ('post_backgrounds' === type) { 56 let text = this.editor.value(); 57 text = text.replace(/@peepso_user_([a-z]*\d+)\(([\s\S]*?)\)/g, '$2'); 58 59 if (!text) { 60 flags.hard.push(false); 61 this.$warning.hide(); 62 } else if (POST_MAX_LENGTH && text.length > POST_MAX_LENGTH) { 63 flags.hard.push(false); 64 this.$warning.show(); 65 } else { 66 flags.hard.push(true); 67 this.$warning.hide(); 68 } 69 } 70 } 71 72 return flags; 73 }, 74 10, 75 2 76 ); 77 } 78 79 /** 80 * Show the postbox background type. 81 */ 82 show() { 83 this.$postboxBtnPreview.hide(); 84 this.$postboxStatus.hide(); 85 this.$postboxBackground.show(); 86 87 // Update text content from the original textarea. 88 let contentObj = { content: this.$postboxStatusTextarea.val() }; 89 contentObj = observer.applyFilters(`postbox_req_${this.$postbox.guid}`, contentObj); 90 this.editor.value(contentObj.content); 91 92 // Call in-place content transform hook. 93 observer.doAction('postbox_content_update', this.$text[0], this.editor); 94 95 // Select the first preset if nothing is selected. 96 let $selected = this.$presets.filter('.active'); 97 if (!$selected.length) { 98 this.select(this.$presets.eq(0)); 99 } 100 101 this.$postbox.on_change(); 102 } 103 104 /** 105 * Select a background preset. 106 * 107 * @param {Element|JQuery} preset 108 */ 109 select(preset) { 110 let $preset = $(preset), 111 bgImage = $preset.css('background-image'), 112 bgColor = $preset.attr('data-background'), 113 textColor = $preset.attr('data-text-color'), 114 id = $preset.attr('data-preset-id'); 115 116 // Update background and text. 117 this.$background.css('background-image', bgImage).attr('data-background', bgColor); 118 this.$text 119 .css('color', textColor) 120 .attr('data-text-color', textColor) 121 .attr('data-preset-id', id); 122 123 // Update selected preset. 124 $preset.addClass('active'); 125 this.$presets.not($preset).removeClass('active'); 126 127 // Sync placeholder text color. 128 if (!this.__styleOverride) { 129 this.__styleOverride = document.createElement('style'); 130 this.__styleOverride.id = 'peepso-post-background'; 131 document.head.appendChild(this.__styleOverride); 132 } 133 this.__styleOverride.innerHTML = `.ps-post__background-text:before { color: ${textColor} !important }`; 134 135 // Focus on the "textarea". 136 this.focus(); 137 } 138 139 cancel() { 140 this.select(this.$presets.eq(0)); 141 this.editor.value(''); 142 143 observer.doAction('postbox_reinit', this.$postboxStatusTextarea); 144 } 145 146 post() { 147 let filterName = 'postbox_req_' + this.$postbox.guid; 148 149 observer.addFilter(filterName, this.postSetRequest, 10, 1, this); 150 this.$postbox.save_post(); 151 observer.removeFilter(filterName, this.postSetRequest, 10); 152 } 153 154 /** 155 * Update the post data. 156 * 157 * @param {Object} data 158 * @returns {Object} 159 */
160 postSetRequest(data) { 161 data.type = 'post_backgrounds'; 162 data.content = this.editor.value(); 163 data.preset_id = this.$text.attr('data-preset-id'); 164 data.text_color = this.$text.attr('data-text-color'); 165 data.background = this.$background.attr('data-background'); 166 167 return data; 168 } 169 170 /** 171 * Handle focus. 172 */ 173 focus() { 174 setTimeout(() => { 175 let value = this.editor.value(); 176 177 if (value) { 178 let selection = window.getSelection(); 179 let children = this.$text[0].children; 180 let lastChild = children[children.length - 1]; 181 182 // TODO 183 } else { 184 // Should just focus on the element if it is empty. 185 this.$text[0].focus(); 186 } 187 }, 0); 188 } 189 190 contentTransform(elem, editor) { 191 // Call in-place content transform hook. 192 observer.doAction('postbox_content_transform', elem, editor); 193 } 194 195 onChange() { 196 this.$postboxStatusTextarea.val(this.editor.value()); 197 this.$postboxStatusTextarea.trigger('keyup'); 198 this.$postboxBtnPreview.hide(); 199 200 // Call in-place content transform hook. 201 observer.doAction('postbox_content_change', this.$text[0], this.editor); 202 } 203 } 204 205 // Initialize class on main postbox initialization. 206 observer.addAction( 207 'peepso_postbox_addons', 208 addons => { 209 let wrapper = { 210 init() {}, 211 set_postbox($postbox) { 212 if ($postbox.find('#post_backgrounds').length) { 213 new PostboxBackground($postbox); 214 } 215 } 216 }; 217 218 addons.push(wrapper); 219 return addons; 220 }, 221 10, 222 1 223 ); 224
225 class PsPostBackgroundActivity { 226 editPost(post_id, act_id) { 227 let $activity = $(`.ps-post[data-id="${act_id}"]`); 228 229 // exit if post is already in edit mode 230 if ($activity.find('.ps-postbox-textarea').length) return; 231 232 // move postbox after the attachment element 233 $activity.find('.ps-js-activity-edit').appendTo($activity.find('.ps-post__body')); 234 235 // trigger original edit event 236 activity.option_edit(post_id, act_id).then(() => { 237 let $postbox = $activity.find('.ps-postbox-content'); 238 let $textarea = $postbox.find('textarea'); 239 240 let $hidden = $postbox.find('[type=hidden]'); 241 let $editor = $activity.find('.ps-js-activity-background-text'); 242 let $warning = $activity.find('.ps-js-activity-background-warning'); 243 let $submit = $postbox.parent().find('.postbox-submit'); 244 let originalHTML = $editor[0].innerHTML; 245 246 // Hide original postbox and show new editor. 247 $postbox.hide(); 248 $editor.attr('contenteditable', 'true'); 249 250 let editor = new ContentEditable($editor[0], { 251 onChange: function () { 252 let text = editor.value(); 253 254 $textarea.add($hidden).val(text); 255 $textarea.trigger('keyup'); 256 257 if (!text) { 258 $submit.hide(); 259 $warning.hide(); 260 } else if (POST_MAX_LENGTH && text.length > POST_MAX_LENGTH) { 261 $submit.hide(); 262 $warning.show(); 263 } else { 264 $submit.show(); 265 $warning.hide(); 266 } 267 268 // Call in-place content transform hook. 269 $textarea.val(editor.value()); 270 observer.doAction('postbox_content_change', $editor[0], editor); 271 }, 272 transform: function (elem, editor) { 273 // Call in-place content transform hook. 274 observer.doAction('postbox_content_transform', elem, editor); 275 } 276 }); 277 278 // Update text content from the original textarea. 279 setTimeout(function () { 280 let postbox = $postbox.closest('.ps-js-activity-edit').data('ps-postbox'); 281 let $textarea = postbox.$text; 282 let originalValue = $textarea.val(); 283 284 $textarea.ps_tagging('val', function (value) { 285 if (value !== originalValue) { 286 $textarea.val(value); 287 editor.value(value); 288 observer.doAction('postbox_content_update', $editor[0], editor); 289 } 290 }); 291 }, 100); 292 293 function filterData(data, postbox) { 294 if (postbox === $postbox.closest('.ps-js-activity-edit').data('ps-postbox')) { 295 data.content = editor.value(); 296 } 297 298 return data; 299 } 300 301 observer.addFilter('postbox_data', filterData, 20, 2); 302 303 // on cancel button 304 $activity.find('.ps-button-cancel').on('click', () => { 305 $editor.removeAttr('contenteditable').html(originalHTML); 306 observer.removeFilter('postbox_data', filterData, 20, 2); 307 }); 308 }); 309 } 310 } 311
312 window.PsPostBackground = new PsPostBackgroundActivity(); 313})(jQuery, window.peepso, window.peepsodata);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.