AssetStore Linkify

AssetStore Linkify is a user script for finding links in plain-text and converting them to HTML <a> tags.

  1. // ==UserScript==
  2. // @name AssetStore Linkify
  3. // @namespace https://github.com/XpycT/
  4. // @version 0.3.2
  5. // @license MIT
  6. // @description AssetStore Linkify is a user script for finding links in plain-text and converting them to HTML <a> tags.
  7. // @homepageURL https://github.com/XpycT/assetstore-linkify
  8. // @supportURL https://github.com/XpycT/assetstore-linkify/issues
  9. // @author XpycT
  10. // @require https://code.jquery.com/jquery-latest.js
  11. // @require https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.0.47/jquery.fancybox.min.js
  12. // @resource fontCss https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css
  13. // @match *://forum.cgpersia.com/*
  14. // @match *://www.cgpeers.to/*
  15. // @match *://gfxpeers.net/*
  16. // @match *://leakforums.co/*
  17. // @grant GM_setValue
  18. // @grant GM_getValue
  19. // @grant GM_addStyle
  20. // @grant GM_xmlhttpRequest
  21. // @grant unsafeWindow
  22. // @grant GM_getResourceText
  23. // @run-at document-start
  24. // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAIAAADajyQQAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QTc1RUY1OEIxRUQ1MTFFNEJBMjNERUQ5QTNFNzNDMzYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QTc1RUY1OEMxRUQ1MTFFNEJBMjNERUQ5QTNFNzNDMzYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpBNzVFRjU4OTFFRDUxMUU0QkEyM0RFRDlBM0U3M0MzNiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpBNzVFRjU4QTFFRDUxMUU0QkEyM0RFRDlBM0U3M0MzNiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PrgK2iMAAAaZSURBVHjaYlTSMWcY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
  25. // ==/UserScript==
  26.  
  27. (function () {
  28. 'use strict';
  29.  
  30. var $ = $ || window.$;
  31.  
  32. const apis = {
  33. 'head': 'https://www.assetstore.unity3d.com/api/en-US/head/package/',
  34. 'content_overview': 'https://www.assetstore.unity3d.com/api/en-US/content/overview/',
  35. 'price': 'https://www.assetstore.unity3d.com/api/en-US/content/price/'
  36. };
  37.  
  38. /**
  39. * replace all assetstore text with link
  40. */
  41. function replaceTextLinks() {
  42. let urlRegex = /\b(https?:\/\/[^\s+\"\<\>]+)/ig;
  43. let snapTextElements = document.evaluate("//text()[not(ancestor::a) " +
  44. "and not(ancestor::script) and not(ancestor::style) and " +
  45. "contains(translate(., 'HTTP', 'http'), 'http') and contains(., 'assetstore.unity')]",
  46. document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  47. for (let i = snapTextElements.snapshotLength - 1; i >= 0; i--) {
  48. let elmText = snapTextElements.snapshotItem(i);
  49. if (urlRegex.test(elmText.nodeValue)) {
  50.  
  51. let elmSpan = document.createElement("div");
  52. elmSpan.className = "unitystore-holder";
  53. let sURLText = elmText.nodeValue;
  54. let latest = sURLText.split('/').pop().trim();
  55. elmSpan.dataset.id = Number.isInteger(latest) ? latest : latest.split('-').pop().trim();
  56.  
  57. elmText.parentNode.replaceChild(elmSpan, elmText);
  58. urlRegex.lastIndex = 0;
  59. for (var match = null, lastLastIndex = 0;
  60. (match = urlRegex.exec(sURLText));) {
  61. elmSpan.appendChild(document.createTextNode(
  62. sURLText.substring(lastLastIndex, match.index)));
  63. let elmLink = document.createElement("a");
  64. elmLink.className = "unitystore-link";
  65. elmLink.setAttribute("href", match[0]);
  66. elmLink.setAttribute("target", '_blank');
  67. elmLink.appendChild(document.createTextNode(match[0]));
  68. elmSpan.appendChild(elmLink);
  69. lastLastIndex = urlRegex.lastIndex;
  70. }
  71. elmSpan.appendChild(document.createTextNode(
  72. sURLText.substring(lastLastIndex)));
  73. elmSpan.normalize();
  74. }
  75. }
  76. }
  77.  
  78. /**
  79. * prepare existing links for infobox
  80. */
  81. function appendToLinks() {
  82. let snapTextElements = document.evaluate("//a[contains(translate(@href, 'HTTP', 'http'), 'http') and contains(@href, 'assetstore.unity')]",
  83. document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  84. for (let i = snapTextElements.snapshotLength - 1; i >= 0; i--) {
  85. let elmLink = snapTextElements.snapshotItem(i);
  86. let latest = $(elmLink).attr('href').split('/').pop().trim();
  87. let data_id = Number.isInteger(latest) ? latest : latest.split('-').pop().trim();
  88. $(elmLink).wrap(`<span class="unitystore-holder" data-id="${data_id}"></span>`);
  89. $(elmLink).addClass('unitystore-link');
  90. }
  91. }
  92.  
  93. /**
  94. * add styles
  95. */
  96. function addStyles() {
  97. let fontCssSrc = GM_getResourceText("fontCss");
  98. fontCssSrc = fontCssSrc.replace(/\.\.\/fonts\/fontawesome-webfont/g, 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/fonts/fontawesome-webfont');
  99. GM_addStyle(fontCssSrc);
  100. GM_addStyle(
  101. `@import url('//fonts.googleapis.com/css?family=Roboto:100,400');
  102. @charset "UTF-8";.fancybox-enabled{overflow:hidden}.fancybox-enabled body{overflow:visible;height:100%}.fancybox-container{position:fixed;top:0;left:0;width:100%;height:100%;z-index:99993;-webkit-backface-visibility:hidden;backface-visibility:hidden}.fancybox-container~.fancybox-container{z-index:99992}.fancybox-bg{position:absolute;top:0;right:0;bottom:0;left:0;background:#0f0f11;opacity:0;transition-timing-function:cubic-bezier(.55,.06,.68,.19);-webkit-backface-visibility:hidden;backface-visibility:hidden}.fancybox-container--ready .fancybox-bg{opacity:.87;transition-timing-function:cubic-bezier(.22,.61,.36,1)}.fancybox-controls{position:absolute;top:0;left:0;right:0;text-align:center;opacity:0;z-index:99994;transition:opacity .2s;pointer-events:none;-webkit-backface-visibility:hidden;backface-visibility:hidden;direction:ltr}.fancybox-show-controls .fancybox-controls{opacity:1}.fancybox-infobar{display:none}.fancybox-show-infobar .fancybox-infobar{display:inline-block;pointer-events:all}.fancybox-infobar__body{display:inline-block;width:70px;line-height:44px;font-size:13px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;text-align:center;color:#ddd;background-color:rgba(30,30,30,.7);pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent;-webkit-font-smoothing:subpixel-antialiased}.fancybox-buttons{position:absolute;top:0;right:0;display:none;pointer-events:all}.fancybox-show-buttons .fancybox-buttons{display:block}.fancybox-slider-wrap{overflow:hidden;direction:ltr}.fancybox-slider,.fancybox-slider-wrap{position:absolute;top:0;left:0;bottom:0;right:0;padding:0;margin:0;z-index:99993;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-tap-highlight-color:transparent}.fancybox-slide{position:absolute;top:0;left:0;width:100%;height:100%;margin:0;padding:0;overflow:auto;outline:none;white-space:normal;box-sizing:border-box;text-align:center;z-index:99994;-webkit-overflow-scrolling:touch}.fancybox-slide:before{content:"";height:100%;width:0}.fancybox-slide:before,.fancybox-slide>*{display:inline-block;vertical-align:middle}.fancybox-slide>*{position:relative;padding:24px;margin:44px 0;border-width:0;text-align:left;background-color:#fff;overflow:auto;box-sizing:border-box}.fancybox-slide--image{overflow:hidden}.fancybox-slide--image:before{display:none}.fancybox-content{display:inline-block;position:relative;margin:44px auto;padding:0;border:0;width:80%;height:calc(100% - 88px);vertical-align:middle;line-height:normal;text-align:left;white-space:normal;outline:none;font-size:16px;font-family:Arial,sans-serif;box-sizing:border-box;-webkit-tap-highlight-color:transparent;-webkit-overflow-scrolling:touch}.fancybox-iframe{display:block;margin:0;padding:0;border:0;width:100%;height:100%;background:#fff}.fancybox-slide--video .fancybox-content,.fancybox-slide--video .fancybox-iframe{background:transparent}.fancybox-placeholder{z-index:99995;background:transparent;cursor:default;overflow:visible;-webkit-transform-origin:top left;transform-origin:top left;background-size:100% 100%;background-repeat:no-repeat;-webkit-backface-visibility:hidden;backface-visibility:hidden}.fancybox-image,.fancybox-placeholder,.fancybox-spaceball{position:absolute;top:0;left:0;margin:0;padding:0;border:0}.fancybox-image,.fancybox-spaceball{width:100%;height:100%;max-width:none;max-height:none;background:transparent;background-size:100% 100%}.fancybox-controls--canzoomOut .fancybox-placeholder{cursor:zoom-out}.fancybox-controls--canzoomIn .fancybox-placeholder{cursor:zoom-in}.fancybox-controls--canGrab .fancybox-placeholder{cursor:-webkit-grab;cursor:grab}.fancybox-controls--isGrabbing .fancybox-placeholder{cursor:-webkit-grabbing;cursor:grabbing}.fancybox-spaceball{z-index:1}.fancybox-tmp{position:absolute;top:-9999px;left:-9999px;visibility:hidden}.fancybox-error{position:absolute;margin:0;padding:40px;top:50%;left:50%;width:380px;max-width:100%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);background:#fff;cursor:default}.fancybox-error p{margin:0;padding:0;color:#444;font:16px/20px Helvetica Neue,Helvetica,Arial,sans-serif}.fancybox-close-small{position:absolute;top:0;right:0;width:44px;height:44px;padding:0;margin:0;border:0;border-radius:0;outline:none;background:transparent;z-index:10;cursor:pointer}.fancybox-close-small:after{content:"×";position:absolute;top:5px;right:5px;width:30px;height:30px;font:20px/30px Arial,Helvetica Neue,Helvetica,sans-serif;color:#888;font-weight:300;text-align:center;border-radius:50%;border-width:0;background:#fff;transition:background .2s;box-sizing:border-box;z-index:2}.fancybox-close-small:focus:after{outline:1px dotted #888}.fancybox-slide--video .fancybox-close-small{top:-36px;right:-36px;background:transparent}.fancybox-close-small:hover:after{color:#555;background:#eee}.fancybox-caption-wrap{position:absolute;bottom:0;left:0;right:0;padding:60px 30px 0;z-index:99998;-webkit-backface-visibility:hidden;backface-visibility:hidden;box-sizing:border-box;background:linear-gradient(180deg,transparent 0,rgba(0,0,0,.1) 20%,rgba(0,0,0,.2) 40%,rgba(0,0,0,.6) 80%,rgba(0,0,0,.8));opacity:0;transition:opacity .2s;pointer-events:none}.fancybox-show-caption .fancybox-caption-wrap{opacity:1}.fancybox-caption{padding:30px 0;border-top:1px solid hsla(0,0%,100%,.4);font-size:14px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:#fff;line-height:20px;-webkit-text-size-adjust:none}.fancybox-caption a,.fancybox-caption button{pointer-events:all}.fancybox-caption a{color:#fff;text-decoration:underline}.fancybox-button{display:inline-block;position:relative;width:44px;height:44px;line-height:44px;margin:0;padding:0;border:0;border-radius:0;cursor:pointer;background:transparent;color:#fff;box-sizing:border-box;vertical-align:top;outline:none}.fancybox-button--disabled{cursor:default;pointer-events:none}.fancybox-button,.fancybox-infobar__body{background:rgba(30,30,30,.6)}.fancybox-button:hover{background:rgba(0,0,0,.8)}.fancybox-button:after,.fancybox-button:before{content:"";pointer-events:none;position:absolute;border-color:#fff;background-color:currentColor;color:currentColor;opacity:.9;box-sizing:border-box;display:inline-block}.fancybox-button--disabled:after,.fancybox-button--disabled:before{opacity:.5}.fancybox-button--left:after{left:20px;-webkit-transform:rotate(-135deg);transform:rotate(-135deg)}.fancybox-button--left:after,.fancybox-button--right:after{top:18px;width:6px;height:6px;background:transparent;border-top:2px solid currentColor;border-right:2px solid currentColor}.fancybox-button--right:after{right:20px;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.fancybox-button--left{border-bottom-left-radius:5px}.fancybox-button--right{border-bottom-right-radius:5px}.fancybox-button--close{float:right}.fancybox-button--close:after,.fancybox-button--close:before{content:"";display:inline-block;position:absolute;height:2px;width:16px;top:calc(50% - 1px);left:calc(50% - 8px)}.fancybox-button--close:before{-webkit-transform:rotate(45deg);transform:rotate(45deg)}.fancybox-button--close:after{-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.fancybox-loading{border:6px solid hsla(0,0%,39%,.4);border-top:6px solid hsla(0,0%,100%,.6);border-radius:100%;height:50px;width:50px;-webkit-animation:a .8s infinite linear;animation:a .8s infinite linear;background:transparent;position:absolute;top:50%;left:50%;margin-top:-25px;margin-left:-25px;z-index:99999}@-webkit-keyframes a{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes a{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@media (max-width:800px){.fancybox-controls{text-align:left}.fancybox-button--left,.fancybox-button--right,.fancybox-buttons button:not(.fancybox-button--close){display:none!important}.fancybox-caption{padding:20px 0;margin:0}}.fancybox-button--fullscreen:before{width:15px;height:11px;left:15px;top:16px;border:2px solid;background:none}.fancybox-button--play:before{top:16px;left:18px;width:0;height:0;border-top:6px inset transparent;border-bottom:6px inset transparent;border-left:10px solid;border-radius:1px;background:transparent}.fancybox-button--pause:before{top:16px;left:18px;width:7px;height:11px;border-style:solid;border-width:0 2px;background:transparent}.fancybox-button--thumbs span{font-size:23px}.fancybox-button--thumbs:before{top:20px;left:21px;width:3px;height:3px;box-shadow:0 -4px 0,-4px -4px 0,4px -4px 0,inset 0 0 0 32px,-4px 0 0,4px 0 0,0 4px 0,-4px 4px 0,4px 4px 0}.fancybox-container--thumbs .fancybox-caption-wrap,.fancybox-container--thumbs .fancybox-controls,.fancybox-container--thumbs .fancybox-slider-wrap{right:220px}.fancybox-thumbs{position:absolute;top:0;right:0;bottom:0;left:auto;width:220px;margin:0;padding:5px 5px 0 0;background:#fff;z-index:99993;word-break:normal;-webkit-overflow-scrolling:touch;-webkit-tap-highlight-color:transparent;box-sizing:border-box}.fancybox-thumbs>ul{list-style:none;position:absolute;position:relative;width:100%;height:100%;margin:0;padding:0;overflow-x:hidden;overflow-y:auto;font-size:0}.fancybox-thumbs>ul>li{float:left;overflow:hidden;max-width:50%;padding:0;margin:0;width:105px;height:75px;position:relative;cursor:pointer;outline:none;border:5px solid #fff;border-top-width:0;border-right-width:0;-webkit-tap-highlight-color:transparent;-webkit-backface-visibility:hidden;backface-visibility:hidden;box-sizing:border-box}li.fancybox-thumbs-loading{background:rgba(0,0,0,.1)}.fancybox-thumbs>ul>li>img{position:absolute;top:0;left:0;min-width:100%;min-height:100%;max-width:none;max-height:none;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.fancybox-thumbs>ul>li:before{content:"";position:absolute;top:0;right:0;bottom:0;left:0;border-radius:2px;border:4px solid #4ea7f9;z-index:99991;opacity:0;transition:all .2s cubic-bezier(.25,.46,.45,.94)}.fancybox-thumbs>ul>li.fancybox-thumbs-active:before{opacity:1}@media (max-width:800px){.fancybox-thumbs{display:none!important}.fancybox-container--thumbs .fancybox-caption-wrap,.fancybox-container--thumbs .fancybox-controls,.fancybox-container--thumbs .fancybox-slider-wrap{right:0}}
  103. .unitystore-holder{white-space:nowrap;}
  104. .unitystore-link {text-decoration: none; border-bottom: 1px dotted;}
  105. .unitystore-link:hover {border-bottom: 1px dotted rgba(0,0,0,0);}
  106. .unitystore-info-label {color: #2e2e2e; background: #8BC34A; padding: 2px 5px; border-radius: 3px; text-shadow: 1px 1px 0px white; position: relative; left: 5px; font-size: 0.8em;font-family:'Roboto',sans-serif; cursor: pointer;}
  107. .assetstore-shadow{z-index:999;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.7);}
  108. .assetstore-dialog.popup-holder{width:798px;height:385px;background:#222b37;position:fixed;top:calc(50% - 195px);left:calc(50% - 395px);z-index:1001;box-shadow:0 0 15px #000}
  109. .assetstore-dialog .popup-holder-close{position:absolute;top:0;right:0;z-index:50;width:30px;height:30px;line-height:30px;background:#222b37;border-radius:0;cursor:pointer;vertical-align:top;outline:0;padding:4px}
  110. .assetstore-dialog .popup-holder-content{padding:5px;position:relative;background-position:right;min-height:100%;-webkit-background-clip:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;background-repeat:no-repeat;box-sizing:border-box}
  111. .assetstore-dialog .popup-holder-main-info{position:absolute;top:0;bottom:0;left:0;width:250px;margin:0;overflow:auto;background-color:#222b37;padding:20px 15px 20px 20px}
  112. .assetstore-dialog .overview-text-overlay{color:#fff;font-family:'Roboto',sans-serif;font-size:12px}
  113. .assetstore-dialog .overview-text-overlay h1{font-family:'Roboto',sans-serif;font-size:28px;line-height:32px;font-weight:100;margin:0;overflow:hidden;text-overflow:ellipsis}
  114. .assetstore-dialog .overview-text-overlay .details-container{font-family:'Roboto',sans-serif;padding:0;position:relative;white-space:nowrap;font-size:16px;line-height:24px}
  115. .assetstore-dialog .overview-text-overlay .details-container .asset-rating.rated{font-size:12px;}
  116. .assetstore-dialog .overview-text-overlay .details-container .asset-rating.unrated{font-weight: 100; font-size: 12px;}
  117. .assetstore-dialog .overview-text-overlay .details-container .asset-price{margin-top:5px;font-weight:400;color:#8ac249}
  118. .assetstore-dialog .overview-text-overlay span{font-weight:100;display:block;overflow:hidden;text-overflow:ellipsis}
  119. .assetstore-dialog .overview-text-overlay .notes{margin:10px 0}
  120. .assetstore-dialog .overview-text-overlay .notes .min-unity-version,.assetstore-dialog .overview-text-overlay .notes .package-size,.assetstore-dialog .overview-text-overlay .notes .package-version{margin:5px;font-weight:400}
  121. .assetstore-dialog .overview-text-overlay .fulldescription{word-break:break-word;font-weight:300;line-height:16px}
  122. .assetstore-dialog .overview-text-overlay .fulldescription a{color:#fff;text-decoration:underline}
  123. .assetstore-dialog .overview-text-overlay .fulldescription strong{font-weight: 400;}
  124. .assetstore-dialog ::-webkit-scrollbar{width:6px;height:6px}
  125. .assetstore-dialog ::-webkit-scrollbar-button{width:0;height:0}
  126. .assetstore-dialog ::-webkit-scrollbar-thumb{background:#e1e1e1;border:0 none #fff;border-radius:0}
  127. .assetstore-dialog ::-webkit-scrollbar-thumb:hover{background:#fff}
  128. .assetstore-dialog ::-webkit-scrollbar-thumb:active{background:#000}
  129. .assetstore-dialog ::-webkit-scrollbar-track{background:#666;border:0 none #fff;border-radius:0}
  130. .assetstore-dialog ::-webkit-scrollbar-track:hover{background:#666}
  131. .assetstore-dialog ::-webkit-scrollbar-track:active{background:#333}
  132. .assetstore-dialog ::-webkit-scrollbar-corner{background:transparent}
  133. .assetstore-dialog .screen-holder{position:absolute;background:rgba(0,0,0,0.85);padding:5px;bottom:0;right:0}
  134. .assetstore-dialog .screen-holder img{width:140px;cursor:pointer;margin:0 3px;}`
  135. );
  136. }
  137.  
  138. function addInfoLabel() {
  139. $('.unitystore-holder').each(function (el) {
  140. let small = $('<small/>').addClass('unitystore-info-label').html('Detail');
  141. small.unbind().on('click', function (e) {
  142. let $label = $(this);
  143. $label.html('Loading...');
  144. let id = $(this).parent().data('id');
  145. let info = {
  146. header: null,
  147. content: null,
  148. price: null
  149. };
  150. // get headers
  151. GM_xmlhttpRequest({
  152. method: "GET",
  153. url: apis.head + id + '.json',
  154. onload: function (response) {
  155. try {
  156. info.header = $.parseJSON(response.responseText);
  157. // price
  158. GM_xmlhttpRequest({
  159. method: "GET",
  160. url: apis.price + id + '.json',
  161. onload: function (response) {
  162. try {
  163. info.price = $.parseJSON(response.responseText);
  164. // content
  165. GM_xmlhttpRequest({
  166. method: "GET",
  167. url: apis.content_overview + id + '.json',
  168. onload: function (response) {
  169. try {
  170. info.content = $.parseJSON(response.responseText);
  171. $label.html('Detail');
  172. createPopup(info);
  173. }
  174. catch (e) {
  175. console.log('content request error');
  176. }
  177. }
  178. });
  179. }
  180. catch (e) {
  181. console.log('price request error');
  182. }
  183. }
  184. });
  185. }
  186. catch (e) {
  187. console.log('header request error');
  188. }
  189. }
  190. });
  191. });
  192. $(this).append(small);
  193. });
  194. }
  195.  
  196. function createPopup(info) {
  197. //console.log(info);
  198. let id = info.content.content.id;
  199.  
  200. preload([info.content.content.keyimage.big]);
  201.  
  202. // check for media gallery
  203. let screenshots = '';
  204. if (info.content.content.images.length > 0) {
  205. screenshots = '<div class="screen-holder">';
  206. for (let i = 0; i <= 2; i++) {
  207. if (info.content.content.images[i] !== undefined) {
  208. let img = info.content.content.images[i];
  209. preload([img.thumb]);
  210. screenshots += `<a data-fancybox="gallery_${id}" href="${img.link}"><img src="${img.thumb}"></a>`;
  211. }
  212. }
  213. screenshots += '</div>';
  214. // load other images for gallery
  215. if (info.content.content.images.length > 3) {
  216. screenshots += '<div style="display:none;">';
  217. for (let i = 3; i < info.content.content.images.length; i++) {
  218. let img = info.content.content.images[i];
  219. preload([img.thumb]);
  220. screenshots += `<a href="${img.link}" data-fancybox="gallery_${id}" data-thumb="${img.thumb}"></a>`;
  221. }
  222. screenshots += '</div>';
  223. }
  224. }
  225.  
  226. let rating = '';
  227. let average = info.content.content.rating.average;
  228. if (average > 0) {
  229. let stars = '';
  230. for (let i = 0; i < average; i++) {
  231. stars += '<i class="fa fa-star" aria-hidden="true"></i>';
  232. }
  233. for (let i = average + 1; i <= 5; i++) {
  234. stars += '<i class="fa fa-star-o" aria-hidden="true"></i>';
  235. }
  236. rating = `${stars} (<i class="fa fa-user" aria-hidden="true"></i> ${info.content.content.rating.count})`;
  237. }
  238.  
  239. let html = `
  240. <div class="assetstore-shadow"></div>
  241. <div class="assetstore-dialog popup-holder" style="display:none;">
  242. <div class="popup-holder-close"><svg width="30" height="30"><g stroke="rgb(160,160,160)" stroke-width="4"><line x1="5" y1="5" x2="25" y2="25"/><line x1="5" y1="25" x2="25" y2="5"/></g></svg></div>
  243. <div class="popup-holder-content" style="background-image: url(${info.content.content.keyimage.big});">
  244. ${screenshots}
  245. </div>
  246. <div class="popup-holder-main-info">
  247. <div class="overview-text-overlay">
  248. <h1><a href="${info.content.content.short_url}" target="_blank" rel="nofollow">${info.header.result.title}</a></h1>
  249. <div class="details-container">
  250. <span class="asset-category">${info.header.result.category}</span>
  251. <span class="asset-author"><a href="${info.content.content.publisher.url}" target="_blank" rel="nofollow">${info.header.result.publisher}</a></span>
  252. <span class="asset-rating ${info.content.content.rating.count === null ? 'unrated' : 'rated'}">${info.content.content.rating.count === null ? 'Not enough ratings' : rating }</span>
  253. <span class="asset-price">${info.price.price}</span>
  254. </div>
  255. <div class="notes">
  256. <span class="package-version">Version: ${info.content.content.version} (${info.content.content.pubdate})</span>
  257. <span class="package-size">Size: ${info.content.content.sizetext}</span>
  258. <span class="min-unity-version">Requires Unity ${info.content.content.min_unity_version} or higher.</span>
  259. </div>
  260. <div class="fulldescription vscroll">${info.content.content.description}</div>
  261. </div>
  262. </div>
  263. </div>`;
  264.  
  265. let popup = $(html);
  266. $('.popup-holder-close', popup).on('click', function () {
  267. $('.assetstore-shadow').remove();
  268. $('.assetstore-dialog.popup-holder').remove();
  269. });
  270. $('.assetstore-dialog').remove();
  271. $('body').append(popup);
  272.  
  273. $("[data-fancybox]").fancybox({
  274. youtube: {
  275. controls: 1,
  276. showinfo: 1,
  277. autoplay: 0
  278. },
  279. vimeo: {
  280. color: 'f00'
  281. }
  282. });
  283.  
  284. setTimeout(function () {
  285. $('.assetstore-dialog').show();
  286. }, 100);
  287. }
  288.  
  289. function preload(images) {
  290. $(images).each(function () {
  291. (new Image()).src = this;
  292. });
  293. }
  294.  
  295. function init() {
  296. addStyles();
  297. appendToLinks();
  298. replaceTextLinks();
  299. addInfoLabel();
  300. }
  301.  
  302. $(function () {
  303. init();
  304. });
  305.  
  306. })();