1var domain_name = 'sokki\x2eor\x2ejp'; 2 3var http_url = 'https://sokki.or.jp'; 4var https_url = 'https://sokki.or.jp'; 5var php_path = '/_administrator/connector.php'; 6var connector = '/_administrator/connector.php'; 7var base_url = ''; 8var site_path = ''; 9var cookie_first_url = 'cms_first_url'; 10//ããã³ãã¨ã³ãAPIç¨Cookieè¨å®. 11if(location.href.match(/[\?|&]access_token=.+/)){ 12 let cookies = document.cookie.split(';'); 13 let expire = 24 * 60 * 60; 14 let is_static_cookie = false; 15 for (let ii = 0; ii < cookies.length; ii++) { 16 let cookie = cookies[ii]; 17 while (cookie.charAt(0) == ' ') { 18 cookie = cookie.substring(1, cookie.length); 19 } 20 let name = cookie.split('=')[0]; 21 let value = cookie.split('=')[1]; 22 if(name === 'static' && value === 'false'){ 23 is_static_cookie = true; 24 break; 25 } 26 } 27 if(!is_static_cookie){ 28 document.cookie = "static=false;max-age="+expire+"; path=/;secure=true;samesite=LAX"; 29 location.reload(); 30 } 31} 32 33window.addEventListener('load', function(event) { 34 if($('selecter') instanceof jQuery) { 35 jQuery.noConflict(); 36 } 37}); 38 39// Smart Phoneç¨ã¢ãã¤ã«ãµã¤ãã¸ã®ãªã³ã¯ 40var strUA = navigator.userAgent.toLowerCase(); 41var uach = navigator.userAgentData; 42 43Event.observe(window,'load',function(){ 44 if( !!document.getElementById('published') ) 45 { 46 if( strUA.match(/iphone/) || strUA.match(/ipod/) || strUA.match(/android/) || (uach && uach.mobile)) 47 { 48 var div = document.createElement('div'); 49 div.id = 'cmsMobileButton'; 50 div.style.textAlign = 'center'; 51 div.style.height = '50px'; 52 var a = document.createElement('a'); 53 a.href = 'https://sokki.or.jp/index.php?a=free_page/goto_mobile&referer='+encodeURI(location.href); 54 a.innerHTML = '表示ï¼ã¢ãã¤ã«'; 55 div.appendChild(a); 56 document.body.appendChild(div); 57 a.style.margin = '30px auto'; 58 a.style.padding = '5px 10px'; 59 a.style.border = '1px solid #233656'; 60 a.style.width = 'auto'; 61 a.style.color = '#ffffff'; 62 a.style.backgroundColor = '#394d68'; 63 a.style.backgroundImage = '-webkit-gradient(linear, left top, left bottom, from(#5e789f), to(#42566f))'; 64 a.style.fontSize = '12px'; 65 a.style.borderRadius = '4px'; 66 a.style.WebkitBorderRadius = '4px'; 67 a.style.textShadow = '#000000 0 -1px 1px'; 68 a.style.textDecoration = 'none'; 69 } 70 } 71}); 72var mobile = false; 73if( strUA.match(/iphone/) || strUA.match(/ipod/) || strUA.match(/ipad/) || strUA.match(/android/) || (uach && uach.mobile)) 74{ 75 mobile = true; 76 function pointerX(event) { 77 var docElement = document.documentElement; 78 body = document.documentElement || document.body || { scrollLeft: 0 }; 79 80 if (event.changedTouches) return (event.changedTouches[0].clientX + 81 (docElement.scrollLeft || body.scrollLeft) - 82 (docElement.clientLeft || 0)); 83 84 return event.pageX || (event.clientX + 85 (docElement.scrollLeft || body.scrollLeft) - 86 (docElement.clientLeft || 0)); 87 } 88 89 function pointerY(event) { 90 var docElement = document.documentElement; 91 body = document.documentElement || document.body || { scrollTop: 0 }; 92 93 if (event.changedTouches) return (event.changedTouches[0].clientY + 94 (docElement.scrollLeft || body.scrollLeft) - 95 (docElement.clientLeft || 0)); 96 97 return event.pageY || (event.clientY + 98 (docElement.scrollTop || body.scrollTop) - 99 (docElement.clientTop || 0)); 100 } 101} 102// do_action 103function do_action (act,title) { 104 self.location.href='?q='+act; 105 if(title != undefined ){ 106 var win = parent.Windows.getFocusedWindow(); 107 win.setTitle(title); 108 } 109} 110 111/* 112 * Ajax Request ( Return Scripts ) 113 * 114 *--------------------------------------------------------- */ 115 116/** 117 * ajax_eval ajaxã§connectorã¨éä¿¡ããã¬ã¹ãã³ã¹ãevalå®è¡ããã 118 * 119 * ajax_eval( string data, boolean async ) 120 * 121 * @param string ã¢ã¯ã·ã§ã³/ã¡ã½ããã®ãã©ã¡ã¼ã¿ï¼ex. site_manager/add_site ) 122 * @param boolean éåæãã©ã° true: éåæéä¿¡ false: åæéä¿¡ 123 * 124 * @return void 125 */ 126function ajax_eval( data, async ) 127{ 128 if( async == null ) async = true; 129 if( !data.match(/&q=/) ) data = '&q='+data; 130 new Ajax.Request(connector, { 131 method: 'post', 132 postBody : data, 133 asynchronous : async, 134 onSuccess : function(obj){ 135 if(obj.responseText){ 136 eval(obj.responseText); 137 } 138 }, 139 onFailure: function(obj){ 140 alert('ã¨ã©ã¼ãçºçãã¾ããã'); 141 } 142 }); 143} 144// function ajax_eval_debug( data, async ) 145// { 146// alert(connector); 147// alert(data);
148// if( async == null ) async = true; 149// if( !data.match(/&q=/) ) data = '&q='+data; 150// new Ajax.Request(connector, { 151// method: 'post', 152// postBody : data, 153// asynchronous : async, 154// onSuccess : function(obj){ 155// alert(obj.responseText); 156// if(obj.responseText){ 157// alert(obj.responseText); 158// eval(obj.responseText); 159// } 160// } 161// }); 162// } 163/** 164 * ajax_json_eval ajaxã§connectorã¨éä¿¡ããã¬ã¹ãã³ã¹ãJSONå½¢å¼ã§åå¾ãevalå®è¡ããã 165 * 166 * ajax_json_eval( string data ) 167 * 168 * @param string ã¢ã¯ã·ã§ã³/ã¡ã½ããã®ãã©ã¡ã¼ã¿ï¼ex. site_manager/add_site ) 169 * 170 * @return void 171 */ 172function ajax_json_eval( data ) { 173 if( !data.match(/&q=/) ) data = '&q='+data; 174 new Ajax.Request(connector, { 175 method: 'post', 176 postBody : data, 177 onSuccess : function(obj){ 178 if(obj.responseText){ 179 eval('ret='+obj.responseText); 180 if( ret.type == 'script' ) { 181 eval(ret.data); 182 } else { 183// alert(obj.responseText); 184 } 185 } 186 }, 187 onFailure: function(obj){ 188 alert('ã¨ã©ã¼ãçºçãã¾ããã'); 189 } 190 }); 191} 192 193/** 194 * ajax_callback ajaxã§ãµã¼ãã¼ã¨éä¿¡ããã¬ã¹ãã³ã¹ãã³ã¼ã«ããã¯é¢æ°ã«å¼æ¸¡ãããã 195 * 196 * ajax_callback( string data, string func, boolean async ) 197 * 198 * @param string ã¢ã¯ã·ã§ã³/ã¡ã½ããã®ãã©ã¡ã¼ã¿ï¼ex. site_manager/add_site ) 199 * @param string 颿°å 200 * @param boolean éåæãã©ã° true: éåæéä¿¡ false: åæéä¿¡ 201 * 202 * @return void 203 */ 204function ajax_callback( data, func, async ) { 205 if( async == null ) async = true; 206 if( !data.match(/&q=/) ) data = '&q='+data; 207 new Ajax.Request(connector, { 208 method: 'post', 209 postBody : data, 210 asynchronous : async, 211 onSuccess : eval(func), 212 onFailure: function(obj){ 213 alert('ã¨ã©ã¼ãçºçãã¾ããã'); 214 } 215 }); 216} 217 218/** 219 * ajax_callback_form_upload 220 * æ±ç¨Ajaxãã¡ã¤ã«ã¢ãããã¼ã颿°ï¼FormData + XMLHttpRequestçï¼ 221 * 222 * @param {string} query - ã³ã³ããã¼ã©ã¨ã¢ã¯ã·ã§ã³ã®ãã¹ï¼ä¾: 'host_manager/upload_backup/1'ï¼ 223 * @param {HTMLFormElement} form - <form> è¦ç´ 224 * @param {Object} options - ãªãã·ã§ã³: { onSuccess: func(result, form), onError: func(result, form) } 225 */ 226function ajax_callback_form_upload(query, form, options = {}) { 227 const url = connector + '?q=' + encodeURIComponent(query); 228 const formData = new FormData(form); 229 const xhr = new XMLHttpRequest(); 230 231 xhr.open('POST', url, true); 232 233 xhr.onload = function () { 234 if (xhr.status >= 200 && xhr.status < 300) { 235 let result; 236 try { 237 result = JSON.parse(xhr.responseText); 238 } catch (e) { 239 alert('ã¬ã¹ãã³ã¹ã®è§£æã«å¤±æãã¾ããã'); 240 return; 241 } 242 if (result.success) { 243 if (typeof options.onSuccess === 'function') { 244 options.onSuccess(result, form); 245 } 246 } else { 247 if (typeof options.onError === 'function') { 248 options.onError(result, form); 249 } 250 } 251 } else { 252 if (typeof options.onError === 'function') { 253 options.onError({ success: false, err_message: 'HTTPã¨ã©ã¼: ' + xhr.status }, form); 254 } else { 255 alert('HTTPã¨ã©ã¼ãçºçãã¾ããã'); 256 } 257 } 258 }; 259 260 xhr.onerror = function () { 261 if (typeof options.onError === 'function') { 262 options.onError({ success: false, err_message: 'éä¿¡ã¨ã©ã¼ãçºçãã¾ããã' }, form); 263 } else { 264 alert('éä¿¡ã¨ã©ã¼ãçºçãã¾ããã'); 265 } 266 }; 267 268 xhr.send(formData); 269} 270 271 272/** 273 * ajax_update ajaxã§ãµã¼ãã¼ã¨éä¿¡ããã¬ã¹ãã³ã¹ãæå®ããDOMã¨ã¬ã¡ã³ãã«æ¿å ¥ããã 274 * 275 * ajax_update( string data, string elm ) 276 * 277 * @param string ã¢ã¯ã·ã§ã³/ã¡ã½ããã®ãã©ã¡ã¼ã¿ï¼ex. site_manager/add_site ) 278 * @param object innerHTMLãç½®æããã¨ã¬ã¡ã³ãã®ID屿§å¤ 279 * 280 * @return void 281 */ 282function ajax_update( data, elm ){ 283 if( !data.match(/&q=/) ) data = '&q='+data; 284 new Ajax.Updater( 285 {success:elm}, 286 connector, { 287 method: "post", 288 postBody : data, 289 evalScripts: true, 290 onFailure:function(httpObj){ 291 alert('ã¨ã©ã¼ãçºçãã¾ããã');
292 $(elm).innerHTML = "Error!!"; 293 } 294 } 295 ); 296} 297 298/** 299 * ajax_eval ajaxã§connectorã¨éä¿¡ããã¬ã¹ãã³ã¹ãevalå®è¡ãããå ¬éãµã¤ãç¨ããã 300 * 301 * ajax_eval( string data, boolean async ) 302 * 303 * @param string ã¢ã¯ã·ã§ã³/ã¡ã½ããã®ãã©ã¡ã¼ã¿ï¼ex. site_manager/add_site ) 304 * @param boolean éåæãã©ã° true: éåæéä¿¡ false: åæéä¿¡ 305 * 306 * @return void 307 */ 308function ajax_eval_p( data, async ) 309{ 310 if( async == null ) async = true; 311 if( !data.match(/&a=/) ) { data = '&a='+data; } 312 new Ajax.Request('/index.php', 313 { 314 method: 'get', 315 parameters : data, 316 asynchronous : async, 317 onSuccess: function(obj) { 318 if(obj.responseText){ 319// alert(obj.responseText); 320 eval(obj.responseText); 321 } 322 }, 323 onFailure: function(obj){ 324 alert('ã¨ã©ã¼ãçºçãã¾ããã'); 325 } 326 }); 327} 328/** 329 * ajax_update_p ajaxã§ãµã¼ãã¼ã¨éä¿¡ããã¬ã¹ãã³ã¹ãæå®ããDOMã¨ã¬ã¡ã³ãã«æ¿å ¥ãããå ¬éãµã¤ãç¨ããã 330 * 331 * ajax_update_p( string data, string elm ) 332 * 333 * @param string ã¢ã¯ã·ã§ã³/ã¡ã½ããã®ãã©ã¡ã¼ã¿ï¼ex. site_manager/add_site ) 334 * @param object innerHTMLãç½®æããã¨ã¬ã¡ã³ãã®ID屿§å¤ 335 * 336 * @return void 337 */ 338function ajax_update_p( data, elm ) 339{ 340 if( !data.match(/&q=/) ) data = '&a='+data; 341 new Ajax.Updater( 342 {success:elm}, 343 '/index.php', { 344 method: "get", 345 parameters : data, 346 evalScripts: true, 347 onFailure:function(httpObj){ 348 $(elm).innerHTML = "Error!!"; 349 }, 350 onFailure: function(obj){ 351 alert('ã¨ã©ã¼ãçºçãã¾ããã'); 352 } 353 } 354 ); 355} 356 357function ajax_submit_p(form_obj){ 358 post_data = Form.serialize(form_obj); 359 new Ajax.Request('/index.php', { 360 method: 'post', 361 postBody : post_data, 362 onSuccess : function(obj){ 363 if(obj.responseText){ 364 eval(obj.responseText); 365 } 366 }, 367 onFailure: function(obj){ 368 alert('ã¨ã©ã¼ãçºçãã¾ããã'); 369 } 370 }); 371} 372 373/** 374 * ajax_dialog dataã§æå®ãããã©ã¡ã¼ã¿ã®ã¬ã¹ãã³ã¹ããã¤ã¢ãã°ã§éã 375 * 376 * ajax_dialog( string data, integer x, integer y ) 377 * 378 * @param string ã¢ã¯ã·ã§ã³/ã¡ã½ããã®ãã©ã¡ã¼ã¿ï¼ex. site_manager/add_site ) 379 * @param integer éããã¤ã¢ãã°ã®å¹ (px)ãããã©ã«ã480px 380 * @param integer éããã¤ã¢ãã°ã®é«ã(px)ãããã©ã«ã320px 381 * 382 * @return void 383 */ 384var mydialog; 385function trigger_outer_dialog_button_overlay(){ 386 var adminDialog = this.frameElement.closest('#admin_dialog'); 387 var outerDialogRowMid = adminDialog.querySelectorAll('#cms_dialog_rowmid')[0]; 388 var outerDialogButtonsOverlay = adminDialog.querySelectorAll('#hideButtons')[0]; 389 390 if (!!outerDialogButtonsOverlay) { 391 outerDialogRowMid.removeChild(outerDialogButtonsOverlay); 392 } else { 393 var span = document.createElement('span'); 394 span.id = 'hideButtons'; 395 span.style.display = 'inline-block'; 396 span.style.height = '50px'; 397 span.style.width = '1001px'; 398 span.style.background = '#fff'; 399 span.style.position = 'absolute'; 400 span.style.bottom ='-50px'; 401 span.style.left ='10px'; 402 span.style.zindex =10500; 403 outerDialogRowMid.appendChild(span); 404 } 405} 406function ajax_dialog(data,x,y,cb) 407{ 408 if( !data.match(/&q=/) ) data = '&q='+data; 409 if( !x ) x = 480; 410 if( !y ) y = 320; 411 if( typeof cb === "function"){ 412 cb(); 413 } 414 Dialog.info( 415 { 416 url: connector, 417 options: { 418 method: 'post', 419 postBody : data, 420 asynchronous : false, 421 evalScripts: true, 422 buttonClass: 'cms-btn' 423 } 424 }, 425 { 426 className:"alert", 427 width:x, 428 height:y, 429 zIndex:10000, 430 onClose:function(){ 431 if( typeof cb === "function"){ 432 cb(); 433 } 434 } 435 } 436 ); 437} 438 439/** 440 * ajax_submit Formãajaxã§POSTããçµæãevalå®è¡ãã 441 * 442 * ajax_submit( obj form ) 443 * 444 * @param obj ãã©ã¼ã ãªãã¸ã§ã¯ã 445 * â»ãã©ã¼ã å ã«<input type="hidden" name="do" value="ã¯ã©ã¹å/ã¡ã½ããå" />ã®è¨è¿°ãããã㨠446 * 447 * @return void 448 */ 449function ajax_submit(form_obj){ 450 post_data = Form.serialize(form_obj); 451 new Ajax.Request(connector, { 452 method: 'post', 453 postBody : post_data, 454 onSuccess : function(obj){ 455 if(obj.responseText){ 456 eval(obj.responseText); 457 } 458 }, 459 onFailure: function(obj){ 460 alert('ã¨ã©ã¼ãçºçãã¾ããã'); 461 } 462 }); 463} 464 465/** 466 * ajax_submit Formãajaxã§POSTããã¬ã¹ãã³ã¹ãæå®ããDOMã¨ã¬ã¡ã³ãã«æ¿å ¥ããã 467 * 468 * ajax_submit( string data, obj form, string elment) 469 * 470 * @param obj ãã©ã¼ã ãªãã¸ã§ã¯ã 471 * â»ãã©ã¼ã å ã«<input type="hidden" name="do" value="ã¯ã©ã¹å/ã¡ã½ããå" />ã®è¨è¿°ãããã㨠472 * 473 * @return void 474 */ 475function ajax_submit_update( data, formelm, elm ) { 476 if( !!$('easy_html') && !!oEditor ) { 477 $('easy_html').value = oEditor.GetXHTML(); 478 oEditor=null; 479 } else if ( !!$('cmp_html') && !!oEditor ) { 480 $('cmp_html').value = oEditor.GetXHTML(); 481 oEditor=null; 482 } 483 if( !data.match(/&q=/) ) data = '&q='+data+'&'+Form.serialize(formelm); 484 new Ajax.Updater( 485 {success:elm}, 486 connector, { 487 method: "post", 488 postBody : data, 489 evalScripts: true, 490 onFailure:function(httpObj){
491 $(elm).innerHTML = "Error!!"; 492 } 493 } 494 ); 495 return false; 496} 497 498/** 499 * alert_dialog ã¢ã©ã¼ããã¤ã¢ãã°ã表示ãã 500 * 501 * alert_dialog( string message[, integer height[, string function]] ) 502 * 503 * @param string ãã¤ã¢ãã°å ã«è¡¨ç¤ºããã¡ãã»ã¼ã¸ï¼HTMLå¯ï¼ 504 * @param integer ãã¤ã¢ãã°ã®é«ãï¼çç¥æ100px) 505 * @param string OKãã¿ã³æ¼ä¸æã«å®è¡ãã颿°åãããã¯å¿å颿°(function(){...}) 506 * 507 * @return void 508 */ 509function alert_dialog(msg, h, func) { 510 if( !h ) h = 150; 511 if(jQuery('#alert').length > 0) jQuery('#alert').attr('id','alert-bf'); 512 Dialog.alert(msg, { 513 windowParameters: {width:480, height:h, zIndex:1000000}, 514 className:"alert", 515 id:"alert", 516 okLabel: "OK", 517 ok: func, 518 buttonClass: 'cms-btn' 519 }); 520 setTimeout( function(){ 521 jQuery('#alert').find('.ok_button').focus(); 522 },100); 523} 524/** 525 * alert_dialog_reload ã¢ã©ã¼ããã¤ã¢ãã°ã表示ããOKãã¿ã³æ¼ä¸ã§ç»é¢ããªãã¼ããã 526 * 527 * alert_dialog_reload( string message[, integer height] ) 528 * 529 * @param string ãã¤ã¢ãã°å ã«è¡¨ç¤ºããã¡ãã»ã¼ã¸ï¼HTMLå¯ï¼ 530 * @param integer ãã¤ã¢ãã°ã®é«ãï¼çç¥æ100px) 531 * 532 * @return void 533 */ 534function alert_dialog_reload(msg, h) { 535 if( !h ) h = 150; 536 if(jQuery('#alert').length > 0) jQuery('#alert').attr('id','alert-bf'); 537 Dialog.alert(msg, { 538 windowParameters: {width:480, height:h, zIndex:1000000}, 539 className:"alert", 540 id:"alert", 541 okLabel: "OK", 542 buttonClass: 'cms-btn', 543 ok: function(){ location.reload(); } 544 }); 545} 546/** 547 * confirm_dialog 確èªãã¤ã¢ãã°ã表示ãã 548 * 549 * confirm_dialog( string message[, integer height[, string function]] ) 550 * 551 * @param string ãã¤ã¢ãã°å ã«è¡¨ç¤ºããã¡ãã»ã¼ã¸ï¼HTMLå¯ï¼ 552 * @param integer ãã¤ã¢ãã°ã®é«ãï¼çç¥æ100px) 553 * @param string OKãã¿ã³æ¼ä¸æã«å®è¡ãã颿°åãããã¯å¿å颿°(function(){...}) 554 * 555 * @return void 556 */ 557function confirm_dialog(msg, func, h) { 558 if( !h ) h = 150; 559 if(jQuery('#alert').length > 0) jQuery('#alert').attr('id','alert-bf'); 560 Dialog.confirm(msg, { 561 windowParameters: {width:480, height:h, zIndex:1000000, duration:0.1}, 562 className:"alert", 563 id:"alert", 564 okLabel: "OK", 565 ok:func, 566 cancelLabel: "ãã£ã³ã»ã«", 567 buttonClass: "cms-btn", 568 cancel:function(){Dialog.closeInfo();} 569 }); 570} 571/** 572 * confirm_dialog_update 確èªãã¤ã¢ãã°ã表示ããOKãã¿ã³æ¼ä¸ã§ãµã¼ãã¼ã¨ajaxéä¿¡ãã¬ã¹ãã³ã¹ãæå®ããDOMã¨ã¬ã¡ã³ãã«æ¿å ¥ããã 573 * 574 * confirm_dialog_update( string message, string data, string element[, integer height] ) 575 * 576 * @param string ãã¤ã¢ãã°å ã«è¡¨ç¤ºããã¡ãã»ã¼ã¸ï¼HTMLå¯ï¼ 577 * @param string ã¢ã¯ã·ã§ã³/ã¡ã½ããã®ãã©ã¡ã¼ã¿ï¼ex. site_manager/add_site ) 578 * @param object innerHTMLãç½®æããã¨ã¬ã¡ã³ãã®ID屿§å¤ 579 * @param integer ãã¤ã¢ãã°ã®é«ãï¼çç¥æ100px) 580 * 581 * @return void 582 */ 583function confirm_dialog_update(msg, data, elm, h) { 584 if( !h ) h = 150; 585 if(jQuery('#alert').length > 0) jQuery('#alert').attr('id','alert-bf'); 586 Dialog.confirm(msg, { 587 windowParameters: {width:320, height:h, zIndex:1000000}, 588 className:"alert", 589 id:"alert", 590 okLabel: "OK", 591 cancelLabel: "ãã£ã³ã»ã«", 592 buttonClass: "cms-btn", 593 ok:function(){ajax_update(data,elm);Dialog.closeInfo();}, 594 cancel:function(){Dialog.closeInfo();} 595 }); 596 597} 598/** 599 * info_dialog æ å ±ãã¤ã¢ãã°ã表示ãã 600 * 601 * info_dialog( string message[, integer width][, integer height][, boolean progress] ) 602 * 603 * @param string ãã¤ã¢ãã°å ã«è¡¨ç¤ºããã¡ãã»ã¼ã¸ï¼HTMLå¯ï¼ 604 * @param integer ãã¤ã¢ãã°ã®å¹ ï¼çç¥æ320px) 605 * @param integer ãã¤ã¢ãã°ã®é«ãï¼çç¥æ100px) 606 * @param boolean ãã¤ã¢ãã°å ã«ããã°ã¬ã¹ã¢ã¤ã³ã³ã表示ãããå¦ã 607 * 608 * @return void 609 */ 610function info_dialog(msg, w, h, progress) { 611 if( !w ) w = 320; 612 if( !h ) w = 150; 613 if( progress !== false ) progress = true; 614 if(jQuery('#alert').length > 0) jQuery('#alert').attr('id','alert-bf'); 615 Dialog.info(msg, { 616 className:"alert", 617 id:"alert", 618 buttonClass: 'cms-btn', 619 windowParameters: {width:w, height:h, zIndex:1000000}, 620 showProgress:progress 621 }); 622} 623function sub_dialog(msg,x,y) { 624 if( !x ) x = 320; 625 if( !y ) y = 100; 626 if(jQuery('#alert').length > 0) jQuery('#alert').attr('id','alert-bf'); 627 Dialog.info(msg, { 628 className:"alert", 629 id:"alert", 630 buttonClass: 'cms-btn', 631 windowParameters: {width:x, height:y, zIndex:1000000}, 632 showProgress:false 633 }); 634} 635function sub_dialog_for_ad(msg,x,y) { 636 if( !x ) x = 320; 637 if( !y ) y = 100; 638 if(jQuery('#alert').length > 0) jQuery('#alert').attr('id','alert-bf'); 639 Dialog.info(msg, { 640 className:"alert", 641 id:"dialog", 642 buttonClass: 'cms-btn', 643 windowParameters: {width:x, height:y, zIndex:1000000}, 644 showProgress:false 645 }); 646} 647/** 648 * close_dialog æ å ±ãã¤ã¢ãã°ã®ã¡ãã»ã¼ã¸ã夿´ãã¦1.5ç§å¾ã«éãã 649 * 650 * close_dialog( string message ) 651 * 652 * @param string ãã¤ã¢ãã°å ã«è¡¨ç¤ºããã¡ãã»ã¼ã¸ï¼HTMLå¯ï¼ 653 * 654 * @return void 655 */ 656function close_dialog(msg) { 657 if(jQuery('#modal_dialog_message').length > 0){ 658 Dialog.setInfoMessage(msg); 659 } else { 660 jQuery('.alert_message').html(msg); 661 jQuery('.alert_buttons').html(''); 662 } 663 setTimeout("Dialog.closeInfo()", 1500); 664} 665/** 666 * set_message æ å ±ãã¤ã¢ãã°ã®ã¡ãã»ã¼ã¸ã夿´ãã 667 * 668 * set_message( string message ) 669 * 670 * @param string ãã¤ã¢ãã°å ã«è¡¨ç¤ºããã¡ãã»ã¼ã¸ï¼HTMLå¯ï¼ 671 * 672 * @return void 673 */ 674function set_message(msg,loading){ 675 if(jQuery('#modal_dialog_message').length > 0){ 676 Dialog.setInfoMessage(msg); 677 } else { 678 jQuery('.alert_message').html(msg); 679 jQuery('.alert_buttons').html(''); 680 if(loading){ 681 jQuery('.alert_buttons').html("<div id='modal_dialog_progress' class='alert_progress'> </div>"); 682 } 683 } 684} 685/** 686 * result_message éãã¦ãããã¤ã¢ãã°ã«ã¡ãã»ã¼ã¸ã¨éãããã¿ã³ãã»ãããã 687 * 688 * result_message( string message ) 689 * 690 * @param string ãã¤ã¢ãã°å ã«è¡¨ç¤ºããã¡ãã»ã¼ã¸ï¼HTMLå¯ï¼ 691 * 692 * @return void 693 */ 694function result_message(msg,okscript){ 695 if(okscript.length==0) okscript = 'Dialog.closeInfo()'; 696 var content = "<div class='alert_message'>" + msg + "</div>" 697 + "<div class='alert_buttons'>" 698 + "<input type='button' value='OK' onclick='" + okscript + "' class='cms-btn'/>"
699 + "</div>"; 700 if(jQuery('#modal_dialog_message').length > 0){ 701 Dialog.setInfoMessage(content); 702 } else { 703 jQuery('#alert_content').html(content); 704 } 705} 706/** 707 * set_size_dialog ãã¤ã¢ãã°ã®ãµã¤ãºã夿´ãã 708 * 709 * set_size_dialog( string element_id ) 710 * 711 * @param string ã¨ã¬ã¡ã³ãIDããããã¯ãªãã¸ã§ã¯ã 712 * 713 * @return void 714 */ 715function set_size_dialog(w,h) 716{ 717 var winobj = self.Windows.getFocusedWindow(); 718 if( winobj === null ) return; 719 winobj.setSize(w,h); 720 winobj.showCenter(); 721} 722/** 723 * toggle ã¨ã¬ã¡ã³ãã®è¡¨ç¤º/é表示ãåãæ¿ãã 724 * 725 * toggle( string element_id ) 726 * 727 * @param string ã¨ã¬ã¡ã³ãIDããããã¯ãªãã¸ã§ã¯ã 728 * 729 * @return void 730 */ 731function toggle(elm) 732{ 733 if( Element.visible(elm) ) 734 { 735 $(elm).hide(); 736 } 737 else 738 { 739 $(elm).show(); 740 } 741} 742 743function set_cookie(keyname, data, expire_flag) 744{ 745 theDay = 1; 746 setDay = new Date(); 747 setDay.setTime(setDay.getTime()+(theDay*1000*60*60*24)); 748 expDay = setDay.toGMTString(); 749 val = get_cookie(keyname); 750 if( val !== '' ) { 751 if(keyname === 'error_report'){ 752 val = escapeRegExp(encodeURIComponent(val)); 753 }else{ 754 val = encodeURIComponent(val); 755 } 756 var re = new RegExp(encodeURIComponent(keyname) + "="+ val +";"); 757 document.cookie.replace(re,''); 758 } 759 if( expire_flag === true) { 760 document.cookie = encodeURIComponent(keyname) + "="+encodeURIComponent(data)+"; expires=" + _raw(expDay) + "; path=/"; 761 } else { 762 document.cookie = encodeURIComponent(keyname) + "="+encodeURIComponent(data)+ "; path=/"; 763 } 764} 765 766function escapeRegExp(string) { 767 // ç¹æ®æåãã¨ã¹ã±ã¼ã 768 return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); 769} 770 771function get_cookie(keyname) 772{ 773 theData = ""; 774 theName = encodeURIComponent(keyname)+"="; 775 theCookie = document.cookie+";"; 776 start = theCookie.indexOf(theName); 777 if (start != -1) 778 { 779 end = theCookie.indexOf(";",start); 780 theData = decodeURIComponent(theCookie.substring(start+theName.length,end)); 781 } 782 return theData; 783} 784 785 786function open_dialog(url, x, y, title, status, modal, dialog_name, reload ) 787{ 788 if( typeof context_menu == 'object' ) context_menu.oncontextmenu_hide(); 789 if( !url ) return false; 790 if( !x ) x = '1000'; 791 if( !y ) y = '640'; 792 var scr = screenInfomation(); 793 y = scr.nowHeight - 30; 794 if( x.toString().match(/([0-9]+)%/) ) { 795 ratio = RegExp.$1 / 100; 796 x = Math.floor(get_brouser_width() * ratio); 797 } 798 if( x > get_brouser_width() ) { 799 x = Math.floor(get_brouser_width() * 0.95); 800 } 801 // y = eval(y)+30; 802 if( !title ) title = ''; 803 if( !status ) status = ''; 804 if( !modal ) modal = true; 805 if( !dialog_name ) dialog_name = 'admin_dialog'; 806 if( !reload ) reload = false; 807 jQuery('#overlay_modal').remove(); 808 jQuery('#admin_dialog').remove(); 809 var win = new Window(dialog_name,{ 810 url:url, 811 className: 'dialog', 812 destroyOnClose: true, 813 width:x, 814 height:y, 815 zIndex: 100005, 816 resizable: true, 817 minimizable: false, 818 maximizable: false, 819 title: title, 820 recenterAuto: true, 821 /*hideEffect: Effect.SwitchOff,*/ 822 // parent: document.getElementById('cms_contents_area'), 823 draggable:true, 824 wiredDrag: false, 825 showEffectOptions:{duration:0.1}, 826 hideEffectOptions:{duration:0}, 827 duration:0, 828 onResize:function(){ 829 try{ 830 var parent = parent; 831 var p = parent.document; 832 }catch(e){ 833 var parent = window; 834 } 835 if( !parent.Windows ) return; 836 var winobj = parent.Windows.getFocusedWindow(); 837 if( winobj === null ) return; 838 // ãã¤ã¢ãã°å¤å´ã®ãµã¤ãº 839 var size = winobj.getSize(); 840 // ã¹ã¯ãªã¼ã³ã®ç¾å¨ã®ãµã¤ãº 841 var scr = screenInfomation(); 842 // ãã¤ã¢ãã°ã®ã¤ã³ã©ã¤ã³ãã¬ã¼ã å ã³ã³ãã³ãã®é«ã 843 var h = 240; 844 if( document.body && document.body.offsetHeight ) { 845 h = document.body.offsetHeight; 846 } else if ( document.documentElement && document.documentElement.offsetHeight ) { 847 h = document.documentElement.offsetHeight; 848 } 849 // ãã¤ã¢ãã°ã®ããã+ããã¿ã®é«ã 850 if( !!parent.$('admin_dialog_row1') && !!parent.$('admin_dialog_row3') && !!parent.$('cms_dialog_ctrl_td') ) { 851 var hof = parent.Element.getDimensions('admin_dialog_row1').height + parent.Element.getDimensions('admin_dialog_row3').height + parent.jQuery('#cms_dialog_rowmid').height(); 852 //æä½éã®ã¦ã¤ã³ãã¦ã®é«ãã®ãã¼ã¸ã³ï¼ããã£ã½ï¼ 853 var min_h_margin = 15; 854 if( h > scr.nowHeight - hof - min_h_margin*2 || 1 ) h = scr.nowHeight - hof - min_h_margin*2 ; 855 winobj.setSize(size['width'],h); 856 size = winobj.getSize(); 857 real_height = size.height + winobj.heightS + winobj.heightN; 858 x = ((scr.width/2) - size.width/2); 859 y = min_h_margin;//(( scr.nowHeight - (real_height+hof) )/2 + scr.y + min_h_margin * 2);// - jQuery(window).scrollTop() ; 860 winobj.showCenter(null,y,x); 861 } 862 863 $('admin_dialog_content').height = $('admin_dialog_table_content').height; 864 var $iframe = jQuery($('admin_dialog_content').contentWindow.document); 865 var frameHeight = jQuery('#admin_dialog_table_content').height(); 866 var height = frameHeight-$iframe.find('#cms_navigation_main .cms-navigation-wrap--head').height(); 867 $iframe.find('.cms-navigation-wrap__sub-scroll').height(height); 868 var addHeight = 0; 869 if($iframe.find('.cms-navigation-nav__table').length > 0 ){ 870 addHeight = $iframe.find('.cms-navigation-nav__table').css('padding').replace('px','') * 2; 871 } 872 if($iframe.find('.cms-navigation-wrap__main').length > 0){ 873 addHeight += $iframe.find('.cms-navigation-wrap__main').height(); 874 } 875 if($iframe.find('#cms_navigation_main .cms-table-list--scroll').length > 0){ 876 addHeight += $iframe.find('#cms_navigation_main .cms-table-list--scroll').height(); 877 } 878 var height = frameHeight - addHeight; 879 $iframe.find('#cms_navigation_list').height(height); 880 jQuery($('admin_dialog_content').contentWindow.document).find('#cms_dialog_container').height(jQuery('#admin_dialog_table_content').height()); 881 jQuery($('admin_dialog_content').contentWindow.document.html).height($('admin_dialog_table_content').height); 882 jQuery($('admin_dialog_content').contentWindow.document).find('iframe').each(function(){ 883 if( this.id && this.parentNode.tagName != 'TD' && jQuery(this).position().top > 0) { 884 jQuery(this).height(jQuery('#admin_dialog_content').height()-jQuery(this).position().top); 885 } 886 }); 887 }, 888 onMaximize:function(){ 889 // $('admin_dialog_content').height = $('admin_dialog_table_content').height; 890 // jQuery($('admin_dialog_content').contentWindow.document).find('#cms_navigation_list').height(jQuery('#admin_dialog_table_content').height()-jQuery($('admin_dialog_content').contentWindow.document).find('#cms_navigation_main>.cms_list_table').height()); 891 // jQuery($('admin_dialog_content').contentWindow.document).find('#cms_dialog_container').height(jQuery('#admin_dialog_table_content').height()); 892 // jQuery($('admin_dialog_content').contentWindow.document.html).height($('admin_dialog_table_content').height); 893 // jQuery($('admin_dialog_content').contentWindow.document).find('iframe').each(function(){ 894 // if( this.id && this.parentNode.tagName != 'TD' && jQuery(this).position().top > 0 ) { 895 // jQuery(this).height(jQuery('#admin_dialog_content').height()-jQuery(this).position().top); 896 // } 897 // }); 898 }, 899 onload:function(){ 900 if(jQuery('#admin_dialog .dialog_close').find('svg').length == 0 ){ 901 var svg = '<a class="cms-dialog-top-close">' 902 +'<svg class="icon--color-dark">' 903 +'<use xlink:href="/_administrator/css/default/images/svg/symbol-defs.svg#icon-close"></use>' 904 +'</svg></a>'; 905 jQuery('#admin_dialog .dialog_close').css('background','none').append(svg); 906 } 907 $('admin_dialog_content').height = $('admin_dialog_table_content').height; 908 var $iframe = jQuery($('admin_dialog_content').contentWindow.document); 909 var frameHeight = jQuery('#admin_dialog_table_content').height(); 910 var height = frameHeight-$iframe.find('#cms_navigation_main .cms-navigation-wrap--head').height(); 911 $iframe.find('.cms-navigation-wrap__sub-scroll').height(height); 912 var addHeight = 0; 913 if($iframe.find('.cms-navigation-nav__table').length > 0 ) addHeight = $iframe.find('.cms-navigation-nav__table').css('padding').replace('px','') * 2; 914 // var height = frameHeight-$iframe.find('#cms_navigation_main>.cms-table-list').height()-$iframe.find('#cms_navigation_main .cms-navigation-wrap--head').height() - addHeight; 915 // var height = frameHeight-$iframe.find('.cms-navigation-wrap__main').height()-$iframe.find('#cms_navigation_main .cms-table-list').height() - addHeight - 200; 916 var addHeight = 0; 917 if($iframe.find('.cms-navigation-nav__table').length > 0 ){ 918 addHeight = $iframe.find('.cms-navigation-nav__table').css('padding').replace('px','') * 2; 919 } 920 if($iframe.find('.cms-navigation-wrap__main').length > 0){ 921 addHeight += $iframe.find('.cms-navigation-wrap__main').height(); 922 } 923 if($iframe.find('#cms_navigation_main .cms-table-list--scroll').length > 0){ 924 addHeight += $iframe.find('#cms_navigation_main .cms-table-list--scroll').height(); 925 } 926 var height = frameHeight - addHeight; 927 $iframe.find('#cms_navigation_list').height(height); 928 jQuery($('admin_dialog_content').contentWindow.document).find('#cms_dialog_container').height(jQuery('#admin_dialog_table_content').height()); 929 jQuery($('admin_dialog_content').contentWindow.document.html).height($('admin_dialog_table_content').height); 930 jQuery($('admin_dialog_content').contentWindow.document).find('iframe').each(function(){ 931// console.log(jQuery(this).position().top); 932 if( this.id && this.parentNode.tagName != 'TD' && jQuery(this).position().top > 0) { 933 jQuery(this).height(jQuery('#admin_dialog_content').height()-jQuery(this).position().top); 934 } 935 }); 936 // jQuery.get('https://manual-v3.secure-cms.net/category.php?c='+win.options.title,function(c){ 937 // if(c && jQuery('.cms-helpsite-btn').length == 0){ 938 // var html = '' 939 // // +'<a href="#" onclick="alert(1);" class="">' 940 // +'<a href="#" style="z-index:1000000" onclick="alert(1);/* OpenSubWin(\'/_administrator/editor/help'+c+'\', 767, 860,\'help\');*/" class="cms-helpsite-btn cms-dialog-top-help">' 941 // // + "testwerwerwerwerwrwwe</a>"; 942 // +'<svg class="icon--color-dark" onclick="alert(2);">' 943 // +'<use xlink:href="/_administrator/css/default/images/svg/symbol-defs.svg#icon-help"></use>' 944 // +'</svg></a><script>alert(3);</script>'; 945 // // jQuery('#admin_dialog_top').append(html); 946 // var a = document.createElement('span'); 947 // a.href="javascript:;"; 948 // a.className = 'cms-helpsite-btn cms-dialog-top-help'; 949 // a.onclick = function(){ OpenSubWin('/_administrator/editor/help'+c,767,860,'help'); return false; }; 950 // a.onmousedown = function(){ event.stopPropagation();}; 951 // var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); 952 // svg.setAttribute("xmlns", "http://www.w3.org/2000/svg"); 953 // svg.setAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink"); 954 // svg.setAttribute("class", "icon--color-dark"); 955 // svg.innerHTML = '<use xlink:href="/_administrator/css/default/images/svg/symbol-defs.svg#icon-help"></use>'; 956 // a.append(svg); 957 // jQuery('#admin_dialog_top').append(a); 958 // // jQuery('.cms-dialog-top-help').on('click', function(event) { 959 // // console.log('test'); 960 // // OpenSubWin('/_administrator/editor/help'+c+'/', 767, 860,'help'); 961 // // return false; 962 // // }); 963 // } 964 // }); 965 } 966 }); 967 if( status ) win.setStatusBar(status); 968 if( !reload ) win.setCloseCallback(windowReload); 969 if( mobile ) 970 { 971 win.show(modal); 972 } else { 973 win.showCenter(modal); 974 } 975 // win.setURL(url); 976 set_cookie(cookie_first_url, url); 977} 978 979//sidebar.class.phpã«ç§»å.
980/* 981var barid = "_cms_sidebar"; 982function open_side_bar(url, title, position) 983{ 984 var sidebar = '<div id="'+barid+'"></div>'; 985 if(url.match(/open_sidebar_for_parts/)) 986 jQuery('html').css("overflow","hidden"); 987 jQuery.ajax(url,{ 988 type: 'get', 989 dataType: 'text', 990 cache: false, 991 timeout: 7000 992 }).done(function(data){ 993 //console.log(data); 994 if(data == 'error') 995 { 996 alert_dialog('éä¿¡ã¨ã©ã¼ãçºçãã¾ãããå度ã試ããã ããã'); 997 jQuery('html').css("overflow","auto"); 998 context_menu.init(); 999 return false; 1000 } 1001 1002 context_menu.clear_event(); 1003 if(jQuery('.cms-mouseover-infobox').length != 0) 1004 jQuery('.cms-mouseover-infobox').remove(); 1005 1006 if(jQuery('#'+barid).length == 0) 1007 jQuery('body').append(sidebar); 1008 jQuery('#'+barid).css({'position':'fixed','top':'0','z-index':'100001'}); 1009 jQuery('#'+barid).css(position,'0'); 1010 jQuery('#'+barid).html(data); 1011 1012 if(jQuery('i.fa-times').length != 0) 1013 { 1014 jQuery('i.fa-times').on('click', function() { 1015 jQuery('#'+barid).remove(); 1016 jQuery('html').css("overflow","auto"); 1017 context_menu.init(); 1018 }); 1019 } 1020 }).fail(function() { 1021 alert_dialog('éä¿¡ã¨ã©ã¼ãçºçãã¾ãããå度ã試ããã ããã'); 1022 jQuery('html').css("overflow","auto"); 1023 context_menu.init(); 1024 return false; 1025 }); 1026 set_cookie(cookie_first_url, url); 1027} 1028*/ 1029/*Cookie Consent Banner*/ 1030function cookie_callback(response) { 1031 var message = response[0].cookie_consent_message; 1032 var cookie_consent = localStorage.getItem('_cms_cookie_consent'); 1033 var display_flag = response[0].cookie_consent_popup_flag; 1034 1035 if(display_flag === '1' && cookie_consent === null){ 1036 display_cookie_banner(message); 1037 } else if(display_flag === '1' && new Date().getTime() > JSON.parse(cookie_consent).dateExpire){ 1038 display_cookie_banner(message); 1039 } else { 1040 return false; 1041 } 1042} 1043 1044function display_cookie_banner(usermessage) { 1045 var bodies = document.querySelectorAll('body'); 1046 var body; 1047 for(var ii=0;ii<bodies.length;ii++){ 1048 if(bodies[ii].id !== 'dialog'){ 1049 body = bodies[ii]; 1050 break; 1051 } 1052 } 1053 1054 if (!!body && body.querySelectorAll('#cms_cookieBanner').length < 1 ) { 1055 var banner = document.createElement('div'); 1056 var closeContainer = document.createElement('div'); 1057 var closeButton = document.createElement('button'); 1058 var closeIcon = document.createElement('span'); 1059 var textContainer = document.createElement('div'); 1060 var acceptButtonContainer = document.createElement('div'); 1061 var acceptButton = document.createElement('button'); 1062 1063 banner.id = 'cms_cookieBanner'; 1064 //banner.className = 'background--color-primary'; 1065 //banner.style.minHeight = '150px'; 1066 //banner.style.position = 'fixed'; 1067 //banner.style.right = '0'; 1068 //banner.style.bottom = '0'; 1069 //banner.style.width = '100%'; 1070 //banner.style.zIndex = '10000'; 1071 //closeContainer.style.padding = '10px'; 1072 //closeContainer.style.cursor = 'pointer'; 1073 //closeContainer.style.width = '36px'; 1074 //closeContainer.style.float = 'right'; 1075 closeContainer.id = 'cms_cookieclose'; 1076 closeContainer.addEventListener("click", set_consent_cookie); 1077 closeButton.type = 'button'; 1078 //closeButton.className = 'close'; 1079 closeIcon.innerHTML = '×';
1080 textContainer.className = 'cms_cookieMessage'; 1081 textContainer.innerHTML = usermessage; 1082 //textContainer.style.textAlign = 'center'; 1083 //textContainer.style.paddingTop = '20px'; 1084 //textContainer.style.paddingBottom = '20px'; 1085 acceptButtonContainer.id ='cms_cookieaccept_container'; 1086 acceptButton.innerHTML = 'åæãã'; 1087 acceptButton.type = 'button'; 1088 acceptButton.className = 'btn'; 1089 acceptButton.id ='cms_cookieaccept'; 1090 acceptButton.addEventListener("click", set_consent_cookie); 1091 body.appendChild(banner); 1092 banner.appendChild(closeContainer); 1093 banner.appendChild(textContainer); 1094 banner.appendChild(acceptButtonContainer); 1095 acceptButtonContainer.appendChild(acceptButton); 1096 closeContainer.appendChild(closeButton); 1097 closeButton.appendChild(closeIcon); 1098 } 1099} 1100 1101function set_consent_cookie(e) { 1102 var cms_cookie_consent; 1103 var cookieBanner = jQuery('body #cms_cookieBanner'); 1104 var now = new Date().getTime(); 1105 var oneYearFromNow = new Date(new Date().setFullYear(new Date().getFullYear() + 1)).getTime(); 1106 1107 if(e.target.id === 'cms_cookieaccept') { 1108 cms_cookie_consent = { userCookieConsent: true, consentDate: now, dateExpire: oneYearFromNow }; 1109 localStorage.setItem('_cms_cookie_consent', JSON.stringify(cms_cookie_consent)); 1110 } else if (e.target.matches('#cms_cookieclose') || e.target.matches('#cms_cookieclose *')) { 1111 cms_cookie_consent = {userCookieConsent: false, consentDate: null, dateExpire: now}; 1112 localStorage.setItem('_cms_cookie_consent', JSON.stringify(cms_cookie_consent)); 1113 } 1114 cookieBanner.fadeOut('slow'); 1115} 1116 1117var get_cookie_banner_settings = (function(){ 1118 var executed = false; 1119 return function(){ 1120 if(!executed){ 1121 executed = true; 1122 jQuery.ajax({ 1123 type: "GET", 1124 dataType: "json", 1125 url: "/index.php?a=free_page/get_cookie_policy_setting/" 1126 }).done((data) => { 1127 cookie_callback(data); 1128 }).fail((data) => { 1129 //console.log('fail'); 1130 //console.log(data.statusText, ' has occurred'); 1131 }); 1132 } 1133 } 1134})(); 1135//get_cookie_banner_settings(); 1136 1137var reload_flag=false; 1138function windowReload(param) 1139{ 1140 param.options.url=false; 1141 /*location.reload();*/ 1142 if( reload_flag !== false ) 1143 { 1144 if( reload_flag === 'ajax' ) 1145 { 1146 info_dialog('æ´æ°ä¸...', 200, 100, true); 1147 new Ajax.Updater( 1148 {success:'cms_contents_area'}, 1149 location.href, { 1150 method: "get", 1151 parameters : 'cmsmode=reload', 1152 evalScripts: true, 1153 onFailure:function(httpObj){ 1154 $(elm).innerHTML = "Error!!"; 1155 }, 1156 onSuccess:function(httpobj){ 1157 /* 1158 setTimeout(function(){ 1159 Dialog.closeInfo(); 1160 const contents = document.querySelector('body #sitedesign-pagetop'); 1161 if(contents){ 1162 contents.style.opacity = '1'; 1163 } 1164 },1200); 1165 */ 1166 Dialog.closeInfo(); 1167 } 1168 } 1169 ); 1170 reload_flag = false; 1171 } else if( reload_flag === true || reload_flag === 'reload' ) { 1172 location.reload(); 1173 } 1174 } 1175 if( typeof context_menu == 'object' ) context_menu.init(); 1176 return true; 1177} 1178function windowClose() 1179{ 1180 return true; 1181} 1182var debug = { 1183 win: null, 1184 p: function(str){ 1185 if( !debug.win ) { 1186 debug.o(); 1187 } 1188 debug.win.document.write(str+"<br>"); 1189 }, 1190 o: function(){ 1191 debug.win = window.open('about:blank','debug','width=300,height=300,resizable=yes'); 1192 } 1193}; 1194var target_element=null; 1195function showFileManager(dir, element_name, easy_edit_mode=null){ 1196 if(typeof context_menu !== 'undefined' && easy_edit_mode != null){ 1197 context_menu.easy_edit_mode = easy_edit_mode; 1198 } 1199 if( !element_name ) element_name = null; 1200 target_element = element_name; 1201 var url = "/_administrator/editor/FCKeditor/editor/filemanager/browser/mcpuk/browser.html?Type=File&Connector=connectors/php/connector.php"; 1202 if( dir ){ 1203 url += '&CurrentFolder=' + dir.replace(/\/+/,"/"); 1204 } else if( get_cookie('close_file_dir') !== '' ) { 1205 url += '&CurrentFolder=' + get_cookie('close_file_dir').replace(/\/+/,"/"); 1206 } 1207 x=800; 1208 y=600; 1209 x = screen.width * .7; 1210 y = (screen.height - 50) * .8; 1211 OpenSubWin(url,x,y,'server_browser'); 1212} 1213function showImageManager(dir, element_name, easy_edit_mode=null){ 1214 if(typeof context_menu !== 'undefined' && easy_edit_mode != null){ 1215 context_menu.easy_edit_mode = easy_edit_mode; 1216 } 1217 if( !element_name ) element_name = null; 1218 target_element = element_name; 1219 if (element_name !== null && element_name.startsWith('cf-')){ 1220 var url = "/_administrator/editor/FCKeditor/editor/filemanager/browser/mcpuk/browser.html?Connector=connectors/php/connector.php"; 1221 } else { 1222 var url = "/_administrator/editor/FCKeditor/editor/filemanager/browser/mcpuk/browser.html?Type=Image&Connector=connectors/php/connector.php"; 1223 } 1224 if( dir ){ 1225 url += '&CurrentFolder=' + dir.replace(/\/+/,"/"); 1226 } else if( get_cookie('close_image_dir') !== '' ) { 1227 url += '&CurrentFolder=' + get_cookie('close_image_dir').replace(/\/+/,"/"); 1228 } 1229 x=800; 1230 y=600; 1231 x = screen.width * .7; 1232 y = (screen.height - 50) * .8; 1233 OpenSubWin(url,x,y,'server_browser'); 1234} 1235function SetUrl( fileUrl ){ 1236 1237 if( !!target_element && !!$(target_element) ) { 1238 $(target_element).value = fileUrl; 1239 if(!!$(target_element).onchange) $(target_element).onchange(); 1240 1241 } else if( typeof context_menu == 'object' && !!context_menu.easy_edit_mode ) { 1242 context_menu.easy_edit_mode_image(fileUrl); 1243 } else { 1244 OpenSubWin(fileUrl,600,480,"image"); 1245 return true; 1246 } 1247} 1248function OpenSubWin(url, x, y,winname ){ 1249 if( !url ) return false; 1250 if( !winname ) winname = 'subwin'; 1251 var option = ''; 1252 if( !mobile ) 1253 { 1254 if( !x ) x = 600; 1255 if( !y ) y = 480; 1256 wx = screen.width; 1257 wy = screen.height - 50; 1258 dx = ( wx - x ) / 2; 1259 dy = ( wy - y ) / 2; 1260 option = "top=" + dy + 'px'; 1261 option += ",left=" + dx + 'px';
1262 option += ",width=" + x + 'px'; 1263 option += ",height=" + y + 'px'; 1264 option += ",scrollbars=yes,status=yes,resizable=yes,chrome=yes,centerscreen=yes"; 1265 w = window.open(url,winname,option); 1266 // w.moveTo(dx,dy); 1267 w.focus(); 1268 1269 // ä½ããããµã¼ãã¼ãã©ã¦ã¶ãéããå ´åã®åæå 1270 const timer = setInterval(() => { 1271 if (w.closed) { 1272 clearInterval(timer); 1273 context_menu.init(); 1274 } 1275 }, 1000); 1276 } 1277 else 1278 { 1279 window.open(url,winname,option); 1280 } 1281} 1282function screenInfomation(){ 1283 var s = new Object(); 1284 var p; 1285 try { 1286 p = parent.document; 1287 s.width = p.documentElement.clientWidth||p.body.clientWidth; // æ¨ªå¹ 1288 s.nowHeight = p.documentElement.clientHeight; // ç¾å¨è¡¨ç¤ºãã¦ããç»é¢ã®é«ã 1289 s.height = p.documentElement.scrollHeight||p.body.clientHeight; // ç»é¢ã®é«ã 1290 s.x = p.documentElement.scrollLeft||p.body.scrollLeft; // 横ã®ç§»åé 1291 s.y = p.documentElement.scrollTop||p.body.scrollTop; // 縦ã®ç§»åé 1292 } catch(e) { 1293 s.width = document.body.clientWidth; 1294 s.nowHeight = document.body.clientHeight; 1295 s.height = window.screen.height - 200; 1296 s.x = document.body.scrollLeft; 1297 s.y = document.body.scrollTop; 1298 p = window.document; 1299 s.width = p.documentElement.clientWidth||p.body.clientWidth; // æ¨ªå¹ 1300 s.nowHeight = p.documentElement.clientHeight; // ç¾å¨è¡¨ç¤ºãã¦ããç»é¢ã®é«ã 1301 s.height = p.documentElement.scrollHeight||p.body.clientHeight; // ç»é¢ã®é«ã 1302 s.x = p.documentElement.scrollLeft||p.body.scrollLeft; // 横ã®ç§»åé 1303 s.y = p.documentElement.scrollTop||p.body.scrollTop; // 縦ã®ç§»åé 1304 1305 1306 } 1307 return s; 1308} 1309 1310function get_brouser_height(){ 1311 // IE以å¤ã 1312 if (!document.all && (document.layers || document.getElementById)) { 1313 return window.innerHeight; 1314 } 1315 // ã¦ã£ã³ãã¦ãºIE 6ã»æ¨æºã¢ã¼ãã 1316 else if (document.getElementById && (document.compatMode=='CSS1Compat')) { 1317 return document.documentElement.clientHeight; 1318 } 1319 // ãã®ä»ã®IEã 1320 else if (document.all) { 1321 return document.body.clientHeight; 1322 } 1323 // ãã®ä»(é対å¿)ã 1324 else { 1325 return 700; 1326 } 1327} 1328function get_brouser_width(){ 1329 // IE以å¤ã 1330 if (!document.all && (document.layers || document.getElementById)) { 1331 return window.innerWidth; 1332 } 1333 // ã¦ã£ã³ãã¦ãºIE 6ã»æ¨æºã¢ã¼ãã 1334 else if (document.getElementById && (document.compatMode=='CSS1Compat')) { 1335 return document.documentElement.clientWidth; 1336 } 1337 // ãã®ä»ã®IEã 1338 else if (document.all) { 1339 return document.body.clientWidth; 1340 } 1341 // ãã®ä»(é対å¿)ã 1342 else { 1343 return 1024; 1344 } 1345} 1346function isNumeric(num){ 1347 var numeric="0123456789"; 1348 if(num.length==0){ 1349 return true; 1350 } 1351 for(i=0;i < num.length;i++){ 1352 if(numeric.indexOf(num.charAt(i))<0){ 1353 return false; 1354 } 1355 } 1356 return true; 1357} 1358/** 1359* ãããã°ç¨ 1360* 1361**/ 1362if (!('console' in window)) { 1363 1364 window.console = {}; 1365 window.console.log = function(str){ 1366 return str; 1367 }; 1368 window.console.warn = function(str){ 1369 return str; 1370 }; 1371 window.console.info = function(str){ 1372 return str; 1373 }; 1374 window.console.error = function(str){ 1375 return str; 1376 }; 1377} 1378function _uc(str) { 1379 return encodeURIComponent(str); 1380} 1381function _u(str) { 1382 return encodeURI(str); 1383} 1384function _us(str) { 1385 return encodeURI(str); 1386} 1387function _h(str) { 1388 return html_escape(str); 1389} 1390function _j(str) { 1391 return escape(str); 1392} 1393function _ba(str) { 1394 return window.btoa(unescape(_uc(str))) 1395} 1396function _raw(str) { 1397 return str; 1398} 1399function html_escape(str) { 1400 if( typeof str === 'number' ) return str; 1401 if(typeof str !== 'string') throw 'invalid parameter:'+str; 1402 return str.replace(/[&'`"<>]/g, function (match) { //' 1403 return { 1404 '&': '&', 1405 "'": ''', 1406 '`': '`', 1407 '"': '"', 1408 '<': '<', 1409 '>': '>' 1410 }[match] 1411 }); 1412} 1413//Javascriptçpreg_quote. 1414function preg_quote(str, delimiter){ 1415 // Quote regular expression characters plus an optional character 1416 // 1417 // version: 1107.2516 1418 // discuss at: http://phpjs.org/functions/preg_quote 1419 // + original by: booeyOH 1420 // + improved by: Ates Goral (http://magnetiq.com) 1421 // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1422 // + bugfixed by: Onno Marsman 1423 // + improved by: Brett Zamir (http://brett-zamir.me) 1424 // * example 1: preg_quote("$40"); 1425 // * returns 1: '\$40' 1426 // * example 2: preg_quote("*RRRING* Hello?"); 1427 // * returns 2: '\*RRRING\* Hello\?' 1428 // * example 3: preg_quote("\\.+*?[^]$(){}=!<>|:"); 1429 // * returns 3: '\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:' 1430 return (str + '').replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + (delimiter || '') + '-]', 'g'), '\\$&'); 1431} 1432 1433if (typeof globalThis.HelperSetButton !== 'function') { 1434 /** 1435 * ãã¿ã³ã®HTMLçæãæ±ç¨çã«è¡ããã«ãã¼ã¯ã©ã¹ 1436 * 1437 * usage. 1438 * top.buttonHelper = new HelperSetButton(); 1439 * top.buttonHelper.rewriteClickEvent = function(b, evSeed) { 1440 * if (b === 'ok') { 1441 * evSeed.jsOnclick = 'buttonHelper.saveImgPropSubmit();'; 1442 * } 1443 * } 1444 * top.buttonHelper.saveImgPropSubmit = function() { 1445 * xxxx 1446 * }
1447 * top.buttonHelper.setButton({ok: 1, cancel: 1, save: 1}); 1448 */ 1449 globalThis.HelperSetButton = class generateContentsHelper { 1450 1451 // 追å ãã¿ã³ 1452 addSeedBtn() { 1453 return {}; 1454 } 1455 1456 getSeedBtn() { 1457 const iniSeed = { 1458 ok: ({ 1459 btnClass: 'cms_btn--ok_return', 1460 icon: 'icon-ok', 1461 label: 'OK', 1462 jsOnclick: 'admin_dialog_content.CMSAdmin.submit_close();' 1463 }), 1464 cancel: ({ 1465 btnClass: 'cms_btn--cancel', 1466 icon: 'icon-cancel', 1467 label: 'ãã£ã³ã»ã«', 1468 jsOnclick: 'admin_dialog_content.CMSAdmin.close();' 1469 }), 1470 close: ({ 1471 btnClass: 'cms_btn--close', 1472 icon: 'icon-cancel', 1473 label: 'éãã', 1474 jsOnclick: 'admin_dialog_content.CMSAdmin.close();' 1475 }), 1476 save: ({ 1477 btnClass: 'cms_btn--save', 1478 icon: 'icon-save', 1479 label: 'ä¿å', 1480 jsOnclick: 'admin_dialog_content.CMSAdmin.submit();' 1481 }), 1482 back_return: ({ 1483 btnClass: 'cms_btn--top', 1484 icon: 'icon-back', 1485 label: 'æ»ã', 1486 jsOnclick: 'admin_dialog_content.resume_result();' 1487 }), 1488 }; 1489 1490 // ãã¼ã¸ 1491 return { 1492 ...iniSeed, 1493 ...this.addSeedBtn() 1494 }; 1495 } 1496 1497 safeConvBtnSeed(seed) { 1498 return JSON.parse(JSON.stringify(seed)); 1499 } 1500 1501 makeBtn(seed_btn) { 1502 const iconId = seed_btn.icon; 1503 if (!/^[a-zA-Z0-9_-]+$/.test(iconId)) { 1504 console.error('Invalid icon ID: Unsafe characters detected in seed_btn.icon.'); 1505 return false; 1506 } 1507 1508 const htmlString = ` 1509 <a href="#" class="cms_btn" alt="" onclick="return false;"> 1510 <svg><use xlink:href=""></use></svg> 1511 </a> 1512 `.trim(); 1513 1514 // æååã§ããhtmlã¿ã°ãDOMè¦ç´ ã«å¤æ 1515 const tmpTag = document.createElement('div'); 1516 tmpTag.insertAdjacentHTML('afterbegin', htmlString); 1517 const aTag = tmpTag.firstElementChild; 1518 if (!aTag || aTag.tagName !== 'A') { 1519 console.error('Failed to create <a> element.'); 1520 return null; 1521 } 1522 1523 // åå¤ãã»ãã 1524 aTag.classList.add(seed_btn.btnClass); 1525 aTag.setAttribute('alt', seed_btn.label); 1526 aTag.setAttribute('onclick', `${seed_btn.jsOnclick} return false;`); 1527 aTag.querySelector('svg').after(document.createTextNode(seed_btn.label)); 1528 1529 const useHref = `/_administrator/css/default/images/svg/symbol-defs.svg#${iconId}` 1530 aTag.querySelector('use').setAttribute('xlink:href', useHref); 1531 1532 return aTag; 1533 } 1534 1535 // ã¤ãã³ã䏿¸ã 1536 rewriteClickEvent(b, evSeed) { 1537 // â¼è¨è¼ãµã³ãã« 1538 // if (b === 'ok') { 1539 // evSeed.jsOnclick = 'admin_dialog_content.CMSAdmin.submit_close();'; 1540 // } 1541 // else if (b === 'cancel') { 1542 // evSeed.jsOnclick = 'admin_dialog_content.CMSAdmin.cancel();'; 1543 // } 1544 } 1545 1546 getBtnElements(button) { 1547 const seed_btn_defaults = this.getSeedBtn(); 1548 let btn_elements = []; 1549 let index = 0; 1550 1551 for (let b in button) { 1552 if (Object.prototype.hasOwnProperty.call(button, b)) { 1553 if ( !seed_btn_defaults.hasOwnProperty(b) ) { 1554 continue; 1555 } 1556 1557 let evSeed = this.safeConvBtnSeed(seed_btn_defaults[b]); 1558 1559 // ã¤ãã³ã䏿¸ã 1560 this.rewriteClickEvent(b, evSeed); 1561 1562 const btnElement = this.makeBtn(evSeed); 1563 if (btnElement) { 1564 btn_elements[index] = btnElement; 1565 index++; 1566 } 1567 } 1568 } 1569 return btn_elements.reverse(); 1570 } 1571 1572 run(viewBtnMany) { 1573 const targetElement = parent.document.getElementById('cms_dialog_ctrl_td'); 1574 if ( !targetElement ) { 1575 console.error('Target element "cms_dialog_ctrl_td" not found.'); 1576 return; 1577 } 1578 1579 targetElement.textContent = ''; 1580 this.getBtnElements(viewBtnMany).forEach(element => { 1581 targetElement.append(element); 1582 }); 1583 1584 try { 1585 const winobj = top.Windows.getFocusedWindow(); 1586 if (winobj && typeof winobj.setStatusBar === 'function') { 1587 winobj.setStatusBar(''); 1588 } 1589 } 1590 catch (e) { 1591 console.warn('Could not set status bar. Window object manipulation failed.', e); 1592 } 1593 } 1594 } 1595} 1596/** 1597 * AI Content Generation - åºå管çã¢ã¸ã¥ã¼ã« 1598 * Google AdSense / Google Ad Manager (IMA SDK) ã®åæåã»ç®¡çãè¡ã 1599 */ 1600if (typeof globalThis.AiAdManager !== 'function') { 1601 1602 globalThis.AiAdManager = class AiAdManager {
1603 #adProvider = 'admanager'; 1604 #adVastTag = ''; 1605 #adsenseClientId = ''; 1606 #adsenseSlotId = ''; 1607 #adsenseAdType = 'auto'; 1608 #adsenseResponsive = false; 1609 #adsenseCloseButtonDelay = 5; 1610 1611 #adContainerOverlay = null; 1612 #adContainer = null; 1613 #closeButton = null; 1614 #countdownTimer = null; 1615 #adsManager = null; 1616 #adsLoader = null; 1617 #zIndexBase = 300000; 1618 1619 #onAdCompleted = null; 1620 1621 /** 1622 * @param {Object} config - åºåè¨å® 1623 * @param {string} config.adProvider - 'adsense' ã¾ã㯠'admanager' 1624 * @param {string} config.adVastTag - Ad Managerç¨VASTã¿ã°URL 1625 * @param {string} config.adsenseClientId - AdSense ã¯ã©ã¤ã¢ã³ãID 1626 * @param {string} config.adsenseSlotId - AdSense ã¹ãããID 1627 * @param {string} config.adsenseAdType - AdSense åºåã¿ã¤ã 1628 * @param {boolean} config.adsenseResponsive - AdSense ã¬ã¹ãã³ã·ãè¨å® 1629 * @param {number} config.adsenseCloseButtonDelay - AdSense éãããã¿ã³è¡¨ç¤ºã¾ã§ã®ç§æ° 1630 */ 1631 constructor(config = {}) { 1632 this.#adProvider = config.adProvider || 'admanager'; 1633 this.#adVastTag = config.adVastTag || ''; 1634 this.#adsenseClientId = config.adsenseClientId || ''; 1635 this.#adsenseSlotId = config.adsenseSlotId || ''; 1636 this.#adsenseAdType = config.adsenseAdType || 'auto'; 1637 this.#adsenseResponsive = config.adsenseResponsive || false; 1638 this.#adsenseCloseButtonDelay = config.adsenseCloseButtonDelay ?? 5; 1639 } 1640 1641 /** 1642 * zIndexã®ãã¼ã¹å¤ãè¨å® 1643 * @param {number} zIndex 1644 */ 1645 setZIndexBase(zIndex) { 1646 this.#zIndexBase = zIndex; 1647 } 1648 1649 /** 1650 * åºåå®äºæã®ã³ã¼ã«ããã¯ãè¨å® 1651 * @param {Function} callback 1652 */ 1653 setOnAdCompleted(callback) { 1654 this.#onAdCompleted = callback; 1655 } 1656 1657 /** 1658 * åºåSDKãèªã¿è¾¼ã 1659 */ 1660 loadAdSdk() { 1661 if (this.#adProvider === 'adsense') { 1662 this.#loadAdSenseScript(); 1663 } else { 1664 this.#loadImaSdk(); 1665 } 1666 } 1667 1668 /** 1669 * åºåã³ã³ãããæ°è¦ä½æ 1670 */ 1671 newAdContainer() { 1672 this.removeAdContainer(); 1673 1674 window.top.document.body.insertAdjacentHTML('beforeend', this.#templateAdContainer()); 1675 this.#adContainerOverlay = window.top.document.getElementById('ai_modal_ad_overlay'); 1676 this.#adContainerOverlay.style.zIndex = this.#zIndexBase + 3; 1677 this.#adContainer = window.top.document.getElementById('ai_modal_ad_container'); 1678 } 1679 1680 /** 1681 * åºåã³ã³ãããåé¤ 1682 */ 1683 removeAdContainer() { 1684 // ã«ã¦ã³ããã¦ã³ã¿ã¤ãã¼ãã¯ãªã¢ 1685 if (this.#countdownTimer) { 1686 clearInterval(this.#countdownTimer); 1687 this.#countdownTimer = null; 1688 } 1689 1690 // ãããã¤ãå¥ã® destroy å¦ç 1691 if (this.#adProvider === 'adsense') { 1692 // AdSense: ç¹å¥ãª destroy å¦çã¯ä¸è¦ï¼DOMåé¤ã§èªåã¯ãªã¼ã³ã¢ããï¼ 1693 } else { 1694 // AdManager: IMA adsManager ã destroy 1695 this.#adsManager?.destroy(); 1696 } 1697 1698 // ã³ã³ããã DOM ããåé¤ 1699 this.#adContainerOverlay?.remove(); 1700 this.#adContainerOverlay = null; 1701 this.#adContainer = null; 1702 this.#closeButton = null; 1703 } 1704 1705 /** 1706 * åºåã³ã³ããã表示 1707 */ 1708 showAdContainer() { 1709 if (this.#adContainerOverlay) { 1710 this.#adContainerOverlay.style.display = 'block'; 1711 } 1712 } 1713 1714 /** 1715 * åºåãåæåãã¦è¡¨ç¤º 1716 */ 1717 initializeAds() { 1718 if (this.#adProvider === 'adsense') { 1719 this.#initializeAdSense(); 1720 } else { 1721 this.#initializeIMA(); 1722 } 1723 } 1724 1725 // ========== ãã©ã¤ãã¼ãã¡ã½ãã: IMA SDK (Ad Manager) ========== 1726 1727 #initializeIMA() { 1728 try { 1729 const adDisplayContainer = new window.google.ima.AdDisplayContainer( 1730 this.#adContainer, 1731 ); 1732 adDisplayContainer.initialize(); 1733 1734 this.#adsLoader = new window.google.ima.AdsLoader(adDisplayContainer); 1735 1736 this.#adsLoader.addEventListener( 1737 window.google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, 1738 this.#onAdsManagerLoaded, 1739 false, 1740 ); 1741 1742 this.#adsLoader.addEventListener( 1743 window.google.ima.AdErrorEvent.Type.AD_ERROR, 1744 (adErrorEvent) => { 1745 const err = adErrorEvent.getError(); 1746 console.error('åºåã¨ã©ã¼:', err.getMessage(), err.getVastErrorCode?.()
1746); 1747 }, 1748 false, 1749 ); 1750 1751 // VASTåºåã¿ã°ããªã¯ã¨ã¹ã 1752 const adsRequest = new window.google.ima.AdsRequest(); 1753 adsRequest.adTagUrl = this.#adVastTag; 1754 1755 this.#adsLoader.requestAds(adsRequest); 1756 1757 } catch (e) { 1758 console.error('IMAåæåã¨ã©ã¼:', e); 1759 throw e; 1760 } 1761 } 1762 1763 #onAdsManagerLoaded = (adsManagerLoadedEvent) => { 1764 this.#adsManager = adsManagerLoadedEvent.getAdsManager(); 1765 1766 this.#adsManager.addEventListener( 1767 window.google.ima.AdErrorEvent.Type.AD_ERROR, 1768 (adErrorEvent) => { 1769 const err = adErrorEvent.getError(); 1770 console.error('åºåã¨ã©ã¼:', err.getMessage(), err.getVastErrorCode?.()); 1771 }, 1772 ); 1773 1774 // åºåéå§ã¤ãã³ã 1775 this.#adsManager.addEventListener( 1776 window.google.ima.AdEvent.Type.STARTED, 1777 () => { 1778 // console.log('åºåãéå§ããã¾ãã'); 1779 } 1780 ); 1781 1782 // åºåå®äºã¤ãã³ã 1783 this.#adsManager.addEventListener( 1784 window.google.ima.AdEvent.Type.ALL_ADS_COMPLETED, 1785 () => { 1786 // console.log('åºå表示ãå®äºãã¾ãã'); 1787 this.removeAdContainer(); 1788 this.#onAdCompleted?.(); 1789 } 1790 ); 1791 1792 // åºåã¹ãããã¤ãã³ã 1793 this.#adsManager.addEventListener( 1794 window.google.ima.AdEvent.Type.SKIPPED, 1795 () => { 1796 // console.log('åºåãã¹ãããããã¾ãã'); 1797 this.removeAdContainer(); 1798 this.#onAdCompleted?.(); 1799 } 1800 ); 1801 1802 // ã¯ãªãã¯ãããã¨ã 1803 this.#adsManager.addEventListener( 1804 window.google.ima.AdEvent.Type.CLICK, 1805 () => { 1806 this.removeAdContainer(); 1807 this.#onAdCompleted?.(); 1808 }, 1809 ); 1810 1811 try { 1812 this.#adsManager.init(this.#adContainer.clientWidth, this.#adContainer.clientHeight, window.google.ima.ViewMode.NORMAL); 1813 this.#adsManager.setVolume(0); // ãã¥ã¼ãè¨å® 1814 this.#adsManager.start(); 1815 // console.log('IMAåºåãæ£å¸¸ã«éå§ããã¾ãã'); 1816 } catch (adError) { 1817 console.error('Failed to start IMA ads:', adError); 1818 } 1819 } 1820 1821 #loadImaSdk() { 1822 // ãã§ã«èªã¿è¾¼ã¿æ¸ã¿ãªãäºéèªã¿è¾¼ã¿ããªã 1823 if (window.google && window.google.ima) { 1824 return; 1825 } 1826 1827 const script = window.top.document.createElement('script'); 1828 script.src = 'https://imasdk.googleapis.com/js/sdkloader/ima3.js'; 1829 script.async = true; 1830 1831 script.onload = () => { 1832 window.google = window.top.window.google; 1833 }; 1834 1835 script.onerror = () => { 1836 console.error('Failed to load IMA SDK'); 1837 }; 1838 1839 window.top.document.head.appendChild(script); 1840 } 1841 1842 // ========== ãã©ã¤ãã¼ãã¡ã½ãã: AdSense ========== 1843 1844 #initializeAdSense() { 1845 try { 1846 if (!this.#adsenseClientId || !this.#adsenseSlotId) { 1847 console.warn('AdSenseè¨å®ãä¸å®å ¨ã§ããã¯ã©ã¤ã¢ã³ãIDã¨ã¹ãããIDãæå®ãã¦ãã ããã'); 1848 return; 1849 } 1850 1851 // AdSense ã® <ins> ã¿ã°ãæºå 1852 const insTag = this.#adContainer.querySelector('ins.adsbygoogle'); 1853 if (!insTag) { 1854 console.error('AdSense <ins> ã¿ã°ãè¦ã¤ããã¾ãã'); 1855 return; 1856 } 1857 1858 // 屿§è¨å® 1859 insTag.setAttribute('data-ad-client', this.#adsenseClientId); 1860 insTag.setAttribute('data-ad-slot', this.#adsenseSlotId); 1861 insTag.setAttribute('data-ad-format', this.#adsenseAdType); 1862 if (this.#adsenseResponsive) { 1863 insTag.setAttribute('data-full-width-responsive', 'true'); 1864 } 1865 1866 // AdSense ã¯ã³ã³ãããè¡¨ç¤ºç¶æ ã§ãªãã¨åæåã§ããªããããå ã«è¡¨ç¤ºãã 1867 this.showAdContainer(); 1868 1869 // éãããã¿ã³ã®åç §ãåå¾ããã¤ãã³ããè¨å® 1870 this.#closeButton = this.#adContainerOverlay.querySelector('[data-name="ai_ad_close_button"]'); 1871 if (this.#closeButton) { 1872 this.#closeButton.addEventListener('click', this.#handleCloseButtonClick); 1873 } 1874 1875 // ã«ã¦ã³ããã¦ã³ãéå§ 1876 this.#startCloseButtonCountdown(); 1877 1878 // AdSense ã¹ã¯ãªãããèªã¿è¾¼ã¾ããã¾ã§å¾ æ©ããã¬ã¤ã¢ã¦ãè¨ç®å®äºå¾ã«åæå 1879 this.#waitForAdSenseScript(() => { 1880 // ã¬ã¤ã¢ã¦ãè¨ç®ã確å®ã«å®äºããããããæ¬¡ã®ãã¬ã¼ã ã¾ã
1880§å¾ æ© 1881 requestAnimationFrame(() => { 1882 try { 1883 // æ¢åã®åºåãã¯ãªã¢ï¼è¤æ°ååæåæå¯¾å¿ï¼ 1884 (window.top.adsbygoogle = window.top.adsbygoogle || []).push({ 1885 google_ad_client: this.#adsenseClientId, 1886 google_ad_slot: this.#adsenseSlotId, 1887 }); 1888 } catch (e) { 1889 console.error('AdSense åæåã¨ã©ã¼:', e); 1890 } 1891 }); 1892 }); 1893 1894 } catch (e) { 1895 console.error('AdSense åæå失æ:', e); 1896 } 1897 } 1898 1899 /** 1900 * éãããã¿ã³ã®ã«ã¦ã³ããã¦ã³ãéå§ 1901 */ 1902 #startCloseButtonCountdown() { 1903 if (!this.#closeButton) return; 1904 1905 let remainingSeconds = this.#adsenseCloseButtonDelay; 1906 const countdownText = this.#closeButton.querySelector('[data-name="ai_ad_countdown_text"]'); 1907 const closeText = this.#closeButton.querySelector('[data-name="ai_ad_close_text"]'); 1908 1909 // åæè¡¨ç¤º 1910 if (countdownText) { 1911 countdownText.textContent = `${remainingSeconds}ç§å¾ã«éãããã¾ã`; 1912 } 1913 1914 this.#countdownTimer = setInterval(() => { 1915 remainingSeconds--; 1916 1917 if (remainingSeconds <= 0) { 1918 // ã«ã¦ã³ããã¦ã³å®äº 1919 clearInterval(this.#countdownTimer); 1920 this.#countdownTimer = null; 1921 1922 // éãããã¿ã³ãæå¹å 1923 this.#closeButton.disabled = false; 1924 this.#closeButton.classList.add('ai_ad_close_button_active'); 1925 1926 if (countdownText) countdownText.style.display = 'none'; 1927 if (closeText) closeText.style.display = 'inline'; 1928 } else { 1929 // ã«ã¦ã³ããã¦ã³æ´æ° 1930 if (countdownText) { 1931 countdownText.textContent = `${remainingSeconds}ç§å¾ã«éãããã¾ã`; 1932 } 1933 } 1934 }, 1000); 1935 } 1936 1937 /** 1938 * éãããã¿ã³ã¯ãªãã¯æã®å¦ç 1939 */ 1940 #handleCloseButtonClick = () => { 1941 this.removeAdContainer(); 1942 this.#onAdCompleted?.(); 1943 } 1944 1945 #waitForAdSenseScript(callback, timeout = 5000) { 1946 const startTime = Date.now(); 1947 const checkInterval = 100; 1948 1949 const checkAndExecute = () => { 1950 if (window.top.adsbygoogle !== undefined) { 1951 callback(); 1952 } else if (Date.now() - startTime < timeout) { 1953 setTimeout(checkAndExecute, checkInterval); 1954 } else { 1955 console.warn('AdSense ã¹ã¯ãªããã®èªã¿è¾¼ã¿ãã¿ã¤ã ã¢ã¦ããã¾ãã'); 1956 } 1957 }; 1958 1959 checkAndExecute(); 1960 } 1961 1962 #loadAdSenseScript() { 1963 // ãã§ã«èªã¿è¾¼ã¿æ¸ã¿ãªãäºéèªã¿è¾¼ã¿ããªã 1964 if (window.adsbygoogle) { 1965 return; 1966 } 1967 1968 const script = window.top.document.createElement('script'); 1969 script.async = true; 1970 script.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js'; 1971 script.setAttribute('data-ad-client', this.#adsenseClientId); 1972 1973 script.onload = () => { 1974 console.log('AdSense script loaded successfully'); 1975 }; 1976 1977 script.onerror = () => { 1978 console.error('Failed to load AdSense script'); 1979 }; 1980 1981 window.top.document.head.appendChild(script); 1982 } 1983 1984 // ========== ãã©ã¤ãã¼ãã¡ã½ãã: ãã³ãã¬ã¼ã ========== 1985 1986 #templateAdContainer() { 1987 if (this.#adProvider === 'adsense') { 1988 return this.#templateAdContainerAdSense(); 1989 } else { 1990 return this.#templateAdContainerAdManager(); 1991 } 1992 } 1993 1994 #templateAdContainerAdManager() { 1995 return ` 1996 <div id="ai_modal_ad_overlay" 1997 style=" 1998 position: fixed; 1999 inset: 0; 2000 background: rgba(0,0,0,.9); 2001 display: none; 2002 " 2003 > 2004 <div id="ai_modal_ad_container" 2005 style=" 2006 position: absolute; 2007 top: 50%; 2008 left: 50%; 2009 transform: translate(-50%, -50%); 2010 width: 1080px; 2011 max-width: 90vw; 2012 max-height: 90vh; 2013 aspect-ratio: 16 / 9; 2014 background-color: black; 2015 " 2016 ></div> 2017 </div> 2018 `; 2019 } 2020 2021 #templateAdContainerAdSense() { 2022 return ` 2023 <div id="ai_modal_ad_overlay" 2024 style=" 2025 position: fixed; 2026 inset: 0; 2027 background: rgba(0,0,0,.9); 2028 display: none; 2029 " 2030 > 2031 <button 2032 data-name="ai_ad_close_button" 2033 disabled 2034 style=" 2035 position: absolute; 2036 top: 16px; 2037 right: 16px; 2038 padding: 8px 16px; 2039 border: none; 2040 border-radius: 4px; 2041 background-color: rgba(255, 255, 255, 0.3); 2042 color: #fff; 2043 font-size: 14px;
2044 cursor: not-allowed; 2045 transition: background-color 0.3s, cursor 0.3s; 2046 z-index: 1; 2047 " 2048 > 2049 <span data-name="ai_ad_countdown_text"></span> 2050 <span data-name="ai_ad_close_text" style="display: none;">â éãã</span> 2051 </button> 2052 <style> 2053 .ai_ad_close_button_active { 2054 background-color: rgba(255, 255, 255, 0.9) !important; 2055 color: #333 !important; 2056 cursor: pointer !important; 2057 } 2058 .ai_ad_close_button_active:hover { 2059 background-color: #fff !important; 2060 } 2061 </style> 2062 <div id="ai_modal_ad_container" 2063 style=" 2064 position: absolute; 2065 top: 50%; 2066 left: 50%; 2067 transform: translate(-50%, -50%); 2068 width: 1080px; 2069 max-width: 90vw; 2070 max-height: 90vh; 2071 padding: 20px; 2072 background-color: #f0f0f0; 2073 border-radius: 8px; 2074 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); 2075 display: flex; 2076 align-items: center; 2077 justify-content: center; 2078 overflow: auto; 2079 " 2080 > 2081 <ins class="adsbygoogle" 2082 style=" 2083 display: block; 2084 text-align: center; 2085 width: 100%; 2086 min-width: 300px; 2087 min-height: 250px; 2088 " 2089 ></ins> 2090 </div> 2091 </div> 2092 `; 2093 } 2094 } 2095} 2096 2097 2098if (typeof globalThis.aiContentGenerator !== 'function') { 2099 2100 const aiContentGeneration_showAD = false; 2101 const aiContentGeneration_textLengthOptions = {"direct_edit_html":[30,200,500,1000,2000],"direct_edit_textbox":[40,100,200],"direct_edit_textarea":[40,200,400],"blog_title":[20,40],"blog_description":[100,200,400],"blog_entry_title":[20,40],"blog_entry_description":[100,200,400],"event_title":[20,40],"event_description":[100,200,400],"event_entry_title":[20,40],"event_entry_description":[100,200,400],"topics_title":[20,40],"topics_description":[100,200,400],"topics_entry_title":[20,40],"topics_entry_description":[100,200,400],"free_page_title":[20,40],"free_page_description":[100,200,400],"metatag_title":[20,40],"metatag_description":[100,200,400],"site_title":[20,40],"site_description":[100,200,400]}; 2102 const aiContentGeneration_tones = ["\u30d5\u30a9\u30fc\u30de\u30eb","\u4e01\u5be7","\u30ab\u30b8\u30e5\u30a2\u30eb","\u67d4\u3089\u304b\u3044","\u529b\u5f37\u3044","\u5ba2\u89b3\u7684"]; 2103 const aiContentGeneration_outputStyles = {"direct_edit_html":"html","direct_edit_textbox":"text","direct_edit_textarea":"text_with_only_br","blog_title":"text","blog_description":"text","blog_entry_title":"text","blog_entry_description":"text","event_title":"text","event_description":"text","event_entry_title":"text","event_entry_description":"text","topics_title":"text","topics_description":"text","topics_entry_title":"text","topics_entry_description":"text","free_page_title":"text","free_page_description":"text","metatag_title":"text","metatag_description":"text","site_title":"text","site_description":"text"}; 2104 2105 // åºåãããã¤ãè¨å® 2106 const aiContentGeneration_adProvider = "adsense"; 2107 const aiContentGeneration_adsenseClientId = "ca-pub-0300124455324951"; 2108 const aiContentGeneration_adsenseSlotId = "7838772540"; 2109 const aiContentGeneration_adsenseAdType = "auto"; 2110 const aiContentGeneration_adsenseResponsive = true; 2111 const aiContentGeneration_adsenseCloseButtonDelay = 5; 2112 const aiContentGeneration_adVastTag = ""; 2113 const aiContentGeneration_adminName = ""; 2114 const aiContentGeneration_manualId = 'ã´ã¼ã´ã¼AIã§çæ'; 2115 const aiContentGeneration_helpCategoryApiURL = 'https\x3a\x2f\x2fmanual\x2dv3\x2esecure\x2dcms\x2enet\x2fcategory\x2ephp\x3fc\x3d' + encodeURIComponent(aiContentGeneration_manualId); 2116 const aiContentGeneration_videoManualApiURL = 'https\x3a\x2f\x2fmanual\x2dv3\x2esecure\x2dcms\x2enet\x2fvideomanual\x2ephp\x3fc\x3d' + encodeURIComponent(aiContentGeneration_manualId); 2117 const aiContentGeneration_helpPageBaseURL = '\x2f\x5fadministrator\x2feditor\x2fhelp'; 2118 2119 globalThis.aiContentGenerator = class aiContentGenerator { 2120 2121 #showAD = aiContentGeneration_showAD; 2122 #adminName = aiContentGeneration_adminName; 2123 #adProvider = aiContentGeneration_adProvider; 2124 #adVastTag = aiContentGeneration_adVastTag; 2125 #adsenseClientId = aiContentGeneration_adsenseClientId; 2126 #adsenseSlotId = aiContentGeneration_adsenseSlotId; 2127 #adsenseAdType = aiContentGeneration_adsenseAdType; 2128 #adsenseResponsive = aiContentGeneration_adsenseResponsive; 2129 #adsenseCloseButtonDelay = aiContentGeneration_adsenseCloseButtonDelay; 2130 #textLengthOptions = []; 2131 #toneOptions = aiContentGeneration_tones; 2132 #outputStyle = null; 2133 2134 #lastResponseId = null; 2135 #baseResponseId = null; 2136 #lastResponseIndex = 0; 2137 #responseMetadataById = new Map(); 2138 #adoptionLoggedActionKeys = new Set(); 2139 #editorAdapter = null; 2140 #adManager = null; 2141 #abortController = null; 2142 2143 #modal = null;
2144 #overlay = null; 2145 #modalShadowHost = null; 2146 #modalShadowRoot = null; 2147 #sendChatButton = null; 2148 #helloByAI = null; 2149 #conversationThreads = null; 2150 2151 // ãªãã·ã§ã³ 2152 #userRequestTextAreaOption = null; 2153 #textLengthOption = null; 2154 #toneOption = null; 2155 2156 #zIndexBase = 300000; 2157 2158 constructor(contentType) { 2159 this.contentType = contentType; 2160 this.#textLengthOptions = aiContentGeneration_textLengthOptions[contentType] || []; 2161 this.#outputStyle = aiContentGeneration_outputStyles[contentType]; 2162 } 2163 2164 /** ã¨ãã£ã¿æ±ç¨ã¢ããã¿ï¼é å»¶çæï¼ãããã ããã¨ãã£ã¿å®è£ ä¾å */ 2165 #helperEditor() { 2166 if (this.#editorAdapter && this.#editorAdapter.type !== 'none') { 2167 return this.#editorAdapter; 2168 } 2169 2170 if (window.FCKeditorAPI) { 2171 this.#editorAdapter = this.#editorFck(); 2172 } 2173 else { 2174 this.#editorAdapter = this.#editorNull(); 2175 } 2176 2177 return this.#editorAdapter; 2178 } 2179 2180 #editorNull() { 2181 return { 2182 type: 'none', 2183 detectInstanceName() { return null; }, 2184 makeInstance() { return null; }, 2185 getHtml() { return ""; }, 2186 insertHtml() { return false; }, 2187 setHtml() { return false; }, 2188 installSafetyHooks() {/* noop */ } 2189 }; 2190 } 2191 2192 #editorFck() { 2193 return { 2194 type: 'fck', 2195 detectInstanceName(container) { 2196 let ifr = null; 2197 if (container && container.querySelector) { 2198 ifr = container.querySelector('iframe[id$="___Frame"]'); 2199 } 2200 if (!ifr) { 2201 ifr = document.querySelector('iframe[id$="___Frame"]'); 2202 } 2203 if (ifr && ifr.id) { 2204 const m = ifr.id.match(/^(.+?)___Frame$/); 2205 if (m) return m[1];
2206 } 2207 return null; 2208 }, 2209 makeInstance(name) { 2210 if (!name || !window.FCKeditorAPI) return null; 2211 try { return window.FCKeditorAPI.GetInstance(name); } 2212 catch (_) { return null; } 2213 }, 2214 getHtml(ed) { 2215 if (!ed) return ""; 2216 try { return ed.GetXHTML(true); } 2217 catch (_) { try { return ed.GetHTML(); } catch (_) { return ""; } } 2218 }, 2219 insertHtml(ed, html) { 2220 if (!ed) return false; 2221 ed.Focus(); ed.InsertHtml(html); return true; 2222 }, 2223 setHtml(ed, html) { 2224 if (!ed) return false; 2225 ed.Focus(); ed.SetHTML(html); return true; 2226 }, 2227 installSafetyHooks() { 2228 window.FCKeditor_OnComplete = (function (orig) { 2229 return function (editorInstance) { 2230 if (typeof orig === "function") orig(editorInstance); 2231 }; 2232 })(window.FCKeditor_OnComplete); 2233 } 2234 }; 2235 } 2236 2237 // ========== ã¢ã¼ãã«çæï¼ã¤ã³ã¹ã¿ã³ã¹å ã·ã³ã°ã«ãã³ï¼ ========== 2238 async #initModal() { 2239 if (this.#modal) { 2240 this.#modal = null; 2241 } 2242 2243 this.#initZIndexBase(); 2244 2245 // æ¢åãåé¤ï¼éè¤IDåé¿ï¼ 2246 window.top.document.getElementById('ai_modal')?.remove(); 2247 window.top.document.getElementById('ai_modal_overlay')?.remove(); 2248 window.top.document.getElementById('ai_modal_host')?.remove(); 2249 2250 // shadow host 2251 this.#modalShadowHost = window.top.document.createElement('div'); 2252 this.#modalShadowHost.id = 'ai_modal_host'; 2253 window.top.document.body.appendChild(this.#modalShadowHost); 2254 2255 // shadow root 2256 this.#modalShadowRoot = this.#modalShadowHost.attachShadow({ mode: 'open' }); 2257 2258 // CSS 2259 const style = document.createElement('link'); 2260 style.rel = 'stylesheet'; 2261 style.href = '/_administrator/css/default/ai_content_generation_modal.css?t=1790968415'; 2262 2263 this.#modalShadowRoot.appendChild(style); 2264 2265 await new Promise((resolve, reject) => { 2266 style.onload = () => resolve(); 2267 style.onerror = () => reject(new Error('Failed to load CSS')); 2268 }); 2269 2270 this.#modalShadowRoot.innerHTML += this.#templateModal(); 2271 2272 this.#modal = this.#modalShadowRoot.getElementById('ai_modal'); 2273 this.#modal.style.zIndex = this.#zIndexBase + 2; 2274 this.#overlay = this.#modalShadowRoot.getElementById('ai_modal_overlay'); 2275 this.#overlay.style.zIndex = this.#zIndexBase + 1; 2276 this.#userRequestTextAreaOption = this.#modal.querySelector('[data-name="ai_modal_options_user_request"]'); 2277 this.#textLengthOption = this.#modal.querySelector('[data-name="ai_modal_options_text_length"]'); 2278 this.#toneOption = this.#modal.querySelector('[data-name="ai_modal_options_tone"]'); 2279 this.#sendChatButton = this.#modal.querySelector('[data-name="ai_modal_send_chat_button"]'); 2280 this.#conversationThreads = this.#modal.querySelector('[data-name="ai_modal_conversation_threads"]'); 2281 this.#helloByAI = this.#modal.querySelector('[data-name="ai_modal_hello_by_ai"]'); 2282 2283 // ã¤ãã³ãè¨å® 2284 this.#modal.querySelector('[data-name="ai_modal_close_button"]').addEventListener("click", () => this.#closeModal('close_button')); 2285 this.#modal.querySelector('[data-name="ai_modal_btn_cancel"]').addEventListener("click", () => this.#closeModal('cancel_button')); 2286 this.#setupManualLinks(); 2287 2288 if (this.#showAD) { 2289 try { 2290 this.#initAdManager(); 2291 this.#adManager.loadAdSdk(); 2292 } catch (e) { 2293 console.error('åºåSDKã®èªã¿è¾¼ã¿ã«å¤±æãã¾ãã:', e); 2294 } 2295 } 2296 2297 // ãã£ããã®éä¿¡ 2298 this.#sendChatButton.addEventListener("click", async (event) => { 2299 2300 const targetButton = event.currentTarget; 2301 2302 const isFirstRequest = !this.#lastResponseId; 2303 const previousResponseId = this.#lastResponseId; 2304 const nextResponseIndex = isFirstRequest 2305 ? 1 2306 : this.#lastResponseIndex + 1; 2307 2308 const userRequest = this.#userRequestTextAreaOption.value || ""; 2309 this.#userRequestTextAreaOption.value = ""; 2310 const chatId = this.#addUserChat(userRequest); 2311 2312 targetButton.disabled = true; 2313 this.#userRequestTextAreaOption.disabled = true; 2314 2315 if (this.#showAD && isFirstRequest && this.#adManager) { 2316 this.#adManager.newAdContainer(); 2317 this.#adManager.initializeAds(); 2318 } 2319 2320 const shownHelloByAI = this.#hideHelloByAI(); 2321 2322 this.#hideInputSection(); 2323 this.#addLoadingIndicator(); 2324 this.#scrollToConversationEnd(); 2325 2326 let inProgressChatId = null; 2327 let streamingHtml = ''; 2328 let chatShown = false; 2329
2330 try { 2331 inProgressChatId = this.#addAIChat('', `pending_${crypto.randomUUID()}`); 2332 await this.#sendAIRequest( 2333 this.contentType, 2334 userRequest, 2335 this.#textLengthOption.value, 2336 this.#toneOption.value, 2337 isFirstRequest ? this.#getRawTextOfBubbleById() : null, 2338 !isFirstRequest ? previousResponseId : null, 2339 !isFirstRequest ? this.#baseResponseId : null, 2340 nextResponseIndex, 2341 // onDelta 2342 (delta) => { 2343 streamingHtml += delta; 2344 this.#setAIChatContent(inProgressChatId, streamingHtml); 2345 this.#scrollToConversationEnd(); 2346 if (!chatShown) { 2347 this.#readyToNewChat(inProgressChatId); 2348 chatShown = true; 2349 } 2350 }, 2351 // onDone 2352 (fullText, responseId, baseResponseId, responseIndex) => { 2353 this.#setAIChatContent(inProgressChatId, fullText); 2354 inProgressChatId = this.#finalizeAIChatResponseId(inProgressChatId, responseId); 2355 this.#lastResponseId = responseId; 2356 this.#baseResponseId = baseResponseId || responseId; 2357 this.#lastResponseIndex = Number(responseIndex) || nextResponseIndex; 2358 this.#responseMetadataById.set(responseId, { 2359 previousResponseId, 2360 baseResponseId: this.#baseResponseId, 2361 responseIndex: this.#lastResponseIndex, 2362 }); 2363 if (!isFirstRequest) { 2364 this.#sendAdoptionAction('regenerated', 'new_generation', previousResponseId); 2365 } 2366 this.#readyToNewChat(inProgressChatId); 2367 this.#showAIChatActions(inProgressChatId); 2368 }, 2369 // onError 2370 (errorMessage) => { 2371 throw { 2372 message: errorMessage, 2373 alertToUser: true, 2374 }; 2375 }, 2376 ); 2377 2378 } catch (error) { 2379 // ãªã¯ã¨ã¹ãã䏿ãããå ´åã¯ä½ãããªã 2380 if (error.name === 'AbortError') { 2381 return; 2382 } 2383 2384 this.#userRequestTextAreaOption.value = userRequest; 2385 this.#removeUserChat(chatId); 2386 if (inProgressChatId) { 2387 this.#removeAIChat(inProgressChatId); 2388 } 2389 if (shownHelloByAI) { 2390 this.#showHelloByAI(); 2391 } 2392 this.#removeLoadingIndicator(); 2393 this.#adManager?.removeAdContainer(); 2394 let errorMessage = error.alertToUser 2395 ? error.message 2396 : 'äºæãã¬ã¨ã©ã¼ãçºçãã¾ããã'; 2397 2398 const brCount = (errorMessage.match(/<br>/g) || []).length; 2399 2400 this.#hideAIModal(); 2401 window.top.alert_dialog(errorMessage, 110 + (brCount * 20), () => { 2402 this.#showAIModal(); 2403 return true; 2404 }); 2405 2406 this.#showInputSection(); 2407 2408 } finally { 2409 targetButton.disabled = false; 2410 this.#userRequestTextAreaOption.disabled = false; 2411 } 2412 }); 2413 } 2414 2415 #initZIndexBase() { 2416 this.#zIndexBase = window.top.document.getElementById('overlay_modal')?.style.zIndex || 300000; 2417 } 2418 2419 #initValues(ctx) { 2420 let targetText = ""; 2421 if (ctx.ce instanceof HTMLInputElement || ctx.ce instanceof HTMLTextAreaElement) { 2422 targetText = ctx.ce.value || ""; 2423 } 2424 else if (ctx && ctx.editor) { 2425 targetText = this.#helperEditor().getHtml(ctx.editor); 2426 } 2427 else if (ctx && ctx.ce) { 2428 targetText = ctx.ce.innerHTML; 2429 } 2430 else { 2431 targetText = ""; 2432 } 2433 2434 window.__ai_modal_ctx__ = ctx; 2435 2436 // ãªãã·ã§ã³ã®å¤ããªã»ãã 2437 if (this.#userRequestTextAreaOption) { 2438 this.#userRequestTextAreaOption.value = ""; 2439 } 2440 if (this.#textLengthOption) { 2441 this.#textLengthOption.value = ""; 2442 } 2443 if (this.#toneOption) { 2444 this.#toneOption.value = ""; 2445 } 2446 this.#lastResponseId = null; 2447 this.#baseResponseId = null; 2448 this.#lastResponseIndex = 0; 2449 this.#responseMetadataById.clear(); 2450 this.#adoptionLoggedActionKeys.clear(); 2451 this.#initConversation(); 2452 2453 if (/^<br\s*\/?>$/i.test(targetText)) { 2454 targetText = ""; 2455 } 2456 2457 this.#addAIChat(targetText); 2458 if (!targetText) { 2459 this.#conversationThreads.querySelector('[data-name="ai_chat_init"]').classList.add('hidden'); 2460 this.#showHelloByAI(); 2461 this.#userRequestTextAreaOption.setAttribute('placeholder', this.#userRequestTextAreaOption.dataset.placeholderForEmpty || ''); 2462 } else { 2463 this.#hideHelloByAI(); 2464 } 2465 2466 this.#initTextLengthOption(targetText); 2467 this.#initToneOption(); 2468 } 2469 2470 #initTextLengthOption(targetText) { 2471 this.#textLengthOptions.forEach(optionValue => { 2472 this.#textLengthOption.insertAdjacentHTML('beforeend', ` 2473 <option value="${_h(optionValue)}">${_h(optionValue)}æå以ä¸</option> 2474 `); 2475 }); 2476 2477 if (targetText.length > 0) { 2478 this.#textLengthOption.insertAdjacentHTML('beforeend', ` 2479 <option value="keep">æ¢åã®æåæ°ãç®å®ã«</option> 2480 `); 2481 } 2482 } 2483 2484 #initToneOption() { 2485 this.#toneOptions.forEach(tone => { 2486 this.#toneOption.insertAdjacentHTML('beforeend', ` 2487 <option value="${_h(tone)}">${_h(tone)}</option> 2488 `); 2489 }); 2490 } 2491 2492 #readyToNewChat(aiChatId) { 2493 this.#removeLoadingIndicator(); 2494 this.#showAIChat(aiChatId); 2495 this.#showInputSection(); 2496 } 2497 2498 #showHelloByAI() { 2499 this.#helloByAI.classList.remove("hidden"); 2500 } 2501 2502 #hideHelloByAI() { 2503 let changed = false; 2504 if (!this.#helloByAI.classList.contains("hidden")) { 2505 this.#helloByAI.classList.add("hidden"); 2506 changed = true; 2507 } 2508 return changed; 2509 } 2510 2511 async #openModalWithContext(ctx) { 2512 await this.#initModal(); 2513 2514 this.#initValues(ctx); 2515 2516 this.#showAIModal(); 2517 2518 this.#userRequestTextAreaOption.focus(); 2519 } 2520 2521 // ========== ãã¿ã³ã«ã¢ã¼ãã«ããã¤ã³ã ========== 2522 bindAiModal(buttonEl, ce = null) { 2523 buttonEl.addEventListener("click", () => { 2524 let instanceName = ce === null 2525 ? this.#helperEditor().detectInstanceName(document) 2526 : null; 2527 let editor = null; 2528 if (instanceName) { 2529 editor = this.#helperEditor().makeInstance(instanceName); 2530 } 2531 2532 if (ce === null) { 2533 if (document.activeElement && 2534 document.activeElement.hasAttribute && 2535 document.activeElement.hasAttribute("contenteditable")) { 2536 ce = document.activeElement; 2537 } 2538 } 2539 2540 if (!editor && !ce) { 2541 instanceName = this.#helperEditor().detectInstanceName(document); 2542 if (instanceName) { 2543 editor = this.#helperEditor().makeInstance(instanceName); 2544 } 2545 if (!ce) { 2546 ce = document.querySelector('[contenteditable="true"]'); 2547 } 2548 } 2549 2550 this.#openModalWithContext({ editor, ce }); 2551 }); 2552 2553 // ã¨ãã£ã¿ã®ã»ãã 2554 this.#helperEditor().installSafetyHooks(); 2555 } 2556 2557 #closeModal(actionSource = null) { 2558 if (actionSource) {
2559 this.#sendAdoptionAction('dismissed', actionSource); 2560 } 2561 // é²è¡ä¸ã®ãã§ãããªã¯ã¨ã¹ãã䏿 2562 this.#abortController?.abort(); 2563 this.#abortController = null; 2564 2565 this.#adManager?.removeAdContainer(); 2566 this.#initConversation(); 2567 this.#hideAIModal(); 2568 this.#modal?.remove(); 2569 this.#modal = null; 2570 this.#overlay?.remove(); 2571 this.#overlay = null; 2572 this.#modalShadowHost?.remove(); 2573 this.#modalShadowHost = null; 2574 this.#modalShadowRoot = null; 2575 } 2576 2577 #setTextAndCloseModal(responseId) { 2578 const ctx = window.__ai_modal_ctx__; 2579 if (!ctx) return; 2580 2581 const text = this.#getRawTextOfBubbleById(responseId); 2582 2583 if (ctx.editor) { 2584 if (this.#helperEditor().setHtml(ctx.editor, text)) { 2585 this.#sendAdoptionAction('applied', 'decision_button', responseId); 2586 this.#closeModal(); 2587 } 2588 else { 2589 throw new Error('ã¨ãã£ã¿ã®æºåãã§ãã¦ãã¾ããã'); 2590 } 2591 } 2592 else if (ctx.ce) { 2593 // NOTE: å¿ è¦ã«å¿ã㦠sanitize ãæ¤è¨ 2594 if (ctx.ce instanceof HTMLInputElement || ctx.ce instanceof HTMLTextAreaElement) { 2595 ctx.ce.value = text; 2596 } else { 2597 ctx.ce.innerHTML = text; 2598 } 2599 ctx.ce.dispatchEvent(new Event('change', { bubbles: true })); 2600 this.#sendAdoptionAction('applied', 'decision_button', responseId); 2601 this.#closeModal(); 2602 } 2603 } 2604 2605 #initConversation() { 2606 this.#conversationThreads.replaceChildren(); 2607 } 2608 2609 #addUserChat(chatByUser) { 2610 const chatId = `user_chat_${crypto.randomUUID()}`; 2611 this.#conversationThreads.insertAdjacentHTML('beforeend', this.#templateUserChat(chatId, chatByUser)); 2612 return chatId; 2613 } 2614 2615 #removeUserChat(chatId) { 2616 this.#conversationThreads.querySelector(`[data-name="${chatId}"]`).remove(); 2617 } 2618 2619 #htmlToPlainText(html) { 2620 const template = document.createElement('template'); 2621 html = html.replace(/<br\s*\/?>\n?/gi, '\n'); 2622 template.innerHTML = html; 2623 return template.content.textContent ?? ''; 2624 } 2625 2626 #setAIChatContent(chatId, chatByAI = '') { 2627 if (!chatId) { 2628 return; 2629 } 2630 if (!this.#conversationThreads) { 2631 return; 2632 } 2633 const thread = this.#conversationThreads.querySelector(`[data-name="${chatId}"]`); 2634 if (!thread) { 2635 return; 2636 } 2637 const chatBubbleByAI = thread.querySelector('[data-name="chatBubbleByAI"]');
2638 const rawChatByAI = thread.querySelector('[data-name="rawChatByAI"]'); 2639 if (!chatBubbleByAI || !rawChatByAI) { 2640 return; 2641 } 2642 rawChatByAI.textContent = chatByAI ?? ''; 2643 if (chatBubbleByAI.dataset.showingSource === "true") { 2644 chatBubbleByAI.textContent = rawChatByAI.textContent; 2645 } else { 2646 chatBubbleByAI.innerText = this.#htmlToPlainText(chatByAI ?? ''); 2647 } 2648 } 2649 2650 #finalizeAIChatResponseId(chatId, responseId) { 2651 const thread = this.#conversationThreads.querySelector(`[data-name="${chatId}"]`); 2652 if (!thread) { 2653 return chatId; 2654 } 2655 const newChatId = `ai_chat_${responseId}`; 2656 thread.dataset.name = newChatId; 2657 const adoptButton = thread.querySelector('[data-action="adopt"]'); 2658 if (adoptButton) { 2659 adoptButton.dataset.responseId = responseId; 2660 adoptButton.disabled = false; 2661 } 2662 return newChatId; 2663 } 2664 2665 #removeAIChat(chatId) { 2666 if (!chatId) { 2667 return; 2668 } 2669 if (!this.#conversationThreads) { 2670 return; 2671 } 2672 this.#conversationThreads.querySelector(`[data-name="${chatId}"]`)?.remove(); 2673 } 2674 2675 #showAIChat(chatId) { 2676 this.#conversationThreads.querySelector(`[data-name="${chatId}"]`).classList.remove('hidden'); 2677 } 2678 2679 #addAIChat(chatByAI, responseId = null) { 2680 2681 const isInitial = responseId === null; 2682 2683 const chatId = isInitial 2684 ? `ai_chat_init` 2685 : `ai_chat_${responseId}`; 2686 2687 this.#conversationThreads.insertAdjacentHTML('beforeend', this.#templateAIChat(chatId)); 2688 2689 const newThread = this.#conversationThreads.querySelector(`[data-name="${chatId}"]`); 2690 if (!isInitial) { 2691 newThread.classList.add('hidden'); 2692 this.#hideAIChatActions(chatId); 2693 } 2694 2695 this.#setAIChatContent(chatId, chatByAI ?? ''); 2696 2697 // ã½ã¼ã¹è¡¨ç¤ºãã°ã« 2698 const sourceToggle = newThread.querySelector('[data-action="showSource"]'); 2699 if (this.#outputStyle === 'html') { 2700 sourceToggle.addEventListener("click", (event) => { 2701 const btn = event.currentTarget; 2702 const isActive = event.currentTarget.dataset.status === "true"; 2703 const chatBubbleByAI = newThread.querySelector('[data-name="chatBubbleByAI"]'); 2704 const rawChatByAI = newThread.querySelector('[data-name="rawChatByAI"]'); 2705 if (isActive) { 2706 chatBubbleByAI.innerText = this.#htmlToPlainText(rawChatByAI.textContent); 2707 chatBubbleByAI.dataset.showingSource = "false"; 2708 btn.classList.remove('cms-btn-ai-source--active'); 2709 } else { 2710 chatBubbleByAI.textContent = rawChatByAI.textContent; 2711 chatBubbleByAI.dataset.showingSource = "true"; 2712 btn.classList.add('cms-btn-ai-source--active'); 2713 } 2714 event.currentTarget.dataset.status = isActive ? "false" : "true"; 2715 }); 2716 } 2717 else { 2718 sourceToggle.remove(); 2719 } 2720 2721 // 決å®ãã¿ã³ 2722 const adoptButton = newThread.querySelector('button[data-action="adopt"]'); 2723 adoptButton.addEventListener("click", () => { 2724 const responseId = adoptButton.dataset.responseId || null; 2725 this.#setTextAndCloseModal(responseId); 2726 }); 2727 if (isInitial) { 2728 adoptButton.remove(); 2729 } 2730 2731 // åå以å¤ã¯ãç¾å¨ã®è¡¨ç¤ºå 容ãã©ãã«ãåé¤ 2732 const chatLabel = newThread.querySelector('[data-name="chatLabel"]'); 2733 if (!isInitial) { 2734 chatLabel.remove(); 2735 } 2736 2737 return chatId; 2738 } 2739 2740 #hideAIChatActions(chatId) { 2741 const thread = this.#conversationThreads.querySelector(`[data-name="${chatId}"]`); 2742 if (!thread) { 2743 return; 2744 } 2745 const actions = thread.querySelector('[data-name="actions"]'); 2746 if (actions) { 2747 actions.classList.add('hidden'); 2748 } 2749 } 2750 2751 #showAIChatActions(chatId) { 2752 const thread = this.#conversationThreads.querySelector(`[data-name="${chatId}"]`); 2753 if (!thread) { 2754 return; 2755 } 2756 const actions = thread.querySelector('[data-name="actions"]'); 2757 if (actions) { 2758 actions.classList.remove('hidden'); 2759 } 2760 } 2761 2762 #getRawTextOfBubbleById(responseId = null) { 2763 const id = responseId === null 2764 ? `ai_chat_init` 2765 : `ai_chat_${responseId}`; 2766 2767 const rawChatByAI = this.#conversationThreads.querySelector(`[data-name="${id}"]`).querySelector('[data-name="rawChatByAI"]'); 2768 return rawChatByAI.textContent; 2769 } 2770 2771 #addLoadingIndicator() { 2772 this.#conversationThreads.insertAdjacentHTML('beforeend', this.#templateLoadingIndicator()); 2773 } 2774 2775 #removeLoadingIndicator() { 2776 this.#conversationThreads.querySelectorAll('[data-name="ai_content_generation_loading_indicator"]').forEach(el => el.remove()); 2777 } 2778 2779 async #sendAIRequest( 2780 content_type, 2781 user_request, 2782 text_length, 2783 tone, 2784 current_input = null, 2785 previous_response_id = null, 2786 base_response_id = null, 2787 response_index = 1, 2788 onDelta, 2789 onDone, 2790 onError, 2791 ) { 2792 // æ¢åã®é²è¡ä¸ã®ãªã¯ã¨ã¹ããããã°ä¸æ 2793 this.#abortController?.abort(); 2794 2795 const request_end_point = 'ai_content_generation_manager/generate_content'; 2796 2797 const form = document.createElement('form'); 2798 form.method = 'POST'; 2799 2800 const createHidden = (name, value) => { 2801 const input = document.createElement('input'); 2802 input.type = 'hidden'; 2803 input.name = name; 2804 input.value = value; 2805 return input; 2806 }; 2807 2808 const fields = [ 2809 { name: 'q', value: request_end_point }, 2810 { name: 'do', value: request_end_point }, 2811 ]; 2812 2813 fields.push({ name: 'content_type', value: content_type }); 2814 fields.push({ name: 'user_request', value: user_request }); 2815 fields.push({ name: 'text_length', value: text_length }); 2816 fields.push({ name: 'tone', value: tone }); 2817 if (current_input !== null) { 2818 fields.push({ name: 'current_input', value: current_input }); 2819 } 2820 if (previous_response_id !== null) { 2821 fields.push({ name: 'previous_response_id', value: previous_response_id }); 2822 } 2823 if (base_response_id !== null) { 2824 fields.push({ name: 'base_response_id', value: base_response_id }); 2825 } 2826 fields.push({ name: 'response_index', value: response_index }); 2827 2828 fields.forEach(({ name, value }) => form.appendChild(createHidden(name, value))); 2829 2830 const formData = new FormData(form); 2831 2832 const headers = new Headers({ 2833 'X-Requested-With': 'XMLHttpRequest', 2834 'Accept': 'text/event-stream', 2835 }); 2836 2837 // AbortControllerã使ãã¦ãªã¯ã¨ã¹ãã䏿å¯è½ã«ãã 2838 this.#abortController = new AbortController(); 2839 2840 const res = await fetch("/_administrator/connector.php", { 2841 method: 'POST', 2842 body: formData, 2843 credentials: 'same-origin', 2844 signal: this.#abortController.signal,
2845 headers, 2846 }); 2847 if (!res.ok) { 2848 throw new Error(`HTTP ${res.status}`); 2849 } 2850 2851 const stream = res.body; 2852 const decoder = new TextDecoder(); 2853 2854 let buffer = ''; 2855 let responseId = null; 2856 2857 const processPayload = (payload) => { 2858 if (!payload) { 2859 return; 2860 } 2861 2862 let parsed; 2863 try { 2864 parsed = JSON.parse(payload); 2865 } catch (_) { 2866 return; 2867 } 2868 2869 if (parsed.type === 'delta') { 2870 const deltaText = parsed.text; 2871 onDelta(deltaText); 2872 } 2873 else if (parsed.type === 'done') { 2874 const finalText = parsed.fullText; 2875 responseId = parsed.responseId; 2876 onDone(finalText, responseId, parsed.baseResponseId, parsed.responseIndex); 2877 } 2878 else if (parsed.type === 'error') { 2879 onError(parsed.message); 2880 } 2881 }; 2882 2883 const extractDataPayload = (rawEvent) => { 2884 const payloadLines = []; 2885 rawEvent.split(/\r?\n/).forEach(line => { 2886 if (line.startsWith('data:')) { 2887 payloadLines.push(line.slice(5).trimStart()); 2888 } 2889 }); 2890 return payloadLines.join('\n').trim(); 2891 }; 2892 2893 const flushBuffer = () => { 2894 let separatorIndex; 2895 while ((separatorIndex = buffer.indexOf('\n\n')) !== -1) { 2896 const rawEvent = buffer.slice(0, separatorIndex).trim(); 2897 buffer = buffer.slice(separatorIndex + 2); 2898 const payload = extractDataPayload(rawEvent); 2899 if (payload) { 2900 processPayload(payload); 2901 } 2902 } 2903 }; 2904 2905 for await (const chunk of stream) { 2906 buffer += decoder.decode(chunk, { stream: true }); 2907 flushBuffer(); 2908 } 2909 } 2910 2911 #sendAdoptionAction(action, actionSource, responseId = this.#lastResponseId) { 2912 const responseMetadata = this.#responseMetadataById.get(responseId); 2913 if (!responseId || !responseMetadata || !responseMetadata.baseResponseId || responseMetadata.responseIndex < 1) { 2914 return; 2915 } 2916 const adoptionLogKey = `${responseId}:${action}`; 2917 if (this.#adoptionLoggedActionKeys.has(adoptionLogKey)) { 2918 return; 2919 } 2920 this.#adoptionLoggedActionKeys.add(adoptionLogKey); 2921 2922 const requestEndPoint = 'ai_content_generation_manager/log_adoption_action'; 2923 const params = new URLSearchParams(); 2924 params.append('q', requestEndPoint); 2925 params.append('do', requestEndPoint); 2926 params.append('content_type', this.contentType); 2927 params.append('response_id', responseId); 2928 params.append('base_response_id', responseMetadata.baseResponseId); 2929 params.append('response_index', String(responseMetadata.responseIndex)); 2930 params.append('action', action); 2931 params.append('action_source', actionSource || ''); 2932 if (responseMetadata.previousResponseId !== null) { 2933 params.append('previous_response_id', responseMetadata.previousResponseId); 2934 } 2935 2936 fetch('/_administrator/connector.php', { 2937 method: 'POST', 2938 body: params.toString(), 2939 credentials: 'same-origin', 2940 keepalive: true, 2941 headers: new Headers({ 2942 'X-Requested-With': 'XMLHttpRequest', 2943 'Accept': 'application/json', 2944 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 2945 }), 2946 }).catch(() => {}); 2947 } 2948 2949 #initAdManager() { 2950 if (this.#adManager) { 2951 return; 2952 } 2953 this.#adManager = new globalThis.AiAdManager({ 2954 adProvider: this.#adProvider, 2955 adVastTag: this.#adVastTag, 2956 adsenseClientId: this.#adsenseClientId, 2957 adsenseSlotId: this.#adsenseSlotId, 2958 adsenseAdType: this.#adsenseAdType, 2959 adsenseResponsive: this.#adsenseResponsive, 2960 adsenseCloseButtonDelay: this.#adsenseCloseButtonDelay, 2961 }); 2962 this.#adManager.setZIndexBase(this.#zIndexBase); 2963 } 2964 2965 #scrollToConversationEnd() { 2966 this.#conversationThreads.lastElementChild?.scrollIntoView({ behavior: 'smooth' }); 2967 } 2968 2969 #hideInputSection = () => { 2970 this.#modal.querySelector('[data-name="ai_modal_input_section"]').classList.add("hidden"); 2971 } 2972 2973 #showInputSection = () => { 2974 this.#modal.querySelector('[data-name="ai_modal_input_section"]').classList.remove("hidden"); 2975 } 2976 2977 #hideAIModal = () => { 2978 this.#modal.classList.add("hidden"); 2979 this.#overlay.classList.add("hidden"); 2980 } 2981 2982 #showAIModal = () => { 2983 this.#modal.classList.remove("hidden"); 2984 this.#overlay.classList.remove("hidden"); 2985 } 2986 2987 #setupManualLinks = () => { 2988 const movieBtn = this.#modal.querySelector('.cms-dialog-top-movie'); 2989 fetch(aiContentGeneration_videoManualApiURL) 2990 .then((res) => (res.ok ? res.text() : '')) 2991 .then((movieId) => { 2992 if (!movieId) return; 2993 movieBtn.addEventListener("click", () => OpenSubWin('https://www.youtube.com/embed/' + _uc(movieId) + '/?rel=0', 920, 520, 'movie_manual')); 2994 movieBtn.hidden = false; 2995 }) 2996 .catch(() => {}); 2997 const manualBtn = this.#modal.querySelector('.cms-dialog-top-help'); 2998 fetch(aiContentGeneration_helpCategoryApiURL) 2999 .then((res) => (res.ok ? res.text() : '')) 3000 .then((helpPath) => { 3001 if (!helpPath) return; 3002 manualBtn.addEventListener("click", () => OpenSubWin(aiContentGeneration_helpPageBaseURL + _us(helpPath), 760, 860, 'help')); 3003 manualBtn.hidden = false; 3004 }) 3005 .catch(() => {}); 3006 } 3007 3008 #templateModal = () => { 3009 let adminName = _h(this.#adminName); 3010 return ` 3011 <div id="ai_modal_overlay" class="cms-ai-overlay"></div> 3012 <div id="ai_modal" class="cms-ai-modal"> 3013 <div class="cms-ai-modal-header"> 3014 <div class="cms-ai-modal-header__title"> 3015 <div class="cms-ai-modal-header__title-text">ã´ã¼ã´ã¼AIã§çæ</div> 3016 <div class="cms-ai-badge"> 3017 <div class="cms-ai-badge__icon"> 3018 <img src="/_administrator/css/default/images/ai/logo-gogoai.svg" alt="AI"> 3019 </div> 3020 <div class="cms-ai-badge__body"> 3021 <div class="cms-ai-badge__text">BETA</div> 3022 </div> 3023 </div> 3024 </div> 3025 <div class="cms-ai-modal-header__btn"> 3026 <span class="cms-helpsite-btn cms-dialog-top-movie" hidden> 3027 <svg> 3028 <use xlink:href="/_administrator/css/default/images/svg/symbol-defs.svg#icon-movie-manual"/> 3029 </svg> 3030 </span> 3031 <span class="cms-helpsite-btn cms-dialog-top-help" hidden> 3032 <svg> 3033 <use xlink:href="/_administrator/css/default/images/svg/symbol-defs.svg#icon-help"/> 3034 </svg> 3035 </span> 3036 <a class="cms-dialog-top-close" data-name="ai_modal_close_button"> 3037 <svg> 3038 <use xlink:href="/_administrator/css/default/images/svg/symbol-defs.svg#icon-close"/> 3039 </svg> 3040 </a> 3041 </div> 3042 </div> 3043 <div class="cms-ai-modal-body"> 3044 <div data-name="ai_modal_hello_by_ai" class="cms-ai-hello"> 3045 ããã«ã¡ã¯ã${adminName}ãã<br> 3046 ãæä¼ãã§ãããã¨ã¯ããã¾ããï¼ 3047 </div> 3048 3049 <div> 3050 <!-- div style="flex-grow: 1;
3050 overflow-y: scroll;" --> 3051 <div data-name="ai_modal_conversation_threads" 3052 style=" 3053 display: flex; 3054 flex-direction: column; 3055 gap: 12px; 3056 " 3057 > 3058 </div> 3059 </div> 3060 3061 <div> 3062 <div 3063 data-name="ai_modal_input_section" class="cms-chat-input-section"> 3064 <textarea data-name="ai_modal_options_user_request" class="cms-chat-user-request" 3065 rows="2" 3066 placeholder="ã´ã¼ã´ã¼AIã¸ã®ãªã¯ã¨ã¹ããå ¥åãã¦ã¿ããï¼\nãã¼ã³ã¨æåæ°ãé¸ã¶ã ãã§ãOKï¼" 3067 data-placeholder-for-empty="ã´ã¼ã´ã¼AIã¸ã®ãªã¯ã¨ã¹ããå ¥åãã¦ã¿ããï¼" 3068 ></textarea> 3069 3070 <div class="cms-chat-input-footer"> 3071 <div class="cms-chat-input-footer__option"> 3072 <div class="cms-chat-select"> 3073 <select data-name="ai_modal_options_tone" class="cms-chat-select-option"> 3074 <option value="" selected>ãã¼ã³ãæå®ããªã</option> 3075 </select> 3076 </div> 3077 <div class="cms-chat-select"> 3078 <select data-name="ai_modal_options_text_length" class="cms-chat-select-option"> 3079 <option value="" selected>æåæ°ãæå®ããªã</option> 3080 </select> 3081 </div> 3082 </div> 3083 <div class="cms-chat-input-footer__send"> 3084 <button type="button" data-name="ai_modal_send_chat_button" class="cms-btn-chat-send"> 3085 <svg> 3086 <use xlink:href="/_administrator/css/default/images/svg/symbol-defs.svg#icon-edit"></use> 3087 </svg> 3088 使 3089 </button> 3090 </div> 3091 </div> 3092 </div> 3093 </div> 3094 </div> 3095 <div class="cms-ai-modal-footer"> 3096 <div class="cms-ai-modal-footer__info"> 3097 â»AIã§çæãããããã¹ãã§ããæåæ°ã¯æ¦ç®ã§ãããå 容ã«èª¤ããããå¯è½æ§ãããã¾ãã®ã§ãã確èªã®ä¸ãå©ç¨ãã ããã 3098 </div> 3099 <button type="button" data-name="ai_modal_btn_cancel" class="cms-ai-btn cms-ai-btn--cancel"> 3100 <svg> 3101 <use xlink:href="/_administrator/css/default/images/svg/symbol-defs.svg#icon-cancel"/> 3102 </svg> 3103 ãã£ã³ã»ã« 3104 </button> 3105 </div> 3106 </div> 3107 `; 3108 } 3109 3110 #templateUserChat = (chatId, chatByUser) => { 3111 chatId = _h(chatId); 3112 chatByUser = _h(chatByUser); 3113 3114 const tone = this.#toneOption.value || null; 3115 const textLength = this.#textLengthOption.value || null; 3116 let toneLabel = ''; 3117 if (tone !== null && tone !== '') { 3118 toneLabel = `ãã¼ã³ã${tone}ã`; 3119 } 3120 3121 let textLengthLabel = ''; 3122 if (textLength !== null && textLength !== '') { 3123 textLengthLabel = this.#textLengthOption.querySelector('option[value="' + textLength + '"]').textContent; 3124 textLengthLabel = `æåæ°ã${textLengthLabel}ã`; 3125 } 3126 const optionsText = toneLabel + textLengthLabel; 3127 3128 if (!chatByUser) { 3129 chatByUser = `<small><i>${optionsText ? optionsText + 'ã§' : ''}ã´ã¼ã´ã¼AIã«ãã¾ãã</i></small>`; 3130 } else if (optionsText) { 3131 chatByUser += `<br><small><i>${optionsText}</i></small>`; 3132 } 3133 // æ¹è¡ã<br>ã«å¤æ 3134 chatByUser = chatByUser.replace(/\n/g, '<br>'); 3135 return ` 3136 <div data-name="${chatId}" class="cms-ai-message-list cms-ai-message-list--end"> 3137 <div data-name="chatBubbleByUser" class="cms-ai-message cms-ai-message--me"> 3138 ${chatByUser} 3139 </div> 3140 </div> 3141 `; 3142 } 3143 3144 #templateAIChat = (chatId) => { 3145 chatId = _h(chatId); 3146 return ` 3147 <div data-name="${chatId}" class="cms-ai-message-list"> 3148 <div data-name="chatLabel"class="cms-ai-message-list__label">ç¾å¨ã®è¡¨ç¤ºå 容</div> 3149 <div data-name="chatBubbleByAI" data-showing-source="false" class="cms-ai-message cms-ai-message--ai"> 3150 </div> 3151 <div class="cms-btn-ai-group" data-name="actions"> 3152 <button type="button" class="cms-btn-ai-source" data-action="showSource" data-status="false"> 3153 <svg> 3154 <use xlink:href="/_administrator/css/default/images/svg/symbol-defs.svg#icon-source"/> 3155 </svg> 3156 ã½ã¼ã¹ 3157 </button> 3158 <button type="button" class="cms-btn-ai-decision" data-action="adopt"> 3159 <svg> 3160 <use xlink:href="/_administrator/css/default/images/svg/symbol-defs.svg#icon-ok"/> 3161 </svg> 3162 ä¸è¨ã§æ±ºå®ãã 3163 </button> 3164 </div> 3165 3166 <div data-name="rawChatByAI" style=" 3167 display: none; 3168 "> 3169 </div> 3170 </div> 3171 `; 3172 } 3173 3174 #templateLoadingIndicator = () => { 3175 return ` 3176 <div data-name="ai_content_generation_loading_indicator"> 3177 <div style=" 3178 display: flex; 3179 align-items: center; 3180 gap: 6px; 3181 "> 3182 <div class="cms-ai-loading-icon-pulse"></div> 3183 3184 <div 3185 style=" 3186 background: linear-gradient(-45deg,#fff 0%,#ccc 25%,#666 50%,#ccc 75%,#fff 100%); 3187 background-size: 200% auto; 3188 -webkit-background-clip: text; 3189 background-clip: text; 3190 color: transparent; 3191 animation: ai_modal_text_on_loading_shine 5s linear infinite; 3192 "> 3193 ã´ã¼ã´ã¼AIããã¹ããçæä¸... 3194 </div> 3195 <style>
3196 @keyframes ai_modal_text_on_loading_shine { 3197 0% { background-position: 300% center; } 3198 100% { background-position: -300% center; } 3199 } 3200 </style> 3201 </div> 3202 </div> 3203 `; 3204 } 3205 3206 } 3207 3208} 3209 3210 3211if (typeof globalThis.aiTextChecker !== 'function') { 3212 3213 const aiTextChecker_checkTypes = {"typo":{"label":"誤åè±åãã§ãã¯","description":"ã¿ã¤ããã¹ãéãä»®åã®èª¤ããåé³ç°ç¾©èªã®èª¤ç¨ï¼ãä¿éãã¨ãä¿è¨¼ããªã©ï¼ãå ¨è§åè§ã®æ··å¨ãªã©ããã§ãã¯ãã¾ãã","default":true},"expression":{"label":"æ¥æ¬èªè¡¨ç¾ãã§ãã¯","description":"ææ³ã®èª¤ãï¼ãæãè¨èã主述ã®ããããªã©ï¼ãæ¬èªã®èª¤ç¨ï¼äºéæ¬èªããããã¦ããã ããã®æ¿«ç¨ãªã©ï¼ãäºéå¦å®ãåé·è¡¨ç¾ããã§ãã¯ãã¾ãã","default":true},"consistency":{"label":"表è¨ãããã§ãã¯","description":"åãèªããã¼ã¸å ã§ç°ãªã表è¨ã«ãªã£ã¦ããç®æï¼ããµã¼ãã¼ãã¨ããµã¼ããã®ãããªé·é³è¨å·ã®ä¸çµ±ä¸ãã«ã¿ã«ãï¼æ¼¢åï¼ã²ãããªã®ä¸çµ±ä¸ãªã©ï¼ããã§ãã¯ãã¾ãã","default":true},"legal":{"label":"æ¯è¡¨æ³è¦³ç¹ãã§ãã¯","description":"åªè¯èª¤èªã»æå©èª¤èªã»ã¹ãã«ã¹ãã¼ã±ãã£ã³ã°ãªã©ãåºå表ç¾ã¨ãã¦ç¢ºèªãå¿ è¦ãªå¯è½æ§ã®ããè¨è¿°ããã§ãã¯ãã¾ãã","default":false}}; 3214 3215 const aiTextChecker_checkTypeLabels = Object.assign({}, {"typo":"誤åè±åãã§ãã¯","expression":"æ¥æ¬èªè¡¨ç¾ãã§ãã¯","consistency":"表è¨ãããã§ãã¯","legal":"æ¯è¡¨æ³è¦³ç¹ãã§ãã¯"}, { custom: 'ã«ã¹ã¿ã ãã§ãã¯' }); 3216 3217 const aiTextChecker_manualId = 'ã´ã¼ã´ã¼AIããã¹ããã§ãã¯'; 3218 const aiTextChecker_helpCategoryApiURL = 'https\x3a\x2f\x2fmanual\x2dv3\x2esecure\x2dcms\x2enet\x2fcategory\x2ephp\x3fc\x3d' + encodeURIComponent(aiTextChecker_manualId); 3219 const aiTextChecker_videoManualApiURL = 'https\x3a\x2f\x2fmanual\x2dv3\x2esecure\x2dcms\x2enet\x2fvideomanual\x2ephp\x3fc\x3d' + encodeURIComponent(aiTextChecker_manualId); 3220 const aiTextChecker_helpPageBaseURL = '\x2f\x5fadministrator\x2feditor\x2fhelp'; 3221 3222 globalThis.aiTextChecker = class aiTextChecker { 3223 #pageElementCollector = null; 3224 #checkApiClient = null; 3225 #issueListRenderer = null; 3226 #issueOverlayController = null; 3227 constructor(){ 3228 this.#initializeServices(); 3229 } 3230 3231 // ç¾å¨éãã¦ããã¤ã³ã¹ã¿ã³ã¹ãããã¼ãã£ã³ã°ãã¿ã³ã¯æ¯å new ãããããåãªã¼ãã³æã«åã¤ã³ã¹ã¿ã³ã¹ã® 3232 // å¾å§æ«ï¼ããã/ã¹ãããã©ã¤ã/ã°ãã¼ãã«ãªã¹ãã¼/ã¿ã¤ãï¼ã確å®ã«éãããã®ä¸ä»£ç®¡çã«ä½¿ãã 3233 static #activeInstance = null; 3234 3235 #modal = null; 3236 #overlay = null; 3237 #shadowHost = null; 3238 #shadowRoot = null; 3239 #modalCssPath = '/_administrator/css/default/ai_text_checker_modal.css'; 3240 #globalCssPath = '/_administrator/css/default/ai_text_checker_global.css'; 3241 #elementMap = null; // æ¡çªID 㨠å®DOMè¦ç´ 㨠æ½åºããã¹ã ã®å¯¾å¿ 3242 #selectionWait = null; // #waitForCheckSelection ã® Promise 解決ç¨ï¼Ãã§éããã¨ã null ãè¿ãï¼ 3243 3244 #initializeServices() { 3245 this.#pageElementCollector = new pageElementCollector(); 3246 this.#checkApiClient = new checkApiClient(); 3247 this.#issueOverlayController = new issueOverlayController({ 3248 doc: window.top.document, 3249 pageElementCollector: this.#pageElementCollector, 3250 modalAccessor: { 3251 isMinimized: () => !!(this.#modal && this.#modal.classList.contains('aiTextCheckerModalMinimized')), 3252 expand: () => { 3253 if (this.#modal && this.#modal.classList.contains('aiTextCheckerModalMinimized')) { 3254 this.#toggleMinimize(); 3255 } 3256 }, 3257 focusCard: (idx) => { 3258 if (!this.#shadowRoot) return; 3259 const cards = this.#shadowRoot.querySelectorAll('.aiTextCheckerIssueList > li'); 3260 const card = cards[idx]; 3261 if (!card) return; 3262 card.scrollIntoView({ behavior: 'smooth', block: 'center' }); 3263 card.classList.add('aiTextCheckerIssueCardFocused'); 3264 setTimeout(() => card.classList.remove('aiTextCheckerIssueCardFocused'), 1500); 3265 }, 3266 }, 3267 }); 3268 } 3269 3270 #initializeViewServices() { 3271 this.#issueListRenderer = new issueListRenderer({ 3272 shadowRoot: this.#shadowRoot, 3273 checkTypeLabels: aiTextChecker_checkTypeLabels, 3274 onPanelModeRequired: () => this.#enterPanelMode(), 3275 onJumpToElement: (elementId, idx) => { 3276 const el = this.#pageElementCollector.resolve(this.#elementMap, elementId); 3277 if (el) this.#issueOverlayController.jumpToElement(el, idx); 3278 }, 3279 onResolvedChange: (idx, reviewed) => { 3280 this.#issueOverlayController.setChipReviewed(idx, reviewed); 3281 }, 3282 }); 3283 } 3284 3285 // ========== å ¬é API ========== 3286 3287 async open() { 3288 // ç¾å¨éãã¦ããã¤ã³ã¹ã¿ã³ã¹ãããã°ããã®å¾å§æ«ãéãã¦ç¢ºå®ã«ä¸ä»£äº¤ä»£ããã 3289 this.#takeOverActiveInstance(); 3290 3291 // ã¢ã¼ãã«ãåæåãã表示ç¨ãµã¼ãã¹ãæ§ç¯ããã 3292 await this.#setupModal(); 3293 3294 // ãã§ãã¯é ç®é¸æ â å®è¡ â ã¨ã©ã¼æã¯ alert_dialog ã® OK å¾ ã¡ â å鏿 ã®ã«ã¼ãã 3295 // ã¨ã©ã¼æã¯ãã©ã¼ã DOM ãç ´æ£ãããã¼ãã£ã³ã°è¡¨ç¤ºã ãéã/è§£é¤ãã¦ãããããå ¥åï¼ãã§ãã¯ç¨®å¥ã»ã«ã¹ã¿ã ããã³ããï¼ã¯èªåçã«ä¿æãããã 3296 while (true) { 3297 const selection = await this.#waitForCheckSelection(); 3298 if (!selection) return; 3299
3300 const errorMessage = await this.#runCheckAndShowResults(selection); 3301 if (errorMessage === null) return; 3302 await this.#showError(errorMessage); 3303 } 3304 } 3305 3306 // ç¾å¨ãçµæè¡¨ç¤ºä¸ã®ãã¤ã³ã¹ã¿ã³ã¹ãåå¨ããã 3307 static hasActiveResults() { 3308 return !!(aiTextChecker.#activeInstance && aiTextChecker.#activeInstance.#hasResults()); 3309 } 3310 3311 // ããã¼ãã£ã³ã°ãã¿ã³çãå¤é¨ããã®èµ·åå£ãçµæè¡¨ç¤ºä¸ã®ä¸æ¸ãèµ·åã¯ç¢ºèªãæãã 3312 static openWithConfirm() { 3313 if (aiTextChecker.hasActiveResults()) { 3314 const inst = aiTextChecker.#activeInstance; 3315 if (inst.#confirmDiscardResults('表示ä¸ã®ãã§ãã¯çµæã¯å¤±ããã¾ãããããããã§ããï¼', () => new aiTextChecker().open())) { 3316 return; 3317 } 3318 } 3319 new aiTextChecker().open(); 3320 } 3321 3322 // ========== ã¡ã¤ã³ããã¼ ========== 3323 3324 #takeOverActiveInstance() { 3325 // ååéããã¤ã³ã¹ã¿ã³ã¹ãéãããã¦ããªããã°ããã®å¾å§æ«ãéãã¦ããä¸ä»£äº¤ä»£ããã 3326 // ï¼ãããããªã㨠top document ä¸ã®ããã/ã¹ãããã©ã¤ãã scroll/resize ãªã¹ãã¼ãæ®çã»èç©ããï¼ 3327 if (aiTextChecker.#activeInstance && aiTextChecker.#activeInstance !== this) { 3328 aiTextChecker.#activeInstance.#closeModal(); 3329 } 3330 aiTextChecker.#activeInstance = this; 3331 } 3332 3333 async #setupModal() { 3334 await this.#initModal(); 3335 this.#initializeViewServices(); 3336 } 3337 3338 #waitForCheckSelection() { 3339 return new Promise((resolve) => { 3340 this.#selectionWait = { resolve }; 3341 this.#renderCheckTypeSelectionScreen(); 3342 }); 3343 } 3344 3345 /** 3346 * ãã§ãã¯ãå®è¡ãã¦çµæã表示ããã 3347 * @return nullï¼æå or abortï¼ãã¾ã㯠stringï¼ã¨ã©ã¼ã¡ãã»ã¼ã¸ãå¼ã³åºãå´ã§ showError ã¸æ¸¡ãï¼ 3348 */ 3349 async #runCheckAndShowResults({ selectedTypes, customPrompt }) { 3350 this.#showLoading(); 3351 3352 this.#elementMap = this.#pageElementCollector.collect('#cms_contents_area') ?? new Map(); 3353 3354 const pageElements = [...this.#elementMap].map(([id, { text }]) => ({ id, text })); 3355 const result = await this.#checkApiClient.check(pageElements, selectedTypes, customPrompt); 3356 3357 if (result.aborted) return null; 3358 if (!result.ok) return result.message; 3359 3360 const results = result.issues; 3361 this.#issueListRenderer.showResults(results); 3362 if (results.length > 0) { 3363 this.#issueOverlayController.show(results, this.#elementMap); 3364 } else { 3365 this.#issueOverlayController.destroy(); 3366 } 3367 return null; 3368 } 3369 3370 // ========== ãã§ãã¯é ç®é¸æç»é¢ ========== 3371 3372 #renderCheckTypeSelectionScreen() { 3373 const body = this.#shadowRoot.querySelector('.aiTextCheckerBody'); 3374 if (!body) { 3375 const wait = this.#selectionWait; 3376 this.#selectionWait = null; 3377 wait?.resolve(null); 3378 return; 3379 } 3380 3381 // æ¢ã«ãã©ã¼ã æ§ç¯æ¸ã¿ãªãåæ§ç¯ããªãï¼å ¥åä¿æãã¨ã©ã¼å鏿æã¯ã«ã¼ãã§ããã«æ»ã£ã¦ããããï¼ã 3382 // éå§ãã¿ã³ã® click ãã³ãã©ã¯ this.#selectionWait ãé½åº¦åç §ããã®ã§ãæ°ãã Promise ã® resolve ãæ¾ããã 3383 if (body.querySelector('.aiTextCheckerSelectScreen')) { 3384 return; 3385 } 3386 3387 let listHtml = ''; 3388 for (const [key, config] of Object.entries(aiTextChecker_checkTypes)) { 3389 const checked = config.default ? 'checked' : ''; 3390 const infoHtml = config.description ? ` 3391 <span class="aiTextCheckerCheckTypeInfo" tabindex="0" aria-label="${_h(config.label)}ã®èª¬æ"> 3392 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="9"/><line x1="12" y1="11" x2="12" y2="16"/><line x1="12" y1="8" x2="12" y2="8"/></svg> 3393 <span class="aiTextCheckerCheckTypeTooltip" role="tooltip">${_h(config.description)}</span> 3394 </span> 3395 ` : ''; 3396 listHtml += ` 3397 <li class="aiTextCheckerCheckTypeItem"> 3398 <label> 3399 <input type="checkbox" name="checkType" value="${key}" ${checked}> 3400 <span>${_h(config.label)}</span> 3401 </label> 3402 ${infoHtml} 3403 </li> 3404 `; 3405 } 3406 3407 body.innerHTML = ` 3408 <div class="aiTextCheckerSelectScreen"> 3409 <div class="aiTextCheckerScopeNote"> 3410 <span class="aiTextCheckerScopeNoteText">ãã®ãã§ãã¯ã¯ç¾å¨ç»é¢ã«è¡¨ç¤ºããã¦ããããã¤ã¬ã¯ãç·¨éãã§ããããã¹ãã対象ã§ããåºå®ã®è£ 飾æè¨ãç»åå ã®æåãªã©ã¯å«ã¾ãã¾ããã</span> 3411 </div> 3412 <p class="aiTextCheckerSelectDesc">ãã§ãã¯ãããé ç®ã鏿ãã¦ãã ãã</p> 3413 <ul class="aiTextCheckerCheckTypeList">${listHtml}</ul> 3414 <div class="aiTextCheckerCustomSection"> 3415 <label class="aiTextCheckerCustomLabel">ã«ã¹ã¿ã ãã§ãã¯ã追å ï¼ä»»æï¼</label> 3416 <textarea class="aiTextCheckerCustomInput" name="customPrompt" placeholder="ä¾
3416: \nã»ãã客æ§ãã¨ãã客ãã¾ããæ··å¨ãã¦ããªããã¨ããã§ãã¯\nã»èªç¤¾åãããµã³ãã«æ ªå¼ä¼ç¤¾ãã§ã¯ãªããæ ªå¼ä¼ç¤¾ãµã³ãã«ãã§çµ±ä¸ããã¦ãããã¨ããã§ãã¯\nã»ç¦æ¢ã¯ã¼ããæå®å¤ããå«ã¾ãã¦ããªããã¨ããã§ãã¯"></textarea> 3417 </div> 3418 <button class="aiTextCheckerStartBtn">ãã§ãã¯éå§</button> 3419 </div> 3420 `; 3421 3422 const startBtn = body.querySelector('.aiTextCheckerStartBtn'); 3423 const checkboxes = body.querySelectorAll('input[name="checkType"]'); 3424 const customInput = body.querySelector('.aiTextCheckerCustomInput'); 3425 3426 const updateBtnState = () => { 3427 const anyChecked = Array.from(checkboxes).some(cb => cb.checked); 3428 const hasCustom = customInput.value.trim() !== ''; 3429 startBtn.disabled = !anyChecked && !hasCustom; 3430 }; 3431 checkboxes.forEach(cb => cb.addEventListener('change', updateBtnState)); 3432 customInput.addEventListener('input', updateBtnState); 3433 updateBtnState(); 3434 3435 startBtn.addEventListener('click', () => { 3436 const selectedTypes = Array.from(checkboxes) 3437 .filter(cb => cb.checked) 3438 .map(cb => cb.value); 3439 const customPrompt = customInput.value.trim(); 3440 3441 const wait = this.#selectionWait; 3442 this.#selectionWait = null; 3443 wait?.resolve({ selectedTypes, customPrompt }); 3444 }); 3445 } 3446 3447 // ========== çµæãªã¹ã表示ï¼ã¢ã¼ãã«å ï¼ ========== 3448 3449 #enterPanelMode() { 3450 if (!this.#modal) return; 3451 3452 // å®äºæ¼åº: ä¸å¤®ã¢ã¼ãã«ããç¬æã«ã¿ãã ãã®ç¶æ ãã¸éé¿ããå³ãããã£ããã¹ã©ã¤ãã¤ã³ãããã 3453 // ï¼å³ã«é ãã/åºããUIã§ãããã¨ãããã¨ãªãä¼ããããã®è¦ãæ¹ï¼ 3454 3455 // 1. transition ãç¡å¹åããã¾ã¾ ããã«+æå°å ã䏿¬é©ç¨ â é ããåãã¯è¦ããä¸ç¬ã§ã¿ãã ãã« 3456 this.#modal.classList.add('aiTextCheckerNoAnim', 'aiTextCheckerModalPanel', 'aiTextCheckerModalMinimized'); 3457 if (this.#overlay) this.#overlay.classList.add('aiTextCheckerOverlayTransparent'); 3458 this.#setTabHandleState(true); 3459 3460 // 2. reflow ãå¼·å¶ãã¦æå°åç¶æ ã確å®ããã¦ãã transition ã復帰 3461 void this.#modal.offsetWidth; 3462 this.#modal.classList.remove('aiTextCheckerNoAnim'); 3463 3464 // 3. 次ãã¬ã¼ã ã§æå°åãè§£é¤ â å³ããã¹ã©ã¤ãã¤ã³ï¼Entering ã§é度ã調æ´ï¼ 3465 this.#modal.classList.add('aiTextCheckerModalEntering'); 3466 requestAnimationFrame(() => { 3467 if (!this.#modal) return; 3468 this.#modal.classList.remove('aiTextCheckerModalMinimized'); 3469 this.#setTabHandleState(false); 3470 const onEnd = (e) => { 3471 if (e.propertyName !== 'transform') return; 3472 this.#modal.classList.remove('aiTextCheckerModalEntering'); 3473 this.#modal.removeEventListener('transitionend', onEnd); 3474 }; 3475 this.#modal.addEventListener('transitionend', onEnd); 3476 }); 3477 } 3478 3479 // ========== ã¢ã¼ãã« ========== 3480 3481 async #initModal() { 3482 const doc = window.top.document; 3483 3484 doc.getElementById('aiTextCheckerModal')?.remove(); 3485 doc.getElementById('aiTextCheckerOverlay')?.remove(); 3486 doc.getElementById('aiTextCheckerShadowHost')?.remove(); 3487 // åã¤ã³ã¹ã¿ã³ã¹ã top document ã«æ®ããããã/ã¹ãããã©ã¤ãã念ã®ããé¤å»ããï¼äºéè¡¨ç¤ºé²æ¢ã®ä¿éºï¼ 3488 doc.getElementById('aiTextCheckerChipLayer')?.remove(); 3489 doc.getElementById('aiTextCheckerSpotlight')?.remove(); 3490 3491 this.#shadowHost = doc.createElement('div'); 3492 this.#shadowHost.id = 'aiTextCheckerShadowHost'; 3493 // Shadow DOM å é¨ã® z-index 㯠Shadow Host å¤ã«ã¯å½±é¿ããªãããã 3494 // Host èªä½ãæåé¢ã® stacking context ã«ããã 3495 // CMSã®å³ã¯ãªãã¯ã¡ãã¥ã¼(.cms_context_menu)ã¯å® computed z-index ã 2147483643 (int32 maxä»è¿) ã®ããã 3496 // ãããä¸åãããã« z-index 㯠int32 æå¤§å¤ã® 2147483647 ã使ãã 3497 this.#shadowHost.style.cssText = 'position:fixed;top:0;left:0;width:0;height:0;z-index:2147483647;'; 3498 doc.body.appendChild(this.#shadowHost); 3499 3500 this.#shadowRoot = this.#shadowHost.attachShadow({ mode: 'open' }); 3501 3502 const style = document.createElement('link'); 3503 style.rel = 'stylesheet'; 3504 style.href = this.#modalCssPath + '?t=1790968415'; 3505 3506 await new Promise(resolve => { 3507 style.onload = resolve; 3508 style.onerror = resolve; 3509 this.#shadowRoot.appendChild(style); 3510 }); 3511 3512 // ãããã»ãã§ãã¯ç¯å²ãã¤ã©ã¤ã㯠Shadow å¤ï¼ãã¼ã¸å ¨ä½ã¹ã³ã¼ãï¼ã«æç»ãããããã 3513 // top ã® head ã«ã°ãã¼ãã«ã¹ã¿ã¤ã«ãèªã¿è¾¼ãï¼åãªã¼ãã³æã®äºéèªã¿è¾¼ã¿ã¯é²ãï¼ 3514 if (!doc.getElementById('aiTextCheckerGlobalStyle')) { 3515 const globalStyle = doc.createElement('link'); 3516 globalStyle.id = 'aiTextCheckerGlobalStyle'; 3517 globalStyle.rel = 'stylesheet'; 3518 globalStyle.href = this.#globalCssPath + '?t=1790968415'; 3519 await new Promise(resolve => { 3520 globalStyle.onload = resolve; 3521 globalStyle.onerror = resolve; 3522 doc.head.appendChild(globalStyle); 3523 }); 3524 } 3525
3526 this.#overlay = document.createElement('div'); 3527 this.#overlay.id = 'aiTextCheckerOverlay'; 3528 // overlay ã¯ãªãã¯ã§ã¯éããªãï¼å³ä¸ã®Ããã¿ã³ããã®ã¿éãã仿§ï¼ 3529 this.#shadowRoot.appendChild(this.#overlay); 3530 3531 this.#modal = document.createElement('div'); 3532 this.#modal.id = 'aiTextCheckerModal'; 3533 this.#modal.innerHTML = ` 3534 <button class="aiTextCheckerTabHandle" type="button" title="æãããã" aria-label="æãããã"><span class="aiTextCheckerTabHandleTriangle"></span></button> 3535 <div class="aiTextCheckerHeader"> 3536 <h3> 3537 <span class="aiTextCheckerHeaderTitleText">ã´ã¼ã´ã¼AIããã¹ããã§ãã¯</span> 3538 <span class="aiTextCheckerBetaBadge" aria-label="ãã¼ã¿ç"> 3539 <span class="aiTextCheckerBetaBadgeIcon"><img src="/_administrator/css/default/images/ai/logo-gogoai.svg" alt="AI"></span> 3540 <span class="aiTextCheckerBetaBadgeBody"><span class="aiTextCheckerBetaBadgeText">BETA</span></span> 3541 </span> 3542 </h3> 3543 <div class="aiTextCheckerHeaderBtns"> 3544 <span class="aiTextCheckerHelpBtn aiTextCheckerMovieBtn" hidden> 3545 <svg> 3546 <use xlink:href="/_administrator/css/default/images/svg/symbol-defs.svg#icon-movie-manual"/> 3547 </svg> 3548 </span> 3549 <span class="aiTextCheckerHelpBtn aiTextCheckerManualBtn" hidden> 3550 <svg> 3551 <use xlink:href="/_administrator/css/default/images/svg/symbol-defs.svg#icon-help"/> 3552 </svg> 3553 </span> 3554 <a class="aiTextCheckerCloseBtn"> 3555 <svg> 3556 <use xlink:href="/_administrator/css/default/images/svg/symbol-defs.svg#icon-close"/> 3557 </svg> 3558 </a> 3559 </div> 3560 </div> 3561 <div class="aiTextCheckerBody"></div> 3562 <div class="aiTextCheckerFooter">æ¬ãã§ãã¯çµæã¯AIã«ããåèæ å ±ã§ãããæ³çå©è¨ã»æ³å¾äºåã®æä¾ãè¡ããã®ã§ã¯ããã¾ããããã¹ã¦ã®ãªã¹ã¯ãæ¤åºãããã¨ãä¿è¨¼ãããã®ã§ã¯ãªããåºåçµæã
3562®æ¡å¦ããã³è¡¨ç¾ã®å¤æã»è²¬ä»»ã¯å©ç¨è ã«å¸°å±ãã¾ãã<br>æçµçãªå¤æã¯æ³åæ å½è ã¾ãã¯å¼è·å£«ã«ã確èªãã ããã</div> 3563 `; 3564 this.#shadowRoot.appendChild(this.#modal); 3565 3566 this.#modal.querySelector('.aiTextCheckerCloseBtn').addEventListener('click', () => this.#requestClose()); 3567 this.#modal.querySelector('.aiTextCheckerTabHandle').addEventListener('click', () => this.#toggleMinimize()); 3568 this.#setupManualLinks(); 3569 } 3570 3571 #setupManualLinks() { 3572 const movieBtn = this.#modal.querySelector('.aiTextCheckerMovieBtn'); 3573 fetch(aiTextChecker_videoManualApiURL) 3574 .then((res) => (res.ok ? res.text() : '')) 3575 .then((movieId) => { 3576 if (!movieId) return; 3577 movieBtn.addEventListener('click', () => OpenSubWin('https://www.youtube.com/embed/' + _uc(movieId) + '/?rel=0', 920, 520, 'movie_manual')); 3578 movieBtn.hidden = false; 3579 }) 3580 .catch(() => {}); 3581 const manualBtn = this.#modal.querySelector('.aiTextCheckerManualBtn'); 3582 fetch(aiTextChecker_helpCategoryApiURL) 3583 .then((res) => (res.ok ? res.text() : '')) 3584 .then((helpPath) => { 3585 if (!helpPath) return; 3586 manualBtn.addEventListener('click', () => OpenSubWin(aiTextChecker_helpPageBaseURL + _us(helpPath), 760, 860, 'help')); 3587 manualBtn.hidden = false; 3588 }) 3589 .catch(() => {}); 3590 } 3591 3592 #toggleMinimize() { 3593 if (!this.#modal) return; 3594 const minimized = this.#modal.classList.toggle('aiTextCheckerModalMinimized'); 3595 this.#setTabHandleState(minimized); 3596 } 3597 3598 // ã¿ããã³ãã«ã®ã©ãã«ãæå°åç¶æ ã«åããã¦åãæ¿ããï¼ã¢ã¤ã³ã³ã®åã㯠CSS å´ã§åè»¢ï¼ 3599 #setTabHandleState(minimized) { 3600 if (!this.#modal) return; 3601 const tab = this.#modal.querySelector('.aiTextCheckerTabHandle'); 3602 if (!tab) return; 3603 tab.title = minimized ? 'å±éãã' : 'æãããã'; 3604 tab.setAttribute('aria-label', minimized ? 'å±éãã' : 'æãããã'); 3605 } 3606 3607 #showLoading() { 3608 const body = this.#shadowRoot.querySelector('.aiTextCheckerBody'); 3609 if (!body) return; 3610 const selectScreen = body.querySelector('.aiTextCheckerSelectScreen'); 3611 if (selectScreen) selectScreen.style.display = 'none'; 3612 if (!body.querySelector('.aiTextCheckerLoading')) { 3613 const loading = document.createElement('div'); 3614 loading.className = 'aiTextCheckerLoading'; 3615 loading.innerHTML = ` 3616 <div class="aiTextCheckerLoadingIcon"></div> 3617 <div class="aiTextCheckerLoadingText">AIãããã¹ãããã§ãã¯ãã¦ãã¾ã...</div> 3618 `; 3619 body.appendChild(loading); 3620 } 3621 } 3622 3623 #hideLoading() { 3624 const body = this.#shadowRoot.querySelector('.aiTextCheckerBody'); 3625 if (!body) return; 3626 const loading = body.querySelector('.aiTextCheckerLoading'); 3627 if (loading) loading.remove(); 3628 const selectScreen = body.querySelector('.aiTextCheckerSelectScreen'); 3629 if (selectScreen) selectScreen.style.display = ''; 3630 } 3631 3632 // ã¨ã©ã¼ã alert_dialog ã§è¡¨ç¤ºãããã¢ã¼ãã«ã¯éããããã¼ãã£ã³ã°ã ãè§£é¤ãã¦ãã©ã¼ã ãå表示ããã 3633 // 表示ä¸ã¯ shadowHost ã visibility:hidden ã§éé¿ãããOK æ¼ä¸æã«æ»ãï¼#confirmDiscardResults ã¨åãã¿ã¼ã³ï¼ã 3634 // OK æ¼ä¸ãå¾ ã£ã¦ããå¼ã³åºãå´ï¼open() ã®ã«ã¼ãï¼ãå鏿ç»é¢ã«æ»ãã 3635 #showError(message) { 3636 this.#hideLoading(); 3637 return new Promise((resolve) => { 3638 const dialog = window.top && window.top.alert_dialog; 3639 const host = this.#shadowHost; 3640 if (typeof dialog === 'function') { 3641 if (host) host.style.visibility = 'hidden'; 3642 dialog(message, undefined, () => { 3643 if (host) host.style.visibility = ''; 3644 resolve(); 3645 return true; 3646 }); 3647 return; 3648 } 3649 alert('ã¨ã©ã¼ãçºçãã¾ããã'); 3650 resolve(); 3651 }); 3652 } 3653 3654 // çµæè¡¨ç¤ºä¸ï¼ããã«ã¢ã¼ãï¼ãã©ãããaiTextCheckerModalPanel ã¯ã©ã¹ã¯ãã§ãã¯å®äºæã«ä»ä¸ãããã 3655 #hasResults() { 3656 return !!(this.#modal && this.#modal.classList.contains('aiTextCheckerModalPanel')); 3657 } 3658 3659 // çµæç ´æ£ç¢ºèªãã¤ã¢ãã°ã確èªãã¤ã¢ãã°ãçµæããã«ã«è¦ããã¦ãã¾ãããã 3660 // 表示ä¸ã¯ shadowHost ã visibility:hidden ã§éé¿ããããã£ã³ã»ã«æã«æ»ãã 3661 // ï¼cancel ã³ã¼ã«ããã¯ãåãããã Dialog.confirm ãç´æ¥å¼ã¶ï¼ 3662 #confirmDiscardResults(message, onOk) { 3663 const topWin = window.top; 3664 const dialog = topWin && topWin.Dialog; 3665 if (!dialog || typeof dialog.confirm !== 'function') return false;
3666 const host = this.#shadowHost; 3667 if (host) host.style.visibility = 'hidden'; 3668 if (topWin.jQuery && topWin.jQuery('#alert').length > 0) { 3669 topWin.jQuery('#alert').attr('id', 'alert-bf'); 3670 } 3671 dialog.confirm(message, { 3672 windowParameters: { width: 480, height: 150, zIndex: 1000000, duration: 0.1 }, 3673 className: 'alert', 3674 id: 'alert', 3675 okLabel: 'OK', 3676 ok: () => { onOk(); return true; }, 3677 cancelLabel: 'ãã£ã³ã»ã«', 3678 buttonClass: 'cms-btn', 3679 cancel: () => { if (host) host.style.visibility = ''; } 3680 }); 3681 return true; 3682 } 3683 3684 // Ããã¿ã³çµç±ã®éããè¦æ±ãçµæè¡¨ç¤ºä¸ã¯ç¢ºèªãã¤ã¢ãã°ãæãã 3685 #requestClose() { 3686 if (this.#hasResults()) { 3687 if (this.#confirmDiscardResults('表示ä¸ã®ãã§ãã¯çµæã¯å¤±ããã¾ãããããããã§ããï¼', () => this.#closeModal())) { 3688 return; 3689 } 3690 } 3691 this.#closeModal(); 3692 } 3693 3694 #closeModal() { 3695 if (this.#selectionWait) { 3696 this.#selectionWait.resolve(null); 3697 this.#selectionWait = null; 3698 }
3699 if (aiTextChecker.#activeInstance === this) { 3700 aiTextChecker.#activeInstance = null; 3701 } 3702 this.#checkApiClient.abort(); 3703 this.#issueOverlayController.destroy(); 3704 if (this.#shadowHost) { 3705 this.#shadowHost.remove(); 3706 this.#shadowHost = null; 3707 this.#shadowRoot = null; 3708 this.#modal = null; 3709 this.#overlay = null; 3710 } 3711 } 3712 3713 }; 3714 3715 class pageElementCollector { 3716 collect(rootId){ 3717 const root = document.querySelector(rootId); 3718 if (!root) { 3719 return new Map(); 3720 } 3721 3722 const consumed = new WeakSet(); // éè¤åé¿ã®ããã®å¦çæ¸ã¿è¦ç´ ã»ãã 3723 const elementMap = new Map(); 3724 3725 // cms-editor-* / cms-inlineedit-* : é常ã®ãã¤ã¬ã¯ãç·¨éè¦ç´ åä½ 3726 // EDIT-navigation-{æ°å¤} : navigation ã ã㯠cms-editor ãä»ãã EDIT- èªä½ãç·¨éåä½ã«ãªãç¹æ®ã¢ã¸ã¥ã¼ã«ãªã®ã§æç¤ºçã«å«ãã 3727 // â» EDIT-navigation-main / -footer ãªã©ã¯ã³ã³ãããªã®ã§é¤å¤ãããã¤ã¬ã¯ãç·¨éåä½ã® EDIT-navigation-{æ°å¤} ã®ã¿æ¡ç¨ 3728 // ãåèãcontext_menuV2.class.php onmouseover_init() 3729 const EXISTING_ID_SEL = '[id^="cms-editor-"],[id^="cms-inlineedit-"],[id^="EDIT-navigation-"]'; 3730 const EDIT_NAV_LEAF_RE = /^EDIT-navigation-\d+$/; 3731 3732 // ããã¹ã㯠#flattenWithMap ã§æ½åºãã 3733 root.querySelectorAll(EXISTING_ID_SEL).forEach(el => { 3734 3735 // EDIT-navigation-{æ°å¤ä»¥å¤}ã¯é¤å¤ 3736 if (el.id.startsWith('EDIT-navigation-') && !EDIT_NAV_LEAF_RE.test(el.id)) { 3737 return; 3738 } 3739 // éè¤åé¿ 3740 if (consumed.has(el)) { 3741 return; 3742 } 3743 // ãã¤ã¬ã¯ãç·¨éã§ããªãè¦ç´ ã¯å¯¾è±¡å¤ï¼ä¾: ãµã¤ãè¨å®ã®ã³ãã¼ã©ã¤ããªã© edit_easy 権éããªãã¢ã¸ã¥ã¼ã«ï¼ 3744 if (!this.#isDirectEditable(el)) { 3745 return; 3746 } 3747 3748 const text = this.#flattenWithMap(el).text; 3749 3750 // ããã¹ãã空ãªã対象å¤ï¼ä¾: ç»åã ãã®ãã¤ã¬ã¯ãç·¨éãã空ã®ãããã¯è¦ç´ ãªã©ï¼ 3751 if (!text) { 3752 return; 3753 } 3754 3755 // IDæ¡çªããå®DOMè¦ç´ ã¨æ½åºããã¹ããã¾ã¨ãã¦ç»é²ãã 3756 const id = 'e' + elementMap.size; 3757 elementMap.set(id, { el, text }); 3758 3759 // å¦çæ¸ã¿ã»ããã«å ¥ãããåå«è¦ç´ ããå¦çæ¸ã¿ãã¨ãã¦ç»é²ããéè¤å¦çãåé¿ãã 3760 consumed.add(el); 3761 el.querySelectorAll(EXISTING_ID_SEL).forEach(c => consumed.add(c)); 3762 }); 3763 3764 return elementMap; 3765 } 3766 3767 resolve(map, id){ 3768 if (!id || !map) return null; 3769 const entry = map.get(id); 3770 return entry ? entry.el : null; 3771 } 3772
3773 // ææè¦ç´ el ã®ä¸ãã original æååã«å¯¾å¿ãã Range ãçµã¿ç«ã¦ãã 3774 // ããã¹ãæ½åºã¯ #flattenWithMap ã«éç´ï¼éä¿¡å´ #collectPageElements ã¨åä¸ãã¸ãã¯ï¼ã 3775 // è¦ã¤ãããªããã° null ãè¿ãï¼ãã®ææã¯ãã¤ã©ã¤ããã¹ãããããï¼ã 3776 buildIssueRange(el, original) { 3777 const want = (original || '').replace(/\s+/g, ' ').trim(); 3778 if (!el || !want) return null; 3779 3780 const { text, boundaryMap } = this.#flattenWithMap(el); 3781 const startIndex = text.indexOf(want); 3782 if (startIndex < 0) return null; // åä¸ original ãè¤æ°ããå ´åã¯å é ä¸è´ã®ã¿æ¡ç¨ 3783 3784 // ä¾: text ã "ã ã" ã§ãwant ã "ã" ãªã startIndex 㯠2ã 3785 // "ã" ã®ãã¤ã©ã¤ãç¯å²ã¯ã2æåç®ã®åãããã2æåç®ã®å¾ãã¾ã§ãªã®ã§ã 3786 // boundaryMap[2] ãã boundaryMap[3] ã¾ã§ã Range ã«ããã 3787 const start = boundaryMap[startIndex]; 3788 const end = boundaryMap[startIndex + want.length]; 3789 if (!start || !end) return null; 3790 3791 const range = document.createRange(); 3792 range.setStart(start.node, start.offset); 3793 range.setEnd(end.node, end.offset); 3794 return range; 3795 } 3796 3797 /** 3798 * ãã®é¢æ°ã®ç®ç: 3799 * ãAIãèªãã æååãã¨ãå®éã®DOMä¸ã®ä½ç½®ãããã¨ã§çµã³ç´ããããã«ããã 3800 * 3801 * AIã«ã¯DOMããã®ã¾ã¾æ¸¡ããªãã®ã§ãã¾ã表示ããã¹ãã ãã1æ¬ã®æåå text ã«ããã 3802 * ãã ãããã®æç¹ã§ä»¥ä¸ã®ãããªå å·¥ãå ¥ãã 3803 * 3804 * <br> ããããã¯è¦ç´ ã®åºåã â åè§ã¹ãã¼ã¹1ã¤ã«ãã 3805 * æ¹è¡ãã¿ããé£ç¶ã¹ãã¼ã¹ â åè§ã¹ãã¼ã¹1ã¤ã«ãã 3806 * é表示è¦ç´ ã script/style â èªã¾ãªã 3807 * 3808 * ã¤ã¾ã AI ãè¦ã text ã¯ãDOMå ã®ããã¹ãããã®ã¾ã¾é£çµãããã®ã§ã¯ãªãã 3809 * 3810 * ããã§ text ãä½ããªãããboundaryMap ãåæã«ä½ãã 3811 * boundaryMap ã¯ãtext ã®åæåã®åå¾ããå DOMã®ã©ãã«å½ããããã®ã¡ã¢ã 3812 * 3813 * ä¾: 3814 * DOM : <div>ã<br>ã</div> 3815 * text: "ã ã" 3816 * 3817 * text ã®ä½ç½®: 3818 * 0æåç® = "ã" 3819 * 1æåç® = " " ï¼<br> ããä½ã£ãã¹ãã¼ã¹ï¼ 3820 * 2æåç® = "ã" 3821 * 3822 * boundaryMap: 3823 * [0] "ã" ã®å 3824 * [1] "ã" ã®å¾ 3825 * [2] "ã" ã®å 3826 * [3] "ã" ã®å¾ 3827 * 3828 * ãã¨ãã° AI ã®æææåã "ã" ãªããtext.indexOf("ã") 㯠2ã 3829 * "ã" ã¯1æåãªã®ã§ããã¤ã©ã¤ãç¯å²ã¯ boundaryMap[2] ãã boundaryMap[3] ã¾ã§ã 3830 * 3831 * ããã§ãAIãè¦ã text ä¸ã®ä½ç½®ããããã©ã¦ã¶ãå¿ è¦ã¨ãã DOM Range ã«æ»ããã 3832 */ 3833 #flattenWithMap(root) { 3834 // DOMãèªã¿ãªããããã®4ã¤ãæ´æ°ãã¦ããã 3835 const state = { 3836 text: '', // AI ã«éãæååãä¾: "ã ã" 3837 boundaryMap: [], // text ã®åå¾ã®ä½ç½®ããDOMä¸ã®ä½ç½®ã¨ãã¦è¦ããé å 3838 prevIsSpace: true, // true ã®éã¯ã次ã®ã¹ãã¼ã¹ã追å ããªã 3839 pendingSeparator: false, // <br> ãªã©ãè¦ã¤ããããã¾ã ã¹ãã¼ã¹ãå ¥ãã¦ããªãç¶æ 3840 }; 3841 3842 // DOMãã¼ãã1ã¤åãåããããã¹ããªãæåãèªã¿ãè¦ç´ ãªãä¸èº«ãå帰çã«èªãã 3843 const walk = (node) => { 3844 if (node.nodeType === Node.ELEMENT_NODE) { 3845 walkElement(node); 3846 return; 3847 } 3848 3849 if (node.nodeType === Node.TEXT_NODE) { 3850 walkTextNode(node); 3851 } 3852 }; 3853 3854 // è¦ç´ ãã¼ããèªããdiv ã p ãªã©ã®ãããã¯è¦ç´ ã¯ãåå¾ã«ã¹ãã¼ã¹ãå¿ è¦ã«ãªãã 3855 const walkElement = (el) => { 3856 const tag = el.tagName; 3857 3858 // script/style ç³»ã¯ç¡è¦ 3859 if (tag === 'SCRIPT' || tag === 'STYLE' || tag === 'NOSCRIPT' || tag === 'TEMPLATE') { 3860 return; 3861 } 3862 3863 const style = getComputedStyle(el); 3864 3865 // display:contents ã¯èªèº«ã®ããã¯ã¹ãæãã getClientRects() ã空ã»opacity ãå¹ããªããã 3866 // åã¯é常ã©ãã表示ãããããä¸å¯è¦æ±ãã«ããªãï¼åããã¹ããåããã¼ããªãããé¤å¤ããï¼ã 3867 const isContents = style.display === 'contents'; 3868 3869 // é表示è¦ç´ ã¯åãå«ãã¦ç¡è¦ 3870 if ( 3871 style.display === 'none' 3872 || style.visibility === 'hidden' 3873 || style.contentVisibility === 'hidden' 3874 || (!isContents && el.getClientRects().length === 0) 3875 ) { 3876 return; 3877 } 3878 3879 // <br> ã¯ãããã§æ¹è¡ãã¦ãããã¨ããå°ãªã®ã§ãæ¬¡ã®æåã®åã«ã¹ãã¼ã¹ãå ¥ããäºç´ããã 3880 if (tag === 'BR') { 3881 state.pendingSeparator = true; 3882 return; 3883 } 3884
3885 // span ã®ãã㪠inline / display:contents ã¯æã®éä¸ãªã®ã§åºåããªãããã以å¤ã¯ãããã¯æ±ãã 3886 const block = !(isContents || style.display.startsWith('inline')); 3887 3888 // ä¾: ãåã®æåã+ã<div>ã®ä¸ã®æåãããã£ã¤ããªãããã«ããã 3889 if (block) { 3890 state.pendingSeparator = true; 3891 } 3892 3893 // åãé çªã«èªããspan ãªã©ã®ã¤ã³ã©ã¤ã³è¦ç´ ã¯ãæ®éã®æã®éä¸ã¨ãã¦èªã¾ããã 3894 for (const child of el.childNodes) { 3895 walk(child); 3896 } 3897 3898 // ä¾: ã<div>ã®ä¸ã®æåã+ãå¾ãã®æåãããã£ã¤ããªãããã«ããã 3899 if (block) { 3900 state.pendingSeparator = true; 3901 } 3902 }; 3903 3904 // ããã¹ããã¼ãã®æåã1ã¤ãã¤èªãã 3905 // i ã¯ããã®ããã¹ããã¼ãå ã®ä½æåç®ããã§ããã¨ã§ Range ã® offset ã«ä½¿ãã 3906 const walkTextNode = (node) => { 3907 const value = node.nodeValue ?? ''; 3908 3909 for (let i = 0; i < value.length; i++) { 3910 const char = value[i]; 3911 3912 // ç©ºç½æåã¯å ¨é¨ã¾ã¨ãã¦ãtext ã«ã¯åè§ã¹ãã¼ã¹1ã¤ã ãå ¥ããã 3913 if (/\s/.test(char)) { 3914 if (!state.prevIsSpace) { 3915 appendChar(' ', { node, offset: i }, { node, offset: i + 1 }); 3916 state.prevIsSpace = true; 3917 } 3918 continue; 3919 } 3920 3921 // <br> ããããã¯å¢çã§äºç´ãã¦ããã¹ãã¼ã¹ãããã®å®æåã®åã«å ¥ããã 3922 flushSeparatorBefore({ 3923 node, 3924 offset: i, 3925 }); 3926 3927 // å®éã®æåã text ã«è¿½å ãããã®æåã®åå¾ã® DOM ä½ç½®ãè¦ããã 3928 appendRealChar(char, { 3929 node, 3930 offset: i, 3931 }, { 3932 node, 3933 offset: i + 1, 3934 }); 3935 } 3936 }; 3937 3938 // äºç´ãã¦ããåºåãããåè§ã¹ãã¼ã¹1ã¤ã¨ã㦠text ã«å ¥ããã 3939 // <br> ç±æ¥ã®ã¹ãã¼ã¹ã¯DOMä¸ã®å®æåã§ã¯ãªãã®ã§ãåå¾ã®ä½ç½®ã¯åã point ã«ããã 3940 const flushSeparatorBefore = (point) => { 3941 if (!state.pendingSeparator) { 3942 return; 3943 } 3944 3945 if (!state.prevIsSpace) { 3946 appendChar(' ', point, point); 3947 state.prevIsSpace = true; 3948 } 3949 state.pendingSeparator = false; 3950 }; 3951 3952 // 宿åã1ã¤è¿½å ããã追å å¾ã¯ãç´åã¯ç©ºç½ã§ã¯ãªããç¶æ ã«ãªãã 3953 const appendRealChar = (char, beforePoint, afterPoint) => { 3954 appendChar(char, beforePoint, afterPoint); 3955 state.prevIsSpace = false; 3956 state.pendingSeparator = false; 3957 }; 3958 3959 // text ã«1æå追å ãããã®æåã®å¾ãã®ä½ç½®ã boundaryMap ã«è¿½å ããã 3960 // æåã®æåã ãã¯ãæåã®åã®ä½ç½®ãå ã«å ¥ããã 3961 // 3962 // ä¾: "ã" ã追å ãã 3963 // boundaryMap = ["ã"ã®å, "ã"ã®å¾] 3964 // 3965 // 次㫠"ã" ã追å ãã 3966 // boundaryMap = ["ã"ã®å, "ã"ã®å¾, "ã"ã®å¾] 3967 const appendChar = (char, beforePoint, afterPoint) => { 3968 if (state.boundaryMap.length === 0) { 3969 state.boundaryMap.push(beforePoint); 3970 } 3971 3972 state.text += char; 3973 state.boundaryMap.push(afterPoint); 3974 }; 3975 3976 // æ«å°¾ã¹ãã¼ã¹ãåã£ããã対å¿ããæå¾ã®å¢çãä¸ç·ã«åãã 3977 const trimTrailingSpaces = () => { 3978 while (/\s$/.test(state.text)) { 3979 state.text = state.text.slice(0, -1); 3980 state.boundaryMap.pop(); 3981 } 3982 }; 3983 3984 walk(root); 3985 trimTrailingSpaces(); 3986 3987 return { 3988 text: state.text, 3989 boundaryMap: state.boundaryMap, 3990 }; 3991 } 3992 3993 3994 // ãã¤ã¬ã¯ãç·¨éãå¯è½ãªè¦ç´ ããå¤å®ããã 3995 // EDIT- ç¥å ï¼èªèº«å«ãï¼ã® id 第2ã»ã°ã¡ã³ããã¢ã¸ã¥ã¼ã«åã¨ããmodules[ã¢ã¸ã¥ã¼ã«å+'_manager']ï¼
3995auth.php ç±æ¥ï¼ã« 'edit_easy' ãããã確èªããã 3996 // ãåèãcontext_menuV2.class.php inline_edit() / onmouseover_init() / ondblclick_init() ã® edit_easy å¤å® 3997 #isDirectEditable(el) { 3998 // modules 㯠context_menuV2.class.php åé ã§åºåãããã°ãã¼ãã«å¤æ°ãç·¨éãµã¤ãç»é¢ä»¥å¤ã§ã¯åå¨ããªã 3999 if (typeof modules === 'undefined') { 4000 return false; 4001 } 4002 if (typeof context_menu === 'undefined' || typeof context_menu.search_parent_node_by_id !== 'function') { 4003 return false; 4004 } 4005 const parent = context_menu.search_parent_node_by_id(el,'EDIT-'); 4006 if(!parent) { 4007 return false; 4008 } 4009 const menuId = parent.id.split('-')[1] || null; 4010 if (!menuId) { 4011 return false; 4012 } 4013 const auth = modules[menuId + '_manager']; 4014 if (!Array.isArray(auth)) { 4015 return false; 4016 } 4017 return auth.indexOf('edit_easy') >= 0; 4018 } 4019 } 4020 4021 class checkApiClient { 4022 #abortController = null; 4023 4024 async check(pageElements, selectedTypes, customPrompt) { 4025 this.#abortController?.abort(); 4026 const controller = new AbortController(); 4027 this.#abortController = controller; 4028 4029 try { 4030 const formData = new FormData(); 4031 formData.append('q', 'ai_text_checker_manager/check_text'); 4032 formData.append('do', 'ai_text_checker_manager/check_text'); 4033 formData.append('page_elements', JSON.stringify(pageElements)); 4034 selectedTypes.forEach(type => formData.append('check_types[]', type)); 4035 formData.append('custom_prompt', customPrompt || ''); 4036 4037 const response = await fetch('/_administrator/connector.php', { 4038 method: 'POST', 4039 body: formData, 4040 credentials: 'same-origin', 4041 signal: controller.signal, 4042 headers: { 4043 'X-Requested-With': 'XMLHttpRequest', 4044 }, 4045 }); 4046 4047 if (!response.ok) { 4048 return { ok: false, message: 'äºæãã¬ã¨ã©ã¼ãçºçãã¾ããã' }; 4049 } 4050 4051 const data = await response.json(); 4052 4053 if (!data || !data.success) { 4054 return { ok: false, message: (data && data.message) || 'äºæãã¬ã¨ã©ã¼ãçºçãã¾ããã' }; 4055 } 4056 4057 if (Array.isArray(data.issues)) { 4058 return { ok: true, issues: data.issues }; 4059 } 4060 4061 return { ok: false, message: 'äºæãã¬ã¨ã©ã¼ãçºçãã¾ããã' }; 4062 } catch (e) { 4063 if (e.name === 'AbortError') { 4064 return { ok: false, aborted: true }; 4065 } 4066 return { ok: false, message: 'äºæãã¬ã¨ã©ã¼ãçºçãã¾ããã' }; 4067 } 4068 } 4069 4070 abort() { 4071 if (this.#abortController) { 4072 this.#abortController.abort(); 4073 this.#abortController = null; 4074 } 4075 } 4076 } 4077 4078 class issueListRenderer { 4079 #shadowRoot = null; 4080 #checkTypeLabels = null; 4081 #onJumpToElement = null; 4082 #onPanelModeRequired = null; 4083 #onResolvedChange = null; 4084 4085 constructor({ 4086 shadowRoot, 4087 checkTypeLabels, 4088 onPanelModeRequired, 4089 onJumpToElement, 4090 onResolvedChange, 4091 }) { 4092 this.#shadowRoot = shadowRoot; 4093 this.#checkTypeLabels = checkTypeLabels; 4094 this.#onPanelModeRequired = onPanelModeRequired; 4095 this.#onJumpToElement = onJumpToElement; 4096 this.#onResolvedChange = onResolvedChange; 4097 } 4098 4099 showResults(results) { 4100 if (results.length === 0) { 4101 this.#showNoIssue(); 4102 return; 4103 } 4104 4105 this.#showIssueList(results); 4106 } 4107 4108 #showNoIssue() { 4109 const body = this.#shadowRoot.querySelector('.aiTextCheckerBody'); 4110 if (!body) return; 4111 4112 body.innerHTML = ` 4113 <div class="aiTextCheckerNoIssue"> 4114 <div class="aiTextCheckerNoIssueSparkles" aria-hidden="true"> 4115 <span class="aiTextCheckerNoIssueSparkle"></span> 4116 <span class="aiTextCheckerNoIssueSparkle"></span> 4117 <span class="aiTextCheckerNoIssueSparkle"></span> 4118 <span class="aiTextCheckerNoIssueSparkle"></span> 4119 <span class="aiTextCheckerNoIssueSparkle"></span> 4120 <span class="aiTextCheckerNoIssueSparkle"></span> 4121 <span class="aiTextCheckerNoIssueSparkle"></span> 4122 <span class="aiTextCheckerNoIssueSparkle"></span> 4123 </div> 4124 <div class="aiTextCheckerNoIssueStage" aria-hidden="true"> 4125 <svg viewBox="0 0 320 200" width="320" height="200" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet"> 4126 <defs> 4127 <linearGradient id="aiTextCheckerPopperCone" x1="0%" y1="100%" x2="100%" y2="0%"> 4128 <stop offset="0%" stop-color="#DA5765"/> 4129 <stop offset="55%" stop-color="#ED7C33"/> 4130 <stop offset="100%" stop-color="#FFA000"/> 4131 </linearGradient> 4132 </defs> 4133 <g class="aiTextCheckerNoIssuePopperPiece" style="--ai-tcp-i:1;--ai-tcp-x:130px;--ai-tcp-y:30px;--ai-tcp-dx:-40px;--ai-tcp-dy:30px;--ai-tcp-rot:14deg;--ai-tcp-fall:90px"> 4134 <rect x="125" y="25" width="10" height="10" rx="2" fill="#DA5765" transform="rotate(18 130 30)"/> 4135 </g> 4136 <g class="aiTextCheckerNoIssuePopperPiece" style="--ai-tcp-i:2;--ai-tcp-x:158px;--ai-tcp-y:18px;--ai-tcp-dx:-30px;--ai-tcp-dy:22px;--ai-tcp-rot:-10deg;--ai-tcp-fall:105px"> 4137 <circle cx="158" cy="18" r="4" fill="#3FA9F5"/> 4138 </g> 4139 <g class="aiTextCheckerNoIssuePopperPiece" style="--ai-tcp-i:3;--ai-tcp-x:108px;--ai-tcp-y:60px;--ai-tcp-dx:-45px;--ai-tcp-dy:28px;--ai-tcp-rot:24deg;--ai-tcp-fall:80px"> 4140 <rect x="103" y="55" width="9" height="9" rx="2" fill="#FFD66E" transform="rotate(-18 108 60)"/> 4141 </g> 4142 <g class="aiTextCheckerNoIssuePopperPiece" style="--ai-tcp-i:4;--ai-tcp-x:142px;--ai-tcp-y:78px;--ai-tcp-dx:-32px;--ai-tcp-dy:20px;--ai-tcp-rot:-22deg;--ai-tcp-fall:95px"> 4143 <circle cx="142" cy="78" r="4" fill="#7ED321"/> 4144 </g> 4145 <g class="aiTextCheckerNoIssuePopperPiece" style="--ai-tcp-i:5;--ai-tcp-x:172px;--ai-tcp-y:55px;--ai-tcp-dx:-25px;--ai-tcp-dy:18px;--ai-tcp-rot:32deg;--ai-tcp-fall:85px"> 4146 <rect x="167" y="50" width="9" height="9" rx="2" fill="#9B59B6" transform="rotate(28 172 55)"/> 4147 </g> 4148 <g class="aiTextCheckerNoIssuePopperPiece" style="--ai-tcp-i:6;--ai-tcp-x:120px;--ai-tcp-y:95px;--ai-tcp-dx:-38px;--ai-tcp-dy:18px;--ai-tcp-rot:-30deg;--ai-tcp-fall:70px"> 4149 <rect x="116" y="91" width="7" height="7" rx="1.5" fill="#E94B7C" transform="rotate(-25 119 94)"/> 4150 </g> 4151 <g class="aiTextCheckerNoIssuePopperPiece" style="--ai-tcp-i:7;--ai-tcp-x:154px;--ai-tcp-y:40px;--ai-tcp-dx:-30px;--ai-tcp-dy:22px;--ai-tcp-rot:0deg;--ai-tcp-fall:90px"> 4152 <path d="M144 36 Q154 26 164 36 Q170 42 162 50" stroke="#FFD66E" stroke-width="2.5" fill="none" stroke-linecap="round"/> 4153 </g> 4154 <g class="aiTextCheckerNoIssuePopperPiece" style="--ai-tcp-i:8;--ai-tcp-x:188px;--ai-tcp-y:32px;--ai-tcp-dx:-22px;--ai-tcp-dy:25px;--ai-tcp-rot:-16deg;--ai-tcp-fall:100px"> 4155 <circle cx="188" cy="32" r="3" fill="#1ABC9C"/> 4156 </g> 4157 <g class="aiTextCheckerNoIssuePopperPiece" style="--ai-tcp-i:9;--ai-tcp-x:128px;--ai-tcp-y:48px;--ai-tcp-dx:-36px;--ai-tcp-dy:26px;--ai-tcp-rot:18deg;--ai-tcp-fall:88px"> 4158 <circle cx="128" cy="48" r="3" fill="#FFA000"/> 4159 </g> 4160 <g class="aiTextCheckerNoIssuePopperPiece" style="--ai-tcp-i:10;--ai-tcp-x:215px;--ai-tcp-y:30px;--ai-tcp-dx:40px;--ai-tcp-dy:30px;--ai-tcp-rot:-14deg;--ai-tcp-fall:90px"> 4161 <rect x="210" y="25" width="10" height="10" rx="2" fill="#1ABC9C" transform="rotate(-18 215 30)"/> 4162 </g> 4163 <g class="aiTextCheckerNoIssuePopperPiece" style="--ai-tcp-i:11;--ai-tcp-x:190px;--ai-tcp-y:14px;--ai-tcp-dx:30px;--ai-tcp-dy:22px;--ai-tcp-rot:10deg;--ai-tcp-fall:108px"> 4164 <circle cx="190" cy="14" r="4" fill="#9B59B6"/> 4165 </g> 4166 <g class="aiTextCheckerNoIssuePopperPiece" style="--ai-tcp-i:12;--ai-tcp-x:236px;--ai-tcp-y:60px;--ai-tcp-dx:45px;--ai-tcp-dy:28px;--ai-tcp-rot:-24deg;--ai-tcp-fall:80px"> 4167 <rect x="231" y="55" width="9" height="9" rx="2" fill="#FFA000" transform="rotate(18 236 60)"/> 4168 </g> 4169 <g class="aiTextCheckerNoIssuePopperPiece" style="--ai-tcp-i:13;--ai-tcp-x:202px;--ai-tcp-y:78px;--ai-tcp-dx:32px;--ai-tcp-dy:20px;--ai-tcp-rot:22deg;--ai-tcp-fall:95px">
4170 <circle cx="202" cy="78" r="4" fill="#DA5765"/> 4171 </g> 4172 <g class="aiTextCheckerNoIssuePopperPiece" style="--ai-tcp-i:14;--ai-tcp-x:172px;--ai-tcp-y:55px;--ai-tcp-dx:25px;--ai-tcp-dy:18px;--ai-tcp-rot:-32deg;--ai-tcp-fall:85px"> 4173 <rect x="167" y="50" width="9" height="9" rx="2" fill="#3FA9F5" transform="rotate(-28 172 55)"/> 4174 </g> 4175 <g class="aiTextCheckerNoIssuePopperPiece" style="--ai-tcp-i:15;--ai-tcp-x:224px;--ai-tcp-y:95px;--ai-tcp-dx:38px;--ai-tcp-dy:18px;--ai-tcp-rot:30deg;--ai-tcp-fall:70px"> 4176 <rect x="220" y="91" width="7" height="7" rx="1.5" fill="#7ED321" transform="rotate(25 223 94)"/> 4177 </g> 4178 <g class="aiTextCheckerNoIssuePopperPiece" style="--ai-tcp-i:16;--ai-tcp-x:186px;--ai-tcp-y:40px;--ai-tcp-dx:30px;--ai-tcp-dy:22px;--ai-tcp-rot:0deg;--ai-tcp-fall:90px"> 4179 <path d="M180 36 Q190 26 200 36 Q204 42 198 52" stroke="#DA5765" stroke-width="2.5" fill="none" stroke-linecap="round"/> 4180 </g> 4181 <g class="aiTextCheckerNoIssuePopperPiece" style="--ai-tcp-i:17;--ai-tcp-x:152px;--ai-tcp-y:32px;--ai-tcp-dx:22px;--ai-tcp-dy:25px;--ai-tcp-rot:16deg;--ai-tcp-fall:100px"> 4182 <circle cx="152" cy="32" r="3" fill="#FFD66E"/> 4183 </g> 4184 <g class="aiTextCheckerNoIssuePopperPiece" style="--ai-tcp-i:18;--ai-tcp-x:212px;--ai-tcp-y:48px;--ai-tcp-dx:36px;--ai-tcp-dy:26px;--ai-tcp-rot:-18deg;--ai-tcp-fall:88px"> 4185 <circle cx="212" cy="48" r="3" fill="#E94B7C"/> 4186 </g> 4187 <g class="aiTextCheckerNoIssuePopperCone aiTextCheckerNoIssuePopperConeLeft"> 4188 <g transform="translate(18 188) rotate(-46)"> 4189 <path d="M0 -2.5 L0 2.5 L78 25 L78 -25 Z" fill="url(#aiTextCheckerPopperCone)"/> 4190 <path d="M20 -8 L20 8" stroke="rgba(255,255,255,0.45)" stroke-width="2.2" stroke-linecap="round"/> 4191 <path d="M40 -14 L40 14" stroke="rgba(255,255,255,0.45)" stroke-width="2.2" stroke-linecap="round"/> 4192 <path d="M58 -20 L58 20" stroke="rgba(255,255,255,0.45)" stroke-width="2.2" stroke-linecap="round"/> 4193 <ellipse cx="78" cy="0" rx="3" ry="25" fill="rgba(0,0,0,0.22)"/> 4194 <circle cx="-1" cy="0" r="3.5" fill="#DA5765"/> 4195 </g> 4196 </g> 4197 <g class="aiTextCheckerNoIssuePopperCone aiTextCheckerNoIssuePopperConeRight"> 4198 <g transform="translate(302 188) rotate(226)"> 4199 <path d="M0 -2.5 L0 2.5 L78 25 L78 -25 Z" fill="url(#aiTextCheckerPopperCone)"/> 4200 <path d="M20 -8 L20 8" stroke="rgba(255,255,255,0.45)" stroke-width="2.2" stroke-linecap="round"/> 4201 <path d="M40 -14 L40 14" stroke="rgba(255,255,255,0.45)" stroke-width="2.2" stroke-linecap="round"/> 4202 <path d="M58 -20 L58 20" stroke="rgba(255,255,255,0.45)" stroke-width="2.2" stroke-linecap="round"/> 4203 <ellipse cx="78" cy="0" rx="3" ry="25" fill="rgba(0,0,0,0.22)"/> 4204 <circle cx="-1" cy="0" r="3.5" fill="#DA5765"/> 4205 </g> 4206 </g> 4207 </svg> 4208 <div class="aiTextCheckerNoIssueTexts"> 4209 <div class="aiTextCheckerNoIssueTitle"> 4210 <span class="aiTextCheckerNoIssueTitleMain">ãè¦äºï¼</span> 4211 <span class="aiTextCheckerNoIssueTitleSub">ç®ç«ã£ãææã¯è¦ã¤ããã¾ããã§ãã</span> 4212 </div> 4213 </div> 4214 </div> 4215 </div> 4216 `; 4217 return; 4218 } 4219 4220 #showIssueList(results) { 4221 // ããã«ã¢ã¼ãã¸åæ¿ï¼ãã¼ã¸ãè¦ããå³ãµã¤ãããã«ï¼ 4222 if (this.#onPanelModeRequired) this.#onPanelModeRequired(); 4223 4224 const body = this.#shadowRoot.querySelector('.aiTextCheckerBody'); 4225 if (!body) return; 4226 4227 body.innerHTML = ` 4228 <div class="aiTextCheckerIssueListHeader"> 4229 <div class="aiTextCheckerIssueListCount"> 4230 <span class="aiTextCheckerIssueListCountNum">${results.length}</span> 4231 <span class="aiTextCheckerIssueListCountLabel">ä»¶ã®ææ</span> 4232 <span class="aiTextCheckerIssueListRemaining" data-remaining="${results.length}">æ®ã ${results.length} ä»¶</span> 4233 </div> 4234 </div> 4235 <ul class="aiTextCheckerIssueList"></ul> 4236 `; 4237 4238 const listEl = body.querySelector('.aiTextCheckerIssueList'); 4239 const remainingEl = body.querySelector('.aiTextCheckerIssueListRemaining'); 4240 const state = { remaining: results.length }; 4241
4242 results.forEach((item, idx) => { 4243 listEl.appendChild(this.#buildIssueCard(item, idx, state, remainingEl)); 4244 }); 4245 } 4246 4247 #buildIssueCard(item, idx, state, remainingEl) { 4248 const card = document.createElement('li'); 4249 card.className = 'aiTextCheckerIssueCard'; 4250 card.setAttribute('data-target-id', item.element_id || ''); 4251 4252 const checkTypeLabel = this.#checkTypeLabels[item.check_type] || 'ææ'; 4253 4254 const head = document.createElement('div'); 4255 head.className = 'aiTextCheckerIssueCardHead'; 4256 head.innerHTML = ` 4257 <span class="aiTextCheckerIssueCardBadge">${idx + 1}</span> 4258 <span class="aiTextCheckerIssueCardCheckType">${_h(checkTypeLabel)}</span> 4259 `; 4260 card.appendChild(head); 4261 4262 const hasSuggested = !!(typeof item.suggested === 'string' && item.suggested.length); 4263 4264 const diff = document.createElement('div'); 4265 diff.className = 'aiTextCheckerIssueCardDiff'; 4266 const origSpan = document.createElement('span'); 4267 origSpan.textContent = item.original || ''; 4268 if (hasSuggested) { 4269 origSpan.className = 'aiTextCheckerIssueCardOriginal'; 4270 const arrow = document.createElement('span'); 4271 arrow.className = 'aiTextCheckerIssueCardArrow'; 4272 arrow.textContent = 'â'; 4273 const suggestedRow = document.createElement('div'); 4274 suggestedRow.className = 'aiTextCheckerIssueCardSuggestedRow'; 4275 const sugSpan = document.createElement('span'); 4276 sugSpan.className = 'aiTextCheckerIssueCardSuggested'; 4277 sugSpan.textContent = item.suggested; 4278 const copyBtn = document.createElement('span'); 4279 copyBtn.className = 'aiTextCheckerIssueCardCopy'; 4280 copyBtn.innerHTML = '<svg width="16" height="16" viewBox="0 0 32 32" aria-hidden="true"><path d="M24.889 10.667c0.981 0 1.778 0.796 1.778 1.778v14.222c0 0.981-0.796 1.778-1.778 1.778h-10.667c-0.981 0-1.778-0.796-1.778-1.778v-14.222c0-0.981 0.796-1.778 1.778-1.778h10.667zM24.889 7.111h-10.667c-2.94 0-5.333 2.393-5.333 5.333v14.222c0 2.94 2.393 5.333 5.333 5.333h10.667c2.94 0 5.333-2.393 5.333-5.333v-14.222c0-2.94-2.393-5.333-5.333-5.333v0z"></path><path d="M17.778 0h-10.667c-2.94 0-5.333 2.393-5.333 5.333v10.667c0 0.981 0.796 1.778 1.778 1.778s1.778-0.796 1.778-1.778v-10.667c0-0.981 0.796-1.778 1.778-1.778h10.667c0.981 0 1.778-0.796 1.778-1.778s-0.796-1.778-1.778-1.778z"></path></svg>'; 4281 copyBtn.setAttribute('aria-label', 'ä¿®æ£å¾ã®ããã¹ããã³ãã¼'); 4282 copyBtn.setAttribute('title', 'ä¿®æ£å¾ã®ããã¹ããã³ãã¼'); 4283 const copyFeedback = document.createElement('span'); 4284 copyFeedback.className = 'aiTextCheckerIssueCardCopyFeedback'; 4285 copyFeedback.setAttribute('aria-live', 'polite'); 4286 copyBtn.addEventListener('click', (e) => { 4287 e.stopPropagation(); 4288 this.#copyToClipboard(item.suggested, copyFeedback); 4289 }); 4290 suggestedRow.appendChild(sugSpan); 4291 suggestedRow.appendChild(copyBtn); 4292 suggestedRow.appendChild(copyFeedback); 4293 diff.appendChild(origSpan); 4294 diff.appendChild(arrow); 4295 diff.appendChild(suggestedRow); 4296 } else { 4297 origSpan.className = 'aiTextCheckerIssueCardTargetText'; 4298 diff.appendChild(origSpan); 4299 } 4300 card.appendChild(diff); 4301 4302 if (item.description) { 4303 const description = document.createElement('div'); 4304 description.className = 'aiTextCheckerIssueCardDescription'; 4305 description.textContent = item.description; 4306 card.appendChild(description); 4307 } 4308 4309 const actions = document.createElement('div'); 4310 actions.className = 'aiTextCheckerIssueCardActions'; 4311 4312 const jumpBtn = document.createElement('button'); 4313 jumpBtn.type = 'button'; 4314 jumpBtn.className = 'aiTextCheckerIssueCardJumpBtn'; 4315 jumpBtn.innerHTML = ` 4316 <span class="aiTextCheckerIssueCardJumpBtnIcon" aria-hidden="true"> 4317 <svg width="14" height="14" viewBox="0 0 24 24" fill="none"> 4318 <path d="M15 10l5 5-5 5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 4319 <path d="M4 4v7a4 4 0 0 0 4 4h12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 4320 </svg> 4321 </span> 4322 <span class="aiTextCheckerIssueCardJumpBtnText">該å½ç®æã¸</span> 4323 `; 4324 jumpBtn.addEventListener('click', (e) => { 4325 e.stopPropagation(); 4326 if (this.#onJumpToElement) this.#onJumpToElement(item.element_id, idx); 4327 }); 4328 4329 const cardState = { resolved: false }; 4330 const checkLabel = document.createElement('label'); 4331 checkLabel.className = 'aiTextCheckerIssueCardCheck'; 4332 const checkInput = document.createElement('input'); 4333 checkInput.type = 'checkbox'; 4334 checkInput.className = 'aiTextCheckerIssueCardCheckInput';
4335 const checkText = document.createElement('span'); 4336 checkText.className = 'aiTextCheckerIssueCardCheckText'; 4337 checkText.textContent = 'ç¢ºèªæ¸ã¿'; 4338 checkLabel.appendChild(checkInput); 4339 checkLabel.appendChild(checkText); 4340 4341 const updateChipReviewed = (reviewed) => { 4342 if (this.#onResolvedChange) this.#onResolvedChange(idx, reviewed); 4343 }; 4344 4345 const markResolved = () => { 4346 if (cardState.resolved) return; 4347 cardState.resolved = true; 4348 if (!checkInput.checked) checkInput.checked = true; 4349 card.classList.add('aiTextCheckerIssueCardResolved', 'aiTextCheckerIssueCardCollapsed', 'aiTextCheckerIssueCardReviewed'); 4350 state.remaining--; 4351 remainingEl.setAttribute('data-remaining', state.remaining); 4352 remainingEl.textContent = 'æ®ã ' + state.remaining + ' ä»¶'; 4353 updateChipReviewed(true); 4354 }; 4355 const markPending = () => { 4356 if (!cardState.resolved) return; 4357 cardState.resolved = false; 4358 if (checkInput.checked) checkInput.checked = false; 4359 card.classList.remove('aiTextCheckerIssueCardResolved', 'aiTextCheckerIssueCardCollapsed', 'aiTextCheckerIssueCardReviewed'); 4360 state.remaining++; 4361 remainingEl.setAttribute('data-remaining', state.remaining); 4362 remainingEl.textContent = 'æ®ã ' + state.remaining + ' ä»¶'; 4363 updateChipReviewed(false); 4364 }; 4365 4366 checkInput.addEventListener('change', () => { 4367 if (checkInput.checked) markResolved(); 4368 else markPending(); 4369 }); 4370 // ã³ã³ãã¯ãæã«ã«ã¼ãæ¬ä½ã¯ãªãã¯ã§ãã§ãã¯ãåãæ¿ããã¨æä½ãã¥ããã®ã§ 4371 // label èµ·ç¹ã®ã¯ãªãã¯ãã«ã¼ãå¤ã« bubble ããªãããã«ãã 4372 checkLabel.addEventListener('click', (e) => e.stopPropagation()); 4373 4374 actions.appendChild(jumpBtn); 4375 actions.appendChild(checkLabel); 4376 card.appendChild(actions); 4377 4378 const summary = document.createElement('div'); 4379 summary.className = 'aiTextCheckerIssueCardSummary'; 4380 const summaryText = document.createElement('span'); 4381 summaryText.className = 'aiTextCheckerIssueCardSummaryText'; 4382 if (hasSuggested) { 4383 const summaryBefore = document.createElement('span'); 4384 summaryBefore.className = 'aiTextCheckerIssueCardSummaryBefore'; 4385 summaryBefore.textContent = item.original || ''; 4386 const summaryArrow = document.createElement('span'); 4387 summaryArrow.className = 'aiTextCheckerIssueCardSummaryArrow'; 4388 summaryArrow.textContent = ' â '; 4389 const summaryAfter = document.createElement('span'); 4390 summaryAfter.className = 'aiTextCheckerIssueCardSummaryAfter'; 4391 summaryAfter.textContent = item.suggested; 4392 summaryText.appendChild(summaryBefore); 4393 summaryText.appendChild(summaryArrow); 4394 summaryText.appendChild(summaryAfter); 4395 } else { 4396 const summaryTargetLabel = document.createElement('span'); 4397 summaryTargetLabel.className = 'aiTextCheckerIssueCardSummaryTargetLabel'; 4398 summaryTargetLabel.textContent = '該å½ç®æ: '; 4399 const summaryTarget = document.createElement('span'); 4400 summaryTarget.className = 'aiTextCheckerIssueCardSummaryTarget'; 4401 summaryTarget.textContent = item.original || ''; 4402 summaryText.appendChild(summaryTargetLabel); 4403 summaryText.appendChild(summaryTarget); 4404 } 4405 summary.appendChild(summaryText); 4406 card.appendChild(summary); 4407 4408 return card; 4409 } 4410 4411 // ========== ã¯ãªãããã¼ã ========== 4412 4413 async #copyToClipboard(text, feedbackEl) { 4414 let ok = false; 4415 try { 4416 if (navigator.clipboard && window.isSecureContext) { 4417 await navigator.clipboard.writeText(text); 4418 ok = true; 4419 } 4420 } catch (_) { 4421 ok = false; 4422 } 4423 if (!ok) { 4424 ok = this.#fallbackCopy(text); 4425 } 4426 this.#showCopyFeedback(feedbackEl, ok ? 'ã³ãã¼ãã¾ãã' : 'ã³ãã¼ã«å¤±æãã¾ãã'); 4427 } 4428 4429 #fallbackCopy(text){ 4430 const doc = window.top.document; 4431 const textarea = doc.createElement('textarea'); 4432 textarea.value = text; 4433 textarea.setAttribute('readonly', ''); 4434 textarea.style.cssText = 'position:fixed;top:0;left:0;width:1px;height:1px;opacity:0;'; 4435 doc.body.appendChild(textarea); 4436 const selection = doc.getSelection(); 4437 const prevRange = (selection && selection.rangeCount > 0) ? selection.getRangeAt(0) : null; 4438 let ok = false;
4439 try { 4440 textarea.select(); 4441 textarea.setSelectionRange(0, textarea.value.length); 4442 ok = doc.execCommand('copy'); 4443 } catch (_) { 4444 ok = false; 4445 } finally { 4446 doc.body.removeChild(textarea); 4447 if (prevRange && selection) { 4448 selection.removeAllRanges(); 4449 selection.addRange(prevRange); 4450 } 4451 } 4452 return ok; 4453 } 4454 4455 #showCopyFeedback(feedbackEl, message){ 4456 if (!feedbackEl) return; 4457 if (feedbackEl._fadeTimer) clearTimeout(feedbackEl._fadeTimer); 4458 if (feedbackEl._removeTimer) clearTimeout(feedbackEl._removeTimer); 4459 feedbackEl.textContent = message; 4460 feedbackEl.classList.remove('aiTextCheckerIssueCardCopyFeedbackFade'); 4461 feedbackEl.classList.add('aiTextCheckerIssueCardCopyFeedbackVisible'); 4462 feedbackEl._fadeTimer = setTimeout(() => { 4463 feedbackEl.classList.add('aiTextCheckerIssueCardCopyFeedbackFade'); 4464 }, 4000); 4465 feedbackEl._removeTimer = setTimeout(() => { 4466 feedbackEl.classList.remove('aiTextCheckerIssueCardCopyFeedbackVisible', 'aiTextCheckerIssueCardCopyFeedbackFade'); 4467 feedbackEl.textContent = ''; 4468 }, 5000); 4469 } 4470 } 4471 4472 class issueOverlayController { 4473 #doc = null; 4474 #elementMap = null; 4475 #pageElementCollector = null; 4476 #modalAccessor = null; 4477 #chipNodes = []; 4478 #chipLayer = null; 4479 #chipReposListener = null; 4480 #chipReposRafId = 0; 4481 #chipScrollRoots = []; 4482 #spotlightSvg = null; 4483 #spotlightHoles = []; 4484 #spotlightBaseRect = null; 4485 #spotlightRoot = null; 4486 #jumpScrollCleanup = null; 4487 4488 constructor({ 4489 doc, 4490 pageElementCollector, 4491 modalAccessor, 4492 }) { 4493 this.#doc = doc; 4494 this.#pageElementCollector = pageElementCollector; 4495 this.#modalAccessor = modalAccessor; 4496 } 4497 4498 show(results, elementMap) { 4499 this.#elementMap = elementMap; 4500 this.#renderElementChips(results); 4501 this.#showSpotlight(); 4502 this.#markIssueHighlights(results); 4503 } 4504 4505 destroy() { 4506 this.#abortJumpScroll(); 4507 this.#removeElementChips(); 4508 this.#clearSpotlight(); 4509 this.#clearIssueHighlights(); 4510 } 4511 4512 setChipReviewed(idx, reviewed) { 4513 if (!this.#chipLayer) return; 4514 const chip = this.#chipLayer.querySelector('.aiTextCheckerIssueChip[data-idx="' + idx + '"]'); 4515 if (!chip) return; 4516 if (reviewed) chip.classList.add('aiTextCheckerIssueChipReviewed'); 4517 else chip.classList.remove('aiTextCheckerIssueChipReviewed'); 4518 } 4519 4520 jumpToElement(el, idx) { 4521 this.#abortJumpScroll(); 4522 const chip = this.#chipLayer 4523 ? this.#chipLayer.querySelector('.aiTextCheckerIssueChip[data-idx="' + idx + '"]') 4524 : null; 4525 4526 const startBounce = () => { 4527 if (!chip) return; 4528 // é£ç¶ã¸ã£ã³ãã§åçããããã«ã¯ã©ã¹ãä¸åº¦å¤ã㦠reflow å¾ã«ä»ãç´ã 4529 chip.classList.remove('aiTextCheckerIssueChipBouncing'); 4530 void chip.offsetWidth; 4531 chip.classList.add('aiTextCheckerIssueChipBouncing'); 4532 const onEnd = () => { 4533 chip.classList.remove('aiTextCheckerIssueChipBouncing'); 4534 chip.removeEventListener('animationend', onEnd); 4535 }; 4536 chip.addEventListener('animationend', onEnd); 4537 }; 4538 4539 // æ¢ã«ç»é¢å ã«å®å ¨ã«åã¾ã£ã¦ãããªãã¹ã¯ãã¼ã«ä¸è¦ â 峿 bounce 4540 const rect = el.getBoundingClientRect(); 4541 const viewportH = window.innerHeight || document.documentElement.clientHeight; 4542 const fullyVisible = rect.top >= 0 && rect.bottom <= viewportH; 4543 if (fullyVisible) { 4544 startBounce(); 4545 return; 4546 } 4547 4548 // ã¹ã¯ãã¼ã«å®è¡ 4549 try { 4550 el.scrollIntoView({ behavior: 'smooth', block: 'center' }); 4551 } catch (_) { 4552 el.scrollIntoView(); 4553 } 4554 4555 // ã¹ã¯ãã¼ã«åæ¢æ¤ç¥ï¼æå¾ã® scroll ã¤ãã³ããã 80ms çµéã§å®äºã¨ã¿ãªã
4555ï¼ 4556 let stopTimer; 4557 let fallbackTimer; 4558 const cleanup = () => { 4559 window.removeEventListener('scroll', onScroll, true); 4560 clearTimeout(stopTimer); 4561 clearTimeout(fallbackTimer); 4562 this.#jumpScrollCleanup = null; 4563 }; 4564 this.#jumpScrollCleanup = cleanup; 4565 const onScroll = () => { 4566 clearTimeout(stopTimer); 4567 stopTimer = setTimeout(() => { 4568 cleanup(); 4569 startBounce(); 4570 }, 80); 4571 }; 4572 window.addEventListener('scroll', onScroll, true); 4573 // 念ã®ããæå¤§ 1.5 ç§ã§å¼·å¶ã¹ã¿ã¼ãï¼scrollã¤ãã³ããçºç«ããªãç°å¢ã¸ã®ä¿éºï¼ 4574 fallbackTimer = setTimeout(() => { 4575 cleanup(); 4576 startBounce(); 4577 }, 1500); 4578 } 4579 4580 #abortJumpScroll() { 4581 if (this.#jumpScrollCleanup) { 4582 this.#jumpScrollCleanup(); 4583 } 4584 } 4585 4586 #renderElementChips(results) { 4587 this.#removeElementChips(); 4588 4589 const doc = this.#doc; 4590 const layer = doc.createElement('div'); 4591 layer.id = 'aiTextCheckerChipLayer'; 4592 doc.body.appendChild(layer); 4593 this.#chipLayer = layer; 4594 4595 const idCount = {}; 4596 results.forEach((item, idx) => { 4597 if (!item.element_id) return; 4598 const target = this.#pageElementCollector.resolve(this.#elementMap, item.element_id); 4599 if (!target) return; 4600 4601 const stack = idCount[item.element_id] || 0; 4602 idCount[item.element_id] = stack + 1; 4603 4604 const chip = doc.createElement('div'); 4605 chip.className = 'aiTextCheckerIssueChip'; 4606 chip.dataset.idx = String(idx); 4607 chip.textContent = String(idx + 1); 4608 chip.title = String(idx + 1) + ' ' + (item.original || ''); 4609 chip.addEventListener('click', (e) => { 4610 e.stopPropagation(); 4611 if (this.#modalAccessor.isMinimized()) { 4612 this.#modalAccessor.expand(); 4613 } 4614 this.#modalAccessor.focusCard(idx); 4615 this.jumpToElement(target, idx); 4616 }); 4617 layer.appendChild(chip); 4618 this.#chipNodes.push({ chip, target, stack }); 4619 }); 4620 4621 this.#updateChipPositions(); 4622 this.#bindChipScrollListeners(); 4623 } 4624 4625 #collectChipScrollRoots() { 4626 const roots = new Set(); 4627 const win = this.#doc.defaultView || window; 4628 for (const { target } of this.#chipNodes) { 4629 let el = target.parentElement; 4630 while (el) { 4631 const style = win.getComputedStyle(el); 4632 if (/(auto|scroll|overlay)/.test(style.overflow + style.overflowX + style.overflowY)) { 4633 roots.add(el); 4634 } 4635 el = el.parentElement; 4636 } 4637 } 4638 return roots; 4639 } 4640 4641 #bindChipScrollListeners() { 4642 if (this.#chipReposListener) return; 4643 4644 // ãããã¨ã¹ãããã©ã¤ãã®ç©´ã¯åã getBoundingClientRect 追å¾ãªã®ã§ 1 æ¬ã®ãªã¹ãã¼ã§ä¸¡æ¹æ´æ°ããã 4645 // scroll ã¯é«é »åº¦ã§çºç«ãããã rAF ã§ã¹ãããã«ããï¼å¤éäºç´ãé²ãï¼ã 4646 this.#chipReposListener = () => { 4647 if (this.#chipReposRafId) return; 4648 this.#chipReposRafId = requestAnimationFrame(() => { 4649 this.#chipReposRafId = 0; 4650 this.#updateChipPositions(); 4651 this.#updateSpotlight(); 4652 }); 4653 }; 4654 4655 const handler = this.#chipReposListener; 4656 const win = this.#doc.defaultView || window; 4657 win.addEventListener('scroll', handler, true); 4658 win.addEventListener('resize', handler); 4659 this.#chipScrollRoots.push(win); 4660 for (const root of this.#collectChipScrollRoots()) { 4661 if (root === win) continue; 4662 root.addEventListener('scroll', handler, { passive: true }); 4663 this.#chipScrollRoots.push(root); 4664 } 4665 } 4666 4667 #unbindChipScrollListeners() { 4668 const handler = this.#chipReposListener; 4669 if (!handler) return; 4670 const win = this.#doc.defaultView || window; 4671 win.removeEventListener('scroll', handler, true); 4672 win.removeEventListener('resize', handler); 4673 for (const root of this.#chipScrollRoots) { 4674 root.removeEventListener('scroll', handler); 4675 } 4676 this.#chipScrollRoots = []; 4677 this.#chipReposListener = null; 4678 if (this.#chipReposRafId) { 4679 cancelAnimationFrame(this.#chipReposRafId); 4680 this.#chipReposRafId = 0; 4681 } 4682 } 4683 4684 #updateChipPositions() { 4685 const viewportH = window.innerHeight || document.documentElement.clientHeight; 4686 const viewportW = window.innerWidth || document.documentElement.clientWidth; 4687 const chipGap = 6; 4688 // ç»é¢ç«¯ã§ã¯æ°åãè¦ããç¯å²ã§ããã端ã ãåãããã以ä¸å å´ã¸ãããã¨ææå¯¾è±¡ã®æåã«è¢«ã 4689 const clipAllowance = 3; 4690 4691 /** åä¸è¦ç´ ã¸ã®è¤æ°ããã㯠stack é ãä¿ã£ãã¾ã¾ã¾ã¨ãã¦ããã */ 4692 const groups = new Map(); 4693 for (const node of this.#chipNodes) { 4694 if (!groups.has(node.target)) groups.set(node.target, []); 4695 groups.get(node.target).push(node); 4696 } 4697 4698 for (const nodes of groups.values()) { 4699 nodes.sort((a, b) => a.stack - b.stack);
4700 const rect = nodes[0].target.getBoundingClientRect(); 4701 const maxChipW = Math.max(...nodes.map(({ chip }) => chip.offsetWidth || 22)); 4702 const inViewport = rect.bottom > 0 && rect.top < viewportH && rect.right > 0 && rect.left < viewportW; 4703 4704 let left = rect.left - maxChipW - chipGap; 4705 if (inViewport) { 4706 if (left < -clipAllowance) { 4707 left = -clipAllowance; 4708 } else if (left + maxChipW > viewportW) { 4709 left = viewportW - maxChipW; 4710 } 4711 } 4712 4713 const tops = nodes.map(({ stack }) => rect.top - 8 + stack * 26); 4714 4715 nodes.forEach(({ chip }, i) => { 4716 chip.style.top = tops[i] + 'px'; 4717 chip.style.left = left + 'px'; 4718 }); 4719 } 4720 } 4721 4722 #removeElementChips() { 4723 this.#unbindChipScrollListeners(); 4724 if (this.#chipLayer) { 4725 this.#chipLayer.remove(); 4726 this.#chipLayer = null; 4727 } 4728 this.#chipNodes = []; 4729 } 4730 4731 // ========== ã¹ãããã©ã¤ãï¼ç¯å²å¤ãã£ãã³ã° / æå¹ã«ç©´ï¼ ========== 4732 4733 // ãã§ãã¯ç¯å²ï¼#cms_contents_areaï¼ãæãå¹ã§è¦ãããã§ãã¯å¯¾è±¡è¦ç´ ã®ä½ç½®ã ãã SVG mask ã§ããæãã 4734 // ãå¨å²ãæããã¦å¯¾è±¡ãæµ®ãããï¼å¼ãç®ï¼ãè¦ãæ¹ï¼ä»¥åã¯å¯¾è±¡ã outline ã§ç¸åãè¶³ãç®æ¹å¼ã ã£ããæ¤å»ï¼ã 4735 // æå¹ã¯ #cms_contents_area ã®é åã ãã«ããããã®å¤å´ï¼ç®¡çãã¼ã«UIï¼ã¯æãããªãã 4736 // filter ã¯ç¥å ã«å½ã¦ãã¨é ä¸ãã¨ã©ã¹ã¿ã©ã¤ãºããåã§æã¡æ¶ããªããã使ããªããã 4737 // SVG mask ã®ç©´æ¹å¼ã¯ãã®å¶ç´ã¨ç¡é¢ä¿ã«æç«ããã 4738 // 穴座æ¨ã¯ getBoundingClientRectï¼viewport åºæºï¼ããã®ã¾ã¾ä½¿ããSVG ã position:fixed ã«ãããã 4739 // ã¹ã¯ãã¼ã«ãªãã»ããã®å ç®ã¯ä¸è¦ã追å¾ã¯ #renderElementChips ã®ãªã¹ãã¼ã«ç¸ä¹ãããã 4740 #showSpotlight() { 4741 this.#clearSpotlight(); 4742 if (!this.#elementMap || this.#elementMap.size === 0) return; 4743 const root = document.querySelector('#cms_contents_area'); 4744 if (!root) return; 4745 4746 const doc = this.#doc; 4747 const SVG_NS = 'http://www.w3.org/2000/svg'; 4748 const maskId = 'aiTextCheckerSpotlightMask'; 4749 4750 const svg = doc.createElementNS(SVG_NS, 'svg'); 4751 svg.id = 'aiTextCheckerSpotlight'; 4752 svg.setAttribute('preserveAspectRatio', 'none'); 4753 4754 const defs = doc.createElementNS(SVG_NS, 'defs'); 4755 const mask = doc.createElementNS(SVG_NS, 'mask'); 4756 mask.id = maskId; 4757 4758 // white = æå¹ã表示ããé åã#cms_contents_area ã®ç©å½¢ã«éå®ããï¼åº§æ¨ã¯ #updateSpotlight ã§è¿½å¾ï¼ã穴㯠black ã§æãã 4759 const base = doc.createElementNS(SVG_NS, 'rect'); 4760 base.setAttribute('fill', '#fff'); 4761 mask.appendChild(base); 4762 this.#spotlightBaseRect = base; 4763 this.#spotlightRoot = root; 4764 4765 this.#spotlightHoles = []; 4766 for (const { el } of this.#elementMap.values()) { 4767 const hole = doc.createElementNS(SVG_NS, 'rect'); 4768 hole.setAttribute('rx', '4'); 4769 hole.setAttribute('fill', '#000'); 4770 mask.appendChild(hole); 4771 this.#spotlightHoles.push({ target: el, rect: hole }); 4772 } 4773 4774 // æå¹ã®å¡ããæ¢åã®ã¢ã¼ãã«èæ¯ãªã¼ãã¼ã¬ã¤ï¼#aiTextCheckerOverlayï¼ã¨åãæè²ã°ã©ãã SVG ã§åç¾ããã 4775 const gradId = 'aiTextCheckerSpotlightGrad'; 4776 const grad = doc.createElementNS(SVG_NS, 'linearGradient'); 4777 grad.id = gradId; 4778 grad.setAttribute('x1', '0'); 4779 grad.setAttribute('y1', '0'); 4780 grad.setAttribute('x2', '0'); 4781 grad.setAttribute('y2', '1'); 4782 [['0%', '#DA5765'], ['25%', '#D4584D'], ['50%', '#ED7C33'], ['75%', '#FFA000'], ['100%', '#FFD900']].forEach(([offset, color]) => { 4783 const stop = doc.createElementNS(SVG_NS, 'stop'); 4784 stop.setAttribute('offset', offset); 4785 stop.setAttribute('stop-color', color); 4786 stop.setAttribute('stop-opacity', '0.8'); 4787 grad.appendChild(stop); 4788 }); 4789 4790 defs.appendChild(mask); 4791 defs.appendChild(grad); 4792 svg.appendChild(defs); 4793 4794 const dim = doc.createElementNS(SVG_NS, 'rect'); 4795 dim.setAttribute('x', '0'); 4796 dim.setAttribute('y', '0'); 4797 dim.setAttribute('width', '100%'); 4798 dim.setAttribute('height', '100%'); 4799 dim.setAttribute('fill', 'url(#' + gradId + ')'); 4800 dim.setAttribute('fill-opacity', '0.5'); 4801 dim.setAttribute('mask', 'url(#' + maskId + ')'); 4802 svg.appendChild(dim); 4803 4804 // ã°ã©ãã«å ãã¦è²å³ã調æ´ããããã®ã¬ã¤ã¤ã¼ 4805 // æãã¯ãã® fill-opacity ã§èª¿æ´ããã 4806 const colorLayer = doc.createElementNS(SVG_NS, 'rect'); 4807 colorLayer.setAttribute('x', '0'); 4808 colorLayer.setAttribute('y', '0'); 4809 colorLayer.setAttribute('width', '100%'); 4810 colorLayer.setAttribute('height', '100%'); 4811 colorLayer.setAttribute('fill', '#fff'); 4812 colorLayer.setAttribute('fill-opacity', '0.15'); 4813 colorLayer.setAttribute('mask', 'url(#' + maskId + ')'); 4814 svg.appendChild(colorLayer); 4815 4816 doc.body.appendChild(svg); 4817 this.#spotlightSvg = svg; 4818 4819 this.#updateSpotlight(); 4820
4821 // ãã§ã¼ãã¤ã³ï¼CSS å´ã§ transition æ¸ã¿ã次ãã¬ã¼ã ã§å¯è¦ã¯ã©ã¹ãä»ä¸ï¼ 4822 requestAnimationFrame(() => { 4823 if (this.#spotlightSvg) this.#spotlightSvg.classList.add('aiTextCheckerSpotlightVisible'); 4824 }); 4825 } 4826 4827 #updateSpotlight() { 4828 if (!this.#spotlightSvg) return; 4829 // æå¹é åã #cms_contents_area ã«è¿½å¾ãããï¼viewport åºæºã®ç©å½¢ï¼ 4830 let br = null; 4831 if (this.#spotlightBaseRect && this.#spotlightRoot) { 4832 br = this.#spotlightRoot.getBoundingClientRect(); 4833 this.#spotlightBaseRect.setAttribute('x', br.left + ''); 4834 this.#spotlightBaseRect.setAttribute('y', br.top + ''); 4835 this.#spotlightBaseRect.setAttribute('width', Math.max(0, br.width) + ''); 4836 this.#spotlightBaseRect.setAttribute('height', Math.max(0, br.height) + ''); 4837 } 4838 const PAD = 4; // 対象ã®ç¸ã®ãªã®ãªã ã¨çª®å±ãªã®ã§å°ãåºãã 4839 for (const { target, rect } of this.#spotlightHoles) { 4840 const r = target.getBoundingClientRect(); 4841 rect.setAttribute('x', (r.left - PAD) + ''); 4842 rect.setAttribute('y', (r.top - PAD) + ''); 4843 rect.setAttribute('width', Math.max(0, r.width + PAD * 2) + ''); 4844 rect.setAttribute('height', Math.max(0, r.height + PAD * 2) + ''); 4845 } 4846 } 4847 4848 #clearSpotlight() { 4849 if (this.#spotlightSvg) { 4850 this.#spotlightSvg.remove(); 4851 this.#spotlightSvg = null; 4852 } 4853 this.#spotlightHoles = []; 4854 this.#spotlightBaseRect = null; 4855 this.#spotlightRoot = null; 4856 } 4857 4858 // ææã®ããæåã ããèæ¯ãã¤ã©ã¤ãããï¼CSS Custom Highlight API / éç ´å£ï¼ã 4859 // DOM ãæ¸ãæããªãã®ã§ãã¤ã¬ã¯ãç·¨éè¦ç´ ã®ä¸èº«ãæ±ããããªããã¼ã«ãèªå追å¾ããã 4860 #markIssueHighlights(results) { 4861 this.#clearIssueHighlights(); 4862 if (!(window.CSS && CSS.highlights)) { 4863 return; 4864 } 4865 4866 const ranges = []; 4867 results.forEach(item => { 4868 const el = this.#pageElementCollector.resolve(this.#elementMap, item.element_id); 4869 if (!el) { 4870 return; 4871 } 4872 const range = this.#pageElementCollector.buildIssueRange(el, item.original); 4873 if (range) { 4874 ranges.push(range); 4875 } 4876 }); 4877 4878 if (ranges.length === 0) return; 4879 CSS.highlights.set('aiTextCheckerIssue', new Highlight(...ranges)); 4880 } 4881 4882 #clearIssueHighlights() { 4883 if (window.CSS && CSS.highlights) { 4884 CSS.highlights.delete('aiTextCheckerIssue'); 4885 } 4886 } 4887 } 4888 4889} 4890 4891// ã´ã¼ã´ã¼AIããã¹ããã§ãã¯ãèµ·åããããã¼ãã£ã³ã°ãã¿ã³ã 4892// å½é¢ AI æ©è½ã¯ããã¹ããã§ãã¯1ã¤ã®ã¿ã®ãããèµ·åå (aiTextChecker)ãç´æ¥å¼ã¶ã 4893// æ§ç¯ã®ä½æ³ã¯ ai_content_generation_function.php ã«æããï¼PHP ã¯ã¯ã©ã¹å¤ã®å®æ°å®ç¾©ã«éç´ããã¯ã©ã¹å ã§ã¯ JS 宿°ã®ã¿åç §ï¼ã 4894if (typeof globalThis.aiFloatingMenu !== 'function') { 4895 4896 // AIã¢ã¸ã¥ã¼ã«ã®å¥ç´ç¶æ³ã¨ããã¹ããã§ãã¯å®è¡æ¨©éããµã¼ãå´ã§å¤å®ã㦠JS 宿°ã¸æ¸¡ãã 4897 // å¥ç´ãªã â ãã¿ã³ãæç»ããªãï¼ã³ã³ããã¡ãã¥ã¼ã®ãé表示ãã¨æ´åï¼
4898 // å¥ç´ããã»æ¨©éãªã â é常表示ã®ã¾ã¾ã¯ãªãã¯ãç¡å¹åããããã¼æã® title ãã¼ã«ãããã§ä½¿ç¨ä¸å¯ãä¼ããï¼ã³ã³ããã® span.disabled ã¨åãæµåï¼ 4899 const aiFloatingMenu_moduleEnabled = false; 4900 const aiFloatingMenu_canRun = false; 4901 4902 globalThis.aiFloatingMenu = class aiFloatingMenu { 4903 4904 #shadowRoot = null; 4905 #cssPath = '/_administrator/css/default/ai_floating_menu.css'; 4906 // AIããã¹ããã§ãã¯ã®å®è¡æ¨©éãfalse ã®å ´åã¯ã¯ãªãã¯ã§ã®èµ·åãææ¢ããããã¼æã® title ãã¼ã«ãããã§ä½¿ç¨ä¸å¯ãä¼ããã 4907 #canRun = aiFloatingMenu_canRun; 4908 4909 // ç·¨éãµã¤ããã¤ããã¹ããã§ãã¯æå¹ãããã« AI ã¢ã¸ã¥ã¼ã«å¥ç´æ¸ã¿ã®å ´åã®ã¿ããã¼ãã£ã³ã°ãã¿ã³ãæç»ããã 4910 async init() { 4911 // context_menuãå®ç¾©ããã¦ããªãå ´åã¯ãç·¨éãµã¤ãã§ã¯ãªãã¨å¤æãã¦ã¡ãã¥ã¼ã表示ããªã 4912 if (typeof context_menu === 'undefined') { 4913 return; 4914 } 4915 // ããã¹ããã§ãã¯æ©è½ãç¡å¹åããã¦ããå ´åã¯ãã®ã¡ãã¥ã¼ã表示ããªã 4916 if (typeof aiTextChecker !== 'function') { 4917 return; 4918 } 4919 // AIã¢ã¸ã¥ã¼ã«ãæªå¥ç´ã®å ´åã¯ãã¿ã³ãæç»ããªãï¼ã³ã³ããã¡ãã¥ã¼ã®éè¡¨ç¤ºã¨æ´åï¼ 4920 if (!aiFloatingMenu_moduleEnabled) { 4921 return; 4922 } 4923 // äºéçæé²æ¢ 4924 if (document.getElementById('cmsAiFloatingHost')) { 4925 return; 4926 } 4927 4928 this.#createShadowHost(); 4929 await this.#loadStyle(); 4930 this.#renderButton(); 4931 this.#bindEvents(); 4932 } 4933 4934 #createShadowHost() { 4935 const host = document.createElement('div'); 4936 host.id = 'cmsAiFloatingHost'; 4937 // Shadow DOM å ã® z-index 㯠Host å¤ã«ä¼æããªããããHost èªä½ã« z-index ãè¨å®ããã 4938 // ã»ãã¤ã¬ã¯ãç·¨éä¸ã®ã°ã¬ã¼ã¢ã¦ã(.cms_marking, z-index:9998)ããä¸ã«æ½ããã¦ãç·¨éä¸ã¯ AI æ©è½ãç¡å¹åããã 4939 // ã»å種ãã¤ã¢ãã°(#overlay_modal=100002, .dialog=100003 ç)ãããä¸ãªã®ã§ããã¤ã¢ãã°è¡¨ç¤ºæãããã¼ãã£ã³ã°ãã¿ã³ã¯èé¢ã«é ãã(å³ä¸ãã«ãã¢ã¤ã³ã³ã¨åãæå)ã 4940 host.style.cssText = 'position:fixed;top:0;left:0;width:0;height:0;z-index:9997;'; 4941 document.body.appendChild(host); 4942 this.#shadowRoot = host.attachShadow({ mode: 'open' }); 4943 } 4944 4945 async #loadStyle() { 4946 const style = document.createElement('link'); 4947 style.rel = 'stylesheet'; 4948 style.href = this.#cssPath + '?t=1790968415'; 4949 this.#shadowRoot.appendChild(style); 4950 4951 // CSS ã®èªã¿è¾¼ã¿ã«å¤±æãã¦ããã¿ã³èªä½ã¯æç»ã»æ©è½ãããï¼è¦ãç®ãå´©ããã ãã«çããreject ã§ 4952 // å¾ç¶ã® #renderButton/#bindEvents ãæ¢ããªãï¼ã#initModal ã®ã¹ã¿ã¤ã«èªã¿è¾¼ã¿ã¨åãæ¹éã 4953 await new Promise(resolve => { 4954 style.onload = resolve; 4955 style.onerror = resolve; 4956 }); 4957 } 4958 4959 #renderButton() { 4960 // innerHTML += ã ã¨æ¢åãã¼ãï¼#loadStyle ã§æ¿å ¥ãã <link>ï¼ãåãã¼ã¹ã§ç½®æãããããã 4961 // <template> çµç±ã§æ«å°¾ã«è¿½å ããã 4962 const template = document.createElement('template'); 4963 template.innerHTML = this.#templateButton(); 4964 this.#shadowRoot.appendChild(template.content); 4965 } 4966 4967 #templateButton = () => { 4968 // 権éãªãæã¯ã©ãã« span ã« .disabled 㨠title ãä»ä¸ï¼ã³ã³ããã® span.disabled ã¨åãæµåï¼ãã¯ãªãã¯ææ¢ã¯ #bindEvents å´ã 4969 const labelAttr = this.#canRun ? '' : ' class="disabled" title="ãã®æ©è½ã¯ãå©ç¨é ãã¾ããã"'; 4970 return ` 4971 <button id="cmsAiFloatingBtn" type="button"> 4972 <img src="/_administrator/css/default/images/ai/logo-gogoai.svg" alt="AI"> 4973 <span id="cmsAiFloatingBtnLabel"${labelAttr}>ããã¹ããã§ãã¯</span> 4974 </button> 4975 `; 4976 } 4977 4978 #bindEvents() { 4979 this.#shadowRoot.getElementById('cmsAiFloatingBtn').addEventListener('click', () => { 4980 // 権éããªãå ´åã¯èµ·åããªã 4981 if (!this.#canRun) { 4982 return; 4983 } 4984 // çµæè¡¨ç¤ºä¸ã®ã¨ã㯠aiTextChecker å´ã§ç¢ºèªãã¤ã¢ãã°ãæãã§ãã䏿¸ãèµ·åããã 4985 aiTextChecker.openWithConfirm(); 4986 }); 4987 } 4988 }; 4989 4990 document.addEventListener('DOMContentLoaded', function() { 4991 new aiFloatingMenu().init(); 4992 }); 4993 4994} 4995var base_url = (location.protocol=='http:')? 'https://sokki.or.jp':'https://sokki.or.jp'; 4996var now_url = location.host.replace('www.',''); 4997/* 4998if( 'https://sokki.or.jp'.replace('http://','').replace('www.','') !== now_url ){ 4999 base_url = '//'+now_url; 5000} 5001*/ 5002base_url = base_url.replace(/^https?:/,''); 5003/* 5004*/ 5005var fileLoadingImage2 = base_url + "/_administrator/images/loading.gif"; 5006var fileBottomNavCloseImage2 = base_url + "/_administrator/images/closelabel.gif";
5007 5008var overlayOpacity2 = 0.8; // controls transparency of shadow overlay 5009 5010var animate2 = true; // toggles resizing animations 5011var resizeSpeed2 = 7; // controls the speed of the image resizing animations (1=slowest and 10=fastest) 5012 5013var borderSize2 = 10; //if you adjust the padding in the CSS, you will need to update this variable 5014var imageArray2 = new Array; 5015var activeImage2; 5016 5017if(animate2 == true){ 5018 overlayDuration2 = 0.2; // shadow fade in/out duration 5019 if(resizeSpeed2 > 10){ resizeSpeed2 = 10;} 5020 if(resizeSpeed2 < 1){ resizeSpeed2 = 1;} 5021 resizeDuration2 = (11 - resizeSpeed2) * 0.15; 5022} else { 5023 overlayDuration2 = 0; 5024 resizeDuration2 = 0; 5025} 5026Object.extend(Element, { 5027 getWidth: function(element) { 5028 element = $(element); 5029 return element.offsetWidth; 5030 }, 5031 setWidth: function(element,w) { 5032 element = $(element); 5033 element.style.width = w +"px"; 5034 }, 5035 setHeight: function(element,h) { 5036 element = $(element); 5037 element.style.height = h +"px"; 5038 }, 5039 setTop: function(element,t) { 5040 element = $(element); 5041 element.style.top = t +"px"; 5042 }, 5043 setLeft: function(element,l) { 5044 element = $(element); 5045 element.style.left = l +"px"; 5046 }, 5047 setSrc: function(element,src) { 5048 element = $(element); 5049 element.src = src; 5050 }, 5051 setHref: function(element,href) { 5052 element = $(element); 5053 element.href = href; 5054 }, 5055 setInnerHTML: function(element,content) { 5056 element = $(element); 5057 element.innerHTML = content; 5058 } 5059}); 5060 5061// ----------------------------------------------------------------------------------- 5062 5063// 5064// Extending built-in Array object 5065// - array.removeDuplicates() 5066// - array.empty() 5067// 5068Array.prototype.removeDuplicates = function () { 5069 for(i = 0; i < this.length; i++){ 5070 for(j = this.length-1; j>i; j--){ 5071 if(this[i][0] == this[j][0]){ 5072 this.splice(j,1); 5073 } 5074 } 5075 } 5076} 5077 5078// ----------------------------------------------------------------------------------- 5079 5080Array.prototype.empty = function () { 5081 for(i = 0; i <= this.length; i++){ 5082 this.shift(); 5083 } 5084} 5085 5086// ----------------------------------------------------------------------------------- 5087 5088// 5089// Lightbox Class Declaration 5090// - initialize() 5091// - start() 5092// - changeImage() 5093// - resizeImageContainer() 5094// - showImage() 5095// - updateDetails() 5096// - updateNav() 5097// - enableKeyboardNav() 5098// - disableKeyboardNav() 5099// - keyboardNavAction() 5100// - preloadNeighborImages() 5101// - end() 5102// 5103// Structuring of code inspired by Scott Upton (http://www.uptonic.com/) 5104// 5105var Lightbox2 = Class.create(); 5106 5107Lightbox2.prototype = { 5108 5109 // initialize() 5110 // Constructor runs on completion of the DOM loading. Calls updateImageList and then 5111 // the function inserts html at the bottom of the page which is used to display the shadow 5112 // overlay and the image container. 5113 // 5114 initialize: function() { 5115
5116 this.updateImageList(); 5117 5118 // Code inserts html at the bottom of the page that looks similar to this: 5119 // 5120 // <div id="overlay"></div> 5121 // <div id="lightbox"> 5122 // <div id="outerImageContainer"> 5123 // <div id="imageContainer"> 5124 // <img id="lightboxImage"> 5125 // <div style="" id="hoverNav"> 5126 // <a href="#" id="prevLink"></a> 5127 // <a href="#" id="nextLink"></a> 5128 // </div> 5129 // <div id="loading"> 5130 // <a href="#" id="loadingLink"> 5131 // <img src="images/loading.gif"> 5132 // </a> 5133 // </div> 5134 // </div> 5135 // </div> 5136 // <div id="imageDataContainer"> 5137 // <div id="imageData"> 5138 // <div id="imageDetails"> 5139 // <span id="caption"></span> 5140 // <span id="numberDisplay"></span> 5141 // </div> 5142 // <div id="bottomNav"> 5143 // <a href="#" id="bottomNavClose"> 5144 // <img src="images/close.gif"> 5145 // </a> 5146 // </div> 5147 // </div> 5148 // </div> 5149 // </div> 5150 5151 5152 var objBody = document.getElementsByTagName("body").item(0); 5153 5154 var objOverlay = document.createElement("div"); 5155 objOverlay.setAttribute('id','overlay2'); 5156 objOverlay.style.display = 'none'; 5157 objOverlay.onclick = function() { myLightbox2.end(); } 5158 objBody.appendChild(objOverlay); 5159 5160 var objLightbox2 = document.createElement("div"); 5161 objLightbox2.setAttribute('id','lightbox2'); 5162 objLightbox2.style.display = 'none'; 5163 objLightbox2.onclick = function(e) { // close Lightbox is user clicks shadow overlay 5164 if (!e) var e = window.event; 5165 var clickObj = Event.element(e).id; 5166 if ( clickObj == 'lightbox2') { 5167 myLightbox2.end(); 5168 } 5169 }; 5170 objBody.appendChild(objLightbox2); 5171 5172 var objOuterImageContainer = document.createElement("div"); 5173 objOuterImageContainer.setAttribute('id','outerImageContainer2'); 5174 objLightbox2.appendChild(objOuterImageContainer); 5175 5176 // When Lightbox starts it will resize itself from 250 by 250 to the current image dimension. 5177 // If animations are turned off, it will be hidden as to prevent a flicker of a 5178 // white 250 by 250 box. 5179 if(animate2){ 5180 Element.setWidth('outerImageContainer2', 250); 5181 Element.setHeight('outerImageContainer2', 250); 5182 } else { 5183 Element.setWidth('outerImageContainer2', 1); 5184 Element.setHeight('outerImageContainer2', 1); 5185 } 5186 5187 var objImageContainer = document.createElement("div"); 5188 objImageContainer.setAttribute('id','imageContainer2'); 5189 objOuterImageContainer.appendChild(objImageContainer); 5190 5191 var objLightboxImage = document.createElement("img"); 5192 objLightboxImage.setAttribute('id','lightboxImage2'); 5193 objImageContainer.appendChild(objLightboxImage); 5194 5195 var objHoverNav = document.createElement("div"); 5196 objHoverNav.setAttribute('id','hoverNav2'); 5197 objImageContainer.appendChild(objHoverNav); 5198 5199 var objPrevLink = document.createElement("a"); 5200 objPrevLink.setAttribute('id','prevLink2'); 5201 objPrevLink.setAttribute('href','#'); 5202 objHoverNav.appendChild(objPrevLink); 5203 5204 var objNextLink = document.createElement("a"); 5205 objNextLink.setAttribute('id','nextLink2'); 5206 objNextLink.setAttribute('href','#'); 5207 objHoverNav.appendChild(objNextLink); 5208 5209 var objLoading = document.createElement("div"); 5210 objLoading.setAttribute('id','loading2'); 5211 objImageContainer.appendChild(objLoading); 5212 5213 var objLoadingLink = document.createElement("a"); 5214 objLoadingLink.setAttribute('id','loadingLink2'); 5215 objLoadingLink.setAttribute('href','#'); 5216 objLoadingLink.onclick = function() { myLightbox2.end(); return false; } 5217 objLoading.appendChild(objLoadingLink); 5218 5219 var objLoadingImage = document.createElement("img"); 5220 objLoadingImage.setAttribute('src', fileLoadingImage2); 5221 objLoadingLink.appendChild(objLoadingImage); 5222 5223 var objImageDataContainer = document.createElement("div"); 5224 objImageDataContainer.setAttribute('id','imageDataContainer2'); 5225 objLightbox2.appendChild(objImageDataContainer); 5226 5227 var objImageData = document.createElement("div"); 5228 objImageData.setAttribute('id','imageData2'); 5229 objImageDataContainer.appendChild(objImageData); 5230 5231 var objImageDetails = document.createElement("div"); 5232 objImageDetails.setAttribute('id','imageDetails2'); 5233 objImageData.appendChild(objImageDetails); 5234 5235 var objCaption = document.createElement("span"); 5236 objCaption.setAttribute('id','caption2'); 5237 objImageDetails.appendChild(objCaption); 5238
5239 var objNumberDisplay = document.createElement("span"); 5240 objNumberDisplay.setAttribute('id','numberDisplay2'); 5241 objImageDetails.appendChild(objNumberDisplay); 5242 5243 var objBottomNav = document.createElement("div"); 5244 objBottomNav.setAttribute('id','bottomNav2'); 5245 objImageData.appendChild(objBottomNav); 5246 5247 var objBottomNavCloseLink = document.createElement("a"); 5248 objBottomNavCloseLink.setAttribute('id','bottomNavClose2'); 5249 objBottomNavCloseLink.setAttribute('href','#'); 5250 objBottomNavCloseLink.onclick = function() { myLightbox2.end(); return false; } 5251 objBottomNav.appendChild(objBottomNavCloseLink); 5252 5253 var objBottomNavCloseImage = document.createElement("img"); 5254 objBottomNavCloseImage.setAttribute('src', fileBottomNavCloseImage2); 5255 objBottomNavCloseLink.appendChild(objBottomNavCloseImage); 5256 }, 5257 5258 5259 // 5260 // updateImageList() 5261 // Loops through anchor tags looking for 'lightbox' references and applies onclick 5262 // events to appropriate links. You can rerun after dynamically adding images w/ajax. 5263 // 5264 updateImageList: function() { 5265 if (!document.getElementsByTagName){ return; } 5266 var anchors = document.getElementsByTagName('a'); 5267 var areas = document.getElementsByTagName('area'); 5268 5269 // loop through all anchor tags 5270 for (var i=0; i<anchors.length; i++){ 5271 var anchor = anchors[i]; 5272 5273 var relAttribute = String(anchor.getAttribute('rel')); 5274 5275 // use the string.match() method to catch 'lightbox' references in the rel attribute 5276 if (anchor.getAttribute('href') && (relAttribute.toLowerCase().match('^(?=.*lightbox)(?!.*lightbox_).*$'))){ 5277 anchor.onclick = function () {myLightbox2.start(this); return false;} 5278 } 5279 } 5280 5281 // loop through all area tags 5282 // todo: combine anchor & area tag loops 5283 for (var i=0; i< areas.length; i++){ 5284 var area = areas[i]; 5285 5286 var relAttribute = String(area.getAttribute('rel')); 5287 5288 // use the string.match() method to catch 'lightbox' references in the rel attribute 5289 if (area.getAttribute('href') && (relAttribute.toLowerCase().match('^(?=.*lightbox)(?!.*lightbox_).*$'))){ 5290 area.onclick = function () {myLightbox2.start(this); return false;} 5291 } 5292 } 5293 }, 5294 5295 5296 // 5297 // start() 5298 // Display overlay and lightbox. If image is part of a set, add siblings to imageArray2. 5299 // 5300 start: function(imageLink) { 5301 5302 hideSelectBoxes(); 5303 hideFlash(); 5304 5305 // stretch overlay to fill page and fade in 5306 var arrayPageSize = getPageSize(); 5307 Element.setWidth('overlay2', arrayPageSize[0]); 5308 Element.setHeight('overlay2', arrayPageSize[1]); 5309 5310 new Effect.Appear('overlay2', { duration: overlayDuration2, from: 0.0, to: overlayOpacity2 }); 5311 5312 imageArray2 = []; 5313 imageNum = 0; 5314 5315 if (!document.getElementsByTagName){ return; } 5316 var anchors = document.getElementsByTagName( imageLink.tagName); 5317 5318 // if image is NOT part of a set.. 5319 if((imageLink.getAttribute('rel') == 'lightbox2')){ 5320 // add single image to imageArray2 5321 imageArray2.push(new Array(imageLink.getAttribute('href'), imageLink.getAttribute('title'))); 5322 } else { 5323 // if image is part of a set.. 5324 // loop through anchors, find other images in set, and add them to imageArray2 5325 for (var i=0; i<anchors.length; i++){ 5326 var anchor = anchors[i]; 5327 if (anchor.getAttribute('href') && (anchor.getAttribute('rel') == imageLink.getAttribute('rel'))){ 5328 imageArray2.push(new Array(anchor.getAttribute('href'), anchor.getAttribute('title'))); 5329 } 5330 } 5331 imageArray2.removeDuplicates(); 5332 while(imageArray2[imageNum][0] != imageLink.getAttribute('href')) { imageNum++;} 5333 } 5334 5335 // calculate top and left offset for the lightbox 5336 var arrayPageScroll = getPageScroll(); 5337 var lightboxTop = arrayPageScroll[1] + (arrayPageSize[3] / 10); 5338 var lightboxLeft = arrayPageScroll[0]; 5339 Element.setTop('lightbox2', lightboxTop); 5340 Element.setLeft('lightbox2', lightboxLeft); 5341 5342 Element.show('lightbox2'); 5343 5344 this.changeImage(imageNum); 5345 }, 5346 5347 // 5348 // changeImage() 5349 // Hide most elements and preload image in preparation for resizing image container. 5350 // 5351 changeImage: function(imageNum) { 5352 5353 activeImage2 = imageNum; // update global var 5354 5355 // hide elements during transition 5356 if(animate2){ Element.show('loading2');} 5357 Element.hide('lightboxImage2');
5358 Element.hide('hoverNav2'); 5359 Element.hide('prevLink2'); 5360 Element.hide('nextLink2'); 5361 Element.hide('imageDataContainer2'); 5362 Element.hide('numberDisplay2'); 5363 5364 imgPreloader = new Image(); 5365 5366 // once image is preloaded, resize image container 5367 imgPreloader.onload=function(){ 5368 Element.setSrc('lightboxImage2', imageArray2[activeImage2][0]); 5369 myLightbox2.resizeImageContainer(imgPreloader.width, imgPreloader.height); 5370 5371 imgPreloader.onload=function(){}; // clear onLoad, IE behaves irratically with animate2d gifs otherwise 5372 } 5373 imgPreloader.src = imageArray2[activeImage2][0]; 5374 }, 5375 5376 // 5377 // resizeImageContainer() 5378 // 5379 resizeImageContainer: function( imgWidth, imgHeight) { 5380 5381 // get curren width and height 5382 this.widthCurrent = Element.getWidth('outerImageContainer2'); 5383 this.heightCurrent = Element.getHeight('outerImageContainer2'); 5384 5385 // get new width and height 5386 var widthNew = (imgWidth + (borderSize2 * 2)); 5387 var heightNew = (imgHeight + (borderSize2 * 2)); 5388 5389 // scalars based on change from old to new 5390 this.xScale = ( widthNew / this.widthCurrent) * 100; 5391 this.yScale = ( heightNew / this.heightCurrent) * 100; 5392 5393 // calculate size difference between new and old image, and resize if necessary 5394 wDiff = this.widthCurrent - widthNew; 5395 hDiff = this.heightCurrent - heightNew; 5396 5397 if(!( hDiff == 0)){ new Effect.Scale('outerImageContainer2', this.yScale, {scaleX: false, duration: resizeDuration2, queue: 'front'}); } 5398 if(!( wDiff == 0)){ new Effect.Scale('outerImageContainer2', this.xScale, {scaleY: false, delay: resizeDuration2, duration: resizeDuration2}); } 5399 5400 // if new and old image are same size and no scaling transition is necessary, 5401 // do a quick pause to prevent image flicker. 5402 if((hDiff == 0) && (wDiff == 0)){ 5403 if (navigator.appVersion.indexOf("MSIE")!=-1){ pause(250); } else { pause(100);} 5404 } 5405 5406 Element.setHeight('prevLink2', imgHeight); 5407 Element.setHeight('nextLink2', imgHeight); 5408 Element.setWidth( 'imageDataContainer2', widthNew); 5409 5410 this.showImage(); 5411 }, 5412 5413 // 5414 // showImage() 5415 // Display image and begin preloading neighbors. 5416 // 5417 showImage: function(){ 5418 Element.hide('loading2'); 5419 new Effect.Appear('lightboxImage2', { duration: resizeDuration2, queue: 'end', afterFinish: function(){ myLightbox2.updateDetails(); } }); 5420 this.preloadNeighborImages(); 5421 }, 5422 5423 // 5424 // updateDetails() 5425 // Display caption, image number, and bottom nav. 5426 // 5427 updateDetails: function() { 5428 5429 // if caption is not null 5430 if(imageArray2[activeImage2][1]){ 5431 Element.show('caption2'); 5432 Element.setInnerHTML( 'caption2', imageArray2[activeImage2][1]); 5433 } 5434 5435 // if image is part of set display 'Image x of x' 5436 if(imageArray2.length > 1){ 5437 Element.show('numberDisplay2'); 5438 Element.setInnerHTML( 'numberDisplay2', "Image " + eval(activeImage2 + 1) + " of " + imageArray2.length); 5439 } 5440 5441 new Effect.Parallel( 5442 [ new Effect.SlideDown( 'imageDataContainer2', { sync: true, duration: resizeDuration2, from: 0.0, to: 1.0 }), 5443 new Effect.Appear('imageDataContainer2', { sync: true, duration: resizeDuration2 }) ], 5444 { duration: resizeDuration2, afterFinish: function() { 5445 // update overlay size and update nav 5446 var arrayPageSize = getPageSize(); 5447 Element.setHeight('overlay2', arrayPageSize[1]); 5448 myLightbox2.updateNav(); 5449 } 5450 } 5451 ); 5452 }, 5453 5454 // 5455 // updateNav() 5456 // Display appropriate previous and next hover navigation. 5457 // 5458 updateNav: function() { 5459 5460 Element.show('hoverNav2'); 5461 5462 // if not first image in set, display prev image button 5463 if(activeImage2 != 0){ 5464 Element.show('prevLink2'); 5465 document.getElementById('prevLink2').onclick = function() { 5466 myLightbox2.changeImage(activeImage2 - 1); return false; 5467 } 5468 } 5469 5470 // if not last image in set, display next image button 5471 if(activeImage2 != (imageArray2.length - 1)){ 5472 Element.show('nextLink2'); 5473 document.getElementById('nextLink2').onclick = function() { 5474 myLightbox2.changeImage(activeImage2 + 1); return false; 5475 } 5476 } 5477 5478 this.enableKeyboardNav(); 5479 }, 5480 5481 // 5482 // enableKeyboardNav() 5483 // 5484 enableKeyboardNav: function() { 5485 document.onkeydown = this.keyboardAction; 5486 }, 5487 5488 // 5489 // disableKeyboardNav() 5490 // 5491 disableKeyboardNav: function() { 5492 document.onkeydown = ''; 5493 }, 5494 5495 // 5496 // keyboardAction() 5497 // 5498 keyboardAction: function(e) { 5499 if (e == null) { // ie 5500 keycode = event.keyCode; 5501 escapeKey = 27; 5502 } else { // mozilla 5503 keycode = e.keyCode; 5504 escapeKey = e.DOM_VK_ESCAPE; 5505 } 5506 5507 key = String.fromCharCode(keycode).toLowerCase(); 5508 5509 if((key == 'x') || (key == 'o') || (key == 'c') || (keycode == escapeKey)){ // close lightbox 5510 myLightbox2.end(); 5511 } else if((key == 'p') || (keycode == 37)){ // display previous image 5512 if(activeImage2 != 0){ 5513 myLightbox2.disableKeyboardNav(); 5514 myLightbox2.changeImage(activeImage2 - 1); 5515 } 5516 } else if((key == 'n') || (keycode == 39)){ // display next image 5517 if(activeImage2 != (imageArray2.length - 1)){ 5518 myLightbox2.disableKeyboardNav(); 5519 myLightbox2.changeImage(activeImage2 + 1); 5520 } 5521 } 5522 5523 }, 5524 5525 // 5526 // preloadNeighborImages() 5527 // Preload previous and next images. 5528 // 5529 preloadNeighborImages: function(){ 5530 5531 if((imageArray2.length - 1) > activeImage2){ 5532 preloadNextImage = new Image(); 5533 preloadNextImage.src = imageArray2[activeImage2 + 1][0]; 5534 } 5535 if(activeImage2 > 0){ 5536 preloadPrevImage = new Image(); 5537 preloadPrevImage.src = imageArray2[activeImage2 - 1][0]; 5538 } 5539 5540 }, 5541 5542 // 5543 // end() 5544 // 5545 end: function() { 5546 this.disableKeyboardNav(); 5547 Element.hide('lightbox2'); 5548 new Effect.Fade('overlay2', { duration: overlayDuration2}); 5549 showSelectBoxes(); 5550 showFlash(); 5551 } 5552} 5553 5554// ----------------------------------------------------------------------------------- 5555 5556// 5557// getPageScroll() 5558// Returns array with x,y page scroll values. 5559// Core code from - quirksmode.com 5560// 5561function getPageScroll(){ 5562 5563 var xScroll, yScroll; 5564 5565 if (self.pageYOffset) { 5566 yScroll = self.pageYOffset; 5567 xScroll = self.pageXOffset; 5568 } else if (document.documentElement && document.documentElement.scrollTop){ // Explorer 6 Strict 5569 yScroll = document.documentElement.scrollTop; 5570 xScroll = document.documentElement.scrollLeft; 5571 } else if (document.body) {// all other Explorers 5572 yScroll = document.body.scrollTop; 5573 xScroll = document.body.scrollLeft; 5574 } 5575 5576 arrayPageScroll = new Array(xScroll,yScroll) 5577 return arrayPageScroll; 5578} 5579 5580// ----------------------------------------------------------------------------------- 5581 5582// 5583// getPageSize() 5584// Returns array with page width, height and window width, height 5585// Core code from - quirksmode.com 5586// Edit for Firefox by pHaez 5587// 5588function getPageSize(){ 5589 5590 var xScroll, yScroll; 5591 5592 if (window.innerHeight && window.scrollMaxY) { 5593 xScroll = window.innerWidth + window.scrollMaxX; 5594 yScroll = window.innerHeight + window.scrollMaxY; 5595 } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac 5596 xScroll = document.body.scrollWidth; 5597 yScroll = document.body.scrollHeight; 5598 } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari 5599 xScroll = document.body.offsetWidth; 5600 yScroll = document.body.offsetHeight; 5601 } 5602 5603 var windowWidth, windowHeight; 5604 5605// console.log(self.innerWidth); 5606// console.log(document.documentElement.clientWidth); 5607
5608 if (self.innerHeight) { // all except Explorer 5609 if(document.documentElement.clientWidth){ 5610 windowWidth = document.documentElement.clientWidth; 5611 } else { 5612 windowWidth = self.innerWidth; 5613 } 5614 windowHeight = self.innerHeight; 5615 } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode 5616 windowWidth = document.documentElement.clientWidth; 5617 windowHeight = document.documentElement.clientHeight; 5618 } else if (document.body) { // other Explorers 5619 windowWidth = document.body.clientWidth; 5620 windowHeight = document.body.clientHeight; 5621 } 5622 5623 // for small pages with total height less then height of the viewport 5624 if(yScroll < windowHeight){ 5625 pageHeight = windowHeight; 5626 } else { 5627 pageHeight = yScroll; 5628 } 5629 5630// console.log("xScroll " + xScroll) 5631// console.log("windowWidth " + windowWidth) 5632 5633 // for small pages with total width less then width of the viewport 5634 if(xScroll < windowWidth){ 5635 pageWidth = xScroll; 5636 } else { 5637 pageWidth = windowWidth; 5638 } 5639// console.log("pageWidth " + pageWidth) 5640 5641 arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight) 5642 return arrayPageSize; 5643} 5644 5645// ----------------------------------------------------------------------------------- 5646 5647// 5648// getKey(key) 5649// Gets keycode. If 'x' is pressed then it hides the lightbox. 5650// 5651function getKey(e){ 5652 if (e == null) { // ie 5653 keycode = event.keyCode; 5654 } else { // mozilla 5655 keycode = e.which; 5656 } 5657 key = String.fromCharCode(keycode).toLowerCase(); 5658 5659 if(key == 'x'){ 5660 } 5661} 5662 5663// ----------------------------------------------------------------------------------- 5664 5665// 5666// listenKey() 5667// 5668function listenKey () { document.onkeypress = getKey; } 5669 5670// --------------------------------------------------- 5671 5672function showSelectBoxes(){ 5673 var selects = document.getElementsByTagName("select"); 5674 for (i = 0; i != selects.length; i++) { 5675 selects[i].style.visibility = "visible"; 5676 } 5677} 5678 5679// --------------------------------------------------- 5680 5681function hideSelectBoxes(){ 5682 var selects = document.getElementsByTagName("select"); 5683 for (i = 0; i != selects.length; i++) { 5684 selects[i].style.visibility = "hidden"; 5685 } 5686} 5687 5688// --------------------------------------------------- 5689 5690function showFlash(){ 5691 var flashObjects = document.getElementsByTagName("object"); 5692 for (i = 0; i < flashObjects.length; i++) { 5693 flashObjects[i].style.visibility = "visible"; 5694 } 5695 5696 var flashEmbeds = document.getElementsByTagName("embed"); 5697 for (i = 0; i < flashEmbeds.length; i++) { 5698 flashEmbeds[i].style.visibility = "visible"; 5699 } 5700} 5701 5702// --------------------------------------------------- 5703 5704function hideFlash(){ 5705 var flashObjects = document.getElementsByTagName("object"); 5706 for (i = 0; i < flashObjects.length; i++) { 5707 flashObjects[i].style.visibility = "hidden"; 5708 } 5709 5710 var flashEmbeds = document.getElementsByTagName("embed"); 5711 for (i = 0; i < flashEmbeds.length; i++) { 5712 flashEmbeds[i].style.visibility = "hidden"; 5713 } 5714 5715} 5716 5717 5718// --------------------------------------------------- 5719 5720// 5721// pause(numberMillis) 5722// Pauses code execution for specified time. Uses busy code, not good. 5723// Help from Ran Bar-On [[email protected]] 5724// 5725 5726function pause(ms){ 5727 var date = new Date(); 5728 curDate = null; 5729 do{var curDate = new Date();} 5730 while( curDate - date < ms); 5731} 5732/* 5733function pause(numberMillis) { 5734 var curently = new Date().getTime() + sender; 5735 while (new Date().getTime(); 5736} 5737*/ 5738// --------------------------------------------------- 5739 5740 5741 5742function initLightbox2() { myLightbox2 = new Lightbox2(); } 5743Event.observe(window, 'load', initLightbox2, false);/* 2021-10-07 lightbox_2 _templates/_modules */ 5744/*! 5745 * Lightbox v2.11.2 5746 * by Lokesh Dhakar 5747 * 5748 * More info: 5749 * http://lokeshdhakar.com/projects/lightbox2/ 5750 * 5751 * Copyright Lokesh Dhakar 5752 * Released under the MIT license 5753 * https://github.com/lokesh/lightbox2/blob/master/LICENSE 5754 * 5755 * @preserve 5756 */ 5757 5758// Uses Node, AMD or browser globals to create a module. 5759(function (root, factory) { 5760 if (typeof define === 'function' && define.amd) { 5761 // AMD. Register as an anonymous module. 5762 define(['jquery'], factory); 5763 } else if (typeof exports === 'object') { 5764 // Node. Does not work with strict CommonJS, but 5765 // only CommonJS-like environments that support module.exports, 5766 // like Node. 5767 module.exports = factory(require('jquery')); 5768 } else { 5769 // Browser globals (root is window) 5770 root.lightbox = factory(root.jQuery); 5771 } 5772}(this, function ($) { 5773 5774 function Lightbox(options) { 5775 this.album = []; 5776 this.currentImageIndex = void 0; 5777 this.init(); 5778 5779 // options 5780 this.options = $.extend({}, this.constructor.defaults); 5781 this.option(options); 5782 } 5783 5784 // Descriptions of all options available on the demo site: 5785 // http://lokeshdhakar.com/projects/lightbox2/index.html#options 5786 Lightbox.defaults = { 5787 albumLabel: 'Image %1 of %2', 5788 alwaysShowNavOnTouchDevices: false, 5789 fadeDuration: 600,
vendor: 4,651 bytes, lines 5790-5895
5790 fitImagesInViewport: true, 5791 imageFadeDuration: 600, 5792 // maxWidth: 800, 5793 // maxHeight: 600, 5794 positionFromTop: 50, 5795 resizeDuration: 700, 5796 showImageNumberLabel: true, 5797 wrapAround: false, 5798 disableScrolling: false, 5799 /* 5800 Sanitize Title 5801 If the caption data is trusted, for example you are hardcoding it in, then leave this to false. 5802 This will free you to add html tags, such as links, in the caption. 5803 5804 If the caption data is user submitted or from some other untrusted source, then set this to true 5805 to prevent xss and other injection attacks. 5806 */ 5807 sanitizeTitle: false 5808 }; 5809 5810 Lightbox.prototype.option = function(options) { 5811 $.extend(this.options, options); 5812 }; 5813 5814 Lightbox.prototype.imageCountLabel = function(currentImageNum, totalImages) { 5815 return this.options.albumLabel.replace(/%1/g, currentImageNum).replace(/%2/g, totalImages); 5816 }; 5817 5818 Lightbox.prototype.init = function() { 5819 var self = this; 5820 // Both enable and build methods require the body tag to be in the DOM. 5821 $(document).ready(function() { 5822 self.enable(); 5823 self.build(); 5824 }); 5825 }; 5826 5827 // Loop through anchors and areamaps looking for either data-lightbox attributes or rel attributes 5828 // that contain 'lightbox'. When these are clicked, start lightbox. 5829 //Lightbox.prototype.enable = function() { 5830 // var self = this; 5831 // $('body').on('click', 'a[rel^=lightbox], area[rel^=lightbox], a[data-lightbox], area[data-lightbox]', function(event) { 5832 // self.start($(event.currentTarget)); 5833 // return false; 5834 // }); 5835 //}; 5836 5837 //å¹²æ¸é²æ¢å¤æ´ 5838 Lightbox.prototype.enable = function() { 5839 var self = this; 5840 $('body').on('click', 'a[rel^=lightbox_2], area[rel^=lightbox_2], a[data-lightbox_2], area[data-lightbox_2]', function(event) { 5841 self.start($(event.currentTarget)); 5842 return false; 5843 }); 5844 }; 5845 5846 // Build html for the lightbox and the overlay. 5847 // Attach event handlers to the new DOM elements. click click click 5848 Lightbox.prototype.build = function() { 5849 if ($('#lightbox').length > 0) { 5850 return; 5851 } 5852 5853 var self = this; 5854 5855 // The two root notes generated, #lightboxOverlay and #lightbox are given 5856 // tabindex attrs so they are focusable. We attach our keyboard event 5857 // listeners to these two elements, and not the document. Clicking anywhere 5858 // while Lightbox is opened will keep the focus on or inside one of these 5859 // two elements. 5860 // 5861 // We do this so we can prevent propogation of the Esc keypress when 5862 // Lightbox is open. This prevents it from intefering with other components 5863 // on the page below. 5864 // 5865 // Github issue: https://github.com/lokesh/lightbox2/issues/663 5866 $('<div id="lightbox_2_Overlay" tabindex="-1" class="lightbox_2_Overlay"></div><div id="lightbox_2" tabindex="-1" class="lightbox_2"><div class="lb-outerContainer"><div class="lb-container"><img class="lb-image" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" alt=""/><div class="lb-nav"><a class="lb-prev" aria-label="Previous image" href="" ></a><a class="lb-next" aria-label="Next image" href="" ></a></div><div class="lb-loader"><a class="lb-cancel"></a></div></div></div><div class="lb-dataContainer"><div class="lb-data"><div class="lb-details"><span class="lb-caption"></span><span class="lb-number"></span></div><div class="lb-closeContainer"><a class="lb-close"></a></div></div></div></div>').appendTo($('body')); 5867 5868 // Cache jQuery objects 5869 this.$lightbox_2 = $('#lightbox_2'); 5870 this.$overlay = $('#lightbox_2_Overlay'); 5871 5872 this.$outerContainer = this.$lightbox_2.find('.lb-outerContainer'); 5873 this.$container = this.$lightbox_2.find('.lb-container'); 5874 this.$image = this.$lightbox_2.find('.lb-image'); 5875 this.$nav = this.$lightbox_2.find('.lb-nav'); 5876 5877 // Store css values for future lookup 5878 this.containerPadding = { 5879 top: parseInt(this.$container.css('padding-top'), 10), 5880 right: parseInt(this.$container.css('padding-right'), 10), 5881 bottom: parseInt(this.$container.css('padding-bottom'), 10), 5882 left: parseInt(this.$container.css('padding-left'), 10) 5883 }; 5884 5885 this.imageBorderWidth = { 5886 top: parseInt(this.$image.css('border-top-width'), 10), 5887 right: parseInt(this.$image.css('border-right-width'), 10), 5888 bottom: parseInt(this.$image.css('border-bottom-width'), 10), 5889 left: parseInt(this.$image.css('border-left-width'), 10) 5890 }; 5891 5892 // Attach event handlers to the newly minted DOM elements 5893 this.$overlay.hide().on('click', function() { 5894 self.end(); 5895 return false;
5896 }); 5897 5898 this.$lightbox_2.hide().on('click', function(event) { 5899 if ($(event.target).attr('id') === 'lightbox') { 5900 self.end(); 5901 } 5902 }); 5903 5904 this.$outerContainer.on('click', function(event) { 5905 if ($(event.target).attr('id') === 'lightbox') { 5906 self.end(); 5907 } 5908 return false; 5909 }); 5910 5911 this.$lightbox_2.find('.lb-prev').on('click', function() { 5912 if (self.currentImageIndex === 0) { 5913 self.changeImage(self.album.length - 1); 5914 } else { 5915 self.changeImage(self.currentImageIndex - 1); 5916 } 5917 return false; 5918 }); 5919 5920 this.$lightbox_2.find('.lb-next').on('click', function() { 5921 if (self.currentImageIndex === self.album.length - 1) { 5922 self.changeImage(0); 5923 } else { 5924 self.changeImage(self.currentImageIndex + 1); 5925 } 5926 return false; 5927 }); 5928 5929 /* 5930 Show context menu for image on right-click 5931 5932 There is a div containing the navigation that spans the entire image and lives above of it. If 5933 you right-click, you are right clicking this div and not the image. This prevents users from 5934 saving the image or using other context menu actions with the image. 5935 5936 To fix this, when we detect the right mouse button is pressed down, but not yet clicked, we 5937 set pointer-events to none on the nav div. This is so that the upcoming right-click event on 5938 the next mouseup will bubble down to the image. Once the right-click/contextmenu event occurs 5939 we set the pointer events back to auto for the nav div so it can capture hover and left-click 5940 events as usual. 5941 */ 5942 this.$nav.on('mousedown', function(event) { 5943 if (event.which === 3) { 5944 self.$nav.css('pointer-events', 'none'); 5945 5946 self.$lightbox_2.one('contextmenu', function() { 5947 setTimeout(function() { 5948 this.$nav.css('pointer-events', 'auto'); 5949 }.bind(self), 0); 5950 }); 5951 } 5952 }); 5953 5954 5955 this.$lightbox_2.find('.lb-loader, .lb-close').on('click', function() { 5956 self.end(); 5957 return false; 5958 }); 5959 }; 5960 // Show overlay and lightbox. If the image is part of a set, add siblings to album array. 5961 Lightbox.prototype.start = function($link) { 5962 5963 var self = this; 5964 var $window = $(window); 5965 5966 $window.on('resize', $.proxy(this.sizeOverlay, this)); 5967 5968 this.sizeOverlay(); 5969 5970 this.album = []; 5971 var imageNumber = 0; 5972 5973 function addToAlbum($link) { 5974 self.album.push({ 5975 alt: $link.attr('data-alt'), 5976 link: $link.attr('href'), 5977 title: $link.attr('data-title') || $link.attr('title') 5978 }); 5979 } 5980 5981 // Support both data-lightbox attribute and rel attribute implementations 5982 //var dataLightboxValue = $link.attr('data-lightbox'); 5983 5984 //å¹²æ¸é²æ¢å¤æ´ 5985 var dataLightboxValue = $link.attr('data-lightbox_2'); 5986 var $links; 5987 5988 if (dataLightboxValue) { 5989 $links = $($link.prop('tagName') + '[data-lightbox="' + dataLightboxValue + '"]'); 5990 for (var i = 0; i < $links.length; i = ++i) { 5991 addToAlbum($($links[i])); 5992 if ($links[i] === $link[0]) { 5993 imageNumber = i; 5994 } 5995 } 5996 } else { 5997 if ($link.attr('rel') === 'lightbox') { 5998 // If image is not part of a set 5999 addToAlbum($link); 6000 } else { 6001 // If image is part of a set 6002 $links = $($link.prop('tagName') + '[rel="' + $link.attr('rel') + '"]'); 6003 for (var j = 0; j < $links.length; j = ++j) { 6004 addToAlbum($($links[j])); 6005 if ($links[j] === $link[0]) { 6006 imageNumber = j; 6007 } 6008 } 6009 } 6010 } 6011 6012 // Position Lightbox 6013 var top = $window.scrollTop() + this.options.positionFromTop; 6014 var left = $window.scrollLeft(); 6015 6016 6017 6018 this.$lightbox_2.css({ 6019 top: top + 'px', 6020 left: left + 'px' 6021 }).fadeIn(this.options.fadeDuration); 6022 6023 // Disable scrolling of the page while open 6024 if (this.options.disableScrolling) { 6025 $('body').addClass('lb-disable-scrolling'); 6026 } 6027 6028 this.changeImage(imageNumber); 6029 }; 6030 6031 // Hide most UI elements in preparation for the animated resizing of the lightbox. 6032 Lightbox.prototype.changeImage = function(imageNumber) { 6033 var self = this; 6034 var filename = this.album[imageNumber].link; 6035 var filetype = filename.split('.').slice(-1)[0]; 6036 var $image = this.$lightbox_2.find('.lb-image'); 6037 6038 // Disable keyboard nav during transitions 6039 this.disableKeyboardNav(); 6040 6041 // Show loading state 6042 this.$overlay.fadeIn(this.options.fadeDuration); 6043 $('.lb-loader').fadeIn('slow'); 6044 this.$lightbox_2.find('.lb-image, .lb-nav, .lb-prev, .lb-next, .lb-dataContainer, .lb-numbers, .lb-caption').hide(); 6045 this.$outerContainer.addClass('animating'); 6046 6047 // When image to show is preloaded, we send the width and height to sizeContainer() 6048 var preloader = new Image(); 6049 preloader.onload = function() { 6050 var $preloader; 6051 var imageHeight; 6052 var imageWidth; 6053 var maxImageHeight; 6054 var maxImageWidth; 6055 var windowHeight; 6056 var windowWidth; 6057 6058 $image.attr({ 6059 'alt': self.album[imageNumber].alt, 6060 'src': filename 6061 }); 6062 6063 $preloader = $(preloader); 6064 6065 $image.width(preloader.width); 6066 $image.height(preloader.height); 6067 windowWidth = $(window).width(); 6068 windowHeight = $(window).height(); 6069 6070 // Calculate the max image dimensions for the current viewport. 6071 // Take into account the border around the image and an additional 10px gutter on each side. 6072 maxImageWidth = windowWidth - self.containerPadding.left - self.containerPadding.right - self.imageBorderWidth.left - self.imageBorderWidth.right - 20; 6073 maxImageHeight = windowHeight - self.containerPadding.top - self.containerPadding.bottom - self.imageBorderWidth.top - self.imageBorderWidth.bottom - self.options.positionFromTop - 70; 6074 6075 /* 6076 Since many SVGs have small intrinsic dimensions, but they support scaling 6077 up without quality loss because of their vector format, max out their 6078 size. 6079 */ 6080 if (filetype === 'svg') { 6081 $image.width(maxImageWidth); 6082 $image.height(maxImageHeight); 6083 } 6084 6085 // Fit image inside the viewport. 6086 if (self.options.fitImagesInViewport) { 6087 6088 // Check if image size is larger then maxWidth|maxHeight in settings 6089 if (self.options.maxWidth && self.options.maxWidth < maxImageWidth) { 6090 maxImageWidth = self.options.maxWidth; 6091 } 6092 if (self.options.maxHeight && self.options.maxHeight < maxImageHeight) { 6093 maxImageHeight = self.options.maxHeight; 6094 } 6095 6096 } else { 6097 maxImageWidth = self.options.maxWidth || preloader.width || maxImageWidth; 6098 maxImageHeight = self.options.maxHeight || preloader.height || maxImageHeight; 6099 } 6100 6101 // Is the current image's width or height is greater than the maxImageWidth or maxImageHeight 6102 // option than we need to size down while maintaining the aspect ratio. 6103 if ((preloader.width > maxImageWidth) || (preloader.height > maxImageHeight)) { 6104 if ((preloader.width / maxImageWidth) > (preloader.height / maxImageHeight)) { 6105 imageWidth = maxImageWidth; 6106 imageHeight = parseInt(preloader.height / (preloader.width / imageWidth), 10); 6107 $image.width(imageWidth); 6108 $image.height(imageHeight); 6109 } else { 6110 imageHeight = maxImageHeight; 6111 imageWidth = parseInt(preloader.width / (preloader.height / imageHeight), 10); 6112 $image.width(imageWidth); 6113 $image.height(imageHeight); 6114 } 6115 } 6116 self.sizeContainer($image.width(), $image.height()); 6117 }; 6118 6119 // Preload image before showing 6120 preloader.src = this.album[imageNumber].link; 6121 this.currentImageIndex = imageNumber; 6122 }; 6123 6124 // Stretch overlay to fit the viewport 6125 Lightbox.prototype.sizeOverlay = function() { 6126 var self = this; 6127 /* 6128 We use a setTimeout 0 to pause JS execution and let the rendering catch-up. 6129 Why do this? If the `disableScrolling` option is set to true, a class is added to the body 6130 tag that disables scrolling and hides the scrollbar. We want to make sure the scrollbar is 6131 hidden before we measure the document width, as the presence of the scrollbar will affect the 6132 number. 6133 */ 6134 setTimeout(function() { 6135 self.$overlay 6136 .width($(document).width()) 6137 .height($(document).height()); 6138 6139 }, 0); 6140 }; 6141 6142 // Animate the size of the lightbox to fit the image we are showing 6143 // This method also shows the the image. 6144 Lightbox.prototype.sizeContainer = function(imageWidth, imageHeight) { 6145 var self = this; 6146 6147 var oldWidth = this.$outerContainer.outerWidth(); 6148 var oldHeight = this.$outerContainer.outerHeight(); 6149 var newWidth = imageWidth + this.containerPadding.left + this.containerPadding.right + this.imageBorderWidth.left + this.imageBorderWidth.right; 6150 var newHeight = imageHeight + this.containerPadding.top + this.containerPadding.bottom + this.imageBorderWidth.top + this.imageBorderWidth.bottom; 6151 6152 function postResize() { 6153 self.$lightbox_2.find('.lb-dataContainer').width(newWidth); 6154 self.$lightbox_2.find('.lb-prevLink').height(newHeight); 6155 self.$lightbox_2.find('.lb-nextLink').height(newHeight); 6156 6157 // Set focus on one of the two root nodes so keyboard events are captured. 6158 self.$overlay.focus(); 6159 6160 self.showImage(); 6161 } 6162 6163 if (oldWidth !== newWidth || oldHeight !== newHeight) { 6164 this.$outerContainer.animate({ 6165 width: newWidth, 6166 height: newHeight 6167 }, this.options.resizeDuration, 'swing', function() { 6168 postResize(); 6169 }); 6170 } else { 6171 postResize(); 6172 } 6173 }; 6174 6175 // Display the image and its details and begin preload neighboring images. 6176 Lightbox.prototype.showImage = function() { 6177 this.$lightbox_2.find('.lb-loader').stop(true).hide(); 6178 this.$lightbox_2.find('.lb-image').fadeIn(this.options.imageFadeDuration); 6179 6180 this.updateNav(); 6181 this.updateDetails(); 6182 this.preloadNeighboringImages(); 6183 this.enableKeyboardNav(); 6184 }; 6185 6186 // Display previous and next navigation if appropriate. 6187 Lightbox.prototype.updateNav = function() { 6188 // Check to see if the browser supports touch events. If so, we take the conservative approach 6189 // and assume that mouse hover events are not supported and always show prev/next navigation 6190 // arrows in image sets. 6191 var alwaysShowNav = false;
6192 try { 6193 document.createEvent('TouchEvent'); 6194 alwaysShowNav = (this.options.alwaysShowNavOnTouchDevices) ? true : false; 6195 } catch (e) {} 6196 6197 this.$lightbox_2.find('.lb-nav').show(); 6198 6199 if (this.album.length > 1) { 6200 if (this.options.wrapAround) { 6201 if (alwaysShowNav) { 6202 this.$lightbox_2.find('.lb-prev, .lb-next').css('opacity', '1'); 6203 } 6204 this.$lightbox_2.find('.lb-prev, .lb-next').show(); 6205 } else { 6206 if (this.currentImageIndex > 0) { 6207 this.$lightbox_2.find('.lb-prev').show(); 6208 if (alwaysShowNav) { 6209 this.$lightbox_2.find('.lb-prev').css('opacity', '1'); 6210 } 6211 } 6212 if (this.currentImageIndex < this.album.length - 1) { 6213 this.$lightbox_2.find('.lb-next').show(); 6214 if (alwaysShowNav) { 6215 this.$lightbox_2.find('.lb-next').css('opacity', '1'); 6216 } 6217 } 6218 } 6219 } 6220 }; 6221 6222 // Display caption, image number, and closing button. 6223 Lightbox.prototype.updateDetails = function() { 6224 var self = this; 6225 6226 // Enable anchor clicks in the injected caption html. 6227 // Thanks Nate Wright for the fix. @https://github.com/NateWr 6228 if (typeof this.album[this.currentImageIndex].title !== 'undefined' && 6229 this.album[this.currentImageIndex].title !== '') { 6230 var $caption = this.$lightbox_2.find('.lb-caption'); 6231 if (this.options.sanitizeTitle) { 6232 $caption.text(this.album[this.currentImageIndex].title); 6233 } else { 6234 $caption.html(this.album[this.currentImageIndex].title); 6235 } 6236 $caption.fadeIn('fast'); 6237 } 6238 6239 if (this.album.length > 1 && this.options.showImageNumberLabel) { 6240 var labelText = this.imageCountLabel(this.currentImageIndex + 1, this.album.length); 6241 this.$lightbox_2.find('.lb-number').text(labelText).fadeIn('fast'); 6242 } else { 6243 this.$lightbox_2.find('.lb-number').hide(); 6244 } 6245 6246 this.$outerContainer.removeClass('animating'); 6247 6248 this.$lightbox_2.find('.lb-dataContainer').fadeIn(this.options.resizeDuration, function() { 6249 return self.sizeOverlay(); 6250 }); 6251 }; 6252 6253 // Preload previous and next images in set. 6254 Lightbox.prototype.preloadNeighboringImages = function() { 6255 if (this.album.length > this.currentImageIndex + 1) { 6256 var preloadNext = new Image(); 6257 preloadNext.src = this.album[this.currentImageIndex + 1].link; 6258 } 6259 if (this.currentImageIndex > 0) { 6260 var preloadPrev = new Image(); 6261 preloadPrev.src = this.album[this.currentImageIndex - 1].link; 6262 } 6263 }; 6264 6265 Lightbox.prototype.enableKeyboardNav = function() { 6266 this.$lightbox_2.on('keyup.keyboard', $.proxy(this.keyboardAction, this)); 6267 this.$overlay.on('keyup.keyboard', $.proxy(this.keyboardAction, this)); 6268 }; 6269 6270 Lightbox.prototype.disableKeyboardNav = function() { 6271 this.$lightbox_2.off('.keyboard'); 6272 this.$overlay.off('.keyboard'); 6273 }; 6274 6275 Lightbox.prototype.keyboardAction = function(event) { 6276 var KEYCODE_ESC = 27; 6277 var KEYCODE_LEFTARROW = 37; 6278 var KEYCODE_RIGHTARROW = 39; 6279 6280 var keycode = event.keyCode; 6281 if (keycode === KEYCODE_ESC) { 6282 // Prevent bubbling so as to not affect other components on the page. 6283 event.stopPropagation(); 6284 this.end(); 6285 } else if (keycode === KEYCODE_LEFTARROW) { 6286 if (this.currentImageIndex !== 0) { 6287 this.changeImage(this.currentImageIndex - 1); 6288 } else if (this.options.wrapAround && this.album.length > 1) { 6289 this.changeImage(this.album.length - 1); 6290 } 6291 } else if (keycode === KEYCODE_RIGHTARROW) { 6292 if (this.currentImageIndex !== this.album.length - 1) { 6293 this.changeImage(this.currentImageIndex + 1); 6294 } else if (this.options.wrapAround && this.album.length > 1) { 6295 this.changeImage(0); 6296 } 6297 } 6298 }; 6299 6300 // Closing time. :-( 6301 Lightbox.prototype.end = function() { 6302 this.disableKeyboardNav(); 6303 $(window).off('resize', this.sizeOverlay); 6304 this.$lightbox_2.fadeOut(this.options.fadeDuration); 6305 this.$overlay.fadeOut(this.options.fadeDuration); 6306 6307 if (this.options.disableScrolling) { 6308 $('body').removeClass('lb-disable-scrolling'); 6309 } 6310 }; 6311 6312 return new Lightbox(); 6313}));;(function($){ 6314 $(window).on('load', function(event) { 6315 const ua = navigator.userAgent; 6316 if(ua.indexOf('Trident') != -1 || ua.indexOf('MSIE') != -1) { 6317 $('.cparts-animate.box > div,.cparts-animate .box > div').css('opacity',1).css('transform','translate(0,0)'); 6318 return false; 6319 } else { 6320 const options = { 6321 threshold: 0.1 6322 }; 6323 const observer = new IntersectionObserver(function(entries) { 6324 for(let i in entries) { 6325 let e = entries[i];
6326 let target=null; 6327 const appClass='moved'; 6328 if(e.intersectionRatio > 0 && !$(e.target).hasClass(appClass)) { 6329 if( $(e.target).find('.box > div').length > 0 ) { 6330 target = $(e.target).find('.box > div'); 6331 } else if( $(e.target).find('> div').length > 0 ) { 6332 target = $(e.target).find('> div'); 6333 } 6334 target.css('opacity',1).css('transform','none'); 6335 $(e.target).addClass(appClass); 6336 } 6337 } 6338 },options); 6339 let elms = document.querySelectorAll('.cparts-animate'); 6340 for(let i in elms) { 6341 if(elms.hasOwnProperty(i)) { 6342 observer.observe(elms[i]); 6343 } 6344 } 6345 } 6346 // dec-ulstyle--03 6347 if($('ul.dec-ulstyle--03').length) { 6348 $('ul.dec-ulstyle--03').each(function(){ 6349 $(this).find('li').addClass('dec-bg--light dec-line--primary'); 6350 }); 6351 } 6352 6353 // dec-olstyle--01 6354 if($('ol.dec-olstyle--01').length) { 6355 $('ol.dec-olstyle--01').each(function(){ 6356 $(this).find('li').addClass('dec-bg-pe--primary'); 6357 }); 6358 } 6359 }); 6360}(jQuery)); 6361(function($){ 6362 6363 $(window).on('load', function() { 6364 6365 $('body#type1column, body#type2column, body#type2column02, body#type3column').each(function() { 6366 // bodyã®ãã©ã³ããµã¤ãºãæãåºã 6367 var baseSize = $('body').css('font-size') 6368 baseSize = parseInt(baseSize); 6369 6370 // ãã©ã³ããµã¤ãºå¤æ´ãã¿ã³ãæ¼ãããæ 6371 $('.cparts-header-block__fontsize').find('button').on('click', function() { 6372 6373 // æ¨æº 6374 if ($(this).hasClass('cparts-btn-fontsize__sm')) { 6375 $('body').css('font-size', baseSize); 6376 $(this).addClass('cparts-btn-fontsize__active') 6377 $(this).siblings('button').removeClass('cparts-btn-fontsize__active') 6378 6379 // 大 6380 } else if ($(this).hasClass('cparts-btn-fontsize__md')) { 6381 $('body').css('font-size', baseSize * 1.2 + 'px'); 6382 $(this).addClass('cparts-btn-fontsize__active') 6383 $(this).siblings('button').removeClass('cparts-btn-fontsize__active') 6384 6385 // ç¹å¤§ 6386 } else if ($(this).hasClass('cparts-btn-fontsize__xl')) { 6387 $('body').css('font-size', baseSize * 1.4 + 'px'); 6388 $(this).addClass('cparts-btn-fontsize__active') 6389 $(this).siblings('button').removeClass('cparts-btn-fontsize__active') 6390 } 6391 }); 6392 }); 6393 6394 }); 6395 6396}(jQuery));
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.