1 2function TagLink( tag, language ) 3{ 4 var url = 'https://store.steampowered.com/tags/'; 5 if ( language ) 6 url += language + '/'; 7 else 8 url += 'th/'; 9 10 url += encodeURIComponent( tag ).replace( /%2F/g, '/' ) + '/'; 11 return url; 12} 13 14 15function AppTaggingMatchTags( rgTerms, rgTags, rgSuggestions ) 16{ 17 if ( rgTags && rgTags.length ) 18 { 19 for ( var i = 0; i < rgTags.length; i++ ) 20 { 21 var strNameNormalized = rgTags[i].name_normalized; 22 if ( !strNameNormalized ) 23 { 24 strNameNormalized = rgTags[i].name_normalized = rgTags[i].name.toLowerCase(); // @todo: We should use .normalize() when browsers actually support it. // For now just return the normal value as \W actually just removes entire tags. 25 } 26 27 var bMatch = true; 28 for ( var iTerm = 0; iTerm < rgTerms.length; iTerm++ ) 29 { 30 if ( strNameNormalized.indexOf( rgTerms[iTerm] ) == -1 ) 31 { 32 bMatch = false; 33 break; 34 } 35 } 36 if ( bMatch ) 37 { 38 rgSuggestions.push( rgTags[i].name ); 39 if ( rgSuggestions.length >= 10 ) 40 break; 41 } 42 } 43 } 44} 45 46function GetTagSuggestFunc( rgTagList ) 47{ 48 return function( value, fnSetSuggestions ) 49 { 50 var rgSuggestions = []; 51 if ( value ) 52 { 53 var rgTerms = value.toLowerCase().split( ' ' ); 54 AppTaggingMatchTags( rgTerms, rgTagList, rgSuggestions ); 55 56 rgSuggestions.sort(); 57 } 58 59 fnSetSuggestions( rgSuggestions ); 60 }; 61} 62 63function InitAppTagModal( appid, rgAppTags, rgUserTags, strTagLinkSNR, strYourTagSNR, bShowBanOption, bIsDLC ) 64{ 65 var $AppTagModal = $J('#app_tagging_modal'); 66 var $AppTagForm = $J('#app_tag_form'); 67 var $AppTagInput = $AppTagForm.find('input[name=tag]'); 68 var $AppTagButton = $AppTagForm.find('button'); 69 var TextSuggest = null; 70 71 var $PopularTags = $AppTagModal.find( '.app_tags.popular_tags' ); 72 var $YourTags = $AppTagModal.find( '.app_tags.your_tags' ); 73 var $FrequentTags = $AppTagModal.find( '.app_tags.previous_tags' ); 74 var $FrequentTagCtn = $AppTagModal.find( '.previous_tags_ctn' ).hide(); 75 76 var rgUserTagsByTagID = {}; 77 for ( var i= 0; i < rgUserTags.length; i++ ) 78 { 79 rgUserTagsByTagID[ rgUserTags[i].tagid ] = rgUserTags[i]; 80 } 81 82 var rgYourPopularTags = null; 83 var rgGlobalPopularTags = []; 84 var bYourPopularTagsRequested = false; 85 var bBannedTag = false; 86 var bAppliedTag = false; 87 var bAppliedTagToChildren = false; 88 89 // setup "advanced" admin mode - internal functions
90 var $AdvCheckbox = $J('#app_tagging_show_advanced'); 91 $AdvCheckbox.prop( 'checked', !!WebStorage.GetLocal( 'ShowAdvancedTaggingOptions' ) ); 92 $AdvCheckbox.on( 'change', function() { 93 if ( $AdvCheckbox.prop('checked') ) 94 { 95 WebStorage.SetLocal( 'ShowAdvancedTaggingOptions', 1 ); 96 $AppTagModal.addClass( 'advanced_enabled' ); 97 } 98 else 99 { 100 WebStorage.RemoveLocal( 'ShowAdvancedTaggingOptions' ); 101 $AppTagModal.removeClass( 'advanced_enabled' ); 102 } 103 } ).trigger('change'); 104 105 var fnUpdateTagButtonState = function() { 106 if ( $AppTagInput.val().length > 0 ) 107 $AppTagButton.removeClass( 'btn_disabled' ); 108 else 109 $AppTagButton.addClass( 'btn_disabled' ); 110 }; 111 112 var fnSetCheckboxTooltip = function( $Checkbox ) 113 { 114 if ( $Checkbox.hasClass('checked') ) 115 $Checkbox.data('tooltip-text', 'à¸à¸¸à¸à¸à¸³à¹à¸à¹à¸à¸à¸µà¹à¹à¸à¹à¸à¹à¹à¸¥à¹à¸§ à¸à¸¥à¸´à¸à¹à¸à¸·à¹à¸à¸¥à¸à¸à¸à¸' ); 116 else 117 $Checkbox.data('tooltip-text', 'à¸à¸¥à¸´à¸à¸à¸µà¹à¸à¸µà¹à¹à¸à¸·à¹à¸à¸à¸³à¹à¸à¹à¸à¸à¸µà¹à¹à¸à¹à¸à¹' ); 118 }; 119 120 var fnSetReportTooltip = function( $ReportFlag ) 121 { 122 if ( $ReportFlag.hasClass('reported') ) 123 $ReportFlag.data('tooltip-text', 'à¸à¸¸à¸à¹à¸à¹à¸£à¸²à¸¢à¸à¸²à¸à¹à¸à¹à¸à¸à¸µà¹à¹à¸¥à¹à¸§à¸§à¹à¸² à¸à¸³à¸¡à¸²à¹à¸à¹à¸à¸²à¸à¹à¸¡à¹à¸à¸£à¸à¸à¸±à¸à¸à¸¥à¸´à¸à¸ ัà¸à¸à¹à¸à¸µà¹ à¸à¸¥à¸´à¸à¸à¸µà¸à¸à¸£à¸±à¹à¸à¹à¸à¸·à¹à¸à¸¥à¸à¸£à¸²à¸¢à¸à¸²à¸à¸à¸µà¹' ); 124 else 125 $ReportFlag.data('tooltip-text', 'à¸à¸¥à¸´à¸à¹à¸à¸·à¹à¸à¸£à¸²à¸¢à¸à¸²à¸à¹à¸à¹à¸à¸à¸µà¹à¸§à¹à¸² à¸à¸³à¸¡à¸²à¹à¸à¹à¸à¸²à¸à¹à¸¡à¹à¸à¸£à¸à¸à¸±à¸à¸à¸¥à¸´à¸à¸ ัà¸à¸à¹à¸à¸µà¹' ); 126 }; 127 128 var fnCheckboxClick = function( checkbox, tag, bPopular, tagid ) 129 { 130 var bWithdraw = $J(checkbox).hasClass('checked'); 131 fnApplyTag( tag, bWithdraw, bPopular, 0, tagid ); 132 }; 133 134 var fnAdjustClick = function( checkbox, tag, bPopular, tagid ) 135 { 136 console.log( rgUserTagsByTagID[ tagid ] ); 137 var nCurrentWeight = ( rgUserTagsByTagID[ tagid ] && rgUserTagsByTagID[ tagid ].weight ) || 0; 138 ShowPromptDialog( 'Adjust Tag Weight', 'Enter a new weight for your vote. Current weight: ' + nCurrentWeight, 'Tag' ) 139 .done( function( value ) { 140 var weight = parseInt( value ); 141 if ( weight ) 142 fnApplyTag( tag, weight < 0, bPopular, 0, tagid, weight ); 143 }); 144 } 145 146 var fnMakeTag = function( tagid, tagdata, checked, bPopular, bReported, bBrowsable ) 147 { 148 var tag = tagdata.name; 149 var $Tag = $J('<div/>', {'class': 'app_tag_control', 'data-tagid': tagid } ); 150 151 var $Checkbox = $J('<div/>', {'data-tooltip-text': '', 'class': 'app_tag_checkbox' + ( checked && !bReported ? ' checked' : '' ) }).click( function() { fnCheckboxClick( this, tag, bPopular, tagid ); }); 152 153 fnSetCheckboxTooltip( $Checkbox ); 154 155 $Tag.append( $Checkbox ); 156 157 if ( bPopular ) 158 { 159 $Tag.addClass( 'popular' ); 160 161 // only if logged in 162 if ( $YourTags.length ) 163 { 164 if ( bShowBanOption ) 165 { 166 var $Ban = $J('<div/>', {'class': 'app_tag_ban'} ); 167 $Ban.data('tooltip-text', 'à¸à¸¥à¸´à¸à¸à¸µà¹à¸à¸µà¹à¹à¸à¸·à¹à¸à¸¥à¸à¹à¸à¹à¸à¸à¸µà¹à¸à¸à¸à¸à¸²à¸à¸à¸¥à¸´à¸à¸ ัà¸à¸à¹à¸à¸µà¹ à¸à¸±à¸§à¹à¸¥à¸·à¸à¸à¸à¸µà¹à¸à¸³à¸à¸±à¸à¹à¸à¸à¸²à¸°à¸à¸¹à¹à¸à¸±à¸à¸à¸²à¹à¸¥à¸°à¹à¸à¹à¸²à¸«à¸à¹à¸²à¸à¸µà¹ Steam à¹à¸à¹à¸²à¸à¸±à¹à¸' ); 168 169 $Tag.append( $Ban ); 170 var content = $J( '<div/>' ); 171 content.append( $J( '<div/>', { 'class': 'app_tag_ban_prompt' } ).text( 'à¸à¸¸à¸à¹à¸à¹à¹à¸à¸«à¸£à¸·à¸à¹à¸¡à¹à¸§à¹à¸²à¸à¹à¸à¸à¸à¸²à¸£à¸¥à¸à¹à¸à¹à¸ "%s" à¸à¸à¸à¸à¸²à¸à¸à¸¥à¸´à¸à¸ ัà¸à¸à¹à¸à¸µà¹?'.replace( /%s/, tag ) ) ); 172 if ( !bIsDLC ) { 173 content.append( $J( '<div/>', { 'class': 'app_tag_ban_checkbox' } ).append( $J( '<input/>', {'type': 'checkbox', 'name':'ban_child_tags', 'checked': 1, 'id': 'ban_child_tags' } ) ) ); 174 content.append( $J( '<div/>', { 'class': 'app_tag_ban_label' } ).append( $J( '<label/>', {'for': 'ban_child_tags' } ).text( 'à¹à¸à¸à¹à¸à¹à¸à¸ªà¸³à¸«à¸£à¸±à¸à¹à¸à¸·à¹à¸à¸«à¸²à¸à¸²à¸§à¸à¹à¹à¸«à¸¥à¸à¸¢à¹à¸à¸¢à¸à¹à¸§à¸¢' ) ) ); 175 content.append( $J( '<div/>
175', { 'class': 'app_tag_ban_note' } ).text( 'à¹à¸à¸£à¸à¸à¸£à¸²à¸: à¸à¸²à¸£à¸à¸³à¹à¸à¸´à¸à¸à¸²à¸£à¸à¸±à¸à¸à¸¥à¹à¸²à¸§à¸à¸°à¸ªà¹à¸à¸à¸¥à¸à¸£à¸°à¸à¸à¸à¹à¸à¹à¸à¸·à¹à¸à¸«à¸²à¸à¸²à¸§à¸à¹à¹à¸«à¸¥à¸à¸à¸±à¹à¸à¸«à¸¡à¸à¸à¸µà¹à¹à¸à¸µà¹à¸¢à¸§à¸à¹à¸à¸à¸à¸±à¸à¹à¸à¸¡à¸à¸µà¹ à¹à¸¡à¹à¹à¸à¹à¹à¸à¸·à¹à¸à¸«à¸²à¸à¸²à¸§à¸à¹à¹à¸«à¸¥à¸à¸à¸µà¹à¸à¸¸à¸à¸ªà¸£à¹à¸²à¸à¸«à¸£à¸·à¸à¸§à¸²à¸à¸à¸³à¸«à¸à¹à¸²à¸¢à¹à¸à¸à¸à¸²à¸à¸à¸à¹à¸§à¸¢ à¹à¸à¹à¸à¸¸à¸à¸à¸°à¸¢à¸±à¸à¸ªà¸²à¸¡à¸²à¸£à¸à¹à¸¥à¸´à¸à¹à¸à¸à¹à¸à¹à¸à¸ªà¸³à¸«à¸£à¸±à¸à¹à¸à¸·à¹à¸à¸«à¸²à¸à¸²à¸§à¸à¹à¹à¸«à¸¥à¸à¹à¸à¹à¸¥à¸°à¸£à¸²à¸¢à¸à¸²à¸£à¹à¸à¹' ) ); 176 } 177 178 $Ban.click( function() { 179 ShowConfirmDialog( 'à¹à¸à¸à¹à¸à¹à¸', content ).done( function() 180 { 181 $Ban.trigger('mouseleave'); // to clear the tooltip 182 var checkbox = content.find( '.app_tag_ban_checkbox > input' ); 183 var bApplyToChildren = false; 184 185 if ( checkbox.is( ':checked' ) ) 186 { 187 // Ban all children 188 bApplyToChildren = true; 189 } 190 fnApplyTag( tag, false, true, -1, 0 /* no tag id */, 0 /* no weight */, bApplyToChildren ); 191 }); 192 }); 193 } 194 else 195 { 196 var $Report = $J('<div/>', {'class': 'app_tag_report' + ( bReported ? ' reported' : '' )}); 197 198 fnSetReportTooltip($Report); 199 $Tag.append($Report); 200 201 $Report.click(function () { 202 fnApplyTag(tag, $Report.hasClass('reported'), true, 2); 203 }); 204 } 205 } 206 } 207 208 if ( bShowBanOption ) 209 { 210 var $AdjCheckbox = $J('<div/>', {'data-tooltip-text': 'Adjust your applied weight', 'class': 'app_tag_advanced app_tag_adjust' }).click( function() { fnAdjustClick( this, tag, bPopular, tagid ); }).text( "±" ); 211 $Tag.append( $AdjCheckbox ); 212 213 $Tag.append( $J('<div/>', {'class': 'app_tag_advanced app_tag_count' } ).text( tagdata.count ) ); 214 } 215 216 if ( bBrowsable ) 217 { 218 var $Link = $J('<a/>', {'class': 'app_tag', 'href': TagLink(tag) + '?snr=' + strTagLinkSNR}).text(tag); 219 $Link.InstrumentLinks(); 220 $Tag.append($Link); 221 } 222 else 223 { 224 var $Link = $J('<div/>', {'class': 'app_tag not_browseable' }).text(tag); 225 $Link.data('tooltip-text', 'รายà¸à¸²à¸£à¸à¸µà¹à¸à¸¹à¸à¹à¸à¹à¸à¸à¹à¸§à¸¢ "%s" ยัà¸à¸¡à¸µà¹à¸¡à¹à¸¡à¸²à¸à¸à¸'.replace( /%s/, $Link.html() ) ); 226 227 $Tag.append( $Link ); 228 } 229 230 return $Tag; 231 }; 232 233 var fnMakeFrequentTag = function( tagid, tag ) 234 { 235 var $Tag = $J('<div/>', {'class': 'app_tag previous_tag', 'data-tagid': tagid, 'data-tooltip-text': 'à¸à¸¥à¸´à¸à¸à¸µà¹à¸à¸µà¹à¹à¸à¸·à¹à¸à¸à¸³à¹à¸à¹à¸à¸à¸µà¹à¹à¸à¹à¸à¹' }).text( tag ).click( function() { fnApplyTag( tag ) } ); 236 237 return $Tag; 238 }; 239 240 var fnCheckTagBox = function( $Elements, withdraw, reported ) 241 { 242 var $Checkbox = $Elements.find( '.app_tag_checkbox' ); 243 244 if ( withdraw || reported ) 245 { 246 $Checkbox.removeClass( 'checked' ); 247 } 248 else 249 { 250 $Checkbox.addClass( 'checked' ); 251 } 252 fnSetCheckboxTooltip( $Checkbox ); 253 254 var $ReportFlag = $Elements.find( '.app_tag_report' ); 255 if ( reported ) 256 $ReportFlag.addClass( 'reported' ); 257 else 258 $ReportFlag.removeClass( 'reported' ); 259 fnSetReportTooltip( $ReportFlag ); 260 }; 261 262 var fnFlashTag = function( $Tag ) 263 { 264 $Tag.addClass('tag_control_flash'); 265 window.setTimeout( function() { $Tag.removeClass( 'tag_control_flash' ) }, 1100 ); 266 }; 267 268 var fnBuildTagDisplay = function( Modal ) 269 { 270 $PopularTags.empty(); 271 $YourTags.empty(); 272 $FrequentTags.empty(); 273 274 for ( var i = 0; i < rgAppTags.length; i++ ) 275 { 276 var tagid = rgAppTags[i].tagid; 277 var $AppTag = fnMakeTag( tagid, rgAppTags[i], rgUserTagsByTagID[tagid], true, rgUserTagsByTagID[tagid] && rgUserTagsByTagID[tagid].is_reported, true ); 278 279 $PopularTags.append( $AppTag ); 280 } 281 282 Modal.AdjustSizing(); 283 284 if ( !$YourTags.length ) 285 { 286 return; //not logged in case 287 } 288 289 if ( rgYourPopularTags === null ) 290 { 291 $YourTags.html( '<div class="yourtags_throbber"><img src="https://store.fastly.steamstatic.com/public/images/login/throbber.gif"></div>' ); 292 if ( !bYourPopularTagsRequested ) 293 { 294 bYourPopularTagsRequested = true; 295 296 var url = 'https://store.steampowered.com/tagdata/myfrequenttags'; 297 var mytag_version = WebStorage.GetLocal( 'mytag_version', true ); 298 if ( mytag_version ) 299 url += '?v=' + parseInt( mytag_version ); 300 301 $J.get( url ).done( function( data ) { 302 rgYourPopularTags = data || []; 303 fnBuildTagDisplay( Modal );
304 Modal.AdjustSizing(); 305 }).fail( function() { 306 rgYourPopularTags = []; 307 fnBuildTagDisplay( Modal ); 308 Modal.AdjustSizing(); 309 }); 310 311 // also load the global popular tags, to populate the autocomplete with 312 $J.get( 'https://store.steampowered.com/tagdata/populartags/thai').done( function ( data ) { 313 for ( var i = 0; i < data.length; i++ ) 314 rgGlobalPopularTags.push( data[i] ); // don't assign, we've got references to this guy 315 }); 316 } 317 } 318 else 319 { 320 var rgYourTagsSeen = {}; 321 for ( var i = 0; i < rgUserTags.length; i++ ) 322 { 323 var tagid = rgUserTags[i].tagid; 324 rgYourTagsSeen[tagid] = true; 325 326 if ( rgUserTagsByTagID[tagid] && rgUserTagsByTagID[tagid].is_reported ) 327 continue; 328 329 var $AppTag = fnMakeTag( tagid, rgUserTags[i], rgUserTagsByTagID[tagid], false, false, rgUserTags[i].browseable ); 330 331 $YourTags.append( $AppTag ); 332 } 333 334 if ( $YourTags.children().length == 0 ) 335 { 336 $YourTags.append( $J('<div/>', {'class': 'app_tag_control no_tags_yet'}).text('ยัà¸à¹à¸¡à¹à¸¡à¸µà¹à¸à¹à¸' ) ); 337 } 338 339 var cPopularTagsToDisplay = 16; 340 for ( var i = 0; i < rgYourPopularTags.length; i++ ) 341 { 342 var tagid = rgYourPopularTags[i].tagid; 343 344 if ( rgYourTagsSeen[tagid] ) 345 continue; 346 347 var $AppTag = fnMakeFrequentTag( tagid, rgYourPopularTags[i].name ); 348 349 $FrequentTags.append( $AppTag ); 350 $FrequentTagCtn.show(); 351 352 if ( --cPopularTagsToDisplay <= 0 ) 353 break; 354 } 355 } 356 }; 357 358 var fnUpdateUserTagsOnPage = function() 359 { 360 var $YourTagsOnPage = $J('.your_tags[data-appid=' + appid + ']'); 361 var $AddYourOwn = $YourTagsOnPage.children( '.app_tag.add_your_own'); 362 var $AddMore = $YourTagsOnPage.children( '.app_tag.add_more'); 363 if ( rgUserTags.length ) 364 { 365 $AddYourOwn.hide(); 366 $AddMore.show(); 367 $YourTagsOnPage.empty(); 368 for ( var i = 0; i < rgUserTags.length; i++ ) 369 { 370 if ( !rgUserTags[i].is_reported && rgUserTags[i].browseable ) 371 { 372 var $AppTag = $J('<a/>', { 'class': 'app_tag', 'href': TagLink(rgUserTags[i].name) + '?snr=' + strYourTagSNR }).text(rgUserTags[i].name); 373 $AppTag.InstrumentLinks(); 374 $YourTagsOnPage.append($AppTag); 375 } 376 } 377 378 // always put non-browseable after all browseable tags, so they are less likely to display 379 for( var i = 0; i < rgUserTags.length; i++ ) 380 { 381 if ( !rgUserTags[i].is_reported && !rgUserTags[i].browseable ) 382 { 383 var $AppTag = $J('<div/>', {'class': 'app_tag not_browseable' }).text( rgUserTags[i].name ); 384 $AppTag.data('tooltip-text', 'รายà¸à¸²à¸£à¸à¸µà¹à¸à¸¹à¸à¹à¸à¹à¸à¸à¹à¸§à¸¢ "%s" ยัà¸à¸¡à¸µà¹à¸¡à¹à¸¡à¸²à¸à¸à¸'.replace( /%s/, $AppTag.html() ) ); 385 386 $YourTagsOnPage.append( $AppTag ); 387 } 388 } 389 } 390 else 391 { 392 $AddYourOwn.show(); 393 $AddMore.hide(); 394 $YourTagsOnPage.empty(); 395 } 396 $YourTagsOnPage.append( $AddYourOwn, $AddMore ); 397 AdjustVisibleAppTags( $YourTagsOnPage ); 398 }; 399 400 var fnIsTagBrowseable = function( tagid, name ) 401 { 402 for ( var i = 0; i < rgGlobalPopularTags.length; i++ ) 403 { 404 if ( rgGlobalPopularTags[i].name == name ) 405 return true; 406 } 407 return false; 408 }; 409 410 var fnApplyTag = function( tag, withdraw, bPopularClick, eReportType, unTagID, nWeight, bApplyToChildren ) 411 { 412 var rgParams = { 413 appid: appid, 414 sessionid: g_sessionID, 415 tag: tag 416 }; 417 if ( unTagID ) 418 rgParams['tagid'] = unTagID; 419 420 if ( nWeight ) 421 { 422 rgParams['weight'] = Math.abs( nWeight ); 423 if ( nWeight < 0 ) 424 rgParams['withdraw'] = 1; 425 } 426 else if ( withdraw ) 427 rgParams['withdraw'] = 1; 428 else if ( eReportType ) 429 rgParams['reporttype'] = eReportType; 430 431 if ( bApplyToChildren ) 432 rgParams['applytochildren'] = bApplyToChildren; 433 434 $J.post( 'https://store.steampowered.com/tagdata/tagapp', rgParams ).done( function( data ) { 435 436 bAppliedTag = true; 437 bAppliedTagToChildren = bAppliedTagToChildren || bApplyToChildren; 438 439 var strControlSelector = '.app_tag_control[data-tagid=' + data.tagid + ']'; 440 var $AppTag = $PopularTags.find( strControlSelector ); 441 var $YourTag = $YourTags.find( strControlSelector ); 442 443 if ( typeof data.browseable == 'undefined' ) 444 { 445 data.browseable = fnIsTagBrowseable( data.tagid, data.name ); 446 } 447 448 if ( !$YourTag.length && !data.withdraw && !data.reported ) 449 { 450 $YourTag = fnMakeTag( data.tagid, data, false, false, false, data.browseable ); 451 $YourTags.append( $YourTag ); 452 $YourTags.children('.no_tags_yet').hide(); 453 } 454 455 var iExistingTag; 456 for ( iExistingTag = 0; iExistingTag < rgUserTags.length; iExistingTag++ ) 457 { 458 if ( rgUserTags[iExistingTag].tagid == data.tagid ) 459 { 460 break; 461 } 462 } 463 464 if ( data.withdraw ) 465 { 466 delete rgUserTagsByTagID[ data.tagid ]; 467 if ( iExistingTag < rgUserTags.length ) 468 rgUserTags.splice( iExistingTag, 1 ); 469 470 fnCheckTagBox( $YourTag, true ); 471 } 472 else 473 {
474 rgUserTagsByTagID[ data.tagid ] = data; 475 if ( iExistingTag >= rgUserTags.length ) 476 { 477 rgUserTags.push( data ); 478 } 479 480 // remove from the frequent tag box 481 $FrequentTags.find( '[data-tagid=' + data.tagid + ']' ).hide(); 482 if ( $FrequentTags.children().length == 0 ) 483 $FrequentTagCtn.hide(); 484 485 // make sure it's checked 486 if ( data.is_reported ) 487 { 488 $YourTag.remove(); 489 } 490 else 491 { 492 fnCheckTagBox( $YourTag ); 493 } 494 } 495 496 fnCheckTagBox( $AppTag, data.withdraw, data.is_reported ); 497 498 // highlight the popular tag to show it has changed 499 if ( !bPopularClick && !data.withdraw && $AppTag.length ) 500 { 501 fnFlashTag( $AppTag ); 502 } 503 504 if ( !data.withdraw && $YourTag.length ) 505 fnFlashTag( $YourTag ); 506 507 // roll "mytag_version" variable which will force a reload of user's frequent tags 508 WebStorage.SetLocal( 'mytag_version', parseInt( WebStorage.GetLocal( 'mytag_version', true ) || 0 ) + 1, true ); 509 510 if ( eReportType > 0 && !withdraw ) 511 { 512 ShowAlertDialog( 'รายà¸à¸²à¸à¹à¸à¹à¸', 'à¸à¸à¸à¸à¸¸à¸à¸ªà¸³à¸«à¸£à¸±à¸à¸£à¸²à¸¢à¸à¸²à¸à¸à¸à¸à¸à¸¸à¸ à¹à¸à¹à¸à¸à¸µà¹à¸¡à¸µà¸à¸³à¸à¸§à¸à¸£à¸²à¸¢à¸à¸²à¸à¸à¸¶à¸à¸à¸³à¸à¸§à¸à¸à¸µà¹à¸à¸³à¸«à¸à¸à¹à¸§à¹à¸à¸°à¸à¸¹à¸à¸¥à¸à¸à¸à¸à¸à¸²à¸à¸à¸¥à¸´à¸à¸ ัà¸à¸à¹à¸à¸µà¹'); 513 } 514 else if ( eReportType == -1 ) 515 { 516 $AppTag.hide( 'fast' ); 517 bBannedTag = true; 518 } 519 520 }).fail( function() { 521 ShowAlertDialog( 'à¸à¸¹à¹à¸¥à¸°à¹à¸à¹à¹à¸à¹à¸à¹à¸à¸ªà¸³à¸«à¸£à¸±à¸à¸à¸¥à¸´à¸à¸ ัà¸à¸à¹à¸à¸µà¹', 'There was a problem adding your tag.' ); 522 }); 523 }; 524 525 var fnOnSubmit = function(event) { 526 if ( event ) 527 event.preventDefault(); 528 529 if ( $AppTagInput.val().length == 0 ) 530 return; 531 532 fnApplyTag( $AppTagInput.val(), false ); 533 $AppTagInput.val('').change().focus(); 534 }; 535 536 var changeUrl = function(url, removeParam="", addParam="") { 537 538 if(url.indexOf("?") === -1) return url; 539 var bits = url.split("?"); 540 if(bits.length < 2) return url; 541 var firstBit = bits[0]; 542 var secondBit = bits[1]; 543 var params = []; 544 if(secondBit.indexOf("&") === -1){ 545 params.push(secondBit); 546 }else{ 547 var nextBits = secondBit.split("&"); 548 for(var i = 0; i < nextBits.length; i++){ 549 params.push(nextBits[i]); 550 } 551 } 552 553 var result = firstBit; 554 555 for(var i = params.length-1; i >= 0; i--){ 556 var param = params[i]; 557 if(param === removeParam){ 558 params.splice(i,1); 559 } 560 } 561 562 if(addParam !== "" && addParam !== null && params.indexOf(addParam) === -1){ 563 params.push(addParam); 564 } 565 566 var extraBits = params.join("&"); 567 if(extraBits === "&") extraBits = ""; 568 569 if(extraBits !== ""){ 570 result += "?" + extraBits; 571 } 572 573 return result; 574 } 575 576 window.ShowAppTagModal = function( appid ) 577 { 578 if ( typeof GetUsabilityTracker !== 'undefined' ) 579 GetUsabilityTracker().AddEvent( 1001 ); 580 581 $AppTagModal.show(); 582 var Modal = ShowAlertDialog( 'à¸à¸¹à¹à¸¥à¸°à¹à¸à¹à¹à¸à¹à¸à¹à¸à¸ªà¸³à¸«à¸£à¸±à¸à¸à¸¥à¸´à¸à¸ ัà¸à¸à¹à¸à¸µà¹', $AppTagModal, 'à¸à¸´à¸' ); 583 Modal.GetContent().addClass( 'app_tag_modal_frame'); 584 fnBuildTagDisplay( Modal ); 585 Modal.AdjustSizing(); 586 587 Modal.always( function() { 588 if ( TextSuggest ) 589 { 590 TextSuggest.Destroy(); 591 TextSuggest = null; 592 } 593 594 fnUpdateUserTagsOnPage(); 595 596 if ( bAppliedTag && bShowBanOption && typeof FlushApp != 'undefined' ) 597 FlushApp( appid, bAppliedTagToChildren ); 598 else if ( bBannedTag ) 599 window.location.reload(); 600 601 window.history.pushState({}, document.title, changeUrl(window.location.href, "tags", "")); 602 603 } ); 604 605 // in the "you need to log in" case, we don't have a form to display 606 if ( $AppTagForm.length ) 607 { 608 $AppTagInput.val(''); 609 $AppTagInput.change( fnUpdateTagButtonState ); 610 $AppTagInput.keyup( fnUpdateTagButtonState ); 611 fnUpdateTagButtonState(); 612 $AppTagInput.focus(); 613 614 $AppTagForm.submit( fnOnSubmit ); 615 $AppTagForm.keyup( function( event ) { if ( event.which == 13 ) event.stopPropagation() } ); 616 617 TextSuggest = new CTextInputSuggest( $AppTagInput, GetTagSuggestFunc( rgGlobalPopularTags ), function( suggestion ) { fnOnSubmit(); } ); 618 619 // hack to size the input control correctly 620 $AppTagForm.find( '.gray_bevel').css( 'margin-right', ( $AppTagButton.width() + 12 ) + 'px' ); 621 } 622 623 //add "tags" param to the URL 624 window.history.pushState({}, document.title, changeUrl(window.location.href, "", "tags")); 625 626 }; 627 628 629 630 var $PopularTagsOnPage = $J('.popular_tags[data-appid=' + appid + ']'); 631 var $YourTagsOnPage = $J('.your_tags[data-appid=' + appid + ']'); 632 AdjustVisibleAppTags( $PopularTagsOnPage ); 633 fnUpdateUserTagsOnPage(); 634 635 $J(window ).on('resize.VisibleAppTags', function() { 636 AdjustVisibleAppTags( $PopularTagsOnPage ); 637 AdjustVisibleAppTags( $YourTagsOnPage ); 638 }); 639} 640 641function AdjustVisibleAppTags( $TagCtn ) 642{ 643 var bPopularTags = $TagCtn.hasClass( 'popular_tags' ); 644 var $AddButton = $TagCtn.children('.app_tag.add_button'); 645 if ( !bPopularTags ) 646 $AddButton = $AddButton.filter(':visible'); 647 648 649 var k_nSpacing = 5; 650 var nSpaceRemaining = $TagCtn.width() - $AddButton.outerWidth(); 651 652 var bAnyHidden = false;
653 $TagCtn.children( '.app_tag:not(.add_button)').each( function() { 654 var $Element = $J(this); 655 var nWidth = $Element.outerWidth() + k_nSpacing; 656 if ( nWidth > nSpaceRemaining ) 657 { 658 $Element.hide(); 659 bAnyHidden = true; 660 } 661 else 662 { 663 nSpaceRemaining -= nWidth; 664 $Element.show(); 665 } 666 }); 667} 668 669function InitTagTabs( strURL, cc, rgTabNames, rgInitialParams ) 670{ 671 var g_rgTabs = {}; 672 var g_strTabRequestURL = strURL; 673 var g_rgTabBaseParams = { 674 cc: cc, 675 l: 'thai', 676 v: 4 677 }; 678 var g_rgTabParams = {}; 679 var g_strActiveTab = null; 680 681 682 var fnOnTabFilterChange = function() 683 { 684 for ( var strTab in g_rgTabs ) 685 { 686 var Tab = g_rgTabs[strTab]; 687 Tab.m_iStart = 0; 688 Tab.m_nLoaded = 0; 689 Tab.m_$Items.css( 'top', '0px' ); 690 } 691 UpdateTabDisplay(); 692 }; 693 694 var fnAddFilter = function( strParam, value, $Checkbox ) 695 { 696 if ( !$Checkbox ) 697 $Checkbox = $J('.tab_filter_control[data-param=' + strParam + '][data-value=' + value + ']'); 698 699 $Checkbox.addClass( 'checked' ); 700 701 if ( !g_rgTabParams[strParam] ) 702 g_rgTabParams[strParam] = []; 703 g_rgTabParams[strParam].push( value ); 704 705 var $Filter = $J('<div/>', {'class': 'tab_filter' } ); 706 $Filter.attr( 'data-param', strParam ); 707 $Filter.attr( 'data-value', value ); 708 $Filter.text( $Checkbox.text() ); 709 $Filter.append( $J('<div/>', {'class': 'tab_filter_remove' }).html(' ').click( function() { fnRemoveFilter( strParam, value, $Checkbox, $Filter ); } ) ); 710 $J('.tab_filters').append( $Filter ); 711 $J('.tab_filter_ctn').show( 'fast' ); 712 713 fnOnTabFilterChange(); 714 }; 715 716 var fnRemoveFilter = function( strParam, value, $Checkbox, $Filter ) 717 { 718 if ( !$Checkbox ) 719 $Checkbox = $J('.tab_filter_control[data-param=' + strParam + '][data-value=' + value + ']'); 720 if ( !$Filter ) 721 $Filter = $J('.tab_filter[data-param=' + strParam + '][data-value=' + value + ']'); 722 723 $Checkbox.removeClass('checked'); 724 725 if ( g_rgTabParams[strParam] ) 726 g_rgTabParams[strParam] = g_rgTabParams[strParam].filter( function( val ) { return val != value; } ); 727 728 $Filter.remove(); 729 if ( !$J('.tab_filters').children().length ) 730 $J('.tab_filter_ctn').hide( 'fast' ); 731 732 fnOnTabFilterChange(); 733 }; 734 735 736 var InitTabEvents = function( Tab ) 737 { 738 Tab.m_$Select.click( function() { 739 UpdateTabDisplay( Tab.m_strName ); 740 } ); 741 742 Tab.m_$Next.css( 'visibility', 'visible' ); 743 Tab.m_$NextLink.attr( 'href', '#' ); 744 Tab.m_$NextLink.click( function( event ) { 745 event.preventDefault(); 746 if ( !Tab.m_bRequestInFlight && !Tab.m_bAnimating ) 747 DoTabScroll( Tab, 10 ); 748 }); 749 750 751 Tab.m_$Prev.css( 'visibility', 'visible' ); 752 Tab.m_$PrevLink.attr( 'href', '#' ); 753 Tab.m_$PrevLink.click( function( event ) { 754 event.preventDefault(); 755 if ( !Tab.m_bRequestInFlight && !Tab.m_bAnimating ) 756 DoTabScroll( Tab, -10 ); 757 }); 758 }; 759 760 var UpdateTabDisplay = function( strActiveTab ) 761 { 762 if ( !strActiveTab ) 763 strActiveTab = g_strActiveTab; 764 else 765 g_strActiveTab = strActiveTab; 766 767 for ( var strTabName in g_rgTabs ) 768 { 769 var Tab = g_rgTabs[strTabName]; 770 if ( strTabName == strActiveTab ) 771 { 772 Tab.m_$Select.addClass( 'active' ); 773 Tab.m_$Content.show(); 774 if ( Tab.m_nLoaded == 0 ) 775 { 776 Tab.m_$Items.empty(); 777 LoadTab( Tab ); 778 } 779 } 780 else 781 { 782 Tab.m_$Select.removeClass( 'active' ); 783 Tab.m_$Content.hide(); 784 } 785 } 786 }; 787 788 var DoTabScroll = function( Tab, delta ) 789 { 790 if ( Tab.m_iStart + delta + 10 > Tab.m_nLoaded ) 791 LoadTab( Tab, delta ); 792 else 793 TagScrollTabTo( Tab, Tab.m_iStart + delta ); 794 }; 795 796 var LoadTab = function( Tab, delta ) 797 { 798 if ( Tab.m_bRequestInFlight ) 799 return; 800 801 if ( !delta ) 802 delta = 0; 803 804 Tab.m_bNeedsReload = false; 805 var url = g_strTabRequestURL + Tab.m_strName; 806 var rgParams = $J.extend( { 807 'start': Tab.m_iStart + delta 808 }, g_rgTabBaseParams ); 809 810 for ( var filter in g_rgTabParams ) 811 { 812 var rgParamValues = g_rgTabParams[filter]; 813 if ( rgParamValues && rgParamValues.length ) 814 { 815 rgParamValues.sort(); 816 for ( var i = 0; i < rgParamValues.length; i++ ) 817 { 818 rgParams[ filter + '[' + i + ']' ] = rgParamValues[i]; 819 } 820 } 821 } 822 823 $J.getJSON( url, rgParams).done( function( data ) { 824 Tab.m_bRequestInFlight = false;
825 826 Tab.m_$Items.append( data.html ); 827 Tab.m_nTotal = data.total; 828 Tab.m_nLoaded = data.start + data.count; 829 830 TagScrollTabTo( Tab, data.start ); 831 }); 832 }; 833 834 var UpdateTabPagingDisplay = function( Tab ) 835 { 836 if ( Tab.m_iStart > 0 ) 837 Tab.m_$Prev.show(); 838 else 839 Tab.m_$Prev.hide(); 840 841 if ( Tab.m_iStart + 10 < Math.min( Tab.m_nTotal, 100 ) ) 842 Tab.m_$Next.show(); 843 else 844 Tab.m_$Next.hide(); 845 846 Tab.m_$CountStart.text( Tab.m_iStart + 1 ); 847 Tab.m_$CountEnd.text( Math.min( Tab.m_iStart + 10, Tab.m_nTotal ) ); 848 Tab.m_$CountTotal.text( Tab.m_nTotal ); 849 }; 850 851 var TagScrollTabTo = function( Tab, iStart ) 852 { 853 var delta = iStart - Tab.m_iStart; 854 Tab.m_iStart = iStart; 855 UpdateTabPagingDisplay( Tab ); 856 857 if ( delta != 0 ) 858 { 859 var nItemHeight = Tab.m_$Items.children(':first-child').height() + 1; 860 861 Tab.m_bAnimating = true; 862 Tab.m_$Items.css( 'position', 'relative' ); 863 var nTop = parseInt( Tab.m_$Items.css('top') ) || 0; 864 Tab.m_$Items.animate( {top: (nTop - (delta * nItemHeight)) + 'px' }, 750, function() { 865 Tab.m_bAnimating = false; 866 } ); 867 } 868 }; 869 870 // perform initialization 871 872 for ( var i = 0 ; i < rgTabNames.length; i++ ) 873 { 874 var strName = rgTabNames[i]; 875 var Tab = { 876 m_strName: strName, 877 m_$Select: $J('#tab_select_' + strName ), 878 m_$Content: $J('#tab_' + strName + '_content' ), 879 m_$Items: $J('#tab_' + strName + '_items' ), 880 m_$Prev: $J('#tab_' + strName + '_prev' ), 881 m_$PrevLink: $J('#tab_' + strName + '_prev > a' ), 882 m_$Next: $J('#tab_' + strName + '_next' ), 883 m_$NextLink: $J('#tab_' + strName + '_next > a' ), 884 m_$CountStart: $J('#tab_' + strName + '_count_start' ), 885 m_$CountEnd: $J('#tab_' + strName + '_count_end' ), 886 m_$CountTotal: $J('#tab_' + strName + '_count_total' ), 887 m_iStart: 0, 888 m_nTotal: parseInt( $J('#tab_' + strName + '_count_total').text() ) || 0, 889 m_nLoaded: 10, 890 891 m_bAnimating: false, 892 m_bRequestInFlight: false 893 }; 894 895 UpdateTabPagingDisplay( Tab ); 896 InitTabEvents( Tab ); 897 898 g_rgTabs[ strName ] = Tab; 899 } 900 901 UpdateTabDisplay( rgTabNames[0] ); 902 903 $J('.tab_filter_control').each( function() { 904 var $Control = $J(this); 905 var strParam = $Control.data('param'); 906 var value = $Control.data('value'); 907 $Control.click( function() { 908 if ( !$Control.hasClass( 'checked' ) ) 909 { 910 fnAddFilter( strParam, value, $Control ); 911 } 912 else 913 { 914 fnRemoveFilter( strParam, value, $Control ); 915 } 916 }); 917 }); 918 919 $J('#related_tags_more_toggle').click( function() { 920 $J('#related_tags_more_toggle').hide(); 921 $J('#related_tags_more').show('fast'); 922 }); 923 924 // due to php, this might be an empty array, or an object. on an object, length will be undefined 925 if ( rgInitialParams.length !== 0 ) 926 { 927 for ( var param in rgInitialParams ) 928 { 929 var rgValues = rgInitialParams[param]; 930 for ( var i = 0; i < rgValues.length; i++ ) 931 { 932 $J('.tab_filter_ctn').show(); // when showing initially, skip the animation that fnAddFilter would run 933 fnAddFilter( param, rgValues[i] ); 934 } 935 } 936 } 937} 938 939 940function InitTagBrowsePage( strTagLanguage, rgDefaultGetParams ) 941{ 942 var rgTagResults = {}; 943 944 var rgActiveTagByOption = { global: null, yours: null, friends: null, recommended: null }; 945 var strActiveOption; 946 947 var fnDisplayTag = function( unTagID, strTagName ) { 948 if ( !rgTagResults[unTagID] ) 949 { 950 var $Element = $J('<div/>', {'class': 'tag_browse_games_results'} ); 951 // some pending info 952 var $GamesElement = $J('<div/>', {'class':'browse_tag_games'}); 953 $GamesElement.append($J('<h3/>').text( strTagName ) ); 954 $GamesElement.append( $J('<div/>', {'class': 'browse_tag_loading' }).html( '<img src="https://store.fastly.steamstatic.com/public/images/login/throbber.gif">' ) ); 955 956 $Element.append( $GamesElement ); 957 $Element.append( $J('<div/>', {'class':'browse_tag_game_total'}).html( ' ' ) ); 958 var rgParams = $J.extend( { name: strTagName }, rgDefaultGetParams ); 959 960 $J.get( 'https://store.steampowered.com/tagdata/gettaggames/' + strTagLanguage + '/' + unTagID + '/', rgParams ).done( function ( html ) { 961 $Element.html( html ); 962 $Element.InstrumentLinks(); 963 if ( typeof GDynamicStore != 'undefined' ) 964 GDynamicStore.DecorateDynamicItems( $Element ); 965 }).fail( function () { 966 $GamesElement.find( '.browse_tag_loading').text( 'à¸à¸à¸à¸ ัย à¸à¸£à¸§à¸à¸à¸à¸à¸±à¸à¸«à¸²à¹à¸à¸à¸²à¸£à¹à¸«à¸¥à¸à¸à¸¥à¸´à¸à¸ ัà¸à¸à¹ à¹à¸à¸£à¸à¸¥à¸à¸à¹à¸«à¸¡à¹à¸à¸µà¸à¸à¸£à¸±à¹à¸à¸ ายหลัà¸' ); 967 }); 968 969 rgTagResults[unTagID] = $Element; 970 } 971 972 $J('#tag_browse_games_ctn').children().detach(); 973 $J('#tag_browse_games_ctn').append( rgTagResults[unTagID] ); 974 }; 975 976 var fnSelectOption = function( strOption, unTagID ) 977 { 978 strActiveOption = strOption; 979 var $Tags = $J('#tag_browse_' + strOption); 980 $Tags.siblings('.tag_browse_tags').hide(); 981 $Tags.show(); 982 983 var $Desc = $J('#tag_browse_description_' + strOption ); 984 $Desc.siblings().hide(); 985 $Desc.show(); 986 987 $J('.tag_browse_option').removeClass('active'); 988 $J('.tag_browse_option[data-browseoption=' + strOption + ']').addClass('active'); 989 990 if ( unTagID ) 991 { 992 var $Tag = $Tags.children('[data-tagid=' + unTagID + ']'); 993 if ( $Tag.length ) 994 rgActiveTagByOption[strActiveOption] = $Tag; 995 } 996 997 // select the first tag if none selected 998 if ( !rgActiveTagByOption[strActiveOption] && $Tags.children().length ) 999 rgActiveTagByOption[strActiveOption] = $J($Tags.children()[0]); 1000 1001 if ( rgActiveTagByOption[strActiveOption] ) 1002 fnSelectTag( rgActiveTagByOption[strActiveOption] ); 1003 }; 1004 1005 var fnSelectTag = function( $Tag ) 1006 { 1007 if ( rgActiveTagByOption[ strActiveOption ] ) 1008 rgActiveTagByOption[ strActiveOption ].removeClass('active'); 1009 1010 $Tag.addClass( 'active' ); 1011 rgActiveTagByOption[ strActiveOption ] = $Tag; 1012 1013 fnDisplayTag( $Tag.data('tagid'), $Tag.text() ); 1014 window.history.replaceState( {}, '', '#' + strActiveOption + '_' + $Tag.data('tagid') ); 1015 }; 1016 1017 $J('.tag_browse_option').click( function () { 1018 fnSelectOption( $J(this).data('browseoption') ); 1019 }); 1020 1021 //TODO: for testing only 1022 var strEvent = window.location.href.indexOf( 'test_mouse' ) == -1 ? 'click' : 'mouseenter'; 1023 $J('.tag_browse_tag').on( strEvent, function() { 1024 fnSelectTag( $J(this) ); 1025 }); 1026 1027 var fnGoToHash = function() { 1028 var hash = window.location.hash; 1029 if ( hash && hash.length > 2 ) 1030 { 1031 var rgHashComponents = hash.substr(1).split('_'); 1032 if ( rgHashComponents.length >= 1 && rgHashComponents.length <= 2 ) 1033 { 1034 var option = rgHashComponents[0]; 1035 var tagid; 1036 if ( rgHashComponents.length >= 2 ) 1037 tagid = parseInt( rgHashComponents[1] ); 1038 if ( rgActiveTagByOption[option] || rgActiveTagByOption[option] === null ) 1039 { 1040 fnSelectOption( option, tagid ); 1041 return; 1042 } 1043 } 1044 } 1045 1046 fnSelectOption('global'); 1047 }; 1048 1049 if ( window.location.hash.length ) 1050 fnGoToHash(); 1051 else 1052 fnSelectOption( 'global' ); 1053} 1054 1055function InitBannedTagModal( appid, $BanModal, bIsDLC ) 1056{ 1057 var bBansChanged = false;
1058 var bAppliedToChildren = false; 1059 window.ShowAppTagBanModal = function() { 1060 $BanModal.show(); 1061 ShowAlertDialog( 'à¹à¸à¹à¸à¸à¸µà¹à¸à¸¹à¸à¹à¸à¸', $BanModal).always( function() { 1062 if ( bBansChanged && typeof FlushApp != 'undefined' ) 1063 FlushApp( appid, bAppliedToChildren ); 1064 else if ( bBansChanged ) 1065 window.location.reload(); 1066 } ); 1067 1068 $BanModal.find( '.app_tag_report').click( function() { 1069 var $Flag = $J(this); 1070 var $Row = $Flag.parent( '.app_tag_control' ); 1071 var tag = $Row.data('tag'); 1072 1073 var content = $J( '<div/>' ); 1074 content.append( $J( '<div/>', { 'class': 'app_tag_ban_prompt' } ).text( 'à¸à¸¸à¸à¹à¸à¹à¹à¸à¸«à¸£à¸·à¸à¹à¸¡à¹à¸§à¹à¸²à¸à¹à¸à¸à¸à¸²à¸£à¹à¸¥à¸´à¸à¹à¸à¸à¹à¸à¹à¸ "%s"?'.replace( /%s/, tag ) ) ); 1075 if ( !bIsDLC ) { 1076 content.append( $J( '<div/>', { 'class': 'app_tag_ban_checkbox' } ).append( $J( '<input/>', {'type': 'checkbox', 'name':'unban_child_tags', 'checked': 1, 'id': 'unban_child_tags' } ) ) ); 1077 content.append( $J( '<div/>', { 'class': 'app_tag_ban_label' } ).append( $J( '<label/>', {'for': 'unban_child_tags' } ).text( 'à¹à¸¥à¸´à¸à¹à¸à¸à¹à¸à¹à¸à¸ªà¸³à¸«à¸£à¸±à¸à¹à¸à¸·à¹à¸à¸«à¸²à¸à¸²à¸§à¸à¹à¹à¸«à¸¥à¸à¸¢à¹à¸à¸¢à¸à¹à¸§à¸¢' ) ) ); 1078 } 1079 1080 ShowConfirmDialog( 'à¹à¸¥à¸´à¸à¹à¸à¸à¹à¸à¹à¸', 1081 content, 1082 'à¹à¸¥à¸´à¸à¹à¸à¸à¹à¸à¹à¸') 1083 .done( function() { 1084 var checkbox = content.find( '.app_tag_ban_checkbox > input' ); 1085 var bApplyToChildren = false; 1086 1087 if ( checkbox.is( ':checked' ) ) 1088 { 1089 // unban all children DLCs as well 1090 bApplyToChildren = true; 1091 } 1092 1093 var rgParams = { 1094 appid: appid, 1095 sessionid: g_sessionID, 1096 tag: tag, 1097 reporttype: -1, 1098 unban: 1, 1099 applytochildren: bApplyToChildren 1100 }; 1101 $J.post( 'https://store.steampowered.com/tagdata/tagapp', rgParams ).done( function( data ) { 1102 $Row.hide( 'fast' ); 1103 }).fail( function () { 1104 ShowAlertDialog( 'à¹à¸¥à¸´à¸à¹à¸à¸à¹à¸à¹à¸', 'à¸à¸£à¸§à¸à¸à¸à¸à¸±à¸à¸«à¸²à¹à¸à¸à¸²à¸£à¹à¸à¸à¸«à¸£à¸·à¸à¹à¸¥à¸´à¸à¹à¸à¸à¹à¸à¹à¸à¸à¸µà¹ à¹à¸à¸£à¸à¸¥à¸à¸à¹à¸«à¸¡à¹à¸à¸µà¸à¸à¸£à¸±à¹à¸à¸ ายหลัà¸' ); 1105 }); 1106 bBansChanged = true; 1107 bAppliedToChildren = bAppliedToChildren || bApplyToChildren; 1108 }); 1109 }); 1110 }; 1111} 1112 1113 1114var g_bLoadingPopularTags = false; 1115var g_rgGlobalPopularTags = []; 1116 1117// A modular tag auto-complete widget. 1118var CTagAutoComplete = function( $elContainer, fnOnTagSelected, bNoFocus ) 1119{ 1120 var $AppTagForm = $elContainer; 1121 var $AppTagInput = $AppTagForm.find('input[name=tag]'); 1122 var $AppTagButton = $AppTagForm.find('button'); 1123 1124 var TextSuggest; 1125 1126 if ( $AppTagForm.length ) 1127 { 1128 var fnOnSubmit = function(event) { 1129 if ( event ) 1130 event.preventDefault(); 1131 1132 if ( $AppTagInput.val().length == 0 ) 1133 return; 1134 1135 fnOnTagSelected( $AppTagInput.val() ); 1136 if ( !bNoFocus ) 1137 $AppTagInput.val('').change().focus(); 1138 }; 1139 1140 var fnUpdateTagButtonState = function() { 1141 if ( $AppTagInput.val().length > 0 ) 1142 $AppTagButton.removeClass( 'btn_disabled' ); 1143 else 1144 $AppTagButton.addClass( 'btn_disabled' ); 1145 }; 1146 1147 $AppTagInput.val(''); 1148 $AppTagInput.change( fnUpdateTagButtonState ); 1149 $AppTagInput.keyup( fnUpdateTagButtonState ); 1150 fnUpdateTagButtonState(); 1151 if ( !bNoFocus ) 1152 $AppTagInput.focus(); 1153 1154 $AppTagForm.submit( fnOnSubmit ); 1155 $AppTagForm.keyup( function( event ) { if ( event.which == 13 ) event.stopPropagation() } ); 1156 1157 TextSuggest = new CTextInputSuggest( $AppTagInput, GetTagSuggestFunc( g_rgGlobalPopularTags ), function( suggestion ) { fnOnSubmit(); } ); 1158 1159 // hack to size the input control correctly 1160 //$AppTagForm.find( '.gray_bevel').css( 'margin-right', ( $AppTagButton.width() + 12 ) + 'px' ); 1161 1162 this.LoadPopularTags( false ); 1163 } 1164} 1165 1166// 1167CTagAutoComplete.prototype.LoadPopularTags = function( bForce ) 1168{ 1169 if ( g_bLoadingPopularTags ) 1170 return; 1171 1172 g_bLoadingPopularTags = true; 1173 if( !bForce && g_rgGlobalPopularTags.length > 0 ) 1174 return; 1175 1176 $J.get( 'https://store.steampowered.com/tagdata/populartags/thai').done( function ( data ) { 1177 for ( var i = 0; i < data.length; i++ ) 1178 { 1179 g_rgGlobalPopularTags.push( data[i] ); // don't assign, we've got references to this guy 1180 } 1181 1182 g_bLoadingPopularTags = false;
1183 }); 1184} 1185 1186
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.