From a1ec3323bcf19b8010b25576ede0d8c7b876dfb8 Mon Sep 17 00:00:00 2001 From: Jonathan Hornung Date: Mon, 11 Jan 2016 12:46:34 +0100 Subject: [PATCH] big big changes --- Gruntfile.js | 3 +- README.md | 13 +- bower.json | 2 +- demo/app.js | 1 + demo/index.html | 55 +---- demo/template.html | 5 + demo2/aping-config.js | 38 +++ demo2/aping-design-default.js | 55 +++++ {demo => demo2}/img/dailymotion.png | Bin {demo => demo2}/img/facebook.png | Bin {demo => demo2}/img/flickr.png | Bin {demo => demo2}/img/instagram.png | Bin {demo => demo2}/img/rss.png | Bin {demo => demo2}/img/tumblr.png | Bin {demo => demo2}/img/twitter.png | Bin {demo => demo2}/img/vimeo.png | Bin {demo => demo2}/img/youtube.png | Bin demo2/index.html | 83 +++++++ demo2/social_app.js | 13 + {demo => demo2}/social_template.html | 2 +- dist/aping-config.js | 70 +++--- dist/aping.js | 348 ++++++++++++--------------- dist/aping.min.js | 4 +- package.json | 4 +- src/aping-config.js | 70 +++--- src/aping-designHelpers.js | 194 --------------- src/aping-directive.js | 69 ++++-- src/aping-helpers.js | 8 +- src/aping-jsonloader-directive.js | 81 +++++++ src/aping-ng-array-directive.js | 41 ++++ 30 files changed, 605 insertions(+), 554 deletions(-) create mode 100644 demo/app.js create mode 100644 demo/template.html create mode 100644 demo2/aping-config.js create mode 100644 demo2/aping-design-default.js rename {demo => demo2}/img/dailymotion.png (100%) rename {demo => demo2}/img/facebook.png (100%) rename {demo => demo2}/img/flickr.png (100%) rename {demo => demo2}/img/instagram.png (100%) rename {demo => demo2}/img/rss.png (100%) rename {demo => demo2}/img/tumblr.png (100%) rename {demo => demo2}/img/twitter.png (100%) rename {demo => demo2}/img/vimeo.png (100%) rename {demo => demo2}/img/youtube.png (100%) create mode 100644 demo2/index.html create mode 100644 demo2/social_app.js rename {demo => demo2}/social_template.html (96%) delete mode 100644 src/aping-designHelpers.js create mode 100644 src/aping-jsonloader-directive.js create mode 100644 src/aping-ng-array-directive.js diff --git a/Gruntfile.js b/Gruntfile.js index 43288cb..591fd2c 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -7,7 +7,8 @@ module.exports = function(grunt) { 'src/aping-helpers.js', 'src/aping-inputObjects.js', 'src/aping-models.js', - 'src/aping-designHelpers.js' + 'src/aping-jsonloader-directive.js', + 'src/aping-ng-array-directive.js' ]; grunt.initConfig({ diff --git a/README.md b/README.md index fb6dd49..63842b9 100644 --- a/README.md +++ b/README.md @@ -9,18 +9,9 @@ _**Note:** apiNG is currently under development and not ready yet for public use [![npm version](https://badge.fury.io/js/aping.png)](https://badge.fury.io/js/aping) [![Bower version](https://badge.fury.io/bo/apiNG.png)](https://badge.fury.io/bo/apiNG) +**apiNG** helps you displaying $http.get results (and much much more ...) -**apiNG** is an AngularJS directive for receiving and displaying data from any source, like REST APIs, JSON files or just simple JavaScript objects. - -## How apiNG works -**apiNG** works as extendable platform, composed of three components: - 1. **_plugins_** pass various data on to **apiNG** - 2. **apiNG** passes the data on to **_designs_** - 3. **_designs_** display the data - -Users can collaborate to create new **_plugins_** and **_designs_** - -## Demos +## Advanced Demos - [Social Wall](http://aping.io/#demo) (default design) - [Image Gallery](https://rawgit.com/JohnnyTheTank/apiNG-design-xgallerify/master/demo/) (xgallerify design) - [Youtube Video Player](https://rawgit.com/JohnnyTheTank/apiNG-design-deadwood/master/demo/) (deadwood design) diff --git a/bower.json b/bower.json index 05baf80..79bc1c4 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "apiNG", - "version": "0.7.0", + "version": "0.8.0", "homepage": "https://github.com/JohnnyTheTank/apiNG", "authors": [ "Jonathan Hornung " diff --git a/demo/app.js b/demo/app.js new file mode 100644 index 0000000..07095c1 --- /dev/null +++ b/demo/app.js @@ -0,0 +1 @@ +var app = angular.module('app', ['jtt_aping']); \ No newline at end of file diff --git a/demo/index.html b/demo/index.html index 6ddcc74..1095e78 100644 --- a/demo/index.html +++ b/demo/index.html @@ -4,68 +4,23 @@ apiNG Demo - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - -
+ + template-url="template.html" + aping-jsonloader="[{'path':'https://commons.wikimedia.org/w/api.php?action=query&list=allimages&format=json&aifrom=berlin', 'format':'jsonp', 'callback':'JSON_CALLBACK'}]"> diff --git a/demo/template.html b/demo/template.html new file mode 100644 index 0000000..36b7b95 --- /dev/null +++ b/demo/template.html @@ -0,0 +1,5 @@ +
+
+
{{item | json}}
+
+
\ No newline at end of file diff --git a/demo2/aping-config.js b/demo2/aping-config.js new file mode 100644 index 0000000..2fdda87 --- /dev/null +++ b/demo2/aping-config.js @@ -0,0 +1,38 @@ +"use strict"; + +apingApp.config(['$provide', function ($provide) { + + $provide.value("apingDefaultSettings", { + //templateUrl: "../src/aping_design_default_social.html", + //items: 20, //items per request + //maxItems: 100, //max items per aping + //orderBy: "timestamp", + //orderReverse: "true", + //model: "social", + apingApiKeys: { + youtube: [ + {'apiKey': 'AIzaSyARYVuV6dho71EMZI6j6-sDEgo8OOnFygM'} + ], + instagram: [ + {'access_token': '3283222.a492704.6c2d53acdc3e47e695dff5c89368597d'} + ], + facebook: [ + {'access_token': 'CAAMC6AyvDH0BAChyXyiSXINl6nAZCaOP0nXS1T67ngaZA0svefRAJyWx3Y5bzic47wE4iZAMHCAAoQCvhUMZB3SQufDyio9g4vZAj5BgQXuMVDjVvqDrajfm7IEvN0U1O2JfC1FA2VfqpnYgRa9fF5ZAQBW4vHc6ZAmXryyJvzPQd5TkIdqUC4n'} + ], + twitter: [ + {'bearer_token': 'AAAAAAAAAAAAAAAAAAAAACs3iwAAAAAA%2BH8LdT7YfKIzk8fvQvqKvoePuxo%3DMKfXX2ojtacGL8aOLAhlBDUrEFpy0DUuiyebet22Wa2YVrX7cc'} + ], + vimeo: [ + {'access_token': '1e53b10910c18adf97682d12e01e60d6'}, + {'access_token': 'ea345d82cd76223342082f620d42cb72'} + ], + 'tumblr': [ + {'api_key': 'lINWJaOl0lu3ajBn5tdqJgs8IFisHu5GJ8hBYzR41f4BHEl9E6'}, + ], + 'bandsintown': [ + {'app_id': 'apiNG-default-design-demo'}, + ] + } + }); + +}]); \ No newline at end of file diff --git a/demo2/aping-design-default.js b/demo2/aping-design-default.js new file mode 100644 index 0000000..2255583 --- /dev/null +++ b/demo2/aping-design-default.js @@ -0,0 +1,55 @@ +"use strict"; + +angular.module('jtt_aping_design_default', ['wu.masonry', 'linkify', 'angularMoment', 'ngSanitize', 'jtt_imagesLoaded']) + .run(['amMoment', function (amMoment) { + amMoment.changeLocale('en'); + }]) + .controller('apingDefaultDesignController', ['$scope', '$sce', function ($scope, $sce) { + + $scope.$on('apiNG.resultMerged', function () { + $scope.workingCopy = $scope.results; + }); + + $scope.getPlatformIcon = function (_platform) { + switch (_platform) { + case "youtube": + case "twitter": + case "instagram": + case "vimeo": + case "vine": + case "facebook": + case "flickr": + case "dailymotion": + case "tumblr": + case "rss": + case "bandsintown": + return "img/"+_platform+".png"; + } + + return false; + }; + + $scope.refresh = function () { + $scope.$broadcast("masonry.reload"); + }; + + $scope.$on('imagesLoaded.SUCCESS', function() { + $scope.refresh(); + }); + $scope.$on('imagesLoaded.ALWAYS', function() { + $scope.refresh(); + }); + + $scope.getUrl = function (url) { + if(url) { + return $sce.trustAsResourceUrl(url); + } + }; + + $scope.getHtml = function (string) { + if(string) { + return $sce.trustAsHtml(string); + } + }; + + }]); \ No newline at end of file diff --git a/demo/img/dailymotion.png b/demo2/img/dailymotion.png similarity index 100% rename from demo/img/dailymotion.png rename to demo2/img/dailymotion.png diff --git a/demo/img/facebook.png b/demo2/img/facebook.png similarity index 100% rename from demo/img/facebook.png rename to demo2/img/facebook.png diff --git a/demo/img/flickr.png b/demo2/img/flickr.png similarity index 100% rename from demo/img/flickr.png rename to demo2/img/flickr.png diff --git a/demo/img/instagram.png b/demo2/img/instagram.png similarity index 100% rename from demo/img/instagram.png rename to demo2/img/instagram.png diff --git a/demo/img/rss.png b/demo2/img/rss.png similarity index 100% rename from demo/img/rss.png rename to demo2/img/rss.png diff --git a/demo/img/tumblr.png b/demo2/img/tumblr.png similarity index 100% rename from demo/img/tumblr.png rename to demo2/img/tumblr.png diff --git a/demo/img/twitter.png b/demo2/img/twitter.png similarity index 100% rename from demo/img/twitter.png rename to demo2/img/twitter.png diff --git a/demo/img/vimeo.png b/demo2/img/vimeo.png similarity index 100% rename from demo/img/vimeo.png rename to demo2/img/vimeo.png diff --git a/demo/img/youtube.png b/demo2/img/youtube.png similarity index 100% rename from demo/img/youtube.png rename to demo2/img/youtube.png diff --git a/demo2/index.html b/demo2/index.html new file mode 100644 index 0000000..6ccdd8c --- /dev/null +++ b/demo2/index.html @@ -0,0 +1,83 @@ + + + + + apiNG Demo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + +
+ + + + \ No newline at end of file diff --git a/demo2/social_app.js b/demo2/social_app.js new file mode 100644 index 0000000..38ad0bc --- /dev/null +++ b/demo2/social_app.js @@ -0,0 +1,13 @@ +var app = angular.module('app', [ + 'jtt_aping', + 'jtt_aping_youtube', + 'jtt_aping_instagram', + 'jtt_aping_facebook', + 'jtt_aping_codebird', + 'jtt_aping_vimeo', + 'jtt_aping_flickr', + 'jtt_aping_dailymotion', + 'jtt_aping_tumblr', + 'jtt_aping_rss', + 'jtt_aping_design_default' +]); \ No newline at end of file diff --git a/demo/social_template.html b/demo2/social_template.html similarity index 96% rename from demo/social_template.html rename to demo2/social_template.html index 0b17e8d..5376cba 100644 --- a/demo/social_template.html +++ b/demo2/social_template.html @@ -1,7 +1,7 @@
-
+
'} - ], - instagram: [ - {'access_token':''} - ], - facebook: [ - {'access_token':''} - ], - twitter: [ - {'bearer_token':''} - ], - vimeo: [ - {'access_token':''} - ], - 'tumblr': [ - {'api_key':''} - ], - github: [ - {'access_token':''} - ], - 'openweathermap': [ - {'api_key':''} - ] - }); + $provide.value("apingDefaultSettings", { + //templateUrl: "", + //items: 20, //items per request + //maxItems: 100, //max items per aping + //orderBy: "timestamp", + //orderReverse: "true", + //model: "social", + //getNativeData: false, + //removeDoubles: false, + apingApiKeys: { + youtube: [ + {'apiKey': ''} + ], + instagram: [ + {'access_token': ''} + ], + facebook: [ + {'access_token': ''} + ], + twitter: [ + {'bearer_token': ''} + ], + vimeo: [ + {'access_token': ''} + ], + 'tumblr': [ + {'api_key': ''} + ], + github: [ + {'access_token': ''} + ], + 'openweathermap': [ + {'api_key': ''} + ] + } - $provide.constant("apingDefaultSettings", { - templateUrl : "", - items : 20, //items per request - maxItems: 100, //max items per aping - orderBy : "timestamp", - orderReverse : "true", - model: "social", - getNativeData: false, - removeDoubles: false }); }]); \ No newline at end of file diff --git a/dist/aping.js b/dist/aping.js index 82da5f5..3a89588 100644 --- a/dist/aping.js +++ b/dist/aping.js @@ -1,12 +1,21 @@ /** @name: aping - @version: 0.1.0 (06-01-2016) + @version: 0.8.0 (11-01-2016) @author: Jonathan Hornung @url: https://github.com/JohnnyTheTank/apiNG#readme @license: MIT */ "use strict"; -var apingApp = angular.module('jtt_aping', []) +var apingApp = angular.module('jtt_aping', ['jtt_aping_jsonloader', 'jtt_aping_ng_array']) + + .config(['$provide', function ($provide) { + + $provide.value("apingDefaultSettings", { + apingApiKeys: {} + }); + + + }]) .directive('aping', ['apingDefaultSettings', 'apingUtilityHelper', function (apingDefaultSettings, apingUtilityHelper) { return { restrict: 'E', @@ -36,43 +45,60 @@ var apingApp = angular.module('jtt_aping', []) var maxItems; var getNativeData; var orderReverse; + var orderBy; var removeDoubles; - if(typeof $scope.items !== "undefined") { + if (typeof $scope.items !== "undefined") { items = $scope.items; - } else if(typeof apingDefaultSettings.items !== "undefined") { + } else if (typeof apingDefaultSettings.items !== "undefined") { items = apingDefaultSettings.items; } else { - items = 20; + items = undefined; } - if(typeof $scope.maxItems !== "undefined") { + if (typeof $scope.maxItems !== "undefined") { maxItems = $scope.maxItems; - } else if(typeof apingDefaultSettings.maxItems !== "undefined") { + } else if (typeof apingDefaultSettings.maxItems !== "undefined") { maxItems = apingDefaultSettings.maxItems; } else { - maxItems = -1; + maxItems = undefined; } - if(typeof $scope.getNativeData !== "undefined") { + if (typeof $scope.getNativeData !== "undefined") { getNativeData = $scope.getNativeData; - } else if(typeof apingDefaultSettings.getNativeData !== "undefined") { + } else if (typeof apingDefaultSettings.getNativeData !== "undefined") { getNativeData = apingDefaultSettings.getNativeData; } else { getNativeData = false; } - if(typeof $scope.orderReverse !== "undefined") { + if (typeof $scope.maxItems !== "undefined") { + maxItems = $scope.maxItems; + } else if (typeof apingDefaultSettings.maxItems !== "undefined") { + maxItems = apingDefaultSettings.maxItems; + } else { + maxItems = undefined; + } + + if (typeof $scope.orderBy !== "undefined") { + orderBy = $scope.orderBy; + } else if (typeof apingDefaultSettings.orderBy !== "undefined") { + orderBy = apingDefaultSettings.orderBy; + } else { + orderBy = "undefined"; + } + + if (typeof $scope.orderReverse !== "undefined") { orderReverse = $scope.orderReverse; - } else if(typeof apingDefaultSettings.orderReverse !== "undefined") { + } else if (typeof apingDefaultSettings.orderReverse !== "undefined") { orderReverse = apingDefaultSettings.orderReverse; } else { orderReverse = false; } - if(typeof $scope.removeDoubles !== "undefined") { + if (typeof $scope.removeDoubles !== "undefined") { removeDoubles = $scope.removeDoubles; - } else if(typeof apingDefaultSettings.removeDoubles !== "undefined") { + } else if (typeof apingDefaultSettings.removeDoubles !== "undefined") { removeDoubles = apingDefaultSettings.removeDoubles; } else { removeDoubles = false; @@ -80,10 +106,10 @@ var apingApp = angular.module('jtt_aping', []) return { model: $scope.model || apingDefaultSettings.model || "native", - getNativeData : getNativeData, + getNativeData: getNativeData, items: items, maxItems: maxItems, - orderBy: $scope.orderBy || apingDefaultSettings.orderBy, + orderBy: orderBy, orderReverse: orderReverse, removeDoubles: removeDoubles }; @@ -99,22 +125,22 @@ var apingApp = angular.module('jtt_aping', []) var appSettings = this.getAppSettings(); - if(appSettings.removeDoubles === true || appSettings.removeDoubles === "true") { + if (appSettings.removeDoubles === true || appSettings.removeDoubles === "true") { $scope.results = apingUtilityHelper.removeDuplicateObjectsFromArray($scope.results, (appSettings.orderBy === false || appSettings.orderBy === "false" || appSettings.orderBy === "$NONE")); } - if(appSettings.orderBy !== false && appSettings.orderBy !== "false" && appSettings.orderBy !== "$NONE") { - if(appSettings.orderBy === "$RANDOM") { + if (appSettings.orderBy !== "undefined" && appSettings.orderBy !== false && appSettings.orderBy !== "false" && appSettings.orderBy !== "$NONE") { + if (appSettings.orderBy === "$RANDOM") { $scope.results = apingUtilityHelper.shuffleArray($scope.results); } else { $scope.results.sort(apingUtilityHelper.sortArrayByProperty(appSettings.orderBy)); - if(appSettings.orderReverse === true || appSettings.orderReverse === "true") { + if (appSettings.orderReverse === true || appSettings.orderReverse === "true") { $scope.results.reverse(); } } } - if(appSettings.maxItems > -1 && $scope.results.length > appSettings.maxItems) { - $scope.results = $scope.results.splice(0,appSettings.maxItems); + if (appSettings.maxItems > -1 && $scope.results.length > appSettings.maxItems) { + $scope.results = $scope.results.splice(0, appSettings.maxItems); } $scope.$broadcast('apiNG.resultMerged'); }; @@ -127,6 +153,7 @@ var apingApp = angular.module('jtt_aping', []) } }; }]); + ;"use strict"; apingApp @@ -160,7 +187,7 @@ apingApp return 0; }; }) - .service('apingUtilityHelper', ['apingInputObjects', 'apingApiKeys', function (apingInputObjects, apingApiKeys) { + .service('apingUtilityHelper', ['apingInputObjects', 'apingDefaultSettings', function (apingInputObjects, apingDefaultSettings) { /** * return random matching API Key from Constant "apingApiKeys". If there is no matching API Key, the function returns 'false' @@ -171,9 +198,9 @@ apingApp */ this.getApiCredentials = function (_platform, _keyName) { - if (apingApiKeys) { - if (apingApiKeys[_platform]) { - return apingApiKeys[_platform][Math.floor(Math.random() * apingApiKeys[_platform].length)][_keyName]; + if (apingDefaultSettings.apingApiKeys) { + if (apingDefaultSettings.apingApiKeys[_platform]) { + return apingDefaultSettings.apingApiKeys[_platform][Math.floor(Math.random() * apingDefaultSettings.apingApiKeys[_platform].length)][_keyName]; } } return false; @@ -624,195 +651,122 @@ apingApp.service('apingModels', [function () { }; }]);;"use strict"; -/** - * this directive "imagesLoaded" is just a custom version of https://github.com/bimal1331/angular-images-loaded - */ - -apingApp.directive('imagesLoaded', ['$timeout', '$rootScope', '$q', function($timeout, $rootScope, $q) { - - var cache = {}; - - var broadcastMessages = { - progress : ['imagesLoaded.QUARTER', 'imagesLoaded.HALF', 'imagesLoaded.THREEQUARTERS', 'imagesLoaded.FULL'], - successful : 'imagesLoaded.SUCCESS', - complete : 'imagesLoaded.FAIL', - always : 'imagesLoaded.ALWAYS' - }; - - /************* Helper functions **********/ - function digestPromise(func) { - $timeout(func, 0); - } - - /*********** Constructors ************/ - function ImageNode(src, func, inBrowserCache) { - this.loaded = undefined; - this.loading = true; +angular.module("jtt_aping_jsonloader", []) + .directive('apingJsonloader', ['apingUtilityHelper', 'jsonloaderFactory', function (apingUtilityHelper, jsonloaderFactory) { + return { + require: '?aping', + restrict: 'A', + replace: 'false', + link: function (scope, element, attrs, apingController) { - if(!inBrowserCache) { - this.node = new Image(); - this.bind(func); - this.node.src = src; - } - else { - this.__onload(func, true); - } + var appSettings = apingController.getAppSettings(); + var requests = apingUtilityHelper.parseJsonFromAttributes(attrs.apingJsonloader, "jsonloader", appSettings); - } + requests.forEach(function (request) { - ImageNode.prototype = { - constructor : ImageNode, + if (request.path) { + //create requestObject for factory function call + var requestObject = { + path: request.path, + }; - bind : function(func) { - var _this = this; - this.node.addEventListener('load', function() { _this.__onload(func, true) }, false); - this.node.addEventListener('error', function() { _this.__onload(func, false) }, false); - }, + if (!request.format || request.format.toLowerCase() != "jsonp") { + requestObject.format = "json"; + } else { + requestObject.format = "jsonp"; + } - __onload : function(func, success) { - this.loaded = true; - this.loading = false; + if (request.callback && request.format === "jsonp") { + requestObject.callback = request.callback; + } else { + requestObject.callback = 'JSON_CALLBACK'; + } - if(success && this.node) { - delete this.node; + jsonloaderFactory.getJsonData(requestObject) + .then(function (_data) { + var resultArray = []; + if (_data.data) { + if (_data.data.constructor !== Array) { + resultArray.push(_data.data); + } else { + if (request.items < 0) { + resultArray = _data.data; + } else { + angular.forEach(_data.data, function (value, key) { + if (key < request.items) { + resultArray.push(value); + } + }); + } + } + } + apingController.concatToResults(resultArray); + }); + } + }); } - - func(success); } - }; - - function ImagesCollection(useProgressEvents) { - this.imagesCount = 0; - this.imagesLoaded = 0; - this.imagesFailed = 0; - this.useProgressEvents = useProgressEvents; - } - - ImagesCollection.prototype = { - constructor : ImagesCollection, - - whenImagesLoaded : function(imageNodes) { - var defer = $q.defer(), - totalImages = imageNodes.length, - _this = this, - imgElem, proxyImage; - - this.imagesCount = totalImages; - - for(var i = 0; i < this.imagesCount; i++) { - imgElem = imageNodes[i]; - - check(imgElem); - } - - function increment(bool) { - var progress; - - if(bool) { - _this.imagesLoaded++; - } - else { - _this.imagesFailed++; - } - - if(_this.useProgressEvents && (progress = (_this.imagesLoaded + _this.imagesFailed)/Math.ceil(totalImages/4)) && (progress % 1 === 0) && progress < 4) { - digestPromise(function() { - defer.notify(broadcastMessages.progress[progress-1]); - }); - } - - if(_this.imagesLoaded + _this.imagesFailed === _this.imagesCount) { - digestPromise(function() { - defer.notify(broadcastMessages.progress[3]); - defer.resolve((_this.imagesFailed > 0) ? broadcastMessages.complete : broadcastMessages.success); - }); - } - - } - - function check(img) { - var source = img.src, - cachedElement = cache[source], - proxyImage; - - if(cachedElement ) { - - if(cachedElement.loaded) { - //Image is in local cache and is loaded - increment(true); + }]) + .factory('jsonloaderFactory', ['$http', function ($http) { + var jsonloaderFactory = {}; + + jsonloaderFactory.getJsonData = function (_requestObject) { + if (_requestObject.format == "jsonp") { + + return $http.jsonp( + _requestObject.path, + { + method: 'GET', + params: {callback: _requestObject.callback}, } - else if(cachedElement.loading) { - //Image is currently being loaded and it's being checked again before successful load, so we wait for the image to load - cachedElement.bind(increment); - } - else if(cachedElement.loaded === false) { - // cachedElement.bind(increment); - // cachedElement.node.src = source; - } - - } - else if(img.complete && img.naturalWidth > 0) { - //Image is not in local cache but is present in browser's cache - cache[source] = new ImageNode(source, increment, true); - } - else { - //Image has not been loaded before, so we make a proxy image element and attach load listeners to it - cache[source] = new ImageNode(source, increment); + ); - } + } else { + return $http({ + method: 'GET', + url: _requestObject.path + }); } - return defer.promise; - } - }; - - //Directive configuration object - return { - restrict : 'A', - compile: function(tElem, tAttrs) { - - return function($scope, $element, $attrs) { - - var descendents = $element[0].childNodes, - useProgressEvents = $attrs.useProgressEvents === 'yes', - oldImageNodesCount = 0, - documentImages = document.images, - imageNodes; - - $scope.$watch( - function() { - return documentImages.length; - }, - function(newVal, oldVal) { + }; + return jsonloaderFactory; + }]);;"use strict"; - var newImageNodesCount, collection; +angular.module("jtt_aping_ng_array", []) + .directive('apingNgArray', ['apingUtilityHelper', function (apingUtilityHelper) { + return { + require: '?aping', + restrict: 'A', + replace: 'false', + link: function (scope, element, attrs, apingController) { - if(newVal === oldVal) return; + var appSettings = apingController.getAppSettings(); + var requests = apingUtilityHelper.parseJsonFromAttributes(attrs.apingNgArray, "ngArray", appSettings); - imageNodes = $element.find('img'); - newImageNodesCount = imageNodes.length; + requests.forEach(function (request) { - if(newImageNodesCount === oldImageNodesCount) return; - oldImageNodesCount = newImageNodesCount; + if (request.name && scope[request.name]) { - collection = new ImagesCollection(useProgressEvents); + var resultArray = []; - digestPromise(function() { - collection.whenImagesLoaded(imageNodes).then( - function(data) { - $scope.$emit(data); - $scope.$emit(broadcastMessages.always); - }, - function(error) { + if (scope[request.name].constructor === Array) { + if (request.items < 0) { + resultArray = scope[request.name]; + } else { + angular.forEach(scope[request.name], function (value, key) { + if (key < request.items) { + resultArray.push(value); + } + }); + } + } else if (typeof scope[request.name] === 'object' && scope[request.name] !== null) { + resultArray.push(scope[request.name]); + } - }, - function(progress) { - useProgressEvents && $scope.$emit('imagesLoaded.PROGRESS', {status : progress}); - } - ); - }); + if (resultArray.length > 0) { + apingController.concatToResults(resultArray); + } } - ); + }); } } - } -}]); \ No newline at end of file + }]); \ No newline at end of file diff --git a/dist/aping.min.js b/dist/aping.min.js index a0b3ed1..796632c 100644 --- a/dist/aping.min.js +++ b/dist/aping.min.js @@ -1,8 +1,8 @@ /** @name: aping - @version: 0.1.0 (06-01-2016) + @version: 0.8.0 (11-01-2016) @author: Jonathan Hornung @url: https://github.com/JohnnyTheTank/apiNG#readme @license: MIT */ -"use strict";var apingApp=angular.module("jtt_aping",[]).directive("aping",["apingDefaultSettings","apingUtilityHelper",function(a,b){return{restrict:"E",replace:"false",scope:{model:"@",getNativeData:"@",items:"@",maxItems:"@",orderBy:"@",orderReverse:"@",templateUrl:"@",payloadJson:"@",removeDoubles:"@"},controller:["$scope",function(c){c.results=[],c.payload=c.payloadJson?b.replaceSingleQuotesAndParseJson(c.payloadJson):{},this.getAppSettings=function(){var b,d,e,f,g;return b="undefined"!=typeof c.items?c.items:"undefined"!=typeof a.items?a.items:20,d="undefined"!=typeof c.maxItems?c.maxItems:"undefined"!=typeof a.maxItems?a.maxItems:-1,e="undefined"!=typeof c.getNativeData?c.getNativeData:"undefined"!=typeof a.getNativeData?a.getNativeData:!1,f="undefined"!=typeof c.orderReverse?c.orderReverse:"undefined"!=typeof a.orderReverse?a.orderReverse:!1,g="undefined"!=typeof c.removeDoubles?c.removeDoubles:"undefined"!=typeof a.removeDoubles?a.removeDoubles:!1,{model:c.model||a.model||"native",getNativeData:e,items:b,maxItems:d,orderBy:c.orderBy||a.orderBy,orderReverse:f,removeDoubles:g}},this.concatToResults=function(a){c.results=c.results.concat(a);var d=this.getAppSettings();(d.removeDoubles===!0||"true"===d.removeDoubles)&&(c.results=b.removeDuplicateObjectsFromArray(c.results,d.orderBy===!1||"false"===d.orderBy||"$NONE"===d.orderBy)),d.orderBy!==!1&&"false"!==d.orderBy&&"$NONE"!==d.orderBy&&("$RANDOM"===d.orderBy?c.results=b.shuffleArray(c.results):(c.results.sort(b.sortArrayByProperty(d.orderBy)),(d.orderReverse===!0||"true"===d.orderReverse)&&c.results.reverse())),d.maxItems>-1&&c.results.length>d.maxItems&&(c.results=c.results.splice(0,d.maxItems)),c.$broadcast("apiNG.resultMerged")},this.apply=function(){c.$apply()}}],templateUrl:function(b,c){return c.templateUrl||a.templateUrl}}}]);apingApp.service("apingTimeHelper",function(){this.getTimestampFromDateString=function(a,b,c){if(("undefined"==typeof b||isNaN(b))&&(b=1),("undefined"==typeof c||isNaN(c))&&(c=0),"string"==typeof a){var d=a.split(/[^0-9]/);try{return parseInt(Math.round(new Date(d[0],d[1]-1,d[2],d[3],d[4],d[5])/1e3*b)+c,10)}catch(e){return 0}}return 0}}).service("apingUtilityHelper",["apingInputObjects","apingApiKeys",function(a,b){this.getApiCredentials=function(a,c){return b&&b[a]?b[a][Math.floor(Math.random()*b[a].length)][c]:!1},this.parseJsonFromAttributes=function(a,b,c){return this.parseRequestsFromAttributes(a,b,c)},this.parseRequestsFromAttributes=function(b,c,d){if("string"!=typeof b||!b)return[];var e=[],f=this.replaceSingleQuotesAndParseJson(b);return angular.forEach(f,function(b,f){b.platform=c,d&&("undefined"==typeof b.items&&"undefined"!=typeof d.items&&(b.items=d.items),"undefined"==typeof b.model&&"undefined"!=typeof d.model&&(b.model=d.model));var g=a.getNew("request",b);e.push(g)}),e},this.replaceSingleQuotesAndParseJson=function(a){return $.parseJSON(a.replace(/'/g,'"'))},this.sortArrayByProperty=function(a){var b=1;return"-"===a[0]&&(b=-1,a=a.substr(1)),function(c,d){var e=c[a]d[a]?1:0;return e*b}},this.shuffleArray=function(a){for(var b=a.length-1;b>0;b--){var c=Math.floor(Math.random()*(b+1)),d=a[b];a[b]=a[c],a[c]=d}return a},this.removeDuplicateObjectsFromArray=function(a,b){var c=[],d="apingStringified",e="apingTempOrder";if(1===a.length)return a;$.each(a,function(a,f){f.$$hashKey=void 0,f[d]=JSON.stringify(f),b===!0&&(f[e]=a),c.push(f)}),c.sort(this.sortArrayByProperty(d));var f,g=[];return $.each(c,function(a,b){"undefined"!=typeof f?"undefined"!=typeof b[d]&&b[d]!==f&&g.push(b):g.push(b),f=b[d],b[d]=void 0}),b===!0&&(c.sort(this.sortArrayByProperty(e)),$.each(c,function(a,b){b[e]=void 0})),g},this.getTextFromHtml=function(a){return a=a.replace(/<br ?\/\>|<br ?\/&rt;|\
/g," "),a=a.replace(/<(?:.|\n)*?>/gm,"")},this.getFirstImageFromHtml=function(a){var b=/]+src="([^">]+)/g;return b.exec(a)},this.parseParametersFromUrl=function(a){var b={};return"string"==typeof a&&(b=JSON.parse('{"'+decodeURI(a.replace(/&/g,'","').replace(/=/g,'":"'))+'"}')),b}}]),apingApp.service("apingInputObjects",["apingDefaultSettings",function(a){this.getNew=function(b,c){var d={};switch(b){case"request":d=$.extend(!0,{model:a.model,items:a.items},c)}return d}}]),apingApp.service("apingModels",[function(){this.getNew=function(a,b){var c={};switch(a){case"social":c={platform:b,blog_name:void 0,blog_id:void 0,blog_link:void 0,type:void 0,timestamp:void 0,date_time:void 0,post_url:void 0,intern_id:void 0,text:void 0,caption:void 0,img_url:void 0,source:void 0,likes:void 0,shares:void 0,comments:void 0,position:void 0};break;case"video":c={platform:b,blog_name:void 0,blog_id:void 0,blog_link:void 0,timestamp:void 0,date_time:void 0,post_url:void 0,intern_id:void 0,text:void 0,caption:void 0,img_url:void 0,source:void 0,markup:void 0,likes:void 0,shares:void 0,duration:void 0,width:void 0,height:void 0,comments:void 0,position:void 0};break;case"image":c={platform:b,blog_name:void 0,blog_id:void 0,blog_link:void 0,timestamp:void 0,date_time:void 0,post_url:void 0,intern_id:void 0,text:void 0,caption:void 0,thumb_url:void 0,thumb_width:void 0,thumb_height:void 0,img_url:void 0,img_width:void 0,img_height:void 0,native_url:void 0,native_width:void 0,native_height:void 0,source:void 0,likes:void 0,shares:void 0,comments:void 0,position:void 0};break;case"event":c={platform:b,artist_name:void 0,artist_id:void 0,artist_link:void 0,start_timestamp:void 0,start_date_time:void 0,end_timestamp:void 0,end_date_time:void 0,event_url:void 0,ticket_url:void 0,sold_out:void 0,intern_id:void 0,text:void 0,caption:void 0,img_url:void 0,place_name:void 0,city:void 0,country:void 0,latitude:void 0,longitude:void 0,street:void 0,zip:void 0,source:void 0};break;case"repo":c={platform:b,owner_name:void 0,owner_id:void 0,owner_link:void 0,owner_img_url:void 0,name:void 0,id:void 0,fullname:void 0,description:void 0,url:void 0,homepage:void 0,language:void 0,clone_url:void 0,git_url:void 0,ssh_url:void 0,svn_url:void 0,isFork:void 0,openIssues:void 0,watchers:void 0,stargazers:void 0,forks:void 0,created_timestamp:void 0,created_date_time:void 0,updated_timestamp:void 0,updated_date_time:void 0,pushed_timestamp:void 0,pushed_date_time:void 0};break;case"activity":c={platform:b,body:void 0,actor_name:void 0,actor_id:void 0,actor_url:void 0,actor_img_url:void 0,actor_type:void 0,action_name:void 0,action_message:void 0,action_id:void 0,action_url:void 0,action_img:void 0,action_type:void 0,object_name:void 0,object_id:void 0,object_img:void 0,object_url:void 0,object_type:void 0,context:void 0,timestamp:void 0,date_time:void 0};break;case"weather":c={platform:b,weather_code:void 0,weather_caption:void 0,weather_text:void 0,weather_icon_name:void 0,weather_icon_url:void 0,temp:void 0,pressure:void 0,humidity:void 0,temp_min:void 0,temp_max:void 0,sea_level:void 0,grnd_level:void 0,wind_speed:void 0,wind_deg:void 0,rain_duration:void 0,rain_volume:void 0,clouds:void 0,timestamp:void 0,date_time:void 0,sunrise_timestamp:void 0,sunrise_date_time:void 0,sunset_timestamp:void 0,sunset_date_time:void 0,loc_city:void 0,loc_city_id:void 0,loc_country:void 0,loc_lat:void 0,loc_lng:void 0,loc_zip:void 0}}return c}}]),apingApp.directive("imagesLoaded",["$timeout","$rootScope","$q",function(a,b,c){function d(b){a(b,0)}function e(a,b,c){this.loaded=void 0,this.loading=!0,c?this.__onload(b,!0):(this.node=new Image,this.bind(b),this.node.src=a)}function f(a){this.imagesCount=0,this.imagesLoaded=0,this.imagesFailed=0,this.useProgressEvents=a}var g={},h={progress:["imagesLoaded.QUARTER","imagesLoaded.HALF","imagesLoaded.THREEQUARTERS","imagesLoaded.FULL"],successful:"imagesLoaded.SUCCESS",complete:"imagesLoaded.FAIL",always:"imagesLoaded.ALWAYS"};return e.prototype={constructor:e,bind:function(a){var b=this;this.node.addEventListener("load",function(){b.__onload(a,!0)},!1),this.node.addEventListener("error",function(){b.__onload(a,!1)},!1)},__onload:function(a,b){this.loaded=!0,this.loading=!1,b&&this.node&&delete this.node,a(b)}},f.prototype={constructor:f,whenImagesLoaded:function(a){function b(a){var b;a?l.imagesLoaded++:l.imagesFailed++,l.useProgressEvents&&(b=(l.imagesLoaded+l.imagesFailed)/Math.ceil(k/4))&&b%1===0&&4>b&&d(function(){j.notify(h.progress[b-1])}),l.imagesLoaded+l.imagesFailed===l.imagesCount&&d(function(){j.notify(h.progress[3]),j.resolve(l.imagesFailed>0?h.complete:h.success)})}function f(a){var c=a.src,d=g[c];d?d.loaded?b(!0):d.loading?d.bind(b):d.loaded===!1:a.complete&&a.naturalWidth>0?g[c]=new e(c,b,!0):g[c]=new e(c,b)}var i,j=c.defer(),k=a.length,l=this;this.imagesCount=k;for(var m=0;m-1&&c.results.length>d.maxItems&&(c.results=c.results.splice(0,d.maxItems)),c.$broadcast("apiNG.resultMerged")},this.apply=function(){c.$apply()}}],templateUrl:function(b,c){return c.templateUrl||a.templateUrl}}}]);apingApp.service("apingTimeHelper",function(){this.getTimestampFromDateString=function(a,b,c){if(("undefined"==typeof b||isNaN(b))&&(b=1),("undefined"==typeof c||isNaN(c))&&(c=0),"string"==typeof a){var d=a.split(/[^0-9]/);try{return parseInt(Math.round(new Date(d[0],d[1]-1,d[2],d[3],d[4],d[5])/1e3*b)+c,10)}catch(e){return 0}}return 0}}).service("apingUtilityHelper",["apingInputObjects","apingDefaultSettings",function(a,b){this.getApiCredentials=function(a,c){return b.apingApiKeys&&b.apingApiKeys[a]?b.apingApiKeys[a][Math.floor(Math.random()*b.apingApiKeys[a].length)][c]:!1},this.parseJsonFromAttributes=function(a,b,c){return this.parseRequestsFromAttributes(a,b,c)},this.parseRequestsFromAttributes=function(b,c,d){if("string"!=typeof b||!b)return[];var e=[],f=this.replaceSingleQuotesAndParseJson(b);return angular.forEach(f,function(b,f){b.platform=c,d&&("undefined"==typeof b.items&&"undefined"!=typeof d.items&&(b.items=d.items),"undefined"==typeof b.model&&"undefined"!=typeof d.model&&(b.model=d.model));var g=a.getNew("request",b);e.push(g)}),e},this.replaceSingleQuotesAndParseJson=function(a){return $.parseJSON(a.replace(/'/g,'"'))},this.sortArrayByProperty=function(a){var b=1;return"-"===a[0]&&(b=-1,a=a.substr(1)),function(c,d){var e=c[a]d[a]?1:0;return e*b}},this.shuffleArray=function(a){for(var b=a.length-1;b>0;b--){var c=Math.floor(Math.random()*(b+1)),d=a[b];a[b]=a[c],a[c]=d}return a},this.removeDuplicateObjectsFromArray=function(a,b){var c=[],d="apingStringified",e="apingTempOrder";if(1===a.length)return a;$.each(a,function(a,f){f.$$hashKey=void 0,f[d]=JSON.stringify(f),b===!0&&(f[e]=a),c.push(f)}),c.sort(this.sortArrayByProperty(d));var f,g=[];return $.each(c,function(a,b){"undefined"!=typeof f?"undefined"!=typeof b[d]&&b[d]!==f&&g.push(b):g.push(b),f=b[d],b[d]=void 0}),b===!0&&(c.sort(this.sortArrayByProperty(e)),$.each(c,function(a,b){b[e]=void 0})),g},this.getTextFromHtml=function(a){return a=a.replace(/<br ?\/\>|<br ?\/&rt;|\
/g," "),a=a.replace(/<(?:.|\n)*?>/gm,"")},this.getFirstImageFromHtml=function(a){var b=/]+src="([^">]+)/g;return b.exec(a)},this.parseParametersFromUrl=function(a){var b={};return"string"==typeof a&&(b=JSON.parse('{"'+decodeURI(a.replace(/&/g,'","').replace(/=/g,'":"'))+'"}')),b}}]),apingApp.service("apingInputObjects",["apingDefaultSettings",function(a){this.getNew=function(b,c){var d={};switch(b){case"request":d=$.extend(!0,{model:a.model,items:a.items},c)}return d}}]),apingApp.service("apingModels",[function(){this.getNew=function(a,b){var c={};switch(a){case"social":c={platform:b,blog_name:void 0,blog_id:void 0,blog_link:void 0,type:void 0,timestamp:void 0,date_time:void 0,post_url:void 0,intern_id:void 0,text:void 0,caption:void 0,img_url:void 0,source:void 0,likes:void 0,shares:void 0,comments:void 0,position:void 0};break;case"video":c={platform:b,blog_name:void 0,blog_id:void 0,blog_link:void 0,timestamp:void 0,date_time:void 0,post_url:void 0,intern_id:void 0,text:void 0,caption:void 0,img_url:void 0,source:void 0,markup:void 0,likes:void 0,shares:void 0,duration:void 0,width:void 0,height:void 0,comments:void 0,position:void 0};break;case"image":c={platform:b,blog_name:void 0,blog_id:void 0,blog_link:void 0,timestamp:void 0,date_time:void 0,post_url:void 0,intern_id:void 0,text:void 0,caption:void 0,thumb_url:void 0,thumb_width:void 0,thumb_height:void 0,img_url:void 0,img_width:void 0,img_height:void 0,native_url:void 0,native_width:void 0,native_height:void 0,source:void 0,likes:void 0,shares:void 0,comments:void 0,position:void 0};break;case"event":c={platform:b,artist_name:void 0,artist_id:void 0,artist_link:void 0,start_timestamp:void 0,start_date_time:void 0,end_timestamp:void 0,end_date_time:void 0,event_url:void 0,ticket_url:void 0,sold_out:void 0,intern_id:void 0,text:void 0,caption:void 0,img_url:void 0,place_name:void 0,city:void 0,country:void 0,latitude:void 0,longitude:void 0,street:void 0,zip:void 0,source:void 0};break;case"repo":c={platform:b,owner_name:void 0,owner_id:void 0,owner_link:void 0,owner_img_url:void 0,name:void 0,id:void 0,fullname:void 0,description:void 0,url:void 0,homepage:void 0,language:void 0,clone_url:void 0,git_url:void 0,ssh_url:void 0,svn_url:void 0,isFork:void 0,openIssues:void 0,watchers:void 0,stargazers:void 0,forks:void 0,created_timestamp:void 0,created_date_time:void 0,updated_timestamp:void 0,updated_date_time:void 0,pushed_timestamp:void 0,pushed_date_time:void 0};break;case"activity":c={platform:b,body:void 0,actor_name:void 0,actor_id:void 0,actor_url:void 0,actor_img_url:void 0,actor_type:void 0,action_name:void 0,action_message:void 0,action_id:void 0,action_url:void 0,action_img:void 0,action_type:void 0,object_name:void 0,object_id:void 0,object_img:void 0,object_url:void 0,object_type:void 0,context:void 0,timestamp:void 0,date_time:void 0};break;case"weather":c={platform:b,weather_code:void 0,weather_caption:void 0,weather_text:void 0,weather_icon_name:void 0,weather_icon_url:void 0,temp:void 0,pressure:void 0,humidity:void 0,temp_min:void 0,temp_max:void 0,sea_level:void 0,grnd_level:void 0,wind_speed:void 0,wind_deg:void 0,rain_duration:void 0,rain_volume:void 0,clouds:void 0,timestamp:void 0,date_time:void 0,sunrise_timestamp:void 0,sunrise_date_time:void 0,sunset_timestamp:void 0,sunset_date_time:void 0,loc_city:void 0,loc_city_id:void 0,loc_country:void 0,loc_lat:void 0,loc_lng:void 0,loc_zip:void 0}}return c}}]),angular.module("jtt_aping_jsonloader",[]).directive("apingJsonloader",["apingUtilityHelper","jsonloaderFactory",function(a,b){return{require:"?aping",restrict:"A",replace:"false",link:function(c,d,e,f){var g=f.getAppSettings(),h=a.parseJsonFromAttributes(e.apingJsonloader,"jsonloader",g);h.forEach(function(a){if(a.path){var c={path:a.path};a.format&&"jsonp"==a.format.toLowerCase()?c.format="jsonp":c.format="json",a.callback&&"jsonp"===a.format?c.callback=a.callback:c.callback="JSON_CALLBACK",b.getJsonData(c).then(function(b){var c=[];b.data&&(b.data.constructor!==Array?c.push(b.data):a.items<0?c=b.data:angular.forEach(b.data,function(b,d){d0&&e.concatToResults(c)}})}}}]); \ No newline at end of file diff --git a/package.json b/package.json index 80c9aaf..b4a4b96 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "aping", - "version": "0.7.0", + "version": "0.8.0", "description": "apiNG is an AngularJS platform for getting some data from REST APIs and displays it in various designs (templates)", - "main": "Gruntfile.js", + "main": "dist/aping.min.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, diff --git a/src/aping-config.js b/src/aping-config.js index b7b4553..6bcc6cc 100644 --- a/src/aping-config.js +++ b/src/aping-config.js @@ -1,42 +1,42 @@ "use strict"; apingApp.config(['$provide', function ($provide) { - $provide.constant("apingApiKeys", { - youtube : [ - {'apiKey':''} - ], - instagram: [ - {'access_token':''} - ], - facebook: [ - {'access_token':''} - ], - twitter: [ - {'bearer_token':''} - ], - vimeo: [ - {'access_token':''} - ], - 'tumblr': [ - {'api_key':''} - ], - github: [ - {'access_token':''} - ], - 'openweathermap': [ - {'api_key':''} - ] - }); + $provide.value("apingDefaultSettings", { + //templateUrl: "", + //items: 20, //items per request + //maxItems: 100, //max items per aping + //orderBy: "timestamp", + //orderReverse: "true", + //model: "social", + //getNativeData: false, + //removeDoubles: false, + apingApiKeys: { + youtube: [ + {'apiKey': ''} + ], + instagram: [ + {'access_token': ''} + ], + facebook: [ + {'access_token': ''} + ], + twitter: [ + {'bearer_token': ''} + ], + vimeo: [ + {'access_token': ''} + ], + 'tumblr': [ + {'api_key': ''} + ], + github: [ + {'access_token': ''} + ], + 'openweathermap': [ + {'api_key': ''} + ] + } - $provide.constant("apingDefaultSettings", { - templateUrl : "", - items : 20, //items per request - maxItems: 100, //max items per aping - orderBy : "timestamp", - orderReverse : "true", - model: "social", - getNativeData: false, - removeDoubles: false }); }]); \ No newline at end of file diff --git a/src/aping-designHelpers.js b/src/aping-designHelpers.js deleted file mode 100644 index 744096f..0000000 --- a/src/aping-designHelpers.js +++ /dev/null @@ -1,194 +0,0 @@ -"use strict"; - -/** - * this directive "imagesLoaded" is just a custom version of https://github.com/bimal1331/angular-images-loaded - */ - -apingApp.directive('imagesLoaded', ['$timeout', '$rootScope', '$q', function($timeout, $rootScope, $q) { - - var cache = {}; - - var broadcastMessages = { - progress : ['imagesLoaded.QUARTER', 'imagesLoaded.HALF', 'imagesLoaded.THREEQUARTERS', 'imagesLoaded.FULL'], - successful : 'imagesLoaded.SUCCESS', - complete : 'imagesLoaded.FAIL', - always : 'imagesLoaded.ALWAYS' - }; - - /************* Helper functions **********/ - function digestPromise(func) { - $timeout(func, 0); - } - - /*********** Constructors ************/ - function ImageNode(src, func, inBrowserCache) { - this.loaded = undefined; - this.loading = true; - - if(!inBrowserCache) { - this.node = new Image(); - this.bind(func); - this.node.src = src; - } - else { - this.__onload(func, true); - } - - } - - ImageNode.prototype = { - constructor : ImageNode, - - bind : function(func) { - var _this = this; - this.node.addEventListener('load', function() { _this.__onload(func, true) }, false); - this.node.addEventListener('error', function() { _this.__onload(func, false) }, false); - }, - - __onload : function(func, success) { - this.loaded = true; - this.loading = false; - - if(success && this.node) { - delete this.node; - } - - func(success); - } - }; - - function ImagesCollection(useProgressEvents) { - this.imagesCount = 0; - this.imagesLoaded = 0; - this.imagesFailed = 0; - this.useProgressEvents = useProgressEvents; - } - - ImagesCollection.prototype = { - constructor : ImagesCollection, - - whenImagesLoaded : function(imageNodes) { - var defer = $q.defer(), - totalImages = imageNodes.length, - _this = this, - imgElem, proxyImage; - - this.imagesCount = totalImages; - - for(var i = 0; i < this.imagesCount; i++) { - imgElem = imageNodes[i]; - - check(imgElem); - } - - function increment(bool) { - var progress; - - if(bool) { - _this.imagesLoaded++; - } - else { - _this.imagesFailed++; - } - - if(_this.useProgressEvents && (progress = (_this.imagesLoaded + _this.imagesFailed)/Math.ceil(totalImages/4)) && (progress % 1 === 0) && progress < 4) { - digestPromise(function() { - defer.notify(broadcastMessages.progress[progress-1]); - }); - } - - if(_this.imagesLoaded + _this.imagesFailed === _this.imagesCount) { - digestPromise(function() { - defer.notify(broadcastMessages.progress[3]); - defer.resolve((_this.imagesFailed > 0) ? broadcastMessages.complete : broadcastMessages.success); - }); - } - - } - - function check(img) { - var source = img.src, - cachedElement = cache[source], - proxyImage; - - if(cachedElement ) { - - if(cachedElement.loaded) { - //Image is in local cache and is loaded - increment(true); - } - else if(cachedElement.loading) { - //Image is currently being loaded and it's being checked again before successful load, so we wait for the image to load - cachedElement.bind(increment); - } - else if(cachedElement.loaded === false) { - // cachedElement.bind(increment); - // cachedElement.node.src = source; - } - - } - else if(img.complete && img.naturalWidth > 0) { - //Image is not in local cache but is present in browser's cache - cache[source] = new ImageNode(source, increment, true); - } - else { - //Image has not been loaded before, so we make a proxy image element and attach load listeners to it - cache[source] = new ImageNode(source, increment); - - } - } - return defer.promise; - } - }; - - //Directive configuration object - return { - restrict : 'A', - compile: function(tElem, tAttrs) { - - return function($scope, $element, $attrs) { - - var descendents = $element[0].childNodes, - useProgressEvents = $attrs.useProgressEvents === 'yes', - oldImageNodesCount = 0, - documentImages = document.images, - imageNodes; - - $scope.$watch( - function() { - return documentImages.length; - }, - function(newVal, oldVal) { - - var newImageNodesCount, collection; - - if(newVal === oldVal) return; - - imageNodes = $element.find('img'); - newImageNodesCount = imageNodes.length; - - if(newImageNodesCount === oldImageNodesCount) return; - oldImageNodesCount = newImageNodesCount; - - collection = new ImagesCollection(useProgressEvents); - - digestPromise(function() { - collection.whenImagesLoaded(imageNodes).then( - function(data) { - $scope.$emit(data); - $scope.$emit(broadcastMessages.always); - }, - function(error) { - - }, - function(progress) { - useProgressEvents && $scope.$emit('imagesLoaded.PROGRESS', {status : progress}); - } - ); - }); - } - ); - } - } - } -}]); \ No newline at end of file diff --git a/src/aping-directive.js b/src/aping-directive.js index f832528..3c28192 100644 --- a/src/aping-directive.js +++ b/src/aping-directive.js @@ -1,5 +1,14 @@ "use strict"; -var apingApp = angular.module('jtt_aping', []) +var apingApp = angular.module('jtt_aping', ['jtt_aping_jsonloader', 'jtt_aping_ng_array']) + + .config(['$provide', function ($provide) { + + $provide.value("apingDefaultSettings", { + apingApiKeys: {} + }); + + + }]) .directive('aping', ['apingDefaultSettings', 'apingUtilityHelper', function (apingDefaultSettings, apingUtilityHelper) { return { restrict: 'E', @@ -29,43 +38,60 @@ var apingApp = angular.module('jtt_aping', []) var maxItems; var getNativeData; var orderReverse; + var orderBy; var removeDoubles; - if(typeof $scope.items !== "undefined") { + if (typeof $scope.items !== "undefined") { items = $scope.items; - } else if(typeof apingDefaultSettings.items !== "undefined") { + } else if (typeof apingDefaultSettings.items !== "undefined") { items = apingDefaultSettings.items; } else { - items = 20; + items = undefined; } - if(typeof $scope.maxItems !== "undefined") { + if (typeof $scope.maxItems !== "undefined") { maxItems = $scope.maxItems; - } else if(typeof apingDefaultSettings.maxItems !== "undefined") { + } else if (typeof apingDefaultSettings.maxItems !== "undefined") { maxItems = apingDefaultSettings.maxItems; } else { - maxItems = -1; + maxItems = undefined; } - if(typeof $scope.getNativeData !== "undefined") { + if (typeof $scope.getNativeData !== "undefined") { getNativeData = $scope.getNativeData; - } else if(typeof apingDefaultSettings.getNativeData !== "undefined") { + } else if (typeof apingDefaultSettings.getNativeData !== "undefined") { getNativeData = apingDefaultSettings.getNativeData; } else { getNativeData = false; } - if(typeof $scope.orderReverse !== "undefined") { + if (typeof $scope.maxItems !== "undefined") { + maxItems = $scope.maxItems; + } else if (typeof apingDefaultSettings.maxItems !== "undefined") { + maxItems = apingDefaultSettings.maxItems; + } else { + maxItems = undefined; + } + + if (typeof $scope.orderBy !== "undefined") { + orderBy = $scope.orderBy; + } else if (typeof apingDefaultSettings.orderBy !== "undefined") { + orderBy = apingDefaultSettings.orderBy; + } else { + orderBy = "undefined"; + } + + if (typeof $scope.orderReverse !== "undefined") { orderReverse = $scope.orderReverse; - } else if(typeof apingDefaultSettings.orderReverse !== "undefined") { + } else if (typeof apingDefaultSettings.orderReverse !== "undefined") { orderReverse = apingDefaultSettings.orderReverse; } else { orderReverse = false; } - if(typeof $scope.removeDoubles !== "undefined") { + if (typeof $scope.removeDoubles !== "undefined") { removeDoubles = $scope.removeDoubles; - } else if(typeof apingDefaultSettings.removeDoubles !== "undefined") { + } else if (typeof apingDefaultSettings.removeDoubles !== "undefined") { removeDoubles = apingDefaultSettings.removeDoubles; } else { removeDoubles = false; @@ -73,10 +99,10 @@ var apingApp = angular.module('jtt_aping', []) return { model: $scope.model || apingDefaultSettings.model || "native", - getNativeData : getNativeData, + getNativeData: getNativeData, items: items, maxItems: maxItems, - orderBy: $scope.orderBy || apingDefaultSettings.orderBy, + orderBy: orderBy, orderReverse: orderReverse, removeDoubles: removeDoubles }; @@ -92,22 +118,22 @@ var apingApp = angular.module('jtt_aping', []) var appSettings = this.getAppSettings(); - if(appSettings.removeDoubles === true || appSettings.removeDoubles === "true") { + if (appSettings.removeDoubles === true || appSettings.removeDoubles === "true") { $scope.results = apingUtilityHelper.removeDuplicateObjectsFromArray($scope.results, (appSettings.orderBy === false || appSettings.orderBy === "false" || appSettings.orderBy === "$NONE")); } - if(appSettings.orderBy !== false && appSettings.orderBy !== "false" && appSettings.orderBy !== "$NONE") { - if(appSettings.orderBy === "$RANDOM") { + if (appSettings.orderBy !== "undefined" && appSettings.orderBy !== false && appSettings.orderBy !== "false" && appSettings.orderBy !== "$NONE") { + if (appSettings.orderBy === "$RANDOM") { $scope.results = apingUtilityHelper.shuffleArray($scope.results); } else { $scope.results.sort(apingUtilityHelper.sortArrayByProperty(appSettings.orderBy)); - if(appSettings.orderReverse === true || appSettings.orderReverse === "true") { + if (appSettings.orderReverse === true || appSettings.orderReverse === "true") { $scope.results.reverse(); } } } - if(appSettings.maxItems > -1 && $scope.results.length > appSettings.maxItems) { - $scope.results = $scope.results.splice(0,appSettings.maxItems); + if (appSettings.maxItems > -1 && $scope.results.length > appSettings.maxItems) { + $scope.results = $scope.results.splice(0, appSettings.maxItems); } $scope.$broadcast('apiNG.resultMerged'); }; @@ -120,3 +146,4 @@ var apingApp = angular.module('jtt_aping', []) } }; }]); + diff --git a/src/aping-helpers.js b/src/aping-helpers.js index 54072ff..fd581de 100644 --- a/src/aping-helpers.js +++ b/src/aping-helpers.js @@ -31,7 +31,7 @@ apingApp return 0; }; }) - .service('apingUtilityHelper', ['apingInputObjects', 'apingApiKeys', function (apingInputObjects, apingApiKeys) { + .service('apingUtilityHelper', ['apingInputObjects', 'apingDefaultSettings', function (apingInputObjects, apingDefaultSettings) { /** * return random matching API Key from Constant "apingApiKeys". If there is no matching API Key, the function returns 'false' @@ -42,9 +42,9 @@ apingApp */ this.getApiCredentials = function (_platform, _keyName) { - if (apingApiKeys) { - if (apingApiKeys[_platform]) { - return apingApiKeys[_platform][Math.floor(Math.random() * apingApiKeys[_platform].length)][_keyName]; + if (apingDefaultSettings.apingApiKeys) { + if (apingDefaultSettings.apingApiKeys[_platform]) { + return apingDefaultSettings.apingApiKeys[_platform][Math.floor(Math.random() * apingDefaultSettings.apingApiKeys[_platform].length)][_keyName]; } } return false; diff --git a/src/aping-jsonloader-directive.js b/src/aping-jsonloader-directive.js new file mode 100644 index 0000000..0b680cc --- /dev/null +++ b/src/aping-jsonloader-directive.js @@ -0,0 +1,81 @@ +"use strict"; + +angular.module("jtt_aping_jsonloader", []) + .directive('apingJsonloader', ['apingUtilityHelper', 'jsonloaderFactory', function (apingUtilityHelper, jsonloaderFactory) { + return { + require: '?aping', + restrict: 'A', + replace: 'false', + link: function (scope, element, attrs, apingController) { + + var appSettings = apingController.getAppSettings(); + var requests = apingUtilityHelper.parseJsonFromAttributes(attrs.apingJsonloader, "jsonloader", appSettings); + + requests.forEach(function (request) { + + if (request.path) { + //create requestObject for factory function call + var requestObject = { + path: request.path, + }; + + if (!request.format || request.format.toLowerCase() != "jsonp") { + requestObject.format = "json"; + } else { + requestObject.format = "jsonp"; + } + + if (request.callback && request.format === "jsonp") { + requestObject.callback = request.callback; + } else { + requestObject.callback = 'JSON_CALLBACK'; + } + + jsonloaderFactory.getJsonData(requestObject) + .then(function (_data) { + var resultArray = []; + if (_data.data) { + if (_data.data.constructor !== Array) { + resultArray.push(_data.data); + } else { + if (request.items < 0) { + resultArray = _data.data; + } else { + angular.forEach(_data.data, function (value, key) { + if (key < request.items) { + resultArray.push(value); + } + }); + } + } + } + apingController.concatToResults(resultArray); + }); + } + }); + } + } + }]) + .factory('jsonloaderFactory', ['$http', function ($http) { + var jsonloaderFactory = {}; + + jsonloaderFactory.getJsonData = function (_requestObject) { + if (_requestObject.format == "jsonp") { + + return $http.jsonp( + _requestObject.path, + { + method: 'GET', + params: {callback: _requestObject.callback}, + } + ); + + } else { + return $http({ + method: 'GET', + url: _requestObject.path + }); + } + }; + return jsonloaderFactory; + }]); \ No newline at end of file diff --git a/src/aping-ng-array-directive.js b/src/aping-ng-array-directive.js new file mode 100644 index 0000000..06ba66f --- /dev/null +++ b/src/aping-ng-array-directive.js @@ -0,0 +1,41 @@ +"use strict"; + +angular.module("jtt_aping_ng_array", []) + .directive('apingNgArray', ['apingUtilityHelper', function (apingUtilityHelper) { + return { + require: '?aping', + restrict: 'A', + replace: 'false', + link: function (scope, element, attrs, apingController) { + + var appSettings = apingController.getAppSettings(); + var requests = apingUtilityHelper.parseJsonFromAttributes(attrs.apingNgArray, "ngArray", appSettings); + + requests.forEach(function (request) { + + if (request.name && scope[request.name]) { + + var resultArray = []; + + if (scope[request.name].constructor === Array) { + if (request.items < 0) { + resultArray = scope[request.name]; + } else { + angular.forEach(scope[request.name], function (value, key) { + if (key < request.items) { + resultArray.push(value); + } + }); + } + } else if (typeof scope[request.name] === 'object' && scope[request.name] !== null) { + resultArray.push(scope[request.name]); + } + + if (resultArray.length > 0) { + apingController.concatToResults(resultArray); + } + } + }); + } + } + }]); \ No newline at end of file