1+ // WebComponent: InstagramWidget 2.3.0 - Collection of WebComponents by Patryk Rzucidlo [@PTKDev] <support@ptkdev.io>
2+ // https://github.com/ptkdev-components/webcomponent-instagram-widget
3+ ( function ( ) { /**
4+ * InstagramWidget WebComponent
5+ * =====================
6+ * Simple Instagram Widget: Photos Box of your Instagram Profile for your blog or website with this WebComponent.
7+ *
8+ * @contributors : Patryk Rzucidło [@ptkdev] <support@ptkdev.io> (https://ptk.dev)
9+ *
10+ * @license : MIT License
11+ *
12+ */
13+ class InstagramWidget extends HTMLElement {
14+ constructor ( ) {
15+ super ( ) ;
16+
17+ const template = document . createElement ( "template" ) ;
18+ template . innerHTML = `<style id="instagram-widget-style">#instagram-widget *{margin:0;padding:0;line-height:0}#instagram-widget .instagram-widget-container{text-align:center;justify-content:center;font-weight:500}#instagram-widget .instagram-widget-photos li img{border-radius:5%;background-color:#f8f8ff;object-fit:cover;object-position:50% 50%;max-width:300px;max-height:300px;min-width:80px;min-height:80px;margin:2px}#instagram-widget .instagram-content ul{list-style-type:none;padding-inline-start:0;width:100%}#instagram-widget .instagram-widget-photos li{list-style-type:none;display:inline}</style><div id="instagram-widget" version="2.3.0">
19+ <div class="instagram-widget-container">
20+ <div class="instagram-widget-content">
21+ <ul class="instagram-widget-photos"></ul>
22+ </div>
23+ </div>
24+ </div>` ;
25+
26+ this . attachShadow ( { mode : "open" } ) ;
27+ this . shadowRoot . appendChild ( template . content . cloneNode ( true ) ) ;
28+ this . json = null ;
29+ this . options_default = {
30+ "username" : "@ptkdev" ,
31+ "items-limit" : "9" ,
32+ "image-width" : "100%" ,
33+ "image-height" : "100%" ,
34+ "grid" : "responsive" ,
35+ "cache" : "enabled" ,
36+ "border-spacing" : "2px" ,
37+ "border-corners" : "5"
38+ } ;
39+
40+ this . options = Object . create ( this . options_default ) ;
41+ }
42+
43+ /**
44+ * Build HTML grid
45+ * =====================
46+ *
47+ */
48+ build_html ( ) {
49+ let data = this . json . graphql . user . edge_owner_to_timeline_media . edges ;
50+
51+ let photos = [ ] ;
52+
53+ for ( let i = 0 ; i < data . length ; i ++ ) {
54+ photos . push ( {
55+ url : `https://www.instagram.com/p/${ data [ i ] . node . shortcode } /` ,
56+ thumbnail : data [ i ] . node . thumbnail_src ,
57+ display_url : data [ i ] . node . display_url !== undefined ? data [ i ] . node . display_url : "" ,
58+ caption : data [ i ] . node . edge_media_to_caption . edges [ 0 ] &&
59+ data [ i ] . node . edge_media_to_caption . edges [ 0 ] . node . text !== undefined ? data [ i ] . node . edge_media_to_caption . edges [ 0 ] . node . text : ""
60+ } ) ;
61+ }
62+
63+ let html = "" ;
64+ for ( let i = 0 ; i < photos . length && i < this . options [ "items-limit" ] ; i ++ ) {
65+ html += `<li><a href="${ photos [ i ] . url } " rel="nofollow external noopener noreferrer" target="_blank" title="${ photos [ i ] . caption . substring ( 0 , 100 ) . replace ( / " / g, "" ) } "><img width="${ this . options [ "image-width" ] } " height="${ this . options [ "image-height" ] } " src="${ photos [ i ] . display_url } " alt="${ photos [ i ] . caption . substring ( 0 , 100 ) . replace ( / " / g, "" ) } " loading="lazy" /></a></li>` ;
66+ }
67+ document . querySelector ( "instagram-widget" ) . shadowRoot . querySelector ( ".instagram-widget-photos" ) . innerHTML = html ;
68+
69+ if ( this . options [ "grid" ] !== "" && this . options [ "grid" ] !== null && this . options [ "grid" ] !== "responsive" ) {
70+ let grid = this . options [ "grid" ] . split ( "x" ) ;
71+ let width = 100 / parseInt ( grid [ 0 ] ) ;
72+ let images = document . querySelector ( "instagram-widget" ) . shadowRoot . querySelectorAll ( ".instagram-widget-photos img" ) ;
73+ for ( let i = 0 ; i < images . length ; i ++ ) {
74+ images [ i ] . removeAttribute ( "width" ) ;
75+ images [ i ] . style . width = `calc(${ ( width ) } % - (${ this . options [ "border-spacing" ] } * (${ parseInt ( grid [ 0 ] ) } * 2)))` ;
76+ images [ i ] . style . maxWidth = "none" ;
77+ images [ i ] . style . maxHeight = "none" ;
78+ images [ i ] . style . borderRadius = `${ this . options [ "border-corners" ] } %` ;
79+ images [ i ] . style . margin = this . options [ "border-spacing" ] ;
80+ }
81+ } else {
82+ let images = document . querySelector ( "instagram-widget" ) . shadowRoot . querySelectorAll ( ".instagram-widget-photos img" ) ;
83+ for ( let i = 0 ; i < images . length ; i ++ ) {
84+ images [ i ] . style . borderRadius = `${ this . options [ "border-corners" ] } %` ;
85+ images [ i ] . style . margin = this . options [ "border-spacing" ] ;
86+ }
87+ }
88+ }
89+
90+ /**
91+ * Get Photos from fetch request
92+ * =====================
93+ *
94+ */
95+ api_fetch ( ) {
96+ let self = this ;
97+
98+ let url = `https://www.instagram.com/${ this . options [ "username" ] . replace ( "@" , "" ) } /?__a=1` ;
99+ fetch ( url , { "cache" : this . options [ "cache" ] === null || this . options [ "cache" ] === "enabled" ? "force-cache" : "default" } ) . then ( function ( response ) {
100+ if ( response . status === 200 ) {
101+ return response . json ( ) ;
102+ }
103+ } ) . then ( function ( response ) {
104+ self . json = response ;
105+ self . build_html ( ) ;
106+ } ) ;
107+ }
108+
109+ static get observedAttributes ( ) {
110+ return [ "username" , "items-limit" , "grid" , "image-width" , "image-height" , "border-spacing" , "border-corners" , "cache" ] ;
111+ }
112+
113+ attributeChangedCallback ( name_attribute , old_vale , new_value ) {
114+ if ( old_vale !== new_value ) {
115+ if ( new_value === null || new_value === "" ) {
116+ this . options [ name_attribute ] = this . options_default [ name_attribute ] ;
117+ } else {
118+ this . options [ name_attribute ] = new_value ;
119+ }
120+
121+ switch ( name_attribute ) {
122+ case "username" :
123+ this . api_fetch ( ) ;
124+ break ;
125+ default :
126+ if ( this . json !== null ) {
127+ this . build_html ( ) ;
128+ }
129+ }
130+ }
131+ }
132+ }
133+
134+ window . customElements . define ( "instagram-widget" , InstagramWidget ) ;
135+ } ) ( ) ;
0 commit comments