├── .gitignore ├── src ├── index.js ├── Meta.js ├── MetaService.js └── MetaDirective.js ├── lib ├── index.js.map ├── index.js ├── Meta.js ├── Meta.js.map ├── MetaDirective.js ├── MetaDirective.js.map ├── MetaService.js.map └── MetaService.js ├── Makefile ├── .travis.yml ├── package.json ├── LICENSE ├── README.md ├── test └── tests.js └── dist ├── fd-angular-meta.js └── fd-angular-meta.js.map /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import './MetaService'; 2 | import './MetaDirective'; 3 | export {Meta} from './Meta'; 4 | -------------------------------------------------------------------------------- /lib/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../src/index.js"],"names":[],"mappings":";;;;;;QAAO,eAAe;;QACf,iBAAiB;;oBACL,QAAQ;;;;;iBAAnB,IAAI","file":"index.js","sourcesContent":["import './MetaService';\nimport './MetaDirective';\nexport {Meta} from './Meta';\n"]} -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { 4 | value: true 5 | }); 6 | 7 | require('./MetaService'); 8 | 9 | require('./MetaDirective'); 10 | 11 | var _Meta = require('./Meta'); 12 | 13 | Object.defineProperty(exports, 'Meta', { 14 | enumerable: true, 15 | get: function get() { 16 | return _Meta.Meta; 17 | } 18 | }); 19 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /src/Meta.js: -------------------------------------------------------------------------------- 1 | import {State} from 'fd-angular-core'; 2 | 3 | export function Meta(object, name, desc) { 4 | let func = desc.value; 5 | 6 | function pushMeta(Meta){ 7 | let args = Array.prototype.slice.call(arguments, 1); 8 | Meta.push(func.apply(this, args)); 9 | } 10 | pushMeta.$inject = ['Meta'].concat((func && func.$inject) || []); 11 | State.onAttach(object, 'pushMeta', { value: pushMeta }); 12 | 13 | function popMeta(Meta) { 14 | Meta.pop(); 15 | } 16 | popMeta.$inject = ['Meta']; 17 | State.onDetach(object, 'popMeta', { value: popMeta }); 18 | } 19 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SRC_FILES = $(shell find src -name '*.js') 2 | LIB_FILES = $(patsubst src/%.js, lib/%.js, $(SRC_FILES)) 3 | 4 | all: lib dist 5 | 6 | clean: 7 | rm -r lib dist 8 | 9 | lib: $(SRC_FILES) 10 | babel --out-dir=lib --source-maps=true --module=umdStrict --stage=0 src 11 | @touch lib 12 | 13 | dist: lib $(LIB_FILES) 14 | @mkdir -p dist 15 | browserify lib/index.js -o dist/fd-angular-meta.raw.js --standalone=FdAngularMeta --extension=js --debug \ 16 | --exclude fd-angular-core 17 | cat dist/fd-angular-meta.raw.js | exorcist dist/fd-angular-meta.js.map > dist/fd-angular-meta.js 18 | rm dist/fd-angular-meta.raw.js 19 | @touch dist 20 | 21 | .PHONEY: all clean 22 | -------------------------------------------------------------------------------- /lib/Meta.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { 4 | value: true 5 | }); 6 | exports.Meta = Meta; 7 | 8 | var _fdAngularCore = require('fd-angular-core'); 9 | 10 | function Meta(object, name, desc) { 11 | var func = desc.value; 12 | 13 | function pushMeta(Meta) { 14 | var args = Array.prototype.slice.call(arguments, 1); 15 | Meta.push(func.apply(this, args)); 16 | } 17 | pushMeta.$inject = ['Meta'].concat(func && func.$inject || []); 18 | _fdAngularCore.State.onAttach(object, 'pushMeta', { value: pushMeta }); 19 | 20 | function popMeta(Meta) { 21 | Meta.pop(); 22 | } 23 | popMeta.$inject = ['Meta']; 24 | _fdAngularCore.State.onDetach(object, 'popMeta', { value: popMeta }); 25 | } 26 | //# sourceMappingURL=Meta.js.map -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '0.12' 4 | deploy: 5 | provider: npm 6 | email: simon.menke@gmail.com 7 | api_key: 8 | secure: 00NpwGy78PhulJxH5RTy79MYf8Hjdc8P6PppQRHveoxpA7xGAviOvaZXLZnrkDxHEUpYl3i7p6ZQf1bkryGt8gMCDRkEReVwmYIEUX3rbq//XZhT+o1Oc5xPywRiI8xM8TY8sqSBrmx/3qabqhHvbvfkbxL+XQA5U2TvKGHg1dX3TN6PFsMW60YZ7/1uIX1GRwgnLU3ksEEOUGb1n7BBV4ZXii9lkhQgOVf9zl+Byb5+7Z5of6DfoyN9LPlCUkHPpKTKInWEsNmnZGS09Jv+Q9MJmeoub9QAYKt7Qczf6skVg57T1Qdham4mxhQLLWieTh8JBUzHo3dD8PmQsX9UcrsHtQvATiEJPeJTeYZvO364QvldsKd+QpUcGxYQNQDl3jGkYzR+rJldsl2S/r8T6771VRw36+kCX/yOEeA1QltThLaqL28VUfYw6xR7JCH1GwXOIZA8T+p/r6hYrfgV5JWX3/YQEd0AVjEdORxB1ATAXO2DbfIEfHT42hfe5fAzvCGZHgBcMZALV+YCgoe8Hu56Xout8SSQ8kEFr8np3CUt3b96FEkGM9sgYpfdcQVjtdnseXA3LlLX4oTCtx+uugpcz2G4cdG3RqGQUhd6ULewmKNh/by0/ieTySN1wzqfZupMsSaeM9+VH0rCUwfHyakn53MYzsnI4K9g0zCe0D4= 9 | on: 10 | tags: true 11 | repo: fd/fd-angular-meta 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fd-angular-meta", 3 | "version": "1.1.0", 4 | "description": "Personal package for handling page meta data", 5 | "repository": "https://github.com/fd/fd-angular-meta.git", 6 | "main": "lib/index.js", 7 | "scripts": { 8 | "test": "echo 'No tests...'", 9 | "build": "make" 10 | }, 11 | "keywords": [ 12 | "utils", 13 | "angular" 14 | ], 15 | "author": "Simon Menke", 16 | "license": "MIT", 17 | "devDependencies": { 18 | "babel": "^5.4.7", 19 | "babel-eslint": "^4.0.5", 20 | "browserify": "^10.2.3", 21 | "eslint": "^0.24.1", 22 | "exorcist": "^0.4.0" 23 | }, 24 | "dependencies": { 25 | "fd-angular-core": "1.x.x" 26 | }, 27 | "jspm": { 28 | "jspmNodeConversion": false, 29 | "format": "es6", 30 | "main": "src/index.js", 31 | "dependencies": { 32 | "fd-angular-core": "npm:fd-angular-core" 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Simon Menke 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /lib/Meta.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../src/Meta.js"],"names":[],"mappings":";;;;;;;6BAAoB,iBAAiB;;AAE9B,SAAS,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE;AACxC,KAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;;AAEtB,UAAS,QAAQ,CAAC,IAAI,EAAC;AACtB,MAAI,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;AACpD,MAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;EAClC;AACD,SAAQ,CAAC,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,AAAC,IAAI,IAAI,IAAI,CAAC,OAAO,IAAK,EAAE,CAAC,CAAC;AACjE,sBAAM,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;;AAExD,UAAS,OAAO,CAAC,IAAI,EAAE;AACtB,MAAI,CAAC,GAAG,EAAE,CAAC;EACX;AACD,QAAO,CAAC,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC;AAC3B,sBAAM,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;CACtD","file":"Meta.js","sourcesContent":["import {State} from 'fd-angular-core';\n\nexport function Meta(object, name, desc) {\n\tlet func = desc.value;\n\n\tfunction pushMeta(Meta){\n\t\tlet args = Array.prototype.slice.call(arguments, 1);\n\t\tMeta.push(func.apply(this, args));\n\t}\n\tpushMeta.$inject = ['Meta'].concat((func && func.$inject) || []);\n\tState.onAttach(object, 'pushMeta', { value: pushMeta });\n\n\tfunction popMeta(Meta) {\n\t\tMeta.pop();\n\t}\n\tpopMeta.$inject = ['Meta'];\n\tState.onDetach(object, 'popMeta', { value: popMeta });\n}\n"]} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # `fd-angular-meta` 2 | 3 | [![Build Status](https://travis-ci.org/fd/fd-angular-meta.svg?branch=master)](https://travis-ci.org/fd/fd-angular-meta) 4 | 5 | ## Getting started 6 | 7 | ```js 8 | import {bootstrap, State, Inject} from 'npm:fd-angular-core'; 9 | import {Meta} 'npm:fd-angular-meta'; 10 | 11 | @State({ 12 | template: `

{{ app.message }}

` 13 | }) 14 | class AppController { 15 | 16 | constructor() { 17 | this.message = "Hello world!"; 18 | } 19 | 20 | @Meta 21 | @Inject('$location') 22 | pushMeta($location) { 23 | return { 24 | url: $location.url(), 25 | description: this.message 26 | }; 27 | } 28 | 29 | } 30 | 31 | bootstrap(AppController); // => Promise 32 | ``` 33 | 34 | 35 | ```html 36 | 37 | 38 | My Website 39 | 40 | ``` 41 | 42 | 43 | ## Options 44 | 45 | * **url** The cannonical url to the current page (defaults to `$location.absUrl()`) 46 | * **image** Link to an image 47 | * **title** Title of the current page. 48 | * **author** Author of the current page. 49 | * **publisher** Publisher of the current page. 50 | * **copyright** Copyright holder of the current page. 51 | * **description** Description of the current page. 52 | * **siteName** Name of the website 53 | * **type** og:type (defaults to `"website"`) 54 | * **twitterHandle** for the the twitter card. 55 | * **status** of the current page (default to `200`) 56 | * **distribution** of the current page (default to `global`) 57 | * **revisit-after** of the current page (default to `7` days) 58 | -------------------------------------------------------------------------------- /lib/MetaDirective.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var _fdAngularCore = require('fd-angular-core'); 4 | 5 | _fdAngularCore.app.directive('fdMeta', ['$compile', function ($compile) { 6 | return { 7 | restrict: 'A', 8 | link: function link($scope, $element) { 9 | var elems = $compile(TMPL)($scope); 10 | $element.find('title').remove(); 11 | $element.prepend(elems); 12 | } 13 | }; 14 | }]); 15 | 16 | var TMPL = '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n'; 17 | //# sourceMappingURL=MetaDirective.js.map -------------------------------------------------------------------------------- /src/MetaService.js: -------------------------------------------------------------------------------- 1 | import {Service, Inject} from 'fd-angular-core'; 2 | 3 | let defaults = { 4 | type: 'website', 5 | status: 200, 6 | distribution: 'global', 7 | revisitAfter: 7, 8 | } 9 | 10 | @Service('Meta') 11 | @Inject('$rootScope', '$location') 12 | class MetaService { 13 | 14 | stack = []; 15 | top = null; 16 | 17 | mappings = {}; 18 | 19 | constructor($rootScope, $location) { 20 | this.$rootScope = $rootScope; 21 | this.$location = $location; 22 | 23 | this.push({}); 24 | } 25 | 26 | push(data) { 27 | let top = this.top; 28 | let loc = this.$location; 29 | let entry = {}; 30 | 31 | // normalize 32 | if (!data.url) { data.url = loc.absUrl(); } 33 | if (data.image) { data.image = toAbsUrl(data.image); } 34 | if (data.url) { data.url = toAbsUrl(data.url); } 35 | 36 | data.author = (data.author || data.copyright || data.publisher); 37 | data.copyright = (data.copyright || data.author || data.publisher); 38 | data.publisher = (data.publisher || data.author || data.copyright); 39 | 40 | // inherit from top 41 | if (top) { 42 | Object.assign(entry, top); 43 | } 44 | 45 | // assign data 46 | for (let key of Object.keys(data)) { 47 | if (data[key] !== undefined) { 48 | entry[key] = data[key]; 49 | } 50 | } 51 | 52 | // apply defaults 53 | for (let key of Object.keys(defaults)) { 54 | if (entry[key] === undefined) { 55 | entry[key] = defaults[key]; 56 | } 57 | } 58 | 59 | this.stack.push(entry); 60 | this.top = entry; 61 | this.$rootScope.meta = this.top; 62 | } 63 | 64 | pop(data) { 65 | this.stack.pop(); 66 | this.top = this.stack[this.stack.length-1]; 67 | this.$rootScope.meta = this.top; 68 | } 69 | 70 | } 71 | 72 | function toAbsUrl(url) { 73 | if (!url) { 74 | return null; 75 | } 76 | 77 | if (url.indexOf('http') === 0) { 78 | return url; 79 | } 80 | 81 | if (url.indexOf('//') === 0) { 82 | return `${window.location.protocol}${url}`; 83 | } 84 | 85 | if (url.indexOf('/') === 0) { 86 | return `${window.location.protocol}//${window.location.host}${url}`; 87 | } 88 | 89 | return `${window.location.protocol}//${window.location.host}/${url}`; 90 | } 91 | -------------------------------------------------------------------------------- /src/MetaDirective.js: -------------------------------------------------------------------------------- 1 | import {app} from 'fd-angular-core'; 2 | 3 | app.directive('fdMeta', ['$compile', function($compile) { 4 | return { 5 | restrict: 'A', 6 | link: function($scope, $element) { 7 | let elems = $compile(TMPL)($scope); 8 | $element.find('title').remove(); 9 | $element.prepend(elems); 10 | } 11 | }; 12 | }]); 13 | 14 | const TMPL = ` 15 | 16 | 17 | 20 | 23 | 26 | 29 | 32 | 35 | 36 | 37 | 38 | 39 | 42 | 45 | 48 | 51 | 54 | 57 | 60 | 61 | 64 | 67 | 70 | 73 | 76 | 77 | `; 78 | -------------------------------------------------------------------------------- /lib/MetaDirective.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../src/MetaDirective.js"],"names":[],"mappings":";;6BAAkB,iBAAiB;;AAEnC,mBAAI,SAAS,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAS,QAAQ,EAAE;AACvD,QAAO;AACN,UAAQ,EAAE,GAAG;AACb,MAAI,EAAE,cAAS,MAAM,EAAE,QAAQ,EAAE;AAChC,OAAI,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;AACnC,WAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC;AAChC,WAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;GACxB;EACD,CAAC;CACF,CAAC,CAAC,CAAC;;AAEJ,IAAM,IAAI,quDA+DT,CAAC","file":"MetaDirective.js","sourcesContent":["import {app} from 'fd-angular-core';\n\napp.directive('fdMeta', ['$compile', function($compile) {\n\treturn {\n\t\trestrict: 'A',\n\t\tlink: function($scope, $element) {\n\t\t\tlet elems = $compile(TMPL)($scope);\n\t\t\t$element.find('title').remove();\n\t\t\t$element.prepend(elems);\n\t\t}\n\t};\n}]);\n\nconst TMPL = `\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n`;\n"]} -------------------------------------------------------------------------------- /test/tests.js: -------------------------------------------------------------------------------- 1 | var test = require('unit.js'); 2 | var Featherhead = require('../lib/index').Featherhead; 3 | 4 | describe('Featherhead', function() { 5 | var fh; 6 | 7 | before(function(){ 8 | fh = new Featherhead({ 9 | commit: "cbc88e4013f93e0b15f70e8fa8441a8921519e55", 10 | assets: "6a713fccf0bd691422ab91675fa005e1b052e45f" 11 | }); 12 | }); 13 | 14 | describe('.commit', function(){ 15 | 16 | it('should be set by the constructor', function() { 17 | test.object(fh) 18 | .hasOwnProperty('commit', 'cbc88e4013f93e0b15f70e8fa8441a8921519e55'); 19 | }); 20 | 21 | it('is required by the constructor', function() { 22 | test.exception(function() { new Featherhead({ assets: "6a713fccf0bd691422ab91675fa005e1b052e45f" }) }) 23 | .match('Featherhead: invalid commit option passed to constructor.'); 24 | }); 25 | 26 | }); 27 | 28 | describe('.assets', function(){ 29 | 30 | it('should be set by the constructor', function() { 31 | test.object(fh) 32 | .hasOwnProperty('assets', '6a713fccf0bd691422ab91675fa005e1b052e45f'); 33 | }); 34 | 35 | it('is required by the constructor', function() { 36 | test.exception(function() { new Featherhead({ commit: "cbc88e4013f93e0b15f70e8fa8441a8921519e55" }) }) 37 | .match('Featherhead: invalid assets option passed to constructor.'); 38 | }); 39 | 40 | }); 41 | 42 | describe('.assetURL()', function(){ 43 | 44 | it('works with relative paths', function() { 45 | test.string(fh.assetURL("path/to/file")) 46 | .is('/_asset/6a713fccf0bd691422ab91675fa005e1b052e45f/path/to/file'); 47 | }); 48 | 49 | it('works with absolute paths', function() { 50 | test.string(fh.assetURL("/path/to/file")) 51 | .is('/_asset/6a713fccf0bd691422ab91675fa005e1b052e45f/path/to/file'); 52 | }); 53 | 54 | }); 55 | 56 | describe('.dataURL()', function(){ 57 | 58 | it('works with relative paths', function() { 59 | test.string(fh.dataURL("path/to/file")) 60 | .is('/_data/fetch/cbc88e4013f93e0b15f70e8fa8441a8921519e55/path/to/file'); 61 | }); 62 | 63 | it('works with absolute paths', function() { 64 | test.string(fh.dataURL("/path/to/file")) 65 | .is('/_data/fetch/cbc88e4013f93e0b15f70e8fa8441a8921519e55/path/to/file'); 66 | }); 67 | 68 | it('strips .json', function() { 69 | test.string(fh.dataURL("/path/to/file.json")) 70 | .is('/_data/fetch/cbc88e4013f93e0b15f70e8fa8441a8921519e55/path/to/file'); 71 | }); 72 | 73 | }); 74 | 75 | 76 | describe('.commitURL()', function(){ 77 | 78 | it('always returns a single value', function() { 79 | test.string(fh.dataURL("path/to/file")) 80 | .is('/_data/commit'); 81 | }); 82 | 83 | }); 84 | }); 85 | -------------------------------------------------------------------------------- /lib/MetaService.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../src/MetaService.js"],"names":[],"mappings":"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","file":"MetaService.js","sourcesContent":["import {Service, Inject} from 'fd-angular-core';\n\nlet defaults = {\n\ttype: 'website',\n\tstatus: 200,\n\tdistribution: 'global',\n\trevisitAfter: 7,\n}\n\n@Service('Meta')\n@Inject('$rootScope', '$location')\nclass MetaService {\n\n\tstack = [];\n\ttop = null;\n\n\tmappings = {};\n\n\tconstructor($rootScope, $location) {\n\t\tthis.$rootScope = $rootScope;\n\t\tthis.$location = $location;\n\n\t\tthis.push({});\n\t}\n\n\tpush(data) {\n\t\tlet top = this.top;\n\t\tlet loc = this.$location;\n\t\tlet entry = {};\n\n\t\t// normalize\n\t\tif (!data.url) { data.url = loc.absUrl(); }\n\t\tif (data.image) { data.image = toAbsUrl(data.image); }\n\t\tif (data.url) { data.url = toAbsUrl(data.url); }\n\n\t\tdata.author = (data.author || data.copyright || data.publisher);\n\t\tdata.copyright = (data.copyright || data.author || data.publisher);\n\t\tdata.publisher = (data.publisher || data.author || data.copyright);\n\n\t\t// inherit from top\n\t\tif (top) {\n\t\t\tObject.assign(entry, top);\n\t\t}\n\n\t\t// assign data\n\t\tfor (let key of Object.keys(data)) {\n\t\t\tif (data[key] !== undefined) {\n\t\t\t\tentry[key] = data[key];\n\t\t\t}\n\t\t}\n\n\t\t// apply defaults\n\t\tfor (let key of Object.keys(defaults)) {\n\t\t\tif (entry[key] === undefined) {\n\t\t\t\tentry[key] = defaults[key];\n\t\t\t}\n\t\t}\n\n\t\tthis.stack.push(entry);\n\t\tthis.top = entry;\n\t\tthis.$rootScope.meta = this.top;\n\t}\n\n\tpop(data) {\n\t\tthis.stack.pop();\n\t\tthis.top = this.stack[this.stack.length-1];\n\t\tthis.$rootScope.meta = this.top;\n\t}\n\n}\n\nfunction toAbsUrl(url) {\n\tif (!url) {\n\t\treturn null;\n\t}\n\n\tif (url.indexOf('http') === 0) {\n\t\treturn url;\n\t}\n\n\tif (url.indexOf('//') === 0) {\n\t\treturn `${window.location.protocol}${url}`;\n\t}\n\n\tif (url.indexOf('/') === 0) {\n\t\treturn `${window.location.protocol}//${window.location.host}${url}`;\n\t}\n\n\treturn `${window.location.protocol}//${window.location.host}/${url}`;\n}\n"]} -------------------------------------------------------------------------------- /lib/MetaService.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); 4 | 5 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 6 | 7 | var _fdAngularCore = require('fd-angular-core'); 8 | 9 | var defaults = { 10 | type: 'website', 11 | status: 200, 12 | distribution: 'global', 13 | revisitAfter: 7 14 | }; 15 | 16 | var MetaService = (function () { 17 | function MetaService($rootScope, $location) { 18 | _classCallCheck(this, _MetaService); 19 | 20 | this.stack = []; 21 | this.top = null; 22 | this.mappings = {}; 23 | 24 | this.$rootScope = $rootScope; 25 | this.$location = $location; 26 | 27 | this.push({}); 28 | } 29 | 30 | _createClass(MetaService, [{ 31 | key: 'push', 32 | value: function push(data) { 33 | var top = this.top; 34 | var loc = this.$location; 35 | var entry = {}; 36 | 37 | // normalize 38 | if (!data.url) { 39 | data.url = loc.absUrl(); 40 | } 41 | if (data.image) { 42 | data.image = toAbsUrl(data.image); 43 | } 44 | if (data.url) { 45 | data.url = toAbsUrl(data.url); 46 | } 47 | 48 | data.author = data.author || data.copyright || data.publisher; 49 | data.copyright = data.copyright || data.author || data.publisher; 50 | data.publisher = data.publisher || data.author || data.copyright; 51 | 52 | // inherit from top 53 | if (top) { 54 | Object.assign(entry, top); 55 | } 56 | 57 | // assign data 58 | var _iteratorNormalCompletion = true; 59 | var _didIteratorError = false; 60 | var _iteratorError = undefined; 61 | 62 | try { 63 | for (var _iterator = Object.keys(data)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { 64 | var key = _step.value; 65 | 66 | if (data[key] !== undefined) { 67 | entry[key] = data[key]; 68 | } 69 | } 70 | 71 | // apply defaults 72 | } catch (err) { 73 | _didIteratorError = true; 74 | _iteratorError = err; 75 | } finally { 76 | try { 77 | if (!_iteratorNormalCompletion && _iterator['return']) { 78 | _iterator['return'](); 79 | } 80 | } finally { 81 | if (_didIteratorError) { 82 | throw _iteratorError; 83 | } 84 | } 85 | } 86 | 87 | var _iteratorNormalCompletion2 = true; 88 | var _didIteratorError2 = false; 89 | var _iteratorError2 = undefined; 90 | 91 | try { 92 | for (var _iterator2 = Object.keys(defaults)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { 93 | var key = _step2.value; 94 | 95 | if (entry[key] === undefined) { 96 | entry[key] = defaults[key]; 97 | } 98 | } 99 | } catch (err) { 100 | _didIteratorError2 = true; 101 | _iteratorError2 = err; 102 | } finally { 103 | try { 104 | if (!_iteratorNormalCompletion2 && _iterator2['return']) { 105 | _iterator2['return'](); 106 | } 107 | } finally { 108 | if (_didIteratorError2) { 109 | throw _iteratorError2; 110 | } 111 | } 112 | } 113 | 114 | this.stack.push(entry); 115 | this.top = entry; 116 | this.$rootScope.meta = this.top; 117 | } 118 | }, { 119 | key: 'pop', 120 | value: function pop(data) { 121 | this.stack.pop(); 122 | this.top = this.stack[this.stack.length - 1]; 123 | this.$rootScope.meta = this.top; 124 | } 125 | }]); 126 | 127 | var _MetaService = MetaService; 128 | MetaService = (0, _fdAngularCore.Inject)('$rootScope', '$location')(MetaService) || MetaService; 129 | MetaService = (0, _fdAngularCore.Service)('Meta')(MetaService) || MetaService; 130 | return MetaService; 131 | })(); 132 | 133 | function toAbsUrl(url) { 134 | if (!url) { 135 | return null; 136 | } 137 | 138 | if (url.indexOf('http') === 0) { 139 | return url; 140 | } 141 | 142 | if (url.indexOf('//') === 0) { 143 | return '' + window.location.protocol + url; 144 | } 145 | 146 | if (url.indexOf('/') === 0) { 147 | return window.location.protocol + '//' + window.location.host + url; 148 | } 149 | 150 | return window.location.protocol + '//' + window.location.host + '/' + url; 151 | } 152 | //# sourceMappingURL=MetaService.js.map -------------------------------------------------------------------------------- /dist/fd-angular-meta.js: -------------------------------------------------------------------------------- 1 | (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.FdAngularMeta = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o