Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
cto
g1
Commits
9928515e
Commit
9928515e
authored
Jun 30, 2018
by
S Anand
Browse files
ENH: urlfilter should handle forms, inputs, sliders. Fixes
#21
@tejesh.p
parent
c550e317
Pipeline
#52745
passed with stage
in 3 minutes and 6 seconds
Changes
4
Pipelines
2
Hide whitespace changes
Inline
Side-by-side
README.md
View file @
9928515e
...
@@ -253,6 +253,7 @@ All interaction components use this naming convention:
...
@@ -253,6 +253,7 @@ All interaction components use this naming convention:
-
`data-target`
: selector that all triggers act on by default
-
`data-target`
: selector that all triggers act on by default
-
`data-mode`
: mode of interaction for all triggers
-
`data-mode`
: mode of interaction for all triggers
-
`data-attr`
: attribute that contains the interaction data, e.g.
`href`
for
`.urlfilter`
-
`data-attr`
: attribute that contains the interaction data, e.g.
`href`
for
`.urlfilter`
-
`data-event`
: event that triggers urlfilter. Defaults to
`'click'`
-
Interactions are triggered on a
*trigger*
. For example,
`.urlfilter`
for
`$().urlfilter()`
.
-
Interactions are triggered on a
*trigger*
. For example,
`.urlfilter`
for
`$().urlfilter()`
.
Clicking / hovering on / typing in a trigger triggers the interaction.
Clicking / hovering on / typing in a trigger triggers the interaction.
-
`data-target`
: selector that this trigger acts on
-
`data-target`
: selector that this trigger acts on
...
...
src/types.js
View file @
9928515e
...
@@ -8,7 +8,7 @@ var state_transitions = {
...
@@ -8,7 +8,7 @@ var state_transitions = {
'
boolean
'
:
{
state
:
'
boolean
'
},
'
boolean
'
:
{
state
:
'
boolean
'
},
'
string
'
:
{
state
:
'
string
'
},
'
string
'
:
{
state
:
'
string
'
},
'
object
'
:
{
state
:
'
object
'
},
'
object
'
:
{
state
:
'
object
'
},
'
mixed
'
:
{
state
:
'
mixed
'
,
end
:
true
}
,
'
mixed
'
:
{
state
:
'
mixed
'
,
end
:
true
}
},
},
'
date
'
:
{
'
date
'
:
{
'
null
'
:
{
state
:
'
date
'
},
'
null
'
:
{
state
:
'
date
'
},
...
...
src/urlfilter.js
View file @
9928515e
import
{
parse
}
from
'
./url.js
'
import
{
parse
}
from
'
./url.js
'
import
{
hasdata
}
from
'
./_util.js
'
import
{
hasdata
}
from
'
./_util.js
'
export
function
urlfilter
(
options
)
{
export
function
urlfilter
(
options
)
{
options
=
options
||
{}
options
=
options
||
{}
...
@@ -9,69 +9,82 @@ export function urlfilter(options) {
...
@@ -9,69 +9,82 @@ export function urlfilter(options) {
return
return
var
doc
=
$self
[
0
].
ownerDocument
var
doc
=
$self
[
0
].
ownerDocument
var
attr
=
options
.
attr
||
$self
.
data
(
'
attr
'
)
||
'
href
'
var
attr
=
options
.
attr
||
$self
.
data
(
'
attr
'
)
||
'
href
'
var
selector
=
options
.
selector
||
$self
.
data
(
'
selector
'
)
||
'
.urlfilter
'
var
event
=
options
.
event
||
$self
.
data
(
'
event
'
)
||
'
click
'
var
default_src
=
options
.
src
||
$self
.
data
(
'
src
'
)
||
'
src
'
var
selector
=
options
.
selector
||
$self
.
data
(
'
selector
'
)
||
'
.urlfilter
'
var
default_mode
=
options
.
mode
||
$self
.
data
(
'
mode
'
)
var
default_src
=
options
.
src
||
$self
.
data
(
'
src
'
)
||
'
src
'
var
default_target
=
options
.
target
||
$self
.
data
(
'
target
'
)
var
default_mode
=
options
.
mode
||
$self
.
data
(
'
mode
'
)
var
default_remove
=
options
.
remove
||
hasdata
(
$self
,
'
remove
'
)
var
default_target
=
options
.
target
||
$self
.
data
(
'
target
'
)
var
off
=
options
.
off
||
hasdata
(
$self
,
'
off
'
)
var
default_remove
=
options
.
remove
||
hasdata
(
$self
,
'
remove
'
)
var
off
=
options
.
off
||
hasdata
(
$self
,
'
off
'
)
// options.location and options.history are used purely for testing
// options.location and options.history are used purely for testing
var
loc
=
options
.
location
||
(
doc
.
defaultView
||
doc
.
parentWindow
).
location
var
loc
=
options
.
location
||
(
doc
.
defaultView
||
doc
.
parentWindow
).
location
var
hist
=
options
.
history
||
(
doc
.
defaultView
||
doc
.
parentWindow
).
history
var
hist
=
options
.
history
||
(
doc
.
defaultView
||
doc
.
parentWindow
).
history
if
(
off
)
if
(
off
)
return
$self
.
off
(
'
click
.urlfilter
'
)
return
$self
.
off
(
event
+
'
.urlfilter
'
)
return
$self
.
on
(
'
click.urlfilter
'
,
selector
,
function
(
e
)
{
return
$self
e
.
preventDefault
()
.
on
(
event
+
'
.urlfilter
'
,
selector
,
function
(
e
)
{
e
.
preventDefault
()
var
$this
=
$
(
this
),
var
$this
=
$
(
this
),
mode
=
$this
.
data
(
'
mode
'
)
||
default_mode
,
mode
=
$this
.
data
(
'
mode
'
)
||
default_mode
,
target
=
$this
.
data
(
'
target
'
)
||
default_target
,
target
=
$this
.
data
(
'
target
'
)
||
default_target
,
src
=
$this
.
data
(
'
src
'
)
||
default_src
,
src
=
$this
.
data
(
'
src
'
)
||
default_src
,
remove
=
hasdata
(
$this
,
'
remove
'
,
default_remove
),
remove
=
hasdata
(
$this
,
'
remove
'
,
default_remove
)
href
=
$this
.
attr
(
attr
),
url
=
parse
(
href
),
q
=
url
.
searchList
function
target_url
(
url
)
{
var
href
var
result
=
parse
(
url
)
if
(
e
.
type
==
'
click
'
)
.
join
(
href
,
{
query
:
false
,
hash
:
false
})
href
=
$this
.
attr
(
attr
)
.
update
(
q
,
mode
)
else
if
(
e
.
type
==
'
submit
'
)
if
(
remove
)
{
href
=
'
?
'
+
$this
.
serialize
()
var
missing_keys
=
{}
else
if
(
e
.
type
==
'
input
'
||
e
.
type
==
'
change
'
)
{
for
(
var
key
in
result
.
searchKey
)
var
key
=
encodeURIComponent
(
$this
.
attr
(
'
id
'
)
||
$this
.
attr
(
'
name
'
))
if
(
result
.
searchKey
[
key
]
===
''
)
var
val
=
encodeURIComponent
(
$this
.
val
())
missing_keys
[
key
]
=
null
href
=
'
?
'
+
key
+
'
=
'
+
val
result
.
update
(
missing_keys
)
}
}
return
result
.
toString
()
}
/*
var
url
=
parse
(
href
),
If the target is... the URL is get/set at
q
=
url
.
searchList
------------------------ ---------------------
unspecified (=> window) location.href
function
target_url
(
url
)
{
'pushState' location.href
var
result
=
parse
(
url
)
'#' location.hash
.
join
(
href
,
{
query
:
false
,
hash
:
false
})
anything else $(target).data(src)
.
update
(
q
,
mode
)
*/
if
(
remove
)
{
if
(
!
target
)
var
missing_keys
=
{}
loc
.
href
=
target_url
(
loc
.
href
)
for
(
var
key
in
result
.
searchKey
)
else
if
(
target
==
'
#
'
)
if
(
result
.
searchKey
[
key
]
===
''
)
loc
.
hash
=
target_url
(
loc
.
hash
.
replace
(
/^#/
,
''
))
missing_keys
[
key
]
=
null
else
if
(
target
.
match
(
/^pushstate$/i
))
result
.
update
(
missing_keys
)
hist
.
pushState
({},
''
,
target_url
(
loc
.
href
))
}
else
{
return
result
.
toString
()
$
(
target
).
each
(
function
()
{
}
var
$target
=
$
(
this
)
var
url
=
target_url
(
$target
.
attr
(
src
))
/*
$target
.
attr
(
src
,
url
).
load
(
url
,
function
()
{
If the target is... the URL is get/set at
$target
.
trigger
({
type
:
'
load
'
,
url
:
url
})
------------------------ ---------------------
unspecified (=> window) location.href
'pushState' location.href
'#' location.hash
anything else $(target).data(src)
*/
if
(
!
target
)
loc
.
href
=
target_url
(
loc
.
href
)
else
if
(
target
==
'
#
'
)
loc
.
hash
=
target_url
(
loc
.
hash
.
replace
(
/^#/
,
''
))
else
if
(
target
.
match
(
/^pushstate$/i
))
hist
.
pushState
({},
''
,
target_url
(
loc
.
href
))
else
{
$
(
target
).
each
(
function
()
{
var
$target
=
$
(
this
)
var
url
=
target_url
(
$target
.
attr
(
src
))
$target
.
attr
(
src
,
url
).
load
(
url
,
function
()
{
$target
.
trigger
({
type
:
'
load
'
,
url
:
url
})
})
})
})
})
}
}
$this
.
trigger
({
type
:
'
urlfilter
'
,
url
:
url
})
$this
.
trigger
({
type
:
'
urlfilter
'
,
url
:
url
})
})
})
}
}
test/test-urlfilter.html
View file @
9928515e
<!DOCTYPE html>
<!DOCTYPE html>
<html>
<html>
<head>
<head>
<title>
urlfilter tests
</title>
<title>
urlfilter tests
</title>
<script
src=
"../node_modules/jquery/dist/jquery.min.js"
></script>
<script
src=
"../node_modules/jquery/dist/jquery.min.js"
></script>
...
@@ -12,12 +13,12 @@
...
@@ -12,12 +13,12 @@
// emit a "
<
key
>
.
get
"
/
"
<
key
>
.
set
"
event on emitter along with value
// emit a "
<
key
>
.
get
"
/
"
<
key
>
.
set
"
event on emitter along with value
function proxylog(object, emitter) {
function proxylog(object, emitter) {
return new Proxy(object, {
return new Proxy(object, {
get: function(obj, key) {
get: function
(obj, key) {
var val = obj[key]
var val = obj[key]
emitter.emit(key + '.get', val)
emitter.emit(key + '.get', val)
return val
return val
},
},
set: function(obj, key, val) {
set: function
(obj, key, val) {
obj[key] = val
obj[key] = val
emitter.emit(key + '.set', val)
emitter.emit(key + '.set', val)
return true
return true
...
@@ -25,28 +26,29 @@
...
@@ -25,28 +26,29 @@
})
})
}
}
var events = new Emitter()
var events = new Emitter()
var loc = proxylog({href: '', hash: ''}, events)
var loc = proxylog({
href: '', hash: ''
}, events)
var hist = {pushState: function(obj, name, href) { loc.href = href }}
var hist = {
pushState: function
(obj, name, href) { loc.href = href }
}
// Check if clicking
"
selector
"
sets location.href / location.hash
"
attr
"
.
// Check if clicking
"
selector
"
sets location.href / location.hash
"
attr
"
.
// The search key in location should initially be
"
init
"
and should become
"
result
"
// The search key in location should initially be
"
init
"
and should become
"
result
"
// A
"
urlfilter
"
event is triggered on the
"
selector
"
// A
"
urlfilter
"
event is triggered on the
"
selector
"
function check(t, selector, attr, init, result) {
function check(t, selector, attr, init, result
, event = 'click'
) {
t.test('
clicking
' + selector + ' sets location.' + attr + ' from ' + init + ' to ' + result, function(st) {
t.test('
Event: ' + event +'
' + selector + ' sets location.' + attr + ' from ' + init + ' to ' + result, function
(st) {
st.plan(3)
st.plan(3)
loc[attr] = init
loc[attr] = init
events.once(attr + '.set', function (val) {
events.once(attr + '.set', function (val) {
st.equal(g1.url.parse(val).search, result, 'check.' + attr + '.set')
st.equal(g1.url.parse(val).search, result, 'check.' + attr + '.set')
})
})
$(selector)
$(selector)
.one('urlfilter', function(e) {
.one('urlfilter', function
(e) {
st.equal(e.type, 'urlfilter', 'event.type == urlfilter')
st.equal(e.type, 'urlfilter', 'event.type == urlfilter')
st.ok(e.url, 'event.url exists')
st.ok(e.url, 'event.url exists')
})
})
.dispatch(
'click'
)
.dispatch(
event
)
})
})
}
}
</script>
</script>
</head>
</head>
<body>
<body>
<script>
<script>
tape
.
onFinish
(
function
()
{
window
.
renderComplete
=
true
})
tape
.
onFinish
(
function
()
{
window
.
renderComplete
=
true
})
...
@@ -54,10 +56,10 @@
...
@@ -54,10 +56,10 @@
<section
class=
"default-section"
>
<section
class=
"default-section"
>
<script>
<script>
var
$el
=
$
(
'
.default-section
'
).
urlfilter
({
location
:
loc
,
history
:
hist
})
var
$el
=
$
(
'
.default-section
'
).
urlfilter
({
location
:
loc
,
history
:
hist
})
tape
(
'
$().urlfilter binds a live click event to the .urlfilter children
'
,
function
(
t
)
{
tape
(
'
$().urlfilter binds a live click event to the .urlfilter children
'
,
function
(
t
)
{
t
.
plan
(
2
*
$el
.
length
)
t
.
plan
(
2
*
$el
.
length
)
$el
.
each
(
function
()
{
$el
.
each
(
function
()
{
var
event
=
jQuery
.
_data
(
this
,
'
events
'
).
click
[
0
]
var
event
=
jQuery
.
_data
(
this
,
'
events
'
).
click
[
0
]
t
.
equal
(
event
.
namespace
,
'
urlfilter
'
)
t
.
equal
(
event
.
namespace
,
'
urlfilter
'
)
t
.
equal
(
event
.
selector
,
'
.urlfilter
'
)
t
.
equal
(
event
.
selector
,
'
.urlfilter
'
)
...
@@ -70,17 +72,17 @@
...
@@ -70,17 +72,17 @@
<div
class=
"urlfilter base"
href=
"?x=1"
>
?x=1
</div>
<div
class=
"urlfilter base"
href=
"?x=1"
>
?x=1
</div>
<button
class=
"urlfilter base"
href=
"?x=1"
>
?x=1
</button>
<button
class=
"urlfilter base"
href=
"?x=1"
>
?x=1
</button>
<script>
<script>
tape
(
'
clicking any element sets location.href to a page with an UPDATED URL
'
,
function
(
t
)
{
tape
(
'
clicking any element sets location.href to a page with an UPDATED URL
'
,
function
(
t
)
{
check
(
t
,
'
a.urlfilter.base
'
,
'
href
'
,
'
?y=1
'
,
'
y=1&x=1
'
)
check
(
t
,
'
a.urlfilter.base
'
,
'
href
'
,
'
?y=1
'
,
'
y=1&x=1
'
)
check
(
t
,
'
i.urlfilter.base
'
,
'
href
'
,
'
?y=1
'
,
'
y=1&x=1
'
)
check
(
t
,
'
i.urlfilter.base
'
,
'
href
'
,
'
?y=1
'
,
'
y=1&x=1
'
)
check
(
t
,
'
div.urlfilter.base
'
,
'
href
'
,
'
?y=1
'
,
'
y=1&x=1
'
)
check
(
t
,
'
div.urlfilter.base
'
,
'
href
'
,
'
?y=1
'
,
'
y=1&x=1
'
)
check
(
t
,
'
button.urlfilter.base
'
,
'
href
'
,
'
?y=1
'
,
'
y=1&x=1
'
)
check
(
t
,
'
button.urlfilter.base
'
,
'
href
'
,
'
?y=1
'
,
'
y=1&x=1
'
)
})
})
tape
(
'
the URL is updated, irrespective of the current URL
'
,
function
(
t
)
{
tape
(
'
the URL is updated, irrespective of the current URL
'
,
function
(
t
)
{
check
(
t
,
'
a.urlfilter.base
'
,
'
href
'
,
''
,
'
x=1
'
)
check
(
t
,
'
a.urlfilter.base
'
,
'
href
'
,
''
,
'
x=1
'
)
check
(
t
,
'
a.urlfilter.base
'
,
'
href
'
,
'
?x
'
,
'
x=1
'
)
check
(
t
,
'
a.urlfilter.base
'
,
'
href
'
,
'
?x
'
,
'
x=1
'
)
check
(
t
,
'
a.urlfilter.base
'
,
'
href
'
,
'
?x=
'
,
'
x=1
'
)
check
(
t
,
'
a.urlfilter.base
'
,
'
href
'
,
'
?x=
'
,
'
x=1
'
)
check
(
t
,
'
a.urlfilter.base
'
,
'
href
'
,
'
?x=0
'
,
'
x=1
'
)
check
(
t
,
'
a.urlfilter.base
'
,
'
href
'
,
'
?x=0
'
,
'
x=1
'
)
check
(
t
,
'
a.urlfilter.base
'
,
'
href
'
,
'
?x=0&x=2
'
,
'
x=1
'
)
check
(
t
,
'
a.urlfilter.base
'
,
'
href
'
,
'
?x=0&x=2
'
,
'
x=1
'
)
})
})
</script>
</script>
...
@@ -99,30 +101,33 @@
...
@@ -99,30 +101,33 @@
<a
class=
"urlfilter del x2"
href=
"?x=2"
data-mode=
"del"
>
del ?x=2
</a>
<a
class=
"urlfilter del x2"
href=
"?x=2"
data-mode=
"del"
>
del ?x=2
</a>
<a
class=
"urlfilter del x12"
href=
"?x=1&x=2"
data-mode=
"del"
>
del ?x=1
&
x=2
</a>
<a
class=
"urlfilter del x12"
href=
"?x=1&x=2"
data-mode=
"del"
>
del ?x=1
&
x=2
</a>
<script>
<script>
tape
(
'
setting data-mode as a child attribute works
'
,
function
(
t
)
{
tape
(
'
setting data-mode as a child attribute works
'
,
function
(
test
)
{
check
(
t
,
'
.def.x1
'
,
'
href
'
,
''
,
'
x=1
'
)
test
.
plan
(
1
)
check
(
t
,
'
.add.x1
'
,
'
href
'
,
''
,
'
x=1
'
)
test
.
test
(
'
test for a tag click
'
,
function
(
t
)
{
check
(
t
,
'
.tog.x1
'
,
'
href
'
,
''
,
'
x=1
'
)
check
(
t
,
'
a.def.x1
'
,
'
href
'
,
''
,
'
x=1
'
)
check
(
t
,
'
.del.x1
'
,
'
href
'
,
''
,
''
)
check
(
t
,
'
a.add.x1
'
,
'
href
'
,
''
,
'
x=1
'
)
check
(
t
,
'
a.tog.x1
'
,
'
href
'
,
''
,
'
x=1
'
)
check
(
t
,
'
.def.x1
'
,
'
href
'
,
'
?x=1
'
,
'
x=1
'
)
check
(
t
,
'
a.del.x1
'
,
'
href
'
,
''
,
''
)
check
(
t
,
'
.add.x1
'
,
'
href
'
,
'
?x=1
'
,
'
x=1&x=1
'
)
check
(
t
,
'
.tog.x1
'
,
'
href
'
,
'
?x=1
'
,
''
)
check
(
t
,
'
a.def.x1
'
,
'
href
'
,
'
?x=1
'
,
'
x=1
'
)
check
(
t
,
'
.del.x1
'
,
'
href
'
,
'
?x=1
'
,
''
)
check
(
t
,
'
a.add.x1
'
,
'
href
'
,
'
?x=1
'
,
'
x=1&x=1
'
)
check
(
t
,
'
a.tog.x1
'
,
'
href
'
,
'
?x=1
'
,
''
)
check
(
t
,
'
.def.y1
'
,
'
href
'
,
'
?x=1
'
,
'
x=1&y=1
'
)
check
(
t
,
'
a.del.x1
'
,
'
href
'
,
'
?x=1
'
,
''
)
check
(
t
,
'
.add.y1
'
,
'
href
'
,
'
?x=1
'
,
'
x=1&y=1
'
)
check
(
t
,
'
.tog.y1
'
,
'
href
'
,
'
?x=1
'
,
'
x=1&y=1
'
)
check
(
t
,
'
a.def.y1
'
,
'
href
'
,
'
?x=1
'
,
'
x=1&y=1
'
)
check
(
t
,
'
.del.y1
'
,
'
href
'
,
'
?x=1
'
,
'
x=1
'
)
check
(
t
,
'
a.add.y1
'
,
'
href
'
,
'
?x=1
'
,
'
x=1&y=1
'
)
check
(
t
,
'
a.tog.y1
'
,
'
href
'
,
'
?x=1
'
,
'
x=1&y=1
'
)
check
(
t
,
'
.def.x2
'
,
'
href
'
,
'
?x=1
'
,
'
x=2
'
)
check
(
t
,
'
a.del.y1
'
,
'
href
'
,
'
?x=1
'
,
'
x=1
'
)
check
(
t
,
'
.add.x2
'
,
'
href
'
,
'
?x=1
'
,
'
x=1&x=2
'
)
check
(
t
,
'
.tog.x2
'
,
'
href
'
,
'
?x=1
'
,
'
x=1&x=2
'
)
check
(
t
,
'
a.def.x2
'
,
'
href
'
,
'
?x=1
'
,
'
x=2
'
)
check
(
t
,
'
.del.x2
'
,
'
href
'
,
'
?x=1
'
,
'
x=1
'
)
check
(
t
,
'
a.add.x2
'
,
'
href
'
,
'
?x=1
'
,
'
x=1&x=2
'
)
check
(
t
,
'
a.tog.x2
'
,
'
href
'
,
'
?x=1
'
,
'
x=1&x=2
'
)
check
(
t
,
'
.del.x1
'
,
'
href
'
,
'
?x=1&x=2&y=3
'
,
'
x=2&y=3
'
)
check
(
t
,
'
a.del.x2
'
,
'
href
'
,
'
?x=1
'
,
'
x=1
'
)
check
(
t
,
'
.del.x12
'
,
'
href
'
,
'
?x=1&x=2
'
,
''
)
check
(
t
,
'
.del.x12
'
,
'
href
'
,
'
?x=1&x=2&x=3&y=4
'
,
'
x=3&y=4
'
)
check
(
t
,
'
a.del.x1
'
,
'
href
'
,
'
?x=1&x=2&y=3
'
,
'
x=2&y=3
'
)
check
(
t
,
'
a.del.x12
'
,
'
href
'
,
'
?x=1&x=2
'
,
''
)
check
(
t
,
'
a.del.x12
'
,
'
href
'
,
'
?x=1&x=2&x=3&y=4
'
,
'
x=3&y=4
'
)
})
})
})
</script>
</script>
...
@@ -133,17 +138,17 @@
...
@@ -133,17 +138,17 @@
<iframe
class=
"target-iframe"
src=
"empty.html?y=1"
width=
"10"
height=
"10"
></iframe>
<iframe
class=
"target-iframe"
src=
"empty.html?y=1"
width=
"10"
height=
"10"
></iframe>
<div
class=
"target-div"
src=
"empty.html?y=1"
></div>
<div
class=
"target-div"
src=
"empty.html?y=1"
></div>
<script>
<script>
tape
(
'
setting data-target to pushState or hash works
'
,
function
(
t
)
{
tape
(
'
setting data-target to pushState or hash works
'
,
function
(
t
)
{
check
(
t
,
'
.pushstate
'
,
'
href
'
,
'
?y=1
'
,
'
y=1&x=1
'
)
check
(
t
,
'
.default-section
.pushstate
'
,
'
href
'
,
'
?y=1
'
,
'
y=1&x=1
'
)
check
(
t
,
'
.hash
'
,
'
hash
'
,
'
#?y=1
'
,
'
y=1&x=1
'
)
check
(
t
,
'
.default-section
.hash
'
,
'
hash
'
,
'
#?y=1
'
,
'
y=1&x=1
'
)
})
})
tape
(
'
setting data-target to selector changes src= and triggers load event
'
,
function
(
t
)
{
tape
(
'
setting data-target to selector changes src= and triggers load event
'
,
function
(
t
)
{
t
.
plan
(
2
*
5
)
t
.
plan
(
2
*
5
)
$
(
'
.selector-div, .selector-iframe
'
).
each
(
function
()
{
$
(
'
.selector-div, .selector-iframe
'
).
each
(
function
()
{
var
$this
=
$
(
this
)
var
$this
=
$
(
this
)
var
$target
=
$
(
$this
.
data
(
'
target
'
))
var
$target
=
$
(
$this
.
data
(
'
target
'
))
.
one
(
'
load
'
,
function
(
e
)
{
.
one
(
'
load
'
,
function
(
e
)
{
t
.
equal
(
e
.
type
,
'
load
'
,
'
load event
'
)
t
.
equal
(
e
.
type
,
'
load
'
,
'
load event
'
)
t
.
equal
(
$target
.
attr
(
'
src
'
),
'
empty.html?y=1&x=1
'
)
t
.
equal
(
$target
.
attr
(
'
src
'
),
'
empty.html?y=1&x=1
'
)
t
.
ok
(
e
.
url
,
'
load event url exists
'
)
t
.
ok
(
e
.
url
,
'
load event url exists
'
)
...
@@ -162,24 +167,158 @@
...
@@ -162,24 +167,158 @@
<a
class=
"urlfilter remove"
href=
"?x=&y="
data-remove
>
?x=
&
y= remove
</a>
<a
class=
"urlfilter remove"
href=
"?x=&y="
data-remove
>
?x=
&
y= remove
</a>
<a
class=
"urlfilter remove-1"
href=
"?x=&y="
data-remove=
"1"
>
?x=
&
y= remove-1
</a>
<a
class=
"urlfilter remove-1"
href=
"?x=&y="
data-remove=
"1"
>
?x=
&
y= remove-1
</a>
<script>
<script>
tape
(
'
data-remove removes empty values
'
,
function
(
t
)
{
tape
(
'
data-remove removes empty values
'
,
function
(
t
)
{
check
(
t
,
'
.no-remove
'
,
'
href
'
,
'
?x=1&y=2&z=3
'
,
'
x=&y=&z=3
'
)
check
(
t
,
'
.no-remove
'
,
'
href
'
,
'
?x=1&y=2&z=3
'
,
'
x=&y=&z=3
'
)
check
(
t
,
'
.remove
'
,
'
href
'
,
'
?x=1&y=2&z=3
'
,
'
z=3
'
)
check
(
t
,
'
.remove
'
,
'
href
'
,
'
?x=1&y=2&z=3
'
,
'
z=3
'
)
})
})
</script>
</script>
</section>
<!-- .default-section -->
</section>
<!-- .default-section -->
<section
class=
"default-input-section"
data-event=
"input"
>
<input
type=
"range"
class=
"urlfilter base"
name=
"slider"
>
<script>
$
(
'
.default-input-section
'
).
urlfilter
({
location
:
loc
,
history
:
hist
,
event
:
'
input
'
})
tape
(
'
clicking any element sets location.href to a page with an UPDATED URL
'
,
function
(
test
)
{
test
.
plan
(
3
)
test
.
test
(
'
test slider no input
'
,
function
(
t
)
{
check
(
t
,
'
input.urlfilter.base
'
,
'
href
'
,
'
?slider=50
'
,
'
slider=50
'
,
'
input
'
)
})
// update slider
test
.
test
(
'
test slider with change in val
'
,
function
(
t
)
{
$
(
'
input.urlfilter.base
'
).
val
(
80
)
check
(
t
,
'
input.urlfilter.base
'
,
'
href
'
,
'
?slider=80
'
,
'
slider=80
'
,
'
input
'
)
})
// update name attr and update slider
test
.
test
(
'
test slider with change in name of <input> element
'
,
function
(
t
)
{
$
(
'
input.urlfilter.base
'
).
attr
(
'
name
'
,
'
slider_renamed
'
)
$
(
'
input.urlfilter.base
'
).
val
(
60
)
check
(
t
,
'
input.urlfilter.base
'
,
'
href
'
,
'
?slider_renamed=620
'
,
'
slider_renamed=60
'
,
'
input
'
)
})
})
</script>
<input
type=
"range"
class=
"urlfilter def x1"
name=
"x"
value=
"50"
data-mode=
""
>
<input
type=
"text"
class=
"urlfilter unicode"
id=
" _<"e;高"e;gt;%/=?;,@$+"
value=
" _<"e;高"e;gt;%/=?;,@$+"
>
<input
type=
"range"
class=
"urlfilter"
id=
"x"
name=
"anything"
value=
"50"
data-mode=
""
>
<input
type=
"range"
class=
"urlfilter add x1"
name=
"x"
value=
"50"
data-mode=
"add"
>
<input
type=
"range"
class=
"urlfilter tog x1"
name=
"x"
value=
"50"
data-mode=
"toggle"
>
<input
type=
"range"
class=
"urlfilter del x1"
name=
"x"
value=
"50"
data-mode=
"del"
>
<input
type=
"range"
class=
"urlfilter def y1"
name=
"y"
value=
"50"
data-mode=
""
>
<input
type=
"range"
class=
"urlfilter add y1"
name=
"y"
value=
"50"
data-mode=
"add"
>
<input
type=
"range"
class=
"urlfilter tog y1"
name=
"y"
value=
"50"
data-mode=
"toggle"
>
<input
type=
"range"
class=
"urlfilter del y1"
name=
"y"
value=
"50"
data-mode=
"del"
>
<input
type=
"range"
class=
"urlfilter def x2"
name=
"x"
value=
"20"
data-mode=
""
>
<input
type=
"range"
class=
"urlfilter add x2"
name=
"x"
value=
"20"
data-mode=
"add"
>
<input
type=
"range"
class=
"urlfilter tog x2"
name=
"x"
value=
"20"
data-mode=
"toggle"
>
<input
type=
"range"
class=
"urlfilter del x2"
name=
"x"
value=
"20"
data-mode=
"del"
>
<script>
tape
(
'
setting data-mode as a child attribute works for input events on sliders
'
,
function
(
test
)
{
test
.
plan
(
1
)
test
.
test
(
'
test for input filters
'
,
function
(
t
)
{
check
(
t
,
'
input.def.x1
'
,
'
href
'
,
''
,
'
x=50
'
,
'
input
'
)
check
(
t
,
'
#x
'
,
'
href
'
,
''
,
'
x=50
'
,
'
input
'
)
check
(
t
,
'
input.unicode
'
,
'
href
'
,
''
,
'
%20_%3C%26quote%3B%E9%AB%98%26quote%3Bgt%3B%25%2F%3D%3F%3B%2C%40%24%2B=%20_%3C%26quote%3B%E9%AB%98%26quote%3Bgt%3B%25%2F%3D%3F%3B%2C%40%24%2B
'
,
'
input
'
)
check
(
t
,
'
input.add.x1
'
,
'
href
'
,
''
,
'
x=50
'
,
'
input
'
)
check
(
t
,
'
input.tog.x1
'
,
'
href
'
,
''
,
'
x=50
'
,
'
input
'
)
check
(
t
,
'
input.del.x1
'
,
'
href
'
,
''
,
''
,
'
input
'
)
check
(
t
,
'
input.def.x1
'
,
'
href
'
,
'
?x=50
'
,
'
x=50
'
,
'
input
'
)
check
(
t
,
'
input.add.x1
'
,
'
href
'
,
'
?x=50
'
,
'
x=50&x=50
'
,
'
input
'
)
check
(
t
,
'
input.tog.x1
'
,
'
href
'
,
'
?x=50
'
,
''
,
'
input
'
)
check
(
t
,
'
input.del.x1
'
,
'
href
'
,
'
?x=50
'
,
''
,
'
input
'
)
check
(
t
,
'
input.def.y1
'
,
'
href
'
,
'
?x=50
'
,
'
x=50&y=50
'
,
'
input
'
)
check
(
t
,
'
input.add.y1
'
,
'
href
'
,
'
?x=50
'
,
'
x=50&y=50
'
,
'
input
'
)
check
(
t
,
'
input.tog.y1
'
,
'
href
'
,
'
?x=50
'
,
'
x=50&y=50
'
,
'
input
'
)
check
(
t
,
'
input.del.y1
'
,
'
href
'
,
'
?x=50
'
,
'
x=50
'
,
'
input
'
)
check
(
t
,
'
input.def.x2
'
,
'
href
'
,
'
?x=1
'
,
'
x=20
'
,
'
input
'
)
check
(
t
,
'
input.add.x2
'
,
'
href
'
,
'
?x=1
'
,
'
x=1&x=20
'
,
'
input
'
)
check
(
t
,
'
input.tog.x2
'
,
'
href
'
,
'
?x=1
'
,
'
x=1&x=20
'
,
'
input
'
)
check
(
t
,
'
input.del.x2
'
,
'
href
'
,
'
?x=1
'
,
'
x=1
'
,
'
input
'
)
check
(
t
,
'
input.del.x1
'
,
'
href
'
,
'
?x=50&x=2&y=3
'
,
'
x=2&y=3
'
,
'
input
'
)
})
})
</script>
<!--
TODO:
- Add test case for <input type="text" name=" _<"e;高"e;gt;%/=?;,@$+" value=" _<"e;高"e;gt;%/=?;,@$+">
- Add test case for <form><input name="k1"><input id="k2"></form>
-->
<input
type=
"range"
class=
"urlfilter ipushstate"
name=
"x"
value=
"1"
data-target=
"pushState"
>
<input
type=
"range"
class=
"urlfilter ihash"
name=
"x"
value=
"1"
data-target=
"#"
>
<script>
tape
(
'
setting data-target to pushState or hash works for input type events
'
,
function
(
t
)
{
check
(
t
,
'
.default-input-section input.ipushstate
'
,
'
href
'
,
'
?y=1
'
,
'
y=1&x=1
'
,
'
input
'
)
check
(
t
,
'
.default-input-section input.ihash
'
,
'
hash
'
,
'
#?y=1
'
,
'
y=1&x=1
'
,
'
input
'
)
})
</script>
</section>
<section
class=
"remove-section"
data-remove
>
<section
class=
"remove-section"
data-remove
>
<a
class=
"urlfilter remove-na"
href=
"?x=&y="
>
?x=
&
y=
</a>
<a
class=
"urlfilter remove-na"
href=
"?x=&y="
>
?x=
&
y=
</a>
<a
class=
"urlfilter remove-no"
href=
"?x=&y="
data-remove=
"no"
>
?x=
&
y= remove=no
</a>
<a
class=
"urlfilter remove-no"
href=
"?x=&y="
data-remove=
"no"
>
?x=
&
y= remove=no
</a>
<script>
<script>
var
$el
=
$
(
'
.remove-section
'
).
urlfilter
({
location
:
loc
,
history
:
hist
})
$
(
'
.remove-section
'
).
urlfilter
({
location
:
loc
,
history
:
hist
})
tape
(
'
data-remove is inherited but can be over-ridden
'
,
function
(
t
)
{
tape
(
'
data-remove is inherited but can be over-ridden
'
,
function
(
t
)
{
check
(
t
,
'
.remove-na
'
,
'
href
'
,
'
?x=1&y=2&z=3
'
,
'
z=3
'
)
check
(
t
,
'
a.remove-na
'
,
'
href
'
,
'
?x=1&y=2&z=3
'
,
'
z=3
'
)
check
(
t
,
'
.remove-no
'
,
'
href
'
,
'
?x=1&y=2&z=3
'
,
'
x=&y=&z=3
'
)
check
(
t
,
'
a.remove-no
'
,
'
href
'
,
'
?x=1&y=2&z=3
'
,
'
x=&y=&z=3
'
)
})
</script>
</section>
<!-- .remove-section -->
<section
class=
"default-form-section"
data-event=
"submit"
>
<form
class=
"urlfilter all_elm"
>
<!-- To SERIALIZE the element must have a name attribute. -->
<input
name=
"k1"
><input
id=
"k2"
>
<input
type=
"text"
name=
" _<"e;高"e;gt;%/=?;,@$+"
value=
" _<"e;高"e;gt;%/=?;,@$+"
>
<input
type=
"text"
id=
"textbox"
name=
"textbox"
value=
"dummy"
><br>
<select
name=
"cars"
>
<option
value=
"volvo"
>
Volvo
</option>
<option
value=
"saab"
>
Saab
</option>
<option
value=
"fiat"
>
Fiat
</option>
<option
value=
"audi"
>
Audi
</option>
</select><br>
<input
type=
"radio"
name=
"gender"
value=
"male"
checked
>
Male
<br>
<input
type=
"radio"
name=
"gender"
value=
"female"
>
Female
<br>
<input
type=
"radio"
name=
"gender"
value=
"other"
>
Other
<br>
<input
type=
"range"
name=
"slider"
value=
"20"
><br>
<input
type=
"checkbox"
name=
"vehicle"
value=
"Bike"
>
I have a bike
<br>
<input
type=
"checkbox"
name=
"vehicle"
value=
"Car"
checked=
"checked"
>
I have a car
<br>
<button
type=
"submit"
>
Submit
</button>
</form>
<script>
$
(
'
.default-form-section
'
).
urlfilter
({
location
:
loc
,
history
:
hist
})
tape
(
'
g1.urlfilter test forms with input text, range and dropdown
'
,
function
(
test
)
{
test
.
plan
(
2
)
test
.
test
(
'
test form with all input elements in it
'
,
function
(
t
)
{
check
(
t
,
'
form.urlfilter.all_elm
'
,
'
href
'
,
'
?
'
,
'
k1=&%20_%3C%26quote%3B%E9%AB%98%26quote%3Bgt%3B%25%2F%3D%3F%3B%2C%40%24%2B=%20_%3C%26quote%3B%E9%AB%98%26quote%3Bgt%3B%25%2F%3D%3F%3B%2C%40%24%2B&textbox=dummy&cars=volvo&gender=male&slider=20&vehicle=Car
'
,
'
submit
'
)
})
// update textbox value
test
.
test
(
'
test form with all input elements and change slider
'
,
function
(
t
)
{
$
(
'
#textbox
'
).
val
(
"
tummy
"
)
check
(
t
,
'
form.urlfilter.all_elm
'
,
'
href
'
,
'
?
'
,
'
k1=&%20_%3C%26quote%3B%E9%AB%98%26quote%3Bgt%3B%25%2F%3D%3F%3B%2C%40%24%2B=%20_%3C%26quote%3B%E9%AB%98%26quote%3Bgt%3B%25%2F%3D%3F%3B%2C%40%24%2B&textbox=tummy&cars=volvo&gender=male&slider=20&vehicle=Car
'
,
'
submit
'
)
})
})
})
</script>
</script>
</section>
<!-- .remove-section -->
<!--
TODO:
- [x] Add test case for <input type="text" name=" _<"e;高"e;gt;%/=?;,@$+" value=" _<"e;高"e;gt;%/=?;,@$+">
- [x] Add test case for <form><input name="k1"><input id="k2"></form>
-->
</section>
</body>
</body>
</html>
</html>
S Anand
@s.anand
mentioned in merge request