1;(function(window) { 2 var BX = window.BX; 3 if (BX["Vote"]) 4 return; 5 var actionUrl = (window.BXMobileApp ? BX.message("SITE_DIR") + "mobile/?mobile_action=vote" : "/bitrix/tools/vote/uf.php"); 6 7 BX.Vote = (function() { 8 var d = function(node, params) { 9 this.node = node; 10 this.form = BX.findChild(this.node, {tagName : "FORM"}, true); 11 this.id = params["id"]; 12 this.voteId = params["voteId"]; 13 this.params = params; 14 var n, answer, i; 15 // Error Node 16 this.errorNode = BX.findChild(this.node, {attribute : {"data-bx-vote-role" : "error"}}, true); 17 // Buttons 18 for (var ii in this.buttons) 19 { 20 if (this.buttons.hasOwnProperty(ii)) 21 { 22 n = BX.findChild(this.node, {attribute : {"data-bx-vote-button" : ii}}, true); 23 if (n && BX.type.isFunction(this[ii])) 24 { 25 this[ii] = BX.delegate(this[ii], this); 26 this.buttons[ii] = n; 27 BX.bind(n, "click", this[ii]); 28 } 29 } 30 } 31 // Answers 32 n = BX.findChildren(this.node, {tagName : "TR"}, true); 33 while (n && (answer = n.pop()) && answer && answer.hasAttribute("data-bx-vote-answer")) 34 { 35 i = BX.findChild(answer, {"tagName" : "A", attribute : {"data-bx-vote-result" : "counter"}}, true); 36 if (i) 37 { 38 if (window.BXMobileApp) 39 { 40 BX.bind(answer, "click", BX.proxy(this.checkMobileUsers, this)); 41 } 42 else 43 { 44 45 BX.bind(i, "click", BX.proxy(this.checkUsers, this)); 46 BX.adjust(i, {attrs : {"data-bx-vote-answer" : answer.getAttribute("data-bx-vote-answer")}}); 47 } 48 } 49 } 50 51 this.onPullEvent = BX.delegate(function(command, params) 52 { 53 if (command == 'voting' && !!params && params["VOTE_ID"] == this.voteId && BX(this.node)) 54 { 55 this.adjustResults(params); 56 } 57 }, this); 58 59 if (window.BXMobileApp) 60 { 61 app.onCustomEvent('onPullExtendWatch', {id: 'VOTE_' + this.voteId}); 62 BX.addCustomEvent('onPull-vote', this.onPullEvent); 63 } 64 else if (BX["PULL"]) 65 { 66 BX.PULL.extendWatch('VOTE_' + this.voteId); 67 BX.addCustomEvent("onPullEvent-vote", this.onPullEvent); 68 } 69 }; 70 d.prototype = { 71 buttons: { 72 showVoteForm: null, 73 showResults: null, 74 actVoting: null, 75 stopOrResume: null, 76 exportXls: null 77 }, 78 params: { 79 }, 80 url: actionUrl, 81 showVoteForm: function(e) { 82 if (this.node.getAttribute("data-bx-vote-lamp") == "green") 83 { 84 var f = BX.proxy(function(data) { 85 if (data && data.data && data.data.event) 86 this.adjustBallot(data.data.attach, data.data.event); 87 this.node.setAttribute("data-bx-vote-form", "shown"); 88 }, this), 89 ff = BX.proxy(function(error) { 90 this.node.setAttribute("data-bx-vote-form", "shown"); 91 }, this); 92 this.send({ action: "getBallot" }, e.target, f, ff); 93 } 94 BX.eventCancelBubble(e); 95 return BX.PreventDefault(e); 96 }, 97 showResults: function(e) { 98 this.node.setAttribute("data-bx-vote-result", (this.node.getAttribute("data-bx-vote-result") == "shown" ? "hidden" : "shown")); 99 BX.eventCancelBubble(e); 100 return BX.PreventDefault(e); 101 }, 102 stopOrResume: function (e) { 103 this.send({ action: this.node.getAttribute("data-bx-vote-lamp") == "red" ? "resume": "stop" }, e.target, BX.proxy(function(data) { 104 if (data["action"] == "stop") 105 { 106 this.node.setAttribute("data-bx-vote-result", "shown"); 107 this.node.setAttribute("data-bx-vote-form", "hidden"); 108 this.node.setAttribute("data-bx-vote-lamp", "red"); 109 } 110 else 111 { 112 if (this.node.getAttribute("data-bx-vote-status") !== "voted") 113 this.node.setAttribute("data-bx-vote-form", "shown"); 114 115 this.node.setAttribute("data-bx-vote-lamp", "green"); 116 } 117 if (data["data"] && data["data"]["attach"]) 118 this.adjustResults(data["data"]["attach"]); 119 }, this)); 120 BX.eventCancelBubble(e); 121 return BX.PreventDefault(e); 122 }, 123 exportXls: function (e) { 124 BX.eventCancelBubble(e); 125 top.location.href = BX.util.add_url_param(this.url, {action: "exportXls", attachId: this.id, sessid: BX.bitrix_sessid()}); 126 return BX.PreventDefault(e); 127 }, 128 actVoting: function(e) {
129 var data = BX.ajax.prepareForm(this.form).data; 130 data["action"] = "vote"; 131 this.send(data, e.target, BX.proxy(function(data) { 132 this.node.setAttribute("data-bx-vote-form", "hidden"); 133 this.node.setAttribute("data-bx-vote-result", "shown"); 134 this.adjustResults(data.data.attach); 135 }, this), BX.proxy(function() { 136 this.node.setAttribute("data-bx-vote-form", "shown"); 137 }, this)); 138 BX.eventCancelBubble(e); 139 return BX.PreventDefault(e); 140 }, 141 send: function(data, el, success, fail) { 142 BX.addClass(el, "ui-btn-clock"); 143 data["sessid"] = BX.bitrix_sessid(); 144 data["attachId"] = this.id; 145 BX.ajax({ 146 method: 'POST', 147 url: BX.util.add_url_param(this.url, {action: data["action"], attachId: this.id}), 148 data: data, 149 dataType: 'json', 150 onsuccess: BX.proxy(function(data) { 151 BX.removeClass(el, 'ui-btn-clock'); 152 if (data.status == "success") 153 { 154 this.showError(null); 155 if (BX.type.isFunction(success)) 156 success.apply(this, arguments); 157 } 158 else 159 { 160 if (data.status == "error" && data["errors"]) 161 this.showError(data["errors"]); 162 if (BX.type.isFunction(fail)) 163 fail.apply(this, arguments); 164 } 165 }, this), 166 onfailure: BX.proxy(function(){ 167 BX.removeClass(el, 'ui-btn-clock'); 168 if (BX.type.isFunction(fail)) 169 fail.apply(this, arguments); 170 }, this) 171 }); 172 }, 173 adjustBallot: function(attachment, event) { 174 var q, a, e, i, j, es, qu, an, v, 175 attach = attachment["QUESTIONS"], 176 ballot = event["ballot"], 177 extras = event["extras"]; 178 for (q in attach) 179 { 180 if (attach.hasOwnProperty(q)) 181 { 182 qu = attach[q]; 183 e = [qu["FIELD_NAME"], qu["FIELD_NAME"] + "[]"]; 184 v = (ballot[q] || {}); 185 while(i = e.shift()) 186 { 187 if (this.form.elements[i]) 188 { 189 es = BX(this.form.elements[i]) ? [this.form.elements[i]] : this.form.elements[i]; 190 for (i = 0; i < es.length;i++) 191 { 192 if (v[es[i].value]) 193 { 194 es[i].checked = "checked"; 195 } 196 else 197 { 198 delete es[i].checked; 199 } 200 } 201 } 202 } 203 204 for (a in attach[q]["ANSWERS"]) 205 { 206 if (attach[q]["ANSWERS"].hasOwnProperty(a)) 207 { 208 an = attach[q]["ANSWERS"][a]; 209 if (an["FIELD_TYPE"] >= 4) 210 { 211 if (this.form.elements[an["MESSAGE_FIELD_NAME"]]) 212 this.form.elements[an["MESSAGE_FIELD_NAME"]].value = (ballot[q] && ballot[q][a] && ballot[q][a]["MESSAGE"] ? ballot[q][a]["MESSAGE"] : ""); 213 else 214 this.form.elements[an["FIELD_NAME"]].value = (ballot[q] && ballot[q][a] && ballot[q][a]["MESSAGE"] ? ballot[q][a]["MESSAGE"] : ""); 215 } 216 } 217 } 218 } 219 } 220 for (i in extras) 221 { 222 if (extras.hasOwnProperty(i) && 223 (q = (BX(this.form.elements[String(attachment["FIELD_NAME"]).replace("#ENTITY_ID#", i)])))) 224 { 225 if (q.value == extras[i]) 226 q.checked = true; 227 else 228 delete q.checked; 229 } 230 } 231 }, 232 adjustResults: function(attachment) { 233 var questions = attachment["QUESTIONS"]; 234 BX.onCustomEvent(this.node, 'OnBeforeChangeData'); 235 var question, answer, i, q, per, n; 236 for (q in questions) 237 { 238 if (questions.hasOwnProperty(q)) 239 { 240 question = BX.findChild(this.node, {"attr": {"id": "question" + q}}, true); 241 if (question) 242 { 243 for (i in questions[q]["ANSWERS"]) 244 { 245 if (questions[q]["ANSWERS"].hasOwnProperty(i)) 246 { 247 answer = BX.findChild(question, {"attr": {"data-bx-vote-answer": i}}, true); 248 if (!!answer) 249 { 250 per = parseInt(questions[q]["ANSWERS"][i]["PERCENT"]); 251 per = (isNaN(per) ? 0 : per); 252 n = BX.findChild(answer, {attribute: {"data-bx-vote-result" : "counter"}}, true); 253 BX.adjust(n, {"html" : questions[q]["ANSWERS"][i]["COUNTER"] + ""}); 254 delete n["VOTED_USER_OBJ"]; 255 BX.adjust(BX.findChild(answer, {"tagName" : "SPAN", attribute : {"data-bx-vote-result" : "percent"}}, true), 256 {"html" : per + '%'}); 257 BX.adjust(BX.findChild(answer, {"tagName" : "DIV", attribute : {"data-bx-vote-result" : "bar"}}, true), 258 {"style" : {"width" : per + '%'}}); 259 } 260 } 261 } 262 } 263 } 264 } 265 n = BX.findChild(this.node, {"tagName" : "DIV", attribute : {"data-bx-vote-result" : "counter"}}, true); 266 BX.adjust(n, {"html" : attachment["COUNTER"] + ""}); 267 BX.onCustomEvent(this.controller, 'OnAfterChangeData'); 268 }, 269 checkUsers : function(event) 270 { 271 var node = event ? BX(event.currentTarget) : null; 272 if (node.hasAttribute("data-bx-vote-answer")) 273 {
274 if (!node['VOTED_USER_OBJ']) 275 { 276 node.VOTED_USER_OBJ = new BVotedUser( 277 node.getAttribute("data-bx-vote-answer"), 278 node, 279 { 280 nameTemplate : this.params["nameTemplate"], 281 urlTemplate : this.params["urlTemplate"], 282 attachId : this.id 283 } 284 ); 285 } 286 node.VOTED_USER_OBJ.click(); 287 } 288 }, 289 checkMobileUsers : function(e) { 290 if (this.node && this.node.getAttribute("data-bx-vote-form") !== "shown") 291 { 292 var node = BX.proxy_context, 293 i = BX.findChild(node, {"tagName" : "A", attribute : {"data-bx-vote-result" : "counter"}}, true); 294 295 if (i && parseInt(i.innerHTML) > 0) 296 { 297 BX.PreventDefault(e); 298 app.openBXTable({ 299 url: BX.util.add_url_param(this.url, {action : "getMobileVoted", attachId : this.id, answerId : node.getAttribute("data-bx-vote-answer"), sessid : BX.bitrix_sessid()}), 300 TABLE_SETTINGS : { 301 markmode : false, 302 cache: false 303 } 304 }); 305 return false; 306 } 307 } 308 return true; 309 }, 310 showError : function(errors) { 311 var textError = ""; 312 if (BX.type.isArray(errors)) 313 { 314 var t = []; 315 for (var i = 0; i < errors.length; i++) 316 { 317 t.push(errors[i]["message"]) 318 } 319 t = t.join("<br />"); 320 textError = (t === "" ? "Unknown error" : t); 321 this.errorNode.innerHTML = textError; 322 this.node.setAttribute("data-bx-vote-error", "shown"); 323 } 324 else 325 { 326 this.errorNode.innerHTML = ""; 327 this.node.setAttribute("data-bx-vote-error", "hidden"); 328 } 329 } 330 }; 331 return d; 332 })(); 333 334 var BVotedUser = (function() 335 { 336 var d = function(answerId, target, params) 337 { 338 this.id = ['vote', answerId, new Date().getTime()].join('-'); 339 this.answerId = answerId; 340 this.node = target; 341 this.status = 'ready'; 342 this.iNumPage = 0; 343 344 this.urlTemplate = params["urlTemplate"]; 345 this.nameTemplate = params["nameTemplate"]; 346 this.attachId = params["attachId"]; 347 this.data = []; 348 this.queue = []; 349 this.popup = null; 350 this.popupScrollCheck = this.popupScrollCheck.bind(this); 351 }; 352 353 d.prototype = { 354 url: actionUrl, 355 click: function() 356 { 357 var votersCount = parseInt(this.node.innerHTML); 358 if (votersCount > 0) 359 { 360 this.showPopup() 361 .then(() => { 362 if (this.data.length > 0) 363 { 364 this.buildVoters(this.data); 365 } 366 }) 367 ; 368 } 369 }, 370 371 buildVoters: function(items) 372 { 373 var popupContainer = this.popup ? this.popup.getPopupContainer() : null; 374 if (popupContainer === null) 375 { 376 return; 377 } 378 379 var container = popupContainer.querySelector('.bx-ilike-popup'); 380 popupContainer.querySelector('.bx-ilike-wrap-block').removeAttribute('style'); 381 var changed = false; 382 items.forEach((voter) => { 383 var voterId = BX.util.htmlspecialchars(voter['ID']); 384 var voterName = BX.util.htmlspecialchars(voter['FULL_NAME']); 385 var voterPhoto = BX.type.isNotEmptyString(voter['PHOTO_SRC']) ? 386 encodeURI(BX.util.htmlspecialchars(voter['PHOTO_SRC'])) : null; 387 var voterType = BX.type.isNotEmptyString(voter['TYPE']) ? 388 BX.util.htmlspecialchars(voter['TYPE']) : null; 389 390 var answerId = ["a", this.answerId, "u", voterId].join(''); 391 if (container.querySelector('a#' + answerId) === null) 392 { 393 var html = [ 394 '<span class="bx-ilike-popup-avatar-new">', 395 '<img src="', (voterPhoto ?? '/bitrix/images/main/blank.gif'), 396 '" class="bx-ilike-popup-avatar-img', (voterPhoto ? '' : ' bx-ilike-popup-avatar-img-default'), 397 '" />', 398 '<span class="bx-ilike-popup-avatar-status-icon"></span>', 399 '</span>', 400 '<span class="bx-ilike-popup-name-new">', voterName, '</span>' 401 ].join(''); 402 403 container.appendChild( 404 BX.create(voter['ID'] !== "HIDDEN" && this.urlTemplate ? "A" : "SPAN", { 405 attrs: {id: answerId}, 406 props: { 407 href: this.urlTemplate.replace(/#(USER_ID|ID)#/i, voterId), 408 target: "_blank", 409 className: "bx-ilike-popup-img" + (voterType ? " bx-ilike-popup-img-" + voterType : "") 410 }, 411 html: html, 412 }) 413 ); 414 } 415 changed = true; 416 }); 417 418 if (changed) 419 { 420 this.popup.adjustPosition({forceBindPosition: true}); 421 this.popupScrollCheck({currentTarget: container}); 422 } 423 }, 424 425 makeError: function(errors) 426 { 427 var contentContainer = this.popup ? this.popup.getPopupContainer() : null; 428 if (contentContainer === null) 429 { 430 return; 431 } 432 433 var text = (errors || [{message: BX.message("VOTE_ERROR_DEFAULT")}]).map((item) => { 434 return item.message; 435 }).join(''); 436 contentContainer.innerHTML = '<div class="bx-vote-popup-error-block">
436' + text + '</div>'; 437 this.popup.adjustPosition({forceBindPosition: true}); 438 }, 439 440 showPopup: function() 441 { 442 return new Promise((resolve) => { 443 var popup = this.getPopup(); 444 popup.show(); 445 popup.setAngle({position:'bottom'}); 446 popup.adjustPosition({forceBindPosition: true}); 447 resolve(popup); 448 }) 449 }, 450 451 getPopup: function() 452 { 453 if (this.popup) 454 { 455 return this.popup; 456 } 457 458 this.popup = new BX.PopupWindow('bx-vote-popup-cont-' + this.id, this.node, { 459 lightShadow: true, 460 offsetTop: -2, 461 offsetLeft: 3, 462 autoHide: true, 463 closeByEsc: true, 464 cacheable: false, 465 bindOptions: {position: "top"}, 466 content: [ 467 '<span class="bx-ilike-wrap-block" style="display: none;">' + 468 '<span class="bx-ilike-popup"><span class="bx-ilike-bottom_scroll"></span></span>' + 469 '</span>', 470 '<span class="bx-ilike-wait"></span>' 471 ].join(''), 472 events: { 473 onFirstShow: () => { 474 this.send(); 475 BX.bind( 476 this.popup.contentContainer.querySelector('.bx-ilike-popup'), 477 'scroll' , 478 this.popupScrollCheck 479 ) 480 }, 481 onClose: () => { 482 this.popup = null; 483 } 484 } 485 }); 486 return this.popup; 487 }, 488 489 popupScrollCheck: function() 490 { 491 var container = this.popup ? this.popup.contentContainer : null; 492 if (container === null) 493 { 494 return; 495 } 496 497 var res = container.querySelector('.bx-ilike-popup'); 498 if ( 499 (res.scrollTop > (res.scrollHeight - res.offsetHeight) / 1.5) 500 || 501 container.offsetHeight > res.offsetHeight 502 ) 503 { 504 this.send(); 505 } 506 }, 507 508 send: function() 509 { 510 if (this.status !== 'ready') 511 { 512 if (this.status === 'busy') 513 { 514 this.queue.push(this.send.bind(this)); 515 } 516 else if (this.status === 'done') 517 { 518 this.finalize(); 519 } 520 return; 521 } 522 523 this.status = 'busy'; 524 525 BX.ajax({ 526 url: BX.util.add_url_param(this.url, {action: "getVoted", attachId: this.attachId, answerId: this.answerId}), 527 method: 'POST', 528 dataType: 'json', 529 data: { 530 iNumPage: (++this.iNumPage), 531 nameTemplate: this.nameTemplate, 532 sessid: BX.bitrix_sessid() 533 }, 534 onsuccess: function(data) 535 { 536 if (data && data.status === "success") 537 { 538 data = data.data; 539 540 this.buildVoters(data.items); 541 this.data = this.data.concat(data.items); 542 543 if (data["statusPage"] === "done" || data.items.length <= 0) 544 { 545 this.status = 'done'; 546 this.finalize(); 547 } 548 else 549 { 550 this.status = 'ready'; 551 var f = this.queue.shift(); 552 if (f) 553 { 554 f.call(this); 555 } 556 } 557 } 558 else 559 { 560 this.status = 'error'; 561 this.makeError(data.errors); 562 this.finalize(); 563 } 564 }.bind(this), 565 onfailure: function() 566 { 567 this.status = 'error'; 568 this.makeError(); 569 this.finalize(); 570 }.bind(this) 571 }); 572 }, 573 574 finalize: function() 575 { 576 this.queue = []; 577 var popupContainer = this.popup ? this.popup.getPopupContainer() : null; 578 if (popupContainer === null) 579 { 580 return; 581 } 582 583 popupContainer.querySelector('.bx-ilike-wait').style.display = "none"; 584 585 BX.unbind( 586 popupContainer.querySelector('.bx-ilike-popup'), 587 'scroll' , 588 this.popupScrollCheck 589 ); 590 } 591 }; 592 return d; 593 })(); 594})(window);
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.