Skip to content

Commit

Permalink
Initial build with hardcoded settings
Browse files Browse the repository at this point in the history
  • Loading branch information
weotch committed Apr 24, 2018
1 parent 5d8661a commit 2420f06
Show file tree
Hide file tree
Showing 8 changed files with 2,795 additions and 0 deletions.
1 change: 1 addition & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "presets": ["env"] }
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
# vue-routing-anchor-parser
A Vue directive that parses itself and children for anchor tags and binds clicks to use Vue Router's push rather if they link internally


## Notes

- This currently only parses children, not the element the directive is added to
- This currently only parses on `bind`, meaning if the contents for the element change later, new `a` tags won't be processed.
50 changes: 50 additions & 0 deletions index.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Default settings
settings =
addBlankToExternal: true
internalHosts: [ location?.host ]

# Deps
URL = require 'url-parse'

# Add listeners to anchors
bind = (el, binding, vnode) ->

# Get the router instance
router = vnode.context.$router

# Get anchors that have an href
el.querySelectorAll('a').forEach (anchor) ->
return unless href = anchor.getAttribute 'href'
url = new URL href
if isInternal url
then handleInternal anchor, url, router
else handleExternal anchor

# Test if an anchor is an internal link
isInternal = (url) ->

# Does it begin with a / and not an //
return true if url.href.match /^\/[^\/]/

# Does the host match the comparer
return true if url.host in settings.internalHosts

# Add click bindings to internal links that resolve. Thus, if the Vue doesn't
# know about a route, it will not be handled by vue-router. Though it won't
# open in a new window.
handleInternal = (anchor, url, router) ->
route = path: "#{url.pathname}#{url.query}"
if router.resolve(route).route.matched.length
anchor.addEventListener 'click', (e) ->
e.preventDefault()
router.push path: "#{url.pathname}#{url.query}"

# Add target blank to external links
handleExternal = (anchor) ->
if settings.addBlankToExternal and not anchor.hasAttribute('target')
anchor.setAttribute 'target', '_blank'

# Directive definition. Relying on Browser garbage collection to cleanup
# listeners
module.exports =
bind: bind
85 changes: 85 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
'use strict';

// Generated by CoffeeScript 2.2.4
(function () {
// Default settings
var URL,
bind,
handleExternal,
handleInternal,
isInternal,
settings,
indexOf = [].indexOf;

settings = {
addBlankToExternal: true,
internalHosts: [typeof location !== "undefined" && location !== null ? location.host : void 0]
};

// Deps
URL = require('url-parse');

// Add listeners to anchors
bind = function bind(el, binding, vnode) {
var router;
// Get the router instance
router = vnode.context.$router;
// Get anchors that have an href
return el.querySelectorAll('a').forEach(function (anchor) {
var href, url;
if (!(href = anchor.getAttribute('href'))) {
return;
}
url = new URL(href);
if (isInternal(url)) {
return handleInternal(anchor, url, router);
} else {
return handleExternal(anchor);
}
});
};

// Test if an anchor is an internal link
isInternal = function isInternal(url) {
var ref;
if (url.href.match(/^\/[^\/]/)) {
// Does it begin with a / and not an //
return true;
}
if (ref = url.host, indexOf.call(settings.internalHosts, ref) >= 0) {
// Does the host match the comparer
return true;
}
};

// Add click bindings to internal links that resolve. Thus, if the Vue doesn't
// know about a route, it will not be handled by vue-router. Though it won't
// open in a new window.
handleInternal = function handleInternal(anchor, url, router) {
var route;
route = {
path: '' + url.pathname + url.query
};
if (router.resolve(route).route.matched.length) {
return anchor.addEventListener('click', function (e) {
e.preventDefault();
return router.push({
path: '' + url.pathname + url.query
});
});
}
};

// Add target blank to external links
handleExternal = function handleExternal(anchor) {
if (settings.addBlankToExternal && !anchor.hasAttribute('target')) {
return anchor.setAttribute('target', '_blank');
}
};

// Directive definition. Relying on Browser garbage collection to cleanup
// listeners
module.exports = {
bind: bind
};
}).call(undefined);
12 changes: 12 additions & 0 deletions nuxt/module.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Register the directive
*/
const path = require('path')
module.exports = function () {
this.addPlugin({
src: path.resolve(__dirname, 'plugin.js')
});
}

// Export meta for Nuxt
module.exports.meta = require('../package.json')
7 changes: 7 additions & 0 deletions nuxt/plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* Nuxt loses the current directory at this point, so I had to refer to the
* the directive src file through the module name.
*/
const Vue = require('vue')
const directive = require('vue-routing-anchor-parser/index.coffee')
Vue.directive('parse-anchors', directive)
35 changes: 35 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name": "vue-routing-anchor-parser",
"version": "1.0.0",
"description": "A Vue directive that parses itself and children for internally linking anchor tags and binds their click events to use Vue Router's push()",
"main": "index.js",
"scripts": {
"build": "coffee -ct index.coffee",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/BKWLD/vue-routing-anchor-parser.git"
},
"keywords": [
"vue",
"router",
"directive"
],
"author": "Bukwild",
"license": "MIT",
"bugs": {
"url": "https://github.com/BKWLD/vue-routing-anchor-parser/issues"
},
"homepage": "https://github.com/BKWLD/vue-routing-anchor-parser#readme",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-preset-env": "^1.6.1",
"coffee-loader": "^0.9.0",
"coffeescript": "^2.2.4",
"webpack": "^4.6.0"
},
"dependencies": {
"url-parse": "^1.4.0"
}
}
Loading

0 comments on commit 2420f06

Please sign in to comment.