349 lines
13 KiB
JavaScript
349 lines
13 KiB
JavaScript
(function(root, factory) {
|
|
if (typeof define === 'function' && define.amd) {
|
|
// AMD. Register as an anonymous module.
|
|
define([], factory);
|
|
} else if (typeof module === 'object' && module.exports) {
|
|
// Node. Does not work with strict CommonJS, but
|
|
// only CommonJS-like environments that support module.exports,
|
|
// like Node.
|
|
module.exports = factory();
|
|
} else {
|
|
// Browser globals (root is window)
|
|
root.returnExports = factory();
|
|
}
|
|
}(typeof self !== 'undefined' ? self : this, function() {
|
|
|
|
var Instafeed, root;
|
|
|
|
Instafeed = (function() {
|
|
|
|
function Instafeed(params, context) {
|
|
var option, value;
|
|
this.options = {
|
|
target: 'instafeed',
|
|
get: 'popular',
|
|
resolution: 'thumbnail',
|
|
sortBy: 'none',
|
|
links: true,
|
|
mock: false,
|
|
useHttp: false,
|
|
};
|
|
if (typeof params === 'object') {
|
|
for (option in params) {
|
|
value = params[option];
|
|
this.options[option] = value;
|
|
}
|
|
}
|
|
this.context = context != null ? context : this;
|
|
this.unique = this._genKey();
|
|
}
|
|
|
|
Instafeed.prototype.hasNext = function() {
|
|
return typeof this.context.nextUrl === 'string' && this.context.nextUrl.length > 0;
|
|
};
|
|
|
|
Instafeed.prototype.next = function() {
|
|
if (!this.hasNext()) {
|
|
return false;
|
|
}
|
|
return this.run(this.context.nextUrl);
|
|
};
|
|
|
|
Instafeed.prototype.run = function(url) {
|
|
var header, instanceName, script;
|
|
if (typeof this.options.clientId !== 'string') {
|
|
if (typeof this.options.accessToken !== 'string') {
|
|
throw new Error('Missing clientId or accessToken.');
|
|
}
|
|
}
|
|
if (typeof this.options.accessToken !== 'string') {
|
|
if (typeof this.options.clientId !== 'string') {
|
|
throw new Error('Missing clientId or accessToken.');
|
|
}
|
|
}
|
|
if ((this.options.before != null) && typeof this.options.before === 'function') {
|
|
this.options.before.call(this);
|
|
}
|
|
if (typeof document !== 'undefined' && document !== null) {
|
|
script = document.createElement('script');
|
|
script.id = 'instafeed-fetcher';
|
|
script.src = url || this._buildUrl();
|
|
header = document.getElementsByTagName('head');
|
|
header[0].appendChild(script);
|
|
instanceName = 'instafeedCache' + this.unique;
|
|
window[instanceName] = new Instafeed(this.options, this);
|
|
window[instanceName].unique = this.unique;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
Instafeed.prototype.parse = function(response) {
|
|
var anchor, fragment, header, htmlString, image, imageString, imageUrl, images, img, imgUrl, instanceName,
|
|
node, reverse, sortSettings, tmpEl, _i, _j, _k, _len, _len1, _len2, _ref;
|
|
if (typeof response !== 'object') {
|
|
if ((this.options.error != null) && typeof this.options.error === 'function') {
|
|
this.options.error.call(this, 'Invalid JSON data');
|
|
return false;
|
|
} else {
|
|
throw new Error('Invalid JSON response');
|
|
}
|
|
}
|
|
if (response.meta.code !== 200) {
|
|
if ((this.options.error != null) && typeof this.options.error === 'function') {
|
|
this.options.error.call(this, response.meta.error_message);
|
|
return false;
|
|
} else {
|
|
throw new Error('Error from Instagram: ' + response.meta.error_message);
|
|
}
|
|
}
|
|
if (response.data.length === 0) {
|
|
if ((this.options.error != null) && typeof this.options.error === 'function') {
|
|
this.options.error.call(this, 'No images were returned from Instagram');
|
|
return false;
|
|
} else {
|
|
throw new Error('No images were returned from Instagram');
|
|
}
|
|
}
|
|
if ((this.options.success != null) && typeof this.options.success === 'function') {
|
|
this.options.success.call(this, response);
|
|
}
|
|
this.context.nextUrl = '';
|
|
if (response.pagination != null) {
|
|
this.context.nextUrl = response.pagination.next_url;
|
|
}
|
|
if (this.options.sortBy !== 'none') {
|
|
if (this.options.sortBy === 'random') {
|
|
sortSettings = ['', 'random'];
|
|
} else {
|
|
sortSettings = this.options.sortBy.split('-');
|
|
}
|
|
reverse = sortSettings[0] === 'least' ? true : false;
|
|
switch (sortSettings[1]) {
|
|
case 'random':
|
|
response.data.sort(function() {
|
|
return 0.5 - Math.random();
|
|
});
|
|
break;
|
|
case 'recent':
|
|
response.data = this._sortBy(response.data, 'created_time', reverse);
|
|
break;
|
|
case 'liked':
|
|
response.data = this._sortBy(response.data, 'likes.count', reverse);
|
|
break;
|
|
case 'commented':
|
|
response.data = this._sortBy(response.data, 'comments.count', reverse);
|
|
break;
|
|
default:
|
|
throw new Error('Invalid option for sortBy: \'' + this.options.sortBy + '\'.');
|
|
}
|
|
}
|
|
if ((typeof document !== 'undefined' && document !== null) && this.options.mock === false) {
|
|
images = response.data;
|
|
if (this.options.limit != null) {
|
|
if (images.length > this.options.limit) {
|
|
images = images.slice(0, this.options.limit + 1 || 9e9);
|
|
}
|
|
}
|
|
fragment = document.createDocumentFragment();
|
|
if ((this.options.filter != null) && typeof this.options.filter === 'function') {
|
|
images = this._filter(images, this.options.filter);
|
|
}
|
|
if ((this.options.template != null) && typeof this.options.template === 'string') {
|
|
htmlString = '';
|
|
imageString = '';
|
|
imgUrl = '';
|
|
tmpEl = document.createElement('div');
|
|
for (_i = 0, _len = images.length; _i < _len; _i++) {
|
|
image = images[_i];
|
|
imageUrl = image.images[this.options.resolution].url;
|
|
if (!this.options.useHttp) {
|
|
imageUrl = imageUrl.replace('http://', '//');
|
|
}
|
|
imageString = this._makeTemplate(this.options.template, {
|
|
model: image,
|
|
id: image.id,
|
|
link: image.link,
|
|
image: imageUrl,
|
|
caption: this._getObjectProperty(image, 'caption.text'),
|
|
likes: image.likes.count,
|
|
comments: image.comments.count,
|
|
location: this._getObjectProperty(image, 'location.name'),
|
|
});
|
|
htmlString += imageString;
|
|
}
|
|
tmpEl.innerHTML = htmlString;
|
|
_ref = [].slice.call(tmpEl.childNodes);
|
|
for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
|
|
node = _ref[_j];
|
|
fragment.appendChild(node);
|
|
}
|
|
} else {
|
|
for (_k = 0, _len2 = images.length; _k < _len2; _k++) {
|
|
image = images[_k];
|
|
img = document.createElement('img');
|
|
imageUrl = image.images[this.options.resolution].url;
|
|
if (!this.options.useHttp) {
|
|
imageUrl = imageUrl.replace('http://', '//');
|
|
}
|
|
img.src = imageUrl;
|
|
if (this.options.links === true) {
|
|
anchor = document.createElement('a');
|
|
imageUrl = image.images['standard_resolution'].url;
|
|
if (!this.options.useHttp) {
|
|
imageUrl = imageUrl.replace('http://', '//');
|
|
}
|
|
anchor.href = imageUrl;
|
|
anchor.setAttribute('data-rel', 'instagram');
|
|
anchor.setAttribute('class', 'imgbox');
|
|
anchor.appendChild(img);
|
|
fragment.appendChild(anchor);
|
|
} else {
|
|
fragment.appendChild(img);
|
|
}
|
|
}
|
|
}
|
|
document.getElementById(this.options.target).appendChild(fragment);
|
|
header = document.getElementsByTagName('head')[0];
|
|
header.removeChild(document.getElementById('instafeed-fetcher'));
|
|
instanceName = 'instafeedCache' + this.unique;
|
|
window[instanceName] = void 0;
|
|
try {
|
|
delete window[instanceName];
|
|
} catch (e) {
|
|
|
|
}
|
|
}
|
|
if ((this.options.after != null) && typeof this.options.after === 'function') {
|
|
this.options.after.call(this);
|
|
}
|
|
return true;
|
|
};
|
|
|
|
Instafeed.prototype._buildUrl = function() {
|
|
var base, endpoint, final;
|
|
base = 'https://api.instagram.com/v1';
|
|
switch (this.options.get) {
|
|
case 'popular':
|
|
endpoint = 'media/popular';
|
|
break;
|
|
case 'tagged':
|
|
if (typeof this.options.tagName !== 'string') {
|
|
throw new Error('No tag name specified. Use the \'tagName\' option.');
|
|
}
|
|
endpoint = 'tags/' + this.options.tagName + '/media/recent';
|
|
break;
|
|
case 'location':
|
|
if (typeof this.options.locationId !== 'number') {
|
|
throw new Error('No location specified. Use the \'locationId\' option.');
|
|
}
|
|
endpoint = 'locations/' + this.options.locationId + '/media/recent';
|
|
break;
|
|
case 'user':
|
|
if (typeof this.options.userId !== 'number') {
|
|
throw new Error('No user specified. Use the \'userId\' option.');
|
|
}
|
|
/*if (typeof this.options.accessToken !== 'string') {
|
|
throw new Error("No access token. Use the 'accessToken' option.");
|
|
}*/
|
|
endpoint = 'users/' + this.options.userId + '/media/recent';
|
|
break;
|
|
default:
|
|
throw new Error('Invalid option for get: \'' + this.options.get + '\'.');
|
|
}
|
|
final = '' + base + '/' + endpoint;
|
|
if (this.options.accessToken != null) {
|
|
final += '?access_token=' + this.options.accessToken;
|
|
} else {
|
|
final += '?client_id=' + this.options.clientId;
|
|
}
|
|
if (this.options.limit != null) {
|
|
final += '&count=' + this.options.limit;
|
|
}
|
|
final += '&callback=instafeedCache' + this.unique + '.parse';
|
|
return final;
|
|
};
|
|
|
|
Instafeed.prototype._genKey = function() {
|
|
var S4;
|
|
S4 = function() {
|
|
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
|
|
};
|
|
return '' + (S4()) + (S4()) + (S4()) + (S4());
|
|
};
|
|
|
|
Instafeed.prototype._makeTemplate = function(template, data) {
|
|
var output, pattern, varName, varValue, _ref;
|
|
pattern = /(?:\{{2})([\w\[\]\.]+)(?:\}{2})/;
|
|
output = template;
|
|
while (pattern.test(output)) {
|
|
varName = output.match(pattern)[1];
|
|
varValue = (_ref = this._getObjectProperty(data, varName)) != null ? _ref : '';
|
|
output = output.replace(pattern, '' + varValue);
|
|
}
|
|
return output;
|
|
};
|
|
|
|
Instafeed.prototype._getObjectProperty = function(object, property) {
|
|
var piece, pieces;
|
|
property = property.replace(/\[(\w+)\]/g, '.$1');
|
|
pieces = property.split('.');
|
|
while (pieces.length) {
|
|
piece = pieces.shift();
|
|
if ((object != null) && piece in object) {
|
|
object = object[piece];
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
return object;
|
|
};
|
|
|
|
Instafeed.prototype._sortBy = function(data, property, reverse) {
|
|
var sorter;
|
|
sorter = function(a, b) {
|
|
var valueA, valueB;
|
|
valueA = this._getObjectProperty(a, property);
|
|
valueB = this._getObjectProperty(b, property);
|
|
if (reverse) {
|
|
if (valueA > valueB) {
|
|
return 1;
|
|
} else {
|
|
return -1;
|
|
}
|
|
}
|
|
if (valueA < valueB) {
|
|
return 1;
|
|
} else {
|
|
return -1;
|
|
}
|
|
};
|
|
data.sort(sorter.bind(this));
|
|
return data;
|
|
};
|
|
|
|
Instafeed.prototype._filter = function(images, filter) {
|
|
var filteredImages, image, _fn, _i, _len;
|
|
filteredImages = [];
|
|
_fn = function(image) {
|
|
if (filter(image)) {
|
|
return filteredImages.push(image);
|
|
}
|
|
};
|
|
for (_i = 0, _len = images.length; _i < _len; _i++) {
|
|
image = images[_i];
|
|
_fn(image);
|
|
}
|
|
return filteredImages;
|
|
};
|
|
|
|
return Instafeed;
|
|
|
|
})();
|
|
|
|
root = typeof exports !== 'undefined' && exports !== null ? exports : window;
|
|
|
|
root.Instafeed = Instafeed;
|
|
|
|
return Instafeed;
|
|
}));
|