1/* 2 * InstagramFeed 3 * 4 * @version 1.3.6 5 * 6 * @author Javier Sanahuja Liebana <[email protected]> 7 * @contributor csanahuja <[email protected]> 8 * 9 * https://github.com/jsanahuja/InstagramFeed 10 * 11 */ 12(function(root, factory) { 13 if (typeof define === "function" && define.amd) { 14 define([], factory); 15 } else if (typeof exports === "object") { 16 module.exports = factory(); 17 } else { 18 root.InstagramFeed = factory(); 19 } 20}(this, function() { 21 var defaults = { 22 'host': "https://www.instagram.com/", 23 'username': '', 24 'tag': '', 25 'container': '', 26 'display_profile': false, 27 'display_biography': false, 28 'display_gallery': true, 29 'display_igtv': false, 30 'get_data': false, 31 'callback': null, 32 'styling': false, 33 'items': 4, 34 'items_per_row': 4, 35 'margin': false, 36 'image_size': 640 37 }; 38 39 var image_sizes = { 40 "150": 0, 41 "240": 1, 42 "320": 2, 43 "480": 3, 44 "640": 4 45 }; 46 47 var escape_map = { 48 '&': '&', 49 '<': '<', 50 '>': '>', 51 '"': '"', 52 "'": ''', 53 '/': '/', 54 '`': '`', 55 '=': '=' 56 }; 57 function escape_string(str){ 58 return str.replace(/[&<>"'`=\/]/g, function (char) { 59 return escape_map[char]; 60 }); 61 } 62 63 return function(opts) { 64 this.options = Object.assign({}, defaults); 65 this.options = Object.assign(this.options, opts); 66 this.is_tag = this.options.username == ""; 67 68 this.valid = true; 69 if (this.options.username == "" && this.options.tag == "") { 70 console.error("InstagramFeed: Error, no username or tag defined."); 71 this.valid = false; 72 } else if (!this.options.get_data && this.options.container == "") { 73 console.error("InstagramFeed: Error, no container found."); 74 this.valid = false; 75 } else if (this.options.get_data && typeof this.options.callback != "function") { 76 console.error("InstagramFeed: Error, invalid or undefined callback for get_data"); 77 this.valid = false; 78 } 79 80 this.get = function(callback) { 81 var url = this.is_tag ? this.options.host + "explore/tags/" + this.options.tag + "/" : this.options.host + this.options.username + "/", 82 xhr = new XMLHttpRequest(); 83 84 var _this = this; 85 xhr.onload = function(e) { 86 if (xhr.readyState === 4) { 87 if (xhr.status === 200) { 88 var data = xhr.responseText.split("window._sharedData = ")[1].split("<\/script>")[0]; 89 data = JSON.parse(data.substr(0, data.length - 1)); 90 data = data.entry_data.ProfilePage || data.entry_data.TagPage; 91 if(typeof data === "undefined"){ 92 console.error("Instagram Feed: It looks like YOUR network has been temporary banned because of too many requests. See https://github.com/jsanahuja/jquery.instagramFeed/issues/25"); 93 return; 94 } 95 data = data[0].graphql.user || data[0].graphql.hashtag; 96 callback(data, _this); 97 } else { 98 console.error("InstagramFeed: Request error. Response: " + xhr.statusText); 99 } 100 } 101 }; 102 xhr.open("GET", url, true); 103 xhr.send(); 104 }; 105 106 this.parse_caption = function(igobj, data) { 107 if ( 108 typeof igobj.node.edge_media_to_caption.edges[0] !== "undefined" && 109 typeof igobj.node.edge_media_to_caption.edges[0].node !== "undefined" && 110 typeof igobj.node.edge_media_to_caption.edges[0].node.text !== "undefined" && 111 igobj.node.edge_media_to_caption.edges[0].node.text !== null 112 ) { 113 return igobj.node.edge_media_to_caption.edges[0].node.text; 114 } 115 116 if ( 117 typeof igobj.node.title !== "undefined" && 118 igobj.node.title !== null && 119 igobj.node.title.length != 0 120 ) { 121 return igobj.node.title; 122 } 123 124 if ( 125 typeof igobj.node.accessibility_caption !== "undefined" && 126 igobj.node.accessibility_caption !== null && 127 igobj.node.accessibility_caption.length != 0 128 ) { 129 return igobj.node.accessibility_caption; 130 } 131 return (this.is_tag ? data.name : data.username) + " image "; 132 } 133 134 this.display = function(data) { 135 // Styling 136 if (this.options.styling) { 137 var width = (100 - this.options.margin * 2 * this.options.items_per_row) / this.options.items_per_row; 138 var styles = { 139 'profile_container': " style='text-align:center;'", 140 'profile_image': " style='border-radius:10em;width:15%;max-width:125px;min-width:50px;'", 141 'profile_name': " style='font-size:1.2em;'", 142 'profile_biography': " style='font-size:1em;'", 143 'gallery_image': " style='margin:" + this.options.margin + "% " + this.options.margin + "%;
143width:" + width + "%;float:left;'" 144 }; 145 } else { 146 var styles = { 147 'profile_container': "", 148 'profile_image': "", 149 'profile_name': "", 150 'profile_biography': "", 151 'gallery_image': "" 152 }; 153 } 154 155 // Profile 156 var html = ""; 157 if (this.options.display_profile) { 158 html += "<div class='instagram_profile'" + styles.profile_container + ">"; 159 html += "<img class='instagram_profile_image' src='" + data.profile_pic_url + "' alt='" + (this.is_tag ? data.name + " tag pic" : data.username + " profile pic") + " profile pic'" + styles.profile_image + " />"; 160 if (this.is_tag) 161 html += "<p class='instagram_tag'" + styles.profile_name + "><a href='https://www.instagram.com/explore/tags/" + this.options.tag + "' rel='noopener' target='_blank'>#" + this.options.tag + "</a></p>"; 162 else 163 html += "<p class='instagram_username'" + styles.profile_name + ">@" + data.full_name + " (<a href='https://www.instagram.com/" + this.options.username + "' rel='noopener' target='_blank'>@" + this.options.username + "</a>)</p>"; 164 165 if (!this.is_tag && this.options.display_biography) 166 html += "<p class='instagram_biography'" + styles.profile_biography + ">" + data.biography + "</p>"; 167 168 html += "</div>"; 169 } 170 171 // Gallery 172 if (this.options.display_gallery) { 173 var image_index = typeof image_sizes[this.options.image_size] !== "undefined" ? image_sizes[this.options.image_size] : image_sizes[640]; 174 175 if (typeof data.is_private !== "undefined" && data.is_private === true) { 176 html += "<p class='instagram_private'><strong>This profile is private</strong></p>"; 177 } else { 178 var imgs = (data.edge_owner_to_timeline_media || data.edge_hashtag_to_media).edges; 179 max = (imgs.length > this.options.items) ? this.options.items : imgs.length; 180 181 for (var i = 0; i < max; i++) { 182 var url = "https://www.instagram.com/p/" + imgs[i].node.shortcode, 183 image, type_resource, 184 caption = escape_string(this.parse_caption(imgs[i], data)); 185 186 switch (imgs[i].node.__typename) { 187 case "GraphSidecar": 188 type_resource = "sidecar" 189 image = imgs[i].node.thumbnail_resources[image_index].src; 190 break; 191 case "GraphVideo": 192 type_resource = "video"; 193 image = imgs[i].node.thumbnail_src 194 break; 195 default: 196 type_resource = "image"; 197 image = imgs[i].node.thumbnail_resources[image_index].src; 198 } 199 200 if (this.is_tag) data.username = ''; 201 html += "<div class='item items-" + this.options.items_per_row + " instagram-" + type_resource + "' " + styles.gallery_image
201+ ">"; 202 html += "<a href='" + url + "' rel='noopener' target='_blank'>"; 203 html += "<div class='image'>"; 204 html += "<img src='" + image + "' alt='" + caption + "'>"; 205 html += "</div>"; 206 html += "</a>"; 207 html += "</div>"; 208 } 209 } 210 } 211 212 // IGTV 213 if (this.options.display_igtv && typeof data.edge_felix_video_timeline !== "undefined") { 214 var igtv = data.edge_felix_video_timeline.edges, 215 max = (igtv.length > this.options.items) ? this.options.items : igtv.length 216 if (igtv.length > 0) { 217 html += "<div class='instagram_igtv'>"; 218 for (var i = 0; i < max; i++) { 219 var url = "https://www.instagram.com/p/" + igtv[i].node.shortcode, 220 caption = this.parse_caption(igtv[i], data); 221 222 html += "<a href='" + url + "' rel='noopener' title='" + caption + "' target='_blank'>"; 223 html += "<img src='" + igtv[i].node.thumbnail_src + "' alt='" + caption + "'" + styles.gallery_image
223+ " />"; 224 html += "</a>"; 225 } 226 html += "</div>"; 227 } 228 } 229 230 this.options.container.innerHTML = html; 231 }; 232 233 this.run = function() { 234 this.get(function(data, instance) { 235 if (instance.options.get_data) 236 instance.options.callback(data); 237 else 238 instance.display(data); 239 }); 240 }; 241 242 if (this.valid) { 243 this.run(); 244 } 245 }; 246}));
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.