diff --git a/.gitignore b/.gitignore index 6cd54797..a77d67a9 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,7 @@ dist *~ *.diff *.patch +test/qunit +src/sizzle /*.html .DS_Store diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 19c60418..00000000 --- a/.gitmodules +++ /dev/null @@ -1,6 +0,0 @@ -[submodule "src/sizzle"] - path = src/sizzle - url = git://github.com/jquery/sizzle.git -[submodule "test/qunit"] - path = test/qunit - url = git://github.com/jquery/qunit.git diff --git a/Makefile b/Makefile index 06cee5de..bf41bccc 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,5 @@ +V ?= 0 + SRC_DIR = src TEST_DIR = test BUILD_DIR = build @@ -10,7 +12,6 @@ COMPILER = ${JS_ENGINE} ${BUILD_DIR}/uglify.js --unsafe POST_COMPILER = ${JS_ENGINE} ${BUILD_DIR}/post-compile.js BASE_FILES = ${SRC_DIR}/core.js\ - ${SRC_DIR}/deferred.js\ ${SRC_DIR}/support.js\ ${SRC_DIR}/data.js\ ${SRC_DIR}/queue.js\ @@ -36,21 +37,48 @@ JQ = ${DIST_DIR}/jquery.js JQ_MIN = ${DIST_DIR}/jquery.min.js SIZZLE_DIR = ${SRC_DIR}/sizzle +QUNIT_DIR = ${TEST_DIR}/qunit JQ_VER = $(shell cat version.txt) VER = sed "s/@VERSION/${JQ_VER}/" DATE=$(shell git log -1 --pretty=format:%ad) -all: update_submodules core - -core: jquery min lint +all: jquery min lint @@echo "jQuery build complete." ${DIST_DIR}: @@mkdir -p ${DIST_DIR} -jquery: ${JQ} +ifeq ($(strip $(V)),0) +verbose = --quiet +else ifeq ($(strip $(V)),1) +verbose = +else +verbose = --verbose +endif + +define clone_or_pull +-@@if test ! -d $(strip ${1})/.git; then \ + echo "Cloning $(strip ${1})..."; \ + git clone $(strip ${verbose}) --depth=1 $(strip ${2}) $(strip ${1}); \ + else \ + echo "Pulling $(strip ${1})..."; \ + git --git-dir=$(strip ${1})/.git pull $(strip ${verbose}) origin master; \ + fi + +endef + +${QUNIT_DIR}: + $(call clone_or_pull, ${QUNIT_DIR}, git://github.com/jquery/qunit.git) + +${SIZZLE_DIR}: + $(call clone_or_pull, ${SIZZLE_DIR}, git://github.com/jeresig/sizzle.git) + +init: ${QUNIT_DIR} ${SIZZLE_DIR} + +jquery: init ${JQ} +jq: init ${JQ} ${JQ}: ${MODULES} | ${DIST_DIR} @@echo "Building" ${JQ} @@ -73,9 +101,9 @@ lint: jquery echo "You must have NodeJS installed in order to test jQuery against JSLint."; \ fi -min: jquery ${JQ_MIN} +min: ${JQ_MIN} -${JQ_MIN}: ${JQ} +${JQ_MIN}: jquery @@if test ! -z ${JS_ENGINE}; then \ echo "Minifying jQuery" ${JQ_MIN}; \ ${COMPILER} ${JQ} > ${JQ_MIN}.tmp; \ @@ -93,28 +121,7 @@ clean: @@echo "Removing built copy of Sizzle" @@rm -f src/selector.js -distclean: clean - @@echo "Removing submodules" + @@echo "Removing cloned directories" @@rm -rf test/qunit src/sizzle -# change pointers for submodules and update them to what is specified in jQuery -# --merge doesn't work when doing an initial clone, thus test if we have non-existing -# submodules, then do an real update -update_submodules: - @@if [ -d .git ]; then \ - if git submodule status | grep -q -E '^-'; then \ - git submodule update --init --recursive; \ - else \ - git submodule update --init --recursive --merge; \ - fi; \ - fi; - -# update the submodules to the latest at the most logical branch -pull_submodules: - @@git submodule foreach "git pull \$$(git config remote.origin.url)" - @@git submodule summary - -pull: pull_submodules - @@git pull ${REMOTE} ${BRANCH} - -.PHONY: all jquery lint min clean distclean update_submodules pull_submodules pull core +.PHONY: all jquery lint min init jq clean diff --git a/README.md b/README.md index a54a02df..d56576c8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[jQuery](http://jquery.com/) - New Wave JavaScript +[jQuery](http://jquery.com/) - New Wave Javascript ================================================== What you need to build your own jQuery @@ -56,89 +56,6 @@ Sometimes, the various git repositories get into an inconsistent state where bui (usually this results in the jquery.js or jquery.min.js being 0 bytes). If this happens, run `make clean`, then run `make` again. -Git for dummies ---------------- - -As the source code is handled by the version control system Git, it's useful to know some features used. - -### Submodules ### - -The repository uses submodules, which normally are handled directly by the Makefile, but sometimes you want to -be able to work with them manually. - -Following are the steps to manually get the submodules: - -1. `git clone https://github.com/jquery/jquery.git` -2. `git submodule init` -3. `git submodule update` - -Or: - -1. `git clone https://github.com/jquery/jquery.git` -2. `git submodule update --init` - -Or: - -1. `git clone --recursive https://github.com/jquery/jquery.git` - -If you want to work inside a submodule, it is possible, but first you need to checkout a branch: - -1. `cd src/sizzle` -2. `git checkout master` - -After you've committed your changes to the submodule, you'll update the jquery project to point to the new commit, -but remember to push the submodule changes before pushing the new jquery commit: - -1. `cd src/sizzle` -2. `git push origin master` -3. `cd ..` -4. `git add src/sizzle` -5. `git commit` - -The makefile has some targets to simplify submodule handling: - -#### `make update_submodules` #### - -checks out the commit pointed to by jquery, but merges your local changes, if any. This target is executed -when you are doing a normal `make`. - -#### `make pull_submodules` #### - -updates the content of the submodules to what is probably the latest upstream code. - -#### `make pull` #### - -make a `make pull_submodules` and after that a `git pull`. if you have no remote tracking in your master branch, you can -execute this command as `make pull REMOTE=origin BRANCH=master` instead. - -### cleaning ### - -If you want to purge your working directory back to the status of upstream, following commands can be used (remember everything you've worked on is gone after these): - -1. `git reset --hard upstream/master` -2. `git clean -fdx` - -### rebasing ### - -For feature/topic branches, you should always used the `--rebase` flag to `git pull`, or if you are usually handling many temporary "to be in a github pull request" branches, run following to automate this: - -* `git config branch.autosetuprebase local` (see `man git-config` for more information) - -### handling merge conflicts ### - -If you're getting merge conflicts when merging, instead of editing the conflicted files manually, you can use the feature -`git mergetool`. Even though the default tool `xxdiff` looks awful/old, it's rather useful. - -Following are some commands that can be used there: - -* `Ctrl + Alt + M` - automerge as much as possible -* `b` - jump to next merge conflict -* `s` - change the order of the conflicted lines -* `u` - undo an merge -* `left mouse button` - mark a block to be the winner -* `middle mouse button` - mark a line to be the winner -* `Ctrl + S` - save -* `Ctrl + Q` - quit Questions? ---------- diff --git a/build/lib/parse-js.js b/build/lib/parse-js.js index 8edecb73..7e4fd0e2 100644 --- a/build/lib/parse-js.js +++ b/build/lib/parse-js.js @@ -182,6 +182,8 @@ var OPERATORS = array_to_hash([ ">>=", "<<=", ">>>=", + "~=", + "%=", "|=", "^=", "&=", @@ -189,7 +191,7 @@ var OPERATORS = array_to_hash([ "||" ]); -var WHITESPACE_CHARS = array_to_hash(characters(" \n\r\t\u200b")); +var WHITESPACE_CHARS = array_to_hash(characters(" \n\r\t")); var PUNC_BEFORE_EXPRESSION = array_to_hash(characters("[{}(,.;:")); @@ -199,47 +201,20 @@ var REGEXP_MODIFIERS = array_to_hash(characters("gmsiy")); /* -----[ Tokenizer ]----- */ -// regexps adapted from http://xregexp.com/plugins/#unicode -var UNICODE = { - letter: new RegExp("[\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u0523\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0621-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971\\u0972\\u097B-\\u097F\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C33\\u0C35-\\u0C39\\u0C3D\\u0C58\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D28\\u0D2A-\\u0D39\\u0D3D\\u0D60\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC\\u0EDD\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8B\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10D0-\\u10FA\\u10FC\\u1100-\\u1159\\u115F-\\u11A2\\u11A8-\\u11F9\\u1200-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u1676\\u1681-\\u169A\\u16A0-\\u16EA\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u1900-\\u191C\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19A9\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u2094\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2C6F\\u2C71-\\u2C7D\\u2C80-\\u2CE4\\u2D00-\\u2D25\\u2D30-\\u2D65\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31B7\\u31F0-\\u31FF\\u3400\\u4DB5\\u4E00\\u9FC3\\uA000-\\uA48C\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA65F\\uA662-\\uA66E\\uA67F-\\uA697\\uA717-\\uA71F\\uA722-\\uA788\\uA78B\\uA78C\\uA7FB-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA90A-\\uA925\\uA930-\\uA946\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAC00\\uD7A3\\uF900-\\uFA2D\\uFA30-\\uFA6A\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]"), - non_spacing_mark: new RegExp("[\\u0300-\\u036F\\u0483-\\u0487\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u0610-\\u061A\\u064B-\\u065E\\u0670\\u06D6-\\u06DC\\u06DF-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0711\\u0730-\\u074A\\u07A6-\\u07B0\\u07EB-\\u07F3\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u082D\\u0900-\\u0902\\u093C\\u0941-\\u0948\\u094D\\u0951-\\u0955\\u0962\\u0963\\u0981\\u09BC\\u09C1-\\u09C4\\u09CD\\u09E2\\u09E3\\u0A01\\u0A02\\u0A3C\\u0A41\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A70\\u0A71\\u0A75\\u0A81\\u0A82\\u0ABC\\u0AC1-\\u0AC5\\u0AC7\\u0AC8\\u0ACD\\u0AE2\\u0AE3\\u0B01\\u0B3C\\u0B3F\\u0B41-\\u0B44\\u0B4D\\u0B56\\u0B62\\u0B63\\u0B82\\u0BC0\\u0BCD\\u0C3E-\\u0C40\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C62\\u0C63\\u0CBC\\u0CBF\\u0CC6\\u0CCC\\u0CCD\\u0CE2\\u0CE3\\u0D41-\\u0D44\\u0D4D\\u0D62\\u0D63\\u0DCA\\u0DD2-\\u0DD4\\u0DD6\\u0E31\\u0E34-\\u0E3A\\u0E47-\\u0E4E\\u0EB1\\u0EB4-\\u0EB9\\u0EBB\\u0EBC\\u0EC8-\\u0ECD\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F71-\\u0F7E\\u0F80-\\u0F84\\u0F86\\u0F87\\u0F90-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u102D-\\u1030\\u1032-\\u1037\\u1039\\u103A\\u103D\\u103E\\u1058\\u1059\\u105E-\\u1060\\u1071-\\u1074\\u1082\\u1085\\u1086\\u108D\\u109D\\u135F\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17B7-\\u17BD\\u17C6\\u17C9-\\u17D3\\u17DD\\u180B-\\u180D\\u18A9\\u1920-\\u1922\\u1927\\u1928\\u1932\\u1939-\\u193B\\u1A17\\u1A18\\u1A56\\u1A58-\\u1A5E\\u1A60\\u1A62\\u1A65-\\u1A6C\\u1A73-\\u1A7C\\u1A7F\\u1B00-\\u1B03\\u1B34\\u1B36-\\u1B3A\\u1B3C\\u1B42\\u1B6B-\\u1B73\\u1B80\\u1B81\\u1BA2-\\u1BA5\\u1BA8\\u1BA9\\u1C2C-\\u1C33\\u1C36\\u1C37\\u1CD0-\\u1CD2\\u1CD4-\\u1CE0\\u1CE2-\\u1CE8\\u1CED\\u1DC0-\\u1DE6\\u1DFD-\\u1DFF\\u20D0-\\u20DC\\u20E1\\u20E5-\\u20F0\\u2CEF-\\u2CF1\\u2DE0-\\u2DFF\\u302A-\\u302F\\u3099\\u309A\\uA66F\\uA67C\\uA67D\\uA6F0\\uA6F1\\uA802\\uA806\\uA80B\\uA825\\uA826\\uA8C4\\uA8E0-\\uA8F1\\uA926-\\uA92D\\uA947-\\uA951\\uA980-\\uA982\\uA9B3\\uA9B6-\\uA9B9\\uA9BC\\uAA29-\\uAA2E\\uAA31\\uAA32\\uAA35\\uAA36\\uAA43\\uAA4C\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uABE5\\uABE8\\uABED\\uFB1E\\uFE00-\\uFE0F\\uFE20-\\uFE26]"), - space_combining_mark: new RegExp("[\\u0903\\u093E-\\u0940\\u0949-\\u094C\\u094E\\u0982\\u0983\\u09BE-\\u09C0\\u09C7\\u09C8\\u09CB\\u09CC\\u09D7\\u0A03\\u0A3E-\\u0A40\\u0A83\\u0ABE-\\u0AC0\\u0AC9\\u0ACB\\u0ACC\\u0B02\\u0B03\\u0B3E\\u0B40\\u0B47\\u0B48\\u0B4B\\u0B4C\\u0B57\\u0BBE\\u0BBF\\u0BC1\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCC\\u0BD7\\u0C01-\\u0C03\\u0C41-\\u0C44\\u0C82\\u0C83\\u0CBE\\u0CC0-\\u0CC4\\u0CC7\\u0CC8\\u0CCA\\u0CCB\\u0CD5\\u0CD6\\u0D02\\u0D03\\u0D3E-\\u0D40\\u0D46-\\u0D48\\u0D4A-\\u0D4C\\u0D57\\u0D82\\u0D83\\u0DCF-\\u0DD1\\u0DD8-\\u0DDF\\u0DF2\\u0DF3\\u0F3E\\u0F3F\\u0F7F\\u102B\\u102C\\u1031\\u1038\\u103B\\u103C\\u1056\\u1057\\u1062-\\u1064\\u1067-\\u106D\\u1083\\u1084\\u1087-\\u108C\\u108F\\u109A-\\u109C\\u17B6\\u17BE-\\u17C5\\u17C7\\u17C8\\u1923-\\u1926\\u1929-\\u192B\\u1930\\u1931\\u1933-\\u1938\\u19B0-\\u19C0\\u19C8\\u19C9\\u1A19-\\u1A1B\\u1A55\\u1A57\\u1A61\\u1A63\\u1A64\\u1A6D-\\u1A72\\u1B04\\u1B35\\u1B3B\\u1B3D-\\u1B41\\u1B43\\u1B44\\u1B82\\u1BA1\\u1BA6\\u1BA7\\u1BAA\\u1C24-\\u1C2B\\u1C34\\u1C35\\u1CE1\\u1CF2\\uA823\\uA824\\uA827\\uA880\\uA881\\uA8B4-\\uA8C3\\uA952\\uA953\\uA983\\uA9B4\\uA9B5\\uA9BA\\uA9BB\\uA9BD-\\uA9C0\\uAA2F\\uAA30\\uAA33\\uAA34\\uAA4D\\uAA7B\\uABE3\\uABE4\\uABE6\\uABE7\\uABE9\\uABEA\\uABEC]"), - connector_punctuation: new RegExp("[\\u005F\\u203F\\u2040\\u2054\\uFE33\\uFE34\\uFE4D-\\uFE4F\\uFF3F]") +function is_alphanumeric_char(ch) { + ch = ch.charCodeAt(0); + return (ch >= 48 && ch <= 57) || + (ch >= 65 && ch <= 90) || + (ch >= 97 && ch <= 122); }; -function is_letter(ch) { - return UNICODE.letter.test(ch); +function is_identifier_char(ch) { + return is_alphanumeric_char(ch) || ch == "$" || ch == "_"; }; function is_digit(ch) { ch = ch.charCodeAt(0); - return ch >= 48 && ch <= 57; //XXX: find out if "UnicodeDigit" means something else than 0..9 -}; - -function is_alphanumeric_char(ch) { - return is_digit(ch) || is_letter(ch); -}; - -function is_unicode_combining_mark(ch) { - return UNICODE.non_spacing_mark.test(ch) || UNICODE.space_combining_mark.test(ch); -}; - -function is_unicode_connector_punctuation(ch) { - return UNICODE.connector_punctuation.test(ch); -}; - -function is_identifier_start(ch) { - return ch == "$" || ch == "_" || is_letter(ch); -}; - -function is_identifier_char(ch) { - return is_identifier_start(ch) - || is_unicode_combining_mark(ch) - || is_digit(ch) - || is_unicode_connector_punctuation(ch) - || ch == "\u200c" // zero-width non-joiner - || ch == "\u200d" // zero-width joiner (in my ECMA-262 PDF, this is also 200c) - ; + return ch >= 48 && ch <= 57; }; function parse_js_number(num) { @@ -278,19 +253,18 @@ function is_token(token, type, val) { var EX_EOF = {}; -function tokenizer($TEXT) { +function tokenizer($TEXT, skip_comments) { var S = { - text : $TEXT.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, ''), - pos : 0, - tokpos : 0, - line : 0, - tokline : 0, - col : 0, - tokcol : 0, - newline_before : false, - regex_allowed : false, - comments_before : [] + text : $TEXT.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, ''), + pos : 0, + tokpos : 0, + line : 0, + tokline : 0, + col : 0, + tokcol : 0, + newline_before : false, + regex_allowed : false }; function peek() { return S.text.charAt(S.pos); }; @@ -325,7 +299,7 @@ function tokenizer($TEXT) { S.tokpos = S.pos; }; - function token(type, value, is_comment) { + function token(type, value) { S.regex_allowed = ((type == "operator" && !HOP(UNARY_POSTFIX, value)) || (type == "keyword" && HOP(KEYWORDS_BEFORE_EXPRESSION, value)) || (type == "punc" && HOP(PUNC_BEFORE_EXPRESSION, value))); @@ -337,10 +311,6 @@ function tokenizer($TEXT) { pos : S.tokpos, nlb : S.newline_before }; - if (!is_comment) { - ret.comments_before = S.comments_before; - S.comments_before = []; - } S.newline_before = false; return ret; }; @@ -381,7 +351,7 @@ function tokenizer($TEXT) { if (ch == "+") return after_e; after_e = false; if (ch == ".") { - if (!has_dot && !has_x) + if (!has_dot) return has_dot = true; return false; } @@ -447,7 +417,7 @@ function tokenizer($TEXT) { ret = S.text.substring(S.pos, i); S.pos = i; } - return token("comment1", ret, true); + return token("comment1", ret); }; function read_multiline_comment() { @@ -455,41 +425,14 @@ function tokenizer($TEXT) { return with_eof_error("Unterminated multiline comment", function(){ var i = find("*/", true), text = S.text.substring(S.pos, i), - tok = token("comment2", text, true); + tok = token("comment2", text); S.pos = i + 2; S.line += text.split("\n").length - 1; S.newline_before = text.indexOf("\n") >= 0; - - // https://github.com/mishoo/UglifyJS/issues/#issue/100 - if (/^@cc_on/i.test(text)) { - warn("WARNING: at line " + S.line); - warn("*** Found \"conditional comment\": " + text); - warn("*** UglifyJS DISCARDS ALL COMMENTS. This means your code might no longer work properly in Internet Explorer."); - } - return tok; }); }; - function read_name() { - var backslash = false, name = "", ch; - while ((ch = peek()) != null) { - if (!backslash) { - if (ch == "\\") backslash = true, next(); - else if (is_identifier_char(ch)) name += next(); - else break; - } - else { - if (ch != "u") parse_error("Expecting UnicodeEscapeSequence -- uXXXX"); - ch = read_escaped_char(); - if (!is_identifier_char(ch)) parse_error("Unicode char: " + ch.charCodeAt(0) + " is not valid in identifier"); - name += ch; - backslash = false; - } - } - return name; - }; - function read_regexp() { return with_eof_error("Unterminated regular expression", function(){ var prev_backslash = false, regexp = "", ch, in_class = false; @@ -509,14 +452,15 @@ function tokenizer($TEXT) { } else { regexp += ch; } - var mods = read_name(); + var mods = read_while(function(ch){ + return HOP(REGEXP_MODIFIERS, ch); + }); return token("regexp", [ regexp, mods ]); }); }; function read_operator(prefix) { function grow(op) { - if (!peek()) return op; var bigger = op + peek(); if (HOP(OPERATORS, bigger)) { next(); @@ -528,18 +472,19 @@ function tokenizer($TEXT) { return token("operator", grow(prefix || next())); }; - function handle_slash() { + var handle_slash = skip_comments ? function() { next(); var regex_allowed = S.regex_allowed; switch (peek()) { - case "/": - S.comments_before.push(read_line_comment()); - S.regex_allowed = regex_allowed; - return next_token(); - case "*": - S.comments_before.push(read_multiline_comment()); - S.regex_allowed = regex_allowed; - return next_token(); + case "/": read_line_comment(); S.regex_allowed = regex_allowed; return next_token(); + case "*": read_multiline_comment(); S.regex_allowed = regex_allowed; return next_token(); + } + return S.regex_allowed ? read_regexp() : read_operator("/"); + } : function() { + next(); + switch (peek()) { + case "/": return read_line_comment(); + case "*": return read_multiline_comment(); } return S.regex_allowed ? read_regexp() : read_operator("/"); }; @@ -552,7 +497,7 @@ function tokenizer($TEXT) { }; function read_word() { - var word = read_name(); + var word = read_while(is_identifier_char); return !HOP(KEYWORDS, word) ? token("name", word) : HOP(OPERATORS, word) @@ -584,7 +529,7 @@ function tokenizer($TEXT) { if (ch == ".") return handle_dot(); if (ch == "/") return handle_slash(); if (HOP(OPERATOR_CHARS, ch)) return read_operator(); - if (ch == "\\" || is_identifier_start(ch)) return read_word(); + if (is_identifier_char(ch)) return read_word(); parse_error("Unexpected character '" + ch + "'"); }; @@ -620,7 +565,7 @@ var ASSIGNMENT = (function(a, ret, i){ } return ret; })( - ["+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&="], + ["+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "~=", "%=", "|=", "^=", "&="], { "=": true }, 0 ); @@ -663,16 +608,16 @@ function NodeWithToken(str, start, end) { NodeWithToken.prototype.toString = function() { return this.name; }; -function parse($TEXT, exigent_mode, embed_tokens) { +function parse($TEXT, strict_mode, embed_tokens) { var S = { - input : typeof $TEXT == "string" ? tokenizer($TEXT, true) : $TEXT, - token : null, - prev : null, - peeked : null, - in_function : 0, - in_loop : 0, - labels : [] + input: tokenizer($TEXT, true), + token: null, + prev: null, + peeked: null, + in_function: 0, + in_loop: 0, + labels: [] }; S.token = next(); @@ -726,7 +671,7 @@ function parse($TEXT, exigent_mode, embed_tokens) { function expect(punc) { return expect_token("punc", punc); }; function can_insert_semicolon() { - return !exigent_mode && ( + return !strict_mode && ( S.token.nlb || is("eof") || is("punc", "}") ); }; @@ -748,20 +693,17 @@ function parse($TEXT, exigent_mode, embed_tokens) { }; function add_tokens(str, start, end) { - return str instanceof NodeWithToken ? str : new NodeWithToken(str, start, end); + return new NodeWithToken(str, start, end); }; - function maybe_embed_tokens(parser) { - if (embed_tokens) return function() { - var start = S.token; - var ast = parser.apply(this, arguments); - ast[0] = add_tokens(ast[0], start, prev()); - return ast; - }; - else return parser; - }; + var statement = embed_tokens ? function() { + var start = S.token; + var stmt = $statement(); + stmt[0] = add_tokens(stmt[0], start, prev()); + return stmt; + } : $statement; - var statement = maybe_embed_tokens(function() { + function $statement() { if (is("operator", "/")) { S.peeked = null; S.token = S.input(true); // force regexp @@ -855,12 +797,12 @@ function parse($TEXT, exigent_mode, embed_tokens) { unexpected(); } } - }); + }; function labeled_statement(label) { S.labels.push(label); var start = S.token, stat = statement(); - if (exigent_mode && !HOP(STATEMENTS_WITH_LABELS, stat[0])) + if (strict_mode && !HOP(STATEMENTS_WITH_LABELS, stat[0])) unexpected(start); S.labels.pop(); return as("label", label, stat); @@ -885,35 +827,29 @@ function parse($TEXT, exigent_mode, embed_tokens) { function for_() { expect("("); - var init = null; - if (!is("punc", ";")) { - init = is("keyword", "var") - ? (next(), var_(true)) - : expression(true, true); - if (is("operator", "in")) - return for_in(init); + var has_var = is("keyword", "var"); + if (has_var) + next(); + if (is("name") && is_token(peek(), "operator", "in")) { + // for (i in foo) + var name = S.token.value; + next(); next(); + var obj = expression(); + expect(")"); + return as("for-in", has_var, name, obj, in_loop(statement)); + } else { + // classic for + var init = is("punc", ";") ? null : has_var ? var_() : expression(); + expect(";"); + var test = is("punc", ";") ? null : expression(); + expect(";"); + var step = is("punc", ")") ? null : expression(); + expect(")"); + return as("for", init, test, step, in_loop(statement)); } - return regular_for(init); }; - function regular_for(init) { - expect(";"); - var test = is("punc", ";") ? null : expression(); - expect(";"); - var step = is("punc", ")") ? null : expression(); - expect(")"); - return as("for", init, test, step, in_loop(statement)); - }; - - function for_in(init) { - var lhs = init[0] == "var" ? as("name", init[1][0]) : init; - next(); - var obj = expression(); - expect(")"); - return as("for-in", init, lhs, obj, in_loop(statement)); - }; - - var function_ = maybe_embed_tokens(function(in_statement) { + function function_(in_statement) { var name = is("name") ? prog1(S.token.value, next) : null; if (in_statement && !name) unexpected(); @@ -941,7 +877,7 @@ function parse($TEXT, exigent_mode, embed_tokens) { S.in_loop = loop; return a; })()); - }); + }; function if_() { var cond = parenthesised(), body = statement(), belse; @@ -1010,7 +946,7 @@ function parse($TEXT, exigent_mode, embed_tokens) { return as("try", body, bcatch, bfinally); }; - function vardefs(no_in) { + function vardefs() { var a = []; for (;;) { if (!is("name")) @@ -1019,7 +955,7 @@ function parse($TEXT, exigent_mode, embed_tokens) { next(); if (is("operator", "=")) { next(); - a.push([ name, expression(false, no_in) ]); + a.push([ name, expression(false) ]); } else { a.push([ name ]); } @@ -1030,8 +966,8 @@ function parse($TEXT, exigent_mode, embed_tokens) { return a; }; - function var_(no_in) { - return as("var", vardefs(no_in)); + function var_() { + return as("var", vardefs()); }; function const_() { @@ -1049,7 +985,7 @@ function parse($TEXT, exigent_mode, embed_tokens) { return subscripts(as("new", newexp, args), true); }; - var expr_atom = maybe_embed_tokens(function(allow_calls) { + function expr_atom(allow_calls) { if (is("operator", "new")) { next(); return new_(); @@ -1084,32 +1020,29 @@ function parse($TEXT, exigent_mode, embed_tokens) { return subscripts(prog1(atom, next), allow_calls); } unexpected(); - }); + }; - function expr_list(closing, allow_trailing_comma, allow_empty) { + function expr_list(closing, allow_trailing_comma) { var first = true, a = []; while (!is("punc", closing)) { if (first) first = false; else expect(","); - if (allow_trailing_comma && is("punc", closing)) break; - if (is("punc", ",") && allow_empty) { - a.push([ "atom", "undefined" ]); - } else { - a.push(expression(false)); - } + if (allow_trailing_comma && is("punc", closing)) + break; + a.push(expression(false)); } next(); return a; }; function array_() { - return as("array", expr_list("]", !exigent_mode, true)); + return as("array", expr_list("]", !strict_mode)); }; function object_() { var first = true, a = []; while (!is("punc", "}")) { if (first) first = false; else expect(","); - if (!exigent_mode && is("punc", "}")) + if (!strict_mode && is("punc", "}")) // allow trailing comma break; var type = S.token.type; @@ -1172,68 +1105,64 @@ function parse($TEXT, exigent_mode, embed_tokens) { return as(tag, op, expr); }; - function expr_op(left, min_prec, no_in) { + function expr_op(left, min_prec) { var op = is("operator") ? S.token.value : null; - if (op && op == "in" && no_in) op = null; var prec = op != null ? PRECEDENCE[op] : null; if (prec != null && prec > min_prec) { next(); - var right = expr_op(expr_atom(true), prec, no_in); - return expr_op(as("binary", op, left, right), min_prec, no_in); + var right = expr_op(expr_atom(true), prec); + return expr_op(as("binary", op, left, right), min_prec); } return left; }; - function expr_ops(no_in) { - return expr_op(expr_atom(true), 0, no_in); + function expr_ops() { + return expr_op(expr_atom(true), 0); }; - function maybe_conditional(no_in) { - var expr = expr_ops(no_in); + function maybe_conditional() { + var expr = expr_ops(); if (is("operator", "?")) { next(); var yes = expression(false); expect(":"); - return as("conditional", expr, yes, expression(false, no_in)); + return as("conditional", expr, yes, expression(false)); } return expr; }; function is_assignable(expr) { - if (!exigent_mode) return true; switch (expr[0]) { case "dot": case "sub": - case "new": - case "call": return true; case "name": return expr[1] != "this"; } }; - function maybe_assign(no_in) { - var left = maybe_conditional(no_in), val = S.token.value; + function maybe_assign() { + var left = maybe_conditional(), val = S.token.value; if (is("operator") && HOP(ASSIGNMENT, val)) { if (is_assignable(left)) { next(); - return as("assign", ASSIGNMENT[val], left, maybe_assign(no_in)); + return as("assign", ASSIGNMENT[val], left, maybe_assign()); } croak("Invalid assignment"); } return left; }; - var expression = maybe_embed_tokens(function(commas, no_in) { + function expression(commas) { if (arguments.length == 0) commas = true; - var expr = maybe_assign(no_in); + var expr = maybe_assign(); if (commas && is("punc", ",")) { next(); - return as("seq", expr, expression(true, no_in)); + return as("seq", expr, expression()); } return expr; - }); + }; function in_loop(cont) { try { @@ -1293,8 +1222,6 @@ function HOP(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }; -var warn = function() {}; - /* -----[ Exports ]----- */ exports.tokenizer = tokenizer; @@ -1310,6 +1237,3 @@ exports.KEYWORDS = KEYWORDS; exports.ATOMIC_START_TOKEN = ATOMIC_START_TOKEN; exports.OPERATORS = OPERATORS; exports.is_alphanumeric_char = is_alphanumeric_char; -exports.set_logger = function(logger) { - warn = logger; -}; diff --git a/build/lib/process.js b/build/lib/process.js index 3878c8d6..edcf599d 100644 --- a/build/lib/process.js +++ b/build/lib/process.js @@ -10,13 +10,14 @@ Exported functions: - - ast_mangle(ast, options) -- mangles the variable/function names - in the AST. Returns an AST. + - ast_mangle(ast, include_toplevel) -- mangles the + variable/function names in the AST. Returns an AST. Pass true + as second argument to mangle toplevel names too. - ast_squeeze(ast) -- employs various optimizations to make the final generated code even smaller. Returns an AST. - - gen_code(ast, options) -- generates JS code from the AST. Pass + - gen_code(ast, beautify) -- generates JS code from the AST. Pass true (or an object, see the code for some options) as second argument to get "pretty" (indented) code. @@ -68,137 +69,139 @@ var jsp = require("./parse-js"), function ast_walker(ast) { function _vardefs(defs) { - return [ this[0], MAP(defs, function(def){ + return MAP(defs, function(def){ var a = [ def[0] ]; if (def.length > 1) a[1] = walk(def[1]); return a; - }) ]; - }; - function _block(statements) { - var out = [ this[0] ]; - if (statements != null) - out.push(MAP(statements, walk)); - return out; + }); }; var walkers = { "string": function(str) { - return [ this[0], str ]; + return [ "string", str ]; }, "num": function(num) { - return [ this[0], num ]; + return [ "num", num ]; }, "name": function(name) { - return [ this[0], name ]; + return [ "name", name ]; }, "toplevel": function(statements) { - return [ this[0], MAP(statements, walk) ]; + return [ "toplevel", MAP(statements, walk) ]; + }, + "block": function(statements) { + var out = [ "block" ]; + if (statements != null) + out.push(MAP(statements, walk)); + return out; + }, + "var": function(defs) { + return [ "var", _vardefs(defs) ]; + }, + "const": function(defs) { + return [ "const", _vardefs(defs) ]; }, - "block": _block, - "splice": _block, - "var": _vardefs, - "const": _vardefs, "try": function(t, c, f) { return [ - this[0], + "try", MAP(t, walk), c != null ? [ c[0], MAP(c[1], walk) ] : null, f != null ? MAP(f, walk) : null ]; }, "throw": function(expr) { - return [ this[0], walk(expr) ]; + return [ "throw", walk(expr) ]; }, "new": function(ctor, args) { - return [ this[0], walk(ctor), MAP(args, walk) ]; + return [ "new", walk(ctor), MAP(args, walk) ]; }, "switch": function(expr, body) { - return [ this[0], walk(expr), MAP(body, function(branch){ + return [ "switch", walk(expr), MAP(body, function(branch){ return [ branch[0] ? walk(branch[0]) : null, MAP(branch[1], walk) ]; }) ]; }, "break": function(label) { - return [ this[0], label ]; + return [ "break", label ]; }, "continue": function(label) { - return [ this[0], label ]; + return [ "continue", label ]; }, "conditional": function(cond, t, e) { - return [ this[0], walk(cond), walk(t), walk(e) ]; + return [ "conditional", walk(cond), walk(t), walk(e) ]; }, "assign": function(op, lvalue, rvalue) { - return [ this[0], op, walk(lvalue), walk(rvalue) ]; + return [ "assign", op, walk(lvalue), walk(rvalue) ]; }, "dot": function(expr) { - return [ this[0], walk(expr) ].concat(slice(arguments, 1)); + return [ "dot", walk(expr) ].concat(slice(arguments, 1)); }, "call": function(expr, args) { - return [ this[0], walk(expr), MAP(args, walk) ]; + return [ "call", walk(expr), MAP(args, walk) ]; }, "function": function(name, args, body) { - return [ this[0], name, args.slice(), MAP(body, walk) ]; + return [ "function", name, args.slice(), MAP(body, walk) ]; }, "defun": function(name, args, body) { - return [ this[0], name, args.slice(), MAP(body, walk) ]; + return [ "defun", name, args.slice(), MAP(body, walk) ]; }, "if": function(conditional, t, e) { - return [ this[0], walk(conditional), walk(t), walk(e) ]; + return [ "if", walk(conditional), walk(t), walk(e) ]; }, "for": function(init, cond, step, block) { - return [ this[0], walk(init), walk(cond), walk(step), walk(block) ]; + return [ "for", walk(init), walk(cond), walk(step), walk(block) ]; }, - "for-in": function(vvar, key, hash, block) { - return [ this[0], walk(vvar), walk(key), walk(hash), walk(block) ]; + "for-in": function(has_var, key, hash, block) { + return [ "for-in", has_var, key, walk(hash), walk(block) ]; }, "while": function(cond, block) { - return [ this[0], walk(cond), walk(block) ]; + return [ "while", walk(cond), walk(block) ]; }, "do": function(cond, block) { - return [ this[0], walk(cond), walk(block) ]; + return [ "do", walk(cond), walk(block) ]; }, "return": function(expr) { - return [ this[0], walk(expr) ]; + return [ "return", walk(expr) ]; }, "binary": function(op, left, right) { - return [ this[0], op, walk(left), walk(right) ]; + return [ "binary", op, walk(left), walk(right) ]; }, "unary-prefix": function(op, expr) { - return [ this[0], op, walk(expr) ]; + return [ "unary-prefix", op, walk(expr) ]; }, "unary-postfix": function(op, expr) { - return [ this[0], op, walk(expr) ]; + return [ "unary-postfix", op, walk(expr) ]; }, "sub": function(expr, subscript) { - return [ this[0], walk(expr), walk(subscript) ]; + return [ "sub", walk(expr), walk(subscript) ]; }, "object": function(props) { - return [ this[0], MAP(props, function(p){ + return [ "object", MAP(props, function(p){ return p.length == 2 ? [ p[0], walk(p[1]) ] : [ p[0], walk(p[1]), p[2] ]; // get/set-ter }) ]; }, "regexp": function(rx, mods) { - return [ this[0], rx, mods ]; + return [ "regexp", rx, mods ]; }, "array": function(elements) { - return [ this[0], MAP(elements, walk) ]; + return [ "array", MAP(elements, walk) ]; }, "stat": function(stat) { - return [ this[0], walk(stat) ]; + return [ "stat", walk(stat) ]; }, "seq": function() { - return [ this[0] ].concat(MAP(slice(arguments), walk)); + return [ "seq" ].concat(MAP(slice(arguments), walk)); }, "label": function(name, block) { - return [ this[0], name, walk(block) ]; + return [ "label", name, walk(block) ]; }, "with": function(expr, block) { - return [ this[0], walk(expr), walk(block) ]; + return [ "with", walk(expr), walk(block) ]; }, "atom": function(name) { - return [ this[0], name ]; + return [ "atom", name ]; } }; @@ -257,8 +260,8 @@ function Scope(parent) { this.rev_mangled = {}; // reverse lookup (mangled => orig.name) this.cname = -1; // current mangled name this.refs = {}; // names referenced from this scope - this.uses_with = false; // will become TRUE if with() is detected in this or any subscopes - this.uses_eval = false; // will become TRUE if eval() is detected in this or any subscopes + this.uses_with = false; // will become TRUE if eval() is detected in this or any subscopes + this.uses_eval = false; // will become TRUE if with() is detected in this or any subscopes this.parent = parent; // parent scope this.children = []; // sub-scopes if (parent) { @@ -379,9 +382,7 @@ function ast_add_scope(ast) { }; function _lambda(name, args, body) { - var is_defun = this[0] == "defun"; - return [ this[0], is_defun ? define(name) : name, args, with_new_scope(function(){ - if (!is_defun) define(name); + return [ this[0], define(name), args, with_new_scope(function(){ MAP(args, define); return MAP(body, walk); })]; @@ -404,7 +405,7 @@ function ast_add_scope(ast) { }, "try": function(t, c, f) { if (c != null) return [ - this[0], + "try", MAP(t, walk), [ define(c[0]), MAP(c[1], walk) ], f != null ? MAP(f, walk) : null @@ -414,6 +415,10 @@ function ast_add_scope(ast) { if (name == "eval") having_eval.push(current_scope); reference(name); + }, + "for-in": function(has_var, name) { + if (has_var) define(name); + else reference(name); } }, function(){ return walk(ast); @@ -456,33 +461,17 @@ function ast_add_scope(ast) { /* -----[ mangle names ]----- */ -function ast_mangle(ast, options) { +function ast_mangle(ast, do_toplevel) { var w = ast_walker(), walk = w.walk, scope; - options = options || {}; function get_mangled(name, newMangle) { - if (!options.toplevel && !scope.parent) return name; // don't mangle toplevel - if (options.except && member(name, options.except)) - return name; + if (!do_toplevel && !scope.parent) return name; // don't mangle toplevel return scope.get_mangled(name, newMangle); }; - function get_define(name) { - // we always lookup a defined symbol for the current scope FIRST, so declared - // vars trump a DEFINE symbol, but if no such var is found, then match a DEFINE value - if (!scope.has(name)) { - if (HOP(options.defines, name)) { - return options.defines[name]; - } - } - return null; - }; - function _lambda(name, args, body) { - var is_defun = this[0] == "defun"; - if (is_defun && name) name = get_mangled(name); + if (name) name = get_mangled(name); body = with_scope(body.scope, function(){ - if (!is_defun && name) name = get_mangled(name); args = MAP(args, function(name){ return get_mangled(name) }); return MAP(body, walk); }); @@ -502,9 +491,9 @@ function ast_mangle(ast, options) { }; function _vardefs(defs) { - return [ this[0], MAP(defs, function(d){ + return MAP(defs, function(d){ return [ get_mangled(d[0]), walk(d[1]) ]; - }) ]; + }); }; return w.with_walkers({ @@ -521,22 +510,28 @@ function ast_mangle(ast, options) { } return ast; }, - "var": _vardefs, - "const": _vardefs, + "var": function(defs) { + return [ "var", _vardefs(defs) ]; + }, + "const": function(defs) { + return [ "const", _vardefs(defs) ]; + }, "name": function(name) { - return get_define(name) || [ this[0], get_mangled(name) ]; + return [ "name", get_mangled(name) ]; }, "try": function(t, c, f) { - return [ this[0], + return [ "try", MAP(t, walk), c != null ? [ get_mangled(c[0]), MAP(c[1], walk) ] : null, f != null ? MAP(f, walk) : null ]; }, "toplevel": function(body) { - var self = this; - return with_scope(self.scope, function(){ - return [ self[0], MAP(body, walk) ]; + return with_scope(this.scope, function(){ + return [ "toplevel", MAP(body, walk) ]; }); + }, + "for-in": function(has_var, name, obj, stat) { + return [ "for-in", has_var, get_mangled(name), walk(obj), walk(stat) ]; } }, function() { return walk(ast_add_scope(ast)); @@ -574,199 +569,52 @@ function aborts(t) { } }; -function boolean_expr(expr) { - return ( (expr[0] == "unary-prefix" - && member(expr[1], [ "!", "delete" ])) || - - (expr[0] == "binary" - && member(expr[1], [ "in", "instanceof", "==", "!=", "===", "!==", "<", "<=", ">=", ">" ])) || - - (expr[0] == "binary" - && member(expr[1], [ "&&", "||" ]) - && boolean_expr(expr[2]) - && boolean_expr(expr[3])) || - - (expr[0] == "conditional" - && boolean_expr(expr[2]) - && boolean_expr(expr[3])) || - - (expr[0] == "assign" - && expr[1] === true - && boolean_expr(expr[3])) || - - (expr[0] == "seq" - && boolean_expr(expr[expr.length - 1])) - ); +function negate(c) { + var not_c = [ "unary-prefix", "!", c ]; + switch (c[0]) { + case "unary-prefix": + return c[1] == "!" ? c[2] : not_c; + case "binary": + var op = c[1], left = c[2], right = c[3]; + switch (op) { + case "<=": return [ "binary", ">", left, right ]; + case "<": return [ "binary", ">=", left, right ]; + case ">=": return [ "binary", "<", left, right ]; + case ">": return [ "binary", "<=", left, right ]; + case "==": return [ "binary", "!=", left, right ]; + case "!=": return [ "binary", "==", left, right ]; + case "===": return [ "binary", "!==", left, right ]; + case "!==": return [ "binary", "===", left, right ]; + case "&&": return best_of(not_c, [ "binary", "||", negate(left), negate(right) ]); + case "||": return best_of(not_c, [ "binary", "&&", negate(left), negate(right) ]); + } + break; + } + return not_c; }; function make_conditional(c, t, e) { - var make_real_conditional = function() { if (c[0] == "unary-prefix" && c[1] == "!") { - return e ? [ "conditional", c[2], e, t ] : [ "binary", "||", c[2], t ]; + return e ? [ "conditional", c[2], e, t ] : [ "binary", "||", c[2], t ]; } else { - return e ? [ "conditional", c, t, e ] : [ "binary", "&&", c, t ]; + return e ? [ "conditional", c, t, e ] : [ "binary", "&&", c, t ]; } - }; - // shortcut the conditional if the expression has a constant value - return when_constant(c, function(ast, val){ - warn_unreachable(val ? e : t); - return (val ? t : e); - }, make_real_conditional); }; function empty(b) { return !b || (b[0] == "block" && (!b[1] || b[1].length == 0)); }; -function is_string(node) { - return (node[0] == "string" || - node[0] == "unary-prefix" && node[1] == "typeof" || - node[0] == "binary" && node[1] == "+" && - (is_string(node[2]) || is_string(node[3]))); -}; - -var when_constant = (function(){ - - var $NOT_CONSTANT = {}; - - // this can only evaluate constant expressions. If it finds anything - // not constant, it throws $NOT_CONSTANT. - function evaluate(expr) { - switch (expr[0]) { - case "string": - case "num": - return expr[1]; - case "name": - case "atom": - switch (expr[1]) { - case "true": return true; - case "false": return false; - } - break; - case "unary-prefix": - switch (expr[1]) { - case "!": return !evaluate(expr[2]); - case "typeof": return typeof evaluate(expr[2]); - case "~": return ~evaluate(expr[2]); - case "-": return -evaluate(expr[2]); - case "+": return +evaluate(expr[2]); - } - break; - case "binary": - var left = expr[2], right = expr[3]; - switch (expr[1]) { - case "&&" : return evaluate(left) && evaluate(right); - case "||" : return evaluate(left) || evaluate(right); - case "|" : return evaluate(left) | evaluate(right); - case "&" : return evaluate(left) & evaluate(right); - case "^" : return evaluate(left) ^ evaluate(right); - case "+" : return evaluate(left) + evaluate(right); - case "*" : return evaluate(left) * evaluate(right); - case "/" : return evaluate(left) / evaluate(right); - case "-" : return evaluate(left) - evaluate(right); - case "<<" : return evaluate(left) << evaluate(right); - case ">>" : return evaluate(left) >> evaluate(right); - case ">>>" : return evaluate(left) >>> evaluate(right); - case "==" : return evaluate(left) == evaluate(right); - case "===" : return evaluate(left) === evaluate(right); - case "!=" : return evaluate(left) != evaluate(right); - case "!==" : return evaluate(left) !== evaluate(right); - case "<" : return evaluate(left) < evaluate(right); - case "<=" : return evaluate(left) <= evaluate(right); - case ">" : return evaluate(left) > evaluate(right); - case ">=" : return evaluate(left) >= evaluate(right); - case "in" : return evaluate(left) in evaluate(right); - case "instanceof" : return evaluate(left) instanceof evaluate(right); - } - } - throw $NOT_CONSTANT; - }; - - return function(expr, yes, no) { - try { - var val = evaluate(expr), ast; - switch (typeof val) { - case "string": ast = [ "string", val ]; break; - case "number": ast = [ "num", val ]; break; - case "boolean": ast = [ "name", String(val) ]; break; - default: throw new Error("Can't handle constant of type: " + (typeof val)); - } - return yes.call(expr, ast, val); - } catch(ex) { - if (ex === $NOT_CONSTANT) { - if (expr[0] == "binary" - && (expr[1] == "===" || expr[1] == "!==") - && ((is_string(expr[2]) && is_string(expr[3])) - || (boolean_expr(expr[2]) && boolean_expr(expr[3])))) { - expr[1] = expr[1].substr(0, 2); - } - else if (no && expr[0] == "binary" - && (expr[1] == "||" || expr[1] == "&&")) { - // the whole expression is not constant but the lval may be... - try { - var lval = evaluate(expr[2]); - expr = ((expr[1] == "&&" && (lval ? expr[3] : lval)) || - (expr[1] == "||" && (lval ? lval : expr[3])) || - expr); - } catch(ex2) { - // IGNORE... lval is not constant - } - } - return no ? no.call(expr, expr) : null; - } - else throw ex; - } - }; - -})(); - -function warn_unreachable(ast) { - if (!empty(ast)) - warn("Dropping unreachable code: " + gen_code(ast, true)); -}; - function ast_squeeze(ast, options) { options = defaults(options, { make_seqs : true, dead_code : true, - keep_comps : true, - no_warnings : false + no_warnings : false, + extra : false }); var w = ast_walker(), walk = w.walk, scope; - function negate(c) { - var not_c = [ "unary-prefix", "!", c ]; - switch (c[0]) { - case "unary-prefix": - return c[1] == "!" && boolean_expr(c[2]) ? c[2] : not_c; - case "seq": - c = slice(c); - c[c.length - 1] = negate(c[c.length - 1]); - return c; - case "conditional": - return best_of(not_c, [ "conditional", c[1], negate(c[2]), negate(c[3]) ]); - case "binary": - var op = c[1], left = c[2], right = c[3]; - if (!options.keep_comps) switch (op) { - case "<=" : return [ "binary", ">", left, right ]; - case "<" : return [ "binary", ">=", left, right ]; - case ">=" : return [ "binary", "<", left, right ]; - case ">" : return [ "binary", "<=", left, right ]; - } - switch (op) { - case "==" : return [ "binary", "!=", left, right ]; - case "!=" : return [ "binary", "==", left, right ]; - case "===" : return [ "binary", "!==", left, right ]; - case "!==" : return [ "binary", "===", left, right ]; - case "&&" : return best_of(not_c, [ "binary", "||", negate(left), negate(right) ]); - case "||" : return best_of(not_c, [ "binary", "&&", negate(left), negate(right) ]); - } - break; - } - return not_c; - }; - function with_scope(s, cont) { var _scope = scope; scope = s; @@ -776,25 +624,95 @@ function ast_squeeze(ast, options) { return ret; }; - function rmblock(block) { - if (block != null && block[0] == "block" && block[1]) { - if (block[1].length == 1) - block = block[1][0]; - else if (block[1].length == 0) - block = [ "block" ]; + function is_constant(node) { + return node[0] == "string" || node[0] == "num"; + }; + + function find_first_execute(node) { + if (!node) + return false; + + switch (node[0]) { + case "num": + case "string": + case "name": + return node; + case "call": + case "conditional": + case "for": + case "if": + case "new": + case "return": + case "stat": + case "switch": + case "throw": + return find_first_execute(node[1]); + case "binary": + return find_first_execute(node[2]); + case "assign": + if (node[1] === true) + return find_first_execute(node[3]); + break; + case "var": + if (node[1][0].length > 1) + return find_first_execute(node[1][0][1]); + break; } + return null; + } + + function find_assign_recursive(p, v) { + if (p[0] == "assign" && p[1] != true || p[0] == "unary-prefix") { + if (p[2][0] == "name" && v[0] == "name" && p[2][1] == v[1]) + return true; + return false; + } + + if (p[0] != "assign" || p[1] !== true) + return false; + + if ((is_constant(p[3]) && p[3][0] == v[0] && p[3][1] == v[1]) || + (p[3][0] == "name" && v[0] == "name" && p[3][1] == v[1]) || + (p[2][0] == "name" && v[0] == "name" && p[2][1] == v[1])) + return true; + + return find_assign_recursive(p[3], v); + }; + + function rmblock(block) { + if (block != null && block[0] == "block" && block[1] && block[1].length == 1) + block = block[1][0]; return block; }; + function clone(obj) { + if (obj && obj.constructor == Array) + return MAP(obj, clone); + return obj; + }; + + function make_seq_to_statements(node) { + if (node[0] != "seq") { + switch (node[0]) { + case "var": + case "const": + return [ node ]; + default: + return [ [ "stat", node ] ]; + } + } + + var ret = []; + for (var i = 1; i < node.length; i++) + ret.push.apply(ret, make_seq_to_statements(node[i])); + + return ret; + }; + function _lambda(name, args, body) { - var is_defun = this[0] == "defun"; - body = with_scope(body.scope, function(){ - var ret = tighten(MAP(body, walk), "lambda"); - if (!is_defun && name && !HOP(scope.refs, name)) - name = null; - return ret; - }); - return [ this[0], name, args, body ]; + return [ this[0], name, args, with_scope(body.scope, function(){ + return tighten(MAP(body, walk), "lambda"); + }) ]; }; // we get here for blocks that have been already transformed. @@ -816,6 +734,64 @@ function ast_squeeze(ast, options) { return a; }, []); + if (options.extra) { + // Detightening things. We do this because then we can assume that the + // statements are structured in a specific way. + statements = (function(a, prev) { + statements.forEach(function(cur) { + switch (cur[0]) { + case "for": + if (cur[1] != null) { + a.push.apply(a, make_seq_to_statements(cur[1])); + cur[1] = null; + } + a.push(cur); + break; + case "stat": + var stats = make_seq_to_statements(cur[1]); + stats.forEach(function(s) { + if (s[1][0] == "unary-postfix") + s[1][0] = "unary-prefix"; + }); + a.push.apply(a, stats); + break; + default: + a.push(cur); + } + }); + return a; + })([]); + + statements = (function(a, prev) { + statements.forEach(function(cur) { + if (!(prev && prev[0] == "stat")) { + a.push(cur); + prev = cur; + return; + } + + var p = prev[1]; + var c = find_first_execute(cur); + if (c && find_assign_recursive(p, c)) { + var old_cur = clone(cur); + c.splice(0, c.length); + c.push.apply(c, p); + var tmp_cur = best_of(cur, [ "toplevel", [ prev, old_cur ] ]); + if (tmp_cur == cur) { + a[a.length -1] = cur; + } else { + cur = old_cur; + a.push(cur); + } + } else { + a.push(cur); + } + prev = cur; + }); + return a; + })([]); + } + statements = (function(a, prev){ statements.forEach(function(cur){ if (prev && ((cur[0] == "var" && prev[0] == "var") || @@ -836,7 +812,7 @@ function ast_squeeze(ast, options) { a.push(st); } else if (!options.no_warnings) - warn_unreachable(st); + warn("Removing unreachable code: " + gen_code(st, true)); } else { a.push(st); @@ -859,6 +835,22 @@ function ast_squeeze(ast, options) { return a; })([]); + if (options.extra) { + statements = (function(a, prev){ + statements.forEach(function(cur){ + var replaced = false; + if (prev && cur[0] == "for" && cur[1] == null && (prev[0] == "var" || prev[0] == "const" || prev[0] == "stat")) { + cur[1] = prev; + a[a.length - 1] = cur; + } else { + a.push(cur); + } + prev = cur; + }); + return a; + })([]); + } + if (block_type == "lambda") statements = (function(i, a, stat){ while (i < statements.length) { stat = statements[i++]; @@ -882,20 +874,6 @@ function ast_squeeze(ast, options) { }; function make_if(c, t, e) { - return when_constant(c, function(ast, val){ - if (val) { - warn_unreachable(e); - return t; - } else { - warn_unreachable(t); - return e; - } - }, function() { - return make_real_if(c, t, e); - }); - }; - - function make_real_if(c, t, e) { c = walk(c); t = walk(t); e = walk(e); @@ -923,10 +901,7 @@ function ast_squeeze(ast, options) { if (empty(e) && empty(t)) return [ "stat", c ]; var ret = [ "if", c, t, e ]; - if (t[0] == "if" && empty(t[3]) && empty(e)) { - ret = best_of(ret, walk([ "if", [ "binary", "&&", c, t[1] ], t[2] ])); - } - else if (t[0] == "stat") { + if (t[0] == "stat") { if (e) { if (e[0] == "stat") { ret = best_of(ret, [ "stat", make_conditional(c, t[1], e[1]) ]); @@ -936,7 +911,7 @@ function ast_squeeze(ast, options) { ret = best_of(ret, [ "stat", make_conditional(c, t[1]) ]); } } - else if (e && t[0] == e[0] && (t[0] == "return" || t[0] == "throw") && t[1] && e[1]) { + else if (e && t[0] == e[0] && (t[0] == "return" || t[0] == "throw")) { ret = best_of(ret, [ t[0], make_conditional(c, t[1], e[1] ) ]); } else if (e && aborts(t)) { @@ -961,25 +936,13 @@ function ast_squeeze(ast, options) { return ret; }; - function _do_while(cond, body) { - return when_constant(cond, function(cond, val){ - if (!val) { - warn_unreachable(body); - return [ "block" ]; - } else { - return [ "for", null, null, null, walk(body) ]; - } - }); - }; - return w.with_walkers({ "sub": function(expr, subscript) { if (subscript[0] == "string") { var name = subscript[1]; - if (is_identifier(name)) + if (is_identifier(name)) { return [ "dot", walk(expr), name ]; - else if (/^[1-9][0-9]*$/.test(name) || name === "0") - return [ "sub", walk(expr), [ "num", parseInt(name, 10) ] ]; + } } }, "if": make_if, @@ -1006,11 +969,29 @@ function ast_squeeze(ast, options) { if (body) return rmblock([ "block", tighten(MAP(body, walk)) ]); }, "binary": function(op, left, right) { - return when_constant([ "binary", op, walk(left), walk(right) ], function yes(c){ - return best_of(walk(c), this); - }, function no() { - return this; - }); + left = walk(left); + right = walk(right); + var best = [ "binary", op, left, right ]; + if (is_constant(right)) { + if (is_constant(left)) { + var val = null; + switch (op) { + case "+": val = left[1] + right[1]; break; + case "*": val = left[1] * right[1]; break; + case "/": val = left[1] / right[1]; break; + case "-": val = left[1] - right[1]; break; + case "<<": val = left[1] << right[1]; break; + case ">>": val = left[1] >> right[1]; break; + case ">>>": val = left[1] >>> right[1]; break; + } + if (val != null) { + best = best_of(best, [ typeof val == "string" ? "string" : "num", val ]); + } + } else if (left[0] == "binary" && left[1] == "+" && left[3][0] == "string") { + best = best_of(best, [ "binary", "+", left[2], [ "string", left[3][1] + right[1] ] ]); + } + } + return best; }, "conditional": function(c, t, e) { return make_conditional(walk(c), walk(t), walk(e)); @@ -1023,14 +1004,17 @@ function ast_squeeze(ast, options) { f != null ? tighten(MAP(f, walk)) : null ]; }, - "unary-prefix": function(op, expr) { - expr = walk(expr); - var ret = [ "unary-prefix", op, expr ]; - if (op == "!") - ret = best_of(ret, negate(expr)); - return when_constant(ret, function(ast, val){ - return walk(ast); // it's either true or false, so minifies to !0 or !1 - }, function() { return ret }); + "unary-prefix": function(op, cond) { + if (op == "!") { + cond = walk(cond); + if (cond[0] == "unary-prefix" && cond[1] == "!") { + var p = w.parent(); + if (p[0] == "unary-prefix" && p[1] == "!") + return cond[2]; + return [ "unary-prefix", "!", cond ]; + } + return best_of(this, negate(cond)); + } }, "name": function(name) { switch (name) { @@ -1051,9 +1035,7 @@ function ast_squeeze(ast, options) { if (expr[0] == "name" && expr[1] == "Array" && args.length != 1 && !scope.has("Array")) { return [ "array", args ]; } - }, - "while": _do_while, - "do": _do_while + } }, function() { return walk(ast_add_scope(ast)); }); @@ -1064,7 +1046,6 @@ function ast_squeeze(ast, options) { var DOT_CALL_NO_PARENS = jsp.array_to_hash([ "name", "array", - "object", "string", "dot", "sub", @@ -1072,9 +1053,9 @@ var DOT_CALL_NO_PARENS = jsp.array_to_hash([ "regexp" ]); -function make_string(str, ascii_only) { +function make_string(str) { var dq = 0, sq = 0; - str = str.replace(/[\\\b\f\n\r\t\x22\x27\u2028\u2029]/g, function(s){ + str = str.replace(/[\\\b\f\n\r\t\x22\x27]/g, function(s){ switch (s) { case "\\": return "\\\\"; case "\b": return "\\b"; @@ -1082,58 +1063,34 @@ function make_string(str, ascii_only) { case "\n": return "\\n"; case "\r": return "\\r"; case "\t": return "\\t"; - case "\u2028": return "\\u2028"; - case "\u2029": return "\\u2029"; case '"': ++dq; return '"'; case "'": ++sq; return "'"; } return s; }); - if (ascii_only) str = to_ascii(str); - if (dq > sq) return "'" + str.replace(/\x27/g, "\\'") + "'"; - else return '"' + str.replace(/\x22/g, '\\"') + '"'; + if (dq > sq) { + return "'" + str.replace(/\x27/g, "\\'") + "'"; + } else { + return '"' + str.replace(/\x22/g, '\\"') + '"'; + } }; -function to_ascii(str) { - return str.replace(/[\u0080-\uffff]/g, function(ch) { - var code = ch.charCodeAt(0).toString(16); - while (code.length < 4) code = "0" + code; - return "\\u" + code; - }); -}; - -var SPLICE_NEEDS_BRACKETS = jsp.array_to_hash([ "if", "while", "do", "for", "for-in", "with" ]); - -function gen_code(ast, options) { - options = defaults(options, { +function gen_code(ast, beautify) { + if (beautify) beautify = defaults(beautify, { indent_start : 0, indent_level : 4, quote_keys : false, - space_colon : false, - beautify : false, - ascii_only : false + space_colon : false }); - var beautify = !!options.beautify; var indentation = 0, newline = beautify ? "\n" : "", space = beautify ? " " : ""; - function encode_string(str) { - return make_string(str, options.ascii_only); - }; - - function make_name(name) { - name = name.toString(); - if (options.ascii_only) - name = to_ascii(name); - return name; - }; - function indent(line) { if (line == null) line = ""; if (beautify) - line = repeat_string(" ", options.indent_start + indentation * options.indent_level) + line; + line = repeat_string(" ", beautify.indent_start + indentation * beautify.indent_level) + line; return line; }; @@ -1187,7 +1144,7 @@ function gen_code(ast, options) { }; function needs_parens(expr) { - if (expr[0] == "function" || expr[0] == "object") { + if (expr[0] == "function") { // dot/call on a literal function requires the // function literal itself to be parenthesized // only if it's the first "thing" in a @@ -1199,8 +1156,9 @@ function gen_code(ast, options) { var a = slice($stack), self = a.pop(), p = a.pop(); while (p) { if (p[0] == "stat") return true; - if (((p[0] == "seq" || p[0] == "call" || p[0] == "dot" || p[0] == "sub" || p[0] == "conditional") && p[1] === self) || - ((p[0] == "binary" || p[0] == "assign" || p[0] == "unary-postfix") && p[2] === self)) { + if ((p[0] == "seq" && p[1] === self) || + (p[0] == "call" && p[1] === self) || + (p[0] == "binary" && p[2] === self)) { self = p; p = a.pop(); } else { @@ -1227,26 +1185,13 @@ function gen_code(ast, options) { }; var generators = { - "string": encode_string, + "string": make_string, "num": make_num, "name": make_name, "toplevel": function(statements) { return make_block_statements(statements) .join(newline + newline); }, - "splice": function(statements) { - var parent = $stack[$stack.length - 2][0]; - if (HOP(SPLICE_NEEDS_BRACKETS, parent)) { - // we need block brackets in this case - return make_block.apply(this, arguments); - } else { - return MAP(make_block_statements(statements, true), - function(line, i) { - // the first line is already indented - return i > 0 ? indent(line) : line; - }).join(newline); - } - }, "block": make_block, "var": function(defs) { return "var " + add_commas(MAP(defs, make_1vardef)) + ";"; @@ -1308,10 +1253,9 @@ function gen_code(ast, options) { }, "dot": function(expr) { var out = make(expr), i = 1; - if (expr[0] == "num") { - if (!/\./.test(expr[1])) - out += "."; - } else if (needs_parens(expr)) + if (expr[0] == "num") + out += "."; + else if (needs_parens(expr)) out = "(" + out + ")"; while (i < arguments.length) out += "." + make_name(arguments[i++]); @@ -1344,11 +1288,12 @@ function gen_code(ast, options) { out.push("(" + args + ")", make(block)); return add_spaces(out); }, - "for-in": function(vvar, key, hash, block) { - return add_spaces([ "for", "(" + - (vvar ? make(vvar).replace(/;+$/, "") : make(key)), - "in", - make(hash) + ")", make(block) ]); + "for-in": function(has_var, key, hash, block) { + var out = add_spaces([ "for", "(" ]); + if (has_var) + out += "var "; + out += add_spaces([ make_name(key) + " in " + make(hash) + ")", make(block) ]); + return out; }, "while": function(condition, block) { return add_spaces([ "while", "(" + make(condition) + ")", make(block) ]); @@ -1371,8 +1316,7 @@ function gen_code(ast, options) { left = "(" + left + ")"; } if (member(rvalue[0], [ "assign", "conditional", "seq" ]) || - rvalue[0] == "binary" && PRECEDENCE[operator] >= PRECEDENCE[rvalue[1]] && - !(rvalue[1] == operator && member(operator, [ "&&", "||", "*" ]))) { + rvalue[0] == "binary" && PRECEDENCE[operator] >= PRECEDENCE[rvalue[1]]) { right = "(" + right + ")"; } return add_spaces([ left, operator, right ]); @@ -1406,15 +1350,14 @@ function gen_code(ast, options) { return indent(make_function(p[0], p[1][2], p[1][3], p[2])); } var key = p[0], val = make(p[1]); - if (options.quote_keys) { - key = encode_string(key); - } else if ((typeof key == "number" || !beautify && +key + "" == key) - && parseFloat(key) >= 0) { + if (beautify && beautify.quote_keys) { + key = make_string(key); + } else if (typeof key == "number" || !beautify && +key + "" == key) { key = make_num(+key); } else if (!is_identifier(key)) { - key = encode_string(key); + key = make_string(key); } - return indent(add_spaces(beautify && options.space_colon + return indent(add_spaces(beautify && beautify.space_colon ? [ key, ":", val ] : [ key + ":", val ])); }).join("," + newline); @@ -1426,7 +1369,6 @@ function gen_code(ast, options) { "array": function(elements) { if (elements.length == 0) return "[]"; return add_spaces([ "[", add_commas(MAP(elements, function(el){ - if (!beautify && el[0] == "atom" && el[1] == "undefined") return ""; return parenthesize(el, "seq"); })), "]" ]); }, @@ -1444,6 +1386,12 @@ function gen_code(ast, options) { }, "atom": function(name) { return make_name(name); + }, + "comment1": function(text) { + return "//" + text + "\n"; + }, + "comment2": function(text) { + return "/*" + text + "*/"; } }; @@ -1487,25 +1435,21 @@ function gen_code(ast, options) { return add_spaces([ out, make_block(body) ]); }; - function make_block_statements(statements, noindent) { + function make_name(name) { + return name.toString(); + }; + + function make_block_statements(statements) { for (var a = [], last = statements.length - 1, i = 0; i <= last; ++i) { var stat = statements[i]; var code = make(stat); if (code != ";") { - if (!beautify && i == last) { - if ((stat[0] == "while" && empty(stat[2])) || - (member(stat[0], [ "for", "for-in"] ) && empty(stat[4])) || - (stat[0] == "if" && empty(stat[2]) && !stat[3]) || - (stat[0] == "if" && stat[3] && empty(stat[3]))) { - code = code.replace(/;*\s*$/, ";"); - } else { - code = code.replace(/;+\s*$/, ""); - } - } + if (!beautify && i == last) + code = code.replace(/;+\s*$/, ""); a.push(code); } } - return noindent ? a : MAP(a, indent); + return MAP(a, indent); }; function make_switch_block(body) { @@ -1536,7 +1480,7 @@ function gen_code(ast, options) { function make_1vardef(def) { var name = def[0], val = def[1]; if (val != null) - name = add_spaces([ make_name(name), "=", parenthesize(val, "seq") ]); + name = add_spaces([ name, "=", make(val) ]); return name; }; @@ -1556,49 +1500,6 @@ function gen_code(ast, options) { return make(ast); }; -function split_lines(code, max_line_length) { - var splits = [ 0 ]; - jsp.parse(function(){ - var next_token = jsp.tokenizer(code); - var last_split = 0; - var prev_token; - function current_length(tok) { - return tok.pos - last_split; - }; - function split_here(tok) { - last_split = tok.pos; - splits.push(last_split); - }; - function custom(){ - var tok = next_token.apply(this, arguments); - out: { - if (prev_token) { - if (prev_token.type == "keyword") break out; - } - if (current_length(tok) > max_line_length) { - switch (tok.type) { - case "keyword": - case "atom": - case "name": - case "punc": - split_here(tok); - break out; - } - } - } - prev_token = tok; - return tok; - }; - custom.context = function() { - return next_token.context.apply(this, arguments); - }; - return custom; - }()); - return splits.map(function(pos, i){ - return code.substring(pos, splits[i + 1] || code.length); - }).join("\n"); -}; - /* -----[ Utilities ]----- */ function repeat_string(str, i) { @@ -1657,10 +1558,5 @@ exports.ast_mangle = ast_mangle; exports.ast_squeeze = ast_squeeze; exports.gen_code = gen_code; exports.ast_add_scope = ast_add_scope; -exports.set_logger = function(logger) { warn = logger }; -exports.make_string = make_string; -exports.split_lines = split_lines; -exports.MAP = MAP; - -// keep this last! exports.ast_squeeze_more = require("./squeeze-more").ast_squeeze_more; +exports.set_logger = function(logger) { warn = logger }; diff --git a/build/post-compile.js b/build/post-compile.js index 1bbeaa6f..4bcafe81 100644 --- a/build/post-compile.js +++ b/build/post-compile.js @@ -4,4 +4,4 @@ var print = require("sys").print, src = require("fs").readFileSync(process.argv[2], "utf8"); // Previously done in sed but reimplemented here due to portability issues -print( src.replace( /^(\s*\*\/)(.+)/m, "$1\n$2" ) + ";" ); +print(src.replace(/^(\s*\*\/)(.+)/m, "$1\n$2;")); diff --git a/build/release-notes.js b/build/release-notes.js deleted file mode 100644 index b112d998..00000000 --- a/build/release-notes.js +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env node -/* - * jQuery Release Note Generator - */ - -var fs = require("fs"), - http = require("http"), - tmpl = require("mustache"), - extract = /(.*?)<[^"]+"component">\s*(\S+)/g; - -var opts = { - version: "1.6.2 RC 1", - short_version: "1.6.2rc1", - final_version: "1.6.2", - categories: [] -}; - -http.request({ - host: "bugs.jquery.com", - port: 80, - method: "GET", - path: "/query?status=closed&resolution=fixed&component=!web&order=component&milestone=" + opts.final_version -}, function (res) { - var data = []; - - res.on( "data", function( chunk ) { - data.push( chunk ); - }); - - res.on( "end", function() { - var match, - file = data.join(""), - cur; - - while ( (match = extract.exec( file )) ) { - if ( "#" + match[1] !== match[2] ) { - var cat = match[3]; - - if ( !cur || cur.name !== cat ) { - cur = { name: match[3], niceName: match[3].replace(/^./, function(a){ return a.toUpperCase(); }), bugs: [] }; - opts.categories.push( cur ); - } - - cur.bugs.push({ ticket: match[1], title: match[2] }); - } - } - - buildNotes(); - }); -}).end(); - -function buildNotes() { - console.log( tmpl.to_html( fs.readFileSync("release-notes.txt", "utf8"), opts ) ); -} diff --git a/build/release-notes.txt b/build/release-notes.txt deleted file mode 100644 index 1d0ae746..00000000 --- a/build/release-notes.txt +++ /dev/null @@ -1,27 +0,0 @@ -

jQuery {{version}} Released

- -

This is a preview release of jQuery. We're releasing it so that everyone can start testing the code in their applications, making sure that there are no major problems.

- -

You can get the code from the jQuery CDN:

- -
- -

You can help us by dropping that code into your existing application and letting us know that if anything no longer works. Please file a bug and be sure to mention that you're testing against jQuery {{version}}.

- -

We want to encourage everyone from the community to try and get involved in contributing back to jQuery core. We've set up a full page of information dedicated towards becoming more involved with the team. The team is here and ready to help you help us!

- -

jQuery {{version}} Change Log

- -

The current change log of the {{version}} release.

- -{{#categories}} -

{{niceName}}

- - -{{/categories}} diff --git a/build/release.js b/build/release.js deleted file mode 100644 index 7a42f998..00000000 --- a/build/release.js +++ /dev/null @@ -1,169 +0,0 @@ -#!/usr/bin/env node -/* - * jQuery Release Management - */ - -var fs = require("fs"), - child = require("child_process"), - debug = false; - -var scpURL = "jqadmin@code.origin.jquery.com:/var/www/html/code.jquery.com/", - cdnURL = "http://code.origin.jquery.com/", - - version = /^[\d.]+(?:(?:a|b|rc)\d+|pre)?$/, - versionFile = "version.txt", - - file = "dist/jquery.js", - minFile = "dist/jquery.min.js", - - files = { - "jquery-VER.js": file, - "jquery-VER.min.js": minFile - }, - - finalFiles = { - "jquery.js": file, - "jquery-latest.js": file, - "jquery.min.js": minFile, - "jquery-latest.min.js": minFile - }; - -exec( "git pull && git status", function( error, stdout, stderr ) { - if ( /Changes to be committed/i.test( stdout ) ) { - exit( "Please commit changed files before attemping to push a release." ); - - } else if ( /Changes not staged for commit/i.test( stdout ) ) { - exit( "Please stash files before attempting to push a release." ); - - } else { - setVersion(); - } -}); - -function setVersion() { - var oldVersion = fs.readFileSync( versionFile, "utf8" ); - - prompt( "New Version (was " + oldVersion + "): ", function( data ) { - if ( data && version.test( data ) ) { - fs.writeFileSync( versionFile, data ); - - exec( "git commit -a -m 'Tagging the " + data + " release.' && git push && " + - "git tag " + data + " && git push origin " + data, function() { - make( data ); - }); - - } else { - console.error( "Malformed version number, please try again." ); - setVersion(); - } - }); -} - -function make( newVersion ) { - exec( "make clean && make", function( error, stdout, stderr ) { - // TODO: Verify JSLint - - Object.keys( files ).forEach(function( oldName ) { - var value = files[ oldName ], name = oldName.replace( /VER/g, newVersion ); - - copy( value, name ); - - delete files[ oldName ]; - files[ name ] = value; - }); - - exec( "scp " + Object.keys( files ).join( " " ) + " " + scpURL, function() { - setNextVersion( newVersion ); - }); - }); -} - -function setNextVersion( newVersion ) { - var isFinal = false; - - if ( /(?:a|b|rc)\d+$/.test( newVersion ) ) { - newVersion = newVersion.replace( /(?:a|b|rc)\d+$/, "pre" ); - - } else if ( /^\d+\.\d+\.?(\d*)$/.test( newVersion ) ) { - newVersion = newVersion.replace( /^(\d+\.\d+\.?)(\d*)$/, function( all, pre, num ) { - return pre + (pre.charAt( pre.length - 1 ) !== "." ? "." : "") + (num ? parseFloat( num ) + 1 : 1) + "pre"; - }); - - isFinal = true; - } - - prompt( "Next Version [" + newVersion + "]: ", function( data ) { - if ( !data ) { - data = newVersion; - } - - if ( version.test( data ) ) { - fs.writeFileSync( versionFile, data ); - - exec( "git commit -a -m 'Updating the source version to " + data + "' && git push", function() { - if ( isFinal ) { - makeFinal( newVersion ); - } - }); - - } else { - console.error( "Malformed version number, please try again." ); - setNextVersion( newVersion ); - } - }); -} - -function makeFinal( newVersion ) { - var all = Object.keys( finalFiles ); - - // Copy all the files - all.forEach(function( name ) { - copy( finalFiles[ name ], name ); - }); - - // Upload files to CDN - exec( "scp " + all.join( " " ) + " " + scpURL, function() { - exec( "curl '" + cdnURL + "{" + all.join( "," ) + "}?reload'", function() { - console.log( "Done." ); - }); - }); -} - -function copy( oldFile, newFile ) { - if ( debug ) { - console.log( "Copying " + oldFile + " to " + newFile ); - - } else { - fs.writeFileSync( newFile, fs.readFileSync( oldFile, "utf8" ) ); - } -} - -function prompt( msg, callback ) { - process.stdout.write( msg ); - - process.stdin.resume(); - process.stdin.setEncoding( "utf8" ); - - process.stdin.once( "data", function( chunk ) { - process.stdin.pause(); - callback( chunk.replace( /\n*$/g, "" ) ); - }); -} - -function exec( cmd, fn ) { - if ( debug ) { - console.log( cmd ); - fn(); - - } else { - child.exec( cmd, fn ); - } -} - -function exit( msg ) { - if ( msg ) { - console.error( "\nError: " + msg ); - } - - process.exit( 1 ); -} diff --git a/build/uglify.js b/build/uglify.js index aad18e8c..943ddd80 100644 --- a/build/uglify.js +++ b/build/uglify.js @@ -1,10 +1,14 @@ #! /usr/bin/env node -// -*- js -*- +// -*- js2 -*- global.sys = require(/^v0\.[012]/.test(process.version) ? "sys" : "util"); -var fs = require("fs"); -var jsp = require("./lib/parse-js"), - pro = require("./lib/process"); +var fs = require("fs"), + jsp = require("./lib/parse-js"), + pro = require("./lib/process"); + +pro.set_logger(function(msg){ + sys.debug(msg); +}); var options = { ast: false, @@ -13,16 +17,13 @@ var options = { squeeze: true, make_seqs: true, dead_code: true, + beautify: false, verbose: false, show_copyright: true, out_same_file: false, - max_line_length: 32 * 1024, - unsafe: false, - reserved_names: null, - defines: { }, - codegen_options: { - ascii_only: false, - beautify: false, + extra: false, + unsafe: false, // XXX: extra & unsafe? but maybe we don't want both, so.... + beautify_options: { indent_level: 4, indent_start: 0, quote_keys: false, @@ -39,15 +40,15 @@ out: while (args.length > 0) { switch (v) { case "-b": case "--beautify": - options.codegen_options.beautify = true; + options.beautify = true; break; case "-i": case "--indent": - options.codegen_options.indent_level = args.shift(); + options.beautify_options.indent_level = args.shift(); break; case "-q": case "--quote-keys": - options.codegen_options.quote_keys = true; + options.beautify_options.quote_keys = true; break; case "-mt": case "--mangle-toplevel": @@ -85,109 +86,23 @@ out: while (args.length > 0) { case "--ast": options.ast = true; break; + case "--extra": + options.extra = true; + break; case "--unsafe": options.unsafe = true; break; - case "--max-line-len": - options.max_line_length = parseInt(args.shift(), 10); - break; - case "--reserved-names": - options.reserved_names = args.shift().split(","); - break; - case "-d": - case "--define": - var defarg = args.shift(); - try { - var defsym = function(sym) { - // KEYWORDS_ATOM doesn't include NaN or Infinity - should we check - // for them too ?? We don't check reserved words and the like as the - // define values are only substituted AFTER parsing - if (jsp.KEYWORDS_ATOM.hasOwnProperty(sym)) { - throw "Don't define values for inbuilt constant '"+sym+"'"; - } - return sym; - }, - defval = function(v) { - if (v.match(/^"(.*)"$/) || v.match(/^'(.*)'$/)) { - return [ "string", RegExp.$1 ]; - } - else if (!isNaN(parseFloat(v))) { - return [ "num", parseFloat(v) ]; - } - else if (v.match(/^[a-z\$_][a-z\$_0-9]*$/i)) { - return [ "name", v ]; - } - else if (!v.match(/"/)) { - return [ "string", v ]; - } - else if (!v.match(/'/)) { - return [ "string", v ]; - } - throw "Can't understand the specified value: "+v; - }; - if (defarg.match(/^([a-z_\$][a-z_\$0-9]*)(=(.*))?$/i)) { - var sym = defsym(RegExp.$1), - val = RegExp.$2 ? defval(RegExp.$2.substr(1)) : [ 'name', 'true' ]; - options.defines[sym] = val; - } - else { - throw "The --define option expects SYMBOL[=value]"; - } - } catch(ex) { - sys.print("ERROR: In option --define "+defarg+"\n"+ex+"\n"); - process.exit(1); - } - break; - case "--define-from-module": - var defmodarg = args.shift(), - defmodule = require(defmodarg), - sym, - val; - for (sym in defmodule) { - if (defmodule.hasOwnProperty(sym)) { - options.defines[sym] = function(val) { - if (typeof val == "string") - return [ "string", val ]; - if (typeof val == "number") - return [ "num", val ]; - if (val === true) - return [ 'name', 'true' ]; - if (val === false) - return [ 'name', 'false' ]; - if (val === null) - return [ 'name', 'null' ]; - if (val === undefined) - return [ 'name', 'undefined' ]; - sys.print("ERROR: In option --define-from-module "+defmodarg+"\n"); - sys.print("ERROR: Unknown object type for: "+sym+"="+val+"\n"); - process.exit(1); - return null; - }(defmodule[sym]); - } - } - break; - case "--ascii": - options.codegen_options.ascii_only = true; - break; default: filename = v; break out; } } -if (options.verbose) { - pro.set_logger(function(msg){ - sys.debug(msg); - }); -} - -jsp.set_logger(function(msg){ - sys.debug(msg); -}); - if (filename) { fs.readFile(filename, "utf8", function(err, text){ - if (err) throw err; + if (err) { + throw err; + } output(squeeze_it(text)); }); } else { @@ -216,9 +131,7 @@ function output(text) { }); } out.write(text); - if (options.output !== true) { - out.end(); - } + out.end(); }; // --------- main ends here. @@ -239,35 +152,36 @@ function show_copyright(comments) { function squeeze_it(code) { var result = ""; if (options.show_copyright) { - var tok = jsp.tokenizer(code), c; + var initial_comments = []; + // keep first comment + var tok = jsp.tokenizer(code, false), c; c = tok(); - result += show_copyright(c.comments_before); + var prev = null; + while (/^comment/.test(c.type) && (!prev || prev == c.type)) { + initial_comments.push(c); + prev = c.type; + c = tok(); + } + result += show_copyright(initial_comments); } try { var ast = time_it("parse", function(){ return jsp.parse(code); }); - if (options.mangle) ast = time_it("mangle", function(){ - return pro.ast_mangle(ast, { - toplevel: options.mangle_toplevel, - defines: options.defines, - except: options.reserved_names + if (options.mangle) + ast = time_it("mangle", function(){ return pro.ast_mangle(ast, options.mangle_toplevel); }); + if (options.squeeze) + ast = time_it("squeeze", function(){ + ast = pro.ast_squeeze(ast, { + make_seqs : options.make_seqs, + dead_code : options.dead_code, + extra : options.extra + }); + if (options.unsafe) + ast = pro.ast_squeeze_more(ast); + return ast; }); - }); - if (options.squeeze) ast = time_it("squeeze", function(){ - ast = pro.ast_squeeze(ast, { - make_seqs : options.make_seqs, - dead_code : options.dead_code, - keep_comps : !options.unsafe - }); - if (options.unsafe) - ast = pro.ast_squeeze_more(ast); - return ast; - }); if (options.ast) return sys.inspect(ast, null, null); - result += time_it("generate", function(){ return pro.gen_code(ast, options.codegen_options) }); - if (!options.codegen_options.beautify && options.max_line_length) { - result = time_it("split", function(){ return pro.split_lines(result, options.max_line_length) }); - } + result += time_it("generate", function(){ return pro.gen_code(ast, options.beautify && options.beautify_options) }); return result; } catch(ex) { sys.debug(ex.stack); diff --git a/src/ajax.js b/src/ajax.js index 355fd7e4..6414e8c2 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -5,9 +5,9 @@ var r20 = /%20/g, rCRLF = /\r?\n/g, rhash = /#.*$/, rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL - rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, + rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, // #7653, #8125, #8152: local protocol detection - rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/, + rlocalProtocol = /(?:^file|^widget|\-extension):$/, rnoContent = /^(?:GET|HEAD)$/, rprotocol = /^\/\//, rquery = /\?/, @@ -15,7 +15,11 @@ var r20 = /%20/g, rselectTextarea = /^(?:select|textarea)/i, rspacesAjax = /\s+/, rts = /([?&])_=[^&]*/, - rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/, + rucHeaders = /(^|\-)([a-z])/g, + rucHeadersFunc = function( _, $1, $2 ) { + return $1 + $2.toUpperCase(); + }, + rurl = /^([\w\+\.\-]+:)\/\/([^\/?#:]*)(?::(\d+))?/, // Keep a copy of the old load method _load = jQuery.fn.load, @@ -45,9 +49,9 @@ var r20 = /%20/g, ajaxLocParts; // #8138, IE may throw an exception when accessing -// a field from window.location if document.domain has been set +// a field from document.location if document.domain has been set try { - ajaxLocation = location.href; + ajaxLocation = document.location.href; } catch( e ) { // Use the href attribute of an A element // since IE will modify it given document.location @@ -57,7 +61,7 @@ try { } // Segment location into parts -ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; +ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ); // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport function addToPrefiltersOrTransports( structure ) { @@ -95,7 +99,7 @@ function addToPrefiltersOrTransports( structure ) { }; } -// Base inspection function for prefilters and transports +//Base inspection function for prefilters and transports function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, dataType /* internal */, inspected /* internal */ ) { @@ -244,7 +248,7 @@ jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".sp jQuery.fn[ o ] = function( f ){ return this.bind( o, f ); }; -}); +} ); jQuery.each( [ "get", "post" ], function( i, method ) { jQuery[ method ] = function( url, data, callback, type ) { @@ -263,7 +267,7 @@ jQuery.each( [ "get", "post" ], function( i, method ) { dataType: type }); }; -}); +} ); jQuery.extend({ @@ -315,6 +319,7 @@ jQuery.extend({ cache: null, traditional: false, headers: {}, + crossDomain: null, */ accepts: { @@ -389,7 +394,6 @@ jQuery.extend({ ifModifiedKey, // Headers (they are sent all at once) requestHeaders = {}, - requestHeadersNames = {}, // Response headers responseHeadersString, responseHeaders, @@ -413,9 +417,7 @@ jQuery.extend({ // Caches the header setRequestHeader: function( name, value ) { if ( !state ) { - var lname = name.toLowerCase(); - name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; - requestHeaders[ name ] = value; + requestHeaders[ name.toLowerCase().replace( rucHeaders, rucHeadersFunc ) ] = value; } return this; }, @@ -602,7 +604,7 @@ jQuery.extend({ s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax ); // Determine if a cross-domain request is in order - if ( s.crossDomain == null ) { + if ( !s.crossDomain ) { parts = rurl.exec( s.url.toLowerCase() ); s.crossDomain = !!( parts && ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] || @@ -644,8 +646,6 @@ jQuery.extend({ // If data is available, append data to url if ( s.data ) { s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data; - // #9682: remove data so that it's not used in an eventual retry - delete s.data; } // Get ifModifiedKey before adding the anti-cache parameter @@ -665,27 +665,24 @@ jQuery.extend({ // Set the correct header, if data is being sent if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { - jqXHR.setRequestHeader( "Content-Type", s.contentType ); + requestHeaders[ "Content-Type" ] = s.contentType; } // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if ( s.ifModified ) { ifModifiedKey = ifModifiedKey || s.url; if ( jQuery.lastModified[ ifModifiedKey ] ) { - jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] ); + requestHeaders[ "If-Modified-Since" ] = jQuery.lastModified[ ifModifiedKey ]; } if ( jQuery.etag[ ifModifiedKey ] ) { - jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] ); + requestHeaders[ "If-None-Match" ] = jQuery.etag[ ifModifiedKey ]; } } // Set the Accepts header for the server, depending on the dataType - jqXHR.setRequestHeader( - "Accept", - s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? - s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) : - s.accepts[ "*" ] - ); + requestHeaders.Accept = s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? + s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) : + s.accepts[ "*" ]; // Check for headers option for ( i in s.headers ) { @@ -729,7 +726,7 @@ jQuery.extend({ transport.send( requestHeaders, done ); } catch (e) { // Propagate exception as error if not done - if ( state < 2 ) { + if ( status < 2 ) { done( -1, e ); // Simply rethrow otherwise } else { @@ -761,7 +758,7 @@ jQuery.extend({ // Serialize the form elements jQuery.each( a, function() { add( this.name, this.value ); - }); + } ); } else { // If traditional, encode the "old" way (the way 1.3.2 or older @@ -777,7 +774,7 @@ jQuery.extend({ }); function buildParams( prefix, obj, traditional, add ) { - if ( jQuery.isArray( obj ) ) { + if ( jQuery.isArray( obj ) && obj.length ) { // Serialize array item. jQuery.each( obj, function( i, v ) { if ( traditional || rbracket.test( prefix ) ) { @@ -797,9 +794,16 @@ function buildParams( prefix, obj, traditional, add ) { }); } else if ( !traditional && obj != null && typeof obj === "object" ) { + // If we see an array here, it is empty and should be treated as an empty + // object + if ( jQuery.isArray( obj ) || jQuery.isEmptyObject( obj ) ) { + add( prefix, "" ); + // Serialize object item. - for ( var name in obj ) { - buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } else { + for ( var name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } } } else { diff --git a/src/ajax/jsonp.js b/src/ajax/jsonp.js index 6b0f95d5..2691591d 100644 --- a/src/ajax/jsonp.js +++ b/src/ajax/jsonp.js @@ -1,7 +1,7 @@ (function( jQuery ) { var jsc = jQuery.now(), - jsre = /(\=)\?(&|$)|\?\?/i; + jsre = /(\=)\?(&|$)|()\?\?()/i; // Default jsonp settings jQuery.ajaxSetup({ @@ -14,12 +14,13 @@ jQuery.ajaxSetup({ // Detect, normalize options and install callbacks for jsonp requests jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { - var inspectData = s.contentType === "application/x-www-form-urlencoded" && - ( typeof s.data === "string" ); + var dataIsString = ( typeof s.data === "string" ); if ( s.dataTypes[ 0 ] === "jsonp" || + originalSettings.jsonpCallback || + originalSettings.jsonp != null || s.jsonp !== false && ( jsre.test( s.url ) || - inspectData && jsre.test( s.data ) ) ) { + dataIsString && jsre.test( s.data ) ) ) { var responseContainer, jsonpCallback = s.jsonpCallback = @@ -27,12 +28,20 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { previous = window[ jsonpCallback ], url = s.url, data = s.data, - replace = "$1" + jsonpCallback + "$2"; + replace = "$1" + jsonpCallback + "$2", + cleanUp = function() { + // Set callback back to previous value + window[ jsonpCallback ] = previous; + // Call if it was a function and we have a response + if ( responseContainer && jQuery.isFunction( previous ) ) { + window[ jsonpCallback ]( responseContainer[ 0 ] ); + } + }; if ( s.jsonp !== false ) { url = url.replace( jsre, replace ); if ( s.url === url ) { - if ( inspectData ) { + if ( dataIsString ) { data = data.replace( jsre, replace ); } if ( s.data === data ) { @@ -50,15 +59,8 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { responseContainer = [ response ]; }; - // Clean-up function - jqXHR.always(function() { - // Set callback back to previous value - window[ jsonpCallback ] = previous; - // Call if it was a function and we have a response - if ( responseContainer && jQuery.isFunction( previous ) ) { - window[ jsonpCallback ]( responseContainer[ 0 ] ); - } - }); + // Install cleanUp function + jqXHR.then( cleanUp, cleanUp ); // Use data converter to retrieve json after script execution s.converters["script json"] = function() { @@ -74,6 +76,6 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { // Delegate to script return "script"; } -}); +} ); })( jQuery ); diff --git a/src/ajax/script.js b/src/ajax/script.js index f7a91801..34ddd046 100644 --- a/src/ajax/script.js +++ b/src/ajax/script.js @@ -25,7 +25,7 @@ jQuery.ajaxPrefilter( "script", function( s ) { s.type = "GET"; s.global = false; } -}); +} ); // Bind script tag hack transport jQuery.ajaxTransport( "script", function(s) { @@ -53,7 +53,7 @@ jQuery.ajaxTransport( "script", function(s) { // Attach handlers for all browsers script.onload = script.onreadystatechange = function( _, isAbort ) { - if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { + if ( !script.readyState || /loaded|complete/.test( script.readyState ) ) { // Handle memory leak in IE script.onload = script.onreadystatechange = null; @@ -84,6 +84,6 @@ jQuery.ajaxTransport( "script", function(s) { } }; } -}); +} ); })( jQuery ); diff --git a/src/ajax/xhr.js b/src/ajax/xhr.js index a87c3239..a6473dd8 100644 --- a/src/ajax/xhr.js +++ b/src/ajax/xhr.js @@ -1,14 +1,21 @@ (function( jQuery ) { -var // #5280: Internet Explorer will keep connections alive if we don't abort on unload - xhrOnUnloadAbort = window.ActiveXObject ? function() { +var // #5280: next active xhr id and list of active xhrs' callbacks + xhrId = jQuery.now(), + xhrCallbacks, + + // XHR used to determine supports properties + testXHR; + +// #5280: Internet Explorer will keep connections alive if we don't abort on unload +function xhrOnUnloadAbort() { + jQuery( window ).unload(function() { // Abort all pending requests for ( var key in xhrCallbacks ) { xhrCallbacks[ key ]( 0, 1 ); } - } : false, - xhrId = 0, - xhrCallbacks; + }); +} // Functions to create xhrs function createStandardXHR() { @@ -38,13 +45,15 @@ jQuery.ajaxSettings.xhr = window.ActiveXObject ? // For all other browsers, use the standard XMLHttpRequest object createStandardXHR; -// Determine support properties -(function( xhr ) { - jQuery.extend( jQuery.support, { - ajax: !!xhr, - cors: !!xhr && ( "withCredentials" in xhr ) - }); -})( jQuery.ajaxSettings.xhr() ); +// Test if we can create an xhr object +testXHR = jQuery.ajaxSettings.xhr(); +jQuery.support.ajax = !!testXHR; + +// Does this browser support crossDomain XHR requests +jQuery.support.cors = testXHR && ( "withCredentials" in testXHR ); + +// No need for the temporary xhr anymore +testXHR = undefined; // Create transport if the browser can provide an xhr if ( jQuery.support.ajax ) { @@ -83,12 +92,11 @@ if ( jQuery.support.ajax ) { xhr.overrideMimeType( s.mimeType ); } - // X-Requested-With header - // For cross-domain requests, seeing as conditions for a preflight are - // akin to a jigsaw puzzle, we simply never set it to be sure. - // (it can always be set on a per-request basis or even using ajaxSetup) - // For same-domain requests, won't change header if already provided. - if ( !s.crossDomain && !headers["X-Requested-With"] ) { + // Requested-With header + // Not set for crossDomain requests with no content + // (see why at http://trac.dojotoolkit.org/ticket/9486) + // Won't change header if already provided + if ( !( s.crossDomain && !s.hasContent ) && !headers["X-Requested-With"] ) { headers[ "X-Requested-With" ] = "XMLHttpRequest"; } @@ -127,9 +135,7 @@ if ( jQuery.support.ajax ) { // Do not keep as active anymore if ( handle ) { xhr.onreadystatechange = jQuery.noop; - if ( xhrOnUnloadAbort ) { - delete xhrCallbacks[ handle ]; - } + delete xhrCallbacks[ handle ]; } // If it's an abort @@ -190,18 +196,15 @@ if ( jQuery.support.ajax ) { if ( !s.async || xhr.readyState === 4 ) { callback(); } else { - handle = ++xhrId; - if ( xhrOnUnloadAbort ) { - // Create the active xhrs callbacks list if needed - // and attach the unload handler - if ( !xhrCallbacks ) { - xhrCallbacks = {}; - jQuery( window ).unload( xhrOnUnloadAbort ); - } - // Add to list of active xhrs callbacks - xhrCallbacks[ handle ] = callback; + // Create the active xhrs callbacks list if needed + // and attach the unload handler + if ( !xhrCallbacks ) { + xhrCallbacks = {}; + xhrOnUnloadAbort(); } - xhr.onreadystatechange = callback; + // Add to list of active xhrs callbacks + handle = xhrId++; + xhr.onreadystatechange = xhrCallbacks[ handle ] = callback; } }, diff --git a/src/attributes.js b/src/attributes.js index 1e0e79f4..59972105 100644 --- a/src/attributes.js +++ b/src/attributes.js @@ -1,67 +1,66 @@ (function( jQuery ) { var rclass = /[\n\t\r]/g, - rspace = /\s+/, + rspaces = /\s+/, rreturn = /\r/g, + rspecialurl = /^(?:href|src|style)$/, rtype = /^(?:button|input)$/i, rfocusable = /^(?:button|input|object|select|textarea)$/i, rclickable = /^a(?:rea)?$/i, - rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, - rinvalidChar = /\:|^on/, - formHook, boolHook; + rradiocheck = /^(?:radio|checkbox)$/i; + +jQuery.props = { + "for": "htmlFor", + "class": "className", + readonly: "readOnly", + maxlength: "maxLength", + cellspacing: "cellSpacing", + rowspan: "rowSpan", + colspan: "colSpan", + tabindex: "tabIndex", + usemap: "useMap", + frameborder: "frameBorder" +}; jQuery.fn.extend({ attr: function( name, value ) { return jQuery.access( this, name, value, true, jQuery.attr ); }, - removeAttr: function( name ) { - return this.each(function() { - jQuery.removeAttr( this, name ); - }); - }, - - prop: function( name, value ) { - return jQuery.access( this, name, value, true, jQuery.prop ); - }, - - removeProp: function( name ) { - name = jQuery.propFix[ name ] || name; - return this.each(function() { - // try/catch handles cases where IE balks (such as removing a property on window) - try { - this[ name ] = undefined; - delete this[ name ]; - } catch( e ) {} + removeAttr: function( name, fn ) { + return this.each(function(){ + jQuery.attr( this, name, "" ); + if ( this.nodeType === 1 ) { + this.removeAttribute( name ); + } }); }, addClass: function( value ) { - var classNames, i, l, elem, - setClass, c, cl; - - if ( jQuery.isFunction( value ) ) { - return this.each(function( j ) { - jQuery( this ).addClass( value.call(this, j, this.className) ); + if ( jQuery.isFunction(value) ) { + return this.each(function(i) { + var self = jQuery(this); + self.addClass( value.call(this, i, self.attr("class")) ); }); } if ( value && typeof value === "string" ) { - classNames = value.split( rspace ); + var classNames = (value || "").split( rspaces ); - for ( i = 0, l = this.length; i < l; i++ ) { - elem = this[ i ]; + for ( var i = 0, l = this.length; i < l; i++ ) { + var elem = this[i]; if ( elem.nodeType === 1 ) { - if ( !elem.className && classNames.length === 1 ) { + if ( !elem.className ) { elem.className = value; } else { - setClass = " " + elem.className + " "; + var className = " " + elem.className + " ", + setClass = elem.className; - for ( c = 0, cl = classNames.length; c < cl; c++ ) { - if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { - setClass += classNames[ c ] + " "; + for ( var c = 0, cl = classNames.length; c < cl; c++ ) { + if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) { + setClass += " " + classNames[c]; } } elem.className = jQuery.trim( setClass ); @@ -74,25 +73,24 @@ jQuery.fn.extend({ }, removeClass: function( value ) { - var classNames, i, l, elem, className, c, cl; - - if ( jQuery.isFunction( value ) ) { - return this.each(function( j ) { - jQuery( this ).removeClass( value.call(this, j, this.className) ); + if ( jQuery.isFunction(value) ) { + return this.each(function(i) { + var self = jQuery(this); + self.removeClass( value.call(this, i, self.attr("class")) ); }); } if ( (value && typeof value === "string") || value === undefined ) { - classNames = (value || "").split( rspace ); + var classNames = (value || "").split( rspaces ); - for ( i = 0, l = this.length; i < l; i++ ) { - elem = this[ i ]; + for ( var i = 0, l = this.length; i < l; i++ ) { + var elem = this[i]; if ( elem.nodeType === 1 && elem.className ) { if ( value ) { - className = (" " + elem.className + " ").replace( rclass, " " ); - for ( c = 0, cl = classNames.length; c < cl; c++ ) { - className = className.replace(" " + classNames[ c ] + " ", " "); + var className = (" " + elem.className + " ").replace(rclass, " "); + for ( var c = 0, cl = classNames.length; c < cl; c++ ) { + className = className.replace(" " + classNames[c] + " ", " "); } elem.className = jQuery.trim( className ); @@ -111,8 +109,9 @@ jQuery.fn.extend({ isBool = typeof stateVal === "boolean"; if ( jQuery.isFunction( value ) ) { - return this.each(function( i ) { - jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + return this.each(function(i) { + var self = jQuery(this); + self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal ); }); } @@ -123,7 +122,7 @@ jQuery.fn.extend({ i = 0, self = jQuery( this ), state = stateVal, - classNames = value.split( rspace ); + classNames = value.split( rspaces ); while ( (className = classNames[ i++ ]) ) { // check each className given, space seperated list @@ -155,42 +154,82 @@ jQuery.fn.extend({ }, val: function( value ) { - var hooks, ret, - elem = this[0]; - if ( !arguments.length ) { - if ( elem ) { - hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ]; + var elem = this[0]; - if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { - return ret; + if ( elem ) { + if ( jQuery.nodeName( elem, "option" ) ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; } - ret = elem.value; + // We need to handle select boxes special + if ( jQuery.nodeName( elem, "select" ) ) { + var index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type === "select-one"; + + // Nothing was selected + if ( index < 0 ) { + return null; + } + + // Loop through all the selected options + for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { + var option = options[ i ]; + + // Don't return options that are disabled or in a disabled optgroup + if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && + (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { + + // Get the specific value for the option + value = jQuery(option).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + // Fixes Bug #2551 -- select.val() broken in IE after form.reset() + if ( one && !values.length && options.length ) { + return jQuery( options[ index ] ).val(); + } + + return values; + } + + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) { + return elem.getAttribute("value") === null ? "on" : elem.value; + } + + // Everything else, we just grab the value + return (elem.value || "").replace(rreturn, ""); - return typeof ret === "string" ? - // handle most common string cases - ret.replace(rreturn, "") : - // handle cases where value is null/undef or number - ret == null ? "" : ret; } return undefined; } - var isFunction = jQuery.isFunction( value ); + var isFunction = jQuery.isFunction(value); - return this.each(function( i ) { - var self = jQuery(this), val; + return this.each(function(i) { + var self = jQuery(this), val = value; if ( this.nodeType !== 1 ) { return; } if ( isFunction ) { - val = value.call( this, i, self.val() ); - } else { - val = value; + val = value.call(this, i, self.val()); } // Treat null/undefined as ""; convert numbers to string @@ -198,16 +237,27 @@ jQuery.fn.extend({ val = ""; } else if ( typeof val === "number" ) { val += ""; - } else if ( jQuery.isArray( val ) ) { - val = jQuery.map(val, function ( value ) { + } else if ( jQuery.isArray(val) ) { + val = jQuery.map(val, function (value) { return value == null ? "" : value + ""; }); } - hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ]; + if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) { + this.checked = jQuery.inArray( self.val(), val ) >= 0; - // If set returns undefined, fall back to normal setting - if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + } else if ( jQuery.nodeName( this, "select" ) ) { + var values = jQuery.makeArray(val); + + jQuery( "option", this ).each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + this.selectedIndex = -1; + } + + } else { this.value = val; } }); @@ -215,72 +265,6 @@ jQuery.fn.extend({ }); jQuery.extend({ - valHooks: { - option: { - get: function( elem ) { - // attributes.value is undefined in Blackberry 4.7 but - // uses .value. See #6932 - var val = elem.attributes.value; - return !val || val.specified ? elem.value : elem.text; - } - }, - select: { - get: function( elem ) { - var value, - index = elem.selectedIndex, - values = [], - options = elem.options, - one = elem.type === "select-one"; - - // Nothing was selected - if ( index < 0 ) { - return null; - } - - // Loop through all the selected options - for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { - var option = options[ i ]; - - // Don't return options that are disabled or in a disabled optgroup - if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && - (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { - - // Get the specific value for the option - value = jQuery( option ).val(); - - // We don't need an array for one selects - if ( one ) { - return value; - } - - // Multi-Selects return an array - values.push( value ); - } - } - - // Fixes Bug #2551 -- select.val() broken in IE after form.reset() - if ( one && !values.length && options.length ) { - return jQuery( options[ index ] ).val(); - } - - return values; - }, - - set: function( elem, value ) { - var values = jQuery.makeArray( value ); - - jQuery(elem).find("option").each(function() { - this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; - }); - - if ( !values.length ) { - elem.selectedIndex = -1; - } - return values; - } - } - }, - attrFn: { val: true, css: true, @@ -291,340 +275,115 @@ jQuery.extend({ height: true, offset: true }, - - attrFix: { - // Always normalize to ensure hook usage - tabindex: "tabIndex" - }, - + attr: function( elem, name, value, pass ) { - var nType = elem.nodeType; - // don't get/set attributes on text, comment and attribute nodes - if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || elem.nodeType === 2 ) { return undefined; } if ( pass && name in jQuery.attrFn ) { - return jQuery( elem )[ name ]( value ); + return jQuery(elem)[name](value); } - // Fallback to prop when attributes are not supported - if ( !("getAttribute" in elem) ) { - return jQuery.prop( elem, name, value ); - } + var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ), + // Whether we are setting (or getting) + set = value !== undefined; - var ret, hooks, - notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + // Try to normalize/fix the name + name = notxml && jQuery.props[ name ] || name; - // Normalize the name if needed - if ( notxml ) { - name = jQuery.attrFix[ name ] || name; - - hooks = jQuery.attrHooks[ name ]; - - if ( !hooks ) { - // Use boolHook for boolean attributes - if ( rboolean.test( name ) ) { - - hooks = boolHook; - - // Use formHook for forms and if the name contains certain characters - } else if ( formHook && name !== "className" && - (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) { - - hooks = formHook; - } - } - } - - if ( value !== undefined ) { - - if ( value === null ) { - jQuery.removeAttr( elem, name ); - return undefined; - - } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { - return ret; - - } else { - elem.setAttribute( name, "" + value ); - return value; - } - - } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { - return ret; - - } else { - - ret = elem.getAttribute( name ); - - // Non-existent attributes return null, we normalize to undefined - return ret === null ? - undefined : - ret; - } - }, - - removeAttr: function( elem, name ) { - var propName; + // Only do all the following if this is a node (faster for style) if ( elem.nodeType === 1 ) { - name = jQuery.attrFix[ name ] || name; - - if ( jQuery.support.getSetAttribute ) { - // Use removeAttribute in browsers that support it - elem.removeAttribute( name ); - } else { - jQuery.attr( elem, name, "" ); - elem.removeAttributeNode( elem.getAttributeNode( name ) ); - } + // These attributes require special treatment + var special = rspecialurl.test( name ); - // Set corresponding property to false for boolean attributes - if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) { - elem[ propName ] = false; - } - } - }, + // Safari mis-reports the default selected property of an option + // Accessing the parent's selectedIndex property fixes it + if ( name === "selected" && !jQuery.support.optSelected ) { + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; - attrHooks: { - type: { - set: function( elem, value ) { - // We can't allow the type property to be changed (since it causes problems in IE) - if ( rtype.test( elem.nodeName ) && elem.parentNode ) { - jQuery.error( "type property can't be changed" ); - } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { - // Setting the type on a radio button after the value resets the value in IE6-9 - // Reset value to it's default in case type is set after value - // This is for element creation - var val = elem.value; - elem.setAttribute( "type", value ); - if ( val ) { - elem.value = val; + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; } - return value; } } - }, - tabIndex: { - get: function( elem ) { + + // If applicable, access the attribute via the DOM 0 way + // 'in' checks fail in Blackberry 4.7 #6931 + if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) { + if ( set ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } + + if ( value === null ) { + if ( elem.nodeType === 1 ) { + elem.removeAttribute( name ); + } + + } else { + elem[ name ] = value; + } + } + + // browsers index elements by id/name on forms, give priority to attributes. + if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) { + return elem.getAttributeNode( name ).nodeValue; + } + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ - var attributeNode = elem.getAttributeNode("tabIndex"); + if ( name === "tabIndex" ) { + var attributeNode = elem.getAttributeNode( "tabIndex" ); - return attributeNode && attributeNode.specified ? - parseInt( attributeNode.value, 10 ) : - rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? - 0 : - undefined; - } - }, - // Use the value property for back compat - // Use the formHook for button elements in IE6/7 (#1954) - value: { - get: function( elem, name ) { - if ( formHook && jQuery.nodeName( elem, "button" ) ) { - return formHook.get( elem, name ); + return attributeNode && attributeNode.specified ? + attributeNode.value : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; } - return name in elem ? - elem.value : - null; - }, - set: function( elem, value, name ) { - if ( formHook && jQuery.nodeName( elem, "button" ) ) { - return formHook.set( elem, value, name ); - } - // Does not return so that setAttribute is also used - elem.value = value; - } - } - }, - propFix: { - tabindex: "tabIndex", - readonly: "readOnly", - "for": "htmlFor", - "class": "className", - maxlength: "maxLength", - cellspacing: "cellSpacing", - cellpadding: "cellPadding", - rowspan: "rowSpan", - colspan: "colSpan", - usemap: "useMap", - frameborder: "frameBorder", - contenteditable: "contentEditable" - }, - - prop: function( elem, name, value ) { - var nType = elem.nodeType; - - // don't get/set properties on text, comment and attribute nodes - if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { - return undefined; - } - - var ret, hooks, - notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); - - if ( notxml ) { - // Fix name and attach hooks - name = jQuery.propFix[ name ] || name; - hooks = jQuery.propHooks[ name ]; - } - - if ( value !== undefined ) { - if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { - return ret; - - } else { - return (elem[ name ] = value); - } - - } else { - if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) { - return ret; - - } else { return elem[ name ]; } - } - }, - - propHooks: {} -}); -// Hook for boolean attributes -boolHook = { - get: function( elem, name ) { - // Align boolean attributes with corresponding properties - return jQuery.prop( elem, name ) ? - name.toLowerCase() : - undefined; - }, - set: function( elem, value, name ) { - var propName; - if ( value === false ) { - // Remove boolean attributes when set to false - jQuery.removeAttr( elem, name ); - } else { - // value is true since we know at this point it's type boolean and not false - // Set boolean attributes to the same name and set the DOM property - propName = jQuery.propFix[ name ] || name; - if ( propName in elem ) { - // Only set the IDL specifically if it already exists on the element - elem[ propName ] = true; + if ( !jQuery.support.style && notxml && name === "style" ) { + if ( set ) { + elem.style.cssText = "" + value; + } + + return elem.style.cssText; } - elem.setAttribute( name, name.toLowerCase() ); + if ( set ) { + // convert the value to a string (all browsers do this but IE) see #1070 + elem.setAttribute( name, "" + value ); + } + + // Ensure that missing attributes return undefined + // Blackberry 4.7 returns "" from getAttribute #6938 + if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) { + return undefined; + } + + var attr = !jQuery.support.hrefNormalized && notxml && special ? + // Some attributes require a special call on IE + elem.getAttribute( name, 2 ) : + elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return attr === null ? undefined : attr; } - return name; + // Handle everything which isn't a DOM element node + if ( set ) { + elem[ name ] = value; + } + return elem[ name ]; } -}; - -// IE6/7 do not support getting/setting some attributes with get/setAttribute -if ( !jQuery.support.getSetAttribute ) { - - // propFix is more comprehensive and contains all fixes - jQuery.attrFix = jQuery.propFix; - - // Use this for any attribute on a form in IE6/7 - formHook = jQuery.attrHooks.name = jQuery.attrHooks.title = jQuery.valHooks.button = { - get: function( elem, name ) { - var ret; - ret = elem.getAttributeNode( name ); - // Return undefined if nodeValue is empty string - return ret && ret.nodeValue !== "" ? - ret.nodeValue : - undefined; - }, - set: function( elem, value, name ) { - // Check form objects in IE (multiple bugs related) - // Only use nodeValue if the attribute node exists on the form - var ret = elem.getAttributeNode( name ); - if ( ret ) { - ret.nodeValue = value; - return value; - } - } - }; - - // Set width and height to auto instead of 0 on empty string( Bug #8150 ) - // This is for removals - jQuery.each([ "width", "height" ], function( i, name ) { - jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { - set: function( elem, value ) { - if ( value === "" ) { - elem.setAttribute( name, "auto" ); - return value; - } - } - }); - }); -} - - -// Some attributes require a special call on IE -if ( !jQuery.support.hrefNormalized ) { - jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { - jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { - get: function( elem ) { - var ret = elem.getAttribute( name, 2 ); - return ret === null ? undefined : ret; - } - }); - }); -} - -if ( !jQuery.support.style ) { - jQuery.attrHooks.style = { - get: function( elem ) { - // Return undefined in the case of empty string - // Normalize to lowercase since IE uppercases css property names - return elem.style.cssText.toLowerCase() || undefined; - }, - set: function( elem, value ) { - return (elem.style.cssText = "" + value); - } - }; -} - -// Safari mis-reports the default selected property of an option -// Accessing the parent's selectedIndex property fixes it -if ( !jQuery.support.optSelected ) { - jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { - get: function( elem ) { - var parent = elem.parentNode; - - if ( parent ) { - parent.selectedIndex; - - // Make sure that it also works with optgroups, see #5701 - if ( parent.parentNode ) { - parent.parentNode.selectedIndex; - } - } - } - }); -} - -// Radios and checkboxes getter/setter -if ( !jQuery.support.checkOn ) { - jQuery.each([ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = { - get: function( elem ) { - // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified - return elem.getAttribute("value") === null ? "on" : elem.value; - } - }; - }); -} -jQuery.each([ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { - set: function( elem, value ) { - if ( jQuery.isArray( value ) ) { - return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0); - } - } - }); }); })( jQuery ); diff --git a/src/core.js b/src/core.js index ab0d9f7b..d77c818e 100644 --- a/src/core.js +++ b/src/core.js @@ -17,7 +17,7 @@ var jQuery = function( selector, context ) { // A simple way to check for HTML strings or ID strings // (both of which we optimize for) - quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/, // Check if a string has a non-whitespace character in it rnotwhite = /\S/, @@ -44,23 +44,21 @@ var jQuery = function( selector, context ) { rmsie = /(msie) ([\w.]+)/, rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, - // Matches dashed string for camelizing - rdashAlpha = /-([a-z])/ig, - - // Used by jQuery.camelCase as callback to replace() - fcamelCase = function( all, letter ) { - return letter.toUpperCase(); - }, - // Keep a UserAgent string for use with jQuery.browser userAgent = navigator.userAgent, // For matching the engine and version of the browser browserMatch, + // Has the ready events already been bound? + readyBound = false, + // The deferred used on DOM ready readyList, + // Promise methods + promiseMethods = "then done fail isResolved isRejected promise".split( " " ), + // The ready event handler DOMContentLoaded, @@ -96,7 +94,7 @@ jQuery.fn = jQuery.prototype = { if ( selector === "body" && !context && document.body ) { this.context = document; this[0] = document.body; - this.selector = selector; + this.selector = "body"; this.length = 1; return this; } @@ -104,13 +102,7 @@ jQuery.fn = jQuery.prototype = { // Handle HTML strings if ( typeof selector === "string" ) { // Are we dealing with HTML string or an ID? - if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [ null, selector, null ]; - - } else { - match = quickExpr.exec( selector ); - } + match = quickExpr.exec( selector ); // Verify a match, and that no context was specified for #id if ( match && (match[1] || !context) ) { @@ -367,11 +359,9 @@ jQuery.extend = jQuery.fn.extend = function() { jQuery.extend({ noConflict: function( deep ) { - if ( window.$ === jQuery ) { - window.$ = _$; - } + window.$ = _$; - if ( deep && window.jQuery === jQuery ) { + if ( deep ) { window.jQuery = _jQuery; } @@ -385,19 +375,15 @@ jQuery.extend({ // the ready event fires. See #6781 readyWait: 1, - // Hold (or release) the ready event - holdReady: function( hold ) { - if ( hold ) { - jQuery.readyWait++; - } else { - jQuery.ready( true ); - } - }, - // Handle when the DOM is ready ready: function( wait ) { - // Either a released hold or an DOMready/load event and not yet ready - if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { + // A third-party is pushing the ready event forwards + if ( wait === true ) { + jQuery.readyWait--; + } + + // Make sure that the DOM is not already loaded + if ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) { // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). if ( !document.body ) { return setTimeout( jQuery.ready, 1 ); @@ -422,11 +408,11 @@ jQuery.extend({ }, bindReady: function() { - if ( readyList ) { + if ( readyBound ) { return; } - readyList = jQuery._Deferred(); + readyBound = true; // Catch cases where $(document).ready() is called after the // browser event has already occurred. @@ -447,7 +433,7 @@ jQuery.extend({ } else if ( document.attachEvent ) { // ensure firing before onload, // maybe late but safe also for iframes - document.attachEvent( "onreadystatechange", DOMContentLoaded ); + document.attachEvent("onreadystatechange", DOMContentLoaded); // A fallback to window.onload, that will always work window.attachEvent( "onload", jQuery.ready ); @@ -535,21 +521,20 @@ jQuery.extend({ // Make sure leading/trailing whitespace is removed (IE can't handle it) data = jQuery.trim( data ); - // Attempt to parse using the native JSON parser first - if ( window.JSON && window.JSON.parse ) { - return window.JSON.parse( data ); - } - // Make sure the incoming data is actual JSON // Logic borrowed from http://json.org/json2.js - if ( rvalidchars.test( data.replace( rvalidescape, "@" ) - .replace( rvalidtokens, "]" ) - .replace( rvalidbraces, "")) ) { + if ( rvalidchars.test(data.replace(rvalidescape, "@") + .replace(rvalidtokens, "]") + .replace(rvalidbraces, "")) ) { - return (new Function( "return " + data ))(); + // Try to use the native JSON parser first + return window.JSON && window.JSON.parse ? + window.JSON.parse( data ) : + (new Function("return " + data))(); + } else { + jQuery.error( "Invalid JSON: " + data ); } - jQuery.error( "Invalid JSON: " + data ); }, // Cross-browser xml parsing @@ -576,24 +561,25 @@ jQuery.extend({ noop: function() {}, - // Evaluates a script in a global context - // Workarounds based on findings by Jim Driscoll - // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + // Evalulates a script in a global context globalEval: function( data ) { - if ( data && rnotwhite.test( data ) ) { - // We use execScript on Internet Explorer - // We use an anonymous function so that context is window - // rather than jQuery in Firefox - ( window.execScript || function( data ) { - window[ "eval" ].call( window, data ); - } )( data ); - } - }, + if ( data && rnotwhite.test(data) ) { + // Inspired by code by Andrea Giammarchi + // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html + var head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement, + script = document.createElement( "script" ); - // Converts a dashed string to camelCased string; - // Used by both the css and data modules - camelCase: function( string ) { - return string.replace( rdashAlpha, fcamelCase ); + if ( jQuery.support.scriptEval() ) { + script.appendChild( document.createTextNode( data ) ); + } else { + script.text = data; + } + + // Use insertBefore instead of appendChild to circumvent an IE6 bug. + // This arises when a base node is used (#2709). + head.insertBefore( script, head.firstChild ); + head.removeChild( script ); + } }, nodeName: function( elem, name ) { @@ -604,7 +590,7 @@ jQuery.extend({ each: function( object, callback, args ) { var name, i = 0, length = object.length, - isObj = length === undefined || jQuery.isFunction( object ); + isObj = length === undefined || jQuery.isFunction(object); if ( args ) { if ( isObj ) { @@ -630,11 +616,8 @@ jQuery.extend({ } } } else { - for ( ; i < length; ) { - if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { - break; - } - } + for ( var value = object[0]; + i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {} } } @@ -665,7 +648,7 @@ jQuery.extend({ // The extra typeof function check is to prevent crashes // in Safari 2 (See: #3039) // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 - var type = jQuery.type( array ); + var type = jQuery.type(array); if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { push.call( ret, array ); @@ -678,9 +661,8 @@ jQuery.extend({ }, inArray: function( elem, array ) { - - if ( indexOf ) { - return indexOf.call( array, elem ); + if ( array.indexOf ) { + return array.indexOf( elem ); } for ( var i = 0, length = array.length; i < length; i++ ) { @@ -730,30 +712,15 @@ jQuery.extend({ // arg is for internal usage only map: function( elems, callback, arg ) { - var value, key, ret = [], - i = 0, - length = elems.length, - // jquery objects are treated as arrays - isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; + var ret = [], value; // Go through the array, translating each of the items to their - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); + // new value (or values). + for ( var i = 0, length = elems.length; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); - if ( value != null ) { - ret[ ret.length ] = value; - } - } - - // Go through every key on the object, - } else { - for ( key in elems ) { - value = callback( elems[ key ], key, arg ); - - if ( value != null ) { - ret[ ret.length ] = value; - } + if ( value != null ) { + ret[ ret.length ] = value; } } @@ -764,35 +731,36 @@ jQuery.extend({ // A global GUID counter for objects guid: 1, - // Bind a function to a context, optionally partially applying any - // arguments. - proxy: function( fn, context ) { - if ( typeof context === "string" ) { - var tmp = fn[ context ]; - context = fn; - fn = tmp; + proxy: function( fn, proxy, thisObject ) { + if ( arguments.length === 2 ) { + if ( typeof proxy === "string" ) { + thisObject = fn; + fn = thisObject[ proxy ]; + proxy = undefined; + + } else if ( proxy && !jQuery.isFunction( proxy ) ) { + thisObject = proxy; + proxy = undefined; + } } - // Quick check to determine if target is callable, in the spec - // this throws a TypeError, but we will just return undefined. - if ( !jQuery.isFunction( fn ) ) { - return undefined; - } - - // Simulated bind - var args = slice.call( arguments, 2 ), + if ( !proxy && fn ) { proxy = function() { - return fn.apply( context, args.concat( slice.call( arguments ) ) ); + return fn.apply( thisObject || this, arguments ); }; + } // Set the guid of unique handler to the same of original handler, so it can be removed - proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; + if ( fn ) { + proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; + } + // So proxy can be declared as an argument return proxy; }, // Mutifunctional method to get and set values to a collection - // The value/s can optionally be executed if it's a function + // The value/s can be optionally by executed if its a function access: function( elems, key, value, exec, fn, pass ) { var length = elems.length; @@ -824,6 +792,171 @@ jQuery.extend({ return (new Date()).getTime(); }, + // Create a simple deferred (one callbacks list) + _Deferred: function() { + var // callbacks list + callbacks = [], + // stored [ context , args ] + fired, + // to avoid firing when already doing so + firing, + // flag to know if the deferred has been cancelled + cancelled, + // the deferred itself + deferred = { + + // done( f1, f2, ...) + done: function() { + if ( !cancelled ) { + var args = arguments, + i, + length, + elem, + type, + _fired; + if ( fired ) { + _fired = fired; + fired = 0; + } + for ( i = 0, length = args.length; i < length; i++ ) { + elem = args[ i ]; + type = jQuery.type( elem ); + if ( type === "array" ) { + deferred.done.apply( deferred, elem ); + } else if ( type === "function" ) { + callbacks.push( elem ); + } + } + if ( _fired ) { + deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] ); + } + } + return this; + }, + + // resolve with given context and args + resolveWith: function( context, args ) { + if ( !cancelled && !fired && !firing ) { + firing = 1; + try { + while( callbacks[ 0 ] ) { + callbacks.shift().apply( context, args ); + } + } + // We have to add a catch block for + // IE prior to 8 or else the finally + // block will never get executed + catch (e) { + throw e; + } + finally { + fired = [ context, args ]; + firing = 0; + } + } + return this; + }, + + // resolve with this as context and given arguments + resolve: function() { + deferred.resolveWith( jQuery.isFunction( this.promise ) ? this.promise() : this, arguments ); + return this; + }, + + // Has this deferred been resolved? + isResolved: function() { + return !!( firing || fired ); + }, + + // Cancel + cancel: function() { + cancelled = 1; + callbacks = []; + return this; + } + }; + + return deferred; + }, + + // Full fledged deferred (two callbacks list) + Deferred: function( func ) { + var deferred = jQuery._Deferred(), + failDeferred = jQuery._Deferred(), + promise; + // Add errorDeferred methods, then and promise + jQuery.extend( deferred, { + then: function( doneCallbacks, failCallbacks ) { + deferred.done( doneCallbacks ).fail( failCallbacks ); + return this; + }, + fail: failDeferred.done, + rejectWith: failDeferred.resolveWith, + reject: failDeferred.resolve, + isRejected: failDeferred.isResolved, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + if ( obj == null ) { + if ( promise ) { + return promise; + } + promise = obj = {}; + } + var i = promiseMethods.length; + while( i-- ) { + obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ]; + } + return obj; + } + } ); + // Make sure only one callback list will be used + deferred.done( failDeferred.cancel ).fail( deferred.cancel ); + // Unexpose cancel + delete deferred.cancel; + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + return deferred; + }, + + // Deferred helper + when: function( object ) { + var lastIndex = arguments.length, + deferred = lastIndex <= 1 && object && jQuery.isFunction( object.promise ) ? + object : + jQuery.Deferred(), + promise = deferred.promise(); + + if ( lastIndex > 1 ) { + var array = slice.call( arguments, 0 ), + count = lastIndex, + iCallback = function( index ) { + return function( value ) { + array[ index ] = arguments.length > 1 ? slice.call( arguments, 0 ) : value; + if ( !( --count ) ) { + deferred.resolveWith( promise, array ); + } + }; + }; + while( ( lastIndex-- ) ) { + object = array[ lastIndex ]; + if ( object && jQuery.isFunction( object.promise ) ) { + object.promise().then( iCallback(lastIndex), deferred.reject ); + } else { + --count; + } + } + if ( !count ) { + deferred.resolveWith( promise, array ); + } + } else if ( deferred !== object ) { + deferred.resolve( object ); + } + return promise; + }, + // Use of jQuery.browser is frowned upon. // More details: http://docs.jquery.com/Utilities/jQuery.browser uaMatch: function( ua ) { @@ -839,29 +972,32 @@ jQuery.extend({ }, sub: function() { - function jQuerySub( selector, context ) { - return new jQuerySub.fn.init( selector, context ); + function jQuerySubclass( selector, context ) { + return new jQuerySubclass.fn.init( selector, context ); } - jQuery.extend( true, jQuerySub, this ); - jQuerySub.superclass = this; - jQuerySub.fn = jQuerySub.prototype = this(); - jQuerySub.fn.constructor = jQuerySub; - jQuerySub.sub = this.sub; - jQuerySub.fn.init = function init( selector, context ) { - if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { - context = jQuerySub( context ); + jQuery.extend( true, jQuerySubclass, this ); + jQuerySubclass.superclass = this; + jQuerySubclass.fn = jQuerySubclass.prototype = this(); + jQuerySubclass.fn.constructor = jQuerySubclass; + jQuerySubclass.subclass = this.subclass; + jQuerySubclass.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySubclass) ) { + context = jQuerySubclass(context); } - return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); + return jQuery.fn.init.call( this, selector, context, rootjQuerySubclass ); }; - jQuerySub.fn.init.prototype = jQuerySub.fn; - var rootjQuerySub = jQuerySub(document); - return jQuerySub; + jQuerySubclass.fn.init.prototype = jQuerySubclass.fn; + var rootjQuerySubclass = jQuerySubclass(document); + return jQuerySubclass; }, browser: {} }); +// Create readyList deferred +readyList = jQuery._Deferred(); + // Populate the class2type map jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { class2type[ "[object " + name + "]" ] = name.toLowerCase(); @@ -878,6 +1014,12 @@ if ( jQuery.browser.webkit ) { jQuery.browser.safari = true; } +if ( indexOf ) { + jQuery.inArray = function( elem, array ) { + return indexOf.call( array, elem ); + }; +} + // IE doesn't match non-breaking spaces with \s if ( rnotwhite.test( "\xA0" ) ) { trimLeft = /^[\s\xA0]+/; @@ -923,6 +1065,7 @@ function doScrollCheck() { jQuery.ready(); } +// Expose jQuery to the global object return jQuery; })(); diff --git a/src/css.js b/src/css.js index cb7df9f8..8a982312 100644 --- a/src/css.js +++ b/src/css.js @@ -2,12 +2,10 @@ var ralpha = /alpha\([^)]*\)/i, ropacity = /opacity=([^)]*)/, - // fixed for IE9, see #8346 - rupper = /([A-Z]|^ms)/g, + rdashAlpha = /-([a-z])/ig, + rupper = /([A-Z])/g, rnumpx = /^-?\d+(?:px)?$/i, rnum = /^-?\d/, - rrelNum = /^[+\-]=/, - rrelNumFilter = /[^+\-\.\de]+/g, cssShow = { position: "absolute", visibility: "hidden", display: "block" }, cssWidth = [ "Left", "Right" ], @@ -15,7 +13,11 @@ var ralpha = /alpha\([^)]*\)/i, curCSS, getComputedStyle, - currentStyle; + currentStyle, + + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; jQuery.fn.css = function( name, value ) { // Setting 'undefined' is a no-op @@ -50,14 +52,11 @@ jQuery.extend({ // Exclude the following css properties to add px cssNumber: { - "fillOpacity": true, - "fontWeight": true, - "lineHeight": true, - "opacity": true, - "orphans": true, - "widows": true, "zIndex": true, - "zoom": true + "fontWeight": true, + "opacity": true, + "zoom": true, + "lineHeight": true }, // Add in properties whose names you wish to fix before @@ -75,29 +74,20 @@ jQuery.extend({ } // Make sure that we're working with the right name - var ret, type, origName = jQuery.camelCase( name ), + var ret, origName = jQuery.camelCase( name ), style = elem.style, hooks = jQuery.cssHooks[ origName ]; name = jQuery.cssProps[ origName ] || origName; // Check if we're setting a value if ( value !== undefined ) { - type = typeof value; - // Make sure that NaN and null values aren't set. See: #7116 - if ( type === "number" && isNaN( value ) || value == null ) { + if ( typeof value === "number" && isNaN( value ) || value == null ) { return; } - // convert relative number strings (+= or -=) to relative numbers. #7345 - if ( type === "string" && rrelNum.test( value ) ) { - value = +value.replace( rrelNumFilter, "" ) + parseFloat( jQuery.css( elem, name ) ); - // Fixes bug #9237 - type = "number"; - } - // If a number was passed in, add 'px' to the (except for certain CSS properties) - if ( type === "number" && !jQuery.cssNumber[ origName ] ) { + if ( typeof value === "number" && !jQuery.cssNumber[ origName ] ) { value += "px"; } @@ -122,17 +112,11 @@ jQuery.extend({ }, css: function( elem, name, extra ) { - var ret, hooks; - // Make sure that we're working with the right name - name = jQuery.camelCase( name ); - hooks = jQuery.cssHooks[ name ]; - name = jQuery.cssProps[ name ] || name; + var ret, origName = jQuery.camelCase( name ), + hooks = jQuery.cssHooks[ origName ]; - // cssFloat needs a special treatment - if ( name === "cssFloat" ) { - name = "float"; - } + name = jQuery.cssProps[ origName ] || origName; // If a hook was provided get the computed value from there if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) { @@ -140,7 +124,7 @@ jQuery.extend({ // Otherwise, if a way to get the computed value exists, use that } else if ( curCSS ) { - return curCSS( elem, name ); + return curCSS( elem, name, origName ); } }, @@ -160,6 +144,10 @@ jQuery.extend({ for ( name in options ) { elem.style[ name ] = old[ name ]; } + }, + + camelCase: function( string ) { + return string.replace( rdashAlpha, fcamelCase ); } }); @@ -173,21 +161,44 @@ jQuery.each(["height", "width"], function( i, name ) { if ( computed ) { if ( elem.offsetWidth !== 0 ) { - return getWH( elem, name, extra ); + val = getWH( elem, name, extra ); + } else { jQuery.swap( elem, cssShow, function() { val = getWH( elem, name, extra ); }); } - return val; + if ( val <= 0 ) { + val = curCSS( elem, name, name ); + + if ( val === "0px" && currentStyle ) { + val = currentStyle( elem, name, name ); + } + + if ( val != null ) { + // Should return "auto" instead of 0, use 0 for + // temporary backwards-compat + return val === "" || val === "auto" ? "0px" : val; + } + } + + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + + // Should return "auto" instead of 0, use 0 for + // temporary backwards-compat + return val === "" || val === "auto" ? "0px" : val; + } + + return typeof val === "string" ? val : val + "px"; } }, set: function( elem, value ) { if ( rnumpx.test( value ) ) { // ignore negative width and height values #1599 - value = parseFloat( value ); + value = parseFloat(value); if ( value >= 0 ) { return value + "px"; @@ -204,56 +215,33 @@ if ( !jQuery.support.opacity ) { jQuery.cssHooks.opacity = { get: function( elem, computed ) { // IE uses filters for opacity - return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? - ( parseFloat( RegExp.$1 ) / 100 ) + "" : + return ropacity.test((computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "") ? + (parseFloat(RegExp.$1) / 100) + "" : computed ? "1" : ""; }, set: function( elem, value ) { - var style = elem.style, - currentStyle = elem.currentStyle; + var style = elem.style; // IE has trouble with opacity if it does not have layout // Force it by setting the zoom level style.zoom = 1; // Set the alpha filter to set the opacity - var opacity = jQuery.isNaN( value ) ? + var opacity = jQuery.isNaN(value) ? "" : "alpha(opacity=" + value * 100 + ")", - filter = currentStyle && currentStyle.filter || style.filter || ""; + filter = style.filter || ""; - style.filter = ralpha.test( filter ) ? - filter.replace( ralpha, opacity ) : - filter + " " + opacity; + style.filter = ralpha.test(filter) ? + filter.replace(ralpha, opacity) : + style.filter + ' ' + opacity; } }; } -jQuery(function() { - // This hook cannot be added until DOM ready because the support test - // for it is not run until after DOM ready - if ( !jQuery.support.reliableMarginRight ) { - jQuery.cssHooks.marginRight = { - get: function( elem, computed ) { - // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right - // Work around by temporarily setting element display to inline-block - var ret; - jQuery.swap( elem, { "display": "inline-block" }, function() { - if ( computed ) { - ret = curCSS( elem, "margin-right", "marginRight" ); - } else { - ret = elem.style.marginRight; - } - }); - return ret; - } - }; - } -}); - if ( document.defaultView && document.defaultView.getComputedStyle ) { - getComputedStyle = function( elem, name ) { + getComputedStyle = function( elem, newName, name ) { var ret, defaultView, computedStyle; name = name.replace( rupper, "-$1" ).toLowerCase(); @@ -310,50 +298,27 @@ if ( document.documentElement.currentStyle ) { curCSS = getComputedStyle || currentStyle; function getWH( elem, name, extra ) { + var which = name === "width" ? cssWidth : cssHeight, + val = name === "width" ? elem.offsetWidth : elem.offsetHeight; - // Start with offset property - var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, - which = name === "width" ? cssWidth : cssHeight; + if ( extra === "border" ) { + return val; + } - if ( val > 0 ) { - if ( extra !== "border" ) { - jQuery.each( which, function() { - if ( !extra ) { - val -= parseFloat( jQuery.css( elem, "padding" + this ) ) || 0; - } - if ( extra === "margin" ) { - val += parseFloat( jQuery.css( elem, extra + this ) ) || 0; - } else { - val -= parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0; - } - }); + jQuery.each( which, function() { + if ( !extra ) { + val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0; } - return val + "px"; - } + if ( extra === "margin" ) { + val += parseFloat(jQuery.css( elem, "margin" + this )) || 0; - // Fall back to computed then uncomputed css if necessary - val = curCSS( elem, name, name ); - if ( val < 0 || val == null ) { - val = elem.style[ name ] || 0; - } - // Normalize "", auto, and prepare for extra - val = parseFloat( val ) || 0; + } else { + val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0; + } + }); - // Add padding, border, margin - if ( extra ) { - jQuery.each( which, function() { - val += parseFloat( jQuery.css( elem, "padding" + this ) ) || 0; - if ( extra !== "padding" ) { - val += parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0; - } - if ( extra === "margin" ) { - val += parseFloat( jQuery.css( elem, extra + this ) ) || 0; - } - }); - } - - return val + "px"; + return val; } if ( jQuery.expr && jQuery.expr.filters ) { diff --git a/src/data.js b/src/data.js index f69d9dec..2d53a710 100644 --- a/src/data.js +++ b/src/data.js @@ -1,7 +1,6 @@ (function( jQuery ) { -var rbrace = /^(?:\{.*\}|\[.*\])$/, - rmultiDash = /([a-z])([A-Z])/g; +var rbrace = /^(?:\{.*\}|\[.*\])$/; jQuery.extend({ cache: {}, @@ -98,7 +97,7 @@ jQuery.extend({ } if ( data !== undefined ) { - thisCache[ jQuery.camelCase( name ) ] = data; + thisCache[ name ] = data; } // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should @@ -108,10 +107,7 @@ jQuery.extend({ return thisCache[ internalKey ] && thisCache[ internalKey ].events; } - return getByName ? - // Check for both converted-to-camel and non-converted data property names - thisCache[ jQuery.camelCase( name ) ] || thisCache[ name ] : - thisCache; + return getByName ? thisCache[ name ] : thisCache; }, removeData: function( elem, name, pvt /* Internal Use Only */ ) { @@ -227,13 +223,12 @@ jQuery.fn.extend({ data = jQuery.data( this[0] ); if ( this[0].nodeType === 1 ) { - var attr = this[0].attributes, name; + var attr = this[0].attributes, name; for ( var i = 0, l = attr.length; i < l; i++ ) { name = attr[i].name; if ( name.indexOf( "data-" ) === 0 ) { - name = jQuery.camelCase( name.substring(5) ); - + name = name.substr( 5 ); dataAttr( this[0], name, data[ name ] ); } } @@ -287,9 +282,7 @@ function dataAttr( elem, key, data ) { // If nothing was found internally, try to fetch any // data from the HTML5 data-* attribute if ( data === undefined && elem.nodeType === 1 ) { - var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase(); - - data = elem.getAttribute( name ); + data = elem.getAttribute( "data-" + key ); if ( typeof data === "string" ) { try { diff --git a/src/deferred.js b/src/deferred.js deleted file mode 100644 index e543f151..00000000 --- a/src/deferred.js +++ /dev/null @@ -1,199 +0,0 @@ -(function( jQuery ) { - -var // Promise methods - promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ), - // Static reference to slice - sliceDeferred = [].slice; - -jQuery.extend({ - // Create a simple deferred (one callbacks list) - _Deferred: function() { - var // callbacks list - callbacks = [], - // stored [ context , args ] - fired, - // to avoid firing when already doing so - firing, - // flag to know if the deferred has been cancelled - cancelled, - // the deferred itself - deferred = { - - // done( f1, f2, ...) - done: function() { - if ( !cancelled ) { - var args = arguments, - i, - length, - elem, - type, - _fired; - if ( fired ) { - _fired = fired; - fired = 0; - } - for ( i = 0, length = args.length; i < length; i++ ) { - elem = args[ i ]; - type = jQuery.type( elem ); - if ( type === "array" ) { - deferred.done.apply( deferred, elem ); - } else if ( type === "function" ) { - callbacks.push( elem ); - } - } - if ( _fired ) { - deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] ); - } - } - return this; - }, - - // resolve with given context and args - resolveWith: function( context, args ) { - if ( !cancelled && !fired && !firing ) { - // make sure args are available (#8421) - args = args || []; - firing = 1; - try { - while( callbacks[ 0 ] ) { - callbacks.shift().apply( context, args ); - } - } - finally { - fired = [ context, args ]; - firing = 0; - } - } - return this; - }, - - // resolve with this as context and given arguments - resolve: function() { - deferred.resolveWith( this, arguments ); - return this; - }, - - // Has this deferred been resolved? - isResolved: function() { - return !!( firing || fired ); - }, - - // Cancel - cancel: function() { - cancelled = 1; - callbacks = []; - return this; - } - }; - - return deferred; - }, - - // Full fledged deferred (two callbacks list) - Deferred: function( func ) { - var deferred = jQuery._Deferred(), - failDeferred = jQuery._Deferred(), - promise; - // Add errorDeferred methods, then and promise - jQuery.extend( deferred, { - then: function( doneCallbacks, failCallbacks ) { - deferred.done( doneCallbacks ).fail( failCallbacks ); - return this; - }, - always: function() { - return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments ); - }, - fail: failDeferred.done, - rejectWith: failDeferred.resolveWith, - reject: failDeferred.resolve, - isRejected: failDeferred.isResolved, - pipe: function( fnDone, fnFail ) { - return jQuery.Deferred(function( newDefer ) { - jQuery.each( { - done: [ fnDone, "resolve" ], - fail: [ fnFail, "reject" ] - }, function( handler, data ) { - var fn = data[ 0 ], - action = data[ 1 ], - returned; - if ( jQuery.isFunction( fn ) ) { - deferred[ handler ](function() { - returned = fn.apply( this, arguments ); - if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise().then( newDefer.resolve, newDefer.reject ); - } else { - newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); - } - }); - } else { - deferred[ handler ]( newDefer[ action ] ); - } - }); - }).promise(); - }, - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - if ( obj == null ) { - if ( promise ) { - return promise; - } - promise = obj = {}; - } - var i = promiseMethods.length; - while( i-- ) { - obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ]; - } - return obj; - } - }); - // Make sure only one callback list will be used - deferred.done( failDeferred.cancel ).fail( deferred.cancel ); - // Unexpose cancel - delete deferred.cancel; - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - return deferred; - }, - - // Deferred helper - when: function( firstParam ) { - var args = arguments, - i = 0, - length = args.length, - count = length, - deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? - firstParam : - jQuery.Deferred(); - function resolveFunc( i ) { - return function( value ) { - args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; - if ( !( --count ) ) { - // Strange bug in FF4: - // Values changed onto the arguments object sometimes end up as undefined values - // outside the $.when method. Cloning the object into a fresh array solves the issue - deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) ); - } - }; - } - if ( length > 1 ) { - for( ; i < length; i++ ) { - if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) { - args[ i ].promise().then( resolveFunc(i), deferred.reject ); - } else { - --count; - } - } - if ( !count ) { - deferred.resolveWith( deferred, args ); - } - } else if ( deferred !== firstParam ) { - deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); - } - return deferred.promise(); - } -}); - -})( jQuery ); \ No newline at end of file diff --git a/src/dimensions.js b/src/dimensions.js index 88fa1750..e2d411dd 100644 --- a/src/dimensions.js +++ b/src/dimensions.js @@ -1,23 +1,21 @@ (function( jQuery ) { -// Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods +// Create innerHeight, innerWidth, outerHeight and outerWidth methods jQuery.each([ "Height", "Width" ], function( i, name ) { var type = name.toLowerCase(); // innerHeight and innerWidth - jQuery.fn[ "inner" + name ] = function() { - var elem = this[0]; - return elem && elem.style ? - parseFloat( jQuery.css( elem, type, "padding" ) ) : + jQuery.fn["inner" + name] = function() { + return this[0] ? + parseFloat( jQuery.css( this[0], type, "padding" ) ) : null; }; // outerHeight and outerWidth - jQuery.fn[ "outer" + name ] = function( margin ) { - var elem = this[0]; - return elem && elem.style ? - parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) : + jQuery.fn["outer" + name] = function( margin ) { + return this[0] ? + parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) : null; }; diff --git a/src/effects.js b/src/effects.js index a7529a0f..d9e9a8b3 100644 --- a/src/effects.js +++ b/src/effects.js @@ -1,7 +1,6 @@ (function( jQuery ) { var elemdisplay = {}, - iframe, iframeDoc, rfxtypes = /^(?:toggle|show|hide)$/, rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i, timerId, @@ -12,11 +11,7 @@ var elemdisplay = {}, [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ], // opacity animations [ "opacity" ] - ], - fxNow, - requestAnimationFrame = window.webkitRequestAnimationFrame || - window.mozRequestAnimationFrame || - window.oRequestAnimationFrame; + ]; jQuery.fn.extend({ show: function( speed, easing, callback ) { @@ -28,22 +23,19 @@ jQuery.fn.extend({ } else { for ( var i = 0, j = this.length; i < j; i++ ) { elem = this[i]; + display = elem.style.display; - if ( elem.style ) { - display = elem.style.display; + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !jQuery._data(elem, "olddisplay") && display === "none" ) { + display = elem.style.display = ""; + } - // Reset the inline display of this element to learn if it is - // being hidden by cascaded rules or not - if ( !jQuery._data(elem, "olddisplay") && display === "none" ) { - display = elem.style.display = ""; - } - - // Set elements which have been overridden with display: none - // in a stylesheet to whatever the default browser style is - // for such an element - if ( display === "" && jQuery.css( elem, "display" ) === "none" ) { - jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName)); - } + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( display === "" && jQuery.css( elem, "display" ) === "none" ) { + jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName)); } } @@ -51,13 +43,10 @@ jQuery.fn.extend({ // to avoid the constant reflow for ( i = 0; i < j; i++ ) { elem = this[i]; + display = elem.style.display; - if ( elem.style ) { - display = elem.style.display; - - if ( display === "" || display === "none" ) { - elem.style.display = jQuery._data(elem, "olddisplay") || ""; - } + if ( display === "" || display === "none" ) { + elem.style.display = jQuery._data(elem, "olddisplay") || ""; } } @@ -71,21 +60,17 @@ jQuery.fn.extend({ } else { for ( var i = 0, j = this.length; i < j; i++ ) { - if ( this[i].style ) { - var display = jQuery.css( this[i], "display" ); + var display = jQuery.css( this[i], "display" ); - if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) { - jQuery._data( this[i], "olddisplay", display ); - } + if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) { + jQuery._data( this[i], "olddisplay", display ); } } // Set the display of the elements in a second loop // to avoid the constant reflow for ( i = 0; i < j; i++ ) { - if ( this[i].style ) { - this[i].style.display = "none"; - } + this[i].style.display = "none"; } return this; @@ -123,54 +108,32 @@ jQuery.fn.extend({ var optall = jQuery.speed(speed, easing, callback); if ( jQuery.isEmptyObject( prop ) ) { - return this.each( optall.complete, [ false ] ); + return this.each( optall.complete ); } - // Do not change referenced properties as per-property easing will be lost - prop = jQuery.extend( {}, prop ); - return this[ optall.queue === false ? "each" : "queue" ](function() { // XXX 'this' does not always have a nodeName when running the // test suite - if ( optall.queue === false ) { - jQuery._mark( this ); - } - - var opt = jQuery.extend( {}, optall ), + var opt = jQuery.extend({}, optall), p, isElement = this.nodeType === 1, hidden = isElement && jQuery(this).is(":hidden"), - name, val, p, - display, e, - parts, start, end, unit; - - // will store per property easing and be used to determine when an animation is complete - opt.animatedProperties = {}; + self = this; for ( p in prop ) { + var name = jQuery.camelCase( p ); - // property name normalization - name = jQuery.camelCase( p ); if ( p !== name ) { prop[ name ] = prop[ p ]; delete prop[ p ]; + p = name; } - val = prop[ name ]; - - // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default) - if ( jQuery.isArray( val ) ) { - opt.animatedProperties[ name ] = val[ 1 ]; - val = prop[ name ] = val[ 0 ]; - } else { - opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing'; + if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) { + return opt.complete.call(this); } - if ( val === "hide" && hidden || val === "show" && !hidden ) { - return opt.complete.call( this ); - } - - if ( isElement && ( name === "height" || name === "width" ) ) { + if ( isElement && ( p === "height" || p === "width" ) ) { // Make sure that nothing sneaks out // Record all 3 overflow attributes because IE does not // change the overflow attribute when overflowX and @@ -186,7 +149,7 @@ jQuery.fn.extend({ this.style.display = "inline-block"; } else { - display = defaultDisplay( this.nodeName ); + var display = defaultDisplay(this.nodeName); // inline-level elements accept inline-block; // block-level elements need to be inline with layout @@ -200,37 +163,44 @@ jQuery.fn.extend({ } } } + + if ( jQuery.isArray( prop[p] ) ) { + // Create (if needed) and add to specialEasing + (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1]; + prop[p] = prop[p][0]; + } } if ( opt.overflow != null ) { this.style.overflow = "hidden"; } - for ( p in prop ) { - e = new jQuery.fx( this, opt, p ); - val = prop[ p ]; + opt.curAnim = jQuery.extend({}, prop); + + jQuery.each( prop, function( name, val ) { + var e = new jQuery.fx( self, opt, name ); if ( rfxtypes.test(val) ) { - e[ val === "toggle" ? hidden ? "show" : "hide" : val ](); + e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop ); } else { - parts = rfxnum.exec( val ); - start = e.cur(); + var parts = rfxnum.exec(val), + start = e.cur(); if ( parts ) { - end = parseFloat( parts[2] ); - unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" ); + var end = parseFloat( parts[2] ), + unit = parts[3] || ( jQuery.cssNumber[ name ] ? "" : "px" ); // We need to compute starting value if ( unit !== "px" ) { - jQuery.style( this, p, (end || 1) + unit); + jQuery.style( self, name, (end || 1) + unit); start = ((end || 1) / e.cur()) * start; - jQuery.style( this, p, start + unit); + jQuery.style( self, name, start + unit); } // If a +=/-= token was provided, we're doing a relative animation if ( parts[1] ) { - end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start; + end = ((parts[1] === "-=" ? -1 : 1) * end) + start; } e.custom( start, end, unit ); @@ -239,7 +209,7 @@ jQuery.fn.extend({ e.custom( start, val, "" ); } } - } + }); // For JS strict compliance return true; @@ -247,18 +217,15 @@ jQuery.fn.extend({ }, stop: function( clearQueue, gotoEnd ) { + var timers = jQuery.timers; + if ( clearQueue ) { this.queue([]); } this.each(function() { - var timers = jQuery.timers, - i = timers.length; - // clear marker counters if we know they won't be - if ( !gotoEnd ) { - jQuery._unmark( true, this ); - } - while ( i-- ) { + // go in reverse order so anything added to the queue during the loop is ignored + for ( var i = timers.length - 1; i >= 0; i-- ) { if ( timers[i].elem === this ) { if (gotoEnd) { // force the next step to be the last @@ -280,17 +247,6 @@ jQuery.fn.extend({ }); -// Animations created synchronously will run synchronously -function createFxNow() { - setTimeout( clearFxNow, 0 ); - return ( fxNow = jQuery.now() ); -} - -function clearFxNow() { - fxNow = undefined; -} - -// Generate parameters to create a standard animation function genFx( type, num ) { var obj = {}; @@ -329,16 +285,13 @@ jQuery.extend({ // Queueing opt.old = opt.complete; - opt.complete = function( noUnmark ) { + opt.complete = function() { + if ( opt.queue !== false ) { + jQuery(this).dequeue(); + } if ( jQuery.isFunction( opt.old ) ) { opt.old.call( this ); } - - if ( opt.queue !== false ) { - jQuery.dequeue( this ); - } else if ( noUnmark !== false ) { - jQuery._unmark( this ); - } }; return opt; @@ -360,7 +313,9 @@ jQuery.extend({ this.elem = elem; this.prop = prop; - options.orig = options.orig || {}; + if ( !options.orig ) { + options.orig = {}; + } } }); @@ -392,10 +347,9 @@ jQuery.fx.prototype = { // Start an animation from one number to another custom: function( from, to, unit ) { var self = this, - fx = jQuery.fx, - raf; + fx = jQuery.fx; - this.startTime = fxNow || createFxNow(); + this.startTime = jQuery.now(); this.start = from; this.end = to; this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" ); @@ -409,20 +363,7 @@ jQuery.fx.prototype = { t.elem = this.elem; if ( t() && jQuery.timers.push(t) && !timerId ) { - // Use requestAnimationFrame instead of setInterval if available - if ( requestAnimationFrame ) { - timerId = true; - raf = function() { - // When timerId gets set to null at any point, this stops - if ( timerId ) { - requestAnimationFrame( raf ); - fx.tick(); - } - }; - requestAnimationFrame( raf ); - } else { - timerId = setInterval( fx.tick, fx.interval ); - } + timerId = setInterval(fx.tick, fx.interval); } }, @@ -453,64 +394,60 @@ jQuery.fx.prototype = { // Each step of an animation step: function( gotoEnd ) { - var t = fxNow || createFxNow(), - done = true, - elem = this.elem, - options = this.options, - i, n; + var t = jQuery.now(), done = true; - if ( gotoEnd || t >= options.duration + this.startTime ) { + if ( gotoEnd || t >= this.options.duration + this.startTime ) { this.now = this.end; this.pos = this.state = 1; this.update(); - options.animatedProperties[ this.prop ] = true; + this.options.curAnim[ this.prop ] = true; - for ( i in options.animatedProperties ) { - if ( options.animatedProperties[i] !== true ) { + for ( var i in this.options.curAnim ) { + if ( this.options.curAnim[i] !== true ) { done = false; } } if ( done ) { // Reset the overflow - if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) { + if ( this.options.overflow != null && !jQuery.support.shrinkWrapBlocks ) { + var elem = this.elem, + options = this.options; jQuery.each( [ "", "X", "Y" ], function (index, value) { elem.style[ "overflow" + value ] = options.overflow[index]; - }); + } ); } // Hide the element if the "hide" operation was done - if ( options.hide ) { - jQuery(elem).hide(); + if ( this.options.hide ) { + jQuery(this.elem).hide(); } // Reset the properties, if the item has been hidden or shown - if ( options.hide || options.show ) { - for ( var p in options.animatedProperties ) { - jQuery.style( elem, p, options.orig[p] ); + if ( this.options.hide || this.options.show ) { + for ( var p in this.options.curAnim ) { + jQuery.style( this.elem, p, this.options.orig[p] ); } } // Execute the complete function - options.complete.call( elem ); + this.options.complete.call( this.elem ); } return false; } else { - // classical easing cannot be used with an Infinity duration - if ( options.duration == Infinity ) { - this.now = t; - } else { - n = t - this.startTime; - this.state = n / options.duration; + var n = t - this.startTime; + this.state = n / this.options.duration; + + // Perform the easing function, defaults to swing + var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop]; + var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear"); + this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration); + this.now = this.start + ((this.end - this.start) * this.pos); - // Perform the easing function, defaults to swing - this.pos = jQuery.easing[ options.animatedProperties[ this.prop ] ]( this.state, n, 0, 1, options.duration ); - this.now = this.start + ((this.end - this.start) * this.pos); - } // Perform the next step of the animation this.update(); } @@ -521,7 +458,9 @@ jQuery.fx.prototype = { jQuery.extend( jQuery.fx, { tick: function() { - for ( var timers = jQuery.timers, i = 0 ; i < timers.length ; ++i ) { + var timers = jQuery.timers; + + for ( var i = 0; i < timers.length; i++ ) { if ( !timers[i]() ) { timers.splice(i--, 1); } @@ -569,47 +508,17 @@ if ( jQuery.expr && jQuery.expr.filters ) { }; } -// Try to restore the default display value of an element function defaultDisplay( nodeName ) { - if ( !elemdisplay[ nodeName ] ) { - - var body = document.body, - elem = jQuery( "<" + nodeName + ">" ).appendTo( body ), - display = elem.css( "display" ); + var elem = jQuery("<" + nodeName + ">").appendTo("body"), + display = elem.css("display"); elem.remove(); - // If the simple way fails, - // get element's real default display by attaching it to a temp iframe if ( display === "none" || display === "" ) { - // No iframe to use yet, so create it - if ( !iframe ) { - iframe = document.createElement( "iframe" ); - iframe.frameBorder = iframe.width = iframe.height = 0; - } - - body.appendChild( iframe ); - - // Create a cacheable copy of the iframe document on first call. - // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML - // document to it; WebKit & Firefox won't allow reusing the iframe document. - if ( !iframeDoc || !iframe.createElement ) { - iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; - iframeDoc.write( ( document.compatMode === "CSS1Compat" ? "" : "" ) + "" ); - iframeDoc.close(); - } - - elem = iframeDoc.createElement( nodeName ); - - iframeDoc.body.appendChild( elem ); - - display = jQuery.css( elem, "display" ); - - body.removeChild( iframe ); + display = "block"; } - // Store the correct default display elemdisplay[ nodeName ] = display; } diff --git a/src/event.js b/src/event.js index 131739b1..f7e0a08c 100644 --- a/src/event.js +++ b/src/event.js @@ -3,7 +3,7 @@ var rnamespaces = /\.(.*)$/, rformElems = /^(?:textarea|input|select)$/i, rperiod = /\./g, - rspaces = / /g, + rspace = / /g, rescape = /[^\w\s.|`]/g, fcleanup = function( nm ) { return nm.replace(rescape, "\\$&"); @@ -23,6 +23,17 @@ jQuery.event = { return; } + // TODO :: Use a try/catch until it's safe to pull this out (likely 1.6) + // Minor release fix for bug #8018 + try { + // For whatever reason, IE has trouble passing the window object + // around, causing it to be cloned in the process + if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) { + elem = window; + } + } + catch ( e ) {} + if ( handler === false ) { handler = returnFalse; } else if ( !handler ) { @@ -59,10 +70,10 @@ jQuery.event = { } if ( !eventHandle ) { - elemData.handle = eventHandle = function( e ) { - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? + elemData.handle = eventHandle = function() { + // Handle the second event of a trigger and when + // an event is called after a page has unloaded + return typeof jQuery !== "undefined" && !jQuery.event.triggered ? jQuery.event.handle.apply( eventHandle.elem, arguments ) : undefined; }; @@ -132,7 +143,7 @@ jQuery.event = { // Add the function to the element's handler list handlers.push( handleObj ); - // Keep track of which events have been used, for event optimization + // Keep track of which events have been used, for global triggering jQuery.event.global[ type ] = true; } @@ -265,185 +276,182 @@ jQuery.event = { } } }, - - // Events that are safe to short-circuit if no handlers are attached. - // Native DOM events should not be added, they may have inline handlers. - customEvent: { - "getData": true, - "setData": true, - "changeData": true - }, - trigger: function( event, data, elem, onlyHandlers ) { + // bubbling is internal + trigger: function( event, data, elem /*, bubbling */ ) { // Event object or event type var type = event.type || event, - namespaces = [], - exclusive; + bubbling = arguments[3]; - if ( type.indexOf("!") >= 0 ) { - // Exclusive events trigger only for the exact event (no namespaces) - type = type.slice(0, -1); - exclusive = true; - } + if ( !bubbling ) { + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + jQuery.extend( jQuery.Event(type), event ) : + // Just the event type (string) + jQuery.Event(type); - if ( type.indexOf(".") >= 0 ) { - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split("."); - type = namespaces.shift(); - namespaces.sort(); - } + if ( type.indexOf("!") >= 0 ) { + event.type = type = type.slice(0, -1); + event.exclusive = true; + } - if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { - // No jQuery handlers for this event type, and it can't have inline handlers - return; - } + // Handle a global trigger + if ( !elem ) { + // Don't bubble custom events when global (to avoid too much overhead) + event.stopPropagation(); - // Caller can pass in an Event, Object, or just an event type string - event = typeof event === "object" ? - // jQuery.Event object - event[ jQuery.expando ] ? event : - // Object literal - new jQuery.Event( type, event ) : - // Just the event type (string) - new jQuery.Event( type ); - - event.type = type; - event.exclusive = exclusive; - event.namespace = namespaces.join("."); - event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)"); - - // triggerHandler() and global events don't bubble or run the default action - if ( onlyHandlers || !elem ) { - event.preventDefault(); - event.stopPropagation(); - } - - // Handle a global trigger - if ( !elem ) { - // TODO: Stop taunting the data cache; remove global events and always attach to document - jQuery.each( jQuery.cache, function() { - // internalKey variable is just used to make it easier to find - // and potentially change this stuff later; currently it just - // points to jQuery.expando - var internalKey = jQuery.expando, - internalCache = this[ internalKey ]; - if ( internalCache && internalCache.events && internalCache.events[ type ] ) { - jQuery.event.trigger( event, data, internalCache.handle.elem ); + // Only trigger if we've ever bound an event for it + if ( jQuery.event.global[ type ] ) { + // XXX This code smells terrible. event.js should not be directly + // inspecting the data cache + jQuery.each( jQuery.cache, function() { + // internalKey variable is just used to make it easier to find + // and potentially change this stuff later; currently it just + // points to jQuery.expando + var internalKey = jQuery.expando, + internalCache = this[ internalKey ]; + if ( internalCache && internalCache.events && internalCache.events[ type ] ) { + jQuery.event.trigger( event, data, internalCache.handle.elem ); + } + }); } - }); - return; - } - - // Don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - // Clean up the event in case it is being reused - event.result = undefined; - event.target = elem; - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data != null ? jQuery.makeArray( data ) : []; - data.unshift( event ); - - var cur = elem, - // IE doesn't like method names with a colon (#3533, #8272) - ontype = type.indexOf(":") < 0 ? "on" + type : ""; - - // Fire event on the current element, then bubble up the DOM tree - do { - var handle = jQuery._data( cur, "handle" ); - - event.currentTarget = cur; - if ( handle ) { - handle.apply( cur, data ); } - // Trigger an inline bound script - if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) { - event.result = false; - event.preventDefault(); + // Handle triggering a single element + + // don't do events on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { + return undefined; } - // Bubble up to document, then to window - cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window; - } while ( cur && !event.isPropagationStopped() ); + // Clean up in case it is reused + event.result = undefined; + event.target = elem; - // If nobody prevented the default action, do it now - if ( !event.isDefaultPrevented() ) { + // Clone the incoming data, if any + data = jQuery.makeArray( data ); + data.unshift( event ); + } + + event.currentTarget = elem; + + // Trigger the event, it is assumed that "handle" is a function + var handle = jQuery._data( elem, "handle" ); + + if ( handle ) { + handle.apply( elem, data ); + } + + var parent = elem.parentNode || elem.ownerDocument; + + // Trigger an inline bound script + try { + if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) { + if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) { + event.result = false; + event.preventDefault(); + } + } + + // prevent IE from throwing an error for some elements with some event types, see #3533 + } catch (inlineError) {} + + if ( !event.isPropagationStopped() && parent ) { + jQuery.event.trigger( event, data, parent, true ); + + } else if ( !event.isDefaultPrevented() ) { var old, - special = jQuery.event.special[ type ] || {}; + target = event.target, + targetType = type.replace( rnamespaces, "" ), + isClick = jQuery.nodeName( target, "a" ) && targetType === "click", + special = jQuery.event.special[ targetType ] || {}; - if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) && - !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + if ( (!special._default || special._default.call( elem, event ) === false) && + !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) { - // Call a native DOM method on the target with the same name name as the event. - // Can't use an .isFunction)() check here because IE6/7 fails that test. - // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch. try { - if ( ontype && elem[ type ] ) { - // Don't re-trigger an onFOO event when we call its FOO() method - old = elem[ ontype ]; + if ( target[ targetType ] ) { + // Make sure that we don't accidentally re-trigger the onFOO events + old = target[ "on" + targetType ]; if ( old ) { - elem[ ontype ] = null; + target[ "on" + targetType ] = null; } - jQuery.event.triggered = type; - elem[ type ](); + jQuery.event.triggered = true; + target[ targetType ](); } - } catch ( ieError ) {} + + // prevent IE from throwing an error for some elements with some event types, see #3533 + } catch (triggerError) {} if ( old ) { - elem[ ontype ] = old; + target[ "on" + targetType ] = old; } - jQuery.event.triggered = undefined; + jQuery.event.triggered = false; } } - - return event.result; }, handle: function( event ) { - event = jQuery.event.fix( event || window.event ); - // Snapshot the handlers list since a called handler may add/remove events. - var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0), - run_all = !event.exclusive && !event.namespace, - args = Array.prototype.slice.call( arguments, 0 ); + var all, handlers, namespaces, namespace_re, events, + namespace_sort = [], + args = jQuery.makeArray( arguments ); - // Use the fix-ed Event rather than the (read-only) native event - args[0] = event; + event = args[0] = jQuery.event.fix( event || window.event ); event.currentTarget = this; - for ( var j = 0, l = handlers.length; j < l; j++ ) { - var handleObj = handlers[ j ]; + // Namespaced event handlers + all = event.type.indexOf(".") < 0 && !event.exclusive; - // Triggered event must 1) be non-exclusive and have no namespace, or - // 2) have namespace(s) a subset or equal to those in the bound event. - if ( run_all || event.namespace_re.test( handleObj.namespace ) ) { - // Pass in a reference to the handler function itself - // So that we can later remove it - event.handler = handleObj.handler; - event.data = handleObj.data; - event.handleObj = handleObj; + if ( !all ) { + namespaces = event.type.split("."); + event.type = namespaces.shift(); + namespace_sort = namespaces.slice(0).sort(); + namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)"); + } - var ret = handleObj.handler.apply( this, args ); + event.namespace = event.namespace || namespace_sort.join("."); - if ( ret !== undefined ) { - event.result = ret; - if ( ret === false ) { - event.preventDefault(); - event.stopPropagation(); + events = jQuery._data(this, "events"); + + handlers = (events || {})[ event.type ]; + + if ( events && handlers ) { + // Clone the handlers to prevent manipulation + handlers = handlers.slice(0); + + for ( var j = 0, l = handlers.length; j < l; j++ ) { + var handleObj = handlers[ j ]; + + // Filter the functions by class + if ( all || namespace_re.test( handleObj.namespace ) ) { + // Pass in a reference to the handler function itself + // So that we can later remove it + event.handler = handleObj.handler; + event.data = handleObj.data; + event.handleObj = handleObj; + + var ret = handleObj.handler.apply( this, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } } - } - if ( event.isImmediatePropagationStopped() ) { - break; + if ( event.isImmediatePropagationStopped() ) { + break; + } } } } + return event.result; }, @@ -482,9 +490,8 @@ jQuery.event = { // Calculate pageX/Y if missing and clientX/Y available if ( event.pageX == null && event.clientX != null ) { - var eventDocument = event.target.ownerDocument || document, - doc = eventDocument.documentElement, - body = eventDocument.body; + var doc = document.documentElement, + body = document.body; event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); @@ -563,10 +570,10 @@ jQuery.removeEvent = document.removeEventListener ? } }; -jQuery.Event = function( src, props ) { +jQuery.Event = function( src ) { // Allow instantiation without the 'new' keyword if ( !this.preventDefault ) { - return new jQuery.Event( src, props ); + return new jQuery.Event( src ); } // Event object @@ -584,11 +591,6 @@ jQuery.Event = function( src, props ) { this.type = src; } - // Put explicitly provided properties onto the event object - if ( props ) { - jQuery.extend( this, props ); - } - // timeStamp is buggy for some events on Firefox(#3843) // So we won't rely on the native value this.timeStamp = jQuery.now(); @@ -650,27 +652,33 @@ jQuery.Event.prototype = { // Checks if an event happened on an element within another element // Used in jQuery.event.special.mouseenter and mouseleave handlers var withinElement = function( event ) { - // Check if mouse(over|out) are still within the same parent element - var related = event.relatedTarget, - inside = false, - eventType = event.type; + var parent = event.relatedTarget; - event.type = event.data; + // Firefox sometimes assigns relatedTarget a XUL element + // which we cannot access the parentNode property of + try { - if ( related !== this ) { - - if ( related ) { - inside = jQuery.contains( this, related ); + // Chrome does something similar, the parentNode property + // can be accessed but is null. + if ( parent !== document && !parent.parentNode ) { + return; + } + // Traverse up the tree + while ( parent && parent !== this ) { + parent = parent.parentNode; } - if ( !inside ) { + if ( parent !== this ) { + // set the correct event type + event.type = event.data; + // handle event if we actually just moused on to a non sub-element jQuery.event.handle.apply( this, arguments ); - - event.type = eventType; } - } + + // assuming we've left the element since we most likely mousedover a xul element + } catch(e) { } }, // In case of event delegation, we only need to rename the event.type, @@ -700,7 +708,7 @@ if ( !jQuery.support.submitBubbles ) { jQuery.event.special.submit = { setup: function( data, namespaces ) { - if ( !jQuery.nodeName( this, "form" ) ) { + if ( this.nodeName && this.nodeName.toLowerCase() !== "form" ) { jQuery.event.add(this, "click.specialSubmit", function( e ) { var elem = e.target, type = elem.type; @@ -749,7 +757,7 @@ if ( !jQuery.support.changeBubbles ) { }).join("-") : ""; - } else if ( jQuery.nodeName( elem, "select" ) ) { + } else if ( elem.nodeName.toLowerCase() === "select" ) { val = elem.selectedIndex; } @@ -789,9 +797,9 @@ if ( !jQuery.support.changeBubbles ) { beforedeactivate: testChange, click: function( e ) { - var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : ""; + var elem = e.target, type = elem.type; - if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) { + if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) { testChange.call( this, e ); } }, @@ -799,9 +807,9 @@ if ( !jQuery.support.changeBubbles ) { // Change has to be called before submit // Keydown will be called before keypress, which is used in submit-event delegation keydown: function( e ) { - var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : ""; + var elem = e.target, type = elem.type; - if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) || + if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") || (e.keyCode === 32 && (type === "checkbox" || type === "radio")) || type === "select-multiple" ) { testChange.call( this, e ); @@ -858,43 +866,27 @@ function trigger( type, elem, args ) { } // Create "bubbling" focus and blur events -if ( !jQuery.support.focusinBubbles ) { +if ( document.addEventListener ) { jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { - - // Attach a single capturing handler while someone wants focusin/focusout - var attaches = 0; - jQuery.event.special[ fix ] = { setup: function() { - if ( attaches++ === 0 ) { - document.addEventListener( orig, handler, true ); - } + this.addEventListener( orig, handler, true ); }, teardown: function() { - if ( --attaches === 0 ) { - document.removeEventListener( orig, handler, true ); - } + this.removeEventListener( orig, handler, true ); } }; - function handler( donor ) { - // Donor event is always a native one; fix it and switch its type. - // Let focusin/out handler cancel the donor focus/blur event. - var e = jQuery.event.fix( donor ); + function handler( e ) { + e = jQuery.event.fix( e ); e.type = fix; - e.originalEvent = {}; - jQuery.event.trigger( e, null, e.target ); - if ( e.isDefaultPrevented() ) { - donor.preventDefault(); - } + return jQuery.event.handle.call( this, e ); } }); } jQuery.each(["bind", "one"], function( i, name ) { jQuery.fn[ name ] = function( type, data, fn ) { - var handler; - // Handle object literals if ( typeof type === "object" ) { for ( var key in type ) { @@ -903,20 +895,15 @@ jQuery.each(["bind", "one"], function( i, name ) { return this; } - if ( arguments.length === 2 || data === false ) { + if ( jQuery.isFunction( data ) || data === false ) { fn = data; data = undefined; } - if ( name === "one" ) { - handler = function( event ) { - jQuery( this ).unbind( event, handler ); - return fn.apply( this, arguments ); - }; - handler.guid = fn.guid || jQuery.guid++; - } else { - handler = fn; - } + var handler = name === "one" ? jQuery.proxy( fn, function( event ) { + jQuery( this ).unbind( event, handler ); + return fn.apply( this, arguments ); + }) : fn; if ( type === "unload" && name !== "one" ) { this.one( type, data, fn ); @@ -954,7 +941,7 @@ jQuery.fn.extend({ undelegate: function( selector, types, fn ) { if ( arguments.length === 0 ) { - return this.unbind( "live" ); + return this.unbind( "live" ); } else { return this.die( types, null, fn, selector ); @@ -969,34 +956,35 @@ jQuery.fn.extend({ triggerHandler: function( type, data ) { if ( this[0] ) { - return jQuery.event.trigger( type, data, this[0], true ); + var event = jQuery.Event( type ); + event.preventDefault(); + event.stopPropagation(); + jQuery.event.trigger( event, data, this[0] ); + return event.result; } }, toggle: function( fn ) { // Save reference to arguments for access in closure var args = arguments, - guid = fn.guid || jQuery.guid++, - i = 0, - toggler = function( event ) { - // Figure out which function to execute - var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i; - jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 ); - - // Make sure that clicks stop - event.preventDefault(); - - // and execute the function - return args[ lastToggle ].apply( this, arguments ) || false; - }; + i = 1; // link all the functions, so any of them can unbind this click handler - toggler.guid = guid; while ( i < args.length ) { - args[ i++ ].guid = guid; + jQuery.proxy( fn, args[ i++ ] ); } - return this.click( toggler ); + return this.click( jQuery.proxy( fn, function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + })); }, hover: function( fnOver, fnOut ) { @@ -1025,16 +1013,8 @@ jQuery.each(["live", "die"], function( i, name ) { return this; } - if ( name === "die" && !types && - origSelector && origSelector.charAt(0) === "." ) { - - context.unbind( origSelector ); - - return this; - } - - if ( data === false || jQuery.isFunction( data ) ) { - fn = data || returnFalse; + if ( jQuery.isFunction( data ) ) { + fn = data; data = undefined; } @@ -1056,7 +1036,7 @@ jQuery.each(["live", "die"], function( i, name ) { preType = type; - if ( liveMap[ type ] ) { + if ( type === "focus" || type === "blur" ) { types.push( liveMap[ type ] + namespaces ); type = type + namespaces; @@ -1127,11 +1107,6 @@ function liveHandler( event ) { if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) { event.type = handleObj.preType; related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0]; - - // Make sure not to accidentally match a child element with the same selector - if ( related && jQuery.contains( elem, related ) ) { - related = elem; - } } if ( !related || related !== elem ) { @@ -1170,7 +1145,7 @@ function liveHandler( event ) { } function liveConvert( type, selector ) { - return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&"); + return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspace, "&"); } jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + @@ -1195,4 +1170,3 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl }); })( jQuery ); - diff --git a/src/intro.js b/src/intro.js index a81c86f9..c0a5643f 100644 --- a/src/intro.js +++ b/src/intro.js @@ -16,6 +16,4 @@ (function( window, undefined ) { // Use the correct document accordingly with window argument (sandbox) -var document = window.document, - navigator = window.navigator, - location = window.location; +var document = window.document; diff --git a/src/manipulation.js b/src/manipulation.js index 439b9596..ba316971 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -9,8 +9,6 @@ var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, rnocache = /<(?:script|object|embed|option|style)/i, // checked="checked" or checked rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, - rscriptType = /\/(java|ecma)script/i, - rcleanScript = /^\s*", "" ], legend: [ 1, "
", "
" ], @@ -71,7 +69,7 @@ jQuery.fn.extend({ } return elem; - }).append( this ); + }).append(this); } return this; @@ -263,9 +261,7 @@ jQuery.fn.extend({ } }); } else { - return this.length ? - this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) : - this; + return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ); } }, @@ -379,27 +375,21 @@ function cloneCopyEvent( src, dest ) { } } -function cloneFixAttributes( src, dest ) { - var nodeName; - +function cloneFixAttributes(src, dest) { // We do not need to do anything for non-Elements if ( dest.nodeType !== 1 ) { return; } + var nodeName = dest.nodeName.toLowerCase(); + // clearAttributes removes the attributes, which we don't want, // but also removes the attachEvent events, which we *do* want - if ( dest.clearAttributes ) { - dest.clearAttributes(); - } + dest.clearAttributes(); // mergeAttributes, in contrast, only merges back on the // original attributes, not the events - if ( dest.mergeAttributes ) { - dest.mergeAttributes( src ); - } - - nodeName = dest.nodeName.toLowerCase(); + dest.mergeAttributes(src); // IE6-8 fail to clone children inside object elements that use // the proprietary classid attribute value (rather than the type @@ -438,21 +428,8 @@ function cloneFixAttributes( src, dest ) { } jQuery.buildFragment = function( args, nodes, scripts ) { - var fragment, cacheable, cacheresults, doc; - - // nodes may contain either an explicit document object, - // a jQuery collection or context object. - // If nodes[0] contains a valid object to assign to doc - if ( nodes && nodes[0] ) { - doc = nodes[0].ownerDocument || nodes[0]; - } - - // Ensure that an attr object doesn't incorrectly stand in as a document object - // Chrome and Firefox seem to allow this to occur and will throw exception - // Fixes #8950 - if ( !doc.createDocumentFragment ) { - doc = document; - } + var fragment, cacheable, cacheresults, + doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document); // Only cache "small" (1/2 KB) HTML strings that are associated with the main document // Cloning options loses the selected state, so don't cache them @@ -462,10 +439,11 @@ jQuery.buildFragment = function( args, nodes, scripts ) { args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) { cacheable = true; - cacheresults = jQuery.fragments[ args[0] ]; - if ( cacheresults && cacheresults !== 1 ) { - fragment = cacheresults; + if ( cacheresults ) { + if ( cacheresults !== 1 ) { + fragment = cacheresults; + } } } @@ -514,7 +492,7 @@ jQuery.each({ function getAll( elem ) { if ( "getElementsByTagName" in elem ) { return elem.getElementsByTagName( "*" ); - + } else if ( "querySelectorAll" in elem ) { return elem.querySelectorAll( "*" ); @@ -523,21 +501,6 @@ function getAll( elem ) { } } -// Used in clean, fixes the defaultChecked property -function fixDefaultChecked( elem ) { - if ( elem.type === "checkbox" || elem.type === "radio" ) { - elem.defaultChecked = elem.checked; - } -} -// Finds all inputs and passes them to fixDefaultChecked -function findInputs( elem ) { - if ( jQuery.nodeName( elem, "input" ) ) { - fixDefaultChecked( elem ); - } else if ( "getElementsByTagName" in elem ) { - jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked ); - } -} - jQuery.extend({ clone: function( elem, dataAndEvents, deepDataAndEvents ) { var clone = elem.cloneNode(true), @@ -582,15 +545,10 @@ jQuery.extend({ } } - srcElements = destElements = null; - // Return the cloned set return clone; - }, - +}, clean: function( elems, context, fragment, scripts ) { - var checkScriptType; - context = context || document; // !context.createElement fails in IE with an error but returns typeof 'object' @@ -598,7 +556,7 @@ jQuery.extend({ context = context.ownerDocument || context[0] && context[0].ownerDocument || document; } - var ret = [], j; + var ret = []; for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { if ( typeof elem === "number" ) { @@ -610,67 +568,54 @@ jQuery.extend({ } // Convert html string into DOM nodes - if ( typeof elem === "string" ) { - if ( !rhtml.test( elem ) ) { - elem = context.createTextNode( elem ); - } else { - // Fix "XHTML"-style tags in all browsers - elem = elem.replace(rxhtmlTag, "<$1>"); + if ( typeof elem === "string" && !rhtml.test( elem ) ) { + elem = context.createTextNode( elem ); - // Trim whitespace, otherwise indexOf won't work as expected - var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(), - wrap = wrapMap[ tag ] || wrapMap._default, - depth = wrap[0], - div = context.createElement("div"); + } else if ( typeof elem === "string" ) { + // Fix "XHTML"-style tags in all browsers + elem = elem.replace(rxhtmlTag, "<$1>"); - // Go to html and back, then peel off extra wrappers - div.innerHTML = wrap[1] + elem + wrap[2]; + // Trim whitespace, otherwise indexOf won't work as expected + var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(), + wrap = wrapMap[ tag ] || wrapMap._default, + depth = wrap[0], + div = context.createElement("div"); - // Move to the right depth - while ( depth-- ) { - div = div.lastChild; - } + // Go to html and back, then peel off extra wrappers + div.innerHTML = wrap[1] + elem + wrap[2]; - // Remove IE's autoinserted from table fragments - if ( !jQuery.support.tbody ) { + // Move to the right depth + while ( depth-- ) { + div = div.lastChild; + } - // String was a , *may* have spurious - var hasBody = rtbody.test(elem), - tbody = tag === "table" && !hasBody ? - div.firstChild && div.firstChild.childNodes : + // Remove IE's autoinserted from table fragments + if ( !jQuery.support.tbody ) { - // String was a bare or - wrap[1] === "
" && !hasBody ? - div.childNodes : - []; + // String was a
, *may* have spurious + var hasBody = rtbody.test(elem), + tbody = tag === "table" && !hasBody ? + div.firstChild && div.firstChild.childNodes : - for ( j = tbody.length - 1; j >= 0 ; --j ) { - if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { - tbody[ j ].parentNode.removeChild( tbody[ j ] ); - } + // String was a bare or + wrap[1] === "
" && !hasBody ? + div.childNodes : + []; + + for ( var j = tbody.length - 1; j >= 0 ; --j ) { + if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { + tbody[ j ].parentNode.removeChild( tbody[ j ] ); } } - // IE completely kills leading whitespace when innerHTML is used - if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { - div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); - } - - elem = div.childNodes; } - } - // Resets defaultChecked for any radios and checkboxes - // about to be appended to the DOM in IE 6/7 (#8060) - var len; - if ( !jQuery.support.appendChecked ) { - if ( elem[0] && typeof (len = elem.length) === "number" ) { - for ( j = 0; j < len; j++ ) { - findInputs( elem[j] ); - } - } else { - findInputs( elem ); + // IE completely kills leading whitespace when innerHTML is used + if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); } + + elem = div.childNodes; } if ( elem.nodeType ) { @@ -681,18 +626,13 @@ jQuery.extend({ } if ( fragment ) { - checkScriptType = function( elem ) { - return !elem.type || rscriptType.test( elem.type ); - }; for ( i = 0; ret[i]; i++ ) { if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) { scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] ); } else { if ( ret[i].nodeType === 1 ) { - var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType ); - - ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) ); + ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) ); } fragment.appendChild( ret[i] ); } @@ -754,7 +694,7 @@ function evalScript( i, elem ) { dataType: "script" }); } else { - jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) ); + jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); } if ( elem.parentNode ) { @@ -762,4 +702,4 @@ function evalScript( i, elem ) { } } -})( jQuery ); \ No newline at end of file +})( jQuery ); diff --git a/src/offset.js b/src/offset.js index 31f2503a..1003c400 100644 --- a/src/offset.js +++ b/src/offset.js @@ -37,8 +37,8 @@ if ( "getBoundingClientRect" in document.documentElement ) { win = getWindow(doc), clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0, - scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop, - scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft, + scrollTop = (win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ), + scrollLeft = (win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft), top = box.top + scrollTop - clientTop, left = box.left + scrollLeft - clientLeft; @@ -151,6 +151,7 @@ jQuery.offset = { this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop); body.removeChild( container ); + body = container = innerDiv = checkDiv = table = td = null; jQuery.offset.initialize = jQuery.noop; }, @@ -180,19 +181,17 @@ jQuery.offset = { curOffset = curElem.offset(), curCSSTop = jQuery.css( elem, "top" ), curCSSLeft = jQuery.css( elem, "left" ), - calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1, + calculatePosition = (position === "absolute" && jQuery.inArray('auto', [curCSSTop, curCSSLeft]) > -1), props = {}, curPosition = {}, curTop, curLeft; - // need to be able to calculate position if either top or left is auto and position is either absolute or fixed + // need to be able to calculate position if either top or left is auto and position is absolute if ( calculatePosition ) { curPosition = curElem.position(); - curTop = curPosition.top; - curLeft = curPosition.left; - } else { - curTop = parseFloat( curCSSTop ) || 0; - curLeft = parseFloat( curCSSLeft ) || 0; } + curTop = calculatePosition ? curPosition.top : parseInt( curCSSTop, 10 ) || 0; + curLeft = calculatePosition ? curPosition.left : parseInt( curCSSLeft, 10 ) || 0; + if ( jQuery.isFunction( options ) ) { options = options.call( elem, i, curOffset ); } @@ -261,16 +260,29 @@ jQuery.fn.extend({ jQuery.each( ["Left", "Top"], function( i, name ) { var method = "scroll" + name; - jQuery.fn[ method ] = function( val ) { - var elem, win; + jQuery.fn[ method ] = function(val) { + var elem = this[0], win; - if ( val === undefined ) { - elem = this[ 0 ]; + if ( !elem ) { + return null; + } - if ( !elem ) { - return null; - } + if ( val !== undefined ) { + // Set the scroll offset + return this.each(function() { + win = getWindow( this ); + if ( win ) { + win.scrollTo( + !i ? val : jQuery(win).scrollLeft(), + i ? val : jQuery(win).scrollTop() + ); + + } else { + this[ method ] = val; + } + }); + } else { win = getWindow( elem ); // Return the scroll offset @@ -279,21 +291,6 @@ jQuery.each( ["Left", "Top"], function( i, name ) { win.document.body[ method ] : elem[ method ]; } - - // Set the scroll offset - return this.each(function() { - win = getWindow( this ); - - if ( win ) { - win.scrollTo( - !i ? val : jQuery( win ).scrollLeft(), - i ? val : jQuery( win ).scrollTop() - ); - - } else { - this[ method ] = val; - } - }); }; }); diff --git a/src/outro.js b/src/outro.js index b49305e7..32b0d087 100644 --- a/src/outro.js +++ b/src/outro.js @@ -1,3 +1,2 @@ -// Expose jQuery to the global object window.jQuery = window.$ = jQuery; })(window); diff --git a/src/queue.js b/src/queue.js index 66383c19..9e3e2fb5 100644 --- a/src/queue.js +++ b/src/queue.js @@ -1,75 +1,34 @@ (function( jQuery ) { -function handleQueueMarkDefer( elem, type, src ) { - var deferDataKey = type + "defer", - queueDataKey = type + "queue", - markDataKey = type + "mark", - defer = jQuery.data( elem, deferDataKey, undefined, true ); - if ( defer && - ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) && - ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) { - // Give room for hard-coded callbacks to fire first - // and eventually mark/queue something else on the element - setTimeout( function() { - if ( !jQuery.data( elem, queueDataKey, undefined, true ) && - !jQuery.data( elem, markDataKey, undefined, true ) ) { - jQuery.removeData( elem, deferDataKey, true ); - defer.resolve(); - } - }, 0 ); - } -} - jQuery.extend({ - - _mark: function( elem, type ) { - if ( elem ) { - type = (type || "fx") + "mark"; - jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true ); - } - }, - - _unmark: function( force, elem, type ) { - if ( force !== true ) { - type = elem; - elem = force; - force = false; - } - if ( elem ) { - type = type || "fx"; - var key = type + "mark", - count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 ); - if ( count ) { - jQuery.data( elem, key, count, true ); - } else { - jQuery.removeData( elem, key, true ); - handleQueueMarkDefer( elem, type, "mark" ); - } - } - }, - queue: function( elem, type, data ) { - if ( elem ) { - type = (type || "fx") + "queue"; - var q = jQuery.data( elem, type, undefined, true ); - // Speed up dequeue by getting out quickly if this is just a lookup - if ( data ) { - if ( !q || jQuery.isArray(data) ) { - q = jQuery.data( elem, type, jQuery.makeArray(data), true ); - } else { - q.push( data ); - } - } + if ( !elem ) { + return; + } + + type = (type || "fx") + "queue"; + var q = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( !data ) { return q || []; } + + if ( !q || jQuery.isArray(data) ) { + q = jQuery._data( elem, type, jQuery.makeArray(data) ); + + } else { + q.push( data ); + } + + return q; }, dequeue: function( elem, type ) { type = type || "fx"; var queue = jQuery.queue( elem, type ), - fn = queue.shift(), - defer; + fn = queue.shift(); // If the fx queue is dequeued, always remove the progress sentinel if ( fn === "inprogress" ) { @@ -90,7 +49,6 @@ jQuery.extend({ if ( !queue.length ) { jQuery.removeData( elem, type + "queue", true ); - handleQueueMarkDefer( elem, type, "queue" ); } } }); @@ -105,7 +63,7 @@ jQuery.fn.extend({ if ( data === undefined ) { return jQuery.queue( this[0], type ); } - return this.each(function() { + return this.each(function( i ) { var queue = jQuery.queue( this, type, data ); if ( type === "fx" && queue[0] !== "inprogress" ) { @@ -118,6 +76,7 @@ jQuery.fn.extend({ jQuery.dequeue( this, type ); }); }, + // Based off of the plugin by Clint Helfers, with permission. // http://blindsignals.com/index.php/2009/07/jquery-delay/ delay: function( time, type ) { @@ -131,41 +90,9 @@ jQuery.fn.extend({ }, time ); }); }, + clearQueue: function( type ) { return this.queue( type || "fx", [] ); - }, - // Get a promise resolved when queues of a certain type - // are emptied (fx is the type by default) - promise: function( type, object ) { - if ( typeof type !== "string" ) { - object = type; - type = undefined; - } - type = type || "fx"; - var defer = jQuery.Deferred(), - elements = this, - i = elements.length, - count = 1, - deferDataKey = type + "defer", - queueDataKey = type + "queue", - markDataKey = type + "mark", - tmp; - function resolve() { - if ( !( --count ) ) { - defer.resolveWith( elements, [ elements ] ); - } - } - while( i-- ) { - if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || - ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || - jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && - jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) { - count++; - tmp.done( resolve ); - } - } - resolve(); - return defer.promise(); } }); diff --git a/src/sizzle b/src/sizzle deleted file mode 160000 index 3ba396e4..00000000 --- a/src/sizzle +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 3ba396e439a07c2a2facafbe07cdaa1b80a24c00 diff --git a/src/support.js b/src/support.js index 882b84a2..7470b33e 100644 --- a/src/support.js +++ b/src/support.js @@ -1,63 +1,44 @@ (function( jQuery ) { -jQuery.support = (function() { +(function() { - var div = document.createElement( "div" ), - documentElement = document.documentElement, - all, - a, - select, - opt, - input, - marginDiv, - support, - fragment, - body, - testElementParent, - testElement, - testElementStyle, - tds, - events, - eventName, - i, - isSupported; + jQuery.support = {}; - // Preliminary tests - div.setAttribute("className", "t"); - div.innerHTML = "
a"; + var div = document.createElement("div"); - all = div.getElementsByTagName( "*" ); - a = div.getElementsByTagName( "a" )[ 0 ]; + div.style.display = "none"; + div.innerHTML = "
a"; + + var all = div.getElementsByTagName("*"), + a = div.getElementsByTagName("a")[0], + select = document.createElement("select"), + opt = select.appendChild( document.createElement("option") ), + input = div.getElementsByTagName("input")[0]; // Can't get basic test support if ( !all || !all.length || !a ) { - return {}; + return; } - // First batch of supports tests - select = document.createElement( "select" ); - opt = select.appendChild( document.createElement("option") ); - input = div.getElementsByTagName( "input" )[ 0 ]; - - support = { + jQuery.support = { // IE strips leading whitespace when .innerHTML is used - leadingWhitespace: ( div.firstChild.nodeType === 3 ), + leadingWhitespace: div.firstChild.nodeType === 3, // Make sure that tbody elements aren't automatically inserted // IE will insert them into empty tables - tbody: !div.getElementsByTagName( "tbody" ).length, + tbody: !div.getElementsByTagName("tbody").length, // Make sure that link elements get serialized correctly by innerHTML // This requires a wrapper element in IE - htmlSerialize: !!div.getElementsByTagName( "link" ).length, + htmlSerialize: !!div.getElementsByTagName("link").length, // Get the style information from getAttribute - // (IE uses .cssText instead) - style: /top/.test( a.getAttribute("style") ), + // (IE uses .cssText insted) + style: /red/.test( a.getAttribute("style") ), // Make sure that URLs aren't manipulated // (IE normalizes it by default) - hrefNormalized: ( a.getAttribute( "href" ) === "/a" ), + hrefNormalized: a.getAttribute("href") === "/a", // Make sure that element opacity exists // (IE uses filter instead) @@ -71,186 +52,174 @@ jQuery.support = (function() { // Make sure that if no value is specified for a checkbox // that it defaults to "on". // (WebKit defaults to "" instead) - checkOn: ( input.value === "on" ), + checkOn: input.value === "on", // Make sure that a selected-by-default option has a working selected property. // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) optSelected: opt.selected, - // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) - getSetAttribute: div.className !== "t", - // Will be defined later - submitBubbles: true, - changeBubbles: true, - focusinBubbles: false, deleteExpando: true, + optDisabled: false, + checkClone: false, noCloneEvent: true, + noCloneChecked: true, + boxModel: null, inlineBlockNeedsLayout: false, shrinkWrapBlocks: false, - reliableMarginRight: true + reliableHiddenOffsets: true }; - // Make sure checked status is properly cloned input.checked = true; - support.noCloneChecked = input.cloneNode( true ).checked; + jQuery.support.noCloneChecked = input.cloneNode( true ).checked; // Make sure that the options inside disabled selects aren't marked as disabled - // (WebKit marks them as disabled) + // (WebKit marks them as diabled) select.disabled = true; - support.optDisabled = !opt.disabled; + jQuery.support.optDisabled = !opt.disabled; + + var _scriptEval = null; + jQuery.support.scriptEval = function() { + if ( _scriptEval === null ) { + var root = document.documentElement, + script = document.createElement("script"), + id = "script" + jQuery.now(); + + try { + script.appendChild( document.createTextNode( "window." + id + "=1;" ) ); + } catch(e) {} + + root.insertBefore( script, root.firstChild ); + + // Make sure that the execution of code works by injecting a script + // tag with appendChild/createTextNode + // (IE doesn't support this, fails, and uses .text instead) + if ( window[ id ] ) { + _scriptEval = true; + delete window[ id ]; + } else { + _scriptEval = false; + } + + root.removeChild( script ); + // release memory in IE + root = script = id = null; + } + + return _scriptEval; + }; // Test to see if it's possible to delete an expando from an element // Fails in Internet Explorer try { delete div.test; - } catch( e ) { - support.deleteExpando = false; + + } catch(e) { + jQuery.support.deleteExpando = false; } if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { - div.attachEvent( "onclick", function() { + div.attachEvent("onclick", function click() { // Cloning a node shouldn't copy over any // bound event handlers (IE does this) - support.noCloneEvent = false; + jQuery.support.noCloneEvent = false; + div.detachEvent("onclick", click); }); - div.cloneNode( true ).fireEvent( "onclick" ); + div.cloneNode(true).fireEvent("onclick"); } - // Check if a radio maintains it's value - // after being appended to the DOM - input = document.createElement("input"); - input.value = "t"; - input.setAttribute("type", "radio"); - support.radioValue = input.value === "t"; + div = document.createElement("div"); + div.innerHTML = ""; - input.setAttribute("checked", "checked"); - div.appendChild( input ); - fragment = document.createDocumentFragment(); + var fragment = document.createDocumentFragment(); fragment.appendChild( div.firstChild ); // WebKit doesn't clone checked state correctly in fragments - support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; - - div.innerHTML = ""; + jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked; // Figure out if the W3C box model works as expected - div.style.width = div.style.paddingLeft = "1px"; + // document.body must exist before we can do this + jQuery(function() { + var div = document.createElement("div"), + body = document.getElementsByTagName("body")[0]; - body = document.getElementsByTagName( "body" )[ 0 ]; - // We use our own, invisible, body unless the body is already present - // in which case we use a div (#9239) - testElement = document.createElement( body ? "div" : "body" ); - testElementStyle = { - visibility: "hidden", - width: 0, - height: 0, - border: 0, - margin: 0 - }; - if ( body ) { - jQuery.extend( testElementStyle, { - position: "absolute", - left: -1000, - top: -1000 - }); - } - for ( i in testElementStyle ) { - testElement.style[ i ] = testElementStyle[ i ]; - } - testElement.appendChild( div ); - testElementParent = body || documentElement; - testElementParent.insertBefore( testElement, testElementParent.firstChild ); + // Frameset documents with no body should not run this code + if ( !body ) { + return; + } - // Check if a disconnected checkbox will retain its checked - // value of true after appended to the DOM (IE6/7) - support.appendChecked = input.checked; + div.style.width = div.style.paddingLeft = "1px"; + body.appendChild( div ); + jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2; - support.boxModel = div.offsetWidth === 2; + if ( "zoom" in div.style ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.style.display = "inline"; + div.style.zoom = 1; + jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2; - if ( "zoom" in div.style ) { - // Check if natively block-level elements act like inline-block - // elements when setting their display to 'inline' and giving - // them layout - // (IE < 8 does this) - div.style.display = "inline"; - div.style.zoom = 1; - support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 ); + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = ""; + div.innerHTML = "
"; + jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2; + } - // Check if elements with layout shrink-wrap their children - // (IE 6 does this) - div.style.display = ""; - div.innerHTML = "
"; - support.shrinkWrapBlocks = ( div.offsetWidth !== 2 ); - } + div.innerHTML = "
t
"; + var tds = div.getElementsByTagName("td"); - div.innerHTML = "
t
"; - tds = div.getElementsByTagName( "td" ); + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0; - // Check if table cells still have offsetWidth/Height when they are set - // to display:none and there are still other visible table cells in a - // table row; if so, offsetWidth/Height are not reliable for use when - // determining if an element has been hidden directly using - // display:none (it is still safe to use offsets if a parent element is - // hidden; don safety goggles and see bug #4512 for more information). - // (only IE 8 fails this test) - isSupported = ( tds[ 0 ].offsetHeight === 0 ); + tds[0].style.display = ""; + tds[1].style.display = "none"; - tds[ 0 ].style.display = ""; - tds[ 1 ].style.display = "none"; + // Check if empty table cells still have offsetWidth/Height + // (IE < 8 fail this test) + jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0; + div.innerHTML = ""; - // Check if empty table cells still have offsetWidth/Height - // (IE < 8 fail this test) - support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); - div.innerHTML = ""; - - // Check if div with explicit width and no margin-right incorrectly - // gets computed margin-right based on width of container. For more - // info see bug #3333 - // Fails in WebKit before Feb 2011 nightlies - // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right - if ( document.defaultView && document.defaultView.getComputedStyle ) { - marginDiv = document.createElement( "div" ); - marginDiv.style.width = "0"; - marginDiv.style.marginRight = "0"; - div.appendChild( marginDiv ); - support.reliableMarginRight = - ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; - } - - // Remove the body element we added - testElement.innerHTML = ""; - testElementParent.removeChild( testElement ); + body.removeChild( div ).style.display = "none"; + div = tds = null; + }); // Technique from Juriy Zaytsev // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/ - // We only care about the case where non-standard event systems - // are used, namely in IE. Short-circuiting here helps us to - // avoid an eval call (in setAttribute) which can cause CSP - // to go haywire. See: https://developer.mozilla.org/en/Security/CSP - if ( div.attachEvent ) { - for( i in { - submit: 1, - change: 1, - focusin: 1 - } ) { - eventName = "on" + i; - isSupported = ( eventName in div ); - if ( !isSupported ) { - div.setAttribute( eventName, "return;" ); - isSupported = ( typeof div[ eventName ] === "function" ); - } - support[ i + "Bubbles" ] = isSupported; + var eventSupported = function( eventName ) { + var el = document.createElement("div"); + eventName = "on" + eventName; + + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( !el.attachEvent ) { + return true; } - } - // Null connected elements to avoid leaks in IE - testElement = fragment = select = opt = body = marginDiv = div = input = null; + var isSupported = (eventName in el); + if ( !isSupported ) { + el.setAttribute(eventName, "return;"); + isSupported = typeof el[eventName] === "function"; + } + el = null; - return support; + return isSupported; + }; + + jQuery.support.submitBubbles = eventSupported("submit"); + jQuery.support.changeBubbles = eventSupported("change"); + + // release memory in IE + div = all = a = null; })(); - -// Keep track of boxModel -jQuery.boxModel = jQuery.support.boxModel; - })( jQuery ); diff --git a/src/traversing.js b/src/traversing.js index 8c4b4ef8..fe2e33d8 100644 --- a/src/traversing.js +++ b/src/traversing.js @@ -17,30 +17,17 @@ var runtil = /Until$/, jQuery.fn.extend({ find: function( selector ) { - var self = this, - i, l; - - if ( typeof selector !== "string" ) { - return jQuery( selector ).filter(function() { - for ( i = 0, l = self.length; i < l; i++ ) { - if ( jQuery.contains( self[ i ], this ) ) { - return true; - } - } - }); - } - var ret = this.pushStack( "", "find", selector ), - length, n, r; + length = 0; - for ( i = 0, l = this.length; i < l; i++ ) { + for ( var i = 0, l = this.length; i < l; i++ ) { length = ret.length; jQuery.find( selector, this[i], ret ); if ( i > 0 ) { // Make sure that the results are unique - for ( n = length; n < ret.length; n++ ) { - for ( r = 0; r < length; r++ ) { + for ( var n = length; n < ret.length; n++ ) { + for ( var r = 0; r < length; r++ ) { if ( ret[r] === ret[n] ) { ret.splice(n--, 1); break; @@ -73,15 +60,12 @@ jQuery.fn.extend({ }, is: function( selector ) { - return !!selector && ( typeof selector === "string" ? - jQuery.filter( selector, this ).length > 0 : - this.filter( selector ).length > 0 ); + return !!selector && jQuery.filter( selector, this ).length > 0; }, closest: function( selectors, context ) { var ret = [], i, l, cur = this[0]; - - // Array + if ( jQuery.isArray( selectors ) ) { var match, selector, matches = {}, @@ -91,8 +75,8 @@ jQuery.fn.extend({ for ( i = 0, l = selectors.length; i < l; i++ ) { selector = selectors[i]; - if ( !matches[ selector ] ) { - matches[ selector ] = POS.test( selector ) ? + if ( !matches[selector] ) { + matches[selector] = jQuery.expr.match.POS.test( selector ) ? jQuery( selector, context || this.context ) : selector; } @@ -100,9 +84,9 @@ jQuery.fn.extend({ while ( cur && cur.ownerDocument && cur !== context ) { for ( selector in matches ) { - match = matches[ selector ]; + match = matches[selector]; - if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) { + if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) { ret.push({ selector: selector, elem: cur, level: level }); } } @@ -115,10 +99,8 @@ jQuery.fn.extend({ return ret; } - // String - var pos = POS.test( selectors ) || typeof selectors !== "string" ? - jQuery( selectors, context || this.context ) : - 0; + var pos = POS.test( selectors ) ? + jQuery( selectors, context || this.context ) : null; for ( i = 0, l = this.length; i < l; i++ ) { cur = this[i]; @@ -130,14 +112,14 @@ jQuery.fn.extend({ } else { cur = cur.parentNode; - if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { + if ( !cur || !cur.ownerDocument || cur === context ) { break; } } } } - ret = ret.length > 1 ? jQuery.unique( ret ) : ret; + ret = ret.length > 1 ? jQuery.unique(ret) : ret; return this.pushStack( ret, "closest", selectors ); }, @@ -160,7 +142,7 @@ jQuery.fn.extend({ add: function( selector, context ) { var set = typeof selector === "string" ? jQuery( selector, context ) : - jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + jQuery.makeArray( selector ), all = jQuery.merge( this.get(), set ); return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? @@ -298,11 +280,6 @@ jQuery.extend({ // Implement the identical functionality for filter and not function winnow( elements, qualifier, keep ) { - - // Can't pass null or undefined to indexOf in Firefox 4 - // Set to 0 to skip string check - qualifier = qualifier || 0; - if ( jQuery.isFunction( qualifier ) ) { return jQuery.grep(elements, function( elem, i ) { var retVal = !!qualifier.call( elem, i, elem ); diff --git a/test/csp.php b/test/csp.php index 13c324ea..acf8f32c 100644 --- a/test/csp.php +++ b/test/csp.php @@ -6,7 +6,6 @@ CSP Test Page - diff --git a/test/data/dashboard.xml b/test/data/dashboard.xml index 5a6f5614..10f6b334 100644 --- a/test/data/dashboard.xml +++ b/test/data/dashboard.xml @@ -1,7 +1,7 @@ - + diff --git a/test/data/offset/absolute.html b/test/data/offset/absolute.html index 9d7990a3..b4db30a6 100644 --- a/test/data/offset/absolute.html +++ b/test/data/offset/absolute.html @@ -16,7 +16,6 @@ #positionTest { position: absolute; } - diff --git a/test/data/offset/body.html b/test/data/offset/body.html index 8dbf282d..e3eb4f80 100644 --- a/test/data/offset/body.html +++ b/test/data/offset/body.html @@ -9,7 +9,6 @@ #marker { position: absolute; border: 2px solid #000; width: 50px; height: 50px; background: #ccc; } - diff --git a/test/data/offset/fixed.html b/test/data/offset/fixed.html index 81ba4ca7..f93c20ff 100644 --- a/test/data/offset/fixed.html +++ b/test/data/offset/fixed.html @@ -13,7 +13,6 @@ #marker { position: absolute; border: 2px solid #000; width: 50px; height: 50px; background: #ccc; } - @@ -35,7 +34,6 @@
-

Click the white box to move the marker to it.

diff --git a/test/data/offset/relative.html b/test/data/offset/relative.html index 280a2fc0..35864760 100644 --- a/test/data/offset/relative.html +++ b/test/data/offset/relative.html @@ -11,7 +11,6 @@ #marker { position: absolute; border: 2px solid #000; width: 50px; height: 50px; background: #ccc; } - diff --git a/test/data/offset/scroll.html b/test/data/offset/scroll.html index a0d1f4d1..50de95e0 100644 --- a/test/data/offset/scroll.html +++ b/test/data/offset/scroll.html @@ -14,7 +14,6 @@ #marker { position: absolute; border: 2px solid #000; width: 50px; height: 50px; background: #ccc; } - diff --git a/test/data/offset/static.html b/test/data/offset/static.html index a61b6d10..b1fb9f15 100644 --- a/test/data/offset/static.html +++ b/test/data/offset/static.html @@ -11,7 +11,6 @@ #marker { position: absolute; border: 2px solid #000; width: 50px; height: 50px; background: #ccc; } - diff --git a/test/data/offset/table.html b/test/data/offset/table.html index 11fb0e79..528e5303 100644 --- a/test/data/offset/table.html +++ b/test/data/offset/table.html @@ -11,7 +11,6 @@ #marker { position: absolute; border: 2px solid #000; width: 50px; height: 50px; background: #ccc; } - diff --git a/test/data/readywaitloader.js b/test/data/readywaitloader.js index e07dac7a..483e07c4 100644 --- a/test/data/readywaitloader.js +++ b/test/data/readywaitloader.js @@ -1,14 +1,14 @@ -// Simple script loader that uses jQuery.readyWait via jQuery.holdReady() +// Simple script loader that uses jQuery.readyWait //Hold on jQuery! -jQuery.holdReady(true); +jQuery.readyWait++; var readyRegExp = /^(complete|loaded)$/; function assetLoaded( evt ){ var node = evt.currentTarget || evt.srcElement; if ( evt.type === "load" || readyRegExp.test(node.readyState) ) { - jQuery.holdReady(false); + jQuery.ready(true); } } diff --git a/test/data/support/bodyBackground.html b/test/data/support/bodyBackground.html deleted file mode 100644 index 9963c391..00000000 --- a/test/data/support/bodyBackground.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - diff --git a/test/data/support/boxModelIE.html b/test/data/support/boxModelIE.html deleted file mode 100644 index 1b11d2a5..00000000 --- a/test/data/support/boxModelIE.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/data/support/hiddenIFrameFF.html b/test/data/support/hiddenIFrameFF.html deleted file mode 100644 index 000ac851..00000000 --- a/test/data/support/hiddenIFrameFF.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/data/testrunner.js b/test/data/testrunner.js index 6d44b460..beb0fe2a 100644 --- a/test/data/testrunner.js +++ b/test/data/testrunner.js @@ -2,9 +2,8 @@ jQuery.noConflict(); // Allow the test to run with other libs or jQuery's. // jQuery-specific QUnit.reset (function() { - var reset = QUnit.reset, - ajaxSettings = jQuery.ajaxSettings; - + var reset = QUnit.reset; + var ajaxSettings = jQuery.ajaxSettings QUnit.reset = function() { reset.apply(this, arguments); jQuery.event.global = {}; @@ -25,9 +24,3 @@ jQuery.noConflict(); // Allow the test to run with other libs or jQuery's. document.write(""); })(); - -// QUnit Aliases -(function() { - window.equals = window.equal; - window.same = window.deepEqual; -})(); diff --git a/test/data/testsuite.css b/test/data/testsuite.css index 295740f5..cffaaa46 100644 --- a/test/data/testsuite.css +++ b/test/data/testsuite.css @@ -1,5 +1,5 @@ /* for testing opacity set in styles in IE */ -ol#empty { opacity: 0; filter:Alpha(opacity=0) progid:DXImageTransform.Microsoft.gradient(startColorStr='#ffff0000', EndColorStr='#ffffffff'); } +ol#empty { opacity: 0; filter:Alpha(opacity=0); } div#fx-tests h4 { background: red; @@ -109,15 +109,3 @@ div#show-tests * { display: none; } #nothiddendiv { font-size: 16px; } #nothiddendivchild.em { font-size: 2em; } #nothiddendivchild.prct { font-size: 150%; } - -/* For testing type on vml in IE #7071 */ -v\:oval { behavior:url(#default#VML); display:inline-block; } - -/* 8099 changes to default styles are read correctly */ -tt { display: none; } -sup { display: none; } -dfn { display: none; } - -/* #9239 Attach a background to the body( avoid crashes in removing the test element in support ) */ -body, div { background: url(http://static.jquery.com/files/rocker/images/logo_jquery_215x53.gif) no-repeat -1000px 0; } - diff --git a/test/data/versioncheck.js b/test/data/versioncheck.js deleted file mode 100644 index f4b7790d..00000000 --- a/test/data/versioncheck.js +++ /dev/null @@ -1,8 +0,0 @@ -// Run minified source from dist (do make first) -// Should be loaded before QUnit but after src -(function() { - if ( /jquery\=min/.test( window.location.search ) ) { - jQuery.noConflict( true ); - document.write(unescape("%3Cscript%20src%3D%27../dist/jquery.min.js%27%3E%3C/script%3E")); - } -})(); \ No newline at end of file diff --git a/test/delegatetest.html b/test/delegatetest.html index 169e60f7..c4f33aae 100644 --- a/test/delegatetest.html +++ b/test/delegatetest.html @@ -183,20 +183,10 @@ DOCUMENT - -

Mouseleave Tests

- -
-

Count mouse leave event

-
-

mouse over here should not trigger the counter.

-
-

0

-
    - + diff --git a/test/index.html b/test/index.html index 4b4c9855..d6213153 100644 --- a/test/index.html +++ b/test/index.html @@ -9,7 +9,6 @@ - @@ -28,14 +27,10 @@ - - - - @@ -51,9 +46,7 @@ -

    jQuery Test Suite - (minified) -

    +

    jQuery Test Suite

    @@ -63,10 +56,10 @@
    - + -
    -
    +
    +

    See this blog entry for more information.

    Here are some links in a normal paragraph: Google, @@ -208,10 +201,6 @@ Z - - - -

    diff --git a/test/localfile.html b/test/localfile.html index c552f214..96e0f982 100644 --- a/test/localfile.html +++ b/test/localfile.html @@ -5,7 +5,6 @@ jQuery Local File Test - diff --git a/test/networkerror.html b/test/networkerror.html index f98bf469..b06a6ba4 100644 --- a/test/networkerror.html +++ b/test/networkerror.html @@ -16,7 +16,6 @@ div { margin-top: 10px; } - diff --git a/test/qunit b/test/qunit deleted file mode 160000 index d4f23f8a..00000000 --- a/test/qunit +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d4f23f8a882d13b71768503e2db9fa33ef169ba0 diff --git a/test/readywait.html b/test/readywait.html index b4d8111e..8e0d3d53 100644 --- a/test/readywait.html +++ b/test/readywait.html @@ -1,13 +1,13 @@ - jQuery.holdReady Test + jQuery.readyWait Test - @@ -52,17 +51,15 @@

    - jQuery.holdReady Test + jQuery.readyWait Test

    - This is a test page for jQuery.readyWait and jQuery.holdReady, - see - #6781 - and - #8803. + This is a test page for jQuery.readyWait, that was + added due to this ticket + #6781.

    - Test for jQuery.holdReady, which can be used + Test for jQuery.readyWait, which can be used by plugins and other scripts to indicate something important to the page is still loading and needs to block the DOM ready callbacks that are registered @@ -70,7 +67,7 @@

    Script loaders are the most likely kind of script - to use jQuery.holdReady, but it could be used by + to use jQuery.readyWait, but it could be used by other things like a script that loads a CSS file and wants to pause the DOM ready callbacks.

    diff --git a/test/unit/ajax.js b/test/unit/ajax.js index 33433922..335c2ac4 100644 --- a/test/unit/ajax.js +++ b/test/unit/ajax.js @@ -14,7 +14,7 @@ test("jQuery.ajax() - success callbacks", function() { stop(); - jQuery("#foo").ajaxStart(function(){ + jQuery('#foo').ajaxStart(function(){ ok( true, "ajaxStart" ); }).ajaxStop(function(){ ok( true, "ajaxStop" ); @@ -46,7 +46,7 @@ test("jQuery.ajax() - success callbacks - (url, options) syntax", function() { stop(); setTimeout(function(){ - jQuery("#foo").ajaxStart(function(){ + jQuery('#foo').ajaxStart(function(){ ok( true, "ajaxStart" ); }).ajaxStop(function(){ ok( true, "ajaxStop" ); @@ -78,7 +78,7 @@ test("jQuery.ajax() - success callbacks (late binding)", function() { stop(); setTimeout(function(){ - jQuery("#foo").ajaxStart(function(){ + jQuery('#foo').ajaxStart(function(){ ok( true, "ajaxStart" ); }).ajaxStop(function(){ ok( true, "ajaxStop" ); @@ -111,7 +111,7 @@ test("jQuery.ajax() - success callbacks (oncomplete binding)", function() { stop(); setTimeout(function(){ - jQuery("#foo").ajaxStart(function(){ + jQuery('#foo').ajaxStart(function(){ ok( true, "ajaxStart" ); }).ajaxStop(function(){ ok( true, "ajaxStop" ); @@ -147,7 +147,7 @@ test("jQuery.ajax() - success callbacks (very late binding)", function() { stop(); setTimeout(function(){ - jQuery("#foo").ajaxStart(function(){ + jQuery('#foo').ajaxStart(function(){ ok( true, "ajaxStart" ); }).ajaxStop(function(){ ok( true, "ajaxStop" ); @@ -214,7 +214,7 @@ test("jQuery.ajax() - error callbacks", function() { expect( 8 ); stop(); - jQuery("#foo").ajaxStart(function(){ + jQuery('#foo').ajaxStart(function(){ ok( true, "ajaxStart" ); }).ajaxStop(function(){ ok( true, "ajaxStop" ); @@ -247,10 +247,10 @@ test( "jQuery.ajax - multiple method signatures introduced in 1.5 ( #8107)", fun stop(); jQuery.when( - jQuery.ajax().success(function() { ok( true, "With no arguments" ); }), - jQuery.ajax("data/name.html").success(function() { ok( true, "With only string URL argument" ); }), - jQuery.ajax("data/name.html", {} ).success(function() { ok( true, "With string URL param and map" ); }), - jQuery.ajax({ url: "data/name.html"} ).success(function() { ok( true, "With only map" ); }) + jQuery.ajax().success(function() { ok( true, 'With no arguments' ); }), + jQuery.ajax('data/name.html').success(function() { ok( true, 'With only string URL argument' ); }), + jQuery.ajax('data/name.html', {} ).success(function() { ok( true, 'With string URL param and map' ); }), + jQuery.ajax({ url: 'data/name.html'} ).success(function() { ok( true, 'With only map' ); }) ).then( start, start ); }); @@ -321,40 +321,25 @@ test("jQuery.ajax() - responseText on error", function() { test(".ajax() - retry with jQuery.ajax( this )", function() { - expect( 2 ); + expect( 1 ); stop(); - var firstTime = true, - previousUrl; + var firstTime = 1; jQuery.ajax({ url: url("data/errorWithText.php"), error: function() { if ( firstTime ) { - firstTime = false; + firstTime = 0; jQuery.ajax( this ); } else { ok( true , "Test retrying with jQuery.ajax(this) works" ); - jQuery.ajax({ - url: url("data/errorWithText.php"), - data: { x: 1 }, - beforeSend: function() { - if ( !previousUrl ) { - previousUrl = this.url; - } else { - strictEqual( this.url , previousUrl, "url parameters are not re-appended" ); - start(); - return false; - } - }, - error: function() { - jQuery.ajax( this ); - } - }); + start(); } } }); + }); test(".ajax() - headers" , function() { @@ -363,7 +348,7 @@ test(".ajax() - headers" , function() { stop(); - jQuery("#foo").ajaxSend(function( evt, xhr ) { + jQuery('#foo').ajaxSend(function( evt, xhr ) { xhr.setRequestHeader( "ajax-send", "test" ); }); @@ -507,7 +492,7 @@ test(".ajax() - hash", function() { test("jQuery ajax - cross-domain detection", function() { - expect( 6 ); + expect( 4 ); var loc = document.location, otherPort = loc.port === 666 ? 667 : 666, @@ -524,16 +509,7 @@ test("jQuery ajax - cross-domain detection", function() { jQuery.ajax({ dataType: "jsonp", - url: "app:/path", - beforeSend: function( _ , s ) { - ok( s.crossDomain , "Adobe AIR app:/ URL detected as cross-domain" ); - return false; - } - }); - - jQuery.ajax({ - dataType: "jsonp", - url: loc.protocol + "//somewebsitethatdoesnotexist-656329477541.com:" + ( loc.port || 80 ), + url: loc.protocol + '//somewebsitethatdoesnotexist-656329477541.com:' + ( loc.port || 80 ), beforeSend: function( _ , s ) { ok( s.crossDomain , "Test different hostnames are detected as cross-domain" ); return false; @@ -549,15 +525,6 @@ test("jQuery ajax - cross-domain detection", function() { } }); - jQuery.ajax({ - dataType: "jsonp", - url: "about:blank", - beforeSend: function( _ , s ) { - ok( s.crossDomain , "Test about:blank is detected as cross-domain" ); - return false; - } - }); - jQuery.ajax({ dataType: "jsonp", url: loc.protocol + "//" + loc.host, @@ -574,7 +541,7 @@ test(".load() - 404 error callbacks", function() { expect( 6 ); stop(); - jQuery("#foo").ajaxStart(function(){ + jQuery('#foo').ajaxStart(function(){ ok( true, "ajaxStart" ); }).ajaxStop(function(){ ok( true, "ajaxStop" ); @@ -598,7 +565,7 @@ test("jQuery.ajax() - abort", function() { expect( 8 ); stop(); - jQuery("#foo").ajaxStart(function(){ + jQuery('#foo').ajaxStart(function(){ ok( true, "ajaxStart" ); }).ajaxStop(function(){ ok( true, "ajaxStop" ); @@ -643,7 +610,7 @@ test("Ajax events with context", function() { }; } - jQuery("#foo").add(context) + jQuery('#foo').add(context) .ajaxSend(event) .ajaxComplete(event) .ajaxError(event) @@ -665,7 +632,7 @@ test("Ajax events with context", function() { complete: function(){ callback("complete").call(this); - jQuery("#foo").add(context).unbind(); + jQuery('#foo').add(context).unbind(); jQuery.ajax({ url: url("data/404.html"), @@ -749,7 +716,7 @@ test("jQuery.ajax() - disabled globals", function() { expect( 3 ); stop(); - jQuery("#foo").ajaxStart(function(){ + jQuery('#foo').ajaxStart(function(){ ok( false, "ajaxStart" ); }).ajaxStop(function(){ ok( false, "ajaxStop" ); @@ -783,9 +750,9 @@ test("jQuery.ajax - xml: non-namespace elements inside namespaced elements", fun url: url("data/with_fries.xml"), dataType: "xml", success: function(resp) { - equals( jQuery("properties", resp).length, 1, "properties in responseXML" ); - equals( jQuery("jsconf", resp).length, 1, "jsconf in responseXML" ); - equals( jQuery("thing", resp).length, 2, "things in responseXML" ); + equals( jQuery("properties", resp).length, 1, 'properties in responseXML' ); + equals( jQuery("jsconf", resp).length, 1, 'jsconf in responseXML' ); + equals( jQuery("thing", resp).length, 2, 'things in responseXML' ); start(); } }); @@ -798,9 +765,9 @@ test("jQuery.ajax - xml: non-namespace elements inside namespaced elements (over url: url("data/with_fries_over_jsonp.php"), dataType: "jsonp xml", success: function(resp) { - equals( jQuery("properties", resp).length, 1, "properties in responseXML" ); - equals( jQuery("jsconf", resp).length, 1, "jsconf in responseXML" ); - equals( jQuery("thing", resp).length, 2, "things in responseXML" ); + equals( jQuery("properties", resp).length, 1, 'properties in responseXML' ); + equals( jQuery("jsconf", resp).length, 1, 'jsconf in responseXML' ); + equals( jQuery("thing", resp).length, 2, 'things in responseXML' ); start(); }, error: function(_1,_2,error) { @@ -819,7 +786,7 @@ test("jQuery.ajax - HEAD requests", function() { type: "HEAD", success: function(data, status, xhr){ var h = xhr.getAllResponseHeaders(); - ok( /Date/i.test(h), "No Date in HEAD response" ); + ok( /Date/i.test(h), 'No Date in HEAD response' ); jQuery.ajax({ url: url("data/name.html"), @@ -827,7 +794,7 @@ test("jQuery.ajax - HEAD requests", function() { type: "HEAD", success: function(data, status, xhr){ var h = xhr.getAllResponseHeaders(); - ok( /Date/i.test(h), "No Date in HEAD response with data" ); + ok( /Date/i.test(h), 'No Date in HEAD response with data' ); start(); } }); @@ -906,8 +873,8 @@ test("jQuery.ajax - dataType html", function() { stop(); var verifyEvaluation = function() { - equals( testFoo, "foo", "Check if script was evaluated for datatype html" ); - equals( foobar, "bar", "Check if script src was evaluated for datatype html" ); + equals( testFoo, "foo", 'Check if script was evaluated for datatype html' ); + equals( foobar, "bar", 'Check if script src was evaluated for datatype html' ); start(); }; @@ -917,7 +884,7 @@ test("jQuery.ajax - dataType html", function() { url: url("data/test.html"), success: function(data) { jQuery("#ap").html(data); - ok( data.match(/^html text/), "Check content for datatype html" ); + ok( data.match(/^html text/), 'Check content for datatype html' ); setTimeout(verifyEvaluation, 600); } }); @@ -928,40 +895,40 @@ test("serialize()", function() { // Add html5 elements only for serialize because selector can't yet find them on non-html5 browsers jQuery("#search").after( - ""+ - "" + ''+ + '' ); - equals( jQuery("#form").serialize(), + equals( jQuery('#form').serialize(), "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&select5=3", - "Check form serialization as query string"); + 'Check form serialization as query string'); - equals( jQuery("#form :input").serialize(), + equals( jQuery('#form :input').serialize(), "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&select5=3", - "Check input serialization as query string"); + 'Check input serialization as query string'); - equals( jQuery("#testForm").serialize(), - "T3=%3F%0D%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=", - "Check form serialization as query string"); + equals( jQuery('#testForm').serialize(), + 'T3=%3F%0D%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=', + 'Check form serialization as query string'); - equals( jQuery("#testForm :input").serialize(), - "T3=%3F%0D%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=", - "Check input serialization as query string"); + equals( jQuery('#testForm :input').serialize(), + 'T3=%3F%0D%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=', + 'Check input serialization as query string'); - equals( jQuery("#form, #testForm").serialize(), + equals( jQuery('#form, #testForm').serialize(), "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&select5=3&T3=%3F%0D%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=", - "Multiple form serialization as query string"); + 'Multiple form serialization as query string'); /* Temporarily disabled. Opera 10 has problems with form serialization. - equals( jQuery("#form, #testForm :input").serialize(), + equals( jQuery('#form, #testForm :input').serialize(), "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&T3=%3F%0D%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=", - "Mixed form/input serialization as query string"); + 'Mixed form/input serialization as query string'); */ jQuery("#html5email, #html5number").remove(); }); test("jQuery.param()", function() { - expect(21); + expect(24); equals( !jQuery.ajaxSettings.traditional, true, "traditional flag, falsy by default" ); @@ -971,13 +938,13 @@ test("jQuery.param()", function() { params = {someName: [1, 2, 3], regularThing: "blah" }; equals( jQuery.param(params), "someName%5B%5D=1&someName%5B%5D=2&someName%5B%5D=3®ularThing=blah", "with array" ); - params = {foo: ["a", "b", "c"]}; + params = {foo: ['a', 'b', 'c']}; equals( jQuery.param(params), "foo%5B%5D=a&foo%5B%5D=b&foo%5B%5D=c", "with array of strings" ); params = {foo: ["baz", 42, "All your base are belong to us"] }; equals( jQuery.param(params), "foo%5B%5D=baz&foo%5B%5D=42&foo%5B%5D=All+your+base+are+belong+to+us", "more array" ); - params = {foo: { bar: "baz", beep: 42, quux: "All your base are belong to us" } }; + params = {foo: { bar: 'baz', beep: 42, quux: 'All your base are belong to us' } }; equals( jQuery.param(params), "foo%5Bbar%5D=baz&foo%5Bbeep%5D=42&foo%5Bquux%5D=All+your+base+are+belong+to+us", "even more arrays" ); params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" }; @@ -989,7 +956,12 @@ test("jQuery.param()", function() { params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" }; equals( jQuery.param(params,true), "a=1&a=2&b=%5Bobject+Object%5D&i=10&i=11&j=true&k=false&l=undefined&l=0&m=cowboy+hat%3F", "huge structure, forced traditional" ); - equals( decodeURIComponent( jQuery.param({ a: [1,2,3], "b[]": [4,5,6], "c[d]": [7,8,9], e: { f: [10], g: [11,12], h: 13 } }) ), "a[]=1&a[]=2&a[]=3&b[]=4&b[]=5&b[]=6&c[d][]=7&c[d][]=8&c[d][]=9&e[f][]=10&e[g][]=11&e[g][]=12&e[h]=13", "Make sure params are not double-encoded." ); + equals( decodeURIComponent( jQuery.param({ a: [1,2,3], 'b[]': [4,5,6], 'c[d]': [7,8,9], e: { f: [10], g: [11,12], h: 13 } }) ), "a[]=1&a[]=2&a[]=3&b[]=4&b[]=5&b[]=6&c[d][]=7&c[d][]=8&c[d][]=9&e[f][]=10&e[g][]=11&e[g][]=12&e[h]=13", "Make sure params are not double-encoded." ); + + // Make sure empty arrays and objects are handled #6481 + equals( jQuery.param({"foo": {"bar": []} }), "foo%5Bbar%5D=", "Empty array param" ); + equals( jQuery.param({"foo": {"bar": [], foo: 1} }), "foo%5Bbar%5D=&foo%5Bfoo%5D=1", "Empty array param" ); + equals( jQuery.param({"foo": {"bar": {}} }), "foo%5Bbar%5D=", "Empty object param" ); // #7945 equals( jQuery.param({"jquery": "1.4.2"}), "jquery=1.4.2", "Check that object with a jQuery property get serialized correctly" ); @@ -1002,7 +974,7 @@ test("jQuery.param()", function() { params = {someName: [1, 2, 3], regularThing: "blah" }; equals( jQuery.param(params), "someName=1&someName=2&someName=3®ularThing=blah", "with array" ); - params = {foo: ["a", "b", "c"]}; + params = {foo: ['a', 'b', 'c']}; equals( jQuery.param(params), "foo=a&foo=b&foo=c", "with array of strings" ); params = {"foo[]":["baz", 42, "All your base are belong to us"]}; @@ -1023,7 +995,7 @@ test("jQuery.param()", function() { params = { param1: null }; equals( jQuery.param(params,false), "param1=null", "Make sure that null params aren't traversed." ); - params = {"test": {"length": 3, "foo": "bar"} }; + params = {'test': {'length': 3, 'foo': 'bar'} }; equals( jQuery.param( params, false ), "test%5Blength%5D=3&test%5Bfoo%5D=bar", "Sub-object with a length property" ); }); @@ -1054,10 +1026,10 @@ test("pass-through request object", function() { errorCount++; errorEx += ": " + xml.status; }); - jQuery("#foo").one("ajaxStop", function () { + jQuery("#foo").one('ajaxStop', function () { equals(successCount, 5, "Check all ajax calls successful"); equals(errorCount, 0, "Check no ajax errors (status" + errorEx + ")"); - jQuery("#foo").unbind("ajaxError"); + jQuery("#foo").unbind('ajaxError'); start(); }); @@ -1111,17 +1083,17 @@ test("global ajaxSettings", function() { var orig = { url: "data/with_fries.xml" }; var t; - jQuery.ajaxSetup({ data: {foo: "bar", bar: "BAR"} }); + jQuery.ajaxSetup({ data: {foo: 'bar', bar: 'BAR'} }); t = jQuery.extend({}, orig); t.data = {}; jQuery.ajax(t); - ok( t.url.indexOf("foo") > -1 && t.url.indexOf("bar") > -1, "Check extending {}" ); + ok( t.url.indexOf('foo') > -1 && t.url.indexOf('bar') > -1, "Check extending {}" ); t = jQuery.extend({}, orig); - t.data = { zoo: "a", ping: "b" }; + t.data = { zoo: 'a', ping: 'b' }; jQuery.ajax(t); - ok( t.url.indexOf("ping") > -1 && t.url.indexOf("zoo") > -1 && t.url.indexOf("foo") > -1 && t.url.indexOf("bar") > -1, "Check extending { zoo: "a", ping: "b" }" ); + ok( t.url.indexOf('ping') > -1 && t.url.indexOf('zoo') > -1 && t.url.indexOf('foo') > -1 && t.url.indexOf('bar') > -1, "Check extending { zoo: 'a', ping: 'b' }" ); jQuery.ajaxSettings = tmp; }); @@ -1130,13 +1102,13 @@ test("global ajaxSettings", function() { test("load(String)", function() { expect(1); stop(); // check if load can be called with only url - jQuery("#first").load("data/name.html", start); + jQuery('#first').load("data/name.html", start); }); test("load('url selector')", function() { expect(1); stop(); // check if load can be called with only url - jQuery("#first").load("data/test3.html div.user", function(){ + jQuery('#first').load("data/test3.html div.user", function(){ equals( jQuery(this).children("div").length, 2, "Verify that specific elements were injected" ); start(); }); @@ -1152,14 +1124,14 @@ test("load(String, Function) with ajaxSetup on dataType json, see #2046", functi jQuery.ajaxSetup({ dataType: "" }); start(); }); - jQuery("#first").load("data/test3.html"); + jQuery('#first').load("data/test3.html"); }); test("load(String, Function) - simple: inject text into DOM", function() { expect(2); stop(); - jQuery("#first").load(url("data/name.html"), function() { - ok( /^ERROR/.test(jQuery("#first").text()), "Check if content was injected into the DOM" ); + jQuery('#first').load(url("data/name.html"), function() { + ok( /^ERROR/.test(jQuery('#first').text()), 'Check if content was injected into the DOM' ); start(); }); }); @@ -1169,15 +1141,15 @@ test("load(String, Function) - check scripts", function() { stop(); var verifyEvaluation = function() { - equals( foobar, "bar", "Check if script src was evaluated after load" ); - equals( jQuery("#ap").html(), "bar", "Check if script evaluation has modified DOM"); + equals( foobar, "bar", 'Check if script src was evaluated after load' ); + equals( jQuery('#ap').html(), 'bar', 'Check if script evaluation has modified DOM'); start(); }; - jQuery("#first").load(url("data/test.html"), function() { - ok( jQuery("#first").html().match(/^html text/), "Check content after loading html" ); - equals( jQuery("#foo").html(), "foo", "Check if script evaluation has modified DOM"); - equals( testFoo, "foo", "Check if script was evaluated after load" ); + jQuery('#first').load(url('data/test.html'), function() { + ok( jQuery('#first').html().match(/^html text/), 'Check content after loading html' ); + equals( jQuery('#foo').html(), 'foo', 'Check if script evaluation has modified DOM'); + equals( testFoo, "foo", 'Check if script was evaluated after load' ); setTimeout(verifyEvaluation, 600); }); }); @@ -1186,9 +1158,9 @@ test("load(String, Function) - check file with only a script tag", function() { expect(3); stop(); - jQuery("#first").load(url("data/test2.html"), function() { - equals( jQuery("#foo").html(), "foo", "Check if script evaluation has modified DOM"); - equals( testFoo, "foo", "Check if script was evaluated after load" ); + jQuery('#first').load(url('data/test2.html'), function() { + equals( jQuery('#foo').html(), 'foo', 'Check if script evaluation has modified DOM'); + equals( testFoo, "foo", 'Check if script was evaluated after load' ); start(); }); @@ -1210,10 +1182,10 @@ test("load(String, Object, Function)", function() { expect(2); stop(); - jQuery("
    ").load(url("data/params_html.php"), { foo: 3, bar: "ok" }, function() { - var $post = jQuery(this).find("#post"); - equals( $post.find("#foo").text(), "3", "Check if a hash of data is passed correctly"); - equals( $post.find("#bar").text(), "ok", "Check if a hash of data is passed correctly"); + jQuery('
    ').load(url('data/params_html.php'), { foo:3, bar:'ok' }, function() { + var $post = jQuery(this).find('#post'); + equals( $post.find('#foo').text(), '3', 'Check if a hash of data is passed correctly'); + equals( $post.find('#bar').text(), 'ok', 'Check if a hash of data is passed correctly'); start(); }); }); @@ -1222,10 +1194,10 @@ test("load(String, String, Function)", function() { expect(2); stop(); - jQuery("
    ").load(url("data/params_html.php"), "foo=3&bar=ok", function() { - var $get = jQuery(this).find("#get"); - equals( $get.find("#foo").text(), "3", "Check if a string of data is passed correctly"); - equals( $get.find("#bar").text(), "ok", "Check if a of data is passed correctly"); + jQuery('
    ').load(url('data/params_html.php'), 'foo=3&bar=ok', function() { + var $get = jQuery(this).find('#get'); + equals( $get.find('#foo').text(), '3', 'Check if a string of data is passed correctly'); + equals( $get.find('#bar').text(), 'ok', 'Check if a of data is passed correctly'); start(); }); }); @@ -1236,8 +1208,8 @@ test("jQuery.get(String, Function) - data in ajaxSettings (#8277)", function() { jQuery.ajaxSetup({ data: "helloworld" }); - jQuery.get(url("data/echoQuery.php"), function(data) { - ok( /helloworld$/.test( data ), "Data from ajaxSettings was used"); + jQuery.get(url('data/echoQuery.php'), function(data) { + ok( /helloworld$/.test( data ), 'Data from ajaxSettings was used'); jQuery.ajaxSetup({ data: null }); @@ -1248,13 +1220,13 @@ test("jQuery.get(String, Function) - data in ajaxSettings (#8277)", function() { test("jQuery.get(String, Hash, Function) - parse xml and use text() on nodes", function() { expect(2); stop(); - jQuery.get(url("data/dashboard.xml"), function(xml) { + jQuery.get(url('data/dashboard.xml'), function(xml) { var content = []; - jQuery("tab", xml).each(function() { + jQuery('tab', xml).each(function() { content.push(jQuery(this).text()); }); - equals( content[0], "blabla", "Check first tab"); - equals( content[1], "blublu", "Check second tab"); + equals( content[0], 'blabla', 'Check first tab'); + equals( content[1], 'blublu', 'Check second tab'); start(); }); }); @@ -1263,7 +1235,7 @@ test("jQuery.getScript(String, Function) - with callback", function() { expect(3); stop(); jQuery.getScript(url("data/test.js"), function( data, _, jqXHR ) { - equals( foobar, "bar", "Check if script was evaluated" ); + equals( foobar, "bar", 'Check if script was evaluated' ); strictEqual( data, jqXHR.responseText, "Same-domain script requests returns the source of the script (#8082)" ); setTimeout(start, 100); }); @@ -1610,7 +1582,7 @@ test("jQuery.ajax() - malformed JSON", function() { }, error: function(xhr, msg, detailedMsg) { equals( "parsererror", msg, "A parse error occurred." ); - ok( /^(Invalid|SyntaxError|exception)/i.test(detailedMsg), "Detailed parsererror message provided" ); + ok( /^Invalid JSON/.test(detailedMsg), "Detailed parsererror message provided" ); start(); } }); @@ -1646,10 +1618,10 @@ test("jQuery.ajax() - json by content-type", function() { data: { header: "json", json: "array" }, success: function( json ) { ok( json.length >= 2, "Check length"); - equals( json[0].name, "John", "Check JSON: first, name" ); - equals( json[0].age, 21, "Check JSON: first, age" ); - equals( json[1].name, "Peter", "Check JSON: second, name" ); - equals( json[1].age, 25, "Check JSON: second, age" ); + equals( json[0].name, 'John', 'Check JSON: first, name' ); + equals( json[0].age, 21, 'Check JSON: first, age' ); + equals( json[1].name, 'Peter', 'Check JSON: second, name' ); + equals( json[1].age, 25, 'Check JSON: second, age' ); start(); } }); @@ -1670,10 +1642,10 @@ test("jQuery.ajax() - json by content-type disabled with options", function() { equals( typeof text , "string" , "json wasn't auto-determined" ); var json = jQuery.parseJSON( text ); ok( json.length >= 2, "Check length"); - equals( json[0].name, "John", "Check JSON: first, name" ); - equals( json[0].age, 21, "Check JSON: first, age" ); - equals( json[1].name, "Peter", "Check JSON: second, name" ); - equals( json[1].age, 25, "Check JSON: second, age" ); + equals( json[0].name, 'John', 'Check JSON: first, name' ); + equals( json[0].age, 21, 'Check JSON: first, age' ); + equals( json[1].name, 'Peter', 'Check JSON: second, name' ); + equals( json[1].age, 25, 'Check JSON: second, age' ); start(); } }); @@ -1684,10 +1656,10 @@ test("jQuery.getJSON(String, Hash, Function) - JSON array", function() { stop(); jQuery.getJSON(url("data/json.php"), {json: "array"}, function(json) { ok( json.length >= 2, "Check length"); - equals( json[0].name, "John", "Check JSON: first, name" ); - equals( json[0].age, 21, "Check JSON: first, age" ); - equals( json[1].name, "Peter", "Check JSON: second, name" ); - equals( json[1].age, 25, "Check JSON: second, age" ); + equals( json[0].name, 'John', 'Check JSON: first, name' ); + equals( json[0].age, 21, 'Check JSON: first, age' ); + equals( json[1].name, 'Peter', 'Check JSON: second, name' ); + equals( json[1].age, 25, 'Check JSON: second, age' ); start(); }); }); @@ -1697,8 +1669,8 @@ test("jQuery.getJSON(String, Function) - JSON object", function() { stop(); jQuery.getJSON(url("data/json.php"), function(json) { if (json && json.data) { - equals( json.data.lang, "en", "Check JSON: lang" ); - equals( json.data.length, 25, "Check JSON: length" ); + equals( json.data.lang, 'en', 'Check JSON: lang' ); + equals( json.data.length, 25, 'Check JSON: length' ); } start(); }); @@ -1730,8 +1702,8 @@ test("jQuery.getJSON(String, Function) - JSON object with absolute url to local stop(); jQuery.getJSON(url(base + "data/json.php"), function(json) { - equals( json.data.lang, "en", "Check JSON: lang" ); - equals( json.data.length, 25, "Check JSON: length" ); + equals( json.data.lang, 'en', 'Check JSON: lang' ); + equals( json.data.length, 25, 'Check JSON: length' ); start(); }); }); @@ -1741,23 +1713,23 @@ test("jQuery.post - data", 3, function() { jQuery.when( jQuery.post( url( "data/name.php" ), { xml: "5-2", length: 3 }, function( xml ) { - jQuery( "math", xml ).each( function() { - equals( jQuery( "calculation", this ).text(), "5-2", "Check for XML" ); - equals( jQuery( "result", this ).text(), "3", "Check for XML" ); + jQuery( 'math', xml ).each( function() { + equals( jQuery( 'calculation', this ).text(), '5-2', 'Check for XML' ); + equals( jQuery( 'result', this ).text(), '3', 'Check for XML' ); }); }), jQuery.ajax({ - url: url("data/echoData.php"), + url: url('data/echoData.php'), type: "POST", data: { - "test": { - "length": 7, - "foo": "bar" + 'test': { + 'length': 7, + 'foo': 'bar' } }, success: function( data ) { - strictEqual( data, "test%5Blength%5D=7&test%5Bfoo%5D=bar", "Check if a sub-object with a length param is serialized correctly"); + strictEqual( data, 'test%5Blength%5D=7&test%5Bfoo%5D=bar', 'Check if a sub-object with a length param is serialized correctly'); } }) ).then( start, start ); @@ -1770,17 +1742,17 @@ test("jQuery.post(String, Hash, Function) - simple with xml", function() { var done = 0; jQuery.post(url("data/name.php"), {xml: "5-2"}, function(xml){ - jQuery("math", xml).each(function() { - equals( jQuery("calculation", this).text(), "5-2", "Check for XML" ); - equals( jQuery("result", this).text(), "3", "Check for XML" ); + jQuery('math', xml).each(function() { + equals( jQuery('calculation', this).text(), '5-2', 'Check for XML' ); + equals( jQuery('result', this).text(), '3', 'Check for XML' ); }); if ( ++done === 2 ) start(); }); jQuery.post(url("data/name.php?xml=5-2"), {}, function(xml){ - jQuery("math", xml).each(function() { - equals( jQuery("calculation", this).text(), "5-2", "Check for XML" ); - equals( jQuery("result", this).text(), "3", "Check for XML" ); + jQuery('math', xml).each(function() { + equals( jQuery('calculation', this).text(), '5-2', 'Check for XML' ); + equals( jQuery('result', this).text(), '3', 'Check for XML' ); }); if ( ++done === 2 ) start(); }); @@ -1796,18 +1768,18 @@ test("jQuery.ajaxSetup({timeout: Number}) - with global timeout", function() { var pass = function() { passed++; if ( passed == 2 ) { - ok( true, "Check local and global callbacks after timeout" ); - jQuery("#qunit-fixture").unbind("ajaxError"); + ok( true, 'Check local and global callbacks after timeout' ); + jQuery('#main').unbind("ajaxError"); start(); } }; var fail = function(a,b,c) { - ok( false, "Check for timeout failed " + a + " " + b ); + ok( false, 'Check for timeout failed ' + a + ' ' + b ); start(); }; - jQuery("#qunit-fixture").ajaxError(pass); + jQuery('#main').ajaxError(pass); jQuery.ajax({ type: "GET", @@ -1829,11 +1801,11 @@ test("jQuery.ajaxSetup({timeout: Number}) with localtimeout", function() { timeout: 15000, url: url("data/name.php?wait=1"), error: function() { - ok( false, "Check for local timeout failed" ); + ok( false, 'Check for local timeout failed' ); start(); }, success: function() { - ok( true, "Check for local timeout" ); + ok( true, 'Check for local timeout' ); start(); } }); @@ -1849,7 +1821,7 @@ test("jQuery.ajax - simple get", function() { type: "GET", url: url("data/name.php?name=foo"), success: function(msg){ - equals( msg, "bar", "Check for GET" ); + equals( msg, 'bar', 'Check for GET' ); start(); } }); @@ -1863,7 +1835,7 @@ test("jQuery.ajax - simple post", function() { url: url("data/name.php"), data: "name=peter", success: function(msg){ - equals( msg, "pan", "Check for POST" ); + equals( msg, 'pan', 'Check for POST' ); start(); } }); @@ -1875,7 +1847,7 @@ test("ajaxSetup()", function() { jQuery.ajaxSetup({ url: url("data/name.php?name=foo"), success: function(msg){ - equals( msg, "bar", "Check for GET" ); + equals( msg, 'bar', 'Check for GET' ); start(); } }); @@ -2037,14 +2009,14 @@ test("jQuery ajax - failing cross-domain", function() { var i = 2; jQuery.ajax({ - url: "http://somewebsitethatdoesnotexist-67864863574657654.com", + url: 'http://somewebsitethatdoesnotexist-67864863574657654.com', success: function(){ ok( false , "success" ); }, error: function(xhr,_,e){ ok( true , "file not found: " + xhr.status + " => " + e ); }, complete: function() { if ( ! --i ) start(); } }); jQuery.ajax({ - url: "http://www.google.com", + url: 'http://www.google.com', success: function(){ ok( false , "success" ); }, error: function(xhr,_,e){ ok( true , "access denied: " + xhr.status + " => " + e ); }, complete: function() { if ( ! --i ) start(); } @@ -2057,7 +2029,7 @@ test("jQuery ajax - atom+xml", function() { stop(); jQuery.ajax({ - url: url( "data/atom+xml.php" ), + url: url( 'data/atom+xml.php' ), success: function(){ ok( true , "success" ); }, error: function(){ ok( false , "error" ); }, complete: function() { start(); } @@ -2269,4 +2241,4 @@ test("jQuery.ajax - active counter", function() { } -//} +//} \ No newline at end of file diff --git a/test/unit/attributes.js b/test/unit/attributes.js index 4716e5b5..8cf47bed 100644 --- a/test/unit/attributes.js +++ b/test/unit/attributes.js @@ -3,141 +3,112 @@ module("attributes", { teardown: moduleTeardown }); var bareObj = function(value) { return value; }; var functionReturningObj = function(value) { return (function() { return value; }); }; +test("jQuery.props: itegrity test", function() { -test("jQuery.attrFix/jQuery.propFix integrity test", function() { - expect(2); - - // This must be maintained and equal jQuery.attrFix when appropriate - // Ensure that accidental or erroneous property - // overwrites don't occur - // This is simply for better code coverage and future proofing. - var props = { - tabindex: "tabIndex", - readonly: "readOnly", - "for": "htmlFor", - "class": "className", - maxlength: "maxLength", - cellspacing: "cellSpacing", - cellpadding: "cellPadding", - rowspan: "rowSpan", - colspan: "colSpan", - usemap: "useMap", - frameborder: "frameBorder", - contenteditable: "contentEditable" - }, - propsShouldBe; + expect(1); - if ( !jQuery.support.getSetAttribute ) { - propsShouldBe = props; - } else { - propsShouldBe = { - tabindex: "tabIndex" - }; - } + // This must be maintained and equal jQuery.props + // Ensure that accidental or erroneous property + // overwrites don't occur + // This is simply for better code coverage and future proofing. + var propsShouldBe = { + "for": "htmlFor", + "class": "className", + readonly: "readOnly", + maxlength: "maxLength", + cellspacing: "cellSpacing", + rowspan: "rowSpan", + colspan: "colSpan", + tabindex: "tabIndex", + usemap: "useMap", + frameborder: "frameBorder" + }; + + same(propsShouldBe, jQuery.props, "jQuery.props passes integrity check"); - deepEqual(propsShouldBe, jQuery.attrFix, "jQuery.attrFix passes integrity check"); - deepEqual(props, jQuery.propFix, "jQuery.propFix passes integrity check"); }); test("attr(String)", function() { - expect(45); + expect(37); - equals( jQuery("#text1").attr("type"), "text", "Check for type attribute" ); - equals( jQuery("#radio1").attr("type"), "radio", "Check for type attribute" ); - equals( jQuery("#check1").attr("type"), "checkbox", "Check for type attribute" ); - equals( jQuery("#simon1").attr("rel"), "bookmark", "Check for rel attribute" ); - equals( jQuery("#google").attr("title"), "Google!", "Check for title attribute" ); - equals( jQuery("#mark").attr("hreflang"), "en", "Check for hreflang attribute" ); - equals( jQuery("#en").attr("lang"), "en", "Check for lang attribute" ); - equals( jQuery("#simon").attr("class"), "blog link", "Check for class attribute" ); - equals( jQuery("#name").attr("name"), "name", "Check for name attribute" ); - equals( jQuery("#text1").attr("name"), "action", "Check for name attribute" ); - ok( jQuery("#form").attr("action").indexOf("formaction") >= 0, "Check for action attribute" ); - equals( jQuery("#text1").attr("value", "t").attr("value"), "t", "Check setting the value attribute" ); - equals( jQuery("
    ").attr("value"), "t", "Check setting custom attr named 'value' on a div" ); - equals( jQuery("#form").attr("blah", "blah").attr("blah"), "blah", "Set non-existant attribute on a form" ); - equals( jQuery("#foo").attr("height"), undefined, "Non existent height attribute should return undefined" ); - - // [7472] & [3113] (form contains an input with name="action" or name="id") - var extras = jQuery("").appendTo("#testForm"); - equals( jQuery("#form").attr("action","newformaction").attr("action"), "newformaction", "Check that action attribute was changed" ); - equals( jQuery("#testForm").attr("target"), undefined, "Retrieving target does not equal the input with name=target" ); - equals( jQuery("#testForm").attr("target", "newTarget").attr("target"), "newTarget", "Set target successfully on a form" ); - equals( jQuery("#testForm").removeAttr("id").attr("id"), undefined, "Retrieving id does not equal the input with name=id after id is removed [#7472]" ); - // Bug #3685 (form contains input with name="name") - equals( jQuery("#testForm").attr("name"), undefined, "Retrieving name does not retrieve input with name=name" ); - extras.remove(); - - equals( jQuery("#text1").attr("maxlength"), "30", "Check for maxlength attribute" ); - equals( jQuery("#text1").attr("maxLength"), "30", "Check for maxLength attribute" ); - equals( jQuery("#area1").attr("maxLength"), "30", "Check for maxLength attribute" ); + // This one sometimes fails randomly ?! + equals( jQuery('#text1').attr('value'), "Test", 'Check for value attribute' ); + + equals( jQuery('#text1').attr('value', "Test2").attr('defaultValue'), "Test", 'Check for defaultValue attribute' ); + equals( jQuery('#text1').attr('type'), "text", 'Check for type attribute' ); + equals( jQuery('#radio1').attr('type'), "radio", 'Check for type attribute' ); + equals( jQuery('#check1').attr('type'), "checkbox", 'Check for type attribute' ); + equals( jQuery('#simon1').attr('rel'), "bookmark", 'Check for rel attribute' ); + equals( jQuery('#google').attr('title'), "Google!", 'Check for title attribute' ); + equals( jQuery('#mark').attr('hreflang'), "en", 'Check for hreflang attribute' ); + equals( jQuery('#en').attr('lang'), "en", 'Check for lang attribute' ); + equals( jQuery('#simon').attr('class'), "blog link", 'Check for class attribute' ); + equals( jQuery('#name').attr('name'), "name", 'Check for name attribute' ); + equals( jQuery('#text1').attr('name'), "action", 'Check for name attribute' ); + ok( jQuery('#form').attr('action').indexOf("formaction") >= 0, 'Check for action attribute' ); + // Temporarily disabled. See: #4299 + // ok( jQuery('#form').attr('action','newformaction').attr('action').indexOf("newformaction") >= 0, 'Check that action attribute was changed' ); + equals( jQuery('#text1').attr('maxlength'), '30', 'Check for maxlength attribute' ); + equals( jQuery('#text1').attr('maxLength'), '30', 'Check for maxLength attribute' ); + equals( jQuery('#area1').attr('maxLength'), '30', 'Check for maxLength attribute' ); + equals( jQuery('#select2').attr('selectedIndex'), 3, 'Check for selectedIndex attribute' ); + equals( jQuery('#foo').attr('nodeName').toUpperCase(), 'DIV', 'Check for nodeName attribute' ); + equals( jQuery('#foo').attr('tagName').toUpperCase(), 'DIV', 'Check for tagName attribute' ); // using innerHTML in IE causes href attribute to be serialized to the full path - jQuery("").attr({ "id": "tAnchor5", "href": "#5" }).appendTo("#qunit-fixture"); - equals( jQuery("#tAnchor5").attr("href"), "#5", "Check for non-absolute href (an anchor)" ); + jQuery('').attr({ 'id': 'tAnchor5', 'href': '#5' }).appendTo('#main'); + equals( jQuery('#tAnchor5').attr('href'), "#5", 'Check for non-absolute href (an anchor)' ); + + equals( jQuery("").appendTo("#qunit-fixture"); - equal( $form.attr("class"), "something", "Retrieve the class attribute on a form." ); - - var $a = jQuery("Click").appendTo("#qunit-fixture"); - equal( $a.attr("onclick"), "something()", "Retrieve ^on attribute without anonymous function wrapper." ); + equals( jQuery(option).attr("selected"), true, "Make sure that a single option is selected, even when in an optgroup." ); ok( jQuery("
    ").attr("doesntexist") === undefined, "Make sure undefined is returned when no attribute is found." ); - ok( jQuery("
    ").attr("title") === undefined, "Make sure undefined is returned when no attribute is found." ); - equal( jQuery("
    ").attr("title", "something").attr("title"), "something", "Set the title attribute." ); ok( jQuery().attr("doesntexist") === undefined, "Make sure undefined is returned when no element is there." ); - equal( jQuery("
    ").attr("value"), undefined, "An unset value on a div returns undefined." ); - equal( jQuery("").attr("value"), "", "An unset value on an input returns current value." ); + + equals( jQuery(document).attr("nodeName"), "#document", "attr works correctly on document nodes (bug #7451)." ); + + var attributeNode = document.createAttribute("irrelevant"), + commentNode = document.createComment("some comment"), + textNode = document.createTextNode("some text"), + obj = {}; + jQuery.each( [document, attributeNode, commentNode, textNode, obj, "#firstp"], function( i, ele ) { + strictEqual( jQuery(ele).attr("nonexisting"), undefined, "attr works correctly for non existing attributes (bug #7500)." ); + }); }); if ( !isLocal ) { test("attr(String) in XML Files", function() { - expect(3); + expect(2); stop(); - jQuery.get("data/dashboard.xml", function( xml ) { - equal( jQuery( "locations", xml ).attr("class"), "foo", "Check class attribute in XML document" ); - equal( jQuery( "location", xml ).attr("for"), "bar", "Check for attribute in XML document" ); - equal( jQuery( "location", xml ).attr("checked"), "different", "Check that hooks are not attached in XML document" ); + jQuery.get("data/dashboard.xml", function(xml) { + equals( jQuery("locations", xml).attr("class"), "foo", "Check class attribute in XML document" ); + equals( jQuery("location", xml).attr("for"), "bar", "Check for attribute in XML document" ); start(); }); }); @@ -145,141 +116,92 @@ if ( !isLocal ) { test("attr(String, Function)", function() { expect(2); - equals( jQuery("#text1").attr("value", function() { return this.id; })[0].value, "text1", "Set value from id" ); - equals( jQuery("#text1").attr("title", function(i) { return i; }).attr("title"), "0", "Set value with an index"); + equals( jQuery('#text1').attr('value', function() { return this.id ;})[0].value, "text1", "Set value from id" ); + equals( jQuery('#text1').attr('title', function(i) { return i }).attr('title'), "0", "Set value with an index"); }); test("attr(Hash)", function() { expect(3); var pass = true; - jQuery("div").attr({foo: "baz", zoo: "ping"}).each(function(){ - if ( this.getAttribute("foo") != "baz" && this.getAttribute("zoo") != "ping" ) pass = false; + jQuery("div").attr({foo: 'baz', zoo: 'ping'}).each(function(){ + if ( this.getAttribute('foo') != "baz" && this.getAttribute('zoo') != "ping" ) pass = false; }); ok( pass, "Set Multiple Attributes" ); - equals( jQuery("#text1").attr({value: function() { return this.id; }})[0].value, "text1", "Set attribute to computed value #1" ); - equals( jQuery("#text1").attr({title: function(i) { return i; }}).attr("title"), "0", "Set attribute to computed value #2"); + equals( jQuery('#text1').attr({'value': function() { return this.id; }})[0].value, "text1", "Set attribute to computed value #1" ); + equals( jQuery('#text1').attr({'title': function(i) { return i; }}).attr('title'), "0", "Set attribute to computed value #2"); }); test("attr(String, Object)", function() { - expect(69); + expect(30); var div = jQuery("div").attr("foo", "bar"), fail = false; for ( var i = 0; i < div.size(); i++ ) { - if ( div.get(i).getAttribute("foo") != "bar" ){ + if ( div.get(i).getAttribute('foo') != "bar" ){ fail = i; break; } } - equals( fail, false, "Set Attribute, the #" + fail + " element didn't get the attribute 'foo'" ); + equals( fail, false, "Set Attribute, the #"+fail+" element didn't get the attribute 'foo'" ); - ok( jQuery("#foo").attr({ "width": null }), "Try to set an attribute to nothing" ); + // Fails on IE since recent changes to .attr() + // ok( jQuery("#foo").attr({"width": null}), "Try to set an attribute to nothing" ); - jQuery("#name").attr("name", "something"); - equals( jQuery("#name").attr("name"), "something", "Set name attribute" ); - jQuery("#name").attr("name", null); - equals( jQuery("#name").attr("name"), undefined, "Remove name attribute" ); - var $input = jQuery("", { name: "something" }); - equals( $input.attr("name"), "something", "Check element creation gets/sets the name attribute." ); - - jQuery("#check2").prop("checked", true).prop("checked", false).attr("checked", true); - equals( document.getElementById("check2").checked, true, "Set checked attribute" ); - equals( jQuery("#check2").prop("checked"), true, "Set checked attribute" ); - equals( jQuery("#check2").attr("checked"), "checked", "Set checked attribute" ); - jQuery("#check2").attr("checked", false); - equals( document.getElementById("check2").checked, false, "Set checked attribute" ); - equals( jQuery("#check2").prop("checked"), false, "Set checked attribute" ); - equals( jQuery("#check2").attr("checked"), undefined, "Set checked attribute" ); - jQuery("#text1").attr("readonly", true); - equals( document.getElementById("text1").readOnly, true, "Set readonly attribute" ); - equals( jQuery("#text1").prop("readOnly"), true, "Set readonly attribute" ); - equals( jQuery("#text1").attr("readonly"), "readonly", "Set readonly attribute" ); - jQuery("#text1").attr("readonly", false); - equals( document.getElementById("text1").readOnly, false, "Set readonly attribute" ); - equals( jQuery("#text1").prop("readOnly"), false, "Set readonly attribute" ); - equals( jQuery("#text1").attr("readonly"), undefined, "Set readonly attribute" ); - - jQuery("#check2").prop("checked", true); - equals( document.getElementById("check2").checked, true, "Set checked attribute" ); - equals( jQuery("#check2").prop("checked"), true, "Set checked attribute" ); - equals( jQuery("#check2").attr("checked"), "checked", "Set checked attribute" ); - jQuery("#check2").prop("checked", false); - equals( document.getElementById("check2").checked, false, "Set checked attribute" ); - equals( jQuery("#check2").prop("checked"), false, "Set checked attribute" ); - equals( jQuery("#check2").attr("checked"), undefined, "Set checked attribute" ); - - jQuery("#check2").attr("checked", "checked"); - equal( document.getElementById("check2").checked, true, "Set checked attribute with 'checked'" ); - equal( jQuery("#check2").prop("checked"), true, "Set checked attribute" ); - equal( jQuery("#check2").attr("checked"), "checked", "Set checked attribute" ); - - jQuery("#text1").prop("readOnly", true); - equals( document.getElementById("text1").readOnly, true, "Set readonly attribute" ); - equals( jQuery("#text1").prop("readOnly"), true, "Set readonly attribute" ); - equals( jQuery("#text1").attr("readonly"), "readonly", "Set readonly attribute" ); - jQuery("#text1").prop("readOnly", false); - equals( document.getElementById("text1").readOnly, false, "Set readonly attribute" ); - equals( jQuery("#text1").prop("readOnly"), false, "Set readonly attribute" ); - equals( jQuery("#text1").attr("readonly"), undefined, "Set readonly attribute" ); - - jQuery("#name").attr("maxlength", "5"); - equals( document.getElementById("name").maxLength, 5, "Set maxlength attribute" ); - jQuery("#name").attr("maxLength", "10"); - equals( document.getElementById("name").maxLength, 10, "Set maxlength attribute" ); - - var $text = jQuery("#text1").attr("autofocus", true); - if ( "autofocus" in $text[0] ) { - equals( $text.attr("autofocus"), "autofocus", "Set boolean attributes to the same name"); - } else { - equals( $text.attr("autofocus"), undefined, "autofocus stays undefined in browsers that do not support it(F<4)"); - } - equals( $text.attr("autofocus", false).attr("autofocus"), undefined, "Setting autofocus attribute to false removes it"); - equals( $text.attr("data-something", true).data("something"), true, "Setting data attributes are not affected by boolean settings"); - equals( $text.attr("data-another", false).data("another"), false, "Setting data attributes are not affected by boolean settings" ); - equals( $text.attr("aria-disabled", false).attr("aria-disabled"), "false", "Setting aria attributes are not affected by boolean settings"); - $text.removeData("something").removeData("another").removeAttr("aria-disabled"); - - jQuery("#foo").attr("contenteditable", true); - equals( jQuery("#foo").attr("contenteditable"), "true", "Enumerated attributes are set properly" ); + jQuery("#name").attr('name', 'something'); + equals( jQuery("#name").attr('name'), 'something', 'Set name attribute' ); + jQuery("#name").attr('name', null); + equals( jQuery("#name").attr('title'), '', 'Remove name attribute' ); + jQuery("#check2").attr('checked', true); + equals( document.getElementById('check2').checked, true, 'Set checked attribute' ); + jQuery("#check2").attr('checked', false); + equals( document.getElementById('check2').checked, false, 'Set checked attribute' ); + jQuery("#text1").attr('readonly', true); + equals( document.getElementById('text1').readOnly, true, 'Set readonly attribute' ); + jQuery("#text1").attr('readonly', false); + equals( document.getElementById('text1').readOnly, false, 'Set readonly attribute' ); + jQuery("#name").attr('maxlength', '5'); + equals( document.getElementById('name').maxLength, '5', 'Set maxlength attribute' ); + jQuery("#name").attr('maxLength', '10'); + equals( document.getElementById('name').maxLength, '10', 'Set maxlength attribute' ); var attributeNode = document.createAttribute("irrelevant"), commentNode = document.createComment("some comment"), textNode = document.createTextNode("some text"), obj = {}; - - jQuery.each( [commentNode, textNode, attributeNode], function( i, elem ) { - var $elem = jQuery( elem ); - $elem.attr( "nonexisting", "foo" ); - strictEqual( $elem.attr("nonexisting"), undefined, "attr(name, value) works correctly on comment and text nodes (bug #7500)." ); + jQuery.each( [document, obj, "#firstp"], function( i, ele ) { + var $ele = jQuery( ele ); + $ele.attr( "nonexisting", "foo" ); + equal( $ele.attr("nonexisting"), "foo", "attr(name, value) works correctly for non existing attributes (bug #7500)." ); + }); + jQuery.each( [commentNode, textNode, attributeNode], function( i, ele ) { + var $ele = jQuery( ele ); + $ele.attr( "nonexisting", "foo" ); + strictEqual( $ele.attr("nonexisting"), undefined, "attr(name, value) works correctly on comment and text nodes (bug #7500)." ); + }); + //cleanup + jQuery.each( [document, "#firstp"], function( i, ele ) { + jQuery( ele ).removeAttr("nonexisting"); }); - jQuery.each( [window, document, obj, "#firstp"], function( i, elem ) { - var $elem = jQuery( elem ); - strictEqual( $elem.attr("nonexisting"), undefined, "attr works correctly for non existing attributes (bug #7500)." ); - equal( $elem.attr("something", "foo" ).attr("something"), "foo", "attr falls back to prop on unsupported arguments" ); - }); - - var table = jQuery("#table").append("cellcellcellcellcell"), - td = table.find("td:first"); + var table = jQuery('#table').append("cellcellcellcellcell"), + td = table.find('td:first'); td.attr("rowspan", "2"); equals( td[0].rowSpan, 2, "Check rowspan is correctly set" ); td.attr("colspan", "2"); equals( td[0].colSpan, 2, "Check colspan is correctly set" ); table.attr("cellspacing", "2"); - equals( table[0].cellSpacing, "2", "Check cellspacing is correctly set" ); - - equals( jQuery("#area1").attr("value"), "foobar", "Value attribute retrieves the property for backwards compatibility." ); + equals( table[0].cellSpacing, 2, "Check cellspacing is correctly set" ); // for #1070 - jQuery("#name").attr("someAttr", "0"); - equals( jQuery("#name").attr("someAttr"), "0", "Set attribute to a string of \"0\"" ); - jQuery("#name").attr("someAttr", 0); - equals( jQuery("#name").attr("someAttr"), "0", "Set attribute to the number 0" ); - jQuery("#name").attr("someAttr", 1); - equals( jQuery("#name").attr("someAttr"), "1", "Set attribute to the number 1" ); + jQuery("#name").attr('someAttr', '0'); + equals( jQuery("#name").attr('someAttr'), '0', 'Set attribute to a string of "0"' ); + jQuery("#name").attr('someAttr', 0); + equals( jQuery("#name").attr('someAttr'), 0, 'Set attribute to the number 0' ); + jQuery("#name").attr('someAttr', 1); + equals( jQuery("#name").attr('someAttr'), 1, 'Set attribute to the number 1' ); // using contents will get comments regular, text, and comment nodes var j = jQuery("#nonnodes").contents(); @@ -289,57 +211,46 @@ test("attr(String, Object)", function() { j.removeAttr("name"); QUnit.reset(); - - // Type - var type = jQuery("#check2").attr("type"); + + var type = jQuery("#check2").attr('type'); var thrown = false; try { - jQuery("#check2").attr("type","hidden"); + jQuery("#check2").attr('type','hidden'); } catch(e) { thrown = true; } ok( thrown, "Exception thrown when trying to change type property" ); - equals( type, jQuery("#check2").attr("type"), "Verify that you can't change the type of an input element" ); + equals( type, jQuery("#check2").attr('type'), "Verify that you can't change the type of an input element" ); var check = document.createElement("input"); var thrown = true; try { - jQuery(check).attr("type", "checkbox"); + jQuery(check).attr('type','checkbox'); } catch(e) { thrown = false; } ok( thrown, "Exception thrown when trying to change type property" ); - equals( "checkbox", jQuery(check).attr("type"), "Verify that you can change the type of an input element that isn't in the DOM" ); + equals( "checkbox", jQuery(check).attr('type'), "Verify that you can change the type of an input element that isn't in the DOM" ); var check = jQuery(""); var thrown = true; try { - check.attr("type","checkbox"); + check.attr('type','checkbox'); } catch(e) { thrown = false; } ok( thrown, "Exception thrown when trying to change type property" ); - equals( "checkbox", check.attr("type"), "Verify that you can change the type of an input element that isn't in the DOM" ); + equals( "checkbox", check.attr('type'), "Verify that you can change the type of an input element that isn't in the DOM" ); var button = jQuery("#button"); var thrown = false; try { - button.attr("type","submit"); + button.attr('type','submit'); } catch(e) { thrown = true; } ok( thrown, "Exception thrown when trying to change type property" ); - equals( "button", button.attr("type"), "Verify that you can't change the type of a button element" ); - - var $radio = jQuery("", { "value": "sup", "type": "radio" }).appendTo("#testForm"); - equals( $radio.val(), "sup", "Value is not reset when type is set after value on a radio" ); - - // Setting attributes on svg elements (bug #3116) - var $svg = jQuery("" - + "" - + "").appendTo("body"); - equals( $svg.attr("cx", 100).attr("cx"), "100", "Set attribute on svg element" ); - $svg.remove(); + equals( "button", button.attr('type'), "Verify that you can't change the type of a button element" ); }); test("attr(jquery_method)", function(){ @@ -349,17 +260,17 @@ test("attr(jquery_method)", function(){ elem = $elem[0]; // one at a time - $elem.attr({html: "foo"}, true); - equals( elem.innerHTML, "foo", "attr(html)"); + $elem.attr({'html': 'foo'}, true); + equals( elem.innerHTML, 'foo', 'attr(html)'); - $elem.attr({text: "bar"}, true); - equals( elem.innerHTML, "bar", "attr(text)"); + $elem.attr({'text': 'bar'}, true); + equals( elem.innerHTML, 'bar', 'attr(text)'); - $elem.attr({css: {color: "red"}}, true); - ok( /^(#ff0000|red)$/i.test(elem.style.color), "attr(css)"); + $elem.attr({'css': {color:'red'}}, true); + ok( /^(#ff0000|red)$/i.test(elem.style.color), 'attr(css)'); - $elem.attr({height: 10}, true); - equals( elem.style.height, "10px", "attr(height)"); + $elem.attr({'height': 10}, true); + equals( elem.style.height, '10px', 'attr(height)'); // Multiple attributes @@ -368,22 +279,22 @@ test("attr(jquery_method)", function(){ css:{ paddingLeft:1, paddingRight:1 } }, true); - equals( elem.style.width, "10px", "attr({...})"); - equals( elem.style.paddingLeft, "1px", "attr({...})"); - equals( elem.style.paddingRight, "1px", "attr({...})"); + equals( elem.style.width, '10px', 'attr({...})'); + equals( elem.style.paddingLeft, '1px', 'attr({...})'); + equals( elem.style.paddingRight, '1px', 'attr({...})'); }); if ( !isLocal ) { test("attr(String, Object) - Loaded via XML document", function() { expect(2); stop(); - jQuery.get("data/dashboard.xml", function( xml ) { + jQuery.get('data/dashboard.xml', function(xml) { var titles = []; - jQuery( "tab", xml ).each(function() { - titles.push( jQuery(this).attr("title") ); + jQuery('tab', xml).each(function() { + titles.push(jQuery(this).attr('title')); }); - equals( titles[0], "Location", "attr() in XML context: Check first title" ); - equals( titles[1], "Users", "attr() in XML context: Check second title" ); + equals( titles[0], 'Location', 'attr() in XML context: Check first title' ); + equals( titles[1], 'Users', 'attr() in XML context: Check second title' ); start(); }); }); @@ -393,158 +304,84 @@ test("attr('tabindex')", function() { expect(8); // elements not natively tabbable - equals(jQuery("#listWithTabIndex").attr("tabindex"), 5, "not natively tabbable, with tabindex set to 0"); - equals(jQuery("#divWithNoTabIndex").attr("tabindex"), undefined, "not natively tabbable, no tabindex set"); + equals(jQuery('#listWithTabIndex').attr('tabindex'), 5, 'not natively tabbable, with tabindex set to 0'); + equals(jQuery('#divWithNoTabIndex').attr('tabindex'), undefined, 'not natively tabbable, no tabindex set'); // anchor with href - equals(jQuery("#linkWithNoTabIndex").attr("tabindex"), 0, "anchor with href, no tabindex set"); - equals(jQuery("#linkWithTabIndex").attr("tabindex"), 2, "anchor with href, tabindex set to 2"); - equals(jQuery("#linkWithNegativeTabIndex").attr("tabindex"), -1, "anchor with href, tabindex set to -1"); + equals(jQuery('#linkWithNoTabIndex').attr('tabindex'), 0, 'anchor with href, no tabindex set'); + equals(jQuery('#linkWithTabIndex').attr('tabindex'), 2, 'anchor with href, tabindex set to 2'); + equals(jQuery('#linkWithNegativeTabIndex').attr('tabindex'), -1, 'anchor with href, tabindex set to -1'); // anchor without href - equals(jQuery("#linkWithNoHrefWithNoTabIndex").attr("tabindex"), undefined, "anchor without href, no tabindex set"); - equals(jQuery("#linkWithNoHrefWithTabIndex").attr("tabindex"), 1, "anchor without href, tabindex set to 2"); - equals(jQuery("#linkWithNoHrefWithNegativeTabIndex").attr("tabindex"), -1, "anchor without href, no tabindex set"); + equals(jQuery('#linkWithNoHrefWithNoTabIndex').attr('tabindex'), undefined, 'anchor without href, no tabindex set'); + equals(jQuery('#linkWithNoHrefWithTabIndex').attr('tabindex'), 1, 'anchor without href, tabindex set to 2'); + equals(jQuery('#linkWithNoHrefWithNegativeTabIndex').attr('tabindex'), -1, 'anchor without href, no tabindex set'); }); test("attr('tabindex', value)", function() { expect(9); - var element = jQuery("#divWithNoTabIndex"); - equals(element.attr("tabindex"), undefined, "start with no tabindex"); + var element = jQuery('#divWithNoTabIndex'); + equals(element.attr('tabindex'), undefined, 'start with no tabindex'); // set a positive string - element.attr("tabindex", "1"); - equals(element.attr("tabindex"), 1, "set tabindex to 1 (string)"); + element.attr('tabindex', '1'); + equals(element.attr('tabindex'), 1, 'set tabindex to 1 (string)'); // set a zero string - element.attr("tabindex", "0"); - equals(element.attr("tabindex"), 0, "set tabindex to 0 (string)"); + element.attr('tabindex', '0'); + equals(element.attr('tabindex'), 0, 'set tabindex to 0 (string)'); // set a negative string - element.attr("tabindex", "-1"); - equals(element.attr("tabindex"), -1, "set tabindex to -1 (string)"); + element.attr('tabindex', '-1'); + equals(element.attr('tabindex'), -1, 'set tabindex to -1 (string)'); // set a positive number - element.attr("tabindex", 1); - equals(element.attr("tabindex"), 1, "set tabindex to 1 (number)"); + element.attr('tabindex', 1); + equals(element.attr('tabindex'), 1, 'set tabindex to 1 (number)'); // set a zero number - element.attr("tabindex", 0); - equals(element.attr("tabindex"), 0, "set tabindex to 0 (number)"); + element.attr('tabindex', 0); + equals(element.attr('tabindex'), 0, 'set tabindex to 0 (number)'); // set a negative number - element.attr("tabindex", -1); - equals(element.attr("tabindex"), -1, "set tabindex to -1 (number)"); + element.attr('tabindex', -1); + equals(element.attr('tabindex'), -1, 'set tabindex to -1 (number)'); - element = jQuery("#linkWithTabIndex"); - equals(element.attr("tabindex"), 2, "start with tabindex 2"); + element = jQuery('#linkWithTabIndex'); + equals(element.attr('tabindex'), 2, 'start with tabindex 2'); - element.attr("tabindex", -1); - equals(element.attr("tabindex"), -1, "set negative tabindex"); + element.attr('tabindex', -1); + equals(element.attr('tabindex'), -1, 'set negative tabindex'); }); test("removeAttr(String)", function() { expect(7); - equals( jQuery("#mark").removeAttr( "class" )[0].className, "", "remove class" ); - equals( jQuery("#form").removeAttr("id").attr("id"), undefined, "Remove id" ); - equals( jQuery("#foo").attr("style", "position:absolute;").removeAttr("style").attr("style"), undefined, "Check removing style attribute" ); - equals( jQuery("#form").attr("style", "position:absolute;").removeAttr("style").attr("style"), undefined, "Check removing style attribute on a form" ); - equals( jQuery("#fx-test-group").attr("height", "3px").removeAttr("height").css("height"), "1px", "Removing height attribute has no effect on height set with style attribute" ); - - jQuery("#check1").removeAttr("checked").prop("checked", true).removeAttr("checked"); - equals( document.getElementById("check1").checked, false, "removeAttr sets boolean properties to false" ); - jQuery("#text1").prop("readOnly", true).removeAttr("readonly"); - equals( document.getElementById("text1").readOnly, false, "removeAttr sets boolean properties to false" ); -}); - -test("prop(String, Object)", function() { - expect(30); - - equals( jQuery("#text1").prop("value"), "Test", "Check for value attribute" ); - equals( jQuery("#text1").prop("value", "Test2").prop("defaultValue"), "Test", "Check for defaultValue attribute" ); - equals( jQuery("#select2").prop("selectedIndex"), 3, "Check for selectedIndex attribute" ); - equals( jQuery("#foo").prop("nodeName").toUpperCase(), "DIV", "Check for nodeName attribute" ); - equals( jQuery("#foo").prop("tagName").toUpperCase(), "DIV", "Check for tagName attribute" ); - equals( jQuery(""); - $select1.val(valueObj( 4 )); - equals( $select1.val(), "4", "Should be possible to set the val() to a newly created option" ); + jQuery("#select1").append(""); + jQuery("#select1").val(valueObj( 4 )); + equals( jQuery("#select1").val(), "4", "Should be possible to set the val() to a newly created option" ); // using contents will get comments regular, text, and comment nodes var j = jQuery("#nonnodes").contents(); @@ -680,8 +485,8 @@ test("val(Function)", function() { test( "val(Array of Numbers) (Bug #7123)", function() { expect(4); - jQuery("#form").append(""); - var elements = jQuery("input[name=arrayTest]").val([ 1, 2 ]); + jQuery('#form').append(''); + var elements = jQuery('input[name=arrayTest]').val([ 1, 2 ]); ok( elements[0].checked, "First element was checked" ); ok( elements[1].checked, "Second element was checked" ); ok( !elements[2].checked, "Third element was unchecked" ); @@ -693,7 +498,6 @@ test( "val(Array of Numbers) (Bug #7123)", function() { test("val(Function) with incoming value", function() { expect(10); - QUnit.reset(); var oldVal = jQuery("#text1").val(); jQuery("#text1").val(function(i, val) { @@ -701,7 +505,7 @@ test("val(Function) with incoming value", function() { return "test"; }); - equals( document.getElementById("text1").value, "test", "Check for modified (via val(String)) value of input element" ); + equals( document.getElementById('text1').value, "test", "Check for modified (via val(String)) value of input element" ); oldVal = jQuery("#text1").val(); @@ -710,7 +514,7 @@ test("val(Function) with incoming value", function() { return 67; }); - equals( document.getElementById("text1").value, "67", "Check for modified (via val(Number)) value of input element" ); + equals( document.getElementById('text1').value, "67", "Check for modified (via val(Number)) value of input element" ); oldVal = jQuery("#select1").val(); @@ -746,7 +550,7 @@ test("val(Function) with incoming value", function() { test("val(select) after form.reset() (Bug #2551)", function() { expect(3); - jQuery("
    ").appendTo("#qunit-fixture"); + jQuery('
    ').appendTo("#main"); jQuery("#kkk").val( "gf" ); @@ -756,21 +560,18 @@ test("val(select) after form.reset() (Bug #2551)", function() { equal( jQuery("#kkk").val(), "cf", "Check value of select after form reset." ); // re-verify the multi-select is not broken (after form.reset) by our fix for single-select - same( jQuery("#select3").val(), ["1", "2"], "Call val() on a multiple=\"multiple\" select" ); + same( jQuery('#select3').val(), ['1', '2'], 'Call val() on a multiple="multiple" select' ); jQuery("#kk").remove(); }); var testAddClass = function(valueObj) { - expect(9); - + expect(5); var div = jQuery("div"); div.addClass( valueObj("test") ); var pass = true; for ( var i = 0; i < div.size(); i++ ) { - if ( !~div.get(i).className.indexOf("test") ) { - pass = false; - } + if ( div.get(i).className.indexOf("test") == -1 ) pass = false; } ok( pass, "Add Class" ); @@ -791,19 +592,6 @@ var testAddClass = function(valueObj) { div.attr("class", "foo"); div.addClass( valueObj("bar baz") ); equals( div.attr("class"), "foo bar baz", "Make sure there isn't too much trimming." ); - - div.removeClass(); - div.addClass( valueObj("foo") ).addClass( valueObj("foo") ) - equal( div.attr("class"), "foo", "Do not add the same class twice in separate calls." ); - - div.addClass( valueObj("fo") ); - equal( div.attr("class"), "foo fo", "Adding a similar class does not get interrupted." ); - div.removeClass().addClass("wrap2"); - ok( div.addClass("wrap").hasClass("wrap"), "Can add similarly named classes"); - - div.removeClass(); - div.addClass( valueObj("bar bar") ); - equal( div.attr("class"), "bar", "Do not add the same class twice in the same call." ); }; test("addClass(String)", function() { @@ -816,20 +604,21 @@ test("addClass(Function)", function() { test("addClass(Function) with incoming value", function() { expect(45); + var div = jQuery("div"), old = div.map(function(){ - return jQuery(this).attr("class") || ""; + return jQuery(this).attr("class"); }); - + div.addClass(function(i, val) { - if ( this.id !== "_firebugConsole") { + if ( this.id !== "_firebugConsole" ) { equals( val, old[i], "Make sure the incoming value is correct." ); return "test"; } }); var pass = true; - for ( var i = 0; i < div.length; i++ ) { - if ( div.get(i).className.indexOf("test") == -1 ) pass = false; + for ( var i = 0; i < div.size(); i++ ) { + if ( div.get(i).className.indexOf("test") == -1 ) pass = false; } ok( pass, "Add Class" ); }); @@ -837,29 +626,29 @@ test("addClass(Function) with incoming value", function() { var testRemoveClass = function(valueObj) { expect(7); - var $divs = jQuery("div"); + var $divs = jQuery('div'); $divs.addClass("test").removeClass( valueObj("test") ); - ok( !$divs.is(".test"), "Remove Class" ); + ok( !$divs.is('.test'), "Remove Class" ); QUnit.reset(); - $divs = jQuery("div"); + $divs = jQuery('div'); $divs.addClass("test").addClass("foo").addClass("bar"); $divs.removeClass( valueObj("test") ).removeClass( valueObj("bar") ).removeClass( valueObj("foo") ); - ok( !$divs.is(".test,.bar,.foo"), "Remove multiple classes" ); + ok( !$divs.is('.test,.bar,.foo'), "Remove multiple classes" ); QUnit.reset(); - $divs = jQuery("div"); + $divs = jQuery('div'); // Make sure that a null value doesn't cause problems $divs.eq(0).addClass("test").removeClass( valueObj(null) ); - ok( $divs.eq(0).is(".test"), "Null value passed to removeClass" ); + ok( $divs.eq(0).is('.test'), "Null value passed to removeClass" ); $divs.eq(0).addClass("test").removeClass( valueObj("") ); - ok( $divs.eq(0).is(".test"), "Empty string passed to removeClass" ); + ok( $divs.eq(0).is('.test'), "Empty string passed to removeClass" ); // using contents will get regular, text, and comment nodes var j = jQuery("#nonnodes").contents(); @@ -889,7 +678,7 @@ test("removeClass(Function) - simple", function() { test("removeClass(Function) with incoming value", function() { expect(45); - var $divs = jQuery("div").addClass("test"), old = $divs.map(function(){ + var $divs = jQuery('div').addClass("test"), old = $divs.map(function(){ return jQuery(this).attr("class"); }); @@ -900,7 +689,7 @@ test("removeClass(Function) with incoming value", function() { } }); - ok( !$divs.is(".test"), "Remove Class" ); + ok( !$divs.is('.test'), "Remove Class" ); QUnit.reset(); }); @@ -938,7 +727,7 @@ var testToggleClass = function(valueObj) { ok( e.is(".testD.testE"), "Assert class present" ); e.toggleClass(); ok( !e.is(".testD.testE"), "Assert class not present" ); - ok( jQuery._data(e[0], "__className__") === "testD testE", "Assert data was stored" ); + ok( jQuery._data(e[0], '__className__') === 'testD testE', "Assert data was stored" ); e.toggleClass(); ok( e.is(".testD.testE"), "Assert class present (restored from data)" ); e.toggleClass(false); @@ -952,7 +741,7 @@ var testToggleClass = function(valueObj) { // Cleanup e.removeClass("testD"); - jQuery.removeData(e[0], "__className__", true); + jQuery.removeData(e[0], '__className__', true); }; test("toggleClass(String|boolean|undefined[, boolean])", function() { @@ -966,7 +755,7 @@ test("toggleClass(Function[, boolean])", function() { test("toggleClass(Fucntion[, boolean]) with incoming value", function() { expect(14); - var e = jQuery("#firstp"), old = e.attr("class") || ""; + var e = jQuery("#firstp"), old = e.attr("class"); ok( !e.is(".test"), "Assert class not present" ); e.toggleClass(function(i, val) { @@ -1013,7 +802,7 @@ test("toggleClass(Fucntion[, boolean]) with incoming value", function() { // Cleanup e.removeClass("test"); - jQuery.removeData(e[0], "__className__", true); + jQuery.removeData(e[0], '__className__', true); }); test("addClass, removeClass, hasClass", function() { diff --git a/test/unit/core.js b/test/unit/core.js index 3a155352..bce0de0f 100644 --- a/test/unit/core.js +++ b/test/unit/core.js @@ -12,7 +12,7 @@ test("Basic requirements", function() { }); test("jQuery()", function() { - expect(29); + expect(24); // Basic constructor's behavior @@ -20,7 +20,6 @@ test("jQuery()", function() { equals( jQuery(undefined).length, 0, "jQuery(undefined) === jQuery([])" ); equals( jQuery(null).length, 0, "jQuery(null) === jQuery([])" ); equals( jQuery("").length, 0, "jQuery('') === jQuery([])" ); - equals( jQuery("#").length, 0, "jQuery('#') === jQuery([])" ); var obj = jQuery("div"); equals( jQuery(obj).selector, "div", "jQuery(jQueryObj) == jQueryObj" ); @@ -29,7 +28,7 @@ test("jQuery()", function() { equals( jQuery(window).length, 1, "Correct number of elements generated for jQuery(window)" ); - var main = jQuery("#qunit-fixture"); + var main = jQuery("#main"); same( jQuery("div p", main).get(), q("sndp", "en", "sap"), "Basic selector with jQuery object as context" ); /* @@ -62,7 +61,7 @@ test("jQuery()", function() { equals( jQuery([1,2,3]).get(1), 2, "Test passing an array to the factory" ); - equals( jQuery(document.body).get(0), jQuery("body").get(0), "Test passing an html node to the factory" ); + equals( jQuery(document.body).get(0), jQuery('body').get(0), "Test passing an html node to the factory" ); var exec = false; @@ -75,13 +74,13 @@ test("jQuery()", function() { id: "test3" }); - equals( elem[0].style.width, "10px", "jQuery() quick setter width"); - equals( elem[0].style.paddingLeft, "1px", "jQuery quick setter css"); - equals( elem[0].style.paddingRight, "1px", "jQuery quick setter css"); - equals( elem[0].childNodes.length, 1, "jQuery quick setter text"); - equals( elem[0].firstChild.nodeValue, "test", "jQuery quick setter text"); - equals( elem[0].className, "test2", "jQuery() quick setter class"); - equals( elem[0].id, "test3", "jQuery() quick setter id"); + equals( elem[0].style.width, '10px', 'jQuery() quick setter width'); + equals( elem[0].style.paddingLeft, '1px', 'jQuery quick setter css'); + equals( elem[0].style.paddingRight, '1px', 'jQuery quick setter css'); + equals( elem[0].childNodes.length, 1, 'jQuery quick setter text'); + equals( elem[0].firstChild.nodeValue, "test", 'jQuery quick setter text'); + equals( elem[0].className, "test2", 'jQuery() quick setter class'); + equals( elem[0].id, "test3", 'jQuery() quick setter id'); exec = true; elem.click(); @@ -96,17 +95,6 @@ test("jQuery()", function() { // manually clean up detached elements elem.remove(); - - equals( jQuery("
    ").length, 1, "Make sure whitespace is trimmed." ); - equals( jQuery(" a
    b ").length, 1, "Make sure whitespace and other characters are trimmed." ); - - var long = ""; - for ( var i = 0; i < 128; i++ ) { - long += "12345678"; - } - - equals( jQuery("
    " + long + "
    ").length, 1, "Make sure whitespace is trimmed on long strings." ); - equals( jQuery(" a
    " + long + "
    b ").length, 1, "Make sure whitespace and other characters are trimmed on long strings." ); }); test("selector state", function() { @@ -126,54 +114,54 @@ test("selector state", function() { equals( test.selector, "", "Body Selector" ); equals( test.context, document.body, "Body Context" ); - test = jQuery("#qunit-fixture"); - equals( test.selector, "#qunit-fixture", "#qunit-fixture Selector" ); - equals( test.context, document, "#qunit-fixture Context" ); + test = jQuery("#main"); + equals( test.selector, "#main", "#main Selector" ); + equals( test.context, document, "#main Context" ); test = jQuery("#notfoundnono"); equals( test.selector, "#notfoundnono", "#notfoundnono Selector" ); equals( test.context, document, "#notfoundnono Context" ); - test = jQuery("#qunit-fixture", document); - equals( test.selector, "#qunit-fixture", "#qunit-fixture Selector" ); - equals( test.context, document, "#qunit-fixture Context" ); + test = jQuery("#main", document); + equals( test.selector, "#main", "#main Selector" ); + equals( test.context, document, "#main Context" ); - test = jQuery("#qunit-fixture", document.body); - equals( test.selector, "#qunit-fixture", "#qunit-fixture Selector" ); - equals( test.context, document.body, "#qunit-fixture Context" ); + test = jQuery("#main", document.body); + equals( test.selector, "#main", "#main Selector" ); + equals( test.context, document.body, "#main Context" ); // Test cloning test = jQuery(test); - equals( test.selector, "#qunit-fixture", "#qunit-fixture Selector" ); - equals( test.context, document.body, "#qunit-fixture Context" ); + equals( test.selector, "#main", "#main Selector" ); + equals( test.context, document.body, "#main Context" ); - test = jQuery(document.body).find("#qunit-fixture"); - equals( test.selector, "#qunit-fixture", "#qunit-fixture find Selector" ); - equals( test.context, document.body, "#qunit-fixture find Context" ); + test = jQuery(document.body).find("#main"); + equals( test.selector, "#main", "#main find Selector" ); + equals( test.context, document.body, "#main find Context" ); - test = jQuery("#qunit-fixture").filter("div"); - equals( test.selector, "#qunit-fixture.filter(div)", "#qunit-fixture filter Selector" ); - equals( test.context, document, "#qunit-fixture filter Context" ); + test = jQuery("#main").filter("div"); + equals( test.selector, "#main.filter(div)", "#main filter Selector" ); + equals( test.context, document, "#main filter Context" ); - test = jQuery("#qunit-fixture").not("div"); - equals( test.selector, "#qunit-fixture.not(div)", "#qunit-fixture not Selector" ); - equals( test.context, document, "#qunit-fixture not Context" ); + test = jQuery("#main").not("div"); + equals( test.selector, "#main.not(div)", "#main not Selector" ); + equals( test.context, document, "#main not Context" ); - test = jQuery("#qunit-fixture").filter("div").not("div"); - equals( test.selector, "#qunit-fixture.filter(div).not(div)", "#qunit-fixture filter, not Selector" ); - equals( test.context, document, "#qunit-fixture filter, not Context" ); + test = jQuery("#main").filter("div").not("div"); + equals( test.selector, "#main.filter(div).not(div)", "#main filter, not Selector" ); + equals( test.context, document, "#main filter, not Context" ); - test = jQuery("#qunit-fixture").filter("div").not("div").end(); - equals( test.selector, "#qunit-fixture.filter(div)", "#qunit-fixture filter, not, end Selector" ); - equals( test.context, document, "#qunit-fixture filter, not, end Context" ); + test = jQuery("#main").filter("div").not("div").end(); + equals( test.selector, "#main.filter(div)", "#main filter, not, end Selector" ); + equals( test.context, document, "#main filter, not, end Context" ); - test = jQuery("#qunit-fixture").parent("body"); - equals( test.selector, "#qunit-fixture.parent(body)", "#qunit-fixture parent Selector" ); - equals( test.context, document, "#qunit-fixture parent Context" ); + test = jQuery("#main").parent("body"); + equals( test.selector, "#main.parent(body)", "#main parent Selector" ); + equals( test.context, document, "#main parent Context" ); - test = jQuery("#qunit-fixture").eq(0); - equals( test.selector, "#qunit-fixture.slice(0,1)", "#qunit-fixture eq Selector" ); - equals( test.context, document, "#qunit-fixture eq Context" ); + test = jQuery("#main").eq(0); + equals( test.selector, "#main.slice(0,1)", "#main eq Selector" ); + equals( test.context, document, "#main eq Context" ); var d = "
    "; equals( @@ -183,26 +171,6 @@ test("selector state", function() { ); }); -test( "globalEval", function() { - - expect( 3 ); - - jQuery.globalEval( "var globalEvalTest = true;" ); - ok( window.globalEvalTest, "Test variable declarations are global" ); - - window.globalEvalTest = false; - - jQuery.globalEval( "globalEvalTest = true;" ); - ok( window.globalEvalTest, "Test variable assignments are global" ); - - window.globalEvalTest = false; - - jQuery.globalEval( "this.globalEvalTest = true;" ); - ok( window.globalEvalTest, "Test context (this) is the window object" ); - - window.globalEvalTest = undefined; -}); - if ( !isLocal ) { test("browser", function() { stop(); @@ -239,7 +207,7 @@ test("noConflict", function() { equals( jQuery.noConflict(true), $$, "noConflict returned the jQuery object" ); equals( jQuery, originaljQuery, "Make sure jQuery was reverted." ); equals( $, original$, "Make sure $ was reverted." ); - ok( $$("#qunit-fixture").html("test"), "Make sure that jQuery still works." ); + ok( $$("#main").html("test"), "Make sure that jQuery still works." ); jQuery = $$; }); @@ -471,7 +439,7 @@ if ( !isLocal ) { test("isXMLDoc - XML", function() { expect(3); stop(); - jQuery.get("data/dashboard.xml", function(xml) { + jQuery.get('data/dashboard.xml', function(xml) { ok( jQuery.isXMLDoc( xml ), "XML document" ); ok( jQuery.isXMLDoc( xml.documentElement ), "XML documentElement" ); ok( jQuery.isXMLDoc( jQuery("tab", xml)[0] ), "XML Tab Element" ); @@ -500,7 +468,7 @@ test("isWindow", function() { }); test("jQuery('html')", function() { - expect(18); + expect(15); QUnit.reset(); jQuery.foo = false; @@ -532,19 +500,6 @@ test("jQuery('html')", function() { ok( jQuery("
    ")[0], "Create a div with closing tag." ); ok( jQuery("
    ")[0], "Create a table with closing tag." ); - - // Test very large html string #7990 - var i; - var li = "
  • very large html string
  • "; - var html = ["
      "]; - for ( i = 0; i < 50000; i += 1 ) { - html.push(li); - } - html.push("
    "); - html = jQuery(html.join(""))[0]; - equals( html.nodeName.toUpperCase(), "UL"); - equals( html.firstChild.nodeName.toUpperCase(), "LI"); - equals( html.childNodes.length, 50000 ); }); test("jQuery('html', context)", function() { @@ -559,7 +514,7 @@ if ( !isLocal ) { test("jQuery(selector, xml).text(str) - Loaded via XML document", function() { expect(2); stop(); - jQuery.get("data/dashboard.xml", function(xml) { + jQuery.get('data/dashboard.xml', function(xml) { // tests for #1419 where IE was a problem var tab = jQuery("tab", xml).eq(0); equals( tab.text(), "blabla", "Verify initial text correct" ); @@ -572,39 +527,39 @@ test("jQuery(selector, xml).text(str) - Loaded via XML document", function() { test("end()", function() { expect(3); - equals( "Yahoo", jQuery("#yahoo").parent().end().text(), "Check for end" ); - ok( jQuery("#yahoo").end(), "Check for end with nothing to end" ); + equals( 'Yahoo', jQuery('#yahoo').parent().end().text(), 'Check for end' ); + ok( jQuery('#yahoo').end(), 'Check for end with nothing to end' ); - var x = jQuery("#yahoo"); + var x = jQuery('#yahoo'); x.parent(); - equals( "Yahoo", jQuery("#yahoo").text(), "Check for non-destructive behaviour" ); + equals( 'Yahoo', jQuery('#yahoo').text(), 'Check for non-destructive behaviour' ); }); test("length", function() { expect(1); - equals( jQuery("#qunit-fixture p").length, 6, "Get Number of Elements Found" ); + equals( jQuery("#main p").length, 6, "Get Number of Elements Found" ); }); test("size()", function() { expect(1); - equals( jQuery("#qunit-fixture p").size(), 6, "Get Number of Elements Found" ); + equals( jQuery("#main p").size(), 6, "Get Number of Elements Found" ); }); test("get()", function() { expect(1); - same( jQuery("#qunit-fixture p").get(), q("firstp","ap","sndp","en","sap","first"), "Get All Elements" ); + same( jQuery("#main p").get(), q("firstp","ap","sndp","en","sap","first"), "Get All Elements" ); }); test("toArray()", function() { expect(1); - same( jQuery("#qunit-fixture p").toArray(), + same( jQuery("#main p").toArray(), q("firstp","ap","sndp","en","sap","first"), "Convert jQuery object to an Array" ) }) test("get(Number)", function() { expect(2); - equals( jQuery("#qunit-fixture p").get(0), document.getElementById("firstp"), "Get A Single Element" ); + equals( jQuery("#main p").get(0), document.getElementById("firstp"), "Get A Single Element" ); strictEqual( jQuery("#firstp").get(1), undefined, "Try get with index larger elements count" ); }); @@ -617,7 +572,7 @@ test("get(-Number)",function() { test("each(Function)", function() { expect(1); var div = jQuery("div"); - div.each(function(){this.foo = "zoo";}); + div.each(function(){this.foo = 'zoo';}); var pass = true; for ( var i = 0; i < div.size(); i++ ) { if ( div.get(i).foo != "zoo" ) pass = false; @@ -636,7 +591,7 @@ test("slice()", function() { same( $links.slice(-1).get(), q("mark"), "slice(-1)" ); same( $links.eq(1).get(), q("groups"), "eq(1)" ); - same( $links.eq("2").get(), q("anchor1"), "eq('2')" ); + same( $links.eq('2').get(), q("anchor1"), "eq('2')" ); same( $links.eq(-1).get(), q("mark"), "eq(-1)" ); }); @@ -653,7 +608,7 @@ test("first()/last()", function() { }); test("map()", function() { - expect(8); + expect(2);//expect(6); same( jQuery("#ap").map(function(){ @@ -671,38 +626,32 @@ test("map()", function() { "Single Map" ); + return;//these haven't been accepted yet + //for #2616 var keys = jQuery.map( {a:1,b:2}, function( v, k ){ return k; - }); + }, [ ] ); + equals( keys.join(""), "ab", "Map the keys from a hash to an array" ); var values = jQuery.map( {a:1,b:2}, function( v, k ){ return v; - }); - equals( values.join(""), "12", "Map the values from a hash to an array" ); + }, [ ] ); - // object with length prop - var values = jQuery.map( {a:1,b:2, length:3}, function( v, k ){ - return v; - }); - equals( values.join(""), "123", "Map the values from a hash with a length property to an array" ); + equals( values.join(""), "12", "Map the values from a hash to an array" ); var scripts = document.getElementsByTagName("script"); var mapped = jQuery.map( scripts, function( v, k ){ return v; - }); - equals( mapped.length, scripts.length, "Map an array(-like) to a hash" ); + }, {length:0} ); - var nonsense = document.getElementsByTagName("asdf"); - var mapped = jQuery.map( nonsense, function( v, k ){ - return v; - }); - equals( mapped.length, nonsense.length, "Map an empty array(-like) to a hash" ); + equals( mapped.length, scripts.length, "Map an array(-like) to a hash" ); var flat = jQuery.map( Array(4), function( v, k ){ return k % 2 ? k : [k,k,k];//try mixing array and regular returns }); + equals( flat.join(""), "00012223", "try the new flatten technique(#2616)" ); }); @@ -809,7 +758,7 @@ test("jQuery.extend(Object, Object)", function() { ok( typeof ret.foo != "string", "Check to make sure values equal with coersion (but not actually equal) overwrite correctly" ); var ret = jQuery.extend(true, { foo:"bar" }, { foo:null } ); - ok( typeof ret.foo !== "undefined", "Make sure a null value doesn't crash with deep extend, for #1908" ); + ok( typeof ret.foo !== 'undefined', "Make sure a null value doesn't crash with deep extend, for #1908" ); var obj = { foo:null }; jQuery.extend(true, obj, { foo:"notnull" } ); @@ -835,7 +784,7 @@ test("jQuery.extend(Object, Object)", function() { }); test("jQuery.each(Object,Function)", function() { - expect(14); + expect(13); jQuery.each( [0,1,2], function(i, n){ equals( i, n, "Check array iteration" ); }); @@ -862,24 +811,17 @@ test("jQuery.each(Object,Function)", function() { equals( total, 3, "Looping over an object, with break" ); var f = function(){}; - f.foo = "bar"; + f.foo = 'bar'; jQuery.each(f, function(i){ - f[i] = "baz"; + f[i] = 'baz'; }); equals( "baz", f.foo, "Loop over a function" ); - - var stylesheet_count = 0; - jQuery.each(document.styleSheets, function(i){ - stylesheet_count++; - }); - equals(stylesheet_count, 2, "should not throw an error in IE while looping over document.styleSheets and return proper amount"); - }); test("jQuery.makeArray", function(){ expect(17); - equals( jQuery.makeArray(jQuery("html>*"))[0].nodeName.toUpperCase(), "HEAD", "Pass makeArray a jQuery object" ); + equals( jQuery.makeArray(jQuery('html>*'))[0].nodeName.toUpperCase(), "HEAD", "Pass makeArray a jQuery object" ); equals( jQuery.makeArray(document.getElementsByName("PWD")).slice(0,1)[0].name, "PWD", "Pass makeArray a nodelist" ); @@ -909,11 +851,11 @@ test("jQuery.makeArray", function(){ equals( jQuery.makeArray(/a/)[0].constructor, RegExp, "Pass makeArray a regex" ); - ok( jQuery.makeArray(document.getElementById("form")).length >= 13, "Pass makeArray a form (treat as elements)" ); + ok( jQuery.makeArray(document.getElementById('form')).length >= 13, "Pass makeArray a form (treat as elements)" ); // For #5610 - same( jQuery.makeArray({length: "0"}), [], "Make sure object is coerced properly."); - same( jQuery.makeArray({length: "5"}), [], "Make sure object is coerced properly."); + same( jQuery.makeArray({'length': '0'}), [], "Make sure object is coerced properly."); + same( jQuery.makeArray({'length': '5'}), [], "Make sure object is coerced properly."); }); test("jQuery.isEmptyObject", function(){ @@ -927,7 +869,7 @@ test("jQuery.isEmptyObject", function(){ }); test("jQuery.proxy", function(){ - expect(7); + expect(4); var test = function(){ equals( this, thisObject, "Make sure that scope is set properly." ); }; var thisObject = { foo: "bar", method: test }; @@ -938,23 +880,11 @@ test("jQuery.proxy", function(){ // Basic scoping jQuery.proxy( test, thisObject )(); - // Another take on it - jQuery.proxy( thisObject, "method" )(); - // Make sure it doesn't freak out equals( jQuery.proxy( null, thisObject ), undefined, "Make sure no function was returned." ); - // Partial application - var test2 = function( a ){ equals( a, "pre-applied", "Ensure arguments can be pre-applied." ); }; - jQuery.proxy( test2, null, "pre-applied" )(); - - // Partial application w/ normal arguments - var test3 = function( a, b ){ equals( b, "normal", "Ensure arguments can be pre-applied and passed as usual." ); }; - jQuery.proxy( test3, null, "pre-applied" )( "normal" ); - - // Test old syntax - var test4 = { meth: function( a ){ equals( a, "boom", "Ensure old syntax works." ); } }; - jQuery.proxy( test4, "meth" )( "boom" ); + // Use the string shortcut + jQuery.proxy( thisObject, "method" )(); }); test("jQuery.parseJSON", function(){ @@ -965,9 +895,9 @@ test("jQuery.parseJSON", function(){ equals( jQuery.parseJSON( "" ), null, "Nothing in, null out." ); same( jQuery.parseJSON("{}"), {}, "Plain object parsing." ); - same( jQuery.parseJSON("{\"test\":1}"), {"test":1}, "Plain object parsing." ); + same( jQuery.parseJSON('{"test":1}'), {"test":1}, "Plain object parsing." ); - same( jQuery.parseJSON("\n{\"test\":1}"), {"test":1}, "Make sure leading whitespaces are handled." ); + same( jQuery.parseJSON('\n{"test":1}'), {"test":1}, "Make sure leading whitespaces are handled." ); try { jQuery.parseJSON("{a:1}"); @@ -984,6 +914,221 @@ test("jQuery.parseJSON", function(){ } }); +test("jQuery._Deferred()", function() { + + expect( 10 ); + + var deferred, + object, + test; + + deferred = jQuery._Deferred(); + + test = false; + + deferred.done( function( value ) { + equals( value , "value" , "Test pre-resolve callback" ); + test = true; + } ); + + deferred.resolve( "value" ); + + ok( test , "Test pre-resolve callbacks called right away" ); + + test = false; + + deferred.done( function( value ) { + equals( value , "value" , "Test post-resolve callback" ); + test = true; + } ); + + ok( test , "Test post-resolve callbacks called right away" ); + + deferred.cancel(); + + test = true; + + deferred.done( function() { + ok( false , "Cancel was ignored" ); + test = false; + } ); + + ok( test , "Test cancel" ); + + deferred = jQuery._Deferred().resolve(); + + try { + deferred.done( function() { + throw "Error"; + } , function() { + ok( true , "Test deferred do not cancel on exception" ); + } ); + } catch( e ) { + strictEqual( e , "Error" , "Test deferred propagates exceptions"); + deferred.done(); + } + + test = ""; + deferred = jQuery._Deferred().done( function() { + + test += "A"; + + }, function() { + + test += "B"; + + } ).resolve(); + + strictEqual( test , "AB" , "Test multiple done parameters" ); + + test = ""; + + deferred.done( function() { + + deferred.done( function() { + + test += "C"; + + } ); + + test += "A"; + + }, function() { + + test += "B"; + } ); + + strictEqual( test , "ABC" , "Test done callbacks order" ); + + deferred = jQuery._Deferred(); + + deferred.resolveWith( jQuery , [ document ] ).done( function( doc ) { + ok( this === jQuery && arguments.length === 1 && doc === document , "Test fire context & args" ); + }); +}); + +test("jQuery.Deferred()", function() { + + expect( 10 ); + + jQuery.Deferred( function( defer ) { + strictEqual( this , defer , "Defer passed as this & first argument" ); + this.resolve( "done" ); + }).then( function( value ) { + strictEqual( value , "done" , "Passed function executed" ); + }); + + jQuery.Deferred().resolve().then( function() { + ok( true , "Success on resolve" ); + }, function() { + ok( false , "Error on resolve" ); + }); + + jQuery.Deferred().reject().then( function() { + ok( false , "Success on reject" ); + }, function() { + ok( true , "Error on reject" ); + }); + + ( new jQuery.Deferred( function( defer ) { + strictEqual( this , defer , "Defer passed as this & first argument (new)" ); + this.resolve( "done" ); + }) ).then( function( value ) { + strictEqual( value , "done" , "Passed function executed (new)" ); + }); + + ( new jQuery.Deferred() ).resolve().then( function() { + ok( true , "Success on resolve (new)" ); + }, function() { + ok( false , "Error on resolve (new)" ); + }); + + ( new jQuery.Deferred() ).reject().then( function() { + ok( false , "Success on reject (new)" ); + }, function() { + ok( true , "Error on reject (new)" ); + }); + + var tmp = jQuery.Deferred(); + + strictEqual( tmp.promise() , tmp.promise() , "Test deferred always return same promise" ); + strictEqual( tmp.promise() , tmp.promise().promise() , "Test deferred's promise always return same promise as deferred" ); +}); + +test("jQuery.when()", function() { + + expect( 23 ); + + // Some other objects + jQuery.each( { + + "an empty string": "", + "a non-empty string": "some string", + "zero": 0, + "a number other than zero": 1, + "true": true, + "false": false, + "null": null, + "undefined": undefined, + "a plain object": {} + + } , function( message , value ) { + + ok( jQuery.isFunction( jQuery.when( value ).then( function( resolveValue ) { + strictEqual( resolveValue , value , "Test the promise was resolved with " + message ); + } ).promise ) , "Test " + message + " triggers the creation of a new Promise" ); + + } ); + + ok( jQuery.isFunction( jQuery.when().then( function( resolveValue ) { + strictEqual( resolveValue , undefined , "Test the promise was resolved with no parameter" ); + } ).promise ) , "Test calling when with no parameter triggers the creation of a new Promise" ); + + var cache, i; + + for( i = 1 ; i < 4 ; i++ ) { + jQuery.when( cache || jQuery.Deferred( function() { + this.resolve( i ); + }) ).then( function( value ) { + strictEqual( value , 1 , "Function executed" + ( i > 1 ? " only once" : "" ) ); + cache = value; + }, function() { + ok( false , "Fail called" ); + }); + } +}); + +test("jQuery.when() - joined", function() { + + expect(8); + + jQuery.when( 1, 2, 3 ).done( function( a, b, c ) { + strictEqual( a , 1 , "Test first param is first resolved value - non-observables" ); + strictEqual( b , 2 , "Test second param is second resolved value - non-observables" ); + strictEqual( c , 3 , "Test third param is third resolved value - non-observables" ); + }).fail( function() { + ok( false , "Test the created deferred was resolved - non-observables"); + }); + + var successDeferred = jQuery.Deferred().resolve( 1 , 2 , 3 ), + errorDeferred = jQuery.Deferred().reject( "error" , "errorParam" ); + + jQuery.when( 1 , successDeferred , 3 ).done( function( a, b, c ) { + strictEqual( a , 1 , "Test first param is first resolved value - resolved observable" ); + same( b , [ 1 , 2 , 3 ] , "Test second param is second resolved value - resolved observable" ); + strictEqual( c , 3 , "Test third param is third resolved value - resolved observable" ); + }).fail( function() { + ok( false , "Test the created deferred was resolved - resolved observable"); + }); + + jQuery.when( 1 , errorDeferred , 3 ).done( function() { + ok( false , "Test the created deferred was rejected - rejected observable"); + }).fail( function( error , errorParam ) { + strictEqual( error , "error" , "Test first param is first rejected value - rejected observable" ); + strictEqual( errorParam , "errorParam" , "Test second param is second rejected value - rejected observable" ); + }); +}); + test("jQuery.sub() - Static Methods", function(){ expect(18); var Subclass = jQuery.sub(); @@ -991,46 +1136,46 @@ test("jQuery.sub() - Static Methods", function(){ topLevelMethod: function() {return this.debug;}, debug: false, config: { - locale: "en_US" + locale: 'en_US' }, setup: function(config) { this.extend(true, this.config, config); } }); Subclass.fn.extend({subClassMethod: function() { return this;}}); - + //Test Simple Subclass - ok(Subclass.topLevelMethod() === false, "Subclass.topLevelMethod thought debug was true"); - ok(Subclass.config.locale == "en_US", Subclass.config.locale + " is wrong!"); - same(Subclass.config.test, undefined, "Subclass.config.test is set incorrectly"); - equal(jQuery.ajax, Subclass.ajax, "The subclass failed to get all top level methods"); - + ok(Subclass.topLevelMethod() === false, 'Subclass.topLevelMethod thought debug was true'); + ok(Subclass.config.locale == 'en_US', Subclass.config.locale + ' is wrong!'); + same(Subclass.config.test, undefined, 'Subclass.config.test is set incorrectly'); + equal(jQuery.ajax, Subclass.ajax, 'The subclass failed to get all top level methods'); + //Create a SubSubclass var SubSubclass = Subclass.sub(); - + //Make Sure the SubSubclass inherited properly - ok(SubSubclass.topLevelMethod() === false, "SubSubclass.topLevelMethod thought debug was true"); - ok(SubSubclass.config.locale == "en_US", SubSubclass.config.locale + " is wrong!"); - same(SubSubclass.config.test, undefined, "SubSubclass.config.test is set incorrectly"); - equal(jQuery.ajax, SubSubclass.ajax, "The subsubclass failed to get all top level methods"); + ok(SubSubclass.topLevelMethod() === false, 'SubSubclass.topLevelMethod thought debug was true'); + ok(SubSubclass.config.locale == 'en_US', SubSubclass.config.locale + ' is wrong!'); + same(SubSubclass.config.test, undefined, 'SubSubclass.config.test is set incorrectly'); + equal(jQuery.ajax, SubSubclass.ajax, 'The subsubclass failed to get all top level methods'); //Modify The Subclass and test the Modifications SubSubclass.fn.extend({subSubClassMethod: function() { return this;}}); - SubSubclass.setup({locale: "es_MX", test: "worked"}); + SubSubclass.setup({locale: 'es_MX', test: 'worked'}); SubSubclass.debug = true; SubSubclass.ajax = function() {return false;}; - ok(SubSubclass.topLevelMethod(), "SubSubclass.topLevelMethod thought debug was false"); - same(SubSubclass(document).subClassMethod, Subclass.fn.subClassMethod, "Methods Differ!"); - ok(SubSubclass.config.locale == "es_MX", SubSubclass.config.locale + " is wrong!"); - ok(SubSubclass.config.test == "worked", "SubSubclass.config.test is set incorrectly"); - notEqual(jQuery.ajax, SubSubclass.ajax, "The subsubclass failed to get all top level methods"); - + ok(SubSubclass.topLevelMethod(), 'SubSubclass.topLevelMethod thought debug was false'); + same(SubSubclass(document).subClassMethod, Subclass.fn.subClassMethod, 'Methods Differ!'); + ok(SubSubclass.config.locale == 'es_MX', SubSubclass.config.locale + ' is wrong!'); + ok(SubSubclass.config.test == 'worked', 'SubSubclass.config.test is set incorrectly'); + notEqual(jQuery.ajax, SubSubclass.ajax, 'The subsubclass failed to get all top level methods'); + //This shows that the modifications to the SubSubClass did not bubble back up to it's superclass - ok(Subclass.topLevelMethod() === false, "Subclass.topLevelMethod thought debug was true"); - ok(Subclass.config.locale == "en_US", Subclass.config.locale + " is wrong!"); - same(Subclass.config.test, undefined, "Subclass.config.test is set incorrectly"); - same(Subclass(document).subSubClassMethod, undefined, "subSubClassMethod set incorrectly"); - equal(jQuery.ajax, Subclass.ajax, "The subclass failed to get all top level methods"); + ok(Subclass.topLevelMethod() === false, 'Subclass.topLevelMethod thought debug was true'); + ok(Subclass.config.locale == 'en_US', Subclass.config.locale + ' is wrong!'); + same(Subclass.config.test, undefined, 'Subclass.config.test is set incorrectly'); + same(Subclass(document).subSubClassMethod, undefined, 'subSubClassMethod set incorrectly'); + equal(jQuery.ajax, Subclass.ajax, 'The subclass failed to get all top level methods'); }); test("jQuery.sub() - .fn Methods", function(){ @@ -1041,25 +1186,25 @@ test("jQuery.sub() - .fn Methods", function(){ jQueryDocument = jQuery(document), selectors, contexts, methods, method, arg, description; - jQueryDocument.toString = function(){ return "jQueryDocument"; }; + jQueryDocument.toString = function(){ return 'jQueryDocument'; }; Subclass.fn.subclassMethod = function(){}; SubclassSubclass.fn.subclassSubclassMethod = function(){}; selectors = [ - "body", - "html, body", - "
    " + 'body', + 'html, body', + '
    ' ]; methods = [ // all methods that return a new jQuery instance - ["eq", 1], - ["add", document], - ["end"], - ["has"], - ["closest", "div"], - ["filter", document], - ["find", "div"] + ['eq', 1], + ['add', document], + ['end'], + ['has'], + ['closest', 'div'], + ['filter', document], + ['find', 'div'] ]; contexts = [undefined, document, jQueryDocument]; @@ -1072,31 +1217,31 @@ test("jQuery.sub() - .fn Methods", function(){ jQuery.each(contexts, function(i, context){ - description = "(\""+selector+"\", "+context+")."+method+"("+(arg||"")+")"; + description = '("'+selector+'", '+context+').'+method+'('+(arg||'')+')'; same( jQuery(selector, context)[method](arg).subclassMethod, undefined, - "jQuery"+description+" doesn't have Subclass methods" + 'jQuery'+description+' doesnt have Subclass methods' ); same( jQuery(selector, context)[method](arg).subclassSubclassMethod, undefined, - "jQuery"+description+" doesn't have SubclassSubclass methods" + 'jQuery'+description+' doesnt have SubclassSubclass methods' ); same( Subclass(selector, context)[method](arg).subclassMethod, Subclass.fn.subclassMethod, - "Subclass"+description+" has Subclass methods" + 'Subclass'+description+' has Subclass methods' ); same( Subclass(selector, context)[method](arg).subclassSubclassMethod, undefined, - "Subclass"+description+" doesn't have SubclassSubclass methods" + 'Subclass'+description+' doesnt have SubclassSubclass methods' ); same( SubclassSubclass(selector, context)[method](arg).subclassMethod, Subclass.fn.subclassMethod, - "SubclassSubclass"+description+" has Subclass methods" + 'SubclassSubclass'+description+' has Subclass methods' ); same( SubclassSubclass(selector, context)[method](arg).subclassSubclassMethod, SubclassSubclass.fn.subclassSubclassMethod, - "SubclassSubclass"+description+" has SubclassSubclass methods" + 'SubclassSubclass'+description+' has SubclassSubclass methods' ); }); @@ -1104,17 +1249,3 @@ test("jQuery.sub() - .fn Methods", function(){ }); }); - -test("jQuery.camelCase()", function() { - - var tests = { - "foo-bar": "fooBar", - "foo-bar-baz": "fooBarBaz" - }; - - expect(2); - - jQuery.each( tests, function( key, val ) { - equal( jQuery.camelCase( key ), val, "Converts: " + key + " => " + val ); - }); -}); diff --git a/test/unit/css.js b/test/unit/css.js index f421f7bd..555f1357 100644 --- a/test/unit/css.js +++ b/test/unit/css.js @@ -1,15 +1,15 @@ module("css", { teardown: moduleTeardown }); test("css(String|Hash)", function() { - expect( 42 ); + expect(41); - equals( jQuery("#qunit-fixture").css("display"), "block", "Check for css property \"display\""); + equals( jQuery('#main').css("display"), 'block', 'Check for css property "display"'); - ok( jQuery("#nothiddendiv").is(":visible"), "Modifying CSS display: Assert element is visible"); - jQuery("#nothiddendiv").css({display: "none"}); - ok( !jQuery("#nothiddendiv").is(":visible"), "Modified CSS display: Assert element is hidden"); - jQuery("#nothiddendiv").css({display: "block"}); - ok( jQuery("#nothiddendiv").is(":visible"), "Modified CSS display: Assert element is visible"); + ok( jQuery('#nothiddendiv').is(':visible'), 'Modifying CSS display: Assert element is visible'); + jQuery('#nothiddendiv').css({display: 'none'}); + ok( !jQuery('#nothiddendiv').is(':visible'), 'Modified CSS display: Assert element is hidden'); + jQuery('#nothiddendiv').css({display: 'block'}); + ok( jQuery('#nothiddendiv').is(':visible'), 'Modified CSS display: Assert element is visible'); var div = jQuery( "
    " ); @@ -32,37 +32,34 @@ test("css(String|Hash)", function() { div2.remove(); // handle negative numbers by ignoring #1599, #4216 - jQuery("#nothiddendiv").css( {width: 1, height: 1} ); + jQuery('#nothiddendiv').css({ 'width': 1, 'height': 1 }); - var width = parseFloat(jQuery("#nothiddendiv").css("width")), height = parseFloat(jQuery("#nothiddendiv").css("height")); - jQuery("#nothiddendiv").css({ width: -1, height: -1 }); - equals( parseFloat(jQuery("#nothiddendiv").css("width")), width, "Test negative width ignored") - equals( parseFloat(jQuery("#nothiddendiv").css("height")), height, "Test negative height ignored") + var width = parseFloat(jQuery('#nothiddendiv').css('width')), height = parseFloat(jQuery('#nothiddendiv').css('height')); + jQuery('#nothiddendiv').css({ width: -1, height: -1 }); + equals( parseFloat(jQuery('#nothiddendiv').css('width')), width, 'Test negative width ignored') + equals( parseFloat(jQuery('#nothiddendiv').css('height')), height, 'Test negative height ignored') - equals( jQuery("
    ").css("display"), "none", "Styles on disconnected nodes"); + equals( jQuery('
    ').css('display'), 'none', 'Styles on disconnected nodes'); - jQuery("#floatTest").css({"float": "right"}); - equals( jQuery("#floatTest").css("float"), "right", "Modified CSS float using \"float\": Assert float is right"); - jQuery("#floatTest").css({"font-size": "30px"}); - equals( jQuery("#floatTest").css("font-size"), "30px", "Modified CSS font-size: Assert font-size is 30px"); - jQuery.each("0,0.25,0.5,0.75,1".split(","), function(i, n) { - jQuery("#foo").css({opacity: n}); + jQuery('#floatTest').css({'float': 'right'}); + equals( jQuery('#floatTest').css('float'), 'right', 'Modified CSS float using "float": Assert float is right'); + jQuery('#floatTest').css({'font-size': '30px'}); + equals( jQuery('#floatTest').css('font-size'), '30px', 'Modified CSS font-size: Assert font-size is 30px'); - equals( jQuery("#foo").css("opacity"), parseFloat(n), "Assert opacity is " + parseFloat(n) + " as a String" ); - jQuery("#foo").css({opacity: parseFloat(n)}); - equals( jQuery("#foo").css("opacity"), parseFloat(n), "Assert opacity is " + parseFloat(n) + " as a Number" ); + jQuery.each("0,0.25,0.5,0.75,1".split(','), function(i, n) { + jQuery('#foo').css({opacity: n}); + equals( jQuery('#foo').css('opacity'), parseFloat(n), "Assert opacity is " + parseFloat(n) + " as a String" ); + jQuery('#foo').css({opacity: parseFloat(n)}); + equals( jQuery('#foo').css('opacity'), parseFloat(n), "Assert opacity is " + parseFloat(n) + " as a Number" ); }); - jQuery("#foo").css({opacity: ""}); - equals( jQuery("#foo").css("opacity"), "1", "Assert opacity is 1 when set to an empty String" ); + jQuery('#foo').css({opacity: ''}); + equals( jQuery('#foo').css('opacity'), '1', "Assert opacity is 1 when set to an empty String" ); - equals( jQuery("#empty").css("opacity"), "0", "Assert opacity is accessible via filter property set in stylesheet in IE" ); - jQuery("#empty").css({ opacity: "1" }); - equals( jQuery("#empty").css("opacity"), "1", "Assert opacity is taken from style attribute when set vs stylesheet in IE with filters" ); - jQuery.support.opacity ? - ok(true, "Requires the same number of tests"): - ok( ~jQuery("#empty")[0].currentStyle.filter.indexOf("gradient"), "Assert setting opacity doesn't overwrite other filters of the stylesheet in IE" ); + equals( jQuery('#empty').css('opacity'), '0', "Assert opacity is accessible via filter property set in stylesheet in IE" ); + jQuery('#empty').css({ opacity: '1' }); + equals( jQuery('#empty').css('opacity'), '1', "Assert opacity is taken from style attribute when set vs stylesheet in IE with filters" ); - var div = jQuery("#nothiddendiv"), child = jQuery("#nothiddendivchild"); + var div = jQuery('#nothiddendiv'), child = jQuery('#nothiddendivchild'); equals( parseInt(div.css("fontSize")), 16, "Verify fontSize px set." ); equals( parseInt(div.css("font-size")), 16, "Verify fontSize px set." ); @@ -108,113 +105,31 @@ test("css(String|Hash)", function() { equals( child[0].style.fontSize, old, "Make sure font-size isn't changed on null." ); }); -test("css() explicit and relative values", function() { - expect(27); - var $elem = jQuery("#nothiddendiv"); - - $elem.css({ width: 1, height: 1, paddingLeft: "1px", opacity: 1 }); - equals( $elem.width(), 1, "Initial css set or width/height works (hash)" ); - equals( $elem.css("paddingLeft"), "1px", "Initial css set of paddingLeft works (hash)" ); - equals( $elem.css("opacity"), "1", "Initial css set of opacity works (hash)" ); - - $elem.css({ width: "+=9" }); - equals( $elem.width(), 10, "'+=9' on width (hash)" ); - - $elem.css({ width: "-=9" }); - equals( $elem.width(), 1, "'-=9' on width (hash)" ); - - $elem.css({ width: "+=9px" }); - equals( $elem.width(), 10, "'+=9px' on width (hash)" ); - - $elem.css({ width: "-=9px" }); - equals( $elem.width(), 1, "'-=9px' on width (hash)" ); - - $elem.css( "width", "+=9" ); - equals( $elem.width(), 10, "'+=9' on width (params)" ); - - $elem.css( "width", "-=9" ) ; - equals( $elem.width(), 1, "'-=9' on width (params)" ); - - $elem.css( "width", "+=9px" ); - equals( $elem.width(), 10, "'+=9px' on width (params)" ); - - $elem.css( "width", "-=9px" ); - equals( $elem.width(), 1, "'-=9px' on width (params)" ); - - $elem.css({ paddingLeft: "+=4" }); - equals( $elem.css("paddingLeft"), "5px", "'+=4' on paddingLeft (hash)" ); - - $elem.css({ paddingLeft: "-=4" }); - equals( $elem.css("paddingLeft"), "1px", "'-=4' on paddingLeft (hash)" ); - - $elem.css({ paddingLeft: "+=4px" }); - equals( $elem.css("paddingLeft"), "5px", "'+=4px' on paddingLeft (hash)" ); - - $elem.css({ paddingLeft: "-=4px" }); - equals( $elem.css("paddingLeft"), "1px", "'-=4px' on paddingLeft (hash)" ); - - $elem.css({ "padding-left": "+=4" }); - equals( $elem.css("paddingLeft"), "5px", "'+=4' on padding-left (hash)" ); - - $elem.css({ "padding-left": "-=4" }); - equals( $elem.css("paddingLeft"), "1px", "'-=4' on padding-left (hash)" ); - - $elem.css({ "padding-left": "+=4px" }); - equals( $elem.css("paddingLeft"), "5px", "'+=4px' on padding-left (hash)" ); - - $elem.css({ "padding-left": "-=4px" }); - equals( $elem.css("paddingLeft"), "1px", "'-=4px' on padding-left (hash)" ); - - $elem.css( "paddingLeft", "+=4" ); - equals( $elem.css("paddingLeft"), "5px", "'+=4' on paddingLeft (params)" ); - - $elem.css( "paddingLeft", "-=4" ); - equals( $elem.css("paddingLeft"), "1px", "'-=4' on paddingLeft (params)" ); - - $elem.css( "padding-left", "+=4px" ); - equals( $elem.css("paddingLeft"), "5px", "'+=4px' on padding-left (params)" ); - - $elem.css( "padding-left", "-=4px" ); - equals( $elem.css("paddingLeft"), "1px", "'-=4px' on padding-left (params)" ); - - $elem.css({ opacity: "-=0.5" }); - equals( $elem.css("opacity"), "0.5", "'-=0.5' on opacity (hash)" ); - - $elem.css({ opacity: "+=0.5" }); - equals( $elem.css("opacity"), "1", "'+=0.5' on opacity (hash)" ); - - $elem.css( "opacity", "-=0.5" ); - equals( $elem.css("opacity"), "0.5", "'-=0.5' on opacity (params)" ); - - $elem.css( "opacity", "+=0.5" ); - equals( $elem.css("opacity"), "1", "'+=0.5' on opacity (params)" ); -}); - test("css(String, Object)", function() { expect(22); - ok( jQuery("#nothiddendiv").is(":visible"), "Modifying CSS display: Assert element is visible"); - jQuery("#nothiddendiv").css("display", "none"); - ok( !jQuery("#nothiddendiv").is(":visible"), "Modified CSS display: Assert element is hidden"); - jQuery("#nothiddendiv").css("display", "block"); - ok( jQuery("#nothiddendiv").is(":visible"), "Modified CSS display: Assert element is visible"); + ok( jQuery('#nothiddendiv').is(':visible'), 'Modifying CSS display: Assert element is visible'); + jQuery('#nothiddendiv').css("display", 'none'); + ok( !jQuery('#nothiddendiv').is(':visible'), 'Modified CSS display: Assert element is hidden'); + jQuery('#nothiddendiv').css("display", 'block'); + ok( jQuery('#nothiddendiv').is(':visible'), 'Modified CSS display: Assert element is visible'); jQuery("#nothiddendiv").css("top", "-1em"); ok( jQuery("#nothiddendiv").css("top"), -16, "Check negative number in EMs." ); - jQuery("#floatTest").css("float", "left"); - equals( jQuery("#floatTest").css("float"), "left", "Modified CSS float using \"float\": Assert float is left"); - jQuery("#floatTest").css("font-size", "20px"); - equals( jQuery("#floatTest").css("font-size"), "20px", "Modified CSS font-size: Assert font-size is 20px"); + jQuery('#floatTest').css('float', 'left'); + equals( jQuery('#floatTest').css('float'), 'left', 'Modified CSS float using "float": Assert float is left'); + jQuery('#floatTest').css('font-size', '20px'); + equals( jQuery('#floatTest').css('font-size'), '20px', 'Modified CSS font-size: Assert font-size is 20px'); - jQuery.each("0,0.25,0.5,0.75,1".split(","), function(i, n) { - jQuery("#foo").css("opacity", n); - equals( jQuery("#foo").css("opacity"), parseFloat(n), "Assert opacity is " + parseFloat(n) + " as a String" ); - jQuery("#foo").css("opacity", parseFloat(n)); - equals( jQuery("#foo").css("opacity"), parseFloat(n), "Assert opacity is " + parseFloat(n) + " as a Number" ); + jQuery.each("0,0.25,0.5,0.75,1".split(','), function(i, n) { + jQuery('#foo').css('opacity', n); + equals( jQuery('#foo').css('opacity'), parseFloat(n), "Assert opacity is " + parseFloat(n) + " as a String" ); + jQuery('#foo').css('opacity', parseFloat(n)); + equals( jQuery('#foo').css('opacity'), parseFloat(n), "Assert opacity is " + parseFloat(n) + " as a Number" ); }); - jQuery("#foo").css("opacity", ""); - equals( jQuery("#foo").css("opacity"), "1", "Assert opacity is 1 when set to an empty String" ); + jQuery('#foo').css('opacity', ''); + equals( jQuery('#foo').css('opacity'), '1', "Assert opacity is 1 when set to an empty String" ); // using contents will get comments regular, text, and comment nodes var j = jQuery("#nonnodes").contents(); @@ -234,7 +149,7 @@ test("css(String, Object)", function() { // Test for Bug #5509 var success = true; try { - jQuery("#foo").css("backgroundColor", "rgba(0, 0, 0, 0.1)"); + jQuery('#foo').css("backgroundColor", "rgba(0, 0, 0, 0.1)"); } catch (e) { success = false; @@ -245,19 +160,19 @@ test("css(String, Object)", function() { if ( !jQuery.support.opacity ) { test("css(String, Object) for MSIE", function() { // for #1438, IE throws JS error when filter exists but doesn't have opacity in it - jQuery("#foo").css("filter", "progid:DXImageTransform.Microsoft.Chroma(color='red');"); - equals( jQuery("#foo").css("opacity"), "1", "Assert opacity is 1 when a different filter is set in IE, #1438" ); + jQuery('#foo').css("filter", "progid:DXImageTransform.Microsoft.Chroma(color='red');"); + equals( jQuery('#foo').css('opacity'), '1', "Assert opacity is 1 when a different filter is set in IE, #1438" ); var filterVal = "progid:DXImageTransform.Microsoft.Alpha(opacity=30) progid:DXImageTransform.Microsoft.Blur(pixelradius=5)"; var filterVal2 = "progid:DXImageTransform.Microsoft.alpha(opacity=100) progid:DXImageTransform.Microsoft.Blur(pixelradius=5)"; var filterVal3 = "progid:DXImageTransform.Microsoft.Blur(pixelradius=5)"; - jQuery("#foo").css("filter", filterVal); - equals( jQuery("#foo").css("filter"), filterVal, "css('filter', val) works" ); - jQuery("#foo").css("opacity", 1); - equals( jQuery("#foo").css("filter"), filterVal2, "Setting opacity in IE doesn't duplicate opacity filter" ); - equals( jQuery("#foo").css("opacity"), 1, "Setting opacity in IE with other filters works" ); - jQuery("#foo").css("filter", filterVal3).css("opacity", 1); - ok( jQuery("#foo").css("filter").indexOf(filterVal3) !== -1, "Setting opacity in IE doesn't clobber other filters" ); + jQuery('#foo').css("filter", filterVal); + equals( jQuery('#foo').css("filter"), filterVal, "css('filter', val) works" ); + jQuery('#foo').css("opacity", 1); + equals( jQuery('#foo').css("filter"), filterVal2, "Setting opacity in IE doesn't duplicate opacity filter" ); + equals( jQuery('#foo').css("opacity"), 1, "Setting opacity in IE with other filters works" ); + jQuery('#foo').css("filter", filterVal3).css("opacity", 1); + ok( jQuery('#foo').css("filter").indexOf(filterVal3) !== -1, "Setting opacity in IE doesn't clobber other filters" ); }); } @@ -396,14 +311,14 @@ test("jQuery.css(elem, 'height') doesn't clear radio buttons (bug #1095)", funct test(":visible selector works properly on table elements (bug #4512)", function () { expect(1); - jQuery("#table").html("cellcell"); - equals(jQuery("#table td:visible").length, 1, "hidden cell is not perceived as visible"); + jQuery('#table').html('cellcell'); + equals(jQuery('#table td:visible').length, 1, "hidden cell is not perceived as visible"); }); test(":visible selector works properly on children with a hidden parent (bug #4512)", function () { expect(1); - jQuery("#table").css("display", "none").html("cellcell"); - equals(jQuery("#table td:visible").length, 0, "hidden cell children not perceived as visible"); + jQuery('#table').css('display', 'none').html('cellcell'); + equals(jQuery('#table td:visible').length, 0, "hidden cell children not perceived as visible"); }); test("internal ref to elem.runtimeStyle (bug #7608)", function () { @@ -418,70 +333,3 @@ test("internal ref to elem.runtimeStyle (bug #7608)", function () { ok( result, "elem.runtimeStyle does not throw exception" ); }); - -test("marginRight computed style (bug #3333)", function() { - expect(1); - - var $div = jQuery("#foo"); - $div.css({ - width: "1px", - marginRight: 0 - }); - - equals($div.css("marginRight"), "0px", "marginRight correctly calculated with a width and display block"); -}); - -test("jQuery.cssProps behavior, (bug #8402)", function() { - var div = jQuery( "
    " ).appendTo(document.body).css({ - position: "absolute", - top: 0, - left: 10 - }); - jQuery.cssProps.top = "left"; - equal( div.css("top"), "10px", "the fixed property is used when accessing the computed style"); - div.css("top", "100px"); - equal( div[0].style.left, "100px", "the fixed property is used when setting the style"); - // cleanup jQuery.cssProps - jQuery.cssProps.top = undefined; -}); - -test("widows & orphans #8936", function () { - - var $p = jQuery("

    ").appendTo("#qunit-fixture"); - - if ( "widows" in $p[0].style ) { - expect(4); - $p.css({ - widows: 0, - orphans: 0 - }); - - equal( $p.css("widows") || jQuery.style( $p[0], "widows" ), 0, "widows correctly start with value 0"); - equal( $p.css("orphans") || jQuery.style( $p[0], "orphans" ), 0, "orphans correctly start with value 0"); - - $p.css({ - widows: 3, - orphans: 3 - }); - - equal( $p.css("widows") || jQuery.style( $p[0], "widows" ), 3, "widows correctly set to 3"); - equal( $p.css("orphans") || jQuery.style( $p[0], "orphans" ), 3, "orphans correctly set to 3"); - } else { - - expect(1); - ok( true, "jQuery does not attempt to test for style props that definitely don't exist in older versions of IE"); - } - - - $p.remove(); -}); - -test("Do not append px to 'fill-opacity' #9548", 1, function() { - - var $div = jQuery("

    ").appendTo("#qunit-fixture"); - - $div.css("fill-opacity", 0).animate({ "fill-opacity": 1.0 }, 0, function () { - equal( jQuery(this).css("fill-opacity"), 1, "Do not append px to 'fill-opacity'"); - }); - -}); diff --git a/test/unit/data.js b/test/unit/data.js index 87a3de33..8fb7f35a 100644 --- a/test/unit/data.js +++ b/test/unit/data.js @@ -283,11 +283,11 @@ test(".data(String) and .data(String, Object)", function() { // #3748 var $elem = jQuery({exists:true}); - equals( $elem.data("nothing"), undefined, "Non-existent data returns undefined"); - equals( $elem.data("null", null).data("null"), null, "null's are preserved"); - equals( $elem.data("emptyString", "").data("emptyString"), "", "Empty strings are preserved"); - equals( $elem.data("false", false).data("false"), false, "false's are preserved"); - equals( $elem.data("exists"), undefined, "Existing data is not returned" ); + equals( $elem.data('nothing'), undefined, "Non-existent data returns undefined"); + equals( $elem.data('null',null).data('null'), null, "null's are preserved"); + equals( $elem.data('emptyString','').data('emptyString'), '', "Empty strings are preserved"); + equals( $elem.data('false',false).data('false'), false, "false's are preserved"); + equals( $elem.data('exists'), undefined, "Existing data is not returned" ); // Clean up $elem.removeData(); @@ -316,7 +316,7 @@ test("data-* attributes", function() { div.remove(); - child.appendTo("#qunit-fixture"); + child.appendTo('#main'); equals( child.data("myobj"), "old data", "Value accessed from data-* attribute"); child.data("myobj", "replaced"); @@ -365,19 +365,19 @@ test("data-* attributes", function() { .attr("data-null", "null") .attr("data-string", "test"); - strictEqual( child.data("true"), true, "Primitive true read from attribute"); - strictEqual( child.data("false"), false, "Primitive false read from attribute"); - strictEqual( child.data("five"), 5, "Primitive number read from attribute"); - strictEqual( child.data("point"), 5.5, "Primitive number read from attribute"); - strictEqual( child.data("pointe"), 5500, "Primitive number read from attribute"); - strictEqual( child.data("pointbad"), "5..5", "Bad number read from attribute"); - strictEqual( child.data("pointbad2"), "-.", "Bad number read from attribute"); - strictEqual( child.data("badjson"), "{123}", "Bad number read from attribute"); - strictEqual( child.data("badjson2"), "[abc]", "Bad number read from attribute"); - strictEqual( child.data("empty"), "", "Empty string read from attribute"); - strictEqual( child.data("space"), " ", "Empty string read from attribute"); - strictEqual( child.data("null"), null, "Primitive null read from attribute"); - strictEqual( child.data("string"), "test", "Typical string read from attribute"); + strictEqual( child.data('true'), true, "Primitive true read from attribute"); + strictEqual( child.data('false'), false, "Primitive false read from attribute"); + strictEqual( child.data('five'), 5, "Primitive number read from attribute"); + strictEqual( child.data('point'), 5.5, "Primitive number read from attribute"); + strictEqual( child.data('pointe'), 5500, "Primitive number read from attribute"); + strictEqual( child.data('pointbad'), "5..5", "Bad number read from attribute"); + strictEqual( child.data('pointbad2'), "-.", "Bad number read from attribute"); + strictEqual( child.data('badjson'), "{123}", "Bad number read from attribute"); + strictEqual( child.data('badjson2'), "[abc]", "Bad number read from attribute"); + strictEqual( child.data('empty'), "", "Empty string read from attribute"); + strictEqual( child.data('space'), " ", "Empty string read from attribute"); + strictEqual( child.data('null'), null, "Primitive null read from attribute"); + strictEqual( child.data('string'), "test", "Typical string read from attribute"); child.remove(); @@ -401,12 +401,12 @@ test("data-* attributes", function() { same(jQuery(elem).data("stuff"), [2,8], "Check stuff property"); break; default: - ok(false, ["Assertion failed on index ", index, ", with data ", data].join("")); + ok(false, ["Assertion failed on index ", index, ", with data ", data].join('')); } } - var metadata = "
    1. Some stuff
    2. Some stuff
    3. Some stuff
    4. Some stuff
    ", - elem = jQuery(metadata).appendTo("#qunit-fixture"); + var metadata = '
    1. Some stuff
    2. Some stuff
    3. Some stuff
    4. Some stuff
    ', + elem = jQuery(metadata).appendTo('#main'); elem.find("li").each(testData); elem.remove(); @@ -483,45 +483,6 @@ if (window.JSON && window.JSON.stringify) { var obj = { foo: "bar" }; jQuery.data(obj, "hidden", true); - equals( JSON.stringify(obj), "{\"foo\":\"bar\"}", "Expando is hidden from JSON.stringify" ); + equals( JSON.stringify(obj), '{"foo":"bar"}', "Expando is hidden from JSON.stringify" ); }); -} - -test("jQuery.data should follow html5 specification regarding camel casing", function() { - expect(8); - - var div = jQuery("
    ") - .prependTo("body"); - - equals(div.data().foo, "a", "Verify single word data-* key"); - equals(div.data().fooBar, "b", "Verify multiple word data-* key"); - equals(div.data().fooBarBaz, "c", "Verify multiple word data-* key"); - - equals(div.data("foo"), "a", "Verify single word data-* key"); - equals(div.data("fooBar"), "b", "Verify multiple word data-* key"); - equals(div.data("fooBarBaz"), "c", "Verify multiple word data-* key"); - - div.data("foo-bar", "d"); - - equals(div.data("fooBar"), "d", "Verify updated data-* key"); - equals(div.data("foo-bar"), "d", "Verify updated data-* key"); - - div.remove(); -}); - -test("jQuery.data should not miss data with preset hyphenated property names", function() { - - expect(2); - - var div = jQuery("
    ", { id: "hyphened" }).appendTo("#qunit-fixture"), - test = { - "camelBar": "camelBar", - "hyphen-foo": "hyphen-foo" - }; - - div.data( test ); - - jQuery.each( test , function(i, k) { - equal( div.data(k), k, "data with property '"+k+"' was correctly found"); - }); -}); +} \ No newline at end of file diff --git a/test/unit/deferred.js b/test/unit/deferred.js deleted file mode 100644 index fbe29070..00000000 --- a/test/unit/deferred.js +++ /dev/null @@ -1,383 +0,0 @@ -module("deferred", { teardown: moduleTeardown }); - -jQuery.each( [ "", " - new operator" ], function( _, withNew ) { - - function createDeferred() { - return withNew ? new jQuery._Deferred() : jQuery._Deferred(); - } - - test("jQuery._Deferred" + withNew, function() { - - expect( 11 ); - - var deferred, - object, - test; - - deferred = createDeferred(); - - test = false; - - deferred.done( function( value ) { - equals( value , "value" , "Test pre-resolve callback" ); - test = true; - } ); - - deferred.resolve( "value" ); - - ok( test , "Test pre-resolve callbacks called right away" ); - - test = false; - - deferred.done( function( value ) { - equals( value , "value" , "Test post-resolve callback" ); - test = true; - } ); - - ok( test , "Test post-resolve callbacks called right away" ); - - deferred.cancel(); - - test = true; - - deferred.done( function() { - ok( false , "Cancel was ignored" ); - test = false; - } ); - - ok( test , "Test cancel" ); - - deferred = createDeferred().resolve(); - - try { - deferred.done( function() { - throw "Error"; - } , function() { - ok( true , "Test deferred do not cancel on exception" ); - } ); - } catch( e ) { - strictEqual( e , "Error" , "Test deferred propagates exceptions"); - deferred.done(); - } - - test = ""; - deferred = createDeferred().done( function() { - - test += "A"; - - }, function() { - - test += "B"; - - } ).resolve(); - - strictEqual( test , "AB" , "Test multiple done parameters" ); - - test = ""; - - deferred.done( function() { - - deferred.done( function() { - - test += "C"; - - } ); - - test += "A"; - - }, function() { - - test += "B"; - } ); - - strictEqual( test , "ABC" , "Test done callbacks order" ); - - deferred = createDeferred(); - - deferred.resolveWith( jQuery , [ document ] ).done( function( doc ) { - ok( this === jQuery && arguments.length === 1 && doc === document , "Test fire context & args" ); - }); - - // #8421 - deferred = createDeferred(); - deferred.resolveWith().done(function() { - ok( true, "Test resolveWith can be called with no argument" ); - }); - }); -} ); - -jQuery.each( [ "", " - new operator" ], function( _, withNew ) { - - function createDeferred( fn ) { - return withNew ? new jQuery.Deferred( fn ) : jQuery.Deferred( fn ); - } - - test("jQuery.Deferred" + withNew, function() { - - expect( 8 ); - - createDeferred().resolve().then( function() { - ok( true , "Success on resolve" ); - ok( this.isResolved(), "Deferred is resolved" ); - }, function() { - ok( false , "Error on resolve" ); - }).always( function() { - ok( true , "Always callback on resolve" ); - }); - - createDeferred().reject().then( function() { - ok( false , "Success on reject" ); - }, function() { - ok( true , "Error on reject" ); - ok( this.isRejected(), "Deferred is rejected" ); - }).always( function() { - ok( true , "Always callback on reject" ); - }); - - createDeferred( function( defer ) { - ok( this === defer , "Defer passed as this & first argument" ); - this.resolve( "done" ); - }).then( function( value ) { - strictEqual( value , "done" , "Passed function executed" ); - }); - }); -} ); - -test( "jQuery.Deferred.pipe - filtering (done)", function() { - - expect(4); - - var defer = jQuery.Deferred(), - piped = defer.pipe(function( a, b ) { - return a * b; - }), - value1, - value2, - value3; - - piped.done(function( result ) { - value3 = result; - }); - - defer.done(function( a, b ) { - value1 = a; - value2 = b; - }); - - defer.resolve( 2, 3 ); - - strictEqual( value1, 2, "first resolve value ok" ); - strictEqual( value2, 3, "second resolve value ok" ); - strictEqual( value3, 6, "result of filter ok" ); - - jQuery.Deferred().reject().pipe(function() { - ok( false, "pipe should not be called on reject" ); - }); - - jQuery.Deferred().resolve().pipe( jQuery.noop ).done(function( value ) { - strictEqual( value, undefined, "pipe done callback can return undefined/null" ); - }); -}); - -test( "jQuery.Deferred.pipe - filtering (fail)", function() { - - expect(4); - - var defer = jQuery.Deferred(), - piped = defer.pipe( null, function( a, b ) { - return a * b; - } ), - value1, - value2, - value3; - - piped.fail(function( result ) { - value3 = result; - }); - - defer.fail(function( a, b ) { - value1 = a; - value2 = b; - }); - - defer.reject( 2, 3 ); - - strictEqual( value1, 2, "first reject value ok" ); - strictEqual( value2, 3, "second reject value ok" ); - strictEqual( value3, 6, "result of filter ok" ); - - jQuery.Deferred().resolve().pipe( null, function() { - ok( false, "pipe should not be called on resolve" ); - } ); - - jQuery.Deferred().reject().pipe( null, jQuery.noop ).fail(function( value ) { - strictEqual( value, undefined, "pipe fail callback can return undefined/null" ); - }); -}); - -test( "jQuery.Deferred.pipe - deferred (done)", function() { - - expect(3); - - var defer = jQuery.Deferred(), - piped = defer.pipe(function( a, b ) { - return jQuery.Deferred(function( defer ) { - defer.reject( a * b ); - }); - }), - value1, - value2, - value3; - - piped.fail(function( result ) { - value3 = result; - }); - - defer.done(function( a, b ) { - value1 = a; - value2 = b; - }); - - defer.resolve( 2, 3 ); - - strictEqual( value1, 2, "first resolve value ok" ); - strictEqual( value2, 3, "second resolve value ok" ); - strictEqual( value3, 6, "result of filter ok" ); -}); - -test( "jQuery.Deferred.pipe - deferred (fail)", function() { - - expect(3); - - var defer = jQuery.Deferred(), - piped = defer.pipe( null, function( a, b ) { - return jQuery.Deferred(function( defer ) { - defer.resolve( a * b ); - }); - } ), - value1, - value2, - value3; - - piped.done(function( result ) { - value3 = result; - }); - - defer.fail(function( a, b ) { - value1 = a; - value2 = b; - }); - - defer.reject( 2, 3 ); - - strictEqual( value1, 2, "first reject value ok" ); - strictEqual( value2, 3, "second reject value ok" ); - strictEqual( value3, 6, "result of filter ok" ); -}); - -test( "jQuery.Deferred.pipe - context", function() { - - expect(4); - - var context = {}; - - jQuery.Deferred().resolveWith( context, [ 2 ] ).pipe(function( value ) { - return value * 3; - }).done(function( value ) { - strictEqual( this, context, "custom context correctly propagated" ); - strictEqual( value, 6, "proper value received" ); - }); - - var defer = jQuery.Deferred(), - piped = defer.pipe(function( value ) { - return value * 3; - }); - - defer.resolve( 2 ); - - piped.done(function( value ) { - strictEqual( this.promise(), piped, "default context gets updated to latest defer in the chain" ); - strictEqual( value, 6, "proper value received" ); - }); -}); - - -test( "jQuery.when" , function() { - - expect( 23 ); - - // Some other objects - jQuery.each( { - - "an empty string": "", - "a non-empty string": "some string", - "zero": 0, - "a number other than zero": 1, - "true": true, - "false": false, - "null": null, - "undefined": undefined, - "a plain object": {} - - } , function( message , value ) { - - ok( jQuery.isFunction( jQuery.when( value ).done(function( resolveValue ) { - strictEqual( resolveValue , value , "Test the promise was resolved with " + message ); - }).promise ) , "Test " + message + " triggers the creation of a new Promise" ); - - } ); - - ok( jQuery.isFunction( jQuery.when().done(function( resolveValue ) { - strictEqual( resolveValue , undefined , "Test the promise was resolved with no parameter" ); - }).promise ) , "Test calling when with no parameter triggers the creation of a new Promise" ); - - var cache, i; - - for( i = 1 ; i < 4 ; i++ ) { - jQuery.when( cache || jQuery.Deferred( function() { - this.resolve( i ); - }) ).done(function( value ) { - strictEqual( value , 1 , "Function executed" + ( i > 1 ? " only once" : "" ) ); - cache = value; - }); - } -}); - -test("jQuery.when - joined", function() { - - expect(25); - - var deferreds = { - value: 1, - success: jQuery.Deferred().resolve( 1 ), - error: jQuery.Deferred().reject( 0 ), - futureSuccess: jQuery.Deferred(), - futureError: jQuery.Deferred() - }, - willSucceed = { - value: true, - success: true, - error: false, - futureSuccess: true, - futureError: false - }; - - jQuery.each( deferreds, function( id1, defer1 ) { - jQuery.each( deferreds, function( id2, defer2 ) { - var shouldResolve = willSucceed[ id1 ] && willSucceed[ id2 ], - expected = shouldResolve ? [ 1, 1 ] : [ 0, undefined ], - code = id1 + "/" + id2; - jQuery.when( defer1, defer2 ).done(function( a, b ) { - if ( shouldResolve ) { - same( [ a, b ], expected, code + " => resolve" ); - } - }).fail(function( a, b ) { - if ( !shouldResolve ) { - same( [ a, b ], expected, code + " => resolve" ); - } - }); - } ); - } ); - deferreds.futureSuccess.resolve( 1 ); - deferreds.futureError.reject( 0 ); -}); diff --git a/test/unit/dimensions.js b/test/unit/dimensions.js index 57229199..fa59a9f7 100644 --- a/test/unit/dimensions.js +++ b/test/unit/dimensions.js @@ -34,7 +34,7 @@ function testWidth( val ) { equals( blah.width( val(10) ), blah, "Make sure that setting a width on an empty set returns the set." ); equals( blah.width(), null, "Make sure 'null' is returned on an empty set"); - jQuery.removeData($div[0], "olddisplay", true); + jQuery.removeData($div[0], 'olddisplay', true); } test("width()", function() { @@ -83,7 +83,7 @@ function testHeight( val ) { equals( blah.height( val(10) ), blah, "Make sure that setting a height on an empty set returns the set." ); equals( blah.height(), null, "Make sure 'null' is returned on an empty set"); - jQuery.removeData($div[0], "olddisplay", true); + jQuery.removeData($div[0], 'olddisplay', true); } test("height()", function() { @@ -107,13 +107,7 @@ test("height() with function args", function() { }); test("innerWidth()", function() { - expect(8); - - equals(jQuery(window).innerWidth(), null, "Test on window without margin option"); - equals(jQuery(window).innerWidth(true), null, "Test on window with margin option"); - - equals(jQuery(document).innerWidth(), null, "Test on document without margin option"); - equals(jQuery(document).innerWidth(true), null, "Test on document with margin option"); + expect(4); var $div = jQuery("#nothiddendiv"); // set styles @@ -138,17 +132,11 @@ test("innerWidth()", function() { equals( div.innerWidth(), 0, "Make sure that disconnected nodes are handled." ); div.remove(); - jQuery.removeData($div[0], "olddisplay", true); + jQuery.removeData($div[0], 'olddisplay', true); }); test("innerHeight()", function() { - expect(8); - - equals(jQuery(window).innerHeight(), null, "Test on window without margin option"); - equals(jQuery(window).innerHeight(true), null, "Test on window with margin option"); - - equals(jQuery(document).innerHeight(), null, "Test on document without margin option"); - equals(jQuery(document).innerHeight(true), null, "Test on document with margin option"); + expect(4); var $div = jQuery("#nothiddendiv"); // set styles @@ -173,16 +161,11 @@ test("innerHeight()", function() { equals( div.innerHeight(), 0, "Make sure that disconnected nodes are handled." ); div.remove(); - jQuery.removeData($div[0], "olddisplay", true); + jQuery.removeData($div[0], 'olddisplay', true); }); test("outerWidth()", function() { - expect(11); - - equal( jQuery( window ).outerWidth(), null, "Test on window without margin option" ); - equal( jQuery( window ).outerWidth( true ), null, "Test on window with margin option" ); - equal( jQuery( document ).outerWidth(), null, "Test on document without margin option" ); - equal( jQuery( document ).outerWidth( true ), null, "Test on document with margin option" ); + expect(7); var $div = jQuery("#nothiddendiv"); $div.css("width", 30); @@ -208,41 +191,11 @@ test("outerWidth()", function() { equals( div.outerWidth(), 0, "Make sure that disconnected nodes are handled." ); div.remove(); - jQuery.removeData($div[0], "olddisplay", true); -}); - -test("child of a hidden elem has accurate inner/outer/Width()/Height() see #9441 #9300", function() { - expect(8); - - // setup html - var $divNormal = jQuery("
    ").css({ width: "100px", height: "100px", border: "10px solid white", padding: "2px", margin: "3px" }), - $divChild = $divNormal.clone(), - $divHiddenParent = jQuery("
    ").css( "display", "none" ).append( $divChild ).appendTo("body"); - $divNormal.appendTo("body"); - - // tests that child div of a hidden div works the same as a normal div - equals( $divChild.width(), $divNormal.width(), "child of a hidden element width() is wrong see #9441" ); - equals( $divChild.innerWidth(), $divNormal.innerWidth(), "child of a hidden element innerWidth() is wrong see #9441" ); - equals( $divChild.outerWidth(), $divNormal.outerWidth(), "child of a hidden element outerWidth() is wrong see #9441" ); - equals( $divChild.outerWidth(true), $divNormal.outerWidth( true ), "child of a hidden element outerWidth( true ) is wrong see #9300" ); - - equals( $divChild.height(), $divNormal.height(), "child of a hidden element height() is wrong see #9441" ); - equals( $divChild.innerHeight(), $divNormal.innerHeight(), "child of a hidden element innerHeight() is wrong see #9441" ); - equals( $divChild.outerHeight(), $divNormal.outerHeight(), "child of a hidden element outerHeight() is wrong see #9441" ); - equals( $divChild.outerHeight(true), $divNormal.outerHeight( true ), "child of a hidden element outerHeight( true ) is wrong see #9300" ); - - // teardown html - $divHiddenParent.remove(); - $divNormal.remove(); + jQuery.removeData($div[0], 'olddisplay', true); }); test("outerHeight()", function() { - expect(11); - - equal( jQuery( window ).outerHeight(), null, "Test on window without margin option" ); - equal( jQuery( window ).outerHeight( true ), null, "Test on window with margin option" ); - equal( jQuery( document ).outerHeight(), null, "Test on document without margin option" ); - equal( jQuery( document ).outerHeight( true ), null, "Test on document with margin option" ); + expect(7); var $div = jQuery("#nothiddendiv"); $div.css("height", 30); @@ -267,5 +220,5 @@ test("outerHeight()", function() { equals( div.outerHeight(), 0, "Make sure that disconnected nodes are handled." ); div.remove(); - jQuery.removeData($div[0], "olddisplay", true); + jQuery.removeData($div[0], 'olddisplay', true); }); diff --git a/test/unit/effects.js b/test/unit/effects.js index 864c4a40..c0a812f4 100644 --- a/test/unit/effects.js +++ b/test/unit/effects.js @@ -2,7 +2,7 @@ module("effects", { teardown: moduleTeardown }); test("sanity check", function() { expect(1); - ok( jQuery("#dl:visible, #qunit-fixture:visible, #foo:visible").length === 3, "QUnit state is correct for testing effects" ); + ok( jQuery("#dl:visible, #main:visible, #foo:visible").length === 3, "QUnit state is correct for testing effects" ); }); test("show()", function() { @@ -14,7 +14,7 @@ test("show()", function() { equals( hiddendiv.css("display"), "block", "Make sure a pre-hidden div is visible." ); - var div = jQuery("
    ").hide().appendTo("#qunit-fixture").show(); + var div = jQuery("
    ").hide().appendTo("#main").show(); equal( div.css("display"), "block", "Make sure pre-hidden divs show" ); @@ -32,8 +32,7 @@ test("show()", function() { hiddendiv.css("display",""); - var pass = true; - div = jQuery("#qunit-fixture div"); + var pass = true, div = jQuery("#main div"); div.show().each(function(){ if ( this.style.display == "none" ) pass = false; }); @@ -63,7 +62,7 @@ test("show()", function() { }); // #show-tests * is set display: none in CSS - jQuery("#qunit-fixture").append("

    "); + jQuery("#main").append('

    '); var old = jQuery("#test-table").show().css("display") !== "table"; jQuery("#test-table").remove(); @@ -89,10 +88,6 @@ test("show()", function() { var elem = jQuery(selector, "#show-tests").show(); equals( elem.css("display"), expected, "Show using correct display type for " + selector ); }); - - // Make sure that showing or hiding a text node doesn't cause an error - jQuery("
    test
    text test").show().remove(); - jQuery("
    test
    text test").hide().remove(); }); test("show(Number) - other displays", function() { @@ -101,7 +96,7 @@ test("show(Number) - other displays", function() { stop(); // #show-tests * is set display: none in CSS - jQuery("#qunit-fixture").append("

    "); + jQuery("#main").append('

    '); var old = jQuery("#test-table").show().css("display") !== "table", num = 0; @@ -143,11 +138,11 @@ test("Persist correct display value", function() { stop(); // #show-tests * is set display: none in CSS - jQuery("#qunit-fixture").append("
    foo
    "); + jQuery("#main").append('
    foo
    '); var $span = jQuery("#show-tests span"), displayNone = $span.css("display"), - display = "", num = 0; + display = '', num = 0; $span.show(); @@ -167,35 +162,13 @@ test("Persist correct display value", function() { }); }); -test("show() resolves correct default display #8099", function() { - expect(7); - var tt8099 = jQuery("").appendTo("body"), - dfn8099 = jQuery("", { html: "foo"}).appendTo("body"); - - equals( tt8099.css("display"), "none", "default display override for all tt" ); - equals( tt8099.show().css("display"), "inline", "Correctly resolves display:inline" ); - - equals( jQuery("#foo").hide().show().css("display"), "block", "Correctly resolves display:block after hide/show" ); - - equals( tt8099.hide().css("display"), "none", "default display override for all tt" ); - equals( tt8099.show().css("display"), "inline", "Correctly resolves display:inline" ); - - equals( dfn8099.css("display"), "none", "default display override for all dfn" ); - equals( dfn8099.show().css("display"), "inline", "Correctly resolves display:inline" ); - - tt8099.remove(); - dfn8099.remove(); - -}); - - test("animate(Hash, Object, Function)", function() { expect(1); stop(); - var hash = {opacity: "show"}; + var hash = {opacity: 'show'}; var hashCopy = jQuery.extend({}, hash); - jQuery("#foo").animate(hash, 0, function() { - equals( hash.opacity, hashCopy.opacity, "Check if animate changed the hash parameter" ); + jQuery('#foo').animate(hash, 0, function() { + equals( hash.opacity, hashCopy.opacity, 'Check if animate changed the hash parameter' ); start(); }); }); @@ -220,7 +193,7 @@ test("animate block as inline width/height", function() { if ( jQuery.support.inlineBlockNeedsLayout || expected === "inline-block" ) { stop(); - jQuery("#foo").css({ display: "inline", width: "", height: "" }).animate({ width: 42, height: 42 }, 100, function() { + jQuery("#foo").css({ display: "inline", width: '', height: '' }).animate({ width: 42, height: 42 }, 100, function() { equals( jQuery(this).css("display"), jQuery.support.inlineBlockNeedsLayout ? "inline" : "inline-block", "inline-block was set on non-floated inline element when animating width/height" ); equals( this.offsetWidth, 42, "width was animated" ); equals( this.offsetHeight, 42, "height was animated" ); @@ -245,9 +218,9 @@ test("animate native inline width/height", function() { if ( jQuery.support.inlineBlockNeedsLayout || expected === "inline-block" ) { stop(); - jQuery("#foo").css({ display: "", width: "", height: "" }) - .append("text") - .children("span") + jQuery("#foo").css({ display: "", width: '', height: '' }) + .append('text') + .children('span') .animate({ width: 42, height: 42 }, 100, function() { equals( jQuery(this).css("display"), "inline-block", "inline-block was set on non-floated inline element when animating width/height" ); equals( this.offsetWidth, 42, "width was animated" ); @@ -344,13 +317,13 @@ test("animate option (queue === false)", function () { var order = []; var $foo = jQuery("#foo"); - $foo.animate({width:"100px"}, 3000, function () { + $foo.animate({width:'100px'}, 3000, function () { // should finish after unqueued animation so second order.push(2); same( order, [ 1, 2 ], "Animations finished in the correct order" ); start(); }); - $foo.animate({fontSize:"2em"}, {queue:false, duration:10, complete:function () { + $foo.animate({fontSize:'2em'}, {queue:false, duration:10, complete:function () { // short duration and out of queue so should finish first order.push(1); }}); @@ -460,7 +433,7 @@ test("stop()", function() { var w = 0; $foo.hide().width(200).width(); - $foo.animate({ width: "show" }, 1000); + $foo.animate({ width:'show' }, 1000); setTimeout(function(){ var nw = $foo.width(); notEqual( nw, w, "An animation occurred " + nw + "px " + w + "px"); @@ -485,9 +458,9 @@ test("stop() - several in queue", function() { var w = 0; $foo.hide().width(200).width(); - $foo.animate({ width: "show" }, 1000); - $foo.animate({ width: "hide" }, 1000); - $foo.animate({ width: "show" }, 1000); + $foo.animate({ width:'show' }, 1000); + $foo.animate({ width:'hide' }, 1000); + $foo.animate({ width:'show' }, 1000); setTimeout(function(){ equals( $foo.queue().length, 3, "All 3 still in the queue" ); var nw = $foo.width(); @@ -510,9 +483,9 @@ test("stop(clearQueue)", function() { var w = 0; $foo.hide().width(200).width(); - $foo.animate({ width: "show" }, 1000); - $foo.animate({ width: "hide" }, 1000); - $foo.animate({ width: "show" }, 1000); + $foo.animate({ width:'show' }, 1000); + $foo.animate({ width:'hide' }, 1000); + $foo.animate({ width:'show' }, 1000); setTimeout(function(){ var nw = $foo.width(); ok( nw != w, "An animation occurred " + nw + "px " + w + "px"); @@ -537,10 +510,10 @@ test("stop(clearQueue, gotoEnd)", function() { var w = 0; $foo.hide().width(200).width(); - $foo.animate({ width: "show" }, 1000); - $foo.animate({ width: "hide" }, 1000); - $foo.animate({ width: "show" }, 1000); - $foo.animate({ width: "hide" }, 1000); + $foo.animate({ width:'show' }, 1000); + $foo.animate({ width:'hide' }, 1000); + $foo.animate({ width:'show' }, 1000); + $foo.animate({ width:'hide' }, 1000); setTimeout(function(){ var nw = $foo.width(); ok( nw != w, "An animation occurred " + nw + "px " + w + "px"); @@ -583,10 +556,10 @@ jQuery.checkOverflowDisplay = function(){ equals(jQuery.css( this, "display" ), "inline", "Display shouldn't be tampered with."); start(); -}; +} test( "jQuery.fx.prototype.cur()", 6, function() { - var div = jQuery( "
    " ).appendTo( "#qunit-fixture" ).css({ + var div = jQuery( "
    " ).appendTo( "#main" ).css({ color: "#ABC", border: "5px solid black", left: "auto", @@ -695,8 +668,8 @@ jQuery.each( { jQuery(elem).css(prop,prop == "opacity" ? 0 : "0px"); return 0; } -}, function( fn, f ) { - jQuery.each({ +}, function(fn, f){ + jQuery.each( { "show": function(elem,prop){ jQuery(elem).hide().addClass("wide"+prop); return "show"; @@ -744,64 +717,59 @@ jQuery.each( { var anim = { width: t_w, height: t_h, opacity: t_o }; - elem.animate(anim, 50); - - jQuery.when( elem ).done(function( elem ){ - - elem = elem[ 0 ]; - + elem.animate(anim, 50, function(){ if ( t_w == "show" ) - equals( elem.style.display, "block", "Showing, display should block: " + elem.style.display); + equals( this.style.display, "block", "Showing, display should block: " + this.style.display); if ( t_w == "hide"||t_w == "show" ) - ok(f_w === "" ? elem.style.width === f_w : elem.style.width.indexOf(f_w) === 0, "Width must be reset to " + f_w + ": " + elem.style.width); + ok(f_w === "" ? this.style.width === f_w : this.style.width.indexOf(f_w) === 0, "Width must be reset to " + f_w + ": " + this.style.width); if ( t_h == "hide"||t_h == "show" ) - ok(f_h === "" ? elem.style.height === f_h : elem.style.height.indexOf(f_h) === 0, "Height must be reset to " + f_h + ": " + elem.style.height); + ok(f_h === "" ? this.style.height === f_h : this.style.height.indexOf(f_h) === 0, "Height must be reset to " + f_h + ": " + this.style.height); - var cur_o = jQuery.style(elem, "opacity"); + var cur_o = jQuery.style(this, "opacity"); if ( t_o == "hide" || t_o == "show" ) equals(cur_o, f_o, "Opacity must be reset to " + f_o + ": " + cur_o); if ( t_w == "hide" ) - equals(elem.style.display, "none", "Hiding, display should be none: " + elem.style.display); + equals(this.style.display, "none", "Hiding, display should be none: " + this.style.display); if ( t_o.constructor == Number ) { equals(cur_o, t_o, "Final opacity should be " + t_o + ": " + cur_o); - ok(jQuery.css(elem, "opacity") != "" || cur_o == t_o, "Opacity should be explicitly set to " + t_o + ", is instead: " + cur_o); + ok(jQuery.css(this, "opacity") != "" || cur_o == t_o, "Opacity should be explicitly set to " + t_o + ", is instead: " + cur_o); } if ( t_w.constructor == Number ) { - equals(elem.style.width, t_w + "px", "Final width should be " + t_w + ": " + elem.style.width); + equals(this.style.width, t_w + "px", "Final width should be " + t_w + ": " + this.style.width); - var cur_w = jQuery.css(elem,"width"); + var cur_w = jQuery.css(this,"width"); - ok(elem.style.width != "" || cur_w == t_w, "Width should be explicitly set to " + t_w + ", is instead: " + cur_w); + ok(this.style.width != "" || cur_w == t_w, "Width should be explicitly set to " + t_w + ", is instead: " + cur_w); } if ( t_h.constructor == Number ) { - equals(elem.style.height, t_h + "px", "Final height should be " + t_h + ": " + elem.style.height); + equals(this.style.height, t_h + "px", "Final height should be " + t_h + ": " + this.style.height); - var cur_h = jQuery.css(elem,"height"); + var cur_h = jQuery.css(this,"height"); - ok(elem.style.height != "" || cur_h == t_h, "Height should be explicitly set to " + t_h + ", is instead: " + cur_w); + ok(this.style.height != "" || cur_h == t_h, "Height should be explicitly set to " + t_h + ", is instead: " + cur_w); } if ( t_h == "show" ) { - var old_h = jQuery.css(elem, "height"); - jQuery(elem).append("
    Some more text
    and some more..."); + var old_h = jQuery.css(this, "height"); + jQuery(this).append("
    Some more text
    and some more..."); if ( /Auto/.test( fn ) ) { - notEqual(jQuery.css(elem, "height"), old_h, "Make sure height is auto."); + notEqual(jQuery.css(this, "height"), old_h, "Make sure height is auto."); } else { - equals(jQuery.css(elem, "height"), old_h, "Make sure height is not auto."); + equals(jQuery.css(this, "height"), old_h, "Make sure height is not auto."); } } // manually remove generated element - jQuery(elem).remove(); + jQuery(this).remove(); start(); }); @@ -810,7 +778,7 @@ jQuery.each( { }); jQuery.fn.saveState = function(hiddenOverflow){ - var check = ["opacity", "height", "width", "display", "overflow"]; + var check = ['opacity','height','width','display','overflow']; expect(check.length); stop(); @@ -831,64 +799,64 @@ jQuery.checkState = function(){ }); // manually clean data on modified element - jQuery.removeData(this, "olddisplay", true); + jQuery.removeData(this, 'olddisplay', true); start(); -}; +} // Chaining Tests test("Chain fadeOut fadeIn", function() { - jQuery("#fadein div").saveState().fadeOut("fast").fadeIn("fast",jQuery.checkState); + jQuery('#fadein div').saveState().fadeOut('fast').fadeIn('fast',jQuery.checkState); }); test("Chain fadeIn fadeOut", function() { - jQuery("#fadeout div").saveState().fadeIn("fast").fadeOut("fast",jQuery.checkState); + jQuery('#fadeout div').saveState().fadeIn('fast').fadeOut('fast',jQuery.checkState); }); test("Chain hide show", function() { - jQuery("#show div").saveState(jQuery.support.shrinkWrapBlocks).hide("fast").show("fast",jQuery.checkState); + jQuery('#show div').saveState(jQuery.support.shrinkWrapBlocks).hide('fast').show('fast',jQuery.checkState); }); test("Chain show hide", function() { - jQuery("#hide div").saveState(jQuery.support.shrinkWrapBlocks).show("fast").hide("fast",jQuery.checkState); + jQuery('#hide div').saveState(jQuery.support.shrinkWrapBlocks).show('fast').hide('fast',jQuery.checkState); }); test("Chain show hide with easing and callback", function() { - jQuery("#hide div").saveState().show("fast").hide("fast","linear",jQuery.checkState); + jQuery('#hide div').saveState().show('fast').hide('fast','linear',jQuery.checkState); }); test("Chain toggle in", function() { - jQuery("#togglein div").saveState(jQuery.support.shrinkWrapBlocks).toggle("fast").toggle("fast",jQuery.checkState); + jQuery('#togglein div').saveState(jQuery.support.shrinkWrapBlocks).toggle('fast').toggle('fast',jQuery.checkState); }); test("Chain toggle out", function() { - jQuery("#toggleout div").saveState(jQuery.support.shrinkWrapBlocks).toggle("fast").toggle("fast",jQuery.checkState); + jQuery('#toggleout div').saveState(jQuery.support.shrinkWrapBlocks).toggle('fast').toggle('fast',jQuery.checkState); }); test("Chain toggle out with easing and callback", function() { - jQuery("#toggleout div").saveState(jQuery.support.shrinkWrapBlocks).toggle("fast").toggle("fast","linear",jQuery.checkState); + jQuery('#toggleout div').saveState(jQuery.support.shrinkWrapBlocks).toggle('fast').toggle('fast','linear',jQuery.checkState); }); test("Chain slideDown slideUp", function() { - jQuery("#slidedown div").saveState(jQuery.support.shrinkWrapBlocks).slideDown("fast").slideUp("fast",jQuery.checkState); + jQuery('#slidedown div').saveState(jQuery.support.shrinkWrapBlocks).slideDown('fast').slideUp('fast',jQuery.checkState); }); test("Chain slideUp slideDown", function() { - jQuery("#slideup div").saveState(jQuery.support.shrinkWrapBlocks).slideUp("fast").slideDown("fast",jQuery.checkState); + jQuery('#slideup div').saveState(jQuery.support.shrinkWrapBlocks).slideUp('fast').slideDown('fast',jQuery.checkState); }); test("Chain slideUp slideDown with easing and callback", function() { - jQuery("#slideup div").saveState(jQuery.support.shrinkWrapBlocks).slideUp("fast").slideDown("fast","linear",jQuery.checkState); + jQuery('#slideup div').saveState(jQuery.support.shrinkWrapBlocks).slideUp('fast').slideDown('fast','linear',jQuery.checkState); }); test("Chain slideToggle in", function() { - jQuery("#slidetogglein div").saveState(jQuery.support.shrinkWrapBlocks).slideToggle("fast").slideToggle("fast",jQuery.checkState); + jQuery('#slidetogglein div').saveState(jQuery.support.shrinkWrapBlocks).slideToggle('fast').slideToggle('fast',jQuery.checkState); }); test("Chain slideToggle out", function() { - jQuery("#slidetoggleout div").saveState(jQuery.support.shrinkWrapBlocks).slideToggle("fast").slideToggle("fast",jQuery.checkState); + jQuery('#slidetoggleout div').saveState(jQuery.support.shrinkWrapBlocks).slideToggle('fast').slideToggle('fast',jQuery.checkState); }); test("Chain fadeToggle in", function() { - jQuery("#fadetogglein div").saveState().fadeToggle("fast").fadeToggle("fast",jQuery.checkState); + jQuery('#fadetogglein div').saveState().fadeToggle('fast').fadeToggle('fast',jQuery.checkState); }); test("Chain fadeToggle out", function() { - jQuery("#fadetoggleout div").saveState().fadeToggle("fast").fadeToggle("fast",jQuery.checkState); + jQuery('#fadetoggleout div').saveState().fadeToggle('fast').fadeToggle('fast',jQuery.checkState); }); test("Chain fadeTo 0.5 1.0 with easing and callback)", function() { - jQuery("#fadeto div").saveState().fadeTo("fast",0.5).fadeTo("fast",1.0,"linear",jQuery.checkState); + jQuery('#fadeto div').saveState().fadeTo('fast',0.5).fadeTo('fast',1.0,'linear',jQuery.checkState); }); jQuery.makeTest = function( text ){ @@ -902,7 +870,7 @@ jQuery.makeTest = function( text ){ .after( elem ); return elem; -}; +} jQuery.makeTest.id = 1; @@ -923,42 +891,34 @@ test("jQuery.show('fast') doesn't clear radio buttons (bug #1095)", function () test("animate with per-property easing", function(){ - expect(5); + expect(3); stop(); - var data = { a:0, b:0, c:0 }, - _test1_called = false, - _test2_called = false, - _default_test_called = false, - props = { - a: [ 100, "_test1" ], - b: [ 100, "_test2" ], - c: 100 - }; + var _test1_called = false; + var _test2_called = false; + var _default_test_called = false; - jQuery.easing["_test1"] = function(p) { + jQuery.easing['_test1'] = function() { _test1_called = true; - return p; }; - jQuery.easing["_test2"] = function(p) { + jQuery.easing['_test2'] = function() { _test2_called = true; - return p; }; - jQuery.easing["_default_test"] = function(p) { + jQuery.easing['_default_test'] = function() { _default_test_called = true; - return p; }; - jQuery(data).animate( props, 400, "_default_test", function(){ + jQuery({a:0,b:0,c:0}).animate({ + a: [100, '_test1'], + b: [100, '_test2'], + c: 100 + }, 400, '_default_test', function(){ start(); - - ok( _test1_called, "Easing function (_test1) called" ); - ok( _test2_called, "Easing function (_test2) called" ); - ok( _default_test_called, "Easing function (_default) called" ); - equal( props.a[ 1 ], "_test1", "animate does not change original props (per-property easing would be lost)"); - equal( props.b[ 1 ], "_test2", "animate does not change original props (per-property easing would be lost)"); + ok(_test1_called, "Easing function (1) called"); + ok(_test2_called, "Easing function (2) called"); + ok(_default_test_called, "Easing function (_default) called"); }); }); @@ -967,7 +927,7 @@ test("hide hidden elements (bug #7141)", function() { expect(3); QUnit.reset(); - var div = jQuery("
    ").appendTo("#qunit-fixture"); + var div = jQuery("
    ").appendTo("#main"); equals( div.css("display"), "none", "Element is hidden by default" ); div.hide(); ok( !jQuery._data(div, "olddisplay"), "olddisplay is undefined after hiding an already-hidden element" ); @@ -982,7 +942,7 @@ test("hide hidden elements, with animation (bug #7141)", function() { QUnit.reset(); stop(); - var div = jQuery("
    ").appendTo("#qunit-fixture"); + var div = jQuery("
    ").appendTo("#main"); equals( div.css("display"), "none", "Element is hidden by default" ); div.hide(1, function () { ok( !jQuery._data(div, "olddisplay"), "olddisplay is undefined after hiding an already-hidden element" ); @@ -995,53 +955,10 @@ test("hide hidden elements, with animation (bug #7141)", function() { test("animate unit-less properties (#4966)", 2, function() { stop(); - var div = jQuery( "
    " ).appendTo( "#qunit-fixture" ); + var div = jQuery( "
    " ).appendTo( "#main" ); equal( div.css( "z-index" ), "0", "z-index is 0" ); div.animate({ zIndex: 2 }, function() { equal( div.css( "z-index" ), "2", "z-index is 2" ); start(); }); }); - -test( "animate properties missing px w/ opacity as last (#9074)", 2, function() { - expect( 6 ); - stop(); - var div = jQuery( "
    " ) - .appendTo( "#qunit-fixture" ); - function cssInt( prop ) { - return parseInt( div.css( prop ), 10 ); - } - equal( cssInt( "marginLeft" ), 0, "Margin left is 0" ); - equal( cssInt( "left" ), 0, "Left is 0" ); - div.animate({ - left: 200, - marginLeft: 200, - opacity: 0 - }, 1000); - setTimeout(function() { - var ml = cssInt( "marginLeft" ), - l = cssInt( "left" ); - notEqual( ml, 0, "Margin left is not 0 after partial animate" ); - notEqual( ml, 200, "Margin left is not 200 after partial animate" ); - notEqual( l, 0, "Left is not 0 after partial animate" ); - notEqual( l, 200, "Left is not 200 after partial animate" ); - div.stop().remove(); - start(); - }, 100); -}); - -test("callbacks should fire in correct order (#9100)", function() { - stop(); - var a = 1, - cb = 0, - $lis = jQuery("

    ").appendTo("#qunit-fixture") - // The test will always pass if no properties are animated or if the duration is 0 - .animate({fontSize: 12}, 13, function() { - a *= jQuery(this).data("operation") === "*2" ? 2 : a; - cb++; - if ( cb === 2 ) { - equal( a, 4, "test value has been *2 and _then_ ^2"); - start(); - } - }); -}); diff --git a/test/unit/event.js b/test/unit/event.js index 7c628880..b7b26046 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -14,28 +14,8 @@ test("null or undefined handler", function() { } catch (e) {} }); -test("bind(),live(),delegate() with non-null,defined data", function() { - - expect(3); - - var handler = function( event, data ) { - equal( data, 0, "non-null, defined data (zero) is correctly passed" ); - }; - - jQuery("#foo").bind("foo", handler); - jQuery("#foo").live("foo", handler); - jQuery("div").delegate("#foo", "foo", handler); - - jQuery("#foo").trigger("foo", 0); - - jQuery("#foo").unbind("foo", handler); - jQuery("#foo").die("foo", handler); - jQuery("div").undelegate("#foo", "foo"); - -}); - test("bind(), with data", function() { - expect(4); + expect(3); var handler = function(event) { ok( event.data, "bind() with data, check passed data exists" ); equals( event.data.foo, "bar", "bind() with data, Check value of passed data" ); @@ -43,12 +23,6 @@ test("bind(), with data", function() { jQuery("#firstp").bind("click", {foo: "bar"}, handler).click().unbind("click", handler); ok( !jQuery._data(jQuery("#firstp")[0], "events"), "Event handler unbound when using data." ); - - var test = function(){}; - var handler2 = function(event) { - equals( event.data, test, "bind() with function data, Check value of passed data" ); - }; - jQuery("#firstp").bind("click", test, handler2).click().unbind("click", handler2); }); test("click(), with data", function() { @@ -88,22 +62,6 @@ test("bind(), multiple events at once", function() { equals( mouseoverCounter, 1, "bind() with multiple events at once" ); }); -test("bind(), five events at once", function() { - expect(1); - - var count = 0, - handler = function(event) { - count++; - }; - - jQuery("#firstp").bind("click mouseover foo bar baz", handler) - .trigger("click").trigger("mouseover") - .trigger("foo").trigger("bar") - .trigger("baz"); - - equals( count, 5, "bind() five events at once" ); -}); - test("bind(), multiple events at once and namespaces", function() { expect(7); @@ -205,7 +163,7 @@ test("bind(), namespace with special add", function() { }); // Should trigger 2 - div.appendTo("#qunit-fixture").remove(); + div.appendTo("#main").remove(); delete jQuery.event.special.test; }); @@ -343,11 +301,11 @@ test("live/delegate immediate propagation", function() { test("bind/delegate bubbling, isDefaultPrevented", function() { expect(2); var $anchor2 = jQuery( "#anchor2" ), - $main = jQuery( "#qunit-fixture" ), + $main = jQuery( "#main" ), fakeClick = function($jq) { // Use a native click so we don't get jQuery simulated bubbling if ( document.createEvent ) { - var e = document.createEvent( "MouseEvents" ); + var e = document.createEvent( 'MouseEvents' ); e.initEvent( "click", true, true ); $jq[0].dispatchEvent(e); } @@ -389,7 +347,7 @@ test("bind(), iframes", function() { jQuery("div", doc).bind("click", function() { ok( true, "Binding to element inside iframe" ); - }).click().unbind("click"); + }).click().unbind('click'); }); test("bind(), trigger change on select", function() { @@ -399,8 +357,8 @@ test("bind(), trigger change on select", function() { equals( event.data, counter++, "Event.data is not a global event object" ); }; jQuery("#form select").each(function(i){ - jQuery(this).bind("change", i, selectOnChange); - }).trigger("change"); + jQuery(this).bind('change', i, selectOnChange); + }).trigger('change'); }); test("bind(), namespaced events, cloned events", 18, function() { @@ -451,7 +409,7 @@ test("bind(), namespaced events, cloned events", 18, function() { }).trigger("tester"); // Make sure events stick with appendTo'd elements (which are cloned) #2027 - jQuery("test").click(function(){ return false; }).appendTo("#qunit-fixture"); + jQuery("test").click(function(){ return false; }).appendTo("#main"); ok( jQuery("a.test:first").triggerHandler("click") === false, "Handler is bound to appendTo'd elements" ); }); @@ -574,7 +532,7 @@ test("bind(name, false), unbind(name, false)", function() { expect(3); var main = 0; - jQuery("#qunit-fixture").bind("click", function(e){ main++; }); + jQuery("#main").bind("click", function(e){ main++; }); jQuery("#ap").trigger("click"); equals( main, 1, "Verify that the trigger happened correctly." ); @@ -589,48 +547,7 @@ test("bind(name, false), unbind(name, false)", function() { equals( main, 1, "Verify that the trigger happened correctly." ); // manually clean up events from elements outside the fixture - jQuery("#qunit-fixture").unbind("click"); -}); - -test("live(name, false), die(name, false)", function() { - expect(3); - - var main = 0; - jQuery("#qunit-fixture").live("click", function(e){ main++; }); - jQuery("#ap").trigger("click"); - equals( main, 1, "Verify that the trigger happened correctly." ); - - main = 0; - jQuery("#ap").live("click", false); - jQuery("#ap").trigger("click"); - equals( main, 0, "Verify that no bubble happened." ); - - main = 0; - jQuery("#ap").die("click", false); - jQuery("#ap").trigger("click"); - equals( main, 1, "Verify that the trigger happened correctly." ); - jQuery("#qunit-fixture").die("click"); -}); - -test("delegate(selector, name, false), undelegate(selector, name, false)", function() { - expect(3); - - var main = 0; - - jQuery("#qunit-fixture").delegate("#ap", "click", function(e){ main++; }); - jQuery("#ap").trigger("click"); - equals( main, 1, "Verify that the trigger happened correctly." ); - - main = 0; - jQuery("#ap").delegate("#groups", "click", false); - jQuery("#groups").trigger("click"); - equals( main, 0, "Verify that no bubble happened." ); - - main = 0; - jQuery("#ap").undelegate("#groups", "click", false); - jQuery("#groups").trigger("click"); - equals( main, 1, "Verify that the trigger happened correctly." ); - jQuery("#qunit-fixture").undelegate("#ap", "click"); + jQuery("#main").unbind("click"); }); test("bind()/trigger()/unbind() on plain object", function() { @@ -688,23 +605,23 @@ test("unbind(type)", function() { } message = "unbind passing function"; - $elem.bind("error1", error).unbind("error1", error).triggerHandler("error1"); + $elem.bind('error1', error).unbind('error1',error).triggerHandler('error1'); message = "unbind all from event"; - $elem.bind("error1", error).unbind("error1").triggerHandler("error1"); + $elem.bind('error1', error).unbind('error1').triggerHandler('error1'); message = "unbind all"; - $elem.bind("error1", error).unbind().triggerHandler("error1"); + $elem.bind('error1', error).unbind().triggerHandler('error1'); message = "unbind many with function"; - $elem.bind("error1 error2",error) - .unbind("error1 error2", error ) - .trigger("error1").triggerHandler("error2"); + $elem.bind('error1 error2',error) + .unbind('error1 error2', error ) + .trigger('error1').triggerHandler('error2'); message = "unbind many"; // #3538 - $elem.bind("error1 error2", error) - .unbind("error1 error2") - .trigger("error1").triggerHandler("error2"); + $elem.bind('error1 error2',error) + .unbind('error1 error2') + .trigger('error1').triggerHandler('error2'); message = "unbind without a type or handler"; $elem.bind("error1 error2.test",error) @@ -720,28 +637,28 @@ test("unbind(eventObject)", function() { function assert( expected ){ num = 0; - $elem.trigger("foo").triggerHandler("bar"); + $elem.trigger('foo').triggerHandler('bar'); equals( num, expected, "Check the right handlers are triggered" ); } $elem // This handler shouldn't be unbound - .bind("foo", function(){ + .bind('foo', function(){ num += 1; }) - .bind("foo", function(e){ + .bind('foo', function(e){ $elem.unbind( e ) num += 2; }) // Neither this one - .bind("bar", function(){ + .bind('bar', function(){ num += 4; }); assert( 7 ); assert( 5 ); - $elem.unbind("bar"); + $elem.unbind('bar'); assert( 1 ); $elem.unbind(); @@ -766,63 +683,12 @@ test("hover()", function() { equals( times, 4, "hover handlers fired" ); }); -test("mouseover triggers mouseenter", function() { - expect(1); - - var count = 0, - elem = jQuery(""); - elem.mouseenter(function () { - count++; - }); - elem.trigger("mouseover"); - equals(count, 1, "make sure mouseover triggers a mouseenter" ); - - elem.remove(); -}); - -test("withinElement implemented with jQuery.contains()", function() { - - expect(1); - - jQuery("#qunit-fixture").append('
    '); - - jQuery("#jc-outer").bind("mouseenter mouseleave", function( event ) { - - equal( this.id, "jc-outer", this.id + " " + event.type ); - - }).trigger("mouseenter"); - - jQuery("#jc-inner").trigger("mousenter"); - - jQuery("#jc-outer").unbind("mouseenter mouseleave").remove(); - jQuery("#jc-inner").remove(); - -}); - -test("mouseenter, mouseleave don't catch exceptions", function() { - expect(2); - - var elem = jQuery("#firstp").hover(function() { throw "an Exception"; }); - - try { - elem.mouseenter(); - } catch (e) { - equals( e, "an Exception", "mouseenter doesn't catch exceptions" ); - } - - try { - elem.mouseleave(); - } catch (e) { - equals( e, "an Exception", "mouseleave doesn't catch exceptions" ); - } -}); - test("trigger() shortcuts", function() { expect(6); - var elem = jQuery("
  • Change location
  • ").prependTo("#firstUL"); - elem.find("a").bind("click", function() { - var close = jQuery("spanx", this); // same with jQuery(this).find("span"); + var elem = jQuery('
  • Change location
  • ').prependTo('#firstUL'); + elem.find('a').bind('click', function() { + var close = jQuery('spanx', this); // same with jQuery(this).find('span'); equals( close.length, 0, "Context element does not exist, length must be zero" ); ok( !close[0], "Context element does not exist, direct access to element must return undefined" ); return false; @@ -836,57 +702,48 @@ test("trigger() shortcuts", function() { }).click(); var counter = 0; - jQuery("#firstp")[0].onclick = function(event) { + jQuery('#firstp')[0].onclick = function(event) { counter++; }; - jQuery("#firstp").click(); + jQuery('#firstp').click(); equals( counter, 1, "Check that click, triggers onclick event handler also" ); var clickCounter = 0; - jQuery("#simon1")[0].onclick = function(event) { + jQuery('#simon1')[0].onclick = function(event) { clickCounter++; }; - jQuery("#simon1").click(); + jQuery('#simon1').click(); equals( clickCounter, 1, "Check that click, triggers onclick event handler on an a tag also" ); - elem = jQuery("").load(function(){ + elem = jQuery('').load(function(){ ok( true, "Trigger the load event, using the shortcut .load() (#2819)"); }).load(); // manually clean up detached elements elem.remove(); - - // test that special handlers do not blow up with VML elements (#7071) - jQuery('').appendTo('head'); - jQuery(' ').appendTo('#form'); - jQuery("#oval").click().keydown(); }); test("trigger() bubbling", function() { - expect(17); + expect(14); - var win = 0, doc = 0, html = 0, body = 0, main = 0, ap = 0; + var doc = 0, html = 0, body = 0, main = 0, ap = 0; - jQuery(window).bind("click", function(e){ win++; }); jQuery(document).bind("click", function(e){ if ( e.target !== document) { doc++; } }); jQuery("html").bind("click", function(e){ html++; }); jQuery("body").bind("click", function(e){ body++; }); - jQuery("#qunit-fixture").bind("click", function(e){ main++; }); + jQuery("#main").bind("click", function(e){ main++; }); jQuery("#ap").bind("click", function(){ ap++; return false; }); jQuery("html").trigger("click"); - equals( win, 1, "HTML bubble" ); equals( doc, 1, "HTML bubble" ); equals( html, 1, "HTML bubble" ); jQuery("body").trigger("click"); - equals( win, 2, "Body bubble" ); equals( doc, 2, "Body bubble" ); equals( html, 2, "Body bubble" ); equals( body, 1, "Body bubble" ); - jQuery("#qunit-fixture").trigger("click"); - equals( win, 3, "Main bubble" ); + jQuery("#main").trigger("click"); equals( doc, 3, "Main bubble" ); equals( html, 3, "Main bubble" ); equals( body, 2, "Main bubble" ); @@ -901,11 +758,11 @@ test("trigger() bubbling", function() { // manually clean up events from elements outside the fixture jQuery(document).unbind("click"); - jQuery("html, body, #qunit-fixture").unbind("click"); + jQuery("html, body, #main").unbind("click"); }); test("trigger(type, [data], [fn])", function() { - expect(16); + expect(14); var handler = function(event, a, b, c) { equals( event.type, "click", "check passed data" ); @@ -922,24 +779,7 @@ test("trigger(type, [data], [fn])", function() { ok( true, "Native call was triggered" ); }; - - $elem.live('mouseenter', function(){ - ok( true, 'Trigger mouseenter bound by live' ); - }); - - $elem.live('mouseleave', function(){ - ok( true, 'Trigger mouseleave bound by live' ); - }); - - $elem.trigger('mouseenter'); - - $elem.trigger('mouseleave'); - - $elem.die('mouseenter'); - - $elem.die('mouseleave'); - - // Triggers handlrs and native + // Triggers handlrs and native // Trigger 5 $elem.bind("click", handler).trigger("click", [1, "2", "abc"]); @@ -954,7 +794,7 @@ test("trigger(type, [data], [fn])", function() { var pass = true; try { - jQuery("#form input:first").hide().trigger("focus"); + jQuery('#form input:first').hide().trigger('focus'); } catch(e) { pass = false; } @@ -962,7 +802,7 @@ test("trigger(type, [data], [fn])", function() { pass = true; try { - jQuery("#qunit-fixture table:first").bind("test:test", function(){}).trigger("test:test"); + jQuery('#main table:first').bind('test:test', function(){}).trigger('test:test'); } catch (e) { pass = false; } @@ -1000,8 +840,8 @@ test("jQuery.Event.currentTarget", function(){ test("trigger(eventObject, [data], [fn])", function() { expect(25); - var $parent = jQuery("
    ").hide().appendTo("body"), - $child = jQuery("

    foo

    ").appendTo( $parent ); + var $parent = jQuery('
    ').hide().appendTo('body'), + $child = jQuery('

    foo

    ').appendTo( $parent ); var event = jQuery.Event("noNew"); ok( event != window, "Instantiate jQuery.Event without the 'new' keyword" ); @@ -1021,21 +861,21 @@ test("trigger(eventObject, [data], [fn])", function() { equals( event.isPropagationStopped(), true, "Verify isPropagationStopped" ); equals( event.isImmediatePropagationStopped(), true, "Verify isPropagationStopped" ); - $parent.bind("foo",function(e){ + $parent.bind('foo',function(e){ // Tries bubbling - equals( e.type, "foo", "Verify event type when passed passing an event object" ); - equals( e.target.id, "child", "Verify event.target when passed passing an event object" ); - equals( e.currentTarget.id, "par", "Verify event.target when passed passing an event object" ); - equals( e.secret, "boo!", "Verify event object's custom attribute when passed passing an event object" ); + equals( e.type, 'foo', 'Verify event type when passed passing an event object' ); + equals( e.target.id, 'child', 'Verify event.target when passed passing an event object' ); + equals( e.currentTarget.id, 'par', 'Verify event.target when passed passing an event object' ); + equals( e.secret, 'boo!', 'Verify event object\'s custom attribute when passed passing an event object' ); }); // test with an event object event = new jQuery.Event("foo"); - event.secret = "boo!"; + event.secret = 'boo!'; $child.trigger(event); // test with a literal object - $child.trigger({type: "foo", secret: "boo!"}); + $child.trigger({type:'foo', secret:'boo!'}); $parent.unbind(); @@ -1043,9 +883,9 @@ test("trigger(eventObject, [data], [fn])", function() { ok( false, "This assertion shouldn't be reached"); } - $parent.bind("foo", error ); + $parent.bind('foo', error ); - $child.bind("foo",function(e, a, b, c ){ + $child.bind('foo',function(e, a, b, c ){ equals( arguments.length, 4, "Check arguments length"); equals( a, 1, "Check first custom argument"); equals( b, 2, "Check second custom argument"); @@ -1063,50 +903,29 @@ test("trigger(eventObject, [data], [fn])", function() { // We should add this back in when we want to test the order // in which event handlers are iterated. - //$child.bind("foo", error ); + //$child.bind('foo', error ); event = new jQuery.Event("foo"); $child.trigger( event, [1,2,3] ).unbind(); equals( event.result, "result", "Check event.result attribute"); // Will error if it bubbles - $child.triggerHandler("foo"); + $child.triggerHandler('foo'); $child.unbind(); $parent.unbind().remove(); }); -test("jQuery.Event( type, props )", function() { - - expect(4); - - var event = jQuery.Event( "keydown", { keyCode: 64 }), - handler = function( event ) { - ok( "keyCode" in event, "Special property 'keyCode' exists" ); - equal( event.keyCode, 64, "event.keyCode has explicit value '64'" ); - }; - - // Supports jQuery.Event implementation - equal( event.type, "keydown", "Verify type" ); - - ok( "keyCode" in event, "Special 'keyCode' property exists" ); - - jQuery("body").bind( "keydown", handler ).trigger( event ); - - jQuery("body").unbind( "keydown" ); - -}); - test("jQuery.Event.currentTarget", function(){ expect(1); var counter = 0, - $elem = jQuery("").click(function(e){ + $elem = jQuery('').click(function(e){ equals( e.currentTarget, this, "Check currentTarget on "+(counter++?"native":"fake") +" event" ); }); // Fake event - $elem.trigger("click"); + $elem.trigger('click'); // Cleanup $elem.unbind(); @@ -1119,7 +938,7 @@ test("toggle(Function, Function, ...)", function() { fn1 = function(e) { count++; }, fn2 = function(e) { count--; }, preventDefault = function(e) { e.preventDefault() }, - link = jQuery("#mark"); + link = jQuery('#mark'); link.click(preventDefault).click().toggle(fn1, fn2).click().click().click().click().click(); equals( count, 1, "Check for toggle(fn, fn)" ); @@ -1163,8 +982,8 @@ test("toggle(Function, Function, ...)", function() { $div.click(); equals( turn, 2, "Trying toggle with 3 functions, attempt 5 yields 2"); - $div.unbind("click",fns[0]); - var data = jQuery._data( $div[0], "events" ); + $div.unbind('click',fns[0]); + var data = jQuery._data( $div[0], 'events' ); ok( !data, "Unbinding one function from toggle unbinds them all"); // manually clean up detached elements @@ -1279,12 +1098,12 @@ test(".live()/.die()", function() { jQuery("div").die("submit"); // Test binding with a different context - var clicked = 0, container = jQuery("#qunit-fixture")[0]; + var clicked = 0, container = jQuery('#main')[0]; jQuery("#foo", container).live("click", function(e){ clicked++; }); - jQuery("div").trigger("click"); - jQuery("#foo").trigger("click"); - jQuery("#qunit-fixture").trigger("click"); - jQuery("body").trigger("click"); + jQuery("div").trigger('click'); + jQuery("#foo").trigger('click'); + jQuery("#main").trigger('click'); + jQuery("body").trigger('click'); equals( clicked, 2, "live with a context" ); // Make sure the event is actually stored on the context @@ -1292,7 +1111,7 @@ test(".live()/.die()", function() { // Test unbinding with a different context jQuery("#foo", container).die("click"); - jQuery("#foo").trigger("click"); + jQuery("#foo").trigger('click'); equals( clicked, 2, "die with a context"); // Test binding with event data @@ -1374,9 +1193,9 @@ test(".live()/.die()", function() { // Make sure we don't loose the target by DOM modifications // after the bubble already reached the liveHandler - var livec = 0, elemDiv = jQuery("#nothiddendivchild").html("").get(0); + var livec = 0, elemDiv = jQuery("#nothiddendivchild").html('').get(0); - jQuery("#nothiddendivchild").live("click", function(e){ jQuery("#nothiddendivchild").html(""); }); + jQuery("#nothiddendivchild").live("click", function(e){ jQuery("#nothiddendivchild").html(''); }); jQuery("#nothiddendivchild").live("click", function(e){ if(e.target) {livec++;} }); jQuery("#nothiddendiv span").click(); @@ -1391,20 +1210,20 @@ test(".live()/.die()", function() { var lived = 0, livee = 0; // bind one pair in one order - jQuery("span#liveSpan1 a").live("click", function(){ lived++; return false; }); - jQuery("span#liveSpan1").live("click", function(){ livee++; }); + jQuery('span#liveSpan1 a').live('click', function(){ lived++; return false; }); + jQuery('span#liveSpan1').live('click', function(){ livee++; }); - jQuery("span#liveSpan1 a").click(); + jQuery('span#liveSpan1 a').click(); equals( lived, 1, "Verify that only one first handler occurred." ); equals( livee, 0, "Verify that second handler doesn't." ); // and one pair in inverse - jQuery("span#liveSpan2").live("click", function(){ livee++; }); - jQuery("span#liveSpan2 a").live("click", function(){ lived++; return false; }); + jQuery('span#liveSpan2').live('click', function(){ livee++; }); + jQuery('span#liveSpan2 a').live('click', function(){ lived++; return false; }); lived = 0; livee = 0; - jQuery("span#liveSpan2 a").click(); + jQuery('span#liveSpan2 a').click(); equals( lived, 1, "Verify that only one first handler occurred." ); equals( livee, 0, "Verify that second handler doesn't." ); @@ -1415,15 +1234,15 @@ test(".live()/.die()", function() { jQuery("span#liveSpan2").die("click"); // Test this, target and currentTarget are correct - jQuery("span#liveSpan1").live("click", function(e){ - equals( this.id, "liveSpan1", "Check the this within a live handler" ); - equals( e.currentTarget.id, "liveSpan1", "Check the event.currentTarget within a live handler" ); - equals( e.target.nodeName.toUpperCase(), "A", "Check the event.target within a live handler" ); + jQuery('span#liveSpan1').live('click', function(e){ + equals( this.id, 'liveSpan1', 'Check the this within a live handler' ); + equals( e.currentTarget.id, 'liveSpan1', 'Check the event.currentTarget within a live handler' ); + equals( e.target.nodeName.toUpperCase(), 'A', 'Check the event.target within a live handler' ); }); - jQuery("span#liveSpan1 a").click(); + jQuery('span#liveSpan1 a').click(); - jQuery("span#liveSpan1").die("click"); + jQuery('span#liveSpan1').die('click'); // Work with deep selectors livee = 0; @@ -1806,20 +1625,20 @@ test(".delegate()/.undelegate()", function() { jQuery("#body").undelegate("div", "submit"); // Test binding with a different context - var clicked = 0, container = jQuery("#qunit-fixture")[0]; - jQuery("#qunit-fixture").delegate("#foo", "click", function(e){ clicked++; }); - jQuery("div").trigger("click"); - jQuery("#foo").trigger("click"); - jQuery("#qunit-fixture").trigger("click"); - jQuery("body").trigger("click"); + var clicked = 0, container = jQuery('#main')[0]; + jQuery("#main").delegate("#foo", "click", function(e){ clicked++; }); + jQuery("div").trigger('click'); + jQuery("#foo").trigger('click'); + jQuery("#main").trigger('click'); + jQuery("body").trigger('click'); equals( clicked, 2, "delegate with a context" ); // Make sure the event is actually stored on the context ok( jQuery._data(container, "events").live, "delegate with a context" ); // Test unbinding with a different context - jQuery("#qunit-fixture").undelegate("#foo", "click"); - jQuery("#foo").trigger("click"); + jQuery("#main").undelegate("#foo", "click"); + jQuery("#foo").trigger('click'); equals( clicked, 2, "undelegate with a context"); // Test binding with event data @@ -1905,9 +1724,9 @@ test(".delegate()/.undelegate()", function() { // Make sure we don't loose the target by DOM modifications // after the bubble already reached the liveHandler - var livec = 0, elemDiv = jQuery("#nothiddendivchild").html("").get(0); + var livec = 0, elemDiv = jQuery("#nothiddendivchild").html('').get(0); - jQuery("#body").delegate("#nothiddendivchild", "click", function(e){ jQuery("#nothiddendivchild").html(""); }); + jQuery("#body").delegate("#nothiddendivchild", "click", function(e){ jQuery("#nothiddendivchild").html(''); }); jQuery("#body").delegate("#nothiddendivchild", "click", function(e){ if(e.target) {livec++;} }); jQuery("#nothiddendiv span").click(); @@ -1922,20 +1741,20 @@ test(".delegate()/.undelegate()", function() { var lived = 0, livee = 0; // bind one pair in one order - jQuery("#body").delegate("span#liveSpan1 a", "click", function(){ lived++; return false; }); - jQuery("#body").delegate("span#liveSpan1", "click", function(){ livee++; }); + jQuery("#body").delegate('span#liveSpan1 a', 'click', function(){ lived++; return false; }); + jQuery("#body").delegate('span#liveSpan1', 'click', function(){ livee++; }); - jQuery("span#liveSpan1 a").click(); + jQuery('span#liveSpan1 a').click(); equals( lived, 1, "Verify that only one first handler occurred." ); equals( livee, 0, "Verify that second handler doesn't." ); // and one pair in inverse - jQuery("#body").delegate("span#liveSpan2", "click", function(){ livee++; }); - jQuery("#body").delegate("span#liveSpan2 a", "click", function(){ lived++; return false; }); + jQuery("#body").delegate('span#liveSpan2', 'click', function(){ livee++; }); + jQuery("#body").delegate('span#liveSpan2 a', 'click', function(){ lived++; return false; }); lived = 0; livee = 0; - jQuery("span#liveSpan2 a").click(); + jQuery('span#liveSpan2 a').click(); equals( lived, 1, "Verify that only one first handler occurred." ); equals( livee, 0, "Verify that second handler doesn't." ); @@ -1943,15 +1762,15 @@ test(".delegate()/.undelegate()", function() { jQuery("#body").undelegate("click"); // Test this, target and currentTarget are correct - jQuery("#body").delegate("span#liveSpan1", "click", function(e){ - equals( this.id, "liveSpan1", "Check the this within a delegate handler" ); - equals( e.currentTarget.id, "liveSpan1", "Check the event.currentTarget within a delegate handler" ); - equals( e.target.nodeName.toUpperCase(), "A", "Check the event.target within a delegate handler" ); + jQuery("#body").delegate('span#liveSpan1', 'click', function(e){ + equals( this.id, 'liveSpan1', 'Check the this within a delegate handler' ); + equals( e.currentTarget.id, 'liveSpan1', 'Check the event.currentTarget within a delegate handler' ); + equals( e.target.nodeName.toUpperCase(), 'A', 'Check the event.target within a delegate handler' ); }); - jQuery("span#liveSpan1 a").click(); + jQuery('span#liveSpan1 a').click(); - jQuery("#body").undelegate("span#liveSpan1", "click"); + jQuery("#body").undelegate('span#liveSpan1', 'click'); // Work with deep selectors livee = 0; @@ -2123,37 +1942,16 @@ test("delegate with submit", function() { jQuery(document).undelegate(); }); -test("undelegate() with only namespaces", function() { - expect(2); - - var $delegate = jQuery("#liveHandlerOrder"), - count = 0; - - $delegate.delegate("a", "click.ns", function(e) { - count++; - }); - - jQuery("a", $delegate).eq(0).trigger("click.ns"); - - equals( count, 1, "delegated click.ns"); - - $delegate.undelegate(".ns"); - - jQuery("a", $delegate).eq(1).trigger("click.ns"); - - equals( count, 1, "no more .ns after undelegate"); -}); - test("Non DOM element events", function() { expect(1); var o = {}; - jQuery(o).bind("nonelementobj", function(e) { + jQuery(o).bind('nonelementobj', function(e) { ok( true, "Event on non-DOM object triggered" ); }); - jQuery(o).trigger("nonelementobj"); + jQuery(o).trigger('nonelementobj'); }); test("window resize", function() { @@ -2168,124 +1966,15 @@ test("window resize", function() { ok( !jQuery._data(window, "__events__"), "Make sure all the events are gone." ); }); -test("focusin bubbles", function() { - expect(5); - - var input = jQuery( "" ).prependTo( "body" ), - order = 0; - - jQuery( "body" ).bind( "focusin.focusinBubblesTest", function(){ - equals( 1, order++, "focusin on the body second" ); - }); - - input.bind( "focusin.focusinBubblesTest", function(){ - equals( 0, order++, "focusin on the element first" ); - }); - - // DOM focus method - input[0].focus(); - - // To make the next focus test work, we need to take focus off the input. - // This will fire another focusin event, so set order to reflect that. - order = 1; - jQuery("#text1")[0].focus(); - - // jQuery trigger, which calls DOM focus - order = 0; - input.trigger( "focus" ); - - input.remove(); - jQuery( "body" ).unbind( "focusin.focusinBubblesTest" ); -}); - -test("custom events with colons (#3533, #8272)", function() { - expect(1); - - var tab = jQuery("
    trigger
    ").appendTo("body"); - try { - tab.trigger("back:forth"); - ok( true, "colon events don't throw" ); - } catch ( e ) { - ok( false, "colon events die" ); - }; - tab.remove(); - -}); - -(function(){ - // This code must be run before DOM ready! - var notYetReady, noEarlyExecution, - order = [], - args = {}; - - notYetReady = !jQuery.isReady; - - test("jQuery.isReady", function() { - expect(2); - - equals(notYetReady, true, "jQuery.isReady should not be true before DOM ready"); - equals(jQuery.isReady, true, "jQuery.isReady should be true once DOM is ready"); - }); - - // Create an event handler. - function makeHandler( testId ) { - // When returned function is executed, push testId onto `order` array - // to ensure execution order. Also, store event handler arg to ensure - // the correct arg is being passed into the event handler. - return function( arg ) { - order.push(testId); - args[testId] = arg; - }; - } - - // Bind to the ready event in every possible way. - jQuery(makeHandler("a")); - jQuery(document).ready(makeHandler("b")); - jQuery(document).bind("ready.readytest", makeHandler("c")); - - // Do it twice, just to be sure. - jQuery(makeHandler("d")); - jQuery(document).ready(makeHandler("e")); - jQuery(document).bind("ready.readytest", makeHandler("f")); - - noEarlyExecution = order.length == 0; - - // This assumes that QUnit tests are run on DOM ready! - test("jQuery ready", function() { - expect(10); - - ok(noEarlyExecution, "Handlers bound to DOM ready should not execute before DOM ready"); - - // Ensure execution order. - same(order, ["a", "b", "d", "e", "c", "f"], "Bound DOM ready handlers should execute in bind-order, but those bound with jQuery(document).bind( 'ready', fn ) will always execute last"); - - // Ensure handler argument is correct. - equals(args.a, jQuery, "Argument passed to fn in jQuery( fn ) should be jQuery"); - equals(args.b, jQuery, "Argument passed to fn in jQuery(document).ready( fn ) should be jQuery"); - ok(args.c instanceof jQuery.Event, "Argument passed to fn in jQuery(document).bind( 'ready', fn ) should be an event object"); - - order = []; - - // Now that the ready event has fired, again bind to the ready event - // in every possible way. These event handlers should execute immediately. - jQuery(makeHandler("g")); - equals(order.pop(), "g", "Event handler should execute immediately"); - equals(args.g, jQuery, "Argument passed to fn in jQuery( fn ) should be jQuery"); - - jQuery(document).ready(makeHandler("h")); - equals(order.pop(), "h", "Event handler should execute immediately"); - equals(args.h, jQuery, "Argument passed to fn in jQuery(document).ready( fn ) should be jQuery"); - - jQuery(document).bind("ready.readytest", makeHandler("never")); - equals(order.length, 0, "Event handler should never execute since DOM ready has already passed"); - - // Cleanup. - jQuery(document).unbind("ready.readytest"); - }); - -})(); - /* +test("jQuery(function($) {})", function() { + stop(); + jQuery(function($) { + equals(jQuery, $, "ready doesn't provide an event object, instead it provides a reference to the jQuery function, see http://docs.jquery.com/Events/ready#fn"); + start(); + }); +}); + test("event properties", function() { stop(); jQuery("#simon1").click(function(event) { @@ -2294,4 +1983,3 @@ test("event properties", function() { }).click(); }); */ - diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index b9bc7587..34425ed3 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -9,7 +9,7 @@ var functionReturningObj = function(value) { return (function() { return value; test("text()", function() { expect(2); var expected = "This link has class=\"blog\": Simon Willison's Weblog"; - equals( jQuery("#sap").text(), expected, "Check for merged text of more then one element." ); + equals( jQuery('#sap').text(), expected, 'Check for merged text of more then one element.' ); // Check serialization of text values equals( jQuery(document.createTextNode("foo")).text(), "foo", "Text node was retreived from .text()." ); @@ -43,34 +43,34 @@ test("text(Function) with incoming value", function() { var old = "This link has class=\"blog\": Simon Willison's Weblog"; - jQuery("#sap").text(function(i, val) { + jQuery('#sap').text(function(i, val) { equals( val, old, "Make sure the incoming value is correct." ); return "foobar"; }); - equals( jQuery("#sap").text(), "foobar", "Check for merged text of more then one element." ); + equals( jQuery("#sap").text(), "foobar", 'Check for merged text of more then one element.' ); QUnit.reset(); }); var testWrap = function(val) { expect(19); - var defaultText = "Try them out:" - var result = jQuery("#first").wrap(val( "
    " )).text(); - equals( defaultText, result, "Check for wrapping of on-the-fly html" ); - ok( jQuery("#first").parent().parent().is(".red"), "Check if wrapper has class 'red'" ); + var defaultText = 'Try them out:' + var result = jQuery('#first').wrap(val( '
    ' )).text(); + equals( defaultText, result, 'Check for wrapping of on-the-fly html' ); + ok( jQuery('#first').parent().parent().is('.red'), 'Check if wrapper has class "red"' ); QUnit.reset(); - var defaultText = "Try them out:" - var result = jQuery("#first").wrap(val( document.getElementById("empty") )).parent(); - ok( result.is("ol"), "Check for element wrapping" ); - equals( result.text(), defaultText, "Check for element wrapping" ); + var defaultText = 'Try them out:' + var result = jQuery('#first').wrap(val( document.getElementById('empty') )).parent(); + ok( result.is('ol'), 'Check for element wrapping' ); + equals( result.text(), defaultText, 'Check for element wrapping' ); QUnit.reset(); - jQuery("#check1").click(function() { + jQuery('#check1').click(function() { var checkbox = this; ok( checkbox.checked, "Checkbox's state is erased after wrap() action, see #769" ); - jQuery(checkbox).wrap(val( "" )); + jQuery(checkbox).wrap(val( '' )); ok( checkbox.checked, "Checkbox's state is erased after wrap() action, see #769" ); }).click(); @@ -143,17 +143,17 @@ var testWrapAll = function(val) { var prev = jQuery("#firstp")[0].previousSibling; var p = jQuery("#firstp,#first")[0].parentNode; - var result = jQuery("#firstp,#first").wrapAll(val( "
    " )); - equals( result.parent().length, 1, "Check for wrapping of on-the-fly html" ); - ok( jQuery("#first").parent().parent().is(".red"), "Check if wrapper has class 'red'" ); - ok( jQuery("#firstp").parent().parent().is(".red"), "Check if wrapper has class 'red'" ); + var result = jQuery('#firstp,#first').wrapAll(val( '
    ' )); + equals( result.parent().length, 1, 'Check for wrapping of on-the-fly html' ); + ok( jQuery('#first').parent().parent().is('.red'), 'Check if wrapper has class "red"' ); + ok( jQuery('#firstp').parent().parent().is('.red'), 'Check if wrapper has class "red"' ); equals( jQuery("#first").parent().parent()[0].previousSibling, prev, "Correct Previous Sibling" ); equals( jQuery("#first").parent().parent()[0].parentNode, p, "Correct Parent" ); QUnit.reset(); var prev = jQuery("#firstp")[0].previousSibling; var p = jQuery("#first")[0].parentNode; - var result = jQuery("#firstp,#first").wrapAll(val( document.getElementById("empty") )); + var result = jQuery('#firstp,#first').wrapAll(val( document.getElementById('empty') )); equals( jQuery("#first").parent()[0], jQuery("#firstp").parent()[0], "Same Parent" ); equals( jQuery("#first").parent()[0].previousSibling, prev, "Correct Previous Sibling" ); equals( jQuery("#first").parent()[0].parentNode, p, "Correct Parent" ); @@ -166,21 +166,21 @@ test("wrapAll(String|Element)", function() { var testWrapInner = function(val) { expect(11); var num = jQuery("#first").children().length; - var result = jQuery("#first").wrapInner(val("
    ")); + var result = jQuery('#first').wrapInner(val('
    ')); equals( jQuery("#first").children().length, 1, "Only one child" ); ok( jQuery("#first").children().is(".red"), "Verify Right Element" ); equals( jQuery("#first").children().children().children().length, num, "Verify Elements Intact" ); QUnit.reset(); var num = jQuery("#first").html("foo
    test
    test2
    ").children().length; - var result = jQuery("#first").wrapInner(val("
    ")); + var result = jQuery('#first').wrapInner(val('
    ')); equals( jQuery("#first").children().length, 1, "Only one child" ); ok( jQuery("#first").children().is(".red"), "Verify Right Element" ); equals( jQuery("#first").children().children().children().length, num, "Verify Elements Intact" ); QUnit.reset(); var num = jQuery("#first").children().length; - var result = jQuery("#first").wrapInner(val(document.getElementById("empty"))); + var result = jQuery('#first').wrapInner(val(document.getElementById('empty'))); equals( jQuery("#first").children().length, 1, "Only one child" ); ok( jQuery("#first").children().is("#empty"), "Verify Right Element" ); equals( jQuery("#first").children().children().length, num, "Verify Elements Intact" ); @@ -202,51 +202,51 @@ test("wrapInner(Function)", function() { test("unwrap()", function() { expect(9); - jQuery("body").append(" "); + jQuery("body").append(' '); - var abcd = jQuery("#unwrap1 > span, #unwrap2 > span").get(), - abcdef = jQuery("#unwrap span").get(); + var abcd = jQuery('#unwrap1 > span, #unwrap2 > span').get(), + abcdef = jQuery('#unwrap span').get(); - equals( jQuery("#unwrap1 span").add("#unwrap2 span:first").unwrap().length, 3, "make #unwrap1 and #unwrap2 go away" ); - same( jQuery("#unwrap > span").get(), abcd, "all four spans should still exist" ); + equals( jQuery('#unwrap1 span').add('#unwrap2 span:first').unwrap().length, 3, 'make #unwrap1 and #unwrap2 go away' ); + same( jQuery('#unwrap > span').get(), abcd, 'all four spans should still exist' ); - same( jQuery("#unwrap3 span").unwrap().get(), jQuery("#unwrap3 > span").get(), "make all b in #unwrap3 go away" ); + same( jQuery('#unwrap3 span').unwrap().get(), jQuery('#unwrap3 > span').get(), 'make all b in #unwrap3 go away' ); - same( jQuery("#unwrap3 span").unwrap().get(), jQuery("#unwrap > span.unwrap3").get(), "make #unwrap3 go away" ); + same( jQuery('#unwrap3 span').unwrap().get(), jQuery('#unwrap > span.unwrap3').get(), 'make #unwrap3 go away' ); - same( jQuery("#unwrap").children().get(), abcdef, "#unwrap only contains 6 child spans" ); + same( jQuery('#unwrap').children().get(), abcdef, '#unwrap only contains 6 child spans' ); - same( jQuery("#unwrap > span").unwrap().get(), jQuery("body > span.unwrap").get(), "make the 6 spans become children of body" ); + same( jQuery('#unwrap > span').unwrap().get(), jQuery('body > span.unwrap').get(), 'make the 6 spans become children of body' ); - same( jQuery("body > span.unwrap").unwrap().get(), jQuery("body > span.unwrap").get(), "can't unwrap children of body" ); - same( jQuery("body > span.unwrap").unwrap().get(), abcdef, "can't unwrap children of body" ); + same( jQuery('body > span.unwrap').unwrap().get(), jQuery('body > span.unwrap').get(), 'can\'t unwrap children of body' ); + same( jQuery('body > span.unwrap').unwrap().get(), abcdef, 'can\'t unwrap children of body' ); - same( jQuery("body > span.unwrap").get(), abcdef, "body contains 6 .unwrap child spans" ); + same( jQuery('body > span.unwrap').get(), abcdef, 'body contains 6 .unwrap child spans' ); - jQuery("body > span.unwrap").remove(); + jQuery('body > span.unwrap').remove(); }); var testAppend = function(valueObj) { - expect(41); - var defaultText = "Try them out:" - var result = jQuery("#first").append(valueObj("buga")); - equals( result.text(), defaultText + "buga", "Check if text appending works" ); - equals( jQuery("#select3").append(valueObj("")).find("option:last-child").attr("value"), "appendTest", "Appending html options to select element"); + expect(37); + var defaultText = 'Try them out:' + var result = jQuery('#first').append(valueObj('buga')); + equals( result.text(), defaultText + 'buga', 'Check if text appending works' ); + equals( jQuery('#select3').append(valueObj('')).find('option:last-child').attr('value'), 'appendTest', 'Appending html options to select element'); QUnit.reset(); var expected = "This link has class=\"blog\": Simon Willison's WeblogTry them out:"; - jQuery("#sap").append(valueObj(document.getElementById("first"))); - equals( jQuery("#sap").text(), expected, "Check for appending of element" ); + jQuery('#sap').append(valueObj(document.getElementById('first'))); + equals( jQuery('#sap').text(), expected, "Check for appending of element" ); QUnit.reset(); expected = "This link has class=\"blog\": Simon Willison's WeblogTry them out:Yahoo"; - jQuery("#sap").append(valueObj([document.getElementById("first"), document.getElementById("yahoo")])); - equals( jQuery("#sap").text(), expected, "Check for appending of array of elements" ); + jQuery('#sap').append(valueObj([document.getElementById('first'), document.getElementById('yahoo')])); + equals( jQuery('#sap').text(), expected, "Check for appending of array of elements" ); QUnit.reset(); expected = "This link has class=\"blog\": Simon Willison's WeblogYahooTry them out:"; - jQuery("#sap").append(valueObj(jQuery("#yahoo, #first"))); - equals( jQuery("#sap").text(), expected, "Check for appending of jQuery object" ); + jQuery('#sap').append(valueObj(jQuery("#yahoo, #first"))); + equals( jQuery('#sap').text(), expected, "Check for appending of jQuery object" ); QUnit.reset(); jQuery("#sap").append(valueObj( 5 )); @@ -262,25 +262,25 @@ var testAppend = function(valueObj) { ok( jQuery("#sap").append(valueObj( document.getElementsByTagName("foo") )), "Check for appending an empty nodelist." ); QUnit.reset(); - jQuery("form").append(valueObj("")); + jQuery("form").append(valueObj('')); jQuery("form input[name=radiotest]").each(function(){ - ok( jQuery(this).is(":checked"), "Append checked radio"); + ok( jQuery(this).is(':checked'), "Append checked radio"); }).remove(); QUnit.reset(); - jQuery("form").append(valueObj("")); + jQuery("form").append(valueObj('')); jQuery("form input[name=radiotest]").each(function(){ - ok( jQuery(this).is(":checked"), "Append alternately formated checked radio"); + ok( jQuery(this).is(':checked'), "Append alternately formated checked radio"); }).remove(); QUnit.reset(); - jQuery("form").append(valueObj("")); + jQuery("form").append(valueObj('')); jQuery("form input[name=radiotest]").each(function(){ - ok( jQuery(this).is(":checked"), "Append HTML5-formated checked radio"); + ok( jQuery(this).is(':checked'), "Append HTML5-formated checked radio"); }).remove(); QUnit.reset(); - jQuery("#sap").append(valueObj( document.getElementById("form") )); + jQuery("#sap").append(valueObj( document.getElementById('form') )); equals( jQuery("#sap>form").size(), 1, "Check for appending a form" ); // Bug #910 QUnit.reset(); @@ -296,31 +296,31 @@ var testAppend = function(valueObj) { ok( pass, "Test for appending a DOM node to the contents of an IFrame" ); QUnit.reset(); - jQuery("
    ").appendTo("#form").append(valueObj( "test" )); - t( "Append legend", "#legend", ["legend"] ); + jQuery('
    ').appendTo('#form').append(valueObj( 'test' )); + t( 'Append legend', '#legend', ['legend'] ); QUnit.reset(); - jQuery("#select1").append(valueObj( "" )); - equals( jQuery("#select1 option:last").text(), "Test", "Appending <OPTION> (all caps)" ); + jQuery('#select1').append(valueObj( '' )); + equals( jQuery('#select1 option:last').text(), "Test", "Appending <OPTION> (all caps)" ); - jQuery("#table").append(valueObj( "" )); - ok( jQuery("#table colgroup").length, "Append colgroup" ); + jQuery('#table').append(valueObj( '' )); + ok( jQuery('#table colgroup').length, "Append colgroup" ); - jQuery("#table colgroup").append(valueObj( "" )); - ok( jQuery("#table colgroup col").length, "Append col" ); + jQuery('#table colgroup').append(valueObj( '' )); + ok( jQuery('#table colgroup col').length, "Append col" ); QUnit.reset(); - jQuery("#table").append(valueObj( "" )); - ok( jQuery("#table caption").length, "Append caption" ); + jQuery('#table').append(valueObj( '' )); + ok( jQuery('#table caption').length, "Append caption" ); QUnit.reset(); - jQuery("form:last") - .append(valueObj( "" )) - .append(valueObj( "" )); + jQuery('form:last') + .append(valueObj( '' )) + .append(valueObj( '' )); t( "Append Select", "#appendSelect1, #appendSelect2", ["appendSelect1", "appendSelect2"] ); - equals( "Two nodes", jQuery("
    ").append("Two", " nodes").text(), "Appending two text nodes (#4011)" ); + equals( "Two nodes", jQuery('
    ').append("Two", " nodes").text(), "Appending two text nodes (#4011)" ); // using contents will get comments regular, text, and comment nodes var j = jQuery("#nonnodes").contents(); @@ -330,31 +330,6 @@ var testAppend = function(valueObj) { d.contents().appendTo("#nonnodes"); d.remove(); ok( jQuery("#nonnodes").contents().length >= 2, "Check node,textnode,comment append cleanup worked" ); - - QUnit.reset(); - var $input = jQuery("").attr({ "type": "checkbox", "checked": true }).appendTo('#testForm'); - equals( $input[0].checked, true, "A checked checkbox that is appended stays checked" ); - - QUnit.reset(); - var $radios = jQuery("input:radio[name='R1']"), - $radioNot = jQuery("").insertAfter( $radios ), - $radio = $radios.eq(1).click(); - $radioNot[0].checked = false; - $radios.parent().wrap("
    "); - equals( $radio[0].checked, true, "Reappending radios uphold which radio is checked" ); - equals( $radioNot[0].checked, false, "Reappending radios uphold not being checked" ); - QUnit.reset(); - - var prev = jQuery("#sap").children().length; - - jQuery("#sap").append( - "", - "", - "" - ); - - equals( jQuery("#sap").children().length, prev + 3, "Make sure that multiple arguments works." ); - QUnit.reset(); } test("append(String|Element|Array<Element>|jQuery)", function() { @@ -368,51 +343,51 @@ test("append(Function)", function() { test("append(Function) with incoming value", function() { expect(12); - var defaultText = "Try them out:", old = jQuery("#first").html(); + var defaultText = 'Try them out:', old = jQuery("#first").html(); - var result = jQuery("#first").append(function(i, val){ + var result = jQuery('#first').append(function(i, val){ equals( val, old, "Make sure the incoming value is correct." ); - return "buga"; + return 'buga'; }); - equals( result.text(), defaultText + "buga", "Check if text appending works" ); + equals( result.text(), defaultText + 'buga', 'Check if text appending works' ); - var select = jQuery("#select3"); + var select = jQuery('#select3'); old = select.html(); equals( select.append(function(i, val){ equals( val, old, "Make sure the incoming value is correct." ); - return ""; - }).find("option:last-child").attr("value"), "appendTest", "Appending html options to select element"); + return ''; + }).find('option:last-child').attr('value'), 'appendTest', 'Appending html options to select element'); QUnit.reset(); var expected = "This link has class=\"blog\": Simon Willison's WeblogTry them out:"; old = jQuery("#sap").html(); - jQuery("#sap").append(function(i, val){ + jQuery('#sap').append(function(i, val){ equals( val, old, "Make sure the incoming value is correct." ); - return document.getElementById("first"); + return document.getElementById('first'); }); - equals( jQuery("#sap").text(), expected, "Check for appending of element" ); + equals( jQuery('#sap').text(), expected, "Check for appending of element" ); QUnit.reset(); expected = "This link has class=\"blog\": Simon Willison's WeblogTry them out:Yahoo"; old = jQuery("#sap").html(); - jQuery("#sap").append(function(i, val){ + jQuery('#sap').append(function(i, val){ equals( val, old, "Make sure the incoming value is correct." ); - return [document.getElementById("first"), document.getElementById("yahoo")]; + return [document.getElementById('first'), document.getElementById('yahoo')]; }); - equals( jQuery("#sap").text(), expected, "Check for appending of array of elements" ); + equals( jQuery('#sap').text(), expected, "Check for appending of array of elements" ); QUnit.reset(); expected = "This link has class=\"blog\": Simon Willison's WeblogYahooTry them out:"; old = jQuery("#sap").html(); - jQuery("#sap").append(function(i, val){ + jQuery('#sap').append(function(i, val){ equals( val, old, "Make sure the incoming value is correct." ); return jQuery("#yahoo, #first"); }); - equals( jQuery("#sap").text(), expected, "Check for appending of jQuery object" ); + equals( jQuery('#sap').text(), expected, "Check for appending of jQuery object" ); QUnit.reset(); old = jQuery("#sap").html(); @@ -439,11 +414,11 @@ test("append the same fragment with events (Bug #6997, 5566)", function () { if ( doExtra ) { element = jQuery("div:first").click(function () { ok(true, "Event exists on original after being unbound on clone"); - jQuery(this).unbind("click"); + jQuery(this).unbind('click'); }); - var clone = element.clone(true).unbind("click"); - clone[0].fireEvent("onclick"); - element[0].fireEvent("onclick"); + var clone = element.clone(true).unbind('click'); + clone[0].fireEvent('onclick'); + element[0].fireEvent('onclick'); // manually clean up detached elements clone.remove(); @@ -454,7 +429,7 @@ test("append the same fragment with events (Bug #6997, 5566)", function () { }); jQuery("#listWithTabIndex li").append(element) - .find("a.test6997").eq(1).click(); + .find('a.test6997').eq(1).click(); element = jQuery("
  • ").click(function () { ok(true, "Before second element events work"); @@ -465,47 +440,13 @@ test("append the same fragment with events (Bug #6997, 5566)", function () { jQuery("#listWithTabIndex li.test6997").eq(1).click(); }); -test("append(xml)", function() { - expect( 1 ); - - function createXMLDoc() { - // Initialize DOM based upon latest installed MSXML or Netscape - var elem, - aActiveX = - [ "MSXML6.DomDocument", - "MSXML3.DomDocument", - "MSXML2.DomDocument", - "MSXML.DomDocument", - "Microsoft.XmlDom" ]; - - if ( document.implementation && "createDocument" in document.implementation ) { - return document.implementation.createDocument( "", "", null ); - } else { - // IE - for ( var n = 0, len = aActiveX.length; n < len; n++ ) { - try { - elem = new ActiveXObject( aActiveX[ n ] ); - return elem; - } catch(_){}; - } - } - } - - var xmlDoc = createXMLDoc(), - xml1 = xmlDoc.createElement("head"), - xml2 = xmlDoc.createElement("test"); - - ok( jQuery( xml1 ).append( xml2 ), "Append an xml element to another without raising an exception." ); - -}); - test("appendTo(String|Element|Array<Element>|jQuery)", function() { expect(16); - var defaultText = "Try them out:" - jQuery("buga").appendTo("#first"); - equals( jQuery("#first").text(), defaultText + "buga", "Check if text appending works" ); - equals( jQuery("").appendTo("#select3").parent().find("option:last-child").attr("value"), "appendTest", "Appending html options to select element"); + var defaultText = 'Try them out:' + jQuery('buga').appendTo('#first'); + equals( jQuery("#first").text(), defaultText + 'buga', 'Check if text appending works' ); + equals( jQuery('').appendTo('#select3').parent().find('option:last-child').attr('value'), 'appendTest', 'Appending html options to select element'); QUnit.reset(); var l = jQuery("#first").children().length + 2; @@ -518,43 +459,43 @@ test("appendTo(String|Element|Array<Element>|jQuery)", function() { QUnit.reset(); var expected = "This link has class=\"blog\": Simon Willison's WeblogTry them out:"; - jQuery(document.getElementById("first")).appendTo("#sap"); - equals( jQuery("#sap").text(), expected, "Check for appending of element" ); + jQuery(document.getElementById('first')).appendTo('#sap'); + equals( jQuery('#sap').text(), expected, "Check for appending of element" ); QUnit.reset(); expected = "This link has class=\"blog\": Simon Willison's WeblogTry them out:Yahoo"; - jQuery([document.getElementById("first"), document.getElementById("yahoo")]).appendTo("#sap"); - equals( jQuery("#sap").text(), expected, "Check for appending of array of elements" ); + jQuery([document.getElementById('first'), document.getElementById('yahoo')]).appendTo('#sap'); + equals( jQuery('#sap').text(), expected, "Check for appending of array of elements" ); QUnit.reset(); ok( jQuery(document.createElement("script")).appendTo("body").length, "Make sure a disconnected script can be appended." ); QUnit.reset(); expected = "This link has class=\"blog\": Simon Willison's WeblogYahooTry them out:"; - jQuery("#yahoo, #first").appendTo("#sap"); - equals( jQuery("#sap").text(), expected, "Check for appending of jQuery object" ); + jQuery("#yahoo, #first").appendTo('#sap'); + equals( jQuery('#sap').text(), expected, "Check for appending of jQuery object" ); QUnit.reset(); - jQuery("#select1").appendTo("#foo"); - t( "Append select", "#foo select", ["select1"] ); + jQuery('#select1').appendTo('#foo'); + t( 'Append select', '#foo select', ['select1'] ); QUnit.reset(); var div = jQuery("
    ").click(function(){ ok(true, "Running a cloned click."); }); - div.appendTo("#qunit-fixture, #moretests"); + div.appendTo("#main, #moretests"); - jQuery("#qunit-fixture div:last").click(); + jQuery("#main div:last").click(); jQuery("#moretests div:last").click(); QUnit.reset(); - var div = jQuery("
    ").appendTo("#qunit-fixture, #moretests"); + var div = jQuery("
    ").appendTo("#main, #moretests"); equals( div.length, 2, "appendTo returns the inserted elements" ); div.addClass("test"); - ok( jQuery("#qunit-fixture div:last").hasClass("test"), "appendTo element was modified after the insertion" ); + ok( jQuery("#main div:last").hasClass("test"), "appendTo element was modified after the insertion" ); ok( jQuery("#moretests div:last").hasClass("test"), "appendTo element was modified after the insertion" ); QUnit.reset(); @@ -566,35 +507,35 @@ test("appendTo(String|Element|Array<Element>|jQuery)", function() { div = jQuery("#moretests div"); - var num = jQuery("#qunit-fixture div").length; - div.remove().appendTo("#qunit-fixture"); + var num = jQuery("#main div").length; + div.remove().appendTo("#main"); - equals( jQuery("#qunit-fixture div").length, num, "Make sure all the removed divs were inserted." ); + equals( jQuery("#main div").length, num, "Make sure all the removed divs were inserted." ); QUnit.reset(); }); var testPrepend = function(val) { expect(5); - var defaultText = "Try them out:" - var result = jQuery("#first").prepend(val( "buga" )); - equals( result.text(), "buga" + defaultText, "Check if text prepending works" ); - equals( jQuery("#select3").prepend(val( "" )).find("option:first-child").attr("value"), "prependTest", "Prepending html options to select element"); + var defaultText = 'Try them out:' + var result = jQuery('#first').prepend(val( 'buga' )); + equals( result.text(), 'buga' + defaultText, 'Check if text prepending works' ); + equals( jQuery('#select3').prepend(val( '' )).find('option:first-child').attr('value'), 'prependTest', 'Prepending html options to select element'); QUnit.reset(); var expected = "Try them out:This link has class=\"blog\": Simon Willison's Weblog"; - jQuery("#sap").prepend(val( document.getElementById("first") )); - equals( jQuery("#sap").text(), expected, "Check for prepending of element" ); + jQuery('#sap').prepend(val( document.getElementById('first') )); + equals( jQuery('#sap').text(), expected, "Check for prepending of element" ); QUnit.reset(); expected = "Try them out:YahooThis link has class=\"blog\": Simon Willison's Weblog"; - jQuery("#sap").prepend(val( [document.getElementById("first"), document.getElementById("yahoo")] )); - equals( jQuery("#sap").text(), expected, "Check for prepending of array of elements" ); + jQuery('#sap').prepend(val( [document.getElementById('first'), document.getElementById('yahoo')] )); + equals( jQuery('#sap').text(), expected, "Check for prepending of array of elements" ); QUnit.reset(); expected = "YahooTry them out:This link has class=\"blog\": Simon Willison's Weblog"; - jQuery("#sap").prepend(val( jQuery("#yahoo, #first") )); - equals( jQuery("#sap").text(), expected, "Check for prepending of jQuery object" ); + jQuery('#sap').prepend(val( jQuery("#yahoo, #first") )); + equals( jQuery('#sap').text(), expected, "Check for prepending of jQuery object" ); }; test("prepend(String|Element|Array<Element>|jQuery)", function() { @@ -608,103 +549,103 @@ test("prepend(Function)", function() { test("prepend(Function) with incoming value", function() { expect(10); - var defaultText = "Try them out:", old = jQuery("#first").html(); - var result = jQuery("#first").prepend(function(i, val) { + var defaultText = 'Try them out:', old = jQuery('#first').html(); + var result = jQuery('#first').prepend(function(i, val) { equals( val, old, "Make sure the incoming value is correct." ); - return "buga"; + return 'buga'; }); - equals( result.text(), "buga" + defaultText, "Check if text prepending works" ); + equals( result.text(), 'buga' + defaultText, 'Check if text prepending works' ); old = jQuery("#select3").html(); - equals( jQuery("#select3").prepend(function(i, val) { + equals( jQuery('#select3').prepend(function(i, val) { equals( val, old, "Make sure the incoming value is correct." ); - return ""; - }).find("option:first-child").attr("value"), "prependTest", "Prepending html options to select element"); + return ''; + }).find('option:first-child').attr('value'), 'prependTest', 'Prepending html options to select element'); QUnit.reset(); var expected = "Try them out:This link has class=\"blog\": Simon Willison's Weblog"; - old = jQuery("#sap").html(); + old = jQuery('#sap').html(); - jQuery("#sap").prepend(function(i, val) { + jQuery('#sap').prepend(function(i, val) { equals( val, old, "Make sure the incoming value is correct." ); - return document.getElementById("first"); + return document.getElementById('first'); }); - equals( jQuery("#sap").text(), expected, "Check for prepending of element" ); + equals( jQuery('#sap').text(), expected, "Check for prepending of element" ); QUnit.reset(); expected = "Try them out:YahooThis link has class=\"blog\": Simon Willison's Weblog"; - old = jQuery("#sap").html(); + old = jQuery('#sap').html(); - jQuery("#sap").prepend(function(i, val) { + jQuery('#sap').prepend(function(i, val) { equals( val, old, "Make sure the incoming value is correct." ); - return [document.getElementById("first"), document.getElementById("yahoo")]; + return [document.getElementById('first'), document.getElementById('yahoo')]; }); - equals( jQuery("#sap").text(), expected, "Check for prepending of array of elements" ); + equals( jQuery('#sap').text(), expected, "Check for prepending of array of elements" ); QUnit.reset(); expected = "YahooTry them out:This link has class=\"blog\": Simon Willison's Weblog"; - old = jQuery("#sap").html(); + old = jQuery('#sap').html(); - jQuery("#sap").prepend(function(i, val) { + jQuery('#sap').prepend(function(i, val) { equals( val, old, "Make sure the incoming value is correct." ); return jQuery("#yahoo, #first"); }); - equals( jQuery("#sap").text(), expected, "Check for prepending of jQuery object" ); + equals( jQuery('#sap').text(), expected, "Check for prepending of jQuery object" ); }); test("prependTo(String|Element|Array<Element>|jQuery)", function() { expect(6); - var defaultText = "Try them out:" - jQuery("buga").prependTo("#first"); - equals( jQuery("#first").text(), "buga" + defaultText, "Check if text prepending works" ); - equals( jQuery("").prependTo("#select3").parent().find("option:first-child").attr("value"), "prependTest", "Prepending html options to select element"); + var defaultText = 'Try them out:' + jQuery('buga').prependTo('#first'); + equals( jQuery('#first').text(), 'buga' + defaultText, 'Check if text prepending works' ); + equals( jQuery('').prependTo('#select3').parent().find('option:first-child').attr('value'), 'prependTest', 'Prepending html options to select element'); QUnit.reset(); var expected = "Try them out:This link has class=\"blog\": Simon Willison's Weblog"; - jQuery(document.getElementById("first")).prependTo("#sap"); - equals( jQuery("#sap").text(), expected, "Check for prepending of element" ); + jQuery(document.getElementById('first')).prependTo('#sap'); + equals( jQuery('#sap').text(), expected, "Check for prepending of element" ); QUnit.reset(); expected = "Try them out:YahooThis link has class=\"blog\": Simon Willison's Weblog"; - jQuery([document.getElementById("first"), document.getElementById("yahoo")]).prependTo("#sap"); - equals( jQuery("#sap").text(), expected, "Check for prepending of array of elements" ); + jQuery([document.getElementById('first'), document.getElementById('yahoo')]).prependTo('#sap'); + equals( jQuery('#sap').text(), expected, "Check for prepending of array of elements" ); QUnit.reset(); expected = "YahooTry them out:This link has class=\"blog\": Simon Willison's Weblog"; - jQuery("#yahoo, #first").prependTo("#sap"); - equals( jQuery("#sap").text(), expected, "Check for prepending of jQuery object" ); + jQuery("#yahoo, #first").prependTo('#sap'); + equals( jQuery('#sap').text(), expected, "Check for prepending of jQuery object" ); QUnit.reset(); - jQuery("").prependTo("form:last"); - jQuery("").prependTo("form:last"); + jQuery('').prependTo('form:last'); + jQuery('').prependTo('form:last'); t( "Prepend Select", "#prependSelect2, #prependSelect1", ["prependSelect2", "prependSelect1"] ); }); var testBefore = function(val) { expect(6); - var expected = "This is a normal link: bugaYahoo"; - jQuery("#yahoo").before(val( "buga" )); - equals( jQuery("#en").text(), expected, "Insert String before" ); + var expected = 'This is a normal link: bugaYahoo'; + jQuery('#yahoo').before(val( 'buga' )); + equals( jQuery('#en').text(), expected, 'Insert String before' ); QUnit.reset(); expected = "This is a normal link: Try them out:Yahoo"; - jQuery("#yahoo").before(val( document.getElementById("first") )); - equals( jQuery("#en").text(), expected, "Insert element before" ); + jQuery('#yahoo').before(val( document.getElementById('first') )); + equals( jQuery('#en').text(), expected, "Insert element before" ); QUnit.reset(); expected = "This is a normal link: Try them out:diveintomarkYahoo"; - jQuery("#yahoo").before(val( [document.getElementById("first"), document.getElementById("mark")] )); - equals( jQuery("#en").text(), expected, "Insert array of elements before" ); + jQuery('#yahoo').before(val( [document.getElementById('first'), document.getElementById('mark')] )); + equals( jQuery('#en').text(), expected, "Insert array of elements before" ); QUnit.reset(); expected = "This is a normal link: diveintomarkTry them out:Yahoo"; - jQuery("#yahoo").before(val( jQuery("#mark, #first") )); - equals( jQuery("#en").text(), expected, "Insert jQuery before" ); + jQuery('#yahoo').before(val( jQuery("#mark, #first") )); + equals( jQuery('#en').text(), expected, "Insert jQuery before" ); var set = jQuery("
    ").before("test"); equals( set[0].nodeName.toLowerCase(), "span", "Insert the element before the disconnected node." ); @@ -721,46 +662,46 @@ test("before(Function)", function() { test("insertBefore(String|Element|Array<Element>|jQuery)", function() { expect(4); - var expected = "This is a normal link: bugaYahoo"; - jQuery("buga").insertBefore("#yahoo"); - equals( jQuery("#en").text(), expected, "Insert String before" ); + var expected = 'This is a normal link: bugaYahoo'; + jQuery('buga').insertBefore('#yahoo'); + equals( jQuery('#en').text(), expected, 'Insert String before' ); QUnit.reset(); expected = "This is a normal link: Try them out:Yahoo"; - jQuery(document.getElementById("first")).insertBefore("#yahoo"); - equals( jQuery("#en").text(), expected, "Insert element before" ); + jQuery(document.getElementById('first')).insertBefore('#yahoo'); + equals( jQuery('#en').text(), expected, "Insert element before" ); QUnit.reset(); expected = "This is a normal link: Try them out:diveintomarkYahoo"; - jQuery([document.getElementById("first"), document.getElementById("mark")]).insertBefore("#yahoo"); - equals( jQuery("#en").text(), expected, "Insert array of elements before" ); + jQuery([document.getElementById('first'), document.getElementById('mark')]).insertBefore('#yahoo'); + equals( jQuery('#en').text(), expected, "Insert array of elements before" ); QUnit.reset(); expected = "This is a normal link: diveintomarkTry them out:Yahoo"; - jQuery("#mark, #first").insertBefore("#yahoo"); - equals( jQuery("#en").text(), expected, "Insert jQuery before" ); + jQuery("#mark, #first").insertBefore('#yahoo'); + equals( jQuery('#en').text(), expected, "Insert jQuery before" ); }); var testAfter = function(val) { expect(6); - var expected = "This is a normal link: Yahoobuga"; - jQuery("#yahoo").after(val( "buga" )); - equals( jQuery("#en").text(), expected, "Insert String after" ); + var expected = 'This is a normal link: Yahoobuga'; + jQuery('#yahoo').after(val( 'buga' )); + equals( jQuery('#en').text(), expected, 'Insert String after' ); QUnit.reset(); expected = "This is a normal link: YahooTry them out:"; - jQuery("#yahoo").after(val( document.getElementById("first") )); - equals( jQuery("#en").text(), expected, "Insert element after" ); + jQuery('#yahoo').after(val( document.getElementById('first') )); + equals( jQuery('#en').text(), expected, "Insert element after" ); QUnit.reset(); expected = "This is a normal link: YahooTry them out:diveintomark"; - jQuery("#yahoo").after(val( [document.getElementById("first"), document.getElementById("mark")] )); - equals( jQuery("#en").text(), expected, "Insert array of elements after" ); + jQuery('#yahoo').after(val( [document.getElementById('first'), document.getElementById('mark')] )); + equals( jQuery('#en').text(), expected, "Insert array of elements after" ); QUnit.reset(); expected = "This is a normal link: YahoodiveintomarkTry them out:"; - jQuery("#yahoo").after(val( jQuery("#mark, #first") )); - equals( jQuery("#en").text(), expected, "Insert jQuery after" ); + jQuery('#yahoo').after(val( jQuery("#mark, #first") )); + equals( jQuery('#en').text(), expected, "Insert jQuery after" ); var set = jQuery("
    ").after("test"); equals( set[1].nodeName.toLowerCase(), "span", "Insert the element after the disconnected node." ); @@ -777,58 +718,58 @@ test("after(Function)", function() { test("insertAfter(String|Element|Array<Element>|jQuery)", function() { expect(4); - var expected = "This is a normal link: Yahoobuga"; - jQuery("buga").insertAfter("#yahoo"); - equals( jQuery("#en").text(), expected, "Insert String after" ); + var expected = 'This is a normal link: Yahoobuga'; + jQuery('buga').insertAfter('#yahoo'); + equals( jQuery('#en').text(), expected, 'Insert String after' ); QUnit.reset(); expected = "This is a normal link: YahooTry them out:"; - jQuery(document.getElementById("first")).insertAfter("#yahoo"); - equals( jQuery("#en").text(), expected, "Insert element after" ); + jQuery(document.getElementById('first')).insertAfter('#yahoo'); + equals( jQuery('#en').text(), expected, "Insert element after" ); QUnit.reset(); expected = "This is a normal link: YahooTry them out:diveintomark"; - jQuery([document.getElementById("first"), document.getElementById("mark")]).insertAfter("#yahoo"); - equals( jQuery("#en").text(), expected, "Insert array of elements after" ); + jQuery([document.getElementById('first'), document.getElementById('mark')]).insertAfter('#yahoo'); + equals( jQuery('#en').text(), expected, "Insert array of elements after" ); QUnit.reset(); expected = "This is a normal link: YahoodiveintomarkTry them out:"; - jQuery("#mark, #first").insertAfter("#yahoo"); - equals( jQuery("#en").text(), expected, "Insert jQuery after" ); + jQuery("#mark, #first").insertAfter('#yahoo'); + equals( jQuery('#en').text(), expected, "Insert jQuery after" ); }); var testReplaceWith = function(val) { - expect(21); - jQuery("#yahoo").replaceWith(val( "buga" )); - ok( jQuery("#replace")[0], "Replace element with string" ); - ok( !jQuery("#yahoo")[0], "Verify that original element is gone, after string" ); + expect(20); + jQuery('#yahoo').replaceWith(val( 'buga' )); + ok( jQuery("#replace")[0], 'Replace element with string' ); + ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after string' ); QUnit.reset(); - jQuery("#yahoo").replaceWith(val( document.getElementById("first") )); - ok( jQuery("#first")[0], "Replace element with element" ); - ok( !jQuery("#yahoo")[0], "Verify that original element is gone, after element" ); + jQuery('#yahoo').replaceWith(val( document.getElementById('first') )); + ok( jQuery("#first")[0], 'Replace element with element' ); + ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after element' ); QUnit.reset(); - jQuery("#qunit-fixture").append("
    "); - jQuery("#baz").replaceWith("Baz"); - equals( jQuery("#bar").text(),"Baz", "Replace element with text" ); - ok( !jQuery("#baz")[0], "Verify that original element is gone, after element" ); + jQuery("#main").append('
    Foo
    '); + jQuery('#baz').replaceWith("Baz"); + equals( jQuery("#bar").text(),"Baz", 'Replace element with text' ); + ok( !jQuery("#baz")[0], 'Verify that original element is gone, after element' ); QUnit.reset(); - jQuery("#yahoo").replaceWith(val( [document.getElementById("first"), document.getElementById("mark")] )); - ok( jQuery("#first")[0], "Replace element with array of elements" ); - ok( jQuery("#mark")[0], "Replace element with array of elements" ); - ok( !jQuery("#yahoo")[0], "Verify that original element is gone, after array of elements" ); + jQuery('#yahoo').replaceWith(val( [document.getElementById('first'), document.getElementById('mark')] )); + ok( jQuery("#first")[0], 'Replace element with array of elements' ); + ok( jQuery("#mark")[0], 'Replace element with array of elements' ); + ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after array of elements' ); QUnit.reset(); - jQuery("#yahoo").replaceWith(val( jQuery("#mark, #first") )); - ok( jQuery("#first")[0], "Replace element with set of elements" ); - ok( jQuery("#mark")[0], "Replace element with set of elements" ); - ok( !jQuery("#yahoo")[0], "Verify that original element is gone, after set of elements" ); + jQuery('#yahoo').replaceWith(val( jQuery("#mark, #first") )); + ok( jQuery("#first")[0], 'Replace element with set of elements' ); + ok( jQuery("#mark")[0], 'Replace element with set of elements' ); + ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after set of elements' ); QUnit.reset(); var tmp = jQuery("
    ").appendTo("body").click(function(){ ok(true, "Newly bound click run." ); }); - var y = jQuery("
    ").appendTo("body").click(function(){ ok(true, "Previously bound click run." ); }); + var y = jQuery('
    ').appendTo("body").click(function(){ ok(true, "Previously bound click run." ); }); var child = y.append("test").find("b").click(function(){ ok(true, "Child bound click run." ); return false; }); y.replaceWith( tmp ); @@ -843,7 +784,7 @@ var testReplaceWith = function(val) { QUnit.reset(); - y = jQuery("
    ").appendTo("body").click(function(){ ok(true, "Previously bound click run." ); }); + y = jQuery('
    ').appendTo("body").click(function(){ ok(true, "Previously bound click run." ); }); var child2 = y.append("test").find("u").click(function(){ ok(true, "Child 2 bound click run." ); return false; }); y.replaceWith( child2 ); @@ -859,27 +800,24 @@ var testReplaceWith = function(val) { equals( set[0].nodeName.toLowerCase(), "span", "Replace the disconnected node." ); equals( set.length, 1, "Replace the disconnected node." ); - var non_existant = jQuery("#does-not-exist").replaceWith( val("should not throw an error") ); - equals( non_existant.length, 0, "Length of non existant element." ); - var $div = jQuery("
    ").appendTo("body"); // TODO: Work on jQuery(...) inline script execution //$div.replaceWith("
    "); - equals(jQuery(".replacewith").length, 1, "Check number of elements in page."); - jQuery(".replacewith").remove(); + equals(jQuery('.replacewith').length, 1, 'Check number of elements in page.'); + jQuery('.replacewith').remove(); QUnit.reset(); - jQuery("#qunit-fixture").append("
    "); - equals( jQuery("#qunit-fixture").find("div[id=replaceWith]").length, 1, "Make sure only one div exists." ); + jQuery("#main").append("
    "); + equals( jQuery("#main").find("div[id=replaceWith]").length, 1, "Make sure only one div exists." ); jQuery("#replaceWith").replaceWith( val("
    ") ); - equals( jQuery("#qunit-fixture").find("div[id=replaceWith]").length, 1, "Make sure only one div exists." ); + equals( jQuery("#main").find("div[id=replaceWith]").length, 1, "Make sure only one div exists." ); jQuery("#replaceWith").replaceWith( val("
    ") ); - equals( jQuery("#qunit-fixture").find("div[id=replaceWith]").length, 1, "Make sure only one div exists." ); + equals( jQuery("#main").find("div[id=replaceWith]").length, 1, "Make sure only one div exists." ); } test("replaceWith(String|Element|Array<Element>|jQuery)", function() { @@ -889,7 +827,7 @@ test("replaceWith(String|Element|Array<Element>|jQuery)", function() { test("replaceWith(Function)", function() { testReplaceWith(functionReturningObj); - expect(22); + expect(21); var y = jQuery("#yahoo")[0]; @@ -903,35 +841,35 @@ test("replaceWith(Function)", function() { test("replaceWith(string) for more than one element", function(){ expect(3); - equals(jQuery("#foo p").length, 3, "ensuring that test data has not changed"); + equals(jQuery('#foo p').length, 3, 'ensuring that test data has not changed'); - jQuery("#foo p").replaceWith("bar"); - equals(jQuery("#foo span").length, 3, "verify that all the three original element have been replaced"); - equals(jQuery("#foo p").length, 0, "verify that all the three original element have been replaced"); + jQuery('#foo p').replaceWith('bar'); + equals(jQuery('#foo span').length, 3, 'verify that all the three original element have been replaced'); + equals(jQuery('#foo p').length, 0, 'verify that all the three original element have been replaced'); }); test("replaceAll(String|Element|Array<Element>|jQuery)", function() { expect(10); - jQuery("buga").replaceAll("#yahoo"); - ok( jQuery("#replace")[0], "Replace element with string" ); - ok( !jQuery("#yahoo")[0], "Verify that original element is gone, after string" ); + jQuery('buga').replaceAll("#yahoo"); + ok( jQuery("#replace")[0], 'Replace element with string' ); + ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after string' ); QUnit.reset(); - jQuery(document.getElementById("first")).replaceAll("#yahoo"); - ok( jQuery("#first")[0], "Replace element with element" ); - ok( !jQuery("#yahoo")[0], "Verify that original element is gone, after element" ); + jQuery(document.getElementById('first')).replaceAll("#yahoo"); + ok( jQuery("#first")[0], 'Replace element with element' ); + ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after element' ); QUnit.reset(); - jQuery([document.getElementById("first"), document.getElementById("mark")]).replaceAll("#yahoo"); - ok( jQuery("#first")[0], "Replace element with array of elements" ); - ok( jQuery("#mark")[0], "Replace element with array of elements" ); - ok( !jQuery("#yahoo")[0], "Verify that original element is gone, after array of elements" ); + jQuery([document.getElementById('first'), document.getElementById('mark')]).replaceAll("#yahoo"); + ok( jQuery("#first")[0], 'Replace element with array of elements' ); + ok( jQuery("#mark")[0], 'Replace element with array of elements' ); + ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after array of elements' ); QUnit.reset(); jQuery("#mark, #first").replaceAll("#yahoo"); - ok( jQuery("#first")[0], "Replace element with set of elements" ); - ok( jQuery("#mark")[0], "Replace element with set of elements" ); - ok( !jQuery("#yahoo")[0], "Verify that original element is gone, after set of elements" ); + ok( jQuery("#first")[0], 'Replace element with set of elements' ); + ok( jQuery("#mark")[0], 'Replace element with set of elements' ); + ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after set of elements' ); }); test("jQuery.clone() (#8017)", function() { @@ -940,7 +878,7 @@ test("jQuery.clone() (#8017)", function() { ok( jQuery.clone && jQuery.isFunction( jQuery.clone ) , "jQuery.clone() utility exists and is a function."); - var main = jQuery("#qunit-fixture")[0], + var main = jQuery("#main")[0], clone = jQuery.clone( main ); equals( main.childNodes.length, clone.childNodes.length, "Simple child length to ensure a large dom tree copies correctly" ); @@ -949,9 +887,9 @@ test("jQuery.clone() (#8017)", function() { test("clone() (#8070)", function () { expect(2); - jQuery("").appendTo("#qunit-fixture"); - var selects = jQuery(".test8070"); - selects.append(""); + jQuery('').appendTo('#main'); + var selects = jQuery('.test8070'); + selects.append(''); equals( selects[0].childNodes.length, 2, "First select got two nodes" ); equals( selects[1].childNodes.length, 2, "Second select got two nodes" ); @@ -961,10 +899,10 @@ test("clone() (#8070)", function () { test("clone()", function() { expect(37); - equals( "This is a normal link: Yahoo", jQuery("#en").text(), "Assert text for #en" ); - var clone = jQuery("#yahoo").clone(); - equals( "Try them out:Yahoo", jQuery("#first").append(clone).text(), "Check for clone" ); - equals( "This is a normal link: Yahoo", jQuery("#en").text(), "Reassert text for #en" ); + equals( 'This is a normal link: Yahoo', jQuery('#en').text(), 'Assert text for #en' ); + var clone = jQuery('#yahoo').clone(); + equals( 'Try them out:Yahoo', jQuery('#first').append(clone).text(), 'Check for clone' ); + equals( 'This is a normal link: Yahoo', jQuery('#en').text(), 'Reassert text for #en' ); var cloneTags = [ "", "", "
    ", "
    ", @@ -974,7 +912,7 @@ test("clone()", function() { ]; for (var i = 0; i < cloneTags.length; i++) { var j = jQuery(cloneTags[i]); - equals( j[0].tagName, j.clone()[0].tagName, "Clone a " + cloneTags[i]); + equals( j[0].tagName, j.clone()[0].tagName, 'Clone a ' + cloneTags[i]); } // using contents will get comments regular, text, and comment nodes @@ -1030,7 +968,7 @@ test("clone()", function() { // this is technically an invalid object, but because of the special // classid instantiation it is the only kind that IE has trouble with, // so let's test with it too. - div = jQuery("
    ").html(" "); + div = jQuery("
    ").html(' '); clone = div.clone(true); equals( clone.length, 1, "One element cloned" ); @@ -1038,7 +976,7 @@ test("clone()", function() { equals( clone[0].nodeName.toUpperCase(), "DIV", "DIV element cloned" ); // and here's a valid one. - div = jQuery("
    ").html(" "); + div = jQuery("
    ").html(' '); clone = div.clone(true); equals( clone.length, 1, "One element cloned" ); @@ -1068,19 +1006,17 @@ test("clone()", function() { }); test("clone(form element) (Bug #3879, #6655)", function() { - expect(5); + expect(6); var element = jQuery(""); equals( element.clone().find("option:selected").val(), element.find("option:selected").val(), "Selected option cloned correctly" ); - element = jQuery("").attr("checked", "checked"); + element = jQuery("").attr('checked', 'checked'); clone = element.clone(); equals( clone.is(":checked"), element.is(":checked"), "Checked input cloned correctly" ); equals( clone[0].defaultValue, "foo", "Checked input defaultValue cloned correctly" ); - - // defaultChecked also gets set now due to setAttribute in attr, is this check still valid? - // equals( clone[0].defaultChecked, !jQuery.support.noCloneChecked, "Checked input defaultChecked cloned correctly" ); + equals( clone[0].defaultChecked, !jQuery.support.noCloneChecked, "Checked input defaultChecked cloned correctly" ); element = jQuery(""); clone = element.clone(); @@ -1117,11 +1053,11 @@ test("clone() on XML nodes", function() { } var testHtml = function(valueObj) { - expect(34); + expect(31); jQuery.scriptorder = 0; - var div = jQuery("#qunit-fixture > div"); + var div = jQuery("#main > div"); div.html(valueObj("test")); var pass = true; for ( var i = 0; i < div.size(); i++ ) { @@ -1129,7 +1065,7 @@ var testHtml = function(valueObj) { } ok( pass, "Set HTML" ); - div = jQuery("
    ").html( valueObj("
    ") ); + div = jQuery("
    ").html( valueObj('
    ') ); equals( div.children().length, 2, "Make sure two child nodes exist." ); equals( div.children().children().length, 1, "Make sure that a grandchild exists." ); @@ -1138,10 +1074,10 @@ var testHtml = function(valueObj) { ok( /^\xA0$|^ $/.test( space ), "Make sure entities are passed through correctly." ); equals( jQuery("
    ").html(valueObj("&"))[0].innerHTML, "&", "Make sure entities are passed through correctly." ); - jQuery("#qunit-fixture").html(valueObj("")); + jQuery("#main").html(valueObj("")); - equals( jQuery("#qunit-fixture").children().length, 1, "Make sure there is a child element." ); - equals( jQuery("#qunit-fixture").children()[0].nodeName.toUpperCase(), "STYLE", "And that a style element was inserted." ); + equals( jQuery("#main").children().length, 1, "Make sure there is a child element." ); + equals( jQuery("#main").children()[0].nodeName.toUpperCase(), "STYLE", "And that a style element was inserted." ); QUnit.reset(); // using contents will get comments regular, text, and comment nodes @@ -1149,18 +1085,18 @@ var testHtml = function(valueObj) { j.html(valueObj("bold")); // this is needed, or the expando added by jQuery unique will yield a different html - j.find("b").removeData(); + j.find('b').removeData(); equals( j.html().replace(/ xmlns="[^"]+"/g, "").toLowerCase(), "bold", "Check node,textnode,comment with html()" ); - jQuery("#qunit-fixture").html(valueObj("")); + jQuery("#main select").html(valueObj("")); + equals( jQuery("#main select").val(), "O2", "Selected option correct" ); - var $div = jQuery("
    "); - equals( $div.html(valueObj( 5 )).html(), "5", "Setting a number as html" ); - equals( $div.html(valueObj( 0 )).html(), "0", "Setting a zero as html" ); + var $div = jQuery('
    '); + equals( $div.html(valueObj( 5 )).html(), '5', 'Setting a number as html' ); + equals( $div.html(valueObj( 0 )).html(), '0', 'Setting a zero as html' ); - var $div2 = jQuery("
    "), insert = "<div>hello1</div>"; + var $div2 = jQuery('
    '), insert = "<div>hello1</div>"; equals( $div2.html(insert).html().replace(/>/g, ">"), insert, "Verify escaped insertion." ); equals( $div2.html("x" + insert).html().replace(/>/g, ">"), "x" + insert, "Verify escaped insertion." ); equals( $div2.html(" " + insert).html().replace(/>/g, ">"), " " + insert, "Verify escaped insertion." ); @@ -1172,23 +1108,17 @@ var testHtml = function(valueObj) { QUnit.reset(); - jQuery("#qunit-fixture").html(valueObj("
    ")); + jQuery("#main").html(valueObj('
    ')); - var child = jQuery("#qunit-fixture").find("script"); + jQuery("#main").html(valueObj("")); + jQuery("#main").html(valueObj("")); + jQuery("#main").html(valueObj("")); - equals( child.length, 2, "Make sure that two non-JavaScript script tags are left." ); - equals( child[0].type, "something/else", "Verify type of script tag." ); - equals( child[1].type, "something/else", "Verify type of script tag." ); + jQuery("#main").html(valueObj('')); - jQuery("#qunit-fixture").html(valueObj("")); - jQuery("#qunit-fixture").html(valueObj("")); - jQuery("#qunit-fixture").html(valueObj("")); + jQuery("#main").html(valueObj('foo
    ')); - jQuery("#qunit-fixture").html(valueObj("")); - - jQuery("#qunit-fixture").html(valueObj("foo
    ")); - - jQuery("#qunit-fixture").html(valueObj("' - ].join ( "\n" ) ).appendTo( "#qunit-fixture" ); - jQuery( [ - '' - ].join ( "\n" ) ).appendTo( "#qunit-fixture" ); - jQuery( [ - '' - ].join ( "\n" ) ).appendTo( "#qunit-fixture" ); -}); - -test("jQuery.buildFragment - plain objects are not a document #8950", function() { - expect(1); - - try { - jQuery('', {}); - ok( true, "Does not allow attribute object to be treated like a doc object"); - } catch (e) {} - -}); diff --git a/test/unit/offset.js b/test/unit/offset.js index ea1a4933..329d69f9 100644 --- a/test/unit/offset.js +++ b/test/unit/offset.js @@ -20,7 +20,7 @@ testoffset("absolute"/* in iframe */, function($, iframe) { // this insures that the results will be wrong // if the offset method is using the scroll offset // of the parent window - var forceScroll = jQuery("
    ", { width: 2000, height: 2000 }).appendTo("body"); + var forceScroll = jQuery('
    ', { width: 2000, height: 2000 }).appendTo('body'); window.scrollTo(200, 200); if ( document.documentElement.scrollTop || document.body.scrollTop ) { @@ -31,7 +31,7 @@ testoffset("absolute"/* in iframe */, function($, iframe) { // get offset tests = [ - { id: "#absolute-1", top: 1, left: 1 } + { id: '#absolute-1', top: 1, left: 1 } ]; jQuery.each( tests, function() { equals( jQuery( this.id, doc ).offset().top, this.top, "jQuery('" + this.id + "').offset().top" ); @@ -41,7 +41,7 @@ testoffset("absolute"/* in iframe */, function($, iframe) { // get position tests = [ - { id: "#absolute-1", top: 0, left: 0 } + { id: '#absolute-1', top: 0, left: 0 } ]; jQuery.each( tests, function() { equals( jQuery( this.id, doc ).position().top, this.top, "jQuery('" + this.id + "').position().top" ); @@ -56,10 +56,10 @@ testoffset("absolute", function( jQuery ) { // get offset tests var tests = [ - { id: "#absolute-1", top: 1, left: 1 }, - { id: "#absolute-1-1", top: 5, left: 5 }, - { id: "#absolute-1-1-1", top: 9, left: 9 }, - { id: "#absolute-2", top: 20, left: 20 } + { id: '#absolute-1', top: 1, left: 1 }, + { id: '#absolute-1-1', top: 5, left: 5 }, + { id: '#absolute-1-1-1', top: 9, left: 9 }, + { id: '#absolute-2', top: 20, left: 20 } ]; jQuery.each( tests, function() { equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset().top" ); @@ -69,10 +69,10 @@ testoffset("absolute", function( jQuery ) { // get position tests = [ - { id: "#absolute-1", top: 0, left: 0 }, - { id: "#absolute-1-1", top: 1, left: 1 }, - { id: "#absolute-1-1-1", top: 1, left: 1 }, - { id: "#absolute-2", top: 19, left: 19 } + { id: '#absolute-1', top: 0, left: 0 }, + { id: '#absolute-1-1', top: 1, left: 1 }, + { id: '#absolute-1-1-1', top: 1, left: 1 }, + { id: '#absolute-2', top: 19, left: 19 } ]; jQuery.each( tests, function() { equals( jQuery( this.id ).position().top, this.top, "jQuery('" + this.id + "').position().top" ); @@ -80,29 +80,29 @@ testoffset("absolute", function( jQuery ) { }); // test #5781 - var offset = jQuery( "#positionTest" ).offset({ top: 10, left: 10 }).offset(); + var offset = jQuery( '#positionTest' ).offset({ top: 10, left: 10 }).offset(); equals( offset.top, 10, "Setting offset on element with position absolute but 'auto' values." ) equals( offset.left, 10, "Setting offset on element with position absolute but 'auto' values." ) // set offset tests = [ - { id: "#absolute-2", top: 30, left: 30 }, - { id: "#absolute-2", top: 10, left: 10 }, - { id: "#absolute-2", top: -1, left: -1 }, - { id: "#absolute-2", top: 19, left: 19 }, - { id: "#absolute-1-1-1", top: 15, left: 15 }, - { id: "#absolute-1-1-1", top: 5, left: 5 }, - { id: "#absolute-1-1-1", top: -1, left: -1 }, - { id: "#absolute-1-1-1", top: 9, left: 9 }, - { id: "#absolute-1-1", top: 10, left: 10 }, - { id: "#absolute-1-1", top: 0, left: 0 }, - { id: "#absolute-1-1", top: -1, left: -1 }, - { id: "#absolute-1-1", top: 5, left: 5 }, - { id: "#absolute-1", top: 2, left: 2 }, - { id: "#absolute-1", top: 0, left: 0 }, - { id: "#absolute-1", top: -1, left: -1 }, - { id: "#absolute-1", top: 1, left: 1 } + { id: '#absolute-2', top: 30, left: 30 }, + { id: '#absolute-2', top: 10, left: 10 }, + { id: '#absolute-2', top: -1, left: -1 }, + { id: '#absolute-2', top: 19, left: 19 }, + { id: '#absolute-1-1-1', top: 15, left: 15 }, + { id: '#absolute-1-1-1', top: 5, left: 5 }, + { id: '#absolute-1-1-1', top: -1, left: -1 }, + { id: '#absolute-1-1-1', top: 9, left: 9 }, + { id: '#absolute-1-1', top: 10, left: 10 }, + { id: '#absolute-1-1', top: 0, left: 0 }, + { id: '#absolute-1-1', top: -1, left: -1 }, + { id: '#absolute-1-1', top: 5, left: 5 }, + { id: '#absolute-1', top: 2, left: 2 }, + { id: '#absolute-1', top: 0, left: 0 }, + { id: '#absolute-1', top: -1, left: -1 }, + { id: '#absolute-1', top: 1, left: 1 } ]; jQuery.each( tests, function() { jQuery( this.id ).offset({ top: this.top, left: this.left }); @@ -144,9 +144,9 @@ testoffset("relative", function( jQuery ) { // get offset var tests = [ - { id: "#relative-1", top: ie ? 6 : 7, left: 7 }, - { id: "#relative-1-1", top: ie ? 13 : 15, left: 15 }, - { id: "#relative-2", top: ie ? 141 : 142, left: 27 } + { id: '#relative-1', top: ie ? 6 : 7, left: 7 }, + { id: '#relative-1-1', top: ie ? 13 : 15, left: 15 }, + { id: '#relative-2', top: ie ? 141 : 142, left: 27 } ]; jQuery.each( tests, function() { equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset().top" ); @@ -156,9 +156,9 @@ testoffset("relative", function( jQuery ) { // get position tests = [ - { id: "#relative-1", top: ie ? 5 : 6, left: 6 }, - { id: "#relative-1-1", top: ie ? 4 : 5, left: 5 }, - { id: "#relative-2", top: ie ? 140 : 141, left: 26 } + { id: '#relative-1', top: ie ? 5 : 6, left: 6 }, + { id: '#relative-1-1', top: ie ? 4 : 5, left: 5 }, + { id: '#relative-2', top: ie ? 140 : 141, left: 26 } ]; jQuery.each( tests, function() { equals( jQuery( this.id ).position().top, this.top, "jQuery('" + this.id + "').position().top" ); @@ -168,18 +168,18 @@ testoffset("relative", function( jQuery ) { // set offset tests = [ - { id: "#relative-2", top: 200, left: 50 }, - { id: "#relative-2", top: 100, left: 10 }, - { id: "#relative-2", top: -5, left: -5 }, - { id: "#relative-2", top: 142, left: 27 }, - { id: "#relative-1-1", top: 100, left: 100 }, - { id: "#relative-1-1", top: 5, left: 5 }, - { id: "#relative-1-1", top: -1, left: -1 }, - { id: "#relative-1-1", top: 15, left: 15 }, - { id: "#relative-1", top: 100, left: 100 }, - { id: "#relative-1", top: 0, left: 0 }, - { id: "#relative-1", top: -1, left: -1 }, - { id: "#relative-1", top: 7, left: 7 } + { id: '#relative-2', top: 200, left: 50 }, + { id: '#relative-2', top: 100, left: 10 }, + { id: '#relative-2', top: -5, left: -5 }, + { id: '#relative-2', top: 142, left: 27 }, + { id: '#relative-1-1', top: 100, left: 100 }, + { id: '#relative-1-1', top: 5, left: 5 }, + { id: '#relative-1-1', top: -1, left: -1 }, + { id: '#relative-1-1', top: 15, left: 15 }, + { id: '#relative-1', top: 100, left: 100 }, + { id: '#relative-1', top: 0, left: 0 }, + { id: '#relative-1', top: -1, left: -1 }, + { id: '#relative-1', top: 7, left: 7 } ]; jQuery.each( tests, function() { jQuery( this.id ).offset({ top: this.top, left: this.left }); @@ -205,10 +205,10 @@ testoffset("static", function( jQuery ) { // get offset var tests = [ - { id: "#static-1", top: ie ? 6 : 7, left: 7 }, - { id: "#static-1-1", top: ie ? 13 : 15, left: 15 }, - { id: "#static-1-1-1", top: ie ? 20 : 23, left: 23 }, - { id: "#static-2", top: ie ? 121 : 122, left: 7 } + { id: '#static-1', top: ie ? 6 : 7, left: 7 }, + { id: '#static-1-1', top: ie ? 13 : 15, left: 15 }, + { id: '#static-1-1-1', top: ie ? 20 : 23, left: 23 }, + { id: '#static-2', top: ie ? 121 : 122, left: 7 } ]; jQuery.each( tests, function() { equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset().top" ); @@ -218,10 +218,10 @@ testoffset("static", function( jQuery ) { // get position tests = [ - { id: "#static-1", top: ie ? 5 : 6, left: 6 }, - { id: "#static-1-1", top: ie ? 12 : 14, left: 14 }, - { id: "#static-1-1-1", top: ie ? 19 : 22, left: 22 }, - { id: "#static-2", top: ie ? 120 : 121, left: 6 } + { id: '#static-1', top: ie ? 5 : 6, left: 6 }, + { id: '#static-1-1', top: ie ? 12 : 14, left: 14 }, + { id: '#static-1-1-1', top: ie ? 19 : 22, left: 22 }, + { id: '#static-2', top: ie ? 120 : 121, left: 6 } ]; jQuery.each( tests, function() { equals( jQuery( this.id ).position().top, this.top, "jQuery('" + this.top + "').position().top" ); @@ -231,22 +231,22 @@ testoffset("static", function( jQuery ) { // set offset tests = [ - { id: "#static-2", top: 200, left: 200 }, - { id: "#static-2", top: 100, left: 100 }, - { id: "#static-2", top: -2, left: -2 }, - { id: "#static-2", top: 121, left: 6 }, - { id: "#static-1-1-1", top: 50, left: 50 }, - { id: "#static-1-1-1", top: 10, left: 10 }, - { id: "#static-1-1-1", top: -1, left: -1 }, - { id: "#static-1-1-1", top: 22, left: 22 }, - { id: "#static-1-1", top: 25, left: 25 }, - { id: "#static-1-1", top: 10, left: 10 }, - { id: "#static-1-1", top: -3, left: -3 }, - { id: "#static-1-1", top: 14, left: 14 }, - { id: "#static-1", top: 30, left: 30 }, - { id: "#static-1", top: 2, left: 2 }, - { id: "#static-1", top: -2, left: -2 }, - { id: "#static-1", top: 7, left: 7 } + { id: '#static-2', top: 200, left: 200 }, + { id: '#static-2', top: 100, left: 100 }, + { id: '#static-2', top: -2, left: -2 }, + { id: '#static-2', top: 121, left: 6 }, + { id: '#static-1-1-1', top: 50, left: 50 }, + { id: '#static-1-1-1', top: 10, left: 10 }, + { id: '#static-1-1-1', top: -1, left: -1 }, + { id: '#static-1-1-1', top: 22, left: 22 }, + { id: '#static-1-1', top: 25, left: 25 }, + { id: '#static-1-1', top: 10, left: 10 }, + { id: '#static-1-1', top: -3, left: -3 }, + { id: '#static-1-1', top: 14, left: 14 }, + { id: '#static-1', top: 30, left: 30 }, + { id: '#static-1', top: 2, left: 2 }, + { id: '#static-1', top: -2, left: -2 }, + { id: '#static-1', top: 7, left: 7 } ]; jQuery.each( tests, function() { jQuery( this.id ).offset({ top: this.top, left: this.left }); @@ -265,13 +265,13 @@ testoffset("static", function( jQuery ) { }); testoffset("fixed", function( jQuery ) { - expect(30); + expect(28); jQuery.offset.initialize(); var tests = [ - { id: "#fixed-1", top: 1001, left: 1001 }, - { id: "#fixed-2", top: 1021, left: 1021 } + { id: '#fixed-1', top: 1001, left: 1001 }, + { id: '#fixed-2', top: 1021, left: 1021 } ]; jQuery.each( tests, function() { @@ -284,18 +284,18 @@ testoffset("fixed", function( jQuery ) { equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset().left" ); } else { // need to have same number of assertions - ok( true, "Fixed position is not supported" ); - ok( true, "Fixed position is not supported" ); + ok( true, 'Fixed position is not supported' ); + ok( true, 'Fixed position is not supported' ); } }); tests = [ - { id: "#fixed-1", top: 100, left: 100 }, - { id: "#fixed-1", top: 0, left: 0 }, - { id: "#fixed-1", top: -4, left: -4 }, - { id: "#fixed-2", top: 200, left: 200 }, - { id: "#fixed-2", top: 0, left: 0 }, - { id: "#fixed-2", top: -5, left: -5 } + { id: '#fixed-1', top: 100, left: 100 }, + { id: '#fixed-1', top: 0, left: 0 }, + { id: '#fixed-1', top: -4, left: -4 }, + { id: '#fixed-2', top: 200, left: 200 }, + { id: '#fixed-2', top: 0, left: 0 }, + { id: '#fixed-2', top: -5, left: -5 } ]; jQuery.each( tests, function() { @@ -314,58 +314,47 @@ testoffset("fixed", function( jQuery ) { equals( jQuery( this.id ).offset().left, this.left + 1, "jQuery('" + this.id + "').offset({ left: " + (this.left + 1) + ", using: fn })" ); } else { // need to have same number of assertions - ok( true, "Fixed position is not supported" ); - ok( true, "Fixed position is not supported" ); - ok( true, "Fixed position is not supported" ); - ok( true, "Fixed position is not supported" ); + ok( true, 'Fixed position is not supported' ); + ok( true, 'Fixed position is not supported' ); + ok( true, 'Fixed position is not supported' ); + ok( true, 'Fixed position is not supported' ); } }); - - // Bug 8316 - var $noTopLeft = jQuery("#fixed-no-top-left"); - if ( jQuery.offset.supportsFixedPosition ) { - equals( $noTopLeft.offset().top, 1007, "Check offset top for fixed element with no top set" ); - equals( $noTopLeft.offset().left, 1007, "Check offset left for fixed element with no left set" ); - } else { - // need to have same number of assertions - ok( true, "Fixed position is not supported" ); - ok( true, "Fixed position is not supported" ); - } }); testoffset("table", function( jQuery ) { expect(4); - equals( jQuery("#table-1").offset().top, 6, "jQuery('#table-1').offset().top" ); - equals( jQuery("#table-1").offset().left, 6, "jQuery('#table-1').offset().left" ); + equals( jQuery('#table-1').offset().top, 6, "jQuery('#table-1').offset().top" ); + equals( jQuery('#table-1').offset().left, 6, "jQuery('#table-1').offset().left" ); - equals( jQuery("#th-1").offset().top, 10, "jQuery('#th-1').offset().top" ); - equals( jQuery("#th-1").offset().left, 10, "jQuery('#th-1').offset().left" ); + equals( jQuery('#th-1').offset().top, 10, "jQuery('#th-1').offset().top" ); + equals( jQuery('#th-1').offset().left, 10, "jQuery('#th-1').offset().left" ); }); testoffset("scroll", function( jQuery, win ) { - expect(22); + expect(16); var ie = jQuery.browser.msie && parseInt( jQuery.browser.version, 10 ) < 8; // IE is collapsing the top margin of 1px - equals( jQuery("#scroll-1").offset().top, ie ? 6 : 7, "jQuery('#scroll-1').offset().top" ); - equals( jQuery("#scroll-1").offset().left, 7, "jQuery('#scroll-1').offset().left" ); + equals( jQuery('#scroll-1').offset().top, ie ? 6 : 7, "jQuery('#scroll-1').offset().top" ); + equals( jQuery('#scroll-1').offset().left, 7, "jQuery('#scroll-1').offset().left" ); // IE is collapsing the top margin of 1px - equals( jQuery("#scroll-1-1").offset().top, ie ? 9 : 11, "jQuery('#scroll-1-1').offset().top" ); - equals( jQuery("#scroll-1-1").offset().left, 11, "jQuery('#scroll-1-1').offset().left" ); + equals( jQuery('#scroll-1-1').offset().top, ie ? 9 : 11, "jQuery('#scroll-1-1').offset().top" ); + equals( jQuery('#scroll-1-1').offset().left, 11, "jQuery('#scroll-1-1').offset().left" ); // scroll offset tests .scrollTop/Left - equals( jQuery("#scroll-1").scrollTop(), 5, "jQuery('#scroll-1').scrollTop()" ); - equals( jQuery("#scroll-1").scrollLeft(), 5, "jQuery('#scroll-1').scrollLeft()" ); + equals( jQuery('#scroll-1').scrollTop(), 5, "jQuery('#scroll-1').scrollTop()" ); + equals( jQuery('#scroll-1').scrollLeft(), 5, "jQuery('#scroll-1').scrollLeft()" ); - equals( jQuery("#scroll-1-1").scrollTop(), 0, "jQuery('#scroll-1-1').scrollTop()" ); - equals( jQuery("#scroll-1-1").scrollLeft(), 0, "jQuery('#scroll-1-1').scrollLeft()" ); + equals( jQuery('#scroll-1-1').scrollTop(), 0, "jQuery('#scroll-1-1').scrollTop()" ); + equals( jQuery('#scroll-1-1').scrollLeft(), 0, "jQuery('#scroll-1-1').scrollLeft()" ); - // equals( jQuery("body").scrollTop(), 0, "jQuery("body").scrollTop()" ); - // equals( jQuery("body").scrollLeft(), 0, "jQuery("body").scrollTop()" ); + // equals( jQuery('body').scrollTop(), 0, "jQuery('body').scrollTop()" ); + // equals( jQuery('body').scrollLeft(), 0, "jQuery('body').scrollTop()" ); win.name = "test"; @@ -390,21 +379,13 @@ testoffset("scroll", function( jQuery, win ) { equals( jQuery(window).scrollLeft(), 0, "jQuery(window).scrollLeft() other window" ); equals( jQuery(document).scrollTop(), 0, "jQuery(window).scrollTop() other document" ); equals( jQuery(document).scrollLeft(), 0, "jQuery(window).scrollLeft() other document" ); - - // Tests scrollTop/Left with empty jquery objects - notEqual( jQuery().scrollTop(100), null, "jQuery().scrollTop(100) testing setter on empty jquery object" ); - notEqual( jQuery().scrollLeft(100), null, "jQuery().scrollLeft(100) testing setter on empty jquery object" ); - notEqual( jQuery().scrollTop(null), null, "jQuery().scrollTop(null) testing setter on empty jquery object" ); - notEqual( jQuery().scrollLeft(null), null, "jQuery().scrollLeft(null) testing setter on empty jquery object" ); - strictEqual( jQuery().scrollTop(), null, "jQuery().scrollTop(100) testing setter on empty jquery object" ); - strictEqual( jQuery().scrollLeft(), null, "jQuery().scrollLeft(100) testing setter on empty jquery object" ); }); testoffset("body", function( jQuery ) { expect(2); - equals( jQuery("body").offset().top, 1, "jQuery('#body').offset().top" ); - equals( jQuery("body").offset().left, 1, "jQuery('#body').offset().left" ); + equals( jQuery('body').offset().top, 1, "jQuery('#body').offset().top" ); + equals( jQuery('body').offset().left, 1, "jQuery('#body').offset().left" ); }); test("Chaining offset(coords) returns jQuery object", function() { @@ -441,32 +422,6 @@ test("offsetParent", function(){ equals( div[1], jQuery("#nothiddendiv")[0], "The div is the offsetParent." ); }); -test("fractions (see #7730 and #7885)", function() { - expect(2); - - jQuery('body').append('
    '); - - var expected = { top: 1000, left: 1000 }; - var div = jQuery('#fractions'); - - div.css({ - position: 'absolute', - left: '1000.7432222px', - top: '1000.532325px', - width: 100, - height: 100 - }); - - div.offset(expected); - - var result = div.offset(); - - equals( result.top, expected.top, "Check top" ); - equals( result.left, expected.left, "Check left" ); - - div.remove(); -}); - function testoffset(name, fn) { test(name, function() { @@ -490,10 +445,10 @@ function testoffset(name, fn) { }); function loadFixture() { - var src = "./data/offset/" + name + ".html?" + parseInt( Math.random()*1000, 10 ), - iframe = jQuery("