Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
J
jquery
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
夏彬
jquery
Commits
7f94a5cc
Commit
7f94a5cc
authored
Feb 03, 2013
by
Rick Waldron
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
2.0: Rewrite data.js (Incl. event, manipulation, tests)
parent
ed0e2d1e
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
354 additions
and
358 deletions
+354
-358
data.js
src/data.js
+214
-227
event.js
src/event.js
+2
-2
manipulation.js
src/manipulation.js
+31
-27
onbeforeunload.html
test/data/onbeforeunload.html
+20
-0
testrunner.js
test/data/testrunner.js
+40
-34
data.js
test/unit/data.js
+36
-2
event.js
test/unit/event.js
+11
-66
No files found.
src/data.js
View file @
7f94a5cc
var
rbrace
=
/
(?:\{[\s\S]
*
\}
|
\[[\s\S]
*
\])
$/
,
var
data_user
,
data_priv
,
rbrace
=
/
(?:\{[\s\S]
*
\}
|
\[[\s\S]
*
\])
$/
,
rmultiDash
=
/
([
A-Z
])
/g
;
rmultiDash
=
/
([
A-Z
])
/g
;
function
internalData
(
elem
,
name
,
data
,
pvt
)
{
function
Data
()
{
if
(
!
jQuery
.
acceptData
(
elem
)
)
{
// Nodes|Objects
return
;
this
.
owners
=
[];
}
// Data objects
this
.
cache
=
[];
var
thisCache
,
ret
,
}
internalKey
=
jQuery
.
expando
,
getByName
=
typeof
name
===
"string"
,
// We have to handle DOM nodes and JS objects differently because IE6-7
Data
.
index
=
function
(
array
,
node
)
{
// can't GC object references properly across the DOM-JS boundary
return
array
.
indexOf
(
node
);
isNode
=
elem
.
nodeType
,
};
// Only DOM nodes need the global jQuery cache; JS object data is
// attached directly to the object so GC can occur automatically
cache
=
isNode
?
jQuery
.
cache
:
elem
,
// Only defining an ID for JS objects if its cache already exists allows
Data
.
prototype
=
{
// the code to shortcut on the same path as a DOM node with no cache
add
:
function
(
owner
)
{
id
=
isNode
?
elem
[
internalKey
]
:
elem
[
internalKey
]
&&
internalKey
;
this
.
owners
.
push
(
owner
);
return
(
this
.
cache
[
this
.
owners
.
length
-
1
]
=
{});
},
set
:
function
(
owner
,
data
,
value
)
{
var
prop
,
index
=
Data
.
index
(
this
.
owners
,
owner
);
// Avoid doing any more work than we need to when trying to get data on an
// If there is no entry for this "owner", create one inline
// object that has no data at all
// and set the index as though an owner entry had always existed
if
(
(
!
id
||
!
cache
[
id
]
||
(
!
pvt
&&
!
cache
[
id
].
data
))
&&
getByName
&&
data
===
undefined
)
{
if
(
index
===
-
1
)
{
return
;
this
.
add
(
owner
);
index
=
this
.
owners
.
length
-
1
;
}
}
// Handle: [ owner, key, value ] args
if
(
typeof
data
===
"string"
)
{
this
.
cache
[
index
][
data
]
=
value
;
if
(
!
id
)
{
// Handle: [ owner, { properties } ] args
// Only DOM nodes need a new unique ID for each element since their data
// ends up in the global cache
if
(
isNode
)
{
elem
[
internalKey
]
=
id
=
core_deletedIds
.
pop
()
||
jQuery
.
guid
++
;
}
else
{
}
else
{
id
=
internalKey
;
// In the case where there was actually no "owner" entry and
}
// this.add( owner ) was called to create one, there will be
}
// a corresponding empty plain object in the cache.
if
(
jQuery
.
isEmptyObject
(
this
.
cache
[
index
]
)
)
{
if
(
!
cache
[
id
]
)
{
this
.
cache
[
index
]
=
data
;
cache
[
id
]
=
{};
// Avoids exposing jQuery metadata on plain JS objects when the object
// is serialized using JSON.stringify
if
(
!
isNode
)
{
cache
[
id
].
toJSON
=
jQuery
.
noop
;
}
}
// An object can be passed to jQuery.data instead of a key/value pair; this gets
// Otherwise, copy the properties one-by-one to the cache object
// shallow copied over onto the existing cache
if
(
typeof
name
===
"object"
||
typeof
name
===
"function"
)
{
if
(
pvt
)
{
cache
[
id
]
=
jQuery
.
extend
(
cache
[
id
],
name
);
}
else
{
}
else
{
cache
[
id
].
data
=
jQuery
.
extend
(
cache
[
id
].
data
,
name
);
for
(
prop
in
data
)
{
this
.
cache
[
index
][
prop
]
=
data
[
prop
];
}
}
}
}
thisCache
=
cache
[
id
];
// jQuery data() is stored in a separate object inside the object's internal data
// cache in order to avoid key collisions between internal data and user-defined
// data.
if
(
!
pvt
)
{
if
(
!
thisCache
.
data
)
{
thisCache
.
data
=
{};
}
thisCache
=
thisCache
.
data
;
}
if
(
data
!==
undefined
)
{
thisCache
[
jQuery
.
camelCase
(
name
)
]
=
data
;
}
// Check for both converted-to-camel and non-converted data property names
// If a data property was specified
if
(
getByName
)
{
// First Try to find as-is property data
ret
=
thisCache
[
name
];
// Test for null|undefined property data
if
(
ret
==
null
)
{
// Try to find the camelCased property
ret
=
thisCache
[
jQuery
.
camelCase
(
name
)
];
}
}
return
this
;
},
get
:
function
(
owner
,
key
)
{
var
cache
,
index
=
Data
.
index
(
this
.
owners
,
owner
);
// A valid cache is found, or needs to be created.
// New entries will be added and return the current
// empty data object to be used as a return reference
// return this.add( owner );
// This logic was required by expectations made of the
// old data system.
cache
=
index
===
-
1
?
this
.
add
(
owner
)
:
this
.
cache
[
index
];
return
key
===
undefined
?
cache
:
cache
[
key
];
},
access
:
function
(
owner
,
key
,
value
)
{
if
(
value
===
undefined
&&
(
key
&&
typeof
key
!==
"object"
)
)
{
// Assume this is a request to read the cached data
return
this
.
get
(
owner
,
key
);
}
else
{
}
else
{
ret
=
thisCache
;
}
return
ret
;
// If only an owner was specified, return the entire
}
// cache object.
if
(
key
===
undefined
)
{
function
internalRemoveData
(
elem
,
name
,
pvt
)
{
return
this
.
get
(
owner
);
if
(
!
jQuery
.
acceptData
(
elem
)
)
{
return
;
}
}
var
thisCache
,
i
,
l
,
// Allow setting or extending (existing objects) with an
// object of properties, or a key and val
isNode
=
elem
.
nodeType
,
this
.
set
(
owner
,
key
,
value
);
return
value
!==
undefined
?
value
:
key
;
// See jQuery.data for more information
cache
=
isNode
?
jQuery
.
cache
:
elem
,
id
=
isNode
?
elem
[
jQuery
.
expando
]
:
jQuery
.
expando
;
// If there is already no cache entry for this object, there is no
// purpose in continuing
if
(
!
cache
[
id
]
)
{
return
;
}
}
// Otherwise, this is a read request.
return
this
.
get
(
owner
,
key
);
},
remove
:
function
(
owner
,
key
)
{
var
i
,
l
,
name
,
camel
=
jQuery
.
camelCase
,
index
=
Data
.
index
(
this
.
owners
,
owner
),
cache
=
this
.
cache
[
index
];
if
(
name
)
{
if
(
key
===
undefined
)
{
cache
=
{};
thisCache
=
pvt
?
cache
[
id
]
:
cache
[
id
].
data
;
if
(
thisCache
)
{
// Support array or space separated string names for data keys
if
(
!
jQuery
.
isArray
(
name
)
)
{
// try the string as a key before any manipulation
if
(
name
in
thisCache
)
{
name
=
[
name
];
}
else
{
}
else
{
if
(
cache
)
{
// split the camel cased version by spaces unless a key with the spaces exists
// Support array or space separated string of keys
name
=
jQuery
.
camelCase
(
name
);
if
(
!
Array
.
isArray
(
key
)
)
{
if
(
name
in
thisCache
)
{
// Try the string as a key before any manipulation
name
=
[
name
];
//
if
(
key
in
cache
)
{
name
=
[
key
];
}
else
{
}
else
{
name
=
name
.
split
(
" "
);
// Split the camel cased version by spaces unless a key with the spaces exists
}
name
=
camel
(
key
);
name
=
name
in
cache
?
[
name
]
:
name
.
split
(
" "
);
}
}
}
else
{
}
else
{
// If "name" is an array of keys...
// If "name" is an array of keys...
...
@@ -143,95 +116,86 @@ function internalRemoveData( elem, name, pvt ) {
...
@@ -143,95 +116,86 @@ function internalRemoveData( elem, name, pvt ) {
// Since there is no way to tell _how_ a key was added, remove
// Since there is no way to tell _how_ a key was added, remove
// both plain key and camelCase key. #12786
// both plain key and camelCase key. #12786
// This will only penalize the array argument path.
// This will only penalize the array argument path.
name
=
name
.
concat
(
jQuery
.
map
(
name
,
jQuery
.
camelCase
)
);
name
=
key
.
concat
(
key
.
map
(
camel
)
);
}
}
i
=
0
;
l
=
name
.
length
;
for
(
i
=
0
,
l
=
name
.
length
;
i
<
l
;
i
++
)
{
for
(
;
i
<
l
;
i
++
)
{
delete
thisCache
[
name
[
i
]
];
delete
cache
[
name
[
i
]
];
}
// If there is no data left in the cache, we want to continue
// and let the cache object itself get destroyed
if
(
!
(
pvt
?
isEmptyDataObject
:
jQuery
.
isEmptyObject
)(
thisCache
)
)
{
return
;
}
}
}
}
}
}
this
.
cache
[
index
]
=
cache
;
},
hasData
:
function
(
owner
)
{
var
index
=
Data
.
index
(
this
.
owners
,
owner
);
// See jQuery.data for more information
if
(
index
>
-
1
)
{
if
(
!
pvt
)
{
return
!
jQuery
.
isEmptyObject
(
this
.
cache
[
index
]
);
delete
cache
[
id
].
data
;
}
return
false
;
},
discard
:
function
(
owner
)
{
var
index
=
Data
.
index
(
this
.
owners
,
owner
);
// Don't destroy the parent cache unless the internal data object
if
(
index
>=
0
)
{
// had been the only thing left in it
this
.
owners
.
splice
(
index
,
1
);
if
(
!
isEmptyDataObject
(
cache
[
id
]
)
)
{
this
.
cache
.
splice
(
index
,
1
);
return
;
}
}
return
this
;
}
}
};
// Destroy the cache
// This will be used by remove()/cleanData() in manipulation to sever
if
(
isNode
)
{
// remaining references to node objects. One day we'll replace the dual
jQuery
.
cleanData
(
[
elem
],
true
);
// arrays with a WeakMap and this won't be an issue.
// (Splices the data objects out of the internal cache arrays)
function
data_discard
(
owner
)
{
data_user
.
discard
(
owner
);
data_priv
.
discard
(
owner
);
}
// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
// These may be used throughout the jQuery core codebase
}
else
if
(
jQuery
.
support
.
deleteExpando
||
cache
!=
cache
.
window
)
{
data_user
=
new
Data
();
delete
cache
[
id
]
;
data_priv
=
new
Data
()
;
// When all else fails, null
}
else
{
cache
[
id
]
=
null
;
}
}
jQuery
.
extend
({
jQuery
.
extend
({
cache
:
{},
// This is no longer relevant to jQuery core, but must remain
// supported for the sake of jQuery 1.9.x API surface compatibility.
acceptData
:
function
()
{
return
true
;
},
// Unique for each copy of jQuery on the page
// Unique for each copy of jQuery on the page
// Non-digits removed to match rinlinejQuery
// Non-digits removed to match rinlinejQuery
expando
:
"jQuery"
+
(
core_version
+
Math
.
random
()
).
replace
(
/
\D
/g
,
""
),
expando
:
"jQuery"
+
(
core_version
+
Math
.
random
()
).
replace
(
/
\D
/g
,
""
),
// The following elements throw uncatchable exceptions if you
// attempt to add expando properties to them.
noData
:
{
"embed"
:
true
,
// Ban all objects except for Flash (which handle expandos)
"object"
:
"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
,
"applet"
:
true
},
hasData
:
function
(
elem
)
{
hasData
:
function
(
elem
)
{
elem
=
elem
.
nodeType
?
jQuery
.
cache
[
elem
[
jQuery
.
expando
]
]
:
elem
[
jQuery
.
expando
];
return
data_user
.
hasData
(
elem
)
||
data_priv
.
hasData
(
elem
);
return
!!
elem
&&
!
isEmptyDataObject
(
elem
);
},
},
data
:
function
(
elem
,
name
,
data
)
{
data
:
function
(
elem
,
name
,
data
)
{
return
internalData
(
elem
,
name
,
data
);
return
data_user
.
access
(
elem
,
name
,
data
);
},
},
removeData
:
function
(
elem
,
name
)
{
removeData
:
function
(
elem
,
name
)
{
return
internalRemoveData
(
elem
,
name
);
return
data_user
.
remove
(
elem
,
name
);
},
},
// For internal use only.
// TODO: Replace all calls to _data and _removeData with direct
// calls to
//
// data_priv.access( elem, name, data );
//
// data_priv.remove( elem, name );
//
_data
:
function
(
elem
,
name
,
data
)
{
_data
:
function
(
elem
,
name
,
data
)
{
return
internalData
(
elem
,
name
,
data
,
true
);
return
data_priv
.
access
(
elem
,
name
,
data
);
},
},
_removeData
:
function
(
elem
,
name
)
{
_removeData
:
function
(
elem
,
name
)
{
return
internalRemoveData
(
elem
,
name
,
true
);
return
data_priv
.
remove
(
elem
,
name
);
},
// A method for determining if a DOM node can handle the data expando
acceptData
:
function
(
elem
)
{
// Do not set data on non-element because it will not be cleared (#8335).
if
(
elem
.
nodeType
&&
elem
.
nodeType
!==
1
&&
elem
.
nodeType
!==
9
)
{
return
false
;
}
var
noData
=
elem
.
nodeName
&&
jQuery
.
noData
[
elem
.
nodeName
.
toLowerCase
()
];
// nodes accept data unless otherwise specified; rejection can be conditional
return
!
noData
||
noData
!==
true
&&
elem
.
getAttribute
(
"classid"
)
===
noData
;
}
}
});
});
...
@@ -245,20 +209,19 @@ jQuery.fn.extend({
...
@@ -245,20 +209,19 @@ jQuery.fn.extend({
// Gets all values
// Gets all values
if
(
key
===
undefined
)
{
if
(
key
===
undefined
)
{
if
(
this
.
length
)
{
if
(
this
.
length
)
{
data
=
jQuery
.
data
(
elem
);
data
=
data_user
.
get
(
elem
);
if
(
elem
.
nodeType
===
1
&&
!
jQuery
.
_data
(
elem
,
"parsed
Attrs"
)
)
{
if
(
elem
.
nodeType
===
1
&&
!
data_priv
.
get
(
elem
,
"hasData
Attrs"
)
)
{
attrs
=
elem
.
attributes
;
attrs
=
elem
.
attributes
;
for
(
;
i
<
attrs
.
length
;
i
++
)
{
for
(
;
i
<
attrs
.
length
;
i
++
)
{
name
=
attrs
[
i
].
name
;
name
=
attrs
[
i
].
name
;
if
(
!
name
.
indexOf
(
"data-"
)
)
{
if
(
name
.
indexOf
(
"data-"
)
===
0
)
{
name
=
jQuery
.
camelCase
(
name
.
slice
(
5
)
);
name
=
jQuery
.
camelCase
(
name
.
substring
(
5
)
);
dataAttr
(
elem
,
name
,
data
[
name
]
);
dataAttr
(
elem
,
name
,
data
[
name
]
);
}
}
}
}
jQuery
.
_data
(
elem
,
"parsed
Attrs"
,
true
);
data_priv
.
set
(
elem
,
"hasData
Attrs"
,
true
);
}
}
}
}
...
@@ -268,37 +231,79 @@ jQuery.fn.extend({
...
@@ -268,37 +231,79 @@ jQuery.fn.extend({
// Sets multiple values
// Sets multiple values
if
(
typeof
key
===
"object"
)
{
if
(
typeof
key
===
"object"
)
{
return
this
.
each
(
function
()
{
return
this
.
each
(
function
()
{
jQuery
.
data
(
this
,
key
);
data_user
.
set
(
this
,
key
);
});
});
}
}
return
jQuery
.
access
(
this
,
function
(
value
)
{
return
jQuery
.
access
(
this
,
function
(
value
)
{
var
data
,
camelKey
=
jQuery
.
camelCase
(
key
);
// Get the Data...
if
(
value
===
undefined
)
{
if
(
value
===
undefined
)
{
// Try to fetch any internally stored data first
return
elem
?
dataAttr
(
elem
,
key
,
jQuery
.
data
(
elem
,
key
)
)
:
null
;
// Attempt to get data from the cache
// with the key as-is
data
=
data_user
.
get
(
elem
,
key
);
if
(
data
!==
undefined
)
{
return
data
;
}
// Attempt to "discover" the data in
// HTML5 custom data-* attrs
data
=
dataAttr
(
elem
,
key
,
undefined
);
if
(
data
!==
undefined
)
{
return
data
;
}
}
// As a last resort, attempt to find
// the data by checking AGAIN, but with
// a camelCased key.
data
=
data_user
.
get
(
elem
,
camelKey
);
if
(
data
!==
undefined
)
{
return
data
;
}
// We tried really hard, but the data doesn't exist.
return
undefined
;
}
// Set the data...
this
.
each
(
function
()
{
this
.
each
(
function
()
{
jQuery
.
data
(
this
,
key
,
value
);
// First, attempt to store a copy or reference of any
// data that might've been store with a camelCased key.
var
data
=
data_user
.
get
(
this
,
camelKey
);
// For HTML5 data-* attribute interop, we have to
// store property names with dashes in a camelCase form.
// This might not apply to all properties...*
data_user
.
set
(
this
,
camelKey
,
value
);
// *... In the case of properties that might ACTUALLY
// have dashes, we need to also store a copy of that
// unchanged property.
if
(
/-/
.
test
(
key
)
&&
data
!==
undefined
)
{
data_user
.
set
(
this
,
key
,
value
);
}
});
});
},
null
,
value
,
arguments
.
length
>
1
,
null
,
true
);
},
null
,
value
,
arguments
.
length
>
1
,
null
,
true
);
},
},
removeData
:
function
(
key
)
{
removeData
:
function
(
key
)
{
return
this
.
each
(
function
()
{
return
this
.
each
(
function
()
{
jQuery
.
removeData
(
this
,
key
);
data_user
.
remove
(
this
,
key
);
});
});
}
}
});
});
function
dataAttr
(
elem
,
key
,
data
)
{
function
dataAttr
(
elem
,
key
,
data
)
{
var
name
;
// If nothing was found internally, try to fetch any
// If nothing was found internally, try to fetch any
// data from the HTML5 data-* attribute
// data from the HTML5 data-* attribute
if
(
data
===
undefined
&&
elem
.
nodeType
===
1
)
{
if
(
data
===
undefined
&&
elem
.
nodeType
===
1
)
{
var
name
=
"data-"
+
key
.
replace
(
rmultiDash
,
"-$1"
).
toLowerCase
();
name
=
"data-"
+
key
.
replace
(
rmultiDash
,
"-$1"
).
toLowerCase
();
data
=
elem
.
getAttribute
(
name
);
data
=
elem
.
getAttribute
(
name
);
if
(
typeof
data
===
"string"
)
{
if
(
typeof
data
===
"string"
)
{
...
@@ -308,13 +313,12 @@ function dataAttr( elem, key, data ) {
...
@@ -308,13 +313,12 @@ function dataAttr( elem, key, data ) {
data
===
"null"
?
null
:
data
===
"null"
?
null
:
// Only convert to a number if it doesn't change the string
// Only convert to a number if it doesn't change the string
+
data
+
""
===
data
?
+
data
:
+
data
+
""
===
data
?
+
data
:
rbrace
.
test
(
data
)
?
jQuery
.
parseJSON
(
data
)
:
rbrace
.
test
(
data
)
?
data
;
JSON
.
parse
(
data
)
:
data
;
}
catch
(
e
)
{}
}
catch
(
e
)
{}
// Make sure we set the data so it isn't changed later
// Make sure we set the data so it isn't changed later
jQuery
.
data
(
elem
,
key
,
data
);
data_user
.
set
(
elem
,
key
,
data
);
}
else
{
}
else
{
data
=
undefined
;
data
=
undefined
;
}
}
...
@@ -322,20 +326,3 @@ function dataAttr( elem, key, data ) {
...
@@ -322,20 +326,3 @@ function dataAttr( elem, key, data ) {
return
data
;
return
data
;
}
}
// checks a cache object for emptiness
function
isEmptyDataObject
(
obj
)
{
var
name
;
for
(
name
in
obj
)
{
// if the public data object is empty, the private is still empty
if
(
name
===
"data"
&&
jQuery
.
isEmptyObject
(
obj
[
name
]
)
)
{
continue
;
}
if
(
name
!==
"toJSON"
)
{
return
false
;
}
}
return
true
;
}
src/event.js
View file @
7f94a5cc
...
@@ -24,7 +24,7 @@ jQuery.event = {
...
@@ -24,7 +24,7 @@ jQuery.event = {
var
handleObjIn
,
eventHandle
,
tmp
,
var
handleObjIn
,
eventHandle
,
tmp
,
events
,
t
,
handleObj
,
events
,
t
,
handleObj
,
special
,
handlers
,
type
,
namespaces
,
origType
,
special
,
handlers
,
type
,
namespaces
,
origType
,
elemData
=
jQuery
.
_data
(
elem
);
elemData
=
data_priv
.
get
(
elem
);
// Don't attach events to noData or text/comment nodes (but allow plain objects)
// Don't attach events to noData or text/comment nodes (but allow plain objects)
if
(
!
elemData
)
{
if
(
!
elemData
)
{
...
@@ -130,7 +130,7 @@ jQuery.event = {
...
@@ -130,7 +130,7 @@ jQuery.event = {
var
j
,
origCount
,
tmp
,
var
j
,
origCount
,
tmp
,
events
,
t
,
handleObj
,
events
,
t
,
handleObj
,
special
,
handlers
,
type
,
namespaces
,
origType
,
special
,
handlers
,
type
,
namespaces
,
origType
,
elemData
=
jQuery
.
hasData
(
elem
)
&&
jQuery
.
_data
(
elem
);
elemData
=
data_priv
.
hasData
(
elem
)
&&
data_priv
.
get
(
elem
);
if
(
!
elemData
||
!
(
events
=
elemData
.
events
)
)
{
if
(
!
elemData
||
!
(
events
=
elemData
.
events
)
)
{
return
;
return
;
...
...
src/manipulation.js
View file @
7f94a5cc
...
@@ -328,7 +328,7 @@ jQuery.fn.extend({
...
@@ -328,7 +328,7 @@ jQuery.fn.extend({
for
(
i
=
0
;
i
<
hasScripts
;
i
++
)
{
for
(
i
=
0
;
i
<
hasScripts
;
i
++
)
{
node
=
scripts
[
i
];
node
=
scripts
[
i
];
if
(
rscriptType
.
test
(
node
.
type
||
""
)
&&
if
(
rscriptType
.
test
(
node
.
type
||
""
)
&&
!
jQuery
.
_data
(
node
,
"globalEval"
)
&&
jQuery
.
contains
(
doc
,
node
)
)
{
!
data_priv
.
access
(
node
,
"globalEval"
)
&&
jQuery
.
contains
(
doc
,
node
)
)
{
if
(
node
.
src
)
{
if
(
node
.
src
)
{
// Hope ajax is available...
// Hope ajax is available...
...
@@ -511,11 +511,9 @@ jQuery.extend({
...
@@ -511,11 +511,9 @@ jQuery.extend({
},
},
cleanData
:
function
(
elems
,
/* internal */
acceptData
)
{
cleanData
:
function
(
elems
,
/* internal */
acceptData
)
{
var
id
,
data
,
elem
,
type
,
var
data
,
elem
,
type
,
l
=
elems
.
length
,
l
=
elems
.
length
,
i
=
0
,
i
=
0
,
internalKey
=
jQuery
.
expando
,
cache
=
jQuery
.
cache
,
special
=
jQuery
.
event
.
special
;
special
=
jQuery
.
event
.
special
;
for
(
;
i
<
l
;
i
++
)
{
for
(
;
i
<
l
;
i
++
)
{
...
@@ -523,8 +521,7 @@ jQuery.extend({
...
@@ -523,8 +521,7 @@ jQuery.extend({
if
(
acceptData
||
jQuery
.
acceptData
(
elem
)
)
{
if
(
acceptData
||
jQuery
.
acceptData
(
elem
)
)
{
id
=
elem
[
internalKey
];
data
=
data_priv
.
access
(
elem
);
data
=
id
&&
cache
[
id
];
if
(
data
)
{
if
(
data
)
{
for
(
type
in
data
.
events
)
{
for
(
type
in
data
.
events
)
{
...
@@ -536,14 +533,10 @@ jQuery.extend({
...
@@ -536,14 +533,10 @@ jQuery.extend({
jQuery
.
removeEvent
(
elem
,
type
,
data
.
handle
);
jQuery
.
removeEvent
(
elem
,
type
,
data
.
handle
);
}
}
}
}
// Remove cache only if it was not already removed by jQuery.event.remove
if
(
cache
[
id
]
)
{
delete
cache
[
id
];
delete
elem
[
internalKey
];
}
}
}
}
}
// Discard any remaining `private` and `user` data
data_discard
(
elem
);
}
}
}
}
});
});
...
@@ -576,24 +569,30 @@ function setGlobalEval( elems, refElements ) {
...
@@ -576,24 +569,30 @@ function setGlobalEval( elems, refElements ) {
i
=
0
;
i
=
0
;
for
(
;
i
<
l
;
i
++
)
{
for
(
;
i
<
l
;
i
++
)
{
jQuery
.
_data
(
elems
[
i
],
"globalEval"
,
!
refElements
||
jQuery
.
_data
(
refElements
[
i
],
"globalEval"
)
);
data_priv
.
set
(
elems
[
i
],
"globalEval"
,
!
refElements
||
data_priv
.
get
(
refElements
[
i
],
"globalEval"
)
);
}
}
}
}
function
cloneCopyEvent
(
src
,
dest
)
{
function
cloneCopyEvent
(
src
,
dest
)
{
var
i
,
l
,
type
,
pdataOld
,
pdataCur
,
udataOld
,
udataCur
,
events
;
if
(
dest
.
nodeType
!==
1
||
!
jQuery
.
hasData
(
src
)
)
{
if
(
dest
.
nodeType
!==
1
)
{
return
;
return
;
}
}
var
i
,
l
,
type
,
// 1. Copy private data: events, handlers, etc.
oldData
=
jQuery
.
_data
(
src
),
if
(
data_priv
.
hasData
(
src
)
)
{
curData
=
jQuery
.
_data
(
dest
,
oldData
),
pdataOld
=
data_priv
.
access
(
src
);
events
=
oldData
.
events
;
pdataCur
=
jQuery
.
extend
(
{},
pdataOld
);
events
=
pdataOld
.
events
;
data_priv
.
set
(
dest
,
pdataCur
);
if
(
events
)
{
if
(
events
)
{
delete
curData
.
handle
;
delete
pdataCur
.
handle
;
curData
.
events
=
{};
pdataCur
.
events
=
{};
for
(
type
in
events
)
{
for
(
type
in
events
)
{
for
(
i
=
0
,
l
=
events
[
type
].
length
;
i
<
l
;
i
++
)
{
for
(
i
=
0
,
l
=
events
[
type
].
length
;
i
<
l
;
i
++
)
{
...
@@ -601,13 +600,18 @@ function cloneCopyEvent( src, dest ) {
...
@@ -601,13 +600,18 @@ function cloneCopyEvent( src, dest ) {
}
}
}
}
}
}
}
// 2. Copy user data
if
(
data_user
.
hasData
(
src
)
)
{
udataOld
=
data_user
.
access
(
src
);
udataCur
=
jQuery
.
extend
(
{},
udataOld
);
// make the cloned public data object a copy from the original
data_user
.
set
(
dest
,
udataCur
);
if
(
curData
.
data
)
{
curData
.
data
=
jQuery
.
extend
(
{},
curData
.
data
);
}
}
}
}
function
getAll
(
context
,
tag
)
{
function
getAll
(
context
,
tag
)
{
var
ret
=
context
.
getElementsByTagName
?
context
.
getElementsByTagName
(
tag
||
"*"
)
:
var
ret
=
context
.
getElementsByTagName
?
context
.
getElementsByTagName
(
tag
||
"*"
)
:
context
.
querySelectorAll
?
context
.
querySelectorAll
(
tag
||
"*"
)
:
context
.
querySelectorAll
?
context
.
querySelectorAll
(
tag
||
"*"
)
:
...
...
test/data/onbeforeunload.html
0 → 100644
View file @
7f94a5cc
<!doctype html>
<html>
<script
src=
"/dist/jquery.js"
></script>
<script>
function
report
(
event
)
{
var
payload
=
{
event
:
event
.
type
};
return
top
.
postMessage
(
JSON
.
stringify
(
payload
),
"*"
);
}
jQuery
(
window
).
on
(
"beforeunload"
,
function
(
event
)
{
report
(
event
);
}).
on
(
"load"
,
function
(
event
)
{
setTimeout
(
function
()
{
window
.
location
.
reload
();
},
50
);
});
</script>
</html>
test/data/testrunner.js
View file @
7f94a5cc
...
@@ -200,6 +200,10 @@ var Globals = (function() {
...
@@ -200,6 +200,10 @@ var Globals = (function() {
*/
*/
QUnit
.
expectJqData
=
function
(
elems
,
key
)
{
QUnit
.
expectJqData
=
function
(
elems
,
key
)
{
var
i
,
elem
,
expando
;
var
i
,
elem
,
expando
;
// As of jQuery 2.0, there will be no "cache"-data is
// stored and managed completely below the API surface
if
(
jQuery
.
cache
)
{
QUnit
.
current_testEnvironment
.
checkJqData
=
true
;
QUnit
.
current_testEnvironment
.
checkJqData
=
true
;
if
(
elems
.
jquery
&&
elems
.
toArray
)
{
if
(
elems
.
jquery
&&
elems
.
toArray
)
{
...
@@ -241,6 +245,8 @@ var Globals = (function() {
...
@@ -241,6 +245,8 @@ var Globals = (function() {
}
}
}
}
}
}
}
};
};
QUnit
.
config
.
urlConfig
.
push
(
{
QUnit
.
config
.
urlConfig
.
push
(
{
id
:
"jqdata"
,
id
:
"jqdata"
,
...
...
test/unit/data.js
View file @
7f94a5cc
...
@@ -6,6 +6,33 @@ test("expando", function(){
...
@@ -6,6 +6,33 @@ test("expando", function(){
equal
(
jQuery
.
expando
!==
undefined
,
true
,
"jQuery is exposing the expando"
);
equal
(
jQuery
.
expando
!==
undefined
,
true
,
"jQuery is exposing the expando"
);
});
});
test
(
"jQuery.data & removeData, expected returns"
,
function
()
{
expect
(
2
);
equal
(
jQuery
.
data
(
document
.
body
,
"hello"
,
"world"
),
"world"
,
"jQuery.data( elem, key, value ) returns value"
);
equal
(
jQuery
.
removeData
(
document
.
body
,
"hello"
),
undefined
,
"jQuery.removeData( elem, key, value ) returns undefined"
);
});
test
(
"jQuery._data & _removeData, expected returns"
,
function
()
{
expect
(
2
);
equal
(
jQuery
.
_data
(
document
.
body
,
"hello"
,
"world"
),
"world"
,
"jQuery.data( elem, key, value ) returns value"
);
equal
(
jQuery
.
_removeData
(
document
.
body
,
"hello"
),
undefined
,
"jQuery.removeData( elem, key, value ) returns undefined"
);
});
function
dataTests
(
elem
)
{
function
dataTests
(
elem
)
{
var
oldCacheLength
,
dataObj
,
internalDataObj
,
expected
,
actual
;
var
oldCacheLength
,
dataObj
,
internalDataObj
,
expected
,
actual
;
...
@@ -106,6 +133,10 @@ test("Data is not being set on comment and text nodes", function() {
...
@@ -106,6 +133,10 @@ test("Data is not being set on comment and text nodes", function() {
ok
(
!
jQuery
.
hasData
(
jQuery
(
"<span>text</span>"
).
contents
().
data
(
"foo"
,
0
)
)
);
ok
(
!
jQuery
.
hasData
(
jQuery
(
"<span>text</span>"
).
contents
().
data
(
"foo"
,
0
)
)
);
});
});
/*
// Since the new data system does not rely on exandos, limiting the type of
// nodes that can have data is no longer necessary. jQuery.acceptData is now irrelevant
// and should be removed from the library.
test("jQuery.acceptData", function() {
test("jQuery.acceptData", function() {
expect(9);
expect(9);
...
@@ -127,7 +158,7 @@ test("jQuery.acceptData", function() {
...
@@ -127,7 +158,7 @@ test("jQuery.acceptData", function() {
ok( !jQuery.acceptData( document.createComment("") ), "comment" );
ok( !jQuery.acceptData( document.createComment("") ), "comment" );
ok( !jQuery.acceptData( document.createTextNode("") ), "text" );
ok( !jQuery.acceptData( document.createTextNode("") ), "text" );
});
});
*/
test
(
".data()"
,
function
()
{
test
(
".data()"
,
function
()
{
expect
(
5
);
expect
(
5
);
...
@@ -424,7 +455,7 @@ if (window.JSON && window.JSON.stringify) {
...
@@ -424,7 +455,7 @@ if (window.JSON && window.JSON.stringify) {
}
}
test
(
"jQuery.data should follow html5 specification regarding camel casing"
,
function
()
{
test
(
"jQuery.data should follow html5 specification regarding camel casing"
,
function
()
{
expect
(
1
0
);
expect
(
1
2
);
var
div
=
jQuery
(
"<div id='myObject' data-w-t-f='ftw' data-big-a-little-a='bouncing-b' data-foo='a' data-foo-bar='b' data-foo-bar-baz='c'></div>"
)
var
div
=
jQuery
(
"<div id='myObject' data-w-t-f='ftw' data-big-a-little-a='bouncing-b' data-foo='a' data-foo-bar='b' data-foo-bar-baz='c'></div>"
)
.
prependTo
(
"body"
);
.
prependTo
(
"body"
);
...
@@ -445,6 +476,9 @@ test("jQuery.data should follow html5 specification regarding camel casing", fun
...
@@ -445,6 +476,9 @@ test("jQuery.data should follow html5 specification regarding camel casing", fun
equal
(
div
.
data
(
"fooBar"
),
"d"
,
"Verify updated data-* key"
);
equal
(
div
.
data
(
"fooBar"
),
"d"
,
"Verify updated data-* key"
);
equal
(
div
.
data
(
"foo-bar"
),
"d"
,
"Verify updated data-* key"
);
equal
(
div
.
data
(
"foo-bar"
),
"d"
,
"Verify updated data-* key"
);
equal
(
div
.
data
(
"fooBar"
),
"d"
,
"Verify updated data-* key (fooBar)"
);
equal
(
div
.
data
(
"foo-bar"
),
"d"
,
"Verify updated data-* key (foo-bar)"
);
div
.
remove
();
div
.
remove
();
});
});
...
...
test/unit/event.js
View file @
7f94a5cc
...
@@ -1371,75 +1371,20 @@ test("Submit event can be stopped (#11049)", function() {
...
@@ -1371,75 +1371,20 @@ test("Submit event can be stopped (#11049)", function() {
// Test beforeunload event only if it supported (i.e. not Opera)
// Test beforeunload event only if it supported (i.e. not Opera)
if
(
window
.
onbeforeunload
===
null
)
{
if
(
window
.
onbeforeunload
===
null
)
{
asyncTest
(
"on(beforeunload)"
,
4
,
function
()
{
asyncTest
(
"on(beforeunload)"
,
1
,
function
()
{
var
win
,
var
iframe
=
jQuery
(
jQuery
.
parseHTML
(
"<iframe src='data/onbeforeunload.html'><iframe>"
));
forIE6
=
0
,
fired
=
false
,
iframe
=
jQuery
(
"<iframe src='data/iframe.html' />"
);
iframe
.
appendTo
(
"#qunit-fixture"
).
one
(
"load"
,
function
(
)
{
window
.
onmessage
=
function
(
event
)
{
win
=
this
.
contentWindow
||
this
.
contentDocument
;
var
payload
=
JSON
.
parse
(
event
.
data
)
;
jQuery
(
win
).
on
(
"beforeunload"
,
function
()
{
ok
(
payload
.
event
,
"beforeunload"
,
"beforeunload event"
);
fired
=
true
;
ok
(
true
,
"beforeunload event is fired"
);
});
strictEqual
(
win
.
onbeforeunload
,
null
,
"onbeforeunload property on window object still equals null"
);
// In old Safari beforeunload event will not fire on iframes
jQuery
(
win
).
on
(
"unload"
,
function
()
{
if
(
!
fired
)
{
ok
(
true
,
"This is suppose to be true only in old Safari"
);
checker
();
}
});
jQuery
(
win
).
on
(
"beforeunload"
,
function
()
{
// On iframe in IE6 beforeunload event will not fire if event is binded through window object,
// nevertheless, test should continue
window
.
setTimeout
(
function
()
{
if
(
!
forIE6
)
{
checker
();
}
});
});
win
.
onbeforeunload
=
function
()
{
if
(
!
forIE6
)
{
forIE6
++
;
checker
();
}
};
function
checker
()
{
ok
(
true
,
"window.onbeforeunload handler is called"
);
iframe
=
jQuery
(
"<iframe src='data/iframe.html' />"
);
iframe
.
appendTo
(
"#qunit-fixture"
).
one
(
"load"
,
function
()
{
win
=
iframe
[
0
].
contentWindow
||
iframe
[
0
].
contentDocument
;
jQuery
(
win
).
on
(
"beforeunload"
,
function
()
{
strictEqual
(
win
.
onbeforeunload
,
null
,
"Event handler is fired, even when onbeforeunload property on window is nulled"
);
iframe
.
remove
();
window
.
onmessage
=
null
;
start
();
start
();
});
};
jQuery
(
win
).
on
(
"unload"
,
function
()
{
if
(
!
fired
)
{
jQuery
(
win
).
trigger
(
"beforeunload"
);
}
});
win
.
onbeforeunload
=
null
;
win
.
location
.
reload
();
});
}
win
.
location
.
reload
();
iframe
.
appendTo
(
"#qunit-fixture"
);
});
});
});
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment