Refactor attach-link and attach-form

This commit is contained in:
Behind The Math
2018-03-20 18:44:15 -04:00
parent 31a6f44c97
commit cd7be77d99
2 changed files with 66 additions and 69 deletions

View File

@@ -1,9 +1,13 @@
var on = require("../events/on") var on = require("../events/on")
var clone = require("../util/clone") var clone = require("../util/clone")
var attrClick = "data-pjax-click-state" var attrState = "data-pjax-state"
var formAction = function(el, event) { var formAction = function(el, event) {
if (isDefaultPrevented(event)) {
return
}
// Since loadUrl modifies options and we may add our own modifications below, // Since loadUrl modifies options and we may add our own modifications below,
// clone it so the changes don't persist // clone it so the changes don't persist
var options = clone(this.options) var options = clone(this.options)
@@ -19,27 +23,9 @@ var formAction = function(el, event) {
var virtLinkElement = document.createElement("a") var virtLinkElement = document.createElement("a")
virtLinkElement.setAttribute("href", options.requestOptions.requestUrl) virtLinkElement.setAttribute("href", options.requestOptions.requestUrl)
// Ignore external links. var attrValue = checkIfShouldAbort(virtLinkElement, options)
if (virtLinkElement.protocol !== window.location.protocol || virtLinkElement.host !== window.location.host) { if (attrValue) {
el.setAttribute(attrClick, "external") el.setAttribute(attrState, attrValue)
return
}
// Ignore click if we are on an anchor on the same page
if (virtLinkElement.pathname === window.location.pathname && virtLinkElement.hash.length > 0) {
el.setAttribute(attrClick, "anchor-present")
return
}
// Ignore empty anchor "foo.html#"
if (virtLinkElement.href === window.location.href.split("#")[0] + "#") {
el.setAttribute(attrClick, "anchor-empty")
return
}
// if declared as a full reload, just normally submit the form
if (options.currentUrlFullReload) {
el.setAttribute(attrClick, "reload")
return return
} }
@@ -59,12 +45,34 @@ var formAction = function(el, event) {
} }
} }
el.setAttribute(attrClick, "submit") el.setAttribute(attrState, "submit")
options.triggerElement = el options.triggerElement = el
this.loadUrl(virtLinkElement.href, options) this.loadUrl(virtLinkElement.href, options)
} }
function checkIfShouldAbort(virtLinkElement, options) {
// Ignore external links.
if (virtLinkElement.protocol !== window.location.protocol || virtLinkElement.host !== window.location.host) {
return "external"
}
// Ignore click if we are on an anchor on the same page
if (virtLinkElement.hash && virtLinkElement.href.replace(virtLinkElement.hash, "") === window.location.href.replace(location.hash, "")) {
return "anchor"
}
// Ignore empty anchor "foo.html#"
if (virtLinkElement.href === window.location.href.split("#")[0] + "#") {
return "anchor-empty"
}
// if declared as a full reload, just normally submit the form
if (options.currentUrlFullReload && virtLinkElement.href === window.location.href.split("#")[0]) {
return "reload"
}
}
var isDefaultPrevented = function(event) { var isDefaultPrevented = function(event) {
return event.defaultPrevented || event.returnValue === false return event.defaultPrevented || event.returnValue === false
} }
@@ -72,19 +80,13 @@ var isDefaultPrevented = function(event) {
module.exports = function(el) { module.exports = function(el) {
var that = this var that = this
on(el, "submit", function(event) { el.setAttribute(attrState, "")
if (isDefaultPrevented(event)) {
return
}
on(el, "submit", function(event) {
formAction.call(that, el, event) formAction.call(that, el, event)
}) })
on(el, "keyup", function(event) { on(el, "keyup", function(event) {
if (isDefaultPrevented(event)) {
return
}
if (event.keyCode === 13) { if (event.keyCode === 13) {
formAction.call(that, el, event) formAction.call(that, el, event)
} }

View File

@@ -4,40 +4,17 @@ var clone = require("../util/clone")
var attrState = "data-pjax-state" var attrState = "data-pjax-state"
var linkAction = function(el, event) { var linkAction = function(el, event) {
if (isDefaultPrevented(event)) {
return
}
// Since loadUrl modifies options and we may add our own modifications below, // Since loadUrl modifies options and we may add our own modifications below,
// clone it so the changes don't persist // clone it so the changes don't persist
var options = clone(this.options) var options = clone(this.options)
// Dont break browser special behavior on links (like page in new window) var attrValue = checkIfShouldAbort(el, event)
if (event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) { if (attrValue) {
el.setAttribute(attrState, "modifier") el.setAttribute(attrState, attrValue)
return
}
// we do test on href now to prevent unexpected behavior if for some reason
// user have href that can be dynamically updated
// Ignore external links.
if (el.protocol !== window.location.protocol || el.host !== window.location.host) {
el.setAttribute(attrState, "external")
return
}
// Ignore click if we are on an anchor on the same page
if (el.pathname === window.location.pathname && el.hash.length > 0) {
el.setAttribute(attrState, "anchor-present")
return
}
// Ignore anchors on the same page (keep native behavior)
if (el.hash && el.href.replace(el.hash, "") === window.location.href.replace(location.hash, "")) {
el.setAttribute(attrState, "anchor")
return
}
// Ignore empty anchor "foo.html#"
if (el.href === window.location.href.split("#")[0] + "#") {
el.setAttribute(attrState, "anchor-empty")
return return
} }
@@ -59,6 +36,31 @@ var linkAction = function(el, event) {
this.loadUrl(el.href, options) this.loadUrl(el.href, options)
} }
function checkIfShouldAbort(el, event) {
// Dont break browser special behavior on links (like page in new window)
if (event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
return "modifier"
}
// we do test on href now to prevent unexpected behavior if for some reason
// user have href that can be dynamically updated
// Ignore external links.
if (el.protocol !== window.location.protocol || el.host !== window.location.host) {
return "external"
}
// Ignore anchors on the same page (keep native behavior)
if (el.hash && el.href.replace(el.hash, "") === window.location.href.replace(location.hash, "")) {
return "anchor"
}
// Ignore empty anchor "foo.html#"
if (el.href === window.location.href.split("#")[0] + "#") {
return "anchor-empty"
}
}
var isDefaultPrevented = function(event) { var isDefaultPrevented = function(event) {
return event.defaultPrevented || event.returnValue === false return event.defaultPrevented || event.returnValue === false
} }
@@ -66,20 +68,13 @@ var isDefaultPrevented = function(event) {
module.exports = function(el) { module.exports = function(el) {
var that = this var that = this
on(el, "click", function(event) {
if (isDefaultPrevented(event)) {
return
}
el.setAttribute(attrState, "") el.setAttribute(attrState, "")
on(el, "click", function(event) {
linkAction.call(that, el, event) linkAction.call(that, el, event)
}) })
on(el, "keyup", function(event) { on(el, "keyup", function(event) {
if (isDefaultPrevented(event)) {
return
}
if (event.keyCode === 13) { if (event.keyCode === 13) {
linkAction.call(that, el, event) linkAction.call(that, el, event)
} }