From 2520be24f0f52c4372af72fdfc78fbdf744cdf39 Mon Sep 17 00:00:00 2001 From: Nik Topler Date: Tue, 29 Sep 2020 21:19:07 +0200 Subject: [PATCH] Updated signin/up system --- ._oauth.js | Bin 4096 -> 0 bytes CSS/*.css | 9 +- CSS/responsive.css | 17 +- CSS/signin.css | 215 ++ CSS/signup.css | 203 +- JS/main.js | 2 + JS/show.js | 6 - JS/signIn/external.js | 34 +- JS/signIn/regular.js | 0 JS/signIn/signin.js | 163 + JS/signIn/signup.js | 301 ++ add-ons/footer-scripts.php | 1 - add-ons/head.php | 2 +- headlines.php | 2 +- include/check.inc.php | 47 + include/insert.inc.php | 93 +- include/isSessionSet.inc.php | 7 + include/session.inc.php | 45 +- oauth.js | 5573 ---------------------------------- signin.php | 83 +- signup.php | 132 + 21 files changed, 1224 insertions(+), 5711 deletions(-) delete mode 100755 ._oauth.js create mode 100644 CSS/signin.css delete mode 100644 JS/signIn/regular.js create mode 100644 JS/signIn/signin.js create mode 100644 JS/signIn/signup.js create mode 100644 include/check.inc.php create mode 100644 include/isSessionSet.inc.php delete mode 100755 oauth.js create mode 100644 signup.php diff --git a/._oauth.js b/._oauth.js deleted file mode 100755 index 187cff541a759135c04855219edef53c4f7ddf7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDJkFz{^v(m+1nBL)UWIUt(=a103vVqpBY z4x)o$3s89mnii1hAaMl-2GQjFT)o7Cf}B*n!qUW|#JrNsyi}0#D?seQz`&1?&rM9u zVaUidFt9MPHcc}(urN$CwhqZijj1p)2+d0@O3uhEOD(cyVo=?DwkGwdzjEs%g%C%{ zpgADpM!{$ZjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kina1Q}Spa(%14CF#GGK&?8 zQj7CTi;`0n((;S46*BWmQi0vh{Jg}RoJxh9)U* { hideExtraSearchOptions() hideSuggestWords() + if(window.location.hash === '#login') manageLoginOptions() + document.querySelectorAll('input').forEach(input => { input.autocomplete = 'off' }) error.window() diff --git a/JS/show.js b/JS/show.js index 494f835..3d02d57 100644 --- a/JS/show.js +++ b/JS/show.js @@ -120,12 +120,6 @@ function manageLoginOptions() { } } -function resetExtraSearchOptions() { - indexTimeLabel.innerHTML = 'Anytime' - for(let i = 0; i < 3; i++) - document.querySelectorAll('.extra-search-options > div > input')[i].value = '' -} - function sidebarCategorySelect(selectedElement) { if(selectedElement.classList.contains('active')) return selectedElement.classList.add('active') diff --git a/JS/signIn/external.js b/JS/signIn/external.js index f1d0901..2a395d7 100644 --- a/JS/signIn/external.js +++ b/JS/signIn/external.js @@ -30,23 +30,23 @@ /** GitHub */ // OAuth.initialize('qFa2sjgoyyIVRhaoOePG2ie1RqY') - document.getElementById('github-btn').onclick = () => { - // Initialize with your OAuth.io app public key - OAuth.initialize('_nPRfzTNGplyDCW0vD9dmek5QAg') - // Use popup for oauth - // Alternative is redirect - OAuth.popup('github').then(github => { - // console.log('github:', github) - // Retrieves user data from oauth provider - // Prompts 'welcome' message with User's email on successful login - // #me() is a convenient method to retrieve user data without requiring you - // to know which OAuth provider url to call - github.me().then(data => { - // console.log('me data:', data) - // alert('GitHub says your email is:' + data.email + ".\nView browser 'Console Log' for more details") - }) - }) - } + // document.getElementById('github-btn').onclick = () => { + // // Initialize with your OAuth.io app public key + // OAuth.initialize('_nPRfzTNGplyDCW0vD9dmek5QAg') + // // Use popup for oauth + // // Alternative is redirect + // OAuth.popup('github').then(github => { + // // console.log('github:', github) + // // Retrieves user data from oauth provider + // // Prompts 'welcome' message with User's email on successful login + // // #me() is a convenient method to retrieve user data without requiring you + // // to know which OAuth provider url to call + // github.me().then(data => { + // // console.log('me data:', data) + // // alert('GitHub says your email is:' + data.email + ".\nView browser 'Console Log' for more details") + // }) + // }) + // } /** FaceBook */ diff --git a/JS/signIn/regular.js b/JS/signIn/regular.js deleted file mode 100644 index e69de29..0000000 diff --git a/JS/signIn/signin.js b/JS/signIn/signin.js new file mode 100644 index 0000000..9b532fb --- /dev/null +++ b/JS/signIn/signin.js @@ -0,0 +1,163 @@ +const email = document.querySelector('.email-container') +const password = document.querySelector('.password-container') + +const emailInput = document.getElementById('email-input') +const passwordInput = document.getElementById('password-input') + +const websiteURL = 'http://localhost:8080/News-website/' + +emailInput.onfocus = () => { + email.querySelector('.label-container').classList.add('active') + email.querySelector('.label-container').classList.add('google-blue') + emailInput.classList.add('active') +} +emailInput.onblur = () => { + if(emailInput.value.length === 0) { + email.querySelector('.label-container').classList.remove('active') + email.querySelector('.label-container').classList.remove('google-blue') + emailInput.classList.remove('active') + } else { + email.querySelector('.label-container').classList.remove('google-blue') + emailInput.classList.remove('active') + } +} +passwordInput.onfocus = () => { + password.querySelector('.label-container').classList.add('active') + password.querySelector('.label-container').classList.add('google-blue') + passwordInput.classList.add('active') +} +passwordInput.onblur = () => { + if(passwordInput.value.length === 0) { + password.querySelector('.label-container').classList.remove('active') + password.querySelector('.label-container').classList.remove('google-blue') + passwordInput.classList.remove('active') + } else { + password.querySelector('.label-container').classList.remove('google-blue') + passwordInput.classList.remove('active') + } +} + +function switchLoginBox() { + + if(!email.classList.contains('active')) { + email.classList.add('active') + password.classList.add('active') + resetPsw() + } else { + email.classList.remove('active') + password.classList.remove('active') + setupSubHeading() + } +} +async function checkEmail() { + array = JSON.stringify([emailInput.value.trim()]) + const res = await fetch('include/check.inc.php', { + method: "POST", + body: createFormData('email', array) + }) + const data = await res.text() + + if(errorHandelingEmail(data) === true) switchLoginBox() + setupProfile() +} + +const errorPswContainer = document.querySelector('.error.psw') +async function checkPassword() { + if(passwordInput.value.length === 0) { + errorPswContainer.classList.remove('disable') + errorPswContainer.firstElementChild.innerHTML = `${icon} Field password must not be empty`; + passwordInput.classList.add('error-red-border') + password.querySelector('label').classList.add('error-red') + return + } + array = JSON.stringify([emailInput.value.trim(), passwordInput.value.trim()]) + const res = await fetch('include/check.inc.php', { + method: "POST", + body: createFormData('login', array) + }) + const data = await res.text() + + if(data === 'success') urlOpen('') + else if(data == 'wrong password') { + errorPswContainer.classList.remove('disable') + errorPswContainer.firstElementChild.innerHTML = `${icon} Incorrect password`; + passwordInput.classList.add('error-red-border') + password.querySelector('label').classList.add('error-red') + } +} + +function setupProfile() { + const upperContainer = document.getElementById('upper-container') + upperContainer.firstElementChild.classList.add('disable') + upperContainer.lastElementChild.classList.remove('disable') + upperContainer.lastElementChild.firstElementChild.querySelector('span').innerHTML = emailInput.value +} +function setupSubHeading() { + const upperContainer = document.getElementById('upper-container') + upperContainer.firstElementChild.classList.remove('disable') + upperContainer.lastElementChild.classList.add('disable') + upperContainer.lastElementChild.firstElementChild.querySelector('span').innerHTML = '' +} + +const errorContainer = document.querySelector('.error') +const icon = `` + +function errorHandelingEmail(data) { + if(data === `user exists`) return true + + if(emailInput.value.length === 0) errorContainer.firstElementChild.innerHTML = `${icon} Enter your email adress` + else if(!validateEmail(emailInput.value.trim())) errorContainer.firstElementChild.innerHTML = `${icon} Email address doesn't exist` + else if(data === `user doesn't exist`) errorContainer.firstElementChild.innerHTML = `${icon} There is no user with this email` + else if(data === `google user doesn't have password set up`) { + errorContainer.firstElementChild.innerHTML = `${icon} No set up password` + errorContainer.lastElementChild.classList.remove('disable') + errorContainer.lastElementChild.innerHTML = `You have logged in with your Google account, but you didn't set up your password.` + } else if(data === `facebook user doesn't have password set up`) { + errorContainer.firstElementChild.innerHTML = `${icon} No set up password` + errorContainer.lastElementChild.classList.remove('disable') + errorContainer.lastElementChild.innerHTML = `You have logged in with your Facebook account, but you didn't set up your password.` + } else if(data === `github user doesn't have password set up`) { + errorContainer.firstElementChild.innerHTML = `${icon} No set up password` + errorContainer.lastElementChild.classList.remove('disable') + errorContainer.lastElementChild.innerHTML = `You have logged in with your Facebook account, but you didn't set up your password.` + } + errorContainer.classList.remove('disable') + email.querySelector('.label-container').classList.add('error-red') + emailInput.classList.add('error-red-border') + + return false +} + +function validateEmail(email) { + let mailformat = /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$/ + if (email.match(mailformat)) return true + else return false +} +function createFormData(word, data) { + let formData = new FormData + formData.append(word, data) + return formData +} + +function urlOpen(string) { window.location.replace(`${websiteURL}headlines.php${string}`) } + +element = document.querySelector('.eye-icon-container') + +function managePswVisibility() { + if(element.firstElementChild.firstElementChild.classList.contains('disable')) { + element.firstElementChild.firstElementChild.classList.remove('disable') + element.firstElementChild.lastElementChild.classList.add('disable') + passwordInput.type = 'text' + } else { + element.firstElementChild.firstElementChild.classList.add('disable') + element.firstElementChild.lastElementChild.classList.remove('disable') + passwordInput.type = 'password' + } +} + +function resetPsw() { + passwordInput.value = '' + element.firstElementChild.firstElementChild.classList.add('disable') + element.firstElementChild.lastElementChild.classList.remove('disable') + passwordInput.type = 'password' +} \ No newline at end of file diff --git a/JS/signIn/signup.js b/JS/signIn/signup.js new file mode 100644 index 0000000..4fcb71b --- /dev/null +++ b/JS/signIn/signup.js @@ -0,0 +1,301 @@ +const name = document.querySelector('.name-container') +const surname = document.querySelector('.surname-container') +const email = document.querySelector('.email-container') +const psw = document.querySelector('.psw-container') +const pswRepeat = document.querySelector('.psw-repeat-container') + +const nameInput = document.getElementById('name-input') +const surnameInput = document.getElementById('surname-input') +const emailInput = document.getElementById('email-input') +const pswInput = document.getElementById('psw-input') +const pswRepeatInput = document.getElementById('psw-repeat-input') + +const countries = ['Arab Emirates','Argentina','Australia','Austria','Belgium','Brasil','Bulgaria','Canada','China','Colombia','Cuba','Czech Republic','Egypt','England','France','Germany','Greece','Hong Kong','Hungary','Indonesia','Ireland','Israel','Italy','Japan','Latvia','Lithuania','Malaysia','Mexico','Morocco','Netherlands','New Zealand','Nigeria','Norway','Philippines','Poland','Portugal','Romania','Russia','Saudia Arabia','Serbia','Singapore','Slovakia','Slovenia','South Africa','South Korea','Sweden','Switzerland','Taiwan','Thailand','Turkey','Ukraine','United States','Venezuela'] + +nameInput.onfocus = () => { + name.querySelector('.label-container').classList.add('active') + name.querySelector('.label-container').classList.add('google-blue') + nameInput.classList.add('active') +} +nameInput.onblur = () => { + if(nameInput.value.length === 0) { + name.querySelector('.label-container').classList.remove('active') + name.querySelector('.label-container').classList.remove('google-blue') + nameInput.classList.remove('active') + } else { + name.querySelector('.label-container').classList.remove('google-blue') + nameInput.classList.remove('active') + } +} +surnameInput.onfocus = () => { + surname.querySelector('.label-container').classList.add('active') + surname.querySelector('.label-container').classList.add('google-blue') + surnameInput.classList.add('active') +} +surnameInput.onblur = () => { + if(surnameInput.value.length === 0) { + surname.querySelector('.label-container').classList.remove('active') + surname.querySelector('.label-container').classList.remove('google-blue') + surnameInput.classList.remove('active') + } else { + surname.querySelector('.label-container').classList.remove('google-blue') + surnameInput.classList.remove('active') + } +} + +emailInput.onfocus = () => { + email.querySelector('.label-container').classList.add('active') + email.querySelector('.label-container').classList.add('google-blue') + emailInput.classList.add('active') +} +emailInput.onblur = () => { + if(emailInput.value.length === 0) { + email.querySelector('.label-container').classList.remove('active') + email.querySelector('.label-container').classList.remove('google-blue') + emailInput.classList.remove('active') + } else { + email.querySelector('.label-container').classList.remove('google-blue') + emailInput.classList.remove('active') + } +} +pswInput.onfocus = () => { + psw.querySelector('.label-container').classList.add('active') + psw.querySelector('.label-container').classList.add('google-blue') + pswInput.classList.add('active') +} +pswInput.onblur = () => { + if(pswInput.value.length === 0) { + psw.querySelector('.label-container').classList.remove('active') + psw.querySelector('.label-container').classList.remove('google-blue') + pswInput.classList.remove('active') + } else { + psw.querySelector('.label-container').classList.remove('google-blue') + pswInput.classList.remove('active') + } +} +pswRepeatInput.onfocus = () => { + pswRepeat.querySelector('.label-container').classList.add('active') + pswRepeat.querySelector('.label-container').classList.add('google-blue') + pswRepeatInput.classList.add('active') +} +pswRepeatInput.onblur = () => { + if(pswRepeatInput.value.length === 0) { + pswRepeat.querySelector('.label-container').classList.remove('active') + pswRepeat.querySelector('.label-container').classList.remove('google-blue') + pswRepeatInput.classList.remove('active') + } else { + pswRepeat.querySelector('.label-container').classList.remove('google-blue') + pswRepeatInput.classList.remove('active') + } +} + +window.onload = () => { + generateCountries() +} + +const indexCountrySelect = document.getElementById('index-country-select') +const indexCountryLabel = document.getElementById('index-country-label') + +function manageOptionSelect() { + if(indexCountrySelect.classList.contains('disable')){ + indexCountrySelect.classList.remove('disable') + showCountrySelect() + } + else indexCountrySelect.classList.add('disable') +} +function showCountrySelect() { + let selectedValue + for(let i = 0; i < countries.length; i++) { + if(indexCountrySelect.children[i].innerHTML === indexCountryLabel.innerHTML) { + indexCountrySelect.children[i].classList.add('selected-option') + selectedValue = i + } + indexCountrySelect.children[i].onmouseenter = () => { eventHandelerForCountrySelect(indexCountrySelect.children[i],'enter') } + indexCountrySelect.children[i].onmouseleave = () => { eventHandelerForCountrySelect(indexCountrySelect.children[i],'leave') } + } + return selectedValue +} +function selectValue(selectedElement) { + event.stopPropagation() + indexCountryLabel.innerHTML = selectedElement.innerHTML + indexCountrySelect.classList.add('disable') +} +let countrySelectValueArray = [] +function eventHandelerForCountrySelect(element, command) { + countrySelectValueArray.push(command) + removeEveryChildsClass(element.parentElement,'selected-option') + if(command == 'enter' || countrySelectValueArray[countrySelectValueArray.length - 1] == 'leave') element.classList.add('selected-option') +} +function removeEveryChildsClass(parent,className) { + for(let i = 0; i < parent.children.length; i++) + parent.children[i].classList.remove(className) +} +function generateCountries() { + for(let i = 0; i < countries.length; i++) { + let div = document.createElement('div') + div.onclick = () => { selectValue(div) } + div.innerHTML = countries[i] + indexCountrySelect.appendChild(div) + } +} +function managePasswordVisibility(element) { + if(element.firstElementChild.firstElementChild.classList.contains('disable')) { + element.firstElementChild.firstElementChild.classList.remove('disable') + element.firstElementChild.lastElementChild.classList.add('disable') + pswInput.type = 'text' + pswRepeatInput.type = 'text' + + } else { + element.firstElementChild.firstElementChild.classList.add('disable') + element.firstElementChild.lastElementChild.classList.remove('disable') + pswInput.type = 'password' + pswRepeatInput.type = 'password' + } +} +const websiteURL = 'http://localhost:8080/News-website/' + +function urlOpen(string) { window.location.replace(`${websiteURL}headlines.php${string}`) } + + +async function register() { + let firstName = nameInput.value.trim() + let lastName = surnameInput.value.trim() + let email = emailInput.value.trim() + let password = pswInput.value.trim() + let passwordRepeat = pswRepeatInput.value.trim() + let country = indexCountryLabel.innerHTML.trim() + error.reset() + if(error.before(firstName, lastName, email, password, passwordRepeat, country) === false) return + insertToDB(firstName, lastName, email, password, passwordRepeat, country) +} +async function insertToDB(firstName, lastName, email, password, passwordRepeat, country) { + array = JSON.stringify([firstName, lastName, email, password, passwordRepeat, country]) + const res = await fetch('include/insert.inc.php', { + method: "POST", + body: createFormData('standard', array) + }) + const data = await res.text() + error.after(data) +} +const icon = `` +const nameError = document.querySelector('.error.name') +const emailError = document.querySelector('.error.email') +const pswError = document.querySelector('.error.psw') +const countryError = document.querySelector('.error.country') +const resultError = document.querySelector('.error.result') + + +const error = { + reset : () => { + nameError.classList.add('disable') + nameError.firstElementChild.innerHTML = "" + nameInput.classList.remove('error-red-border') + name.querySelector('label').classList.remove('error-red') + emailError.classList.add('disable') + emailError.firstElementChild.innerHTML = "" + emailInput.classList.remove('error-red-border') + email.querySelector('label').classList.remove('error-red') + pswError.classList.add('disable') + pswError.firstElementChild.innerHTML = "" + pswInput.classList.remove('error-red-border') + psw.querySelector('label').classList.remove('error-red') + pswRepeatInput.classList.remove('error-red-border') + pswRepeat.querySelector('label').classList.remove('error-red') + countryError.classList.add('disable') + countryError.firstElementChild.innerHTML = "" + resultError.classList.add('disable') + }, + before : (FirstName, LastName, Email, Password, PasswordRepeat, Country) => { + let num = 0 + if(FirstName.length === 0 || LastName.length === 0) { + nameError.classList.remove('disable') + if(FirstName.length === 0 && LastName.length === 0) { + nameError.firstElementChild.innerHTML = `${icon} Name and Surname must not be empty` + nameInput.classList.add('error-red-border') + name.querySelector('label').classList.add('error-red') + surnameInput.classList.add('error-red-border') + surname.querySelector('label').classList.add('error-red') + } else if(FirstName.length !== 0 && LastName.length === 0) { + nameError.firstElementChild.innerHTML = `${icon} Surname must not be empty` + surnameInput.classList.add('error-red-border') + surname.querySelector('label').classList.add('error-red') + } else if(FirstName.length === 0 && LastName.length !== 0) { + nameError.firstElementChild.innerHTML = `${icon} Name must not be empty` + nameInput.classList.add('error-red-border') + name.querySelector('label').classList.add('error-red') + } + num = num++ + } + if(Email.length === 0 || validateEmail(Email) === false) { + if(validateEmail(Email) === false) emailError.firstElementChild.innerHTML = `${icon} Incorrect email format` + else emailError.firstElementChild.innerHTML = `${icon} Field email must be filled` + emailError.classList.remove('disable') + emailInput.classList.add('error-red-border') + email.querySelector('label').classList.add('error-red') + num = num++ + } + if(Password.length === 0 || PasswordRepeat.length === 0 || Password.length < 6) { + pswError.classList.remove('disable') + if(Password.length === 0 && PasswordRepeat.length === 0 || Password.length < 6) { + if(Password.length === 0 && PasswordRepeat.length === 0) pswError.firstElementChild.innerHTML = `${icon} You must type in your password` + else pswError.firstElementChild.innerHTML = `${icon} Password must include atleast 7 characters` + pswInput.classList.add('error-red-border') + psw.querySelector('label').classList.add('error-red') + pswRepeatInput.classList.add('error-red-border') + pswRepeat.querySelector('label').classList.add('error-red') + } else if(Password !== PasswordRepeat) { + pswError.firstElementChild.innerHTML = `${icon} Passwords do not match` + pswInput.classList.add('error-red-border') + psw.querySelector('label').classList.add('error-red') + pswRepeatInput.classList.add('error-red-border') + pswRepeat.querySelector('label').classList.add('error-red') + } else if(Password.length !== 0 && PasswordRepeat.length === 0) { + pswError.firstElementChild.innerHTML = `${icon} Surname must not be empty` + pswRepeatInput.classList.add('error-red-border') + pswRepeat.querySelector('label').classList.add('error-red') + } else if(Password.length === 0 && PasswordRepeat.length !== 0) { + nameError.firstElementChild.innerHTML = `${icon} Name must not be empty` + pswInput.classList.add('error-red-border') + psw.querySelector('label').classList.add('error-red') + } + num = num++ + } + if(Country === 'Select Country') { + countryError.classList.remove('disable') + countryError.firstElementChild.innerHTML = `${icon} You must select country` + num = num++ + } + if(num > 0) return false + else true + }, + after : (data) => { + if(data === 'success') return urlOpen('') + + resultError.classList.remove('disable') + if(data === `user exist's`) resultError.firstElementChild.innerHTML = 'User with this email already exists!' + else if(data.includes('google') || data.includes('facebook') || data.includes('github')) resultError.firstElementChild.innerHTML = `You don't have set up password. Sign in with ${data.split(' ')[1]}` + else if(data === 'incorrect email') { + emailError.firstElementChild.innerHTML = `${icon} Incorrect email format` + emailError.classList.remove('disable') + emailInput.classList.add('error-red-border') + email.querySelector('label').classList.add('error-red') + } else if(data === `passwords don't match`) { + pswError.firstElementChild.innerHTML = `${icon} Passwords do not match` + pswInput.classList.add('error-red-border') + psw.querySelector('label').classList.add('error-red') + pswRepeatInput.classList.add('error-red-border') + pswRepeat.querySelector('label').classList.add('error-red') + } + } +} +function createFormData(word, data) { + let formData = new FormData + formData.append(word, data) + return formData +} + +function validateEmail(email) { + let mailformat = /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$/ + if (email.match(mailformat)) return true + else return false +} \ No newline at end of file diff --git a/add-ons/footer-scripts.php b/add-ons/footer-scripts.php index ce88c59..e34c4a3 100644 --- a/add-ons/footer-scripts.php +++ b/add-ons/footer-scripts.php @@ -1,3 +1,2 @@ - diff --git a/add-ons/head.php b/add-ons/head.php index 144f4c3..383ac7b 100644 --- a/add-ons/head.php +++ b/add-ons/head.php @@ -4,7 +4,7 @@ - + diff --git a/headlines.php b/headlines.php index dbc8930..b631504 100644 --- a/headlines.php +++ b/headlines.php @@ -4,7 +4,7 @@ - + diff --git a/include/check.inc.php b/include/check.inc.php new file mode 100644 index 0000000..c68cd83 --- /dev/null +++ b/include/check.inc.php @@ -0,0 +1,47 @@ +connect()->prepare($sql); + $stmt->execute([$userInfo[0]]); + $row = $stmt->fetch(); + if(isset($_POST['email'])) { + if($row) { + if($row['password'] == null) { + if($row['googleID'] != null) echo "google user doesn't have password set up"; + else if($row['facebookID'] != null) echo "facebook user doesn't have password set up"; + else if($row['githubID'] != null) echo "github user doesn't have password set up"; + } else echo 'user exists'; + + } else echo "user doesn't exist"; + return; + } + } + public function login($userInfo) { + if(!filter_var($userInfo[0], FILTER_VALIDATE_EMAIL)) { + echo 'error email'; + return; + } + + $sql = 'SELECT * FROM users WHERE email = ?'; + $stmt = $this->connect()->prepare($sql); + $stmt->execute([$userInfo[0]]); + $row = $stmt->fetch(); + + if(password_verify($userInfo[1], $row['password'])) { + include_once 'session.inc.php'; + $session = new Session(); + $session->setSession($userInfo[0]); + echo 'success'; + } else echo 'wrong password'; + } +} + +$checkObj = new Check(); + +if($_SERVER['REQUEST_METHOD'] !== 'POST') return; +if(isset($_POST['email'])) $checkObj->email(json_decode($_POST['email'])); +else if(isset($_POST['login'])) $checkObj->login(json_decode($_POST['login'])); + diff --git a/include/insert.inc.php b/include/insert.inc.php index 48b48f2..3f9c4e8 100644 --- a/include/insert.inc.php +++ b/include/insert.inc.php @@ -1,6 +1,6 @@ checkIfUserExists('google', $userInfo); + $userExist = $this->checkIfUserExistsExternal('google', $userInfo); if($userExist == 'empty') $this->insert('google', $userInfo); else if($userExist == 'ID') $this->updateID('googleID', $userInfo); $this->setSessionVariables($userInfo[6]); echo 'success'; } public function facebook($userInfo) { - $userExist = $this->checkIfUserExists('facebook', $userInfo); + $userExist = $this->checkIfUserExistsExternal('facebook', $userInfo); if($userExist == 'empty') $this->insert('facebook', $userInfo); else if($userExist == 'ID') $this->updateID('facebookID', $userInfo); $this->setSessionVariables($userInfo[6]); echo 'success'; } - public function checkIfUserExists($type, $userInfo) { + public function checkIfUserExistsExternal($type, $userInfo) { $sql = 'SELECT * FROM users WHERE email = ?'; $stmt = $this->connect()->prepare($sql); @@ -42,19 +42,29 @@ class Login extends Dbh { public function insert($type, $userInfo) { if($type == 'google') { $num = 2; + $emailNum = 6; $sql = 'INSERT INTO users(name, surname, email, google_profile_img, googleID) VALUES(?, ?, ?, ?, ?)'; $hashGoogleID = password_hash($userInfo[0], PASSWORD_DEFAULT); $array = [$userInfo[3], $userInfo[4], $userInfo[6], $userInfo[5], $hashGoogleID]; } else if ($type == 'facebook') { $num = 3; + $emailNum = 6; $sql = 'INSERT INTO users(name, surname, email, facebook_profile_img, facebookID) VALUES(?, ?, ?, ?, ?)'; $hashFacebookID = password_hash($userInfo[0], PASSWORD_DEFAULT); $array = [$userInfo[3], $userInfo[4], $userInfo[6], $userInfo[5], $hashFacebookID]; + } else if($type === 'standard') { + $num = 1; + $emailNum = 2; + $countryID = $this->getCountryIDwithName($userInfo[5]); + $hashPassword = password_hash($userInfo[3], PASSWORD_DEFAULT); + $sql = 'INSERT INTO users(name, surname, email, password, country_id) VALUES(?, ?, ?, ?, ?)'; + $array = [$userInfo[0], $userInfo[1], $userInfo[2], $hashPassword, $countryID]; } $stmt = $this->connect()->prepare($sql); $stmt->execute($array); - - $this->updateProfileChoice($num, $userInfo[6]); + $this->updateProfileChoice($num, $userInfo[$emailNum]); + $this->setSessionVariables($userInfo[$emailNum]); + echo 'success'; } public function updateID($type, $userInfo) { if($this->isIdSet($type, $userInfo) == 1) { @@ -85,42 +95,50 @@ class Login extends Dbh { $stmt->execute([$num, $email]); } public function setSessionVariables($email) { - session_start(); + include_once 'session.inc.php'; + $session = new Session(); + $session->setSession($email); + } + public function getCountryIDwithName($country) { + $sql = 'SELECT * FROM countries WHERE name = ?'; + $stmt = $this->connect()->prepare($sql); + $stmt->execute([$country]); + $row = $stmt->fetch(); + $countryID = $row['id']; + return $countryID; + } + public function standard($userInfo) { + $res = $this->checkIfUserExists($userInfo[2]); + if($res == "user exist's") { + echo "user exist's"; + return; + } else if($res == "exist google" || $res == "exist facebook" || $res == "exist github") { + echo $res; + return; + } + if(!filter_var($userInfo[2], FILTER_VALIDATE_EMAIL)) { + echo 'incorrect email'; + return; + } + if($userInfo[3] !== $userInfo[4]) { + echo "passwords don't match"; + return; + } + $this->insert('standard', $userInfo); + } + public function checkIfUserExists($email) { $sql = 'SELECT * FROM users WHERE email = ?'; $stmt = $this->connect()->prepare($sql); $stmt->execute([$email]); $row = $stmt->fetch(); - - $_SESSION['id'] = $row['id']; - $_SESSION['name'] = $row['name']; - $_SESSION['surname'] = $row['surname']; - $_SESSION['email'] = $email; - $_SESSION['gender'] = $row['gender']; - $_SESSION['password_change'] = $row['password_change']; - $_SESSION['profile_img'] = $row['profile_img']; - $_SESSION['profile_color'] = $row['profile_color']; - $_SESSION['google_profile_img'] = $row['google_profile_img']; - $_SESSION['facebook_profile_img'] = $row['facebook_profile_img']; - $_SESSION['github_profile_img'] = $row['github_profile_img']; - $_SESSION['profile_choice'] = $row['profile_choice']; - $_SESSION['googleID'] = $this->checkIfStringNull($row['googleID']); - $_SESSION['facebookID'] = $this->checkIfStringNull($row['facebookID']); - $_SESSION['githubID'] = $this->checkIfStringNull($row['githubID']); - $_SESSION['country'] = $this->getCountryWithID($row['country_id']); - } - - public function checkIfStringNull($string) { - if($string == null) return 0; - else return 1; - } - public function getCountryWithID($countryID) { - $sql = 'SELECT * FROM countries WHERE id = ?'; - $stmt = $this->connect()->prepare($sql); - $stmt->execute([$countryID]); - $row = $stmt->fetch(); - $country = array($row['name'], $row['acronym']); - return $country; + if($row) { + if($row['googleID'] != null) return "exist google"; + if($row['facebookID'] != null) return "exist facebook"; + if($row['githubID'] != null) return "exist github"; + return "user exist's"; + } + else return "user doesn't exist's"; } } @@ -129,3 +147,4 @@ $loginObj = new Login(); if($_SERVER['REQUEST_METHOD'] !== 'POST') return; else if(isset($_POST['google'])) $loginObj->google(json_decode($_POST['google'])); else if(isset($_POST['facebook'])) $loginObj->facebook(json_decode($_POST['facebook'])); +else if(isset($_POST['standard'])) $loginObj->standard(json_decode($_POST['standard'])); \ No newline at end of file diff --git a/include/isSessionSet.inc.php b/include/isSessionSet.inc.php new file mode 100644 index 0000000..f53c8c4 --- /dev/null +++ b/include/isSessionSet.inc.php @@ -0,0 +1,7 @@ +connect()->prepare($sql); + $stmt->execute([$email]); + $row = $stmt->fetch(); + $_SESSION['id'] = $row['id']; + $_SESSION['name'] = $row['name']; + $_SESSION['surname'] = $row['surname']; + $_SESSION['email'] = $email; + $_SESSION['gender'] = $row['gender']; + $_SESSION['password_change'] = $row['password_change']; + $_SESSION['profile_img'] = $row['profile_img']; + $_SESSION['profile_color'] = $row['profile_color']; + $_SESSION['google_profile_img'] = $row['google_profile_img']; + $_SESSION['facebook_profile_img'] = $row['facebook_profile_img']; + $_SESSION['github_profile_img'] = $row['github_profile_img']; + $_SESSION['profile_choice'] = $row['profile_choice']; + $_SESSION['googleID'] = $this->checkIfStringNull($row['googleID']); + $_SESSION['facebookID'] = $this->checkIfStringNull($row['facebookID']); + $_SESSION['githubID'] = $this->checkIfStringNull($row['githubID']); + $_SESSION['country'] = $this->getCountryWithID($row['country_id']); + } + public function checkIfStringNull($string) { + if($string == null) return 0; + else return 1; + } + public function getCountryWithID($countryID) { + $sql = 'SELECT * FROM countries WHERE id = ?'; + $stmt = $this->connect()->prepare($sql); + $stmt->execute([$countryID]); + $row = $stmt->fetch(); + $country = array($row['name'], $row['acronym']); + return $country; + } +} + \ No newline at end of file diff --git a/oauth.js b/oauth.js deleted file mode 100755 index f1064c6..0000000 --- a/oauth.js +++ /dev/null @@ -1,5573 +0,0 @@ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.oauthioWeb = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0)) { - frm = document.createElement("iframe"); - frm.src = config.oauthd_url + "/auth/iframe?d=" + encodeURIComponent(Url.getAbsUrl("/")); - frm.width = 0; - frm.height = 0; - frm.frameBorder = 0; - frm.style.visibility = "hidden"; - document.body.appendChild(frm); - } - wndTimeout = setTimeout(function() { - if (defer != null) { - defer.reject(new Error("Authorization timed out")); - } - if (opts.callback && typeof opts.callback === "function") { - opts.callback(new Error("Authorization timed out")); - } - try { - wnd.close(); - } catch (_error) {} - }, 1200 * 1000); - wnd = window.open(url, "Authorization", wnd_options); - if (wnd) { - wnd.focus(); - interval = window.setInterval(function() { - if (wnd === null || wnd.closed) { - window.clearInterval(interval); - if (!gotmessage) { - if (defer != null) { - defer.reject(new Error("The popup was closed")); - } - if (opts.callback && typeof opts.callback === "function") { - return opts.callback(new Error("The popup was closed")); - } - } - } - }, 500); - } else { - if (defer != null) { - defer.reject(new Error("Could not open a popup")); - } - if (opts.callback && typeof opts.callback === "function") { - opts.callback(new Error("Could not open a popup")); - } - } - return defer != null ? defer.promise() : void 0; - }, - redirect: function(provider, opts, url) { - var redirect_uri, res; - if (arguments.length === 2) { - url = opts; - opts = {}; - } - if (typeof url !== 'string') { - throw new Error('You must specify an url'); - } - if (cache.cacheEnabled(opts.cache)) { - res = cache.tryCache(oauth, provider, opts.cache); - if (res) { - url = Url.getAbsUrl(url) + (url.indexOf("#") === -1 ? "#" : "&") + "oauthio=cache:" + provider; - location_operations.changeHref(url); - location_operations.reload(); - return; - } - } - if (!opts.state) { - opts.state = sha1.create_hash(); - opts.state_type = "client"; - } - cookies.create("oauthio_state", opts.state); - redirect_uri = encodeURIComponent(Url.getAbsUrl(url)); - url = config.oauthd_url + "/auth/" + provider + "?k=" + config.key; - url += "&redirect_uri=" + redirect_uri; - if (opts) { - url += "&opts=" + encodeURIComponent(JSON.stringify(opts)); - } - location_operations.changeHref(url); - }, - isRedirect: function(provider) { - var cache_provider, data, e; - if (oauth_result == null) { - return false; - } - if ((oauth_result != null ? oauth_result.substr(0, 6) : void 0) === "cache:") { - cache_provider = oauth_result != null ? oauth_result.substr(6) : void 0; - if (!provider) { - return cache_provider; - } - return cache_provider.toLowerCase() === provider.toLowerCase(); - } - try { - data = JSON.parse(oauth_result); - } catch (_error) { - e = _error; - return false; - } - if (provider) { - return data.provider.toLowerCase() === provider.toLowerCase(); - } - return data.provider; - }, - callback: function(provider, opts, callback) { - var defer, err, res; - defer = $.Deferred(); - if (arguments.length === 1 && typeof provider === "function") { - callback = provider; - provider = undefined; - opts = {}; - } - if (arguments.length === 1 && typeof provider === "string") { - opts = {}; - } - if (arguments.length === 2 && typeof opts === "function") { - callback = opts; - opts = {}; - } - if (cache.cacheEnabled(opts != null ? opts.cache : void 0) || (oauth_result != null ? oauth_result.substr(0, 6) : void 0) === "cache:") { - if (!provider && (oauth_result != null ? oauth_result.substr(0, 6) : void 0) === "cache:") { - provider = oauth_result.substr(6); - } - res = cache.tryCache(oauth, provider, true); - if (res) { - if (callback) { - if (res) { - return callback(null, res); - } - } else { - if (defer != null) { - defer.resolve(res); - } - return defer != null ? defer.promise() : void 0; - } - } else if ((oauth_result != null ? oauth_result.substr(0, 6) : void 0) === "cache:") { - err = new Error('Could not fetch data from cache'); - if (callback) { - return callback(err); - } else { - if (defer != null) { - defer.reject(err); - } - return defer != null ? defer.promise() : void 0; - } - } - } - if (!oauth_result) { - return; - } - oauthio.request.sendCallback({ - data: oauth_result, - provider: provider, - cache: opts != null ? opts.cache : void 0, - expires: opts != null ? opts.expires : void 0, - callback: callback - }, defer); - return defer != null ? defer.promise() : void 0; - }, - clearCache: function(provider) { - return cache.clearCache(provider); - }, - http_me: function(opts) { - if (oauthio.request.http_me) { - oauthio.request.http_me(opts); - } - }, - http: function(opts) { - if (oauthio.request.http) { - oauthio.request.http(opts); - } - }, - getVersion: function() { - return OAuthio.getVersion.apply(this); - } - }; - return oauth; -}; - -},{"../tools/cookies":10,"../tools/sha1":14,"./providers":5,"./request":6}],5:[function(require,module,exports){ -"use strict"; -var config; - -config = require("../config"); - -module.exports = function(OAuthio) { - var $, providers_api, providers_cb, providers_desc; - $ = OAuthio.getJquery(); - providers_desc = {}; - providers_cb = {}; - providers_api = { - execProvidersCb: function(provider, e, r) { - var cbs, i; - if (providers_cb[provider]) { - cbs = providers_cb[provider]; - delete providers_cb[provider]; - for (i in cbs) { - cbs[i](e, r); - } - } - }, - fetchDescription: function(provider) { - if (providers_desc[provider]) { - return; - } - providers_desc[provider] = true; - $.ajax({ - url: config.oauthd_api + "/providers/" + provider, - data: { - extend: true - }, - dataType: "json" - }).done(function(data) { - providers_desc[provider] = data.data; - providers_api.execProvidersCb(provider, null, data.data); - }).always(function() { - if (typeof providers_desc[provider] !== "object") { - delete providers_desc[provider]; - providers_api.execProvidersCb(provider, new Error("Unable to fetch request description")); - } - }); - }, - getDescription: function(provider, opts, callback) { - opts = opts || {}; - if (typeof providers_desc[provider] === "object") { - return callback(null, providers_desc[provider]); - } - if (!providers_desc[provider]) { - providers_api.fetchDescription(provider); - } - if (!opts.wait) { - return callback(null, {}); - } - providers_cb[provider] = providers_cb[provider] || []; - providers_cb[provider].push(callback); - } - }; - return providers_api; -}; - -},{"../config":1}],6:[function(require,module,exports){ -"use strict"; -var Url, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - -Url = require('../tools/url')(); - -module.exports = function(OAuthio, client_states, providers_api) { - var $, cache, config, extended_methods, fetched_methods; - $ = OAuthio.getJquery(); - config = OAuthio.getConfig(); - cache = OAuthio.getCache(); - extended_methods = []; - fetched_methods = false; - return { - retrieveMethods: function() { - var defer; - defer = $.Deferred(); - if (!fetched_methods) { - $.ajax(config.oauthd_url + '/api/extended-endpoints').then(function(data) { - extended_methods = data.data; - fetched_methods = true; - return defer.resolve(); - }).fail(function(e) { - fetched_methods = true; - return defer.reject(e); - }); - } else { - defer.resolve(extended_methods); - } - return defer.promise(); - }, - generateMethods: function(request_object, tokens, provider) { - var j, k, kk, len, name_array, pt, results, v, vv; - if (extended_methods != null) { - results = []; - for (k = j = 0, len = extended_methods.length; j < len; k = ++j) { - v = extended_methods[k]; - name_array = v.name.split('.'); - pt = request_object; - results.push((function() { - var l, len1, results1; - results1 = []; - for (kk = l = 0, len1 = name_array.length; l < len1; kk = ++l) { - vv = name_array[kk]; - if (kk < name_array.length - 1) { - if (pt[vv] == null) { - pt[vv] = {}; - } - results1.push(pt = pt[vv]); - } else { - results1.push(pt[vv] = this.mkHttpAll(provider, tokens, v, arguments)); - } - } - return results1; - }).apply(this, arguments)); - } - return results; - } - }, - http: function(opts) { - var defer, desc_opts, doRequest, i, options; - doRequest = function() { - var i, k, qs, request; - request = options.oauthio.request || {}; - if (!request.cors) { - options.url = encodeURIComponent(options.url); - if (options.url[0] !== "/") { - options.url = "/" + options.url; - } - options.url = config.oauthd_url + "/request/" + options.oauthio.provider + options.url; - options.headers = options.headers || {}; - options.headers.oauthio = "k=" + config.key; - if (options.oauthio.tokens.oauth_token && options.oauthio.tokens.oauth_token_secret) { - options.headers.oauthio += "&oauthv=1"; - } - for (k in options.oauthio.tokens) { - options.headers.oauthio += "&" + encodeURIComponent(k) + "=" + encodeURIComponent(options.oauthio.tokens[k]); - } - delete options.oauthio; - return $.ajax(options); - } - if (options.oauthio.tokens) { - if (options.oauthio.tokens.access_token) { - options.oauthio.tokens.token = options.oauthio.tokens.access_token; - } - if (!options.url.match(/^[a-z]{2,16}:\/\//)) { - if (options.url[0] !== "/") { - options.url = "/" + options.url; - } - options.url = request.url + options.url; - } - options.url = Url.replaceParam(options.url, options.oauthio.tokens, request.parameters); - if (request.query) { - qs = []; - for (i in request.query) { - qs.push(encodeURIComponent(i) + "=" + encodeURIComponent(Url.replaceParam(request.query[i], options.oauthio.tokens, request.parameters))); - } - if (indexOf.call(options.url, "?") >= 0) { - options.url += "&" + qs; - } else { - options.url += "?" + qs; - } - } - if (request.headers) { - options.headers = options.headers || {}; - for (i in request.headers) { - options.headers[i] = Url.replaceParam(request.headers[i], options.oauthio.tokens, request.parameters); - } - } - delete options.oauthio; - return $.ajax(options); - } - }; - options = {}; - i = void 0; - for (i in opts) { - options[i] = opts[i]; - } - if (!options.oauthio.request || options.oauthio.request === true) { - desc_opts = { - wait: !!options.oauthio.request - }; - defer = $.Deferred(); - providers_api.getDescription(options.oauthio.provider, desc_opts, function(e, desc) { - if (e) { - return defer.reject(e); - } - if (options.oauthio.tokens.oauth_token && options.oauthio.tokens.oauth_token_secret) { - options.oauthio.request = desc.oauth1 && desc.oauth1.request; - } else { - options.oauthio.request = desc.oauth2 && desc.oauth2.request; - } - defer.resolve(); - }); - return defer.then(doRequest); - } else { - return doRequest(); - } - }, - http_me: function(opts) { - var defer, desc_opts, doRequest, k, options; - doRequest = function() { - var defer, k, promise, request; - defer = $.Deferred(); - request = options.oauthio.request || {}; - options.url = config.oauthd_url + "/auth/" + options.oauthio.provider + "/me"; - options.headers = options.headers || {}; - options.headers.oauthio = "k=" + config.key; - if (options.oauthio.tokens.oauth_token && options.oauthio.tokens.oauth_token_secret) { - options.headers.oauthio += "&oauthv=1"; - } - for (k in options.oauthio.tokens) { - options.headers.oauthio += "&" + encodeURIComponent(k) + "=" + encodeURIComponent(options.oauthio.tokens[k]); - } - delete options.oauthio; - promise = $.ajax(options); - $.when(promise).done(function(data) { - defer.resolve(data.data); - }).fail(function(data) { - if (data.responseJSON) { - defer.reject(data.responseJSON.data); - } else { - defer.reject(new Error("An error occured while trying to access the resource")); - } - }); - return defer.promise(); - }; - options = {}; - for (k in opts) { - options[k] = opts[k]; - } - if (!options.oauthio.request || options.oauthio.request === true) { - desc_opts = { - wait: !!options.oauthio.request - }; - defer = $.Deferred(); - providers_api.getDescription(options.oauthio.provider, desc_opts, function(e, desc) { - if (e) { - return defer.reject(e); - } - if (options.oauthio.tokens.oauth_token && options.oauthio.tokens.oauth_token_secret) { - options.oauthio.request = desc.oauth1 && desc.oauth1.request; - } else { - options.oauthio.request = desc.oauth2 && desc.oauth2.request; - } - defer.resolve(); - }); - return defer.then(doRequest); - } else { - return doRequest(); - } - }, - http_all: function(options, endpoint_descriptor, parameters) { - var doRequest; - doRequest = function() { - var defer, k, promise, request; - defer = $.Deferred(); - request = options.oauthio.request || {}; - options.headers = options.headers || {}; - options.headers.oauthio = "k=" + config.key; - if (options.oauthio.tokens.oauth_token && options.oauthio.tokens.oauth_token_secret) { - options.headers.oauthio += "&oauthv=1"; - } - for (k in options.oauthio.tokens) { - options.headers.oauthio += "&" + encodeURIComponent(k) + "=" + encodeURIComponent(options.oauthio.tokens[k]); - } - delete options.oauthio; - promise = $.ajax(options); - $.when(promise).done(function(data) { - var error; - if (typeof data.data === 'string') { - try { - data.data = JSON.parse(data.data); - } catch (_error) { - error = _error; - data.data = data.data; - } finally { - defer.resolve(data.data); - } - } - }).fail(function(data) { - if (data.responseJSON) { - defer.reject(data.responseJSON.data); - } else { - defer.reject(new Error("An error occured while trying to access the resource")); - } - }); - return defer.promise(); - }; - return doRequest(); - }, - mkHttp: function(provider, tokens, request, method) { - var base; - base = this; - return function(opts, opts2) { - var i, options; - options = {}; - if (typeof opts === "string") { - if (typeof opts2 === "object") { - for (i in opts2) { - options[i] = opts2[i]; - } - } - options.url = opts; - } else if (typeof opts === "object") { - for (i in opts) { - options[i] = opts[i]; - } - } - options.type = options.type || method; - options.oauthio = { - provider: provider, - tokens: tokens, - request: request - }; - return base.http(options); - }; - }, - mkHttpMe: function(provider, tokens, request, method) { - var base; - base = this; - return function(filter) { - var options; - options = {}; - options.type = options.type || method; - options.oauthio = { - provider: provider, - tokens: tokens, - request: request - }; - options.data = options.data || {}; - if (filter) { - options.data.filter = filter.join(","); - } - return base.http_me(options); - }; - }, - mkHttpAll: function(provider, tokens, endpoint_descriptor) { - var base; - base = this; - return function() { - var k, options, th_param, v; - options = {}; - options.type = endpoint_descriptor.method; - options.url = config.oauthd_url + endpoint_descriptor.endpoint.replace(':provider', provider); - options.oauthio = { - provider: provider, - tokens: tokens - }; - options.data = {}; - for (k in arguments) { - v = arguments[k]; - th_param = endpoint_descriptor.params[k]; - if (th_param != null) { - options.data[th_param.name] = v; - } - } - options.data = options.data || {}; - return base.http_all(options, endpoint_descriptor, arguments); - }; - }, - sendCallback: function(opts, defer) { - var base, data, e, err, i, make_res, request, res, tokens; - base = this; - data = void 0; - err = void 0; - try { - data = JSON.parse(opts.data); - } catch (_error) { - e = _error; - defer.reject(new Error("Error while parsing result")); - return opts.callback(new Error("Error while parsing result")); - } - if (!data || !data.provider) { - return; - } - if (opts.provider && data.provider.toLowerCase() !== opts.provider.toLowerCase()) { - err = new Error("Returned provider name does not match asked provider"); - defer.reject(err); - if (opts.callback && typeof opts.callback === "function") { - return opts.callback(err); - } else { - return; - } - } - if (data.status === "error" || data.status === "fail") { - err = new Error(data.message); - err.body = data.data; - defer.reject(err); - if (opts.callback && typeof opts.callback === "function") { - return opts.callback(err); - } else { - return; - } - } - if (data.status !== "success" || !data.data) { - err = new Error(); - err.body = data.data; - defer.reject(err); - if (opts.callback && typeof opts.callback === "function") { - return opts.callback(err); - } else { - return; - } - } - data.state = data.state.replace(/\s+/g, ""); - i = 0; - while (i < client_states.length) { - client_states[i] = client_states[i].replace(/\s+/g, ""); - i++; - } - if (!data.state || client_states.indexOf(data.state) === -1) { - defer.reject(new Error("State is not matching")); - if (opts.callback && typeof opts.callback === "function") { - return opts.callback(new Error("State is not matching")); - } else { - return; - } - } - if (!opts.provider) { - data.data.provider = data.provider; - } - res = data.data; - res.provider = data.provider.toLowerCase(); - if (cache.cacheEnabled(opts.cache) && res) { - if (opts.expires && !res.expires_in) { - res.expires_in = opts.expires; - } - cache.storeCache(data.provider, res); - } - request = res.request; - delete res.request; - tokens = void 0; - if (res.access_token) { - tokens = { - access_token: res.access_token - }; - } else if (res.oauth_token && res.oauth_token_secret) { - tokens = { - oauth_token: res.oauth_token, - oauth_token_secret: res.oauth_token_secret - }; - } - if (!request) { - defer.resolve(res); - if (opts.callback && typeof opts.callback === "function") { - return opts.callback(null, res); - } else { - return; - } - } - if (request.required) { - for (i in request.required) { - tokens[request.required[i]] = res[request.required[i]]; - } - } - make_res = function(method) { - return base.mkHttp(data.provider, tokens, request, method); - }; - res.toJson = function() { - var a; - a = {}; - if (res.access_token != null) { - a.access_token = res.access_token; - } - if (res.oauth_token != null) { - a.oauth_token = res.oauth_token; - } - if (res.oauth_token_secret != null) { - a.oauth_token_secret = res.oauth_token_secret; - } - if (res.expires_in != null) { - a.expires_in = res.expires_in; - } - if (res.token_type != null) { - a.token_type = res.token_type; - } - if (res.id_token != null) { - a.id_token = res.id_token; - } - if (res.provider != null) { - a.provider = res.provider; - } - if (res.email != null) { - a.email = res.email; - } - return a; - }; - res.get = make_res("GET"); - res.post = make_res("POST"); - res.put = make_res("PUT"); - res.patch = make_res("PATCH"); - res.del = make_res("DELETE"); - res.me = base.mkHttpMe(data.provider, tokens, request, "GET"); - return this.retrieveMethods().then((function(_this) { - return function() { - _this.generateMethods(res, tokens, data.provider); - defer.resolve(res); - if (opts.callback && typeof opts.callback === "function") { - return opts.callback(null, res); - } else { - - } - }; - })(this)).fail((function(_this) { - return function(e) { - console.log('Could not retrieve methods', e); - defer.resolve(res); - if (opts.callback && typeof opts.callback === "function") { - return opts.callback(null, res); - } else { - - } - }; - })(this)); - } - }; -}; - -},{"../tools/url":15}],7:[function(require,module,exports){ -"use strict"; -module.exports = function(OAuthio) { - var $, UserObject, config, lastSave, storage; - $ = OAuthio.getJquery(); - config = OAuthio.getConfig(); - storage = OAuthio.getStorage(); - lastSave = null; - UserObject = (function() { - function UserObject(data) { - this.token = data.token; - this.data = data.user; - this.providers = data.providers; - lastSave = this.getEditableData(); - } - - UserObject.prototype.getEditableData = function() { - var data, key; - data = []; - for (key in this.data) { - if (['id', 'email'].indexOf(key) === -1) { - data.push({ - key: key, - value: this.data[key] - }); - } - } - return data; - }; - - UserObject.prototype.save = function() { - var d, dataToSave, i, j, keyIsInLastSave, len, len1, ref; - dataToSave = {}; - for (i = 0, len = lastSave.length; i < len; i++) { - d = lastSave[i]; - if (this.data[d.key] !== d.value) { - dataToSave[d.key] = this.data[d.key]; - } - if (this.data[d.key] === null) { - delete this.data[d.key]; - } - } - keyIsInLastSave = function(key) { - var j, len1, o; - for (j = 0, len1 = lastSave.length; j < len1; j++) { - o = lastSave[j]; - if (o.key === key) { - return true; - } - } - return false; - }; - ref = this.getEditableData(); - for (j = 0, len1 = ref.length; j < len1; j++) { - d = ref[j]; - if (!keyIsInLastSave(d.key)) { - dataToSave[d.key] = this.data[d.key]; - } - } - this.saveLocal(); - return OAuthio.API.put('/api/usermanagement/user?k=' + config.key + '&token=' + this.token, dataToSave); - }; - - UserObject.prototype.select = function(provider) { - var OAuthResult; - OAuthResult = null; - return OAuthResult; - }; - - UserObject.prototype.saveLocal = function() { - var copy; - copy = { - token: this.token, - user: this.data, - providers: this.providers - }; - storage.erase('oio_auth'); - return storage.create('oio_auth', JSON.stringify(copy), 21600); - }; - - UserObject.prototype.hasProvider = function(provider) { - return !!this.providers && this.providers.indexOf(provider) !== -1; - }; - - UserObject.prototype.getProviders = function() { - var defer; - defer = $.Deferred(); - OAuthio.API.get('/api/usermanagement/user/providers?k=' + config.key + '&token=' + this.token).done((function(_this) { - return function(providers) { - _this.providers = providers.data; - _this.saveLocal(); - return defer.resolve(_this.providers); - }; - })(this)).fail(function(err) { - return defer.reject(err); - }); - return defer.promise(); - }; - - UserObject.prototype.addProvider = function(oauthRes) { - var defer; - defer = $.Deferred(); - if (typeof oauthRes.toJson === 'function') { - oauthRes = oauthRes.toJson(); - } - oauthRes.email = this.data.email; - if (!this.providers) { - this.providers = []; - } - this.providers.push(oauthRes.provider); - OAuthio.API.post('/api/usermanagement/user/providers?k=' + config.key + '&token=' + this.token, oauthRes).done((function(_this) { - return function(res) { - _this.data = res.data; - _this.saveLocal(); - return defer.resolve(); - }; - })(this)).fail((function(_this) { - return function(err) { - _this.providers.splice(_this.providers.indexOf(oauthRes.provider), 1); - return defer.reject(err); - }; - })(this)); - return defer.promise(); - }; - - UserObject.prototype.removeProvider = function(provider) { - var defer; - defer = $.Deferred(); - this.providers.splice(this.providers.indexOf(provider), 1); - OAuthio.API.del('/api/usermanagement/user/providers/' + provider + '?k=' + config.key + '&token=' + this.token).done((function(_this) { - return function(res) { - _this.saveLocal(); - return defer.resolve(res); - }; - })(this)).fail((function(_this) { - return function(err) { - _this.providers.push(provider); - return defer.reject(err); - }; - })(this)); - return defer.promise(); - }; - - UserObject.prototype.changePassword = function(oldPassword, newPassword) { - return OAuthio.API.post('/api/usermanagement/user/password?k=' + config.key + '&token=' + this.token, { - password: newPassword - }); - }; - - UserObject.prototype.isLoggued = function() { - return OAuthio.User.isLogged(); - }; - - UserObject.prototype.isLogged = function() { - return OAuthio.User.isLogged(); - }; - - UserObject.prototype.logout = function() { - var defer; - defer = $.Deferred(); - storage.erase('oio_auth'); - OAuthio.API.post('/api/usermanagement/user/logout?k=' + config.key + '&token=' + this.token).done(function() { - return defer.resolve(); - }).fail(function(err) { - return defer.reject(err); - }); - return defer.promise(); - }; - - return UserObject; - - })(); - return { - initialize: function(public_key, options) { - return OAuthio.initialize(public_key, options); - }, - setOAuthdURL: function(url) { - return OAuthio.setOAuthdURL(url); - }, - signup: function(data) { - var defer; - defer = $.Deferred(); - if (typeof data.toJson === 'function') { - data = data.toJson(); - } - OAuthio.API.post('/api/usermanagement/signup?k=' + config.key, data).done(function(res) { - storage.create('oio_auth', JSON.stringify(res.data), res.data.expires_in || 21600); - return defer.resolve(new UserObject(res.data)); - }).fail(function(err) { - return defer.reject(err); - }); - return defer.promise(); - }, - signin: function(email, password) { - var defer, signinData; - defer = $.Deferred(); - if (typeof email !== "string" && !password) { - signinData = email; - if (typeof signinData.toJson === 'function') { - signinData = signinData.toJson(); - } - OAuthio.API.post('/api/usermanagement/signin?k=' + config.key, signinData).done(function(res) { - storage.create('oio_auth', JSON.stringify(res.data), res.data.expires_in || 21600); - return defer.resolve(new UserObject(res.data)); - }).fail(function(err) { - return defer.reject(err); - }); - } else { - OAuthio.API.post('/api/usermanagement/signin?k=' + config.key, { - email: email, - password: password - }).done(function(res) { - storage.create('oio_auth', JSON.stringify(res.data), res.data.expires_in || 21600); - return defer.resolve(new UserObject(res.data)); - }).fail(function(err) { - return defer.reject(err); - }); - } - return defer.promise(); - }, - confirmResetPassword: function(newPassword, sptoken) { - return OAuthio.API.post('/api/usermanagement/user/password?k=' + config.key, { - password: newPassword, - token: sptoken - }); - }, - resetPassword: function(email, callback) { - return OAuthio.API.post('/api/usermanagement/user/password/reset?k=' + config.key, { - email: email - }); - }, - refreshIdentity: function() { - var defer; - defer = $.Deferred(); - OAuthio.API.get('/api/usermanagement/user?k=' + config.key + '&token=' + JSON.parse(storage.read('oio_auth')).token).done(function(res) { - return defer.resolve(new UserObject(res.data)); - }).fail(function(err) { - return defer.reject(err); - }); - return defer.promise(); - }, - getIdentity: function() { - var user; - user = storage.read('oio_auth'); - if (!user) { - return null; - } - return new UserObject(JSON.parse(user)); - }, - isLogged: function() { - var a; - a = storage.read('oio_auth'); - if (a) { - return true; - } - return false; - } - }; -}; - -},{}],8:[function(require,module,exports){ -(function() { - var OAuthio, jquery; - jquery = require('./tools/jquery-lite.js'); - OAuthio = require('./lib/core')(window, document, jquery, navigator); - OAuthio.extend('OAuth', require('./lib/oauth')); - OAuthio.extend('API', require('./lib/api')); - OAuthio.extend('User', require('./lib/user')); - if (typeof angular !== "undefined" && angular !== null) { - angular.module('oauthio', []).factory('OAuth', [ - function() { - return OAuthio.OAuth; - } - ]).factory('User', [ - function() { - return OAuthio.User; - } - ]); - } - exports.OAuthio = OAuthio; - window.User = exports.User = exports.OAuthio.User; - window.OAuth = exports.OAuth = exports.OAuthio.OAuth; - if (typeof define === 'function' && define.amd) { - define(function() { - return exports; - }); - } - if ((typeof module !== "undefined" && module !== null ? module.exports : void 0)) { - module.exports = exports; - } - return exports; -})(); - -},{"./lib/api":2,"./lib/core":3,"./lib/oauth":4,"./lib/user":7,"./tools/jquery-lite.js":11}],9:[function(require,module,exports){ -"use strict"; -module.exports = { - init: function(storage, config) { - this.config = config; - return this.storage = storage; - }, - tryCache: function(OAuth, provider, cache) { - var e, i, res; - if (this.cacheEnabled(cache)) { - cache = this.storage.read("oauthio_provider_" + provider); - if (!cache) { - return false; - } - cache = decodeURIComponent(cache); - } - if (typeof cache === "string") { - try { - cache = JSON.parse(cache); - } catch (_error) { - e = _error; - return false; - } - } - if (typeof cache === "object") { - res = {}; - for (i in cache) { - if (i !== "request" && typeof cache[i] !== "function") { - res[i] = cache[i]; - } - } - return OAuth.create(provider, res, cache.request); - } - return false; - }, - storeCache: function(provider, cache) { - var expires; - expires = 3600; - if (cache.expires_in) { - expires = cache.expires_in; - } else if (this.config.options.expires || this.config.options.expires === false) { - expires = this.config.options.expires; - } - this.storage.create("oauthio_provider_" + provider, encodeURIComponent(JSON.stringify(cache)), expires); - }, - cacheEnabled: function(cache) { - if (typeof cache === "undefined") { - return this.config.options.cache; - } - return cache; - }, - clearCache: function(provider) { - if (provider) { - this.storage.erase("oauthio_provider_" + provider); - } else { - this.storage.eraseFrom("oauthio_provider_"); - } - } -}; - -},{}],10:[function(require,module,exports){ -"use strict"; -module.exports = { - init: function(config, document) { - this.config = config; - return this.document = document; - }, - create: function(name, value, expires) { - var date; - this.erase(name); - date = new Date(); - if (expires) { - date.setTime(date.getTime() + (expires || 1200) * 1000); - } else { - date.setFullYear(date.getFullYear() + 3); - } - expires = "; expires=" + date.toGMTString(); - this.document.cookie = name + "=" + value + expires + "; path=/"; - }, - read: function(name) { - var c, ca, i, nameEQ; - nameEQ = name + "="; - ca = this.document.cookie.split(";"); - i = 0; - while (i < ca.length) { - c = ca[i]; - while (c.charAt(0) === " ") { - c = c.substring(1, c.length); - } - if (c.indexOf(nameEQ) === 0) { - return c.substring(nameEQ.length, c.length); - } - i++; - } - return null; - }, - erase: function(name) { - var date; - date = new Date(); - date.setTime(date.getTime() - 86400000); - this.document.cookie = name + "=; expires=" + date.toGMTString() + "; path=/"; - }, - eraseFrom: function(prefix) { - var cname, cookie, cookies, j, len; - cookies = this.document.cookie.split(";"); - for (j = 0, len = cookies.length; j < len; j++) { - cookie = cookies[j]; - cname = cookie.split("=")[0].trim(); - if (cname.substr(0, prefix.length) === prefix) { - this.erase(cname); - } - } - } -}; - -},{}],11:[function(require,module,exports){ -/*! - * jQuery JavaScript Library v2.1.1 -attributes,-attributes/attr,-attributes/classes,-attributes/prop,-attributes/support,-attributes/val,-css/addGetHookIf,-css/curCSS,-css/defaultDisplay,-css/hiddenVisibleSelectors,-css/support,-css/swap,-css/var,-css/var/cssExpand,-css/var/getStyles,-css/var/isHidden,-css/var/rmargin,-css/var/rnumnonpx,-css,-effects,-effects/Tween,-effects/animatedSelector,-dimensions,-offset,-data/var/data_user,-deprecated,-event/alias,-event/support,-intro,-manipulation/_evalUrl,-manipulation/support,-manipulation/var,-manipulation/var/rcheckableType,-manipulation,-outro,-queue,-queue/delay,-selector-native,-selector-sizzle,-sizzle/dist,-sizzle/dist/sizzle,-sizzle/dist/min,-sizzle/test,-sizzle/test/jquery,-traversing,-traversing/findFilter,-traversing/var/rneedsContext,-traversing/var,-wrap,-exports,-exports/amd - * http://jquery.com/ - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * - * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2014-09-24T13:40Z - */ - -(function( global, factory ) { - - if ( typeof module === "object" && typeof module.exports === "object" ) { - // For CommonJS and CommonJS-like environments where a proper window is present, - // execute the factory and get jQuery - // For environments that do not inherently posses a window with a document - // (such as Node.js), expose a jQuery-making factory as module.exports - // This accentuates the need for the creation of a real window - // e.g. var jQuery = require("jquery")(window); - // See ticket #14549 for more info - module.exports = global.document ? - factory( global, true ) : - function( w ) { - if ( !w.document ) { - throw new Error( "jQuery requires a window with a document" ); - } - return factory( w ); - }; - } else { - factory( global ); - } - -// Pass this if window is not defined yet -}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { - -// Can't do this because several apps including ASP.NET trace -// the stack via arguments.caller.callee and Firefox dies if -// you try to trace through "use strict" call chains. (#13335) -// Support: Firefox 18+ -// - -var arr = []; - -var slice = arr.slice; - -var concat = arr.concat; - -var push = arr.push; - -var indexOf = arr.indexOf; - -var class2type = {}; - -var toString = class2type.toString; - -var hasOwn = class2type.hasOwnProperty; - -var support = {}; - - - -var - // Use the correct document accordingly with window argument (sandbox) - document = window.document, - - version = "2.1.1 -attributes,-attributes/attr,-attributes/classes,-attributes/prop,-attributes/support,-attributes/val,-css/addGetHookIf,-css/curCSS,-css/defaultDisplay,-css/hiddenVisibleSelectors,-css/support,-css/swap,-css/var,-css/var/cssExpand,-css/var/getStyles,-css/var/isHidden,-css/var/rmargin,-css/var/rnumnonpx,-css,-effects,-effects/Tween,-effects/animatedSelector,-dimensions,-offset,-data/var/data_user,-deprecated,-event/alias,-event/support,-intro,-manipulation/_evalUrl,-manipulation/support,-manipulation/var,-manipulation/var/rcheckableType,-manipulation,-outro,-queue,-queue/delay,-selector-native,-selector-sizzle,-sizzle/dist,-sizzle/dist/sizzle,-sizzle/dist/min,-sizzle/test,-sizzle/test/jquery,-traversing,-traversing/findFilter,-traversing/var/rneedsContext,-traversing/var,-wrap,-exports,-exports/amd", - - // Define a local copy of jQuery - jQuery = function( selector, context ) { - // The jQuery object is actually just the init constructor 'enhanced' - // Need init if jQuery is called (just allow error to be thrown if not included) - return new jQuery.fn.init( selector, context ); - }, - - // Support: Android<4.1 - // Make sure we trim BOM and NBSP - rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, - - // Matches dashed string for camelizing - rmsPrefix = /^-ms-/, - rdashAlpha = /-([\da-z])/gi, - - // Used by jQuery.camelCase as callback to replace() - fcamelCase = function( all, letter ) { - return letter.toUpperCase(); - }; - -jQuery.fn = jQuery.prototype = { - // The current version of jQuery being used - jquery: version, - - constructor: jQuery, - - // Start with an empty selector - selector: "", - - // The default length of a jQuery object is 0 - length: 0, - - toArray: function() { - return slice.call( this ); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - return num != null ? - - // Return just the one element from the set - ( num < 0 ? this[ num + this.length ] : this[ num ] ) : - - // Return all the elements in a clean array - slice.call( this ); - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems ) { - - // Build a new jQuery matched element set - var ret = jQuery.merge( this.constructor(), elems ); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - ret.context = this.context; - - // Return the newly-formed element set - return ret; - }, - - // Execute a callback for every element in the matched set. - // (You can seed the arguments with an array of args, but this is - // only used internally.) - each: function( callback, args ) { - return jQuery.each( this, callback, args ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map(this, function( elem, i ) { - return callback.call( elem, i, elem ); - })); - }, - - slice: function() { - return this.pushStack( slice.apply( this, arguments ) ); - }, - - first: function() { - return this.eq( 0 ); - }, - - last: function() { - return this.eq( -1 ); - }, - - eq: function( i ) { - var len = this.length, - j = +i + ( i < 0 ? len : 0 ); - return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); - }, - - end: function() { - return this.prevObject || this.constructor(null); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: arr.sort, - splice: arr.splice -}; - -jQuery.extend = jQuery.fn.extend = function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[0] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - - // skip the boolean and the target - target = arguments[ i ] || {}; - i++; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !jQuery.isFunction(target) ) { - target = {}; - } - - // extend jQuery itself if only one argument is passed - if ( i === length ) { - target = this; - i--; - } - - for ( ; i < length; i++ ) { - // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) { - // Extend the base object - for ( name in options ) { - src = target[ name ]; - copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { - if ( copyIsArray ) { - copyIsArray = false; - clone = src && jQuery.isArray(src) ? src : []; - - } else { - clone = src && jQuery.isPlainObject(src) ? src : {}; - } - - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - -jQuery.extend({ - // Unique for each copy of jQuery on the page - expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), - - // Assume jQuery is ready without the ready module - isReady: true, - - error: function( msg ) { - throw new Error( msg ); - }, - - noop: function() {}, - - // See test/unit/core.js for details concerning isFunction. - // Since version 1.3, DOM methods and functions like alert - // aren't supported. They return false on IE (#2968). - isFunction: function( obj ) { - return jQuery.type(obj) === "function"; - }, - - isArray: Array.isArray, - - isWindow: function( obj ) { - return obj != null && obj === obj.window; - }, - - isNumeric: function( obj ) { - // parseFloat NaNs numeric-cast false positives (null|true|false|"") - // ...but misinterprets leading-number strings, particularly hex literals ("0x...") - // subtraction forces infinities to NaN - return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0; - }, - - isPlainObject: function( obj ) { - // Not plain objects: - // - Any object or value whose internal [[Class]] property is not "[object Object]" - // - DOM nodes - // - window - if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { - return false; - } - - if ( obj.constructor && - !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { - return false; - } - - // If the function hasn't returned already, we're confident that - // |obj| is a plain object, created by {} or constructed with new Object - return true; - }, - - isEmptyObject: function( obj ) { - var name; - for ( name in obj ) { - return false; - } - return true; - }, - - type: function( obj ) { - if ( obj == null ) { - return obj + ""; - } - // Support: Android < 4.0, iOS < 6 (functionish RegExp) - return typeof obj === "object" || typeof obj === "function" ? - class2type[ toString.call(obj) ] || "object" : - typeof obj; - }, - - // Evaluates a script in a global context - globalEval: function( code ) { - var script, - indirect = eval; - - code = jQuery.trim( code ); - - if ( code ) { - // If the code includes a valid, prologue position - // strict mode pragma, execute code by injecting a - // script tag into the document. - if ( code.indexOf("use strict") === 1 ) { - script = document.createElement("script"); - script.text = code; - document.head.appendChild( script ).parentNode.removeChild( script ); - } else { - // Otherwise, avoid the DOM node creation, insertion - // and removal by using an indirect global eval - indirect( code ); - } - } - }, - - // Convert dashed to camelCase; used by the css and data modules - // Microsoft forgot to hump their vendor prefix (#9572) - camelCase: function( string ) { - return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); - }, - - nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); - }, - - // args is for internal usage only - each: function( obj, callback, args ) { - var value, - i = 0, - length = obj.length, - isArray = isArraylike( obj ); - - if ( args ) { - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback.apply( obj[ i ], args ); - - if ( value === false ) { - break; - } - } - } else { - for ( i in obj ) { - value = callback.apply( obj[ i ], args ); - - if ( value === false ) { - break; - } - } - } - - // A special, fast, case for the most common use of each - } else { - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback.call( obj[ i ], i, obj[ i ] ); - - if ( value === false ) { - break; - } - } - } else { - for ( i in obj ) { - value = callback.call( obj[ i ], i, obj[ i ] ); - - if ( value === false ) { - break; - } - } - } - } - - return obj; - }, - - // Support: Android<4.1 - trim: function( text ) { - return text == null ? - "" : - ( text + "" ).replace( rtrim, "" ); - }, - - // results is for internal usage only - makeArray: function( arr, results ) { - var ret = results || []; - - if ( arr != null ) { - if ( isArraylike( Object(arr) ) ) { - jQuery.merge( ret, - typeof arr === "string" ? - [ arr ] : arr - ); - } else { - push.call( ret, arr ); - } - } - - return ret; - }, - - inArray: function( elem, arr, i ) { - return arr == null ? -1 : indexOf.call( arr, elem, i ); - }, - - merge: function( first, second ) { - var len = +second.length, - j = 0, - i = first.length; - - for ( ; j < len; j++ ) { - first[ i++ ] = second[ j ]; - } - - first.length = i; - - return first; - }, - - grep: function( elems, callback, invert ) { - var callbackInverse, - matches = [], - i = 0, - length = elems.length, - callbackExpect = !invert; - - // Go through the array, only saving the items - // that pass the validator function - for ( ; i < length; i++ ) { - callbackInverse = !callback( elems[ i ], i ); - if ( callbackInverse !== callbackExpect ) { - matches.push( elems[ i ] ); - } - } - - return matches; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - var value, - i = 0, - length = elems.length, - isArray = isArraylike( elems ), - ret = []; - - // Go through the array, translating each of the items to their new values - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - - // Go through every key on the object, - } else { - for ( i in elems ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - } - - // Flatten any nested arrays - return concat.apply( [], ret ); - }, - - // A global GUID counter for objects - guid: 1, - - // Bind a function to a context, optionally partially applying any - // arguments. - proxy: function( fn, context ) { - var tmp, args, proxy; - - if ( typeof context === "string" ) { - tmp = fn[ context ]; - context = fn; - fn = tmp; - } - - // 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 - args = slice.call( arguments, 2 ); - proxy = function() { - return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); - }; - - // Set the guid of unique handler to the same of original handler, so it can be removed - proxy.guid = fn.guid = fn.guid || jQuery.guid++; - - return proxy; - }, - - now: Date.now, - - // jQuery.support is not used in Core but other projects attach their - // properties to it so it needs to exist. - support: support -}); - -// Populate the class2type map -jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); -}); - -function isArraylike( obj ) { - var length = obj.length, - type = jQuery.type( obj ); - - if ( type === "function" || jQuery.isWindow( obj ) ) { - return false; - } - - if ( obj.nodeType === 1 && length ) { - return true; - } - - return type === "array" || length === 0 || - typeof length === "number" && length > 0 && ( length - 1 ) in obj; -} - -var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); - -// Initialize a jQuery object - - -// A central reference to the root jQuery(document) -var rootjQuery, - - // A simple way to check for HTML strings - // Prioritize #id over to avoid XSS via location.hash (#9521) - // Strict HTML recognition (#11290: must start with <) - rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, - - init = jQuery.fn.init = function( selector, context ) { - var match, elem; - - // HANDLE: $(""), $(null), $(undefined), $(false) - if ( !selector ) { - return this; - } - - // Handle HTML strings - if ( typeof selector === "string" ) { - if ( selector[0] === "<" && selector[ 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 = rquickExpr.exec( selector ); - } - - // Match html or make sure no context is specified for #id - if ( match && (match[1] || !context) ) { - - // HANDLE: $(html) -> $(array) - if ( match[1] ) { - context = context instanceof jQuery ? context[0] : context; - - // scripts is true for back-compat - // Intentionally let the error be thrown if parseHTML is not present - jQuery.merge( this, jQuery.parseHTML( - match[1], - context && context.nodeType ? context.ownerDocument || context : document, - true - ) ); - - // HANDLE: $(html, props) - if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { - for ( match in context ) { - // Properties of context are called as methods if possible - if ( jQuery.isFunction( this[ match ] ) ) { - this[ match ]( context[ match ] ); - - // ...and otherwise set as attributes - } else { - this.attr( match, context[ match ] ); - } - } - } - - return this; - - // HANDLE: $(#id) - } else { - elem = document.getElementById( match[2] ); - - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - if ( elem && elem.parentNode ) { - // Inject the element directly into the jQuery object - this.length = 1; - this[0] = elem; - } - - this.context = document; - this.selector = selector; - return this; - } - - // HANDLE: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return ( context || rootjQuery ).find( selector ); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor( context ).find( selector ); - } - - // HANDLE: $(DOMElement) - } else if ( selector.nodeType ) { - this.context = this[0] = selector; - this.length = 1; - return this; - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) { - return typeof rootjQuery.ready !== "undefined" ? - rootjQuery.ready( selector ) : - // Execute immediately if ready is not present - selector( jQuery ); - } - - if ( selector.selector !== undefined ) { - this.selector = selector.selector; - this.context = selector.context; - } - - return jQuery.makeArray( selector, this ); - }; - -// Give the init function the jQuery prototype for later instantiation -init.prototype = jQuery.fn; - -// Initialize central reference -rootjQuery = jQuery( document ); -var rnotwhite = (/\S+/g); - - - -// String to Object options format cache -var optionsCache = {}; - -// Convert String-formatted options into Object-formatted ones and store in cache -function createOptions( options ) { - var object = optionsCache[ options ] = {}; - jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { - object[ flag ] = true; - }); - return object; -} - -/* - * Create a callback list using the following parameters: - * - * options: an optional list of space-separated options that will change how - * the callback list behaves or a more traditional option object - * - * By default a callback list will act like an event callback list and can be - * "fired" multiple times. - * - * Possible options: - * - * once: will ensure the callback list can only be fired once (like a Deferred) - * - * memory: will keep track of previous values and will call any callback added - * after the list has been fired right away with the latest "memorized" - * values (like a Deferred) - * - * unique: will ensure a callback can only be added once (no duplicate in the list) - * - * stopOnFalse: interrupt callings when a callback returns false - * - */ -jQuery.Callbacks = function( options ) { - - // Convert options from String-formatted to Object-formatted if needed - // (we check in cache first) - options = typeof options === "string" ? - ( optionsCache[ options ] || createOptions( options ) ) : - jQuery.extend( {}, options ); - - var // Last fire value (for non-forgettable lists) - memory, - // Flag to know if list was already fired - fired, - // Flag to know if list is currently firing - firing, - // First callback to fire (used internally by add and fireWith) - firingStart, - // End of the loop when firing - firingLength, - // Index of currently firing callback (modified by remove if needed) - firingIndex, - // Actual callback list - list = [], - // Stack of fire calls for repeatable lists - stack = !options.once && [], - // Fire callbacks - fire = function( data ) { - memory = options.memory && data; - fired = true; - firingIndex = firingStart || 0; - firingStart = 0; - firingLength = list.length; - firing = true; - for ( ; list && firingIndex < firingLength; firingIndex++ ) { - if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { - memory = false; // To prevent further calls using add - break; - } - } - firing = false; - if ( list ) { - if ( stack ) { - if ( stack.length ) { - fire( stack.shift() ); - } - } else if ( memory ) { - list = []; - } else { - self.disable(); - } - } - }, - // Actual Callbacks object - self = { - // Add a callback or a collection of callbacks to the list - add: function() { - if ( list ) { - // First, we save the current length - var start = list.length; - (function add( args ) { - jQuery.each( args, function( _, arg ) { - var type = jQuery.type( arg ); - if ( type === "function" ) { - if ( !options.unique || !self.has( arg ) ) { - list.push( arg ); - } - } else if ( arg && arg.length && type !== "string" ) { - // Inspect recursively - add( arg ); - } - }); - })( arguments ); - // Do we need to add the callbacks to the - // current firing batch? - if ( firing ) { - firingLength = list.length; - // With memory, if we're not firing then - // we should call right away - } else if ( memory ) { - firingStart = start; - fire( memory ); - } - } - return this; - }, - // Remove a callback from the list - remove: function() { - if ( list ) { - jQuery.each( arguments, function( _, arg ) { - var index; - while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { - list.splice( index, 1 ); - // Handle firing indexes - if ( firing ) { - if ( index <= firingLength ) { - firingLength--; - } - if ( index <= firingIndex ) { - firingIndex--; - } - } - } - }); - } - return this; - }, - // Check if a given callback is in the list. - // If no argument is given, return whether or not list has callbacks attached. - has: function( fn ) { - return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); - }, - // Remove all callbacks from the list - empty: function() { - list = []; - firingLength = 0; - return this; - }, - // Have the list do nothing anymore - disable: function() { - list = stack = memory = undefined; - return this; - }, - // Is it disabled? - disabled: function() { - return !list; - }, - // Lock the list in its current state - lock: function() { - stack = undefined; - if ( !memory ) { - self.disable(); - } - return this; - }, - // Is it locked? - locked: function() { - return !stack; - }, - // Call all callbacks with the given context and arguments - fireWith: function( context, args ) { - if ( list && ( !fired || stack ) ) { - args = args || []; - args = [ context, args.slice ? args.slice() : args ]; - if ( firing ) { - stack.push( args ); - } else { - fire( args ); - } - } - return this; - }, - // Call all the callbacks with the given arguments - fire: function() { - self.fireWith( this, arguments ); - return this; - }, - // To know if the callbacks have already been called at least once - fired: function() { - return !!fired; - } - }; - - return self; -}; - - -jQuery.extend({ - - Deferred: function( func ) { - var tuples = [ - // action, add listener, listener list, final state - [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], - [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], - [ "notify", "progress", jQuery.Callbacks("memory") ] - ], - state = "pending", - promise = { - state: function() { - return state; - }, - always: function() { - deferred.done( arguments ).fail( arguments ); - return this; - }, - then: function( /* fnDone, fnFail, fnProgress */ ) { - var fns = arguments; - return jQuery.Deferred(function( newDefer ) { - jQuery.each( tuples, function( i, tuple ) { - var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; - // deferred[ done | fail | progress ] for forwarding actions to newDefer - deferred[ tuple[1] ](function() { - var returned = fn && fn.apply( this, arguments ); - if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise() - .done( newDefer.resolve ) - .fail( newDefer.reject ) - .progress( newDefer.notify ); - } else { - newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); - } - }); - }); - fns = null; - }).promise(); - }, - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - return obj != null ? jQuery.extend( obj, promise ) : promise; - } - }, - deferred = {}; - - // Keep pipe for back-compat - promise.pipe = promise.then; - - // Add list-specific methods - jQuery.each( tuples, function( i, tuple ) { - var list = tuple[ 2 ], - stateString = tuple[ 3 ]; - - // promise[ done | fail | progress ] = list.add - promise[ tuple[1] ] = list.add; - - // Handle state - if ( stateString ) { - list.add(function() { - // state = [ resolved | rejected ] - state = stateString; - - // [ reject_list | resolve_list ].disable; progress_list.lock - }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); - } - - // deferred[ resolve | reject | notify ] - deferred[ tuple[0] ] = function() { - deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); - return this; - }; - deferred[ tuple[0] + "With" ] = list.fireWith; - }); - - // Make the deferred a promise - promise.promise( deferred ); - - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - - // All done! - return deferred; - }, - - // Deferred helper - when: function( subordinate /* , ..., subordinateN */ ) { - var i = 0, - resolveValues = slice.call( arguments ), - length = resolveValues.length, - - // the count of uncompleted subordinates - remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, - - // the master Deferred. If resolveValues consist of only a single Deferred, just use that. - deferred = remaining === 1 ? subordinate : jQuery.Deferred(), - - // Update function for both resolve and progress values - updateFunc = function( i, contexts, values ) { - return function( value ) { - contexts[ i ] = this; - values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; - if ( values === progressValues ) { - deferred.notifyWith( contexts, values ); - } else if ( !( --remaining ) ) { - deferred.resolveWith( contexts, values ); - } - }; - }, - - progressValues, progressContexts, resolveContexts; - - // add listeners to Deferred subordinates; treat others as resolved - if ( length > 1 ) { - progressValues = new Array( length ); - progressContexts = new Array( length ); - resolveContexts = new Array( length ); - for ( ; i < length; i++ ) { - if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { - resolveValues[ i ].promise() - .done( updateFunc( i, resolveContexts, resolveValues ) ) - .fail( deferred.reject ) - .progress( updateFunc( i, progressContexts, progressValues ) ); - } else { - --remaining; - } - } - } - - // if we're not waiting on anything, resolve the master - if ( !remaining ) { - deferred.resolveWith( resolveContexts, resolveValues ); - } - - return deferred.promise(); - } -}); - - -// The deferred used on DOM ready -var readyList; - -jQuery.fn.ready = function( fn ) { - // Add the callback - jQuery.ready.promise().done( fn ); - - return this; -}; - -jQuery.extend({ - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // A counter to track how many items to wait for before - // 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 ) { - - // Abort if there are pending holds or we're already ready - if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { - return; - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if ( wait !== true && --jQuery.readyWait > 0 ) { - return; - } - - // If there are functions bound, to execute - readyList.resolveWith( document, [ jQuery ] ); - - // Trigger any bound ready events - if ( jQuery.fn.triggerHandler ) { - jQuery( document ).triggerHandler( "ready" ); - jQuery( document ).off( "ready" ); - } - } -}); - -/** - * The ready event handler and self cleanup method - */ -function completed() { - document.removeEventListener( "DOMContentLoaded", completed, false ); - window.removeEventListener( "load", completed, false ); - jQuery.ready(); -} - -jQuery.ready.promise = function( obj ) { - if ( !readyList ) { - - readyList = jQuery.Deferred(); - - // Catch cases where $(document).ready() is called after the browser event has already occurred. - // we once tried to use readyState "interactive" here, but it caused issues like the one - // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 - if ( document.readyState === "complete" ) { - // Handle it asynchronously to allow scripts the opportunity to delay ready - setTimeout( jQuery.ready ); - - } else { - - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", completed, false ); - - // A fallback to window.onload, that will always work - window.addEventListener( "load", completed, false ); - } - } - return readyList.promise( obj ); -}; - -// Kick off the DOM ready check even if the user does not -jQuery.ready.promise(); - - - - -// Multifunctional method to get and set values of a collection -// The value/s can optionally be executed if it's a function -var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { - var i = 0, - len = elems.length, - bulk = key == null; - - // Sets many values - if ( jQuery.type( key ) === "object" ) { - chainable = true; - for ( i in key ) { - jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); - } - - // Sets one value - } else if ( value !== undefined ) { - chainable = true; - - if ( !jQuery.isFunction( value ) ) { - raw = true; - } - - if ( bulk ) { - // Bulk operations run against the entire set - if ( raw ) { - fn.call( elems, value ); - fn = null; - - // ...except when executing function values - } else { - bulk = fn; - fn = function( elem, key, value ) { - return bulk.call( jQuery( elem ), value ); - }; - } - } - - if ( fn ) { - for ( ; i < len; i++ ) { - fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); - } - } - } - - return chainable ? - elems : - - // Gets - bulk ? - fn.call( elems ) : - len ? fn( elems[0], key ) : emptyGet; -}; - - -/** - * Determines whether an object can have data - */ -jQuery.acceptData = function( owner ) { - // Accepts only: - // - Node - // - Node.ELEMENT_NODE - // - Node.DOCUMENT_NODE - // - Object - // - Any - /* jshint -W018 */ - return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); -}; - - -function Data() { - // Support: Android < 4, - // Old WebKit does not have Object.preventExtensions/freeze method, - // return new empty object instead with no [[set]] accessor - Object.defineProperty( this.cache = {}, 0, { - get: function() { - return {}; - } - }); - - this.expando = jQuery.expando + Math.random(); -} - -Data.uid = 1; -Data.accepts = jQuery.acceptData; - -Data.prototype = { - key: function( owner ) { - // We can accept data for non-element nodes in modern browsers, - // but we should not, see #8335. - // Always return the key for a frozen object. - if ( !Data.accepts( owner ) ) { - return 0; - } - - var descriptor = {}, - // Check if the owner object already has a cache key - unlock = owner[ this.expando ]; - - // If not, create one - if ( !unlock ) { - unlock = Data.uid++; - - // Secure it in a non-enumerable, non-writable property - try { - descriptor[ this.expando ] = { value: unlock }; - Object.defineProperties( owner, descriptor ); - - // Support: Android < 4 - // Fallback to a less secure definition - } catch ( e ) { - descriptor[ this.expando ] = unlock; - jQuery.extend( owner, descriptor ); - } - } - - // Ensure the cache object - if ( !this.cache[ unlock ] ) { - this.cache[ unlock ] = {}; - } - - return unlock; - }, - set: function( owner, data, value ) { - var prop, - // There may be an unlock assigned to this node, - // if there is no entry for this "owner", create one inline - // and set the unlock as though an owner entry had always existed - unlock = this.key( owner ), - cache = this.cache[ unlock ]; - - // Handle: [ owner, key, value ] args - if ( typeof data === "string" ) { - cache[ data ] = value; - - // Handle: [ owner, { properties } ] args - } else { - // Fresh assignments by object are shallow copied - if ( jQuery.isEmptyObject( cache ) ) { - jQuery.extend( this.cache[ unlock ], data ); - // Otherwise, copy the properties one-by-one to the cache object - } else { - for ( prop in data ) { - cache[ prop ] = data[ prop ]; - } - } - } - return cache; - }, - get: function( owner, key ) { - // Either a valid cache is found, or will be created. - // New caches will be created and the unlock returned, - // allowing direct access to the newly created - // empty data object. A valid owner object must be provided. - var cache = this.cache[ this.key( owner ) ]; - - return key === undefined ? - cache : cache[ key ]; - }, - access: function( owner, key, value ) { - var stored; - // In cases where either: - // - // 1. No key was specified - // 2. A string key was specified, but no value provided - // - // Take the "read" path and allow the get method to determine - // which value to return, respectively either: - // - // 1. The entire cache object - // 2. The data stored at the key - // - if ( key === undefined || - ((key && typeof key === "string") && value === undefined) ) { - - stored = this.get( owner, key ); - - return stored !== undefined ? - stored : this.get( owner, jQuery.camelCase(key) ); - } - - // [*]When the key is not a string, or both a key and value - // are specified, set or extend (existing objects) with either: - // - // 1. An object of properties - // 2. A key and value - // - this.set( owner, key, value ); - - // Since the "set" path can have two possible entry points - // return the expected data based on which path was taken[*] - return value !== undefined ? value : key; - }, - remove: function( owner, key ) { - var i, name, camel, - unlock = this.key( owner ), - cache = this.cache[ unlock ]; - - if ( key === undefined ) { - this.cache[ unlock ] = {}; - - } else { - // Support array or space separated string of keys - if ( jQuery.isArray( key ) ) { - // If "name" is an array of keys... - // When data is initially created, via ("key", "val") signature, - // keys will be converted to camelCase. - // Since there is no way to tell _how_ a key was added, remove - // both plain key and camelCase key. #12786 - // This will only penalize the array argument path. - name = key.concat( key.map( jQuery.camelCase ) ); - } else { - camel = jQuery.camelCase( key ); - // Try the string as a key before any manipulation - if ( key in cache ) { - name = [ key, camel ]; - } else { - // If a key with the spaces exists, use it. - // Otherwise, create an array by matching non-whitespace - name = camel; - name = name in cache ? - [ name ] : ( name.match( rnotwhite ) || [] ); - } - } - - i = name.length; - while ( i-- ) { - delete cache[ name[ i ] ]; - } - } - }, - hasData: function( owner ) { - return !jQuery.isEmptyObject( - this.cache[ owner[ this.expando ] ] || {} - ); - }, - discard: function( owner ) { - if ( owner[ this.expando ] ) { - delete this.cache[ owner[ this.expando ] ]; - } - } -}; -var data_priv = new Data(); - - - -/* - Implementation Summary - - 1. Enforce API surface and semantic compatibility with 1.9.x branch - 2. Improve the module's maintainability by reducing the storage - paths to a single mechanism. - 3. Use the same single mechanism to support "private" and "user" data. - 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) - 5. Avoid exposing implementation details on user objects (eg. expando properties) - 6. Provide a clear path for implementation upgrade to WeakMap in 2014 -*/ -var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, - rmultiDash = /([A-Z])/g; - -function dataAttr( elem, key, data ) { - var name; - - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if ( data === undefined && elem.nodeType === 1 ) { - name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); - data = elem.getAttribute( name ); - - if ( typeof data === "string" ) { - try { - data = data === "true" ? true : - data === "false" ? false : - data === "null" ? null : - // Only convert to a number if it doesn't change the string - +data + "" === data ? +data : - rbrace.test( data ) ? jQuery.parseJSON( data ) : - data; - } catch( e ) {} - - // Make sure we set the data so it isn't changed later - data_user.set( elem, key, data ); - } else { - data = undefined; - } - } - return data; -} - -jQuery.extend({ - hasData: function( elem ) { - return data_user.hasData( elem ) || data_priv.hasData( elem ); - }, - - data: function( elem, name, data ) { - return data_user.access( elem, name, data ); - }, - - removeData: function( elem, name ) { - data_user.remove( elem, name ); - }, - - // TODO: Now that all calls to _data and _removeData have been replaced - // with direct calls to data_priv methods, these can be deprecated. - _data: function( elem, name, data ) { - return data_priv.access( elem, name, data ); - }, - - _removeData: function( elem, name ) { - data_priv.remove( elem, name ); - } -}); - -jQuery.fn.extend({ - data: function( key, value ) { - var i, name, data, - elem = this[ 0 ], - attrs = elem && elem.attributes; - - // Gets all values - if ( key === undefined ) { - if ( this.length ) { - data = data_user.get( elem ); - - if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) { - i = attrs.length; - while ( i-- ) { - - // Support: IE11+ - // The attrs elements can be null (#14894) - if ( attrs[ i ] ) { - name = attrs[ i ].name; - if ( name.indexOf( "data-" ) === 0 ) { - name = jQuery.camelCase( name.slice(5) ); - dataAttr( elem, name, data[ name ] ); - } - } - } - data_priv.set( elem, "hasDataAttrs", true ); - } - } - - return data; - } - - // Sets multiple values - if ( typeof key === "object" ) { - return this.each(function() { - data_user.set( this, key ); - }); - } - - return access( this, function( value ) { - var data, - camelKey = jQuery.camelCase( key ); - - // The calling jQuery object (element matches) is not empty - // (and therefore has an element appears at this[ 0 ]) and the - // `value` parameter was not undefined. An empty jQuery object - // will result in `undefined` for elem = this[ 0 ] which will - // throw an exception if an attempt to read a data cache is made. - if ( elem && value === undefined ) { - // Attempt to get data from the cache - // with the key as-is - data = data_user.get( elem, key ); - if ( data !== undefined ) { - return data; - } - - // Attempt to get data from the cache - // with the key camelized - data = data_user.get( elem, camelKey ); - if ( data !== undefined ) { - return data; - } - - // Attempt to "discover" the data in - // HTML5 custom data-* attrs - data = dataAttr( elem, camelKey, undefined ); - if ( data !== undefined ) { - return data; - } - - // We tried really hard, but the data doesn't exist. - return; - } - - // Set the data... - this.each(function() { - // First, attempt to store a copy or reference of any - // data that might've been store with a camelCased key. - var data = data_user.get( this, camelKey ); - - // For HTML5 data-* attribute interop, we have to - // store property names with dashes in a camelCase form. - // This might not apply to all properties...* - data_user.set( this, camelKey, value ); - - // *... In the case of properties that might _actually_ - // have dashes, we need to also store a copy of that - // unchanged property. - if ( key.indexOf("-") !== -1 && data !== undefined ) { - data_user.set( this, key, value ); - } - }); - }, null, value, arguments.length > 1, null, true ); - }, - - removeData: function( key ) { - return this.each(function() { - data_user.remove( this, key ); - }); - } -}); -var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; - -var strundefined = typeof undefined; - - - -var - rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, - rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; - -function returnTrue() { - return true; -} - -function returnFalse() { - return false; -} - -function safeActiveElement() { - try { - return document.activeElement; - } catch ( err ) { } -} - -/* - * Helper functions for managing events -- not part of the public interface. - * Props to Dean Edwards' addEvent library for many of the ideas. - */ -jQuery.event = { - - global: {}, - - add: function( elem, types, handler, data, selector ) { - - var handleObjIn, eventHandle, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = data_priv.get( elem ); - - // Don't attach events to noData or text/comment nodes (but allow plain objects) - if ( !elemData ) { - return; - } - - // Caller can pass in an object of custom data in lieu of the handler - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - selector = handleObjIn.selector; - } - - // Make sure that the handler has a unique ID, used to find/remove it later - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure and main handler, if this is the first - if ( !(events = elemData.events) ) { - events = elemData.events = {}; - } - if ( !(eventHandle = elemData.handle) ) { - eventHandle = elemData.handle = 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 !== strundefined && jQuery.event.triggered !== e.type ? - jQuery.event.dispatch.apply( elem, arguments ) : undefined; - }; - } - - // Handle multiple events separated by a space - types = ( types || "" ).match( rnotwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[t] ) || []; - type = origType = tmp[1]; - namespaces = ( tmp[2] || "" ).split( "." ).sort(); - - // There *must* be a type, no attaching namespace-only handlers - if ( !type ) { - continue; - } - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[ type ] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = ( selector ? special.delegateType : special.bindType ) || type; - - // Update special based on newly reset type - special = jQuery.event.special[ type ] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend({ - type: type, - origType: origType, - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - needsContext: selector && jQuery.expr.match.needsContext.test( selector ), - namespace: namespaces.join(".") - }, handleObjIn ); - - // Init the event handler queue if we're the first - if ( !(handlers = events[ type ]) ) { - handlers = events[ type ] = []; - handlers.delegateCount = 0; - - // Only use addEventListener if the special events handler returns false - if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle, false ); - } - } - } - - if ( special.add ) { - special.add.call( elem, handleObj ); - - if ( !handleObj.handler.guid ) { - handleObj.handler.guid = handler.guid; - } - } - - // Add to the element's handler list, delegates in front - if ( selector ) { - handlers.splice( handlers.delegateCount++, 0, handleObj ); - } else { - handlers.push( handleObj ); - } - - // Keep track of which events have ever been used, for event optimization - jQuery.event.global[ type ] = true; - } - - }, - - // Detach an event or set of events from an element - remove: function( elem, types, handler, selector, mappedTypes ) { - - var j, origCount, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = data_priv.hasData( elem ) && data_priv.get( elem ); - - if ( !elemData || !(events = elemData.events) ) { - return; - } - - // Once for each type.namespace in types; type may be omitted - types = ( types || "" ).match( rnotwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[t] ) || []; - type = origType = tmp[1]; - namespaces = ( tmp[2] || "" ).split( "." ).sort(); - - // Unbind all events (on this namespace, if provided) for the element - if ( !type ) { - for ( type in events ) { - jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); - } - continue; - } - - special = jQuery.event.special[ type ] || {}; - type = ( selector ? special.delegateType : special.bindType ) || type; - handlers = events[ type ] || []; - tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); - - // Remove matching events - origCount = j = handlers.length; - while ( j-- ) { - handleObj = handlers[ j ]; - - if ( ( mappedTypes || origType === handleObj.origType ) && - ( !handler || handler.guid === handleObj.guid ) && - ( !tmp || tmp.test( handleObj.namespace ) ) && - ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { - handlers.splice( j, 1 ); - - if ( handleObj.selector ) { - handlers.delegateCount--; - } - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - } - - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if ( origCount && !handlers.length ) { - if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { - jQuery.removeEvent( elem, type, elemData.handle ); - } - - delete events[ type ]; - } - } - - // Remove the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - delete elemData.handle; - data_priv.remove( elem, "events" ); - } - }, - - trigger: function( event, data, elem, onlyHandlers ) { - - var i, cur, tmp, bubbleType, ontype, handle, special, - eventPath = [ elem || document ], - type = hasOwn.call( event, "type" ) ? event.type : event, - namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; - - cur = tmp = elem = elem || document; - - // Don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { - return; - } - - if ( type.indexOf(".") >= 0 ) { - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split("."); - type = namespaces.shift(); - namespaces.sort(); - } - ontype = type.indexOf(":") < 0 && "on" + type; - - // Caller can pass in a jQuery.Event object, Object, or just an event type string - event = event[ jQuery.expando ] ? - event : - new jQuery.Event( type, typeof event === "object" && event ); - - // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) - event.isTrigger = onlyHandlers ? 2 : 3; - event.namespace = namespaces.join("."); - event.namespace_re = event.namespace ? - new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : - null; - - // Clean up the event in case it is being reused - event.result = undefined; - if ( !event.target ) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data == null ? - [ event ] : - jQuery.makeArray( data, [ event ] ); - - // Allow special events to draw outside the lines - special = jQuery.event.special[ type ] || {}; - if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (#9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { - - bubbleType = special.delegateType || type; - if ( !rfocusMorph.test( bubbleType + type ) ) { - cur = cur.parentNode; - } - for ( ; cur; cur = cur.parentNode ) { - eventPath.push( cur ); - tmp = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( tmp === (elem.ownerDocument || document) ) { - eventPath.push( tmp.defaultView || tmp.parentWindow || window ); - } - } - - // Fire handlers on the event path - i = 0; - while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { - - event.type = i > 1 ? - bubbleType : - special.bindType || type; - - // jQuery handler - handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" ); - if ( handle ) { - handle.apply( cur, data ); - } - - // Native handler - handle = ontype && cur[ ontype ]; - if ( handle && handle.apply && jQuery.acceptData( cur ) ) { - event.result = handle.apply( cur, data ); - if ( event.result === false ) { - event.preventDefault(); - } - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if ( !onlyHandlers && !event.isDefaultPrevented() ) { - - if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && - jQuery.acceptData( elem ) ) { - - // Call a native DOM method on the target with the same name name as the event. - // Don't do default actions on window, that's where global variables be (#6170) - if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { - - // Don't re-trigger an onFOO event when we call its FOO() method - tmp = elem[ ontype ]; - - if ( tmp ) { - elem[ ontype ] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - elem[ type ](); - jQuery.event.triggered = undefined; - - if ( tmp ) { - elem[ ontype ] = tmp; - } - } - } - } - - return event.result; - }, - - dispatch: function( event ) { - - // Make a writable jQuery.Event from the native event object - event = jQuery.event.fix( event ); - - var i, j, ret, matched, handleObj, - handlerQueue = [], - args = slice.call( arguments ), - handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [], - special = jQuery.event.special[ event.type ] || {}; - - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[0] = event; - event.delegateTarget = this; - - // Call the preDispatch hook for the mapped type, and let it bail if desired - if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { - return; - } - - // Determine handlers - handlerQueue = jQuery.event.handlers.call( this, event, handlers ); - - // Run delegates first; they may want to stop propagation beneath us - i = 0; - while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { - event.currentTarget = matched.elem; - - j = 0; - while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { - - // Triggered event must either 1) have no namespace, or - // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). - if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { - - event.handleObj = handleObj; - event.data = handleObj.data; - - ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) - .apply( matched.elem, args ); - - if ( ret !== undefined ) { - if ( (event.result = ret) === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - // Call the postDispatch hook for the mapped type - if ( special.postDispatch ) { - special.postDispatch.call( this, event ); - } - - return event.result; - }, - - handlers: function( event, handlers ) { - var i, matches, sel, handleObj, - handlerQueue = [], - delegateCount = handlers.delegateCount, - cur = event.target; - - // Find delegate handlers - // Black-hole SVG instance trees (#13180) - // Avoid non-left-click bubbling in Firefox (#3861) - if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { - - for ( ; cur !== this; cur = cur.parentNode || this ) { - - // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) - if ( cur.disabled !== true || event.type !== "click" ) { - matches = []; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - - // Don't conflict with Object.prototype properties (#13203) - sel = handleObj.selector + " "; - - if ( matches[ sel ] === undefined ) { - matches[ sel ] = handleObj.needsContext ? - jQuery( sel, this ).index( cur ) >= 0 : - jQuery.find( sel, this, null, [ cur ] ).length; - } - if ( matches[ sel ] ) { - matches.push( handleObj ); - } - } - if ( matches.length ) { - handlerQueue.push({ elem: cur, handlers: matches }); - } - } - } - } - - // Add the remaining (directly-bound) handlers - if ( delegateCount < handlers.length ) { - handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); - } - - return handlerQueue; - }, - - // Includes some event props shared by KeyEvent and MouseEvent - props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), - - fixHooks: {}, - - keyHooks: { - props: "char charCode key keyCode".split(" "), - filter: function( event, original ) { - - // Add which for key events - if ( event.which == null ) { - event.which = original.charCode != null ? original.charCode : original.keyCode; - } - - return event; - } - }, - - mouseHooks: { - props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "), - filter: function( event, original ) { - var eventDoc, doc, body, - button = original.button; - - // Calculate pageX/Y if missing and clientX/Y available - if ( event.pageX == null && original.clientX != null ) { - eventDoc = event.target.ownerDocument || document; - doc = eventDoc.documentElement; - body = eventDoc.body; - - event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); - event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - // Note: button is not normalized, so don't use it - if ( !event.which && button !== undefined ) { - event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); - } - - return event; - } - }, - - fix: function( event ) { - if ( event[ jQuery.expando ] ) { - return event; - } - - // Create a writable copy of the event object and normalize some properties - var i, prop, copy, - type = event.type, - originalEvent = event, - fixHook = this.fixHooks[ type ]; - - if ( !fixHook ) { - this.fixHooks[ type ] = fixHook = - rmouseEvent.test( type ) ? this.mouseHooks : - rkeyEvent.test( type ) ? this.keyHooks : - {}; - } - copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; - - event = new jQuery.Event( originalEvent ); - - i = copy.length; - while ( i-- ) { - prop = copy[ i ]; - event[ prop ] = originalEvent[ prop ]; - } - - // Support: Cordova 2.5 (WebKit) (#13255) - // All events should have a target; Cordova deviceready doesn't - if ( !event.target ) { - event.target = document; - } - - // Support: Safari 6.0+, Chrome < 28 - // Target should not be a text node (#504, #13143) - if ( event.target.nodeType === 3 ) { - event.target = event.target.parentNode; - } - - return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; - }, - - special: { - load: { - // Prevent triggered image.load events from bubbling to window.load - noBubble: true - }, - focus: { - // Fire native event if possible so blur/focus sequence is correct - trigger: function() { - if ( this !== safeActiveElement() && this.focus ) { - this.focus(); - return false; - } - }, - delegateType: "focusin" - }, - blur: { - trigger: function() { - if ( this === safeActiveElement() && this.blur ) { - this.blur(); - return false; - } - }, - delegateType: "focusout" - }, - click: { - // For checkbox, fire native event so checked state will be right - trigger: function() { - if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { - this.click(); - return false; - } - }, - - // For cross-browser consistency, don't fire native .click() on links - _default: function( event ) { - return jQuery.nodeName( event.target, "a" ); - } - }, - - beforeunload: { - postDispatch: function( event ) { - - // Support: Firefox 20+ - // Firefox doesn't alert if the returnValue field is not set. - if ( event.result !== undefined && event.originalEvent ) { - event.originalEvent.returnValue = event.result; - } - } - } - }, - - simulate: function( type, elem, event, bubble ) { - // Piggyback on a donor event to simulate a different one. - // Fake originalEvent to avoid donor's stopPropagation, but if the - // simulated event prevents default then we do the same on the donor. - var e = jQuery.extend( - new jQuery.Event(), - event, - { - type: type, - isSimulated: true, - originalEvent: {} - } - ); - if ( bubble ) { - jQuery.event.trigger( e, null, elem ); - } else { - jQuery.event.dispatch.call( elem, e ); - } - if ( e.isDefaultPrevented() ) { - event.preventDefault(); - } - } -}; - -jQuery.removeEvent = function( elem, type, handle ) { - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle, false ); - } -}; - -jQuery.Event = function( src, props ) { - // Allow instantiation without the 'new' keyword - if ( !(this instanceof jQuery.Event) ) { - return new jQuery.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = src.defaultPrevented || - src.defaultPrevented === undefined && - // Support: Android < 4.0 - src.returnValue === false ? - returnTrue : - returnFalse; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - jQuery.extend( this, props ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || jQuery.now(); - - // Mark it as fixed - this[ jQuery.expando ] = true; -}; - -// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -jQuery.Event.prototype = { - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse, - - preventDefault: function() { - var e = this.originalEvent; - - this.isDefaultPrevented = returnTrue; - - if ( e && e.preventDefault ) { - e.preventDefault(); - } - }, - stopPropagation: function() { - var e = this.originalEvent; - - this.isPropagationStopped = returnTrue; - - if ( e && e.stopPropagation ) { - e.stopPropagation(); - } - }, - stopImmediatePropagation: function() { - var e = this.originalEvent; - - this.isImmediatePropagationStopped = returnTrue; - - if ( e && e.stopImmediatePropagation ) { - e.stopImmediatePropagation(); - } - - this.stopPropagation(); - } -}; - -// Create mouseenter/leave events using mouseover/out and event-time checks -// Support: Chrome 15+ -jQuery.each({ - mouseenter: "mouseover", - mouseleave: "mouseout", - pointerenter: "pointerover", - pointerleave: "pointerout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - delegateType: fix, - bindType: fix, - - handle: function( event ) { - var ret, - target = this, - related = event.relatedTarget, - handleObj = event.handleObj; - - // For mousenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || (related !== target && !jQuery.contains( target, related )) ) { - event.type = handleObj.origType; - ret = handleObj.handler.apply( this, arguments ); - event.type = fix; - } - return ret; - } - }; -}); - -// Create "bubbling" focus and blur events -// Support: Firefox, Chrome, Safari -if ( !support.focusinBubbles ) { - jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { - - // Attach a single capturing handler on the document while someone wants focusin/focusout - var handler = function( event ) { - jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); - }; - - jQuery.event.special[ fix ] = { - setup: function() { - var doc = this.ownerDocument || this, - attaches = data_priv.access( doc, fix ); - - if ( !attaches ) { - doc.addEventListener( orig, handler, true ); - } - data_priv.access( doc, fix, ( attaches || 0 ) + 1 ); - }, - teardown: function() { - var doc = this.ownerDocument || this, - attaches = data_priv.access( doc, fix ) - 1; - - if ( !attaches ) { - doc.removeEventListener( orig, handler, true ); - data_priv.remove( doc, fix ); - - } else { - data_priv.access( doc, fix, attaches ); - } - } - }; - }); -} - -jQuery.fn.extend({ - - on: function( types, selector, data, fn, /*INTERNAL*/ one ) { - var origFn, type; - - // Types can be a map of types/handlers - if ( typeof types === "object" ) { - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { - // ( types-Object, data ) - data = data || selector; - selector = undefined; - } - for ( type in types ) { - this.on( type, selector, data, types[ type ], one ); - } - return this; - } - - if ( data == null && fn == null ) { - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return this; - } - - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return this.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - }); - }, - one: function( types, selector, data, fn ) { - return this.on( types, selector, data, fn, 1 ); - }, - off: function( types, selector, fn ) { - var handleObj, type; - if ( types && types.preventDefault && types.handleObj ) { - // ( event ) dispatched jQuery.Event - handleObj = types.handleObj; - jQuery( types.delegateTarget ).off( - handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, - handleObj.selector, - handleObj.handler - ); - return this; - } - if ( typeof types === "object" ) { - // ( types-object [, selector] ) - for ( type in types ) { - this.off( type, selector, types[ type ] ); - } - return this; - } - if ( selector === false || typeof selector === "function" ) { - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if ( fn === false ) { - fn = returnFalse; - } - return this.each(function() { - jQuery.event.remove( this, types, fn, selector ); - }); - }, - - trigger: function( type, data ) { - return this.each(function() { - jQuery.event.trigger( type, data, this ); - }); - }, - triggerHandler: function( type, data ) { - var elem = this[0]; - if ( elem ) { - return jQuery.event.trigger( type, data, elem, true ); - } - } -}); -var nonce = jQuery.now(); - -var rquery = (/\?/); - - - -// Support: Android 2.3 -// Workaround failure to string-cast null input -jQuery.parseJSON = function( data ) { - return JSON.parse( data + "" ); -}; - - -// Cross-browser xml parsing -jQuery.parseXML = function( data ) { - var xml, tmp; - if ( !data || typeof data !== "string" ) { - return null; - } - - // Support: IE9 - try { - tmp = new DOMParser(); - xml = tmp.parseFromString( data, "text/xml" ); - } catch ( e ) { - xml = undefined; - } - - if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { - jQuery.error( "Invalid XML: " + data ); - } - return xml; -}; - - -var - // Document location - ajaxLocParts, - ajaxLocation, - - rhash = /#.*$/, - rts = /([?&])_=[^&]*/, - rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, - // #7653, #8125, #8152: local protocol detection - rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, - rnoContent = /^(?:GET|HEAD)$/, - rprotocol = /^\/\//, - rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/, - - /* Prefilters - * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) - * 2) These are called: - * - BEFORE asking for a transport - * - AFTER param serialization (s.data is a string if s.processData is true) - * 3) key is the dataType - * 4) the catchall symbol "*" can be used - * 5) execution will start with transport dataType and THEN continue down to "*" if needed - */ - prefilters = {}, - - /* Transports bindings - * 1) key is the dataType - * 2) the catchall symbol "*" can be used - * 3) selection will start with transport dataType and THEN go to "*" if needed - */ - transports = {}, - - // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression - allTypes = "*/".concat("*"); - -// #8138, IE may throw an exception when accessing -// a field from window.location if document.domain has been set -try { - ajaxLocation = location.href; -} catch( e ) { - // Use the href attribute of an A element - // since IE will modify it given document.location - ajaxLocation = document.createElement( "a" ); - ajaxLocation.href = ""; - ajaxLocation = ajaxLocation.href; -} - -// Segment location into parts -ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; - -// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport -function addToPrefiltersOrTransports( structure ) { - - // dataTypeExpression is optional and defaults to "*" - return function( dataTypeExpression, func ) { - - if ( typeof dataTypeExpression !== "string" ) { - func = dataTypeExpression; - dataTypeExpression = "*"; - } - - var dataType, - i = 0, - dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || []; - - if ( jQuery.isFunction( func ) ) { - // For each dataType in the dataTypeExpression - while ( (dataType = dataTypes[i++]) ) { - // Prepend if requested - if ( dataType[0] === "+" ) { - dataType = dataType.slice( 1 ) || "*"; - (structure[ dataType ] = structure[ dataType ] || []).unshift( func ); - - // Otherwise append - } else { - (structure[ dataType ] = structure[ dataType ] || []).push( func ); - } - } - } - }; -} - -// Base inspection function for prefilters and transports -function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { - - var inspected = {}, - seekingTransport = ( structure === transports ); - - function inspect( dataType ) { - var selected; - inspected[ dataType ] = true; - jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { - var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); - if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) { - options.dataTypes.unshift( dataTypeOrTransport ); - inspect( dataTypeOrTransport ); - return false; - } else if ( seekingTransport ) { - return !( selected = dataTypeOrTransport ); - } - }); - return selected; - } - - return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); -} - -// A special extend for ajax options -// that takes "flat" options (not to be deep extended) -// Fixes #9887 -function ajaxExtend( target, src ) { - var key, deep, - flatOptions = jQuery.ajaxSettings.flatOptions || {}; - - for ( key in src ) { - if ( src[ key ] !== undefined ) { - ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ]; - } - } - if ( deep ) { - jQuery.extend( true, target, deep ); - } - - return target; -} - -/* Handles responses to an ajax request: - * - finds the right dataType (mediates between content-type and expected dataType) - * - returns the corresponding response - */ -function ajaxHandleResponses( s, jqXHR, responses ) { - - var ct, type, finalDataType, firstDataType, - contents = s.contents, - dataTypes = s.dataTypes; - - // Remove auto dataType and get content-type in the process - while ( dataTypes[ 0 ] === "*" ) { - dataTypes.shift(); - if ( ct === undefined ) { - ct = s.mimeType || jqXHR.getResponseHeader("Content-Type"); - } - } - - // Check if we're dealing with a known content-type - if ( ct ) { - for ( type in contents ) { - if ( contents[ type ] && contents[ type ].test( ct ) ) { - dataTypes.unshift( type ); - break; - } - } - } - - // Check to see if we have a response for the expected dataType - if ( dataTypes[ 0 ] in responses ) { - finalDataType = dataTypes[ 0 ]; - } else { - // Try convertible dataTypes - for ( type in responses ) { - if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { - finalDataType = type; - break; - } - if ( !firstDataType ) { - firstDataType = type; - } - } - // Or just use first one - finalDataType = finalDataType || firstDataType; - } - - // If we found a dataType - // We add the dataType to the list if needed - // and return the corresponding response - if ( finalDataType ) { - if ( finalDataType !== dataTypes[ 0 ] ) { - dataTypes.unshift( finalDataType ); - } - return responses[ finalDataType ]; - } -} - -/* Chain conversions given the request and the original response - * Also sets the responseXXX fields on the jqXHR instance - */ -function ajaxConvert( s, response, jqXHR, isSuccess ) { - var conv2, current, conv, tmp, prev, - converters = {}, - // Work with a copy of dataTypes in case we need to modify it for conversion - dataTypes = s.dataTypes.slice(); - - // Create converters map with lowercased keys - if ( dataTypes[ 1 ] ) { - for ( conv in s.converters ) { - converters[ conv.toLowerCase() ] = s.converters[ conv ]; - } - } - - current = dataTypes.shift(); - - // Convert to each sequential dataType - while ( current ) { - - if ( s.responseFields[ current ] ) { - jqXHR[ s.responseFields[ current ] ] = response; - } - - // Apply the dataFilter if provided - if ( !prev && isSuccess && s.dataFilter ) { - response = s.dataFilter( response, s.dataType ); - } - - prev = current; - current = dataTypes.shift(); - - if ( current ) { - - // There's only work to do if current dataType is non-auto - if ( current === "*" ) { - - current = prev; - - // Convert response if prev dataType is non-auto and differs from current - } else if ( prev !== "*" && prev !== current ) { - - // Seek a direct converter - conv = converters[ prev + " " + current ] || converters[ "* " + current ]; - - // If none found, seek a pair - if ( !conv ) { - for ( conv2 in converters ) { - - // If conv2 outputs current - tmp = conv2.split( " " ); - if ( tmp[ 1 ] === current ) { - - // If prev can be converted to accepted input - conv = converters[ prev + " " + tmp[ 0 ] ] || - converters[ "* " + tmp[ 0 ] ]; - if ( conv ) { - // Condense equivalence converters - if ( conv === true ) { - conv = converters[ conv2 ]; - - // Otherwise, insert the intermediate dataType - } else if ( converters[ conv2 ] !== true ) { - current = tmp[ 0 ]; - dataTypes.unshift( tmp[ 1 ] ); - } - break; - } - } - } - } - - // Apply converter (if not an equivalence) - if ( conv !== true ) { - - // Unless errors are allowed to bubble, catch and return them - if ( conv && s[ "throws" ] ) { - response = conv( response ); - } else { - try { - response = conv( response ); - } catch ( e ) { - return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; - } - } - } - } - } - } - - return { state: "success", data: response }; -} - -jQuery.extend({ - - // Counter for holding the number of active queries - active: 0, - - // Last-Modified header cache for next request - lastModified: {}, - etag: {}, - - ajaxSettings: { - url: ajaxLocation, - type: "GET", - isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), - global: true, - processData: true, - async: true, - contentType: "application/x-www-form-urlencoded; charset=UTF-8", - /* - timeout: 0, - data: null, - dataType: null, - username: null, - password: null, - cache: null, - throws: false, - traditional: false, - headers: {}, - */ - - accepts: { - "*": allTypes, - text: "text/plain", - html: "text/html", - xml: "application/xml, text/xml", - json: "application/json, text/javascript" - }, - - contents: { - xml: /xml/, - html: /html/, - json: /json/ - }, - - responseFields: { - xml: "responseXML", - text: "responseText", - json: "responseJSON" - }, - - // Data converters - // Keys separate source (or catchall "*") and destination types with a single space - converters: { - - // Convert anything to text - "* text": String, - - // Text to html (true = no transformation) - "text html": true, - - // Evaluate text as a json expression - "text json": jQuery.parseJSON, - - // Parse text as xml - "text xml": jQuery.parseXML - }, - - // For options that shouldn't be deep extended: - // you can add your own custom options here if - // and when you create one that shouldn't be - // deep extended (see ajaxExtend) - flatOptions: { - url: true, - context: true - } - }, - - // Creates a full fledged settings object into target - // with both ajaxSettings and settings fields. - // If target is omitted, writes into ajaxSettings. - ajaxSetup: function( target, settings ) { - return settings ? - - // Building a settings object - ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : - - // Extending ajaxSettings - ajaxExtend( jQuery.ajaxSettings, target ); - }, - - ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), - ajaxTransport: addToPrefiltersOrTransports( transports ), - - // Main method - ajax: function( url, options ) { - - // If url is an object, simulate pre-1.5 signature - if ( typeof url === "object" ) { - options = url; - url = undefined; - } - - // Force options to be an object - options = options || {}; - - var transport, - // URL without anti-cache param - cacheURL, - // Response headers - responseHeadersString, - responseHeaders, - // timeout handle - timeoutTimer, - // Cross-domain detection vars - parts, - // To know if global events are to be dispatched - fireGlobals, - // Loop variable - i, - // Create the final options object - s = jQuery.ajaxSetup( {}, options ), - // Callbacks context - callbackContext = s.context || s, - // Context for global events is callbackContext if it is a DOM node or jQuery collection - globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ? - jQuery( callbackContext ) : - jQuery.event, - // Deferreds - deferred = jQuery.Deferred(), - completeDeferred = jQuery.Callbacks("once memory"), - // Status-dependent callbacks - statusCode = s.statusCode || {}, - // Headers (they are sent all at once) - requestHeaders = {}, - requestHeadersNames = {}, - // The jqXHR state - state = 0, - // Default abort message - strAbort = "canceled", - // Fake xhr - jqXHR = { - readyState: 0, - - // Builds headers hashtable if needed - getResponseHeader: function( key ) { - var match; - if ( state === 2 ) { - if ( !responseHeaders ) { - responseHeaders = {}; - while ( (match = rheaders.exec( responseHeadersString )) ) { - responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; - } - } - match = responseHeaders[ key.toLowerCase() ]; - } - return match == null ? null : match; - }, - - // Raw string - getAllResponseHeaders: function() { - return state === 2 ? responseHeadersString : null; - }, - - // Caches the header - setRequestHeader: function( name, value ) { - var lname = name.toLowerCase(); - if ( !state ) { - name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; - requestHeaders[ name ] = value; - } - return this; - }, - - // Overrides response content-type header - overrideMimeType: function( type ) { - if ( !state ) { - s.mimeType = type; - } - return this; - }, - - // Status-dependent callbacks - statusCode: function( map ) { - var code; - if ( map ) { - if ( state < 2 ) { - for ( code in map ) { - // Lazy-add the new callback in a way that preserves old ones - statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; - } - } else { - // Execute the appropriate callbacks - jqXHR.always( map[ jqXHR.status ] ); - } - } - return this; - }, - - // Cancel the request - abort: function( statusText ) { - var finalText = statusText || strAbort; - if ( transport ) { - transport.abort( finalText ); - } - done( 0, finalText ); - return this; - } - }; - - // Attach deferreds - deferred.promise( jqXHR ).complete = completeDeferred.add; - jqXHR.success = jqXHR.done; - jqXHR.error = jqXHR.fail; - - // Remove hash character (#7531: and string promotion) - // Add protocol if not provided (prefilters might expect it) - // Handle falsy url in the settings object (#10093: consistency with old signature) - // We also use the url parameter if available - s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ) - .replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); - - // Alias method option to type as per ticket #12004 - s.type = options.method || options.type || s.method || s.type; - - // Extract dataTypes list - s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ]; - - // A cross-domain request is in order when we have a protocol:host:port mismatch - if ( s.crossDomain == null ) { - parts = rurl.exec( s.url.toLowerCase() ); - s.crossDomain = !!( parts && - ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] || - ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !== - ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) ) - ); - } - - // Convert data if not already a string - if ( s.data && s.processData && typeof s.data !== "string" ) { - s.data = jQuery.param( s.data, s.traditional ); - } - - // Apply prefilters - inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); - - // If request was aborted inside a prefilter, stop there - if ( state === 2 ) { - return jqXHR; - } - - // We can fire global events as of now if asked to - fireGlobals = s.global; - - // Watch for a new set of requests - if ( fireGlobals && jQuery.active++ === 0 ) { - jQuery.event.trigger("ajaxStart"); - } - - // Uppercase the type - s.type = s.type.toUpperCase(); - - // Determine if request has content - s.hasContent = !rnoContent.test( s.type ); - - // Save the URL in case we're toying with the If-Modified-Since - // and/or If-None-Match header later on - cacheURL = s.url; - - // More options handling for requests with no content - if ( !s.hasContent ) { - - // If data is available, append data to url - if ( s.data ) { - cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data ); - // #9682: remove data so that it's not used in an eventual retry - delete s.data; - } - - // Add anti-cache in url if needed - if ( s.cache === false ) { - s.url = rts.test( cacheURL ) ? - - // If there is already a '_' parameter, set its value - cacheURL.replace( rts, "$1_=" + nonce++ ) : - - // Otherwise add one to the end - cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++; - } - } - - // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. - if ( s.ifModified ) { - if ( jQuery.lastModified[ cacheURL ] ) { - jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); - } - if ( jQuery.etag[ cacheURL ] ) { - jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); - } - } - - // 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 ); - } - - // 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 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : - s.accepts[ "*" ] - ); - - // Check for headers option - for ( i in s.headers ) { - jqXHR.setRequestHeader( i, s.headers[ i ] ); - } - - // Allow custom headers/mimetypes and early abort - if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { - // Abort if not done already and return - return jqXHR.abort(); - } - - // aborting is no longer a cancellation - strAbort = "abort"; - - // Install callbacks on deferreds - for ( i in { success: 1, error: 1, complete: 1 } ) { - jqXHR[ i ]( s[ i ] ); - } - - // Get transport - transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); - - // If no transport, we auto-abort - if ( !transport ) { - done( -1, "No Transport" ); - } else { - jqXHR.readyState = 1; - - // Send global event - if ( fireGlobals ) { - globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); - } - // Timeout - if ( s.async && s.timeout > 0 ) { - timeoutTimer = setTimeout(function() { - jqXHR.abort("timeout"); - }, s.timeout ); - } - - try { - state = 1; - transport.send( requestHeaders, done ); - } catch ( e ) { - // Propagate exception as error if not done - if ( state < 2 ) { - done( -1, e ); - // Simply rethrow otherwise - } else { - throw e; - } - } - } - - // Callback for when everything is done - function done( status, nativeStatusText, responses, headers ) { - var isSuccess, success, error, response, modified, - statusText = nativeStatusText; - - // Called once - if ( state === 2 ) { - return; - } - - // State is "done" now - state = 2; - - // Clear timeout if it exists - if ( timeoutTimer ) { - clearTimeout( timeoutTimer ); - } - - // Dereference transport for early garbage collection - // (no matter how long the jqXHR object will be used) - transport = undefined; - - // Cache response headers - responseHeadersString = headers || ""; - - // Set readyState - jqXHR.readyState = status > 0 ? 4 : 0; - - // Determine if successful - isSuccess = status >= 200 && status < 300 || status === 304; - - // Get response data - if ( responses ) { - response = ajaxHandleResponses( s, jqXHR, responses ); - } - - // Convert no matter what (that way responseXXX fields are always set) - response = ajaxConvert( s, response, jqXHR, isSuccess ); - - // If successful, handle type chaining - if ( isSuccess ) { - - // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. - if ( s.ifModified ) { - modified = jqXHR.getResponseHeader("Last-Modified"); - if ( modified ) { - jQuery.lastModified[ cacheURL ] = modified; - } - modified = jqXHR.getResponseHeader("etag"); - if ( modified ) { - jQuery.etag[ cacheURL ] = modified; - } - } - - // if no content - if ( status === 204 || s.type === "HEAD" ) { - statusText = "nocontent"; - - // if not modified - } else if ( status === 304 ) { - statusText = "notmodified"; - - // If we have data, let's convert it - } else { - statusText = response.state; - success = response.data; - error = response.error; - isSuccess = !error; - } - } else { - // We extract error from statusText - // then normalize statusText and status for non-aborts - error = statusText; - if ( status || !statusText ) { - statusText = "error"; - if ( status < 0 ) { - status = 0; - } - } - } - - // Set data for the fake xhr object - jqXHR.status = status; - jqXHR.statusText = ( nativeStatusText || statusText ) + ""; - - // Success/Error - if ( isSuccess ) { - deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); - } else { - deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); - } - - // Status-dependent callbacks - jqXHR.statusCode( statusCode ); - statusCode = undefined; - - if ( fireGlobals ) { - globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", - [ jqXHR, s, isSuccess ? success : error ] ); - } - - // Complete - completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); - - if ( fireGlobals ) { - globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); - // Handle the global AJAX counter - if ( !( --jQuery.active ) ) { - jQuery.event.trigger("ajaxStop"); - } - } - } - - return jqXHR; - }, - - getJSON: function( url, data, callback ) { - return jQuery.get( url, data, callback, "json" ); - }, - - getScript: function( url, callback ) { - return jQuery.get( url, undefined, callback, "script" ); - } -}); - -jQuery.each( [ "get", "post" ], function( i, method ) { - jQuery[ method ] = function( url, data, callback, type ) { - // shift arguments if data argument was omitted - if ( jQuery.isFunction( data ) ) { - type = type || callback; - callback = data; - data = undefined; - } - - return jQuery.ajax({ - url: url, - type: method, - dataType: type, - data: data, - success: callback - }); - }; -}); - -// Attach a bunch of functions for handling common AJAX events -jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) { - jQuery.fn[ type ] = function( fn ) { - return this.on( type, fn ); - }; -}); - - -var r20 = /%20/g, - rbracket = /\[\]$/, - rCRLF = /\r?\n/g, - rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, - rsubmittable = /^(?:input|select|textarea|keygen)/i; - -function buildParams( prefix, obj, traditional, add ) { - var name; - - if ( jQuery.isArray( obj ) ) { - // Serialize array item. - jQuery.each( obj, function( i, v ) { - if ( traditional || rbracket.test( prefix ) ) { - // Treat each array item as a scalar. - add( prefix, v ); - - } else { - // Item is non-scalar (array or object), encode its numeric index. - buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); - } - }); - - } else if ( !traditional && jQuery.type( obj ) === "object" ) { - // Serialize object item. - for ( name in obj ) { - buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); - } - - } else { - // Serialize scalar item. - add( prefix, obj ); - } -} - -// Serialize an array of form elements or a set of -// key/values into a query string -jQuery.param = function( a, traditional ) { - var prefix, - s = [], - add = function( key, value ) { - // If value is a function, invoke it and return its value - value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); - s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); - }; - - // Set traditional to true for jQuery <= 1.3.2 behavior. - if ( traditional === undefined ) { - traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; - } - - // If an array was passed in, assume that it is an array of form elements. - if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { - // 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 - // did it), otherwise encode params recursively. - for ( prefix in a ) { - buildParams( prefix, a[ prefix ], traditional, add ); - } - } - - // Return the resulting serialization - return s.join( "&" ).replace( r20, "+" ); -}; - -jQuery.fn.extend({ - serialize: function() { - return jQuery.param( this.serializeArray() ); - }, - serializeArray: function() { - return this.map(function() { - // Can add propHook for "elements" to filter or add form elements - var elements = jQuery.prop( this, "elements" ); - return elements ? jQuery.makeArray( elements ) : this; - }) - .filter(function() { - var type = this.type; - - // Use .is( ":disabled" ) so that fieldset[disabled] works - return this.name && !jQuery( this ).is( ":disabled" ) && - rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && - ( this.checked || !rcheckableType.test( type ) ); - }) - .map(function( i, elem ) { - var val = jQuery( this ).val(); - - return val == null ? - null : - jQuery.isArray( val ) ? - jQuery.map( val, function( val ) { - return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - }) : - { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - }).get(); - } -}); - - -jQuery.ajaxSettings.xhr = function() { - try { - return new XMLHttpRequest(); - } catch( e ) {} -}; - -var xhrId = 0, - xhrCallbacks = {}, - xhrSuccessStatus = { - // file protocol always yields status code 0, assume 200 - 0: 200, - // Support: IE9 - // #1450: sometimes IE returns 1223 when it should be 204 - 1223: 204 - }, - xhrSupported = jQuery.ajaxSettings.xhr(); - -// Support: IE9 -// Open requests must be manually aborted on unload (#5280) -if ( window.ActiveXObject ) { - jQuery( window ).on( "unload", function() { - for ( var key in xhrCallbacks ) { - xhrCallbacks[ key ](); - } - }); -} - -support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); -support.ajax = xhrSupported = !!xhrSupported; - -jQuery.ajaxTransport(function( options ) { - var callback; - - // Cross domain only allowed if supported through XMLHttpRequest - if ( support.cors || xhrSupported && !options.crossDomain ) { - return { - send: function( headers, complete ) { - var i, - xhr = options.xhr(), - id = ++xhrId; - - xhr.open( options.type, options.url, options.async, options.username, options.password ); - - // Apply custom fields if provided - if ( options.xhrFields ) { - for ( i in options.xhrFields ) { - xhr[ i ] = options.xhrFields[ i ]; - } - } - - // Override mime type if needed - if ( options.mimeType && xhr.overrideMimeType ) { - xhr.overrideMimeType( options.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 ( !options.crossDomain && !headers["X-Requested-With"] ) { - headers["X-Requested-With"] = "XMLHttpRequest"; - } - - // Set headers - for ( i in headers ) { - xhr.setRequestHeader( i, headers[ i ] ); - } - - // Callback - callback = function( type ) { - return function() { - if ( callback ) { - delete xhrCallbacks[ id ]; - callback = xhr.onload = xhr.onerror = null; - - if ( type === "abort" ) { - xhr.abort(); - } else if ( type === "error" ) { - complete( - // file: protocol always yields status 0; see #8605, #14207 - xhr.status, - xhr.statusText - ); - } else { - complete( - xhrSuccessStatus[ xhr.status ] || xhr.status, - xhr.statusText, - // Support: IE9 - // Accessing binary-data responseText throws an exception - // (#11426) - typeof xhr.responseText === "string" ? { - text: xhr.responseText - } : undefined, - xhr.getAllResponseHeaders() - ); - } - } - }; - }; - - // Listen to events - xhr.onload = callback(); - xhr.onerror = callback("error"); - - // Create the abort callback - callback = xhrCallbacks[ id ] = callback("abort"); - - try { - // Do send the request (this may raise an exception) - xhr.send( options.hasContent && options.data || null ); - } catch ( e ) { - // #14683: Only rethrow if this hasn't been notified as an error yet - if ( callback ) { - throw e; - } - } - }, - - abort: function() { - if ( callback ) { - callback(); - } - } - }; - } -}); - - - - -// Install script dataType -jQuery.ajaxSetup({ - accepts: { - script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" - }, - contents: { - script: /(?:java|ecma)script/ - }, - converters: { - "text script": function( text ) { - jQuery.globalEval( text ); - return text; - } - } -}); - -// Handle cache's special case and crossDomain -jQuery.ajaxPrefilter( "script", function( s ) { - if ( s.cache === undefined ) { - s.cache = false; - } - if ( s.crossDomain ) { - s.type = "GET"; - } -}); - -// Bind script tag hack transport -jQuery.ajaxTransport( "script", function( s ) { - // This transport only deals with cross domain requests - if ( s.crossDomain ) { - var script, callback; - return { - send: function( _, complete ) { - script = jQuery(" + @@ -29,38 +30,78 @@

Sign In

-
- Use Fews account to sign in +
+ Use Fews account to sign in +
+
+ + + +
+
- \ No newline at end of file diff --git a/signup.php b/signup.php new file mode 100644 index 0000000..7401c27 --- /dev/null +++ b/signup.php @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + News Website + + + + +
+
+ +
+

Fews

+
+
+

Create your Fews Account

+
+
+ +
+
+
+
+ +
+ +
+
+
+
+
+
+
+
+ +
+ +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+ +
+
+
+
+
+
+
+
+

+ You can also sign up with + google or + facebook. +

+
+
+ +
+
Next
+
+
+
+
+
+ + + \ No newline at end of file