1Redactor.add('plugin', 'giphy', { 2 translations: { 3 'en': { 4 "giphy": { 5 "title": "GIF" 6 } 7 } 8 }, 9 defaults: { 10 context: false, 11 }, 12 modals: { 13 id: 1, 14 edit: { 15 width: '100%', 16 title: 'Search for GIFs', 17 form: { 18 search: { type: 'input', placeholder: JBL.texts.giphy_search.title, onInput: () => this._search() }, 19 }, 20 } 21 }, 22 subscribe: { 23 'dropdown.open': function(event) { 24 const dropdown = event.get('dropdown'); 25 if (dropdown.getName() === 'giphy') { 26 const textQuery = document.querySelector('.rx-form-input'); 27 var typingTimer; 28 const timeout = 500; 29 textQuery.addEventListener("keyup", (event) => { 30 typingTimer = setTimeout(() => { 31 this.handle_input(event); 32 }, timeout); 33 }); 34 textQuery.addEventListener("keydown", (event) => { 35 clearTimeout(typingTimer); 36 }); 37 38 this.start_plugin(dropdown); 39 } 40 } 41 }, 42 init() { 43 this.offset_count = 0; 44 this.data = []; 45 }, 46 start() { 47 let button = { 48 title: this.lang.get('giphy.title'), 49 icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14"><path d="M2.275 2.1656C1.5095 2.2347.888 2.5943.5011 3.192c-.1939.2995-.3284.66-.4057 1.0876L.063 4.459v2.366c0 2.1724.002 2.3798.0243 2.535.0597.4144.1976.7755.4142 1.084.1049.1493.3957.4285.5592.5367.3825.2532.8633.4155 1.3543.4574.13.011 1.4855.0141 4.739.0106 5.0027-.0054 4.659.0006 4.9994-.086.8348-.2122 1.4151-.7974 1.6703-1.6841a4.2606 4.2606 0 0 0 .0805-.3476l.0328-.182V6.776c0-2.504.0015-2.4408-.0639-2.758-.0905-.4392-.3265-.8688-.6389-1.163-.2991-.2815-.6904-.491-1.1235-.6015-.3844-.098.1111-.089-5.0897-.0911-2.5795-.001-4.7152.0004-4.746.0032m-.0538 1.0207c-.2756.0498-.51.1612-.683.3243-.2113.1993-.3383.4436-.435.8364l-.031.126-.005 2.268c-.0033 1.5364 0 2.3154.01 2.415.0689.679.4434 1.0755 1.1803 1.2492l.1295.0306 4.557.0048c3.1357.0033 4.6028.0002 4.704-.01.6202-.0624 1.0226-.3982 1.2017-1.0028.0912-.308.0878-.1937.0825-2.7358-.0052-2.5094-.0003-2.3552-.082-2.6036-.1571-.4775-.543-.7807-1.1401-.896-.1466-.0282-.1775-.0284-4.7633-.0271-3.9175.001-4.6324.0042-4.7256.021M6.356 4.55c-.4732.0067-.5002.0085-.563.0375-.0924.0427-.1946.143-.243.2386-.0372.0734-.041.0938-.041.2209 0 .1264.0038.1473.0394.2147.0526.1.1477.1924.2449.238.0755.0353.0929.0375.3282.0417l.2485.0044v2.5007l-.2415.0061c-.2285.0059-.2462.0084-.3294.046-.114.0514-.2265.1699-.2691.2834-.042.112-.0355.2725.0154.382.0458.0983.152.2046.2506.2509l.077.0361h2.002l.0855-.0395c.1075-.0497.2027-.1456.2526-.2545.0325-.0707.0386-.1028.0386-.203 0-.1476-.0404-.246-.1429-.3485-.1268-.1268-.226-.1555-.5374-.1555H7.378V5.5457l.2555-.0043c.242-.0042.2595-.0063.3325-.041.2735-.1303.3736-.4781.2086-.7252-.0622-.093-.1206-.1422-.2263-.1903-.0723-.0329-.0803-.0334-.5843-.0376a54.4274 54.4274 0 0 0-1.008.0027m-3.4564.0216c-.5.1085-.8923.4616-1.0414.9374-.065.207-.0688.2908-.063 1.372.0051.9794.0061 1.0112.0355 1.1222.1359.513.5374.9052 1.0463 1.022.0971.0224.1762.0258.595.0258.455 0 .4902-.0018.6067-.0315.5044-.1286.8896-.5116 1.0192-1.0135.0267-.1033.031-.1652.0365-.5294.0071-.4734-.0006-.5364-.0802-.6548-.0636-.0946-.1475-.162-.2486-.1999-.0748-.028-.0997-.029-.6322-.025l-.5544.0041-.07.035c-.091.0455-.2024.1567-.2456.245-.05.1022-.0555.2767-.0124.3917.038.1011.143.218.244.2713.0673.0355.0802.0371.3343.0416l.2642.0046-.0065.1004c-.0096.1487-.0755.2548-.2.3221-.0537.029-.0724.0303-.462.0303s-.4083-.0012-.462-.0303c-.066-.0357-.1335-.1043-.17-.1727-.0246-.0465-.026-.1003-.026-1.036 0-.9284.0015-.99.0256-1.0385.0365-.0733.116-.1504.1904-.1849.0601-.0278.0867-.0296.442-.0296.3558 0 .3818.0018.4422.0297.0918.0425.159.1161.2135.2342.0619.134.1272.2042.2436.2622.0862.043.106.0473.2207.0476.1075.0003.1373-.005.203-.0364.1087-.052.1833-.1221.239-.2247.0456-.0841.048-.0957.048-.2286 0-.1196-.0053-.1527-.0368-.2272-.1436-.341-.4221-.6222-.7541-.7617-.2033-.0854-.2917-.0956-.8191-.0947-.3507.0006-.4995.006-.5654.0202M9.24 4.5631c-.1164.0355-.2504.1504-.3065.2628-.0162.0324-.0356.1017-.0432.154-.0176.122-.0186 3.5196-.001 3.6411.007.0485.027.1178.0446.154.0436.0903.1503.1932.2468.2381.0681.0318.0994.0375.2063.0377.1101.0002.1361-.0048.2063-.0393.1026-.0503.2015-.1492.2476-.2475l.0361-.077.0038-.7662.0039-.7662.8365-.0038.8364-.0038.0935-.046a.5208.5208 0 0 0 .2377-.2387c.0274-.0556.0322-.0872.0321-.2123 0-.1713-.0213-.2268-.1308-.3406-.0829-.0862-.1722-.1318-.2921-.1491-.0527-.0076-.4335-.0139-.8545-.014L9.884 6.146v-.6013l.9905-.0038.9905-.0039.07-.035c.0901-.045.2006-.1559.2443-.245.0507-.1035.0568-.2776.0138-.392-.0433-.115-.17-.2425-.2831-.2847-.
49081-.0303-.082-.0303-1.358-.0291-.7024.0007-1.2927.006-1.312.0119" fill-rule="evenodd"/></svg>', 50 command: 'giphy.popup', 51 position: { 52 'after': 'link' 53 } 54 }; 55 56 this.app.toolbar.add('giphy', button); 57 }, 58 popup(e, button) { 59 // create 60 //let stack = this.app.create('stack'); 61 //stack.create('giphy', this.modals.edit); 62 const form = this.app.create('form', { 63 items: { 64 search: { type: 'input', placeholder: 'Search for gifs', name: 'giphy-search' }, 65 } 66 }); 67 68 this.app.dropdown.create('giphy', { form, width: '350px' }); 69 this.app.dropdown.open(e, button); 70 }, 71 start_plugin(dropdown) { 72 // setup all the elements aside from the text search 73 const stack = dropdown.getForm(); 74 const tool = stack.getItem('search'); 75 76 //$item = document.querySelector('.rx-form-input'); 77 $box = this.dom('<div id="giphy-results" name="giphy"></div>').addClass('rx-giphy-wrapper'); 78 $buttons = this.dom('<div class="rx-giphy-buttons"></div>'); 79 $refreshButton = this.dom('<button class="refresh-giphy-button btn btn-primary">Refresh</button>'); 80 $refreshButton.on('click', () => { this._refreshGifs(); }); 81 $logo = this.dom('<div><img class="giphy-logo" src="' + JBL.giphy_logo_url + '"></img></div>'); 82 83 // append the items 84 tool.append($box); 85 tool.append($buttons); 86 $buttons.append($refreshButton); 87 $buttons.append($logo); 88 89 // get the first batch of gifs 90 this._refreshGifs(); 91 }, 92 handle_input(e) { 93 var query = e.target.value; 94 this.offset_count = 0; 95 this._search(query, false); 96 }, 97 _search(query, offset) { 98 let api_key = JBL.giphy_api_key; 99 let giphy_url_gif_search = 'https://api.giphy.com/v1/gifs/search'; 100 let rating = "pg"; 101 let paginate_by = 9; 102 // Limit of next pages before reset 103 let page_limit = 4; 104 105 if (offset) { 106 this.offset_count += paginate_by 107 this.offset_count %= (paginate_by * page_limit); 108 } 109 110 let parameters = { 111 q: query, 112 api_key: api_key, 113 rating: rating, 114 limit: paginate_by, 115 offset: this.offset_count 116 }; 117 118 // Kept the jquery from the old plugin but we should probably use fetch instead? 119 $.getJSON(giphy_url_gif_search + "?" + $.param(parameters), this.handle_giphy_response.bind(this)); 120 }, 121 handle_giphy_response: function (response) { 122 data = response.data; 123 let $wrapper = this.dom('#giphy-results'); 124 $wrapper.empty(); 125 for (var i = 0; i < data.length; i++) { 126 var object = data[i]; 127 let gifUrl = object.images.original.url; 128 let $item = this.dom('<div class="gif"><img style="width:110px;height:110px;" src=' + gifUrl + '></img></div>'); 129 $item.on('click', () => { this._selectGif(gifUrl) }); 130 $wrapper.append($item) 131 } 132 }, 133 _selectGif(gifUrl) { 134 let htmlString = '<img src="' + gifUrl + '" alt="GIF"/>'; 135 this.app.editor.insertContent({ html: htmlString, caret: 'after' }); 136 this.app.dropdown.close(); 137 }, 138 _refreshGifs() { 139 const textQuery = document.querySelector('.rx-form-input').value; 140 const randomTags = ['success', 'happiness', 'team']; 141 142 if(textQuery) { 143 this._search(textQuery, true); 144 } else { 145 let randomTag = randomTags[Math.floor(Math.random() * randomTags.length)]; 146 this._search(randomTag, true); 147 } 148 }, 149});
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.