From eb769f29358fc5f5a6969b83dd0b0c98620b8ba6 Mon Sep 17 00:00:00 2001 From: Michael Christopher Date: Thu, 14 Nov 2013 14:22:59 -0800 Subject: [PATCH 01/43] Adding overwrite and parent revision support to upload calls --- DropNet.Tests/Helpers/RequestHelperTest.cs | 2 +- DropNet/Client/Files.Async.cs | 18 ++++++++----- DropNet/Client/Files.Sync.cs | 25 +++++++++++------- DropNet/Client/Files.Task.cs | 8 +++--- DropNet/Helpers/RequestHelper.cs | 30 +++++++++++++++++++--- 5 files changed, 59 insertions(+), 24 deletions(-) diff --git a/DropNet.Tests/Helpers/RequestHelperTest.cs b/DropNet.Tests/Helpers/RequestHelperTest.cs index 35a5ff1..6d0f679 100644 --- a/DropNet.Tests/Helpers/RequestHelperTest.cs +++ b/DropNet.Tests/Helpers/RequestHelperTest.cs @@ -246,7 +246,7 @@ public void CreateUploadFileRequestTest() string filename = fixture.CreateAnonymous(); byte[] fileData = System.Text.Encoding.UTF8.GetBytes(fixture.CreateAnonymous()); - RestRequest actual = _target.CreateUploadFileRequest(path, filename, fileData, "dropbox"); + RestRequest actual = _target.CreateUploadFileRequest(path, filename, fileData, "dropbox", true, null); Assert.IsNotNull(actual); Assert.IsTrue(actual.Method == Method.POST); diff --git a/DropNet/Client/Files.Async.cs b/DropNet/Client/Files.Async.cs index b473b7d..c37f60e 100644 --- a/DropNet/Client/Files.Async.cs +++ b/DropNet/Client/Files.Async.cs @@ -115,7 +115,9 @@ public void GetFileAsync(string path, long startByte, long endByte, string rev, /// The path of the folder to upload to /// The local file to upload/// Success callback /// Failure callback - public void UploadFileAsync(string path, FileInfo localFile, Action success, Action failure) + /// Specify wether the file upload should replace an existing file + /// The revision of the file you're editing + public void UploadFileAsync(string path, FileInfo localFile, Action success, Action failure, bool overwrite = true, string parentRevision = null) { //Get the file stream byte[] bytes; @@ -128,7 +130,7 @@ public void UploadFileAsync(string path, FileInfo localFile, Action su } } - UploadFileAsync(path, localFile.Name, bytes, success, failure); + UploadFileAsync(path, localFile.Name, bytes, success, failure, overwrite, parentRevision); } #endif @@ -140,11 +142,13 @@ public void UploadFileAsync(string path, FileInfo localFile, Action su /// The file data /// Success callback /// Failure callback - public void UploadFileAsync(string path, string filename, byte[] fileData, Action success, Action failure) + /// Specify wether the file upload should replace an existing file + /// The revision of the file you're editing + public void UploadFileAsync(string path, string filename, byte[] fileData, Action success, Action failure, bool overwrite = true, string parentRevision = null) { if (path != "" && !path.StartsWith("/")) path = "/" + path; - var request = _requestHelper.CreateUploadFileRequest(path, filename, fileData, Root); + var request = _requestHelper.CreateUploadFileRequest(path, filename, fileData, Root, overwrite, parentRevision); ExecuteAsync(ApiType.Content, request, success, failure); } @@ -157,11 +161,13 @@ public void UploadFileAsync(string path, string filename, byte[] fileData, Actio /// The file data /// The callback Action to perform on completion /// The callback Action to perform on exception - public void UploadFileAsync(string path, string filename, Stream fileStream, Action success, Action failure) + /// Specify wether the file upload should replace an existing file + /// The revision of the file you're editing + public void UploadFileAsync(string path, string filename, Stream fileStream, Action success, Action failure, bool overwrite = true, string parentRevision = null) { if (path != "" && !path.StartsWith("/")) path = "/" + path; - var request = _requestHelper.CreateUploadFileRequest(path, filename, fileStream, Root); + var request = _requestHelper.CreateUploadFileRequest(path, filename, fileStream, Root, overwrite, parentRevision); ExecuteAsync(ApiType.Content, request, success, failure); } diff --git a/DropNet/Client/Files.Sync.cs b/DropNet/Client/Files.Sync.cs index 9e5e994..e82b1e5 100644 --- a/DropNet/Client/Files.Sync.cs +++ b/DropNet/Client/Files.Sync.cs @@ -143,14 +143,16 @@ public byte[] GetFileContentFromFS(FileInfo localFile) /// The path of the folder to upload to /// The Name of the file to upload to dropbox /// The file data + /// Specify wether the file upload should replace an existing file + /// The revision of the file you're editing /// True on success - public MetaData UploadFilePUT(string path, string filename, byte[] fileData) + public MetaData UploadFilePUT(string path, string filename, byte[] fileData, bool overwrite = true, string parentRevision = null) { if (!path.StartsWith("/")) { path = "/" + path; } - var request = _requestHelper.CreateUploadFilePutRequest(path, filename, fileData, Root); + var request = _requestHelper.CreateUploadFilePutRequest(path, filename, fileData, Root, overwrite, parentRevision); var response = _restClientContent.Execute(request); //TODO - Return something better here? @@ -163,14 +165,16 @@ public MetaData UploadFilePUT(string path, string filename, byte[] fileData) /// The path of the folder to upload to /// The Name of the file to upload to dropbox /// The file data + /// Specify wether the file upload should replace an existing file + /// The revision of the file you're editing /// True on success - public MetaData UploadFile(string path, string filename, byte[] fileData) + public MetaData UploadFile(string path, string filename, byte[] fileData, bool overwrite = true, string parentRevision = null) { if (!path.StartsWith("/")) { path = "/" + path; } - var request = _requestHelper.CreateUploadFileRequest(path, filename, fileData, Root); + var request = _requestHelper.CreateUploadFileRequest(path, filename, fileData, Root, overwrite, parentRevision); var response = _restClientContent.Execute(request); //TODO - Return something better here? @@ -183,14 +187,16 @@ public MetaData UploadFile(string path, string filename, byte[] fileData) /// The path of the folder to upload to /// The Name of the file to upload to dropbox /// The file stream + /// Specify wether the file upload should replace an existing file + /// The revision of the file you're editing /// True on success - public MetaData UploadFile(string path, string filename, Stream stream) + public MetaData UploadFile(string path, string filename, Stream stream, bool overwrite = true, string parentRevision = null) { if (!path.StartsWith("/")) { path = "/" + path; } - var request = _requestHelper.CreateUploadFileRequest(path, filename, stream, Root); + var request = _requestHelper.CreateUploadFileRequest(path, filename, stream, Root, overwrite, parentRevision); var response = _restClientContent.Execute(request); //TODO - Return something better here? @@ -227,11 +233,12 @@ public ChunkedUpload AppendChunkedUpload(ChunkedUpload upload, byte[] fileData) /// /// A ChunkedUpload object received from the StartChunkedUpload method /// The full path of the file to upload to - /// Specify wether the file upload should replace an existing file. + /// Specify wether the file upload should replace an existing file + /// The revision of the file you're editing /// A object representing the chunked upload on success - public MetaData CommitChunkedUpload(ChunkedUpload upload, string path, bool overwrite = true) + public MetaData CommitChunkedUpload(ChunkedUpload upload, string path, bool overwrite = true, string parentRevision = null) { - var request = _requestHelper.CreateCommitChunkedUploadRequest(upload, path, Root, overwrite); + var request = _requestHelper.CreateCommitChunkedUploadRequest(upload, path, Root, overwrite, parentRevision); var response = _restClientContent.Execute(request); return response.Data; } diff --git a/DropNet/Client/Files.Task.cs b/DropNet/Client/Files.Task.cs index 8361254..6a1c4ee 100644 --- a/DropNet/Client/Files.Task.cs +++ b/DropNet/Client/Files.Task.cs @@ -55,20 +55,20 @@ public Task GetFileTask(string path) return ExecuteTask(ApiType.Content, request); } - public Task UploadFileTask(string path, string filename, byte[] fileData) + public Task UploadFileTask(string path, string filename, byte[] fileData, bool overwrite = true, string parentRevision = null) { if (path != "" && !path.StartsWith("/")) path = "/" + path; - var request = _requestHelper.CreateUploadFileRequest(path, filename, fileData, Root); + var request = _requestHelper.CreateUploadFileRequest(path, filename, fileData, Root, overwrite, parentRevision); return ExecuteTask(ApiType.Content, request); } - public Task UploadFileTask(string path, string filename, Stream fileStream) + public Task UploadFileTask(string path, string filename, Stream fileStream, bool overwrite = true, string parentRevision = null) { if (path != "" && !path.StartsWith("/")) path = "/" + path; - var request = _requestHelper.CreateUploadFileRequest(path, filename, fileStream, Root); + var request = _requestHelper.CreateUploadFileRequest(path, filename, fileStream, Root, overwrite, parentRevision); return ExecuteTask(ApiType.Content, request); } diff --git a/DropNet/Helpers/RequestHelper.cs b/DropNet/Helpers/RequestHelper.cs index 70f4712..b900d17 100644 --- a/DropNet/Helpers/RequestHelper.cs +++ b/DropNet/Helpers/RequestHelper.cs @@ -99,7 +99,7 @@ public RestRequest CreateGetFileRequest(string path, string root, long startByte return request; } - public RestRequest CreateUploadFileRequest(string path, string filename, byte[] fileData, string root) + public RestRequest CreateUploadFileRequest(string path, string filename, byte[] fileData, string root, bool overwrite, string parent_revision) { var request = new RestRequest(Method.POST); request.Resource = "{version}/files/{root}{path}"; @@ -111,12 +111,18 @@ public RestRequest CreateUploadFileRequest(string path, string filename, byte[] // but the oauth sig only needs the filename, which we have in the OTHER parameter //request.AddParameter("file", filename); + request.AddParameter("overwrite", overwrite); + if (!String.IsNullOrEmpty(parent_revision)) + { + request.AddParameter("parent_rev", parent_revision); + } + request.AddFile("file", fileData, filename); return request; } - public RestRequest CreateUploadFilePutRequest(string path, string filename, byte[] fileData, string root) + public RestRequest CreateUploadFilePutRequest(string path, string filename, byte[] fileData, string root, bool overwrite, string parent_revision) { var request = new RestRequest(Method.PUT); //Need to put the OAuth Parmeters in the Resource to get around them being put in the body @@ -129,12 +135,18 @@ public RestRequest CreateUploadFilePutRequest(string path, string filename, byte //Need to add the "file" parameter with the file name request.AddParameter("file", filename, ParameterType.UrlSegment); + request.AddParameter("overwrite", overwrite); + if (!String.IsNullOrEmpty(parent_revision)) + { + request.AddParameter("parent_rev", parent_revision); + } + request.AddParameter("file", fileData, ParameterType.RequestBody); return request; } - public RestRequest CreateUploadFileRequest(string path, string filename, Stream fileStream, string root) + public RestRequest CreateUploadFileRequest(string path, string filename, Stream fileStream, string root, bool overwrite, string parent_revision) { var request = new RestRequest(Method.POST); //Don't want these to timeout (Maybe use something better here?) @@ -148,6 +160,12 @@ public RestRequest CreateUploadFileRequest(string path, string filename, Stream // but the oauth sig only needs the filename, which we have in the OTHER parameter //request.AddParameter("file", filename); + request.AddParameter("overwrite", overwrite); + if (!String.IsNullOrEmpty(parent_revision)) + { + request.AddParameter("parent_rev", parent_revision); + } + request.AddFile("file", s => StreamUtils.CopyStream(fileStream, s), filename); return request; @@ -181,7 +199,7 @@ public RestRequest CreateAppendChunkedUploadRequest(ChunkedUpload upload, byte[] return request; } - public RestRequest CreateCommitChunkedUploadRequest(ChunkedUpload upload, string path, string root, bool overwrite) + public RestRequest CreateCommitChunkedUploadRequest(ChunkedUpload upload, string path, string root, bool overwrite, string parent_revision) { var request = new RestRequest(Method.POST); request.Resource = "{version}/commit_chunked_upload/{root}{path}"; @@ -191,6 +209,10 @@ public RestRequest CreateCommitChunkedUploadRequest(ChunkedUpload upload, string request.AddParameter("overwrite", overwrite); request.AddParameter("upload_id", upload.UploadId); + if (!String.IsNullOrEmpty(parent_revision)) + { + request.AddParameter("parent_rev", parent_revision); + } return request; } From dce3c17390141c14fb92c4966accc2815f1ded33 Mon Sep 17 00:00:00 2001 From: Austin Thompson Date: Tue, 26 Nov 2013 06:32:35 -0600 Subject: [PATCH 02/43] Added async version of chunked upload functions --- DropNet/Client/Files.Async.cs | 43 +++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/DropNet/Client/Files.Async.cs b/DropNet/Client/Files.Async.cs index c37f60e..d9fd47b 100644 --- a/DropNet/Client/Files.Async.cs +++ b/DropNet/Client/Files.Async.cs @@ -172,6 +172,49 @@ public void UploadFileAsync(string path, string filename, Stream fileStream, Act ExecuteAsync(ApiType.Content, request, success, failure); } + /// + /// Starts a chunked upload to Dropbox given a byte array. + /// + /// The file data + /// The callback Action to perform on completion + /// The callback Action to perform on exception + public void StartChunkedUploadAsync(byte[] fileData, Action success, Action failure) + { + var request = _requestHelper.CreateChunkedUploadRequest(fileData); + + ExecuteAsync(ApiType.Content, request, success, failure); + } + + /// + /// Add data to a chunked upload given a byte array. + /// + /// A ChunkedUpload object received from the StartChunkedUpload method + /// The file data + /// The callback Action to perform on completion + /// The callback Action to perform on exception + public void AppendChunkedUploadAsync(ChunkedUpload upload, byte[] fileData, Action success, Action failure) + { + var request = _requestHelper.CreateAppendChunkedUploadRequest(upload, fileData); + + ExecuteAsync(ApiType.Content, request, success, failure); + } + + /// + /// Commit a completed chunked upload + /// + /// A ChunkedUpload object received from the StartChunkedUpload method + /// The full path of the file to upload to + /// The callback Action to perform on completion + /// The callback Action to perform on exception + /// Specify wether the file upload should replace an existing file + /// The revision of the file you're editing + public void CommitChunkedUploadAsync(ChunkedUpload upload, string path, Action success, Action failure, bool overwrite = true, string parentRevision = null) + { + var request = _requestHelper.CreateCommitChunkedUploadRequest(upload, path, Root, overwrite, parentRevision); + + ExecuteAsync(ApiType.Content, request, success, failure); + } + /// /// Deletes the file or folder from dropbox with the given path /// From 7565ada5b5f53f7943edde1ee748dd2c2fc28be2 Mon Sep 17 00:00:00 2001 From: Austin Thompson Date: Thu, 28 Nov 2013 21:14:46 -0600 Subject: [PATCH 03/43] Added UploadChunkedFileAsync to handle the complexity of chunked uploads. --- DropNet/Client/Files.Async.cs | 17 +++++- DropNet/DropNet.csproj | 1 + DropNet/Helpers/ChunkedUploadHelper.cs | 85 ++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 DropNet/Helpers/ChunkedUploadHelper.cs diff --git a/DropNet/Client/Files.Async.cs b/DropNet/Client/Files.Async.cs index d9fd47b..6f72231 100644 --- a/DropNet/Client/Files.Async.cs +++ b/DropNet/Client/Files.Async.cs @@ -3,7 +3,6 @@ using DropNet.Models; using RestSharp; using System; -using DropNet.Authenticators; using DropNet.Exceptions; namespace DropNet @@ -172,6 +171,22 @@ public void UploadFileAsync(string path, string filename, Stream fileStream, Act ExecuteAsync(ApiType.Content, request, success, failure); } + /// + /// Uploads a File to Dropbox in chunks that are assembled into a single file when finished. + /// + /// The callback function that returns a byte array given an offset + /// The full path of the file to upload to + /// The callback Action to perform on completion + /// The callback Action to perform on exception + /// Specify wether the file upload should replace an existing file + /// The revision of the file you're editing + /// The total size of the file if available + public void UploadChunkedFileAsync(Func chunkNeeded, string path, Action success, Action failure, bool overwrite = true, string parentRevision = null, long? fileSize = null) + { + var chunkedUploader = new DropNet.Helpers.ChunkedUploadHelper(this, chunkNeeded, path, success, failure, overwrite, parentRevision, fileSize); + chunkedUploader.Start(); + } + /// /// Starts a chunked upload to Dropbox given a byte array. /// diff --git a/DropNet/DropNet.csproj b/DropNet/DropNet.csproj index 15338f6..f4ecb3d 100644 --- a/DropNet/DropNet.csproj +++ b/DropNet/DropNet.csproj @@ -75,6 +75,7 @@ + diff --git a/DropNet/Helpers/ChunkedUploadHelper.cs b/DropNet/Helpers/ChunkedUploadHelper.cs new file mode 100644 index 0000000..4c7d510 --- /dev/null +++ b/DropNet/Helpers/ChunkedUploadHelper.cs @@ -0,0 +1,85 @@ +using System; +using DropNet.Exceptions; +using DropNet.Models; + +namespace DropNet.Helpers +{ + public class ChunkedUploadHelper + { + private readonly DropNetClient _client; + private readonly Func _chunkNeeded; + private readonly string _path; + private readonly Action _success; + private readonly Action _failure; + private readonly bool _overwrite; + private readonly string _parentRevision; + private readonly long? _fileSize; + + public ChunkedUploadHelper(DropNetClient client, Func chunkNeeded, string path, Action success, Action failure, bool overwrite, string parentRevision, long? fileSize) + { + if (client == null) + { + throw new ArgumentNullException("client"); + } + + if (chunkNeeded == null) + { + throw new ArgumentNullException("chunkNeeded"); + } + + if (success == null) + { + throw new ArgumentNullException("success"); + } + + if (failure == null) + { + throw new ArgumentNullException("failure"); + } + + _client = client; + _chunkNeeded = chunkNeeded; + _path = path; + _success = success; + _failure = failure; + _overwrite = overwrite; + _parentRevision = parentRevision; + _fileSize = fileSize; + } + + public void Start() + { + var firstChunk = _chunkNeeded.Invoke(0); + var chunkLength = firstChunk.GetLength(0); + if (chunkLength <= 0) + { + _failure.Invoke(new DropboxException("Aborting chunked upload because chunkNeeded function returned no data on first call.")); + } + + _client.StartChunkedUploadAsync(firstChunk, OnChunkSuccess, OnChunkedUploadFailure ); + } + + private void OnChunkSuccess(ChunkedUpload chunkedUpload) + { + var offset = chunkedUpload.Offset; + var nextChunk = _fileSize.GetValueOrDefault(long.MaxValue) > offset + ? _chunkNeeded.Invoke(offset) + : new byte[0]; + + var chunkLength = nextChunk.GetLength(0); + if (chunkLength > 0) + { + _client.AppendChunkedUploadAsync(chunkedUpload, nextChunk, OnChunkSuccess, OnChunkedUploadFailure); + } + else + { + _client.CommitChunkedUploadAsync(chunkedUpload, _path, _success, _failure, _overwrite, _parentRevision); + } + } + + private void OnChunkedUploadFailure(DropboxException dropboxException) + { + _failure.Invoke(dropboxException); + } + } +} \ No newline at end of file From 31bd34af8af92bdff72557d4072cc150488105f1 Mon Sep 17 00:00:00 2001 From: Austin Thompson Date: Fri, 29 Nov 2013 16:25:19 -0600 Subject: [PATCH 04/43] Added progress support for async chunked uploads --- .../DropNet.WindowsPhone.csproj | 6 +++ DropNet/Client/Files.Async.cs | 5 +- DropNet/DropNet.csproj | 1 + DropNet/Helpers/ChunkedUploadHelper.cs | 16 +++++- DropNet/Models/ChunkedUploadProgress.cs | 53 +++++++++++++++++++ 5 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 DropNet/Models/ChunkedUploadProgress.cs diff --git a/DropNet.WindowsPhone/DropNet.WindowsPhone.csproj b/DropNet.WindowsPhone/DropNet.WindowsPhone.csproj index 8fa8730..5dd26da 100644 --- a/DropNet.WindowsPhone/DropNet.WindowsPhone.csproj +++ b/DropNet.WindowsPhone/DropNet.WindowsPhone.csproj @@ -86,6 +86,9 @@ Models\ChunkedUpload.cs + + Models\ChunkedUploadProgress.cs + Models\CopyRefResponse.cs @@ -111,6 +114,9 @@ Helpers\RequestHelper.cs + + Helpers\ChunkedUploadHelper.cs + diff --git a/DropNet/Client/Files.Async.cs b/DropNet/Client/Files.Async.cs index 6f72231..c0969c1 100644 --- a/DropNet/Client/Files.Async.cs +++ b/DropNet/Client/Files.Async.cs @@ -178,12 +178,13 @@ public void UploadFileAsync(string path, string filename, Stream fileStream, Act /// The full path of the file to upload to /// The callback Action to perform on completion /// The callback Action to perform on exception + /// The optional callback Action that receives upload progress /// Specify wether the file upload should replace an existing file /// The revision of the file you're editing /// The total size of the file if available - public void UploadChunkedFileAsync(Func chunkNeeded, string path, Action success, Action failure, bool overwrite = true, string parentRevision = null, long? fileSize = null) + public void UploadChunkedFileAsync(Func chunkNeeded, string path, Action success, Action failure, Action progress = null, bool overwrite = true, string parentRevision = null, long? fileSize = null) { - var chunkedUploader = new DropNet.Helpers.ChunkedUploadHelper(this, chunkNeeded, path, success, failure, overwrite, parentRevision, fileSize); + var chunkedUploader = new DropNet.Helpers.ChunkedUploadHelper(this, chunkNeeded, path, success, failure, progress, overwrite, parentRevision, fileSize); chunkedUploader.Start(); } diff --git a/DropNet/DropNet.csproj b/DropNet/DropNet.csproj index f4ecb3d..d53ab79 100644 --- a/DropNet/DropNet.csproj +++ b/DropNet/DropNet.csproj @@ -79,6 +79,7 @@ + diff --git a/DropNet/Helpers/ChunkedUploadHelper.cs b/DropNet/Helpers/ChunkedUploadHelper.cs index 4c7d510..420e30b 100644 --- a/DropNet/Helpers/ChunkedUploadHelper.cs +++ b/DropNet/Helpers/ChunkedUploadHelper.cs @@ -11,11 +11,13 @@ public class ChunkedUploadHelper private readonly string _path; private readonly Action _success; private readonly Action _failure; + private readonly Action _progress; private readonly bool _overwrite; private readonly string _parentRevision; private readonly long? _fileSize; + private long _chunksCompleted; - public ChunkedUploadHelper(DropNetClient client, Func chunkNeeded, string path, Action success, Action failure, bool overwrite, string parentRevision, long? fileSize) + public ChunkedUploadHelper(DropNetClient client, Func chunkNeeded, string path, Action success, Action failure, Action progress, bool overwrite, string parentRevision, long? fileSize) { if (client == null) { @@ -42,6 +44,7 @@ public ChunkedUploadHelper(DropNetClient client, Func chunkNeeded, _path = path; _success = success; _failure = failure; + _progress = progress; _overwrite = overwrite; _parentRevision = parentRevision; _fileSize = fileSize; @@ -56,11 +59,22 @@ public void Start() _failure.Invoke(new DropboxException("Aborting chunked upload because chunkNeeded function returned no data on first call.")); } + UpdateProgress(0, null); _client.StartChunkedUploadAsync(firstChunk, OnChunkSuccess, OnChunkedUploadFailure ); } + private void UpdateProgress(long offset, string uploadId) + { + if (_progress != null) + { + _progress.Invoke(new ChunkedUploadProgress(uploadId, _chunksCompleted, offset, _fileSize)); + } + } + private void OnChunkSuccess(ChunkedUpload chunkedUpload) { + _chunksCompleted++; + UpdateProgress(chunkedUpload.Offset, chunkedUpload.UploadId); var offset = chunkedUpload.Offset; var nextChunk = _fileSize.GetValueOrDefault(long.MaxValue) > offset ? _chunkNeeded.Invoke(offset) diff --git a/DropNet/Models/ChunkedUploadProgress.cs b/DropNet/Models/ChunkedUploadProgress.cs new file mode 100644 index 0000000..6681639 --- /dev/null +++ b/DropNet/Models/ChunkedUploadProgress.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; + +namespace DropNet.Models +{ + public class ChunkedUploadProgress + { + private readonly string _uploadId; + private readonly long _chunksCompleted; + private readonly long _bytesSaved; + private readonly long? _fileSize; + + public ChunkedUploadProgress(string uploadId, long chunksCompleted, long bytesSaved, long? fileSize) + { + _uploadId = uploadId; + this._chunksCompleted = chunksCompleted; + this._bytesSaved = bytesSaved; + this._fileSize = fileSize; + } + + public string UploadId + { + get + { + return this._uploadId; + } + } + + public long ChunksCompleted + { + get + { + return this._chunksCompleted; + } + } + + public long BytesSaved + { + get + { + return this._bytesSaved; + } + } + + public long? FileSize + { + get + { + return this._fileSize; + } + } + } +} From 169fee8ce7545b06991b9da1e874104790cda511 Mon Sep 17 00:00:00 2001 From: Austin Thompson Date: Sun, 1 Dec 2013 21:16:55 -0600 Subject: [PATCH 05/43] Added chunked upload auto retry on chunk failure A default retry limit of 100 is used for now. It is per upload and not per chunk. The retry count was added to the progress information so that it can be displayed to users if desired. Some sort of sliding delay between retries might be a good idea so that the limit isn't burned through too quickly in certain situations (disconnect ethernet cable, airplaine mode, etc.). --- DropNet/Client/Files.Async.cs | 5 +++-- DropNet/Helpers/ChunkedUploadHelper.cs | 20 +++++++++++++++++--- DropNet/Models/ChunkedUploadProgress.cs | 18 ++++++++++++++---- 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/DropNet/Client/Files.Async.cs b/DropNet/Client/Files.Async.cs index c0969c1..ba8533a 100644 --- a/DropNet/Client/Files.Async.cs +++ b/DropNet/Client/Files.Async.cs @@ -182,9 +182,10 @@ public void UploadFileAsync(string path, string filename, Stream fileStream, Act /// Specify wether the file upload should replace an existing file /// The revision of the file you're editing /// The total size of the file if available - public void UploadChunkedFileAsync(Func chunkNeeded, string path, Action success, Action failure, Action progress = null, bool overwrite = true, string parentRevision = null, long? fileSize = null) + /// The number of times to retry uploading if a chunk fails, unlimited if null. + public void UploadChunkedFileAsync(Func chunkNeeded, string path, Action success, Action failure, Action progress = null, bool overwrite = true, string parentRevision = null, long? fileSize = null, long? maxRetries = null) { - var chunkedUploader = new DropNet.Helpers.ChunkedUploadHelper(this, chunkNeeded, path, success, failure, progress, overwrite, parentRevision, fileSize); + var chunkedUploader = new DropNet.Helpers.ChunkedUploadHelper(this, chunkNeeded, path, success, failure, progress, overwrite, parentRevision, fileSize, maxRetries); chunkedUploader.Start(); } diff --git a/DropNet/Helpers/ChunkedUploadHelper.cs b/DropNet/Helpers/ChunkedUploadHelper.cs index 420e30b..58b9d70 100644 --- a/DropNet/Helpers/ChunkedUploadHelper.cs +++ b/DropNet/Helpers/ChunkedUploadHelper.cs @@ -6,6 +6,7 @@ namespace DropNet.Helpers { public class ChunkedUploadHelper { + private const long DefaultMaxRetries = 100; private readonly DropNetClient _client; private readonly Func _chunkNeeded; private readonly string _path; @@ -15,9 +16,12 @@ public class ChunkedUploadHelper private readonly bool _overwrite; private readonly string _parentRevision; private readonly long? _fileSize; + private readonly long? _maxRetries; private long _chunksCompleted; + private long _chunksFailed; + private ChunkedUpload _lastChunkUploaded; - public ChunkedUploadHelper(DropNetClient client, Func chunkNeeded, string path, Action success, Action failure, Action progress, bool overwrite, string parentRevision, long? fileSize) + public ChunkedUploadHelper(DropNetClient client, Func chunkNeeded, string path, Action success, Action failure, Action progress, bool overwrite, string parentRevision, long? fileSize, long? maxRetries) { if (client == null) { @@ -48,6 +52,7 @@ public ChunkedUploadHelper(DropNetClient client, Func chunkNeeded, _overwrite = overwrite; _parentRevision = parentRevision; _fileSize = fileSize; + _maxRetries = maxRetries; } public void Start() @@ -67,13 +72,14 @@ private void UpdateProgress(long offset, string uploadId) { if (_progress != null) { - _progress.Invoke(new ChunkedUploadProgress(uploadId, _chunksCompleted, offset, _fileSize)); + _progress.Invoke(new ChunkedUploadProgress(uploadId, _chunksCompleted, offset, _chunksFailed, _fileSize)); } } private void OnChunkSuccess(ChunkedUpload chunkedUpload) { _chunksCompleted++; + _lastChunkUploaded = chunkedUpload; UpdateProgress(chunkedUpload.Offset, chunkedUpload.UploadId); var offset = chunkedUpload.Offset; var nextChunk = _fileSize.GetValueOrDefault(long.MaxValue) > offset @@ -93,7 +99,15 @@ private void OnChunkSuccess(ChunkedUpload chunkedUpload) private void OnChunkedUploadFailure(DropboxException dropboxException) { - _failure.Invoke(dropboxException); + _chunksFailed++; + if (_lastChunkUploaded != null && _chunksFailed <= _maxRetries.GetValueOrDefault(DefaultMaxRetries)) + { + OnChunkSuccess(_lastChunkUploaded); + } + else + { + _failure.Invoke(dropboxException); + } } } } \ No newline at end of file diff --git a/DropNet/Models/ChunkedUploadProgress.cs b/DropNet/Models/ChunkedUploadProgress.cs index 6681639..5bd8ea9 100644 --- a/DropNet/Models/ChunkedUploadProgress.cs +++ b/DropNet/Models/ChunkedUploadProgress.cs @@ -8,14 +8,16 @@ public class ChunkedUploadProgress private readonly string _uploadId; private readonly long _chunksCompleted; private readonly long _bytesSaved; + private readonly long _retryCount; private readonly long? _fileSize; - public ChunkedUploadProgress(string uploadId, long chunksCompleted, long bytesSaved, long? fileSize) + public ChunkedUploadProgress(string uploadId, long chunksCompleted, long bytesSaved, long retryCount, long? fileSize) { _uploadId = uploadId; - this._chunksCompleted = chunksCompleted; - this._bytesSaved = bytesSaved; - this._fileSize = fileSize; + _chunksCompleted = chunksCompleted; + _bytesSaved = bytesSaved; + _retryCount = retryCount; + _fileSize = fileSize; } public string UploadId @@ -49,5 +51,13 @@ public long? FileSize return this._fileSize; } } + + public long RetryCount + { + get + { + return this._retryCount; + } + } } } From c6b7016d84098169e0d4c2eb6d4d285a9d11430b Mon Sep 17 00:00:00 2001 From: Jason Smith Date: Mon, 13 Jan 2014 12:15:49 +1100 Subject: [PATCH 06/43] Added IDropNetClient interface for simpler mocking during testing. All HTML comments have been transfered to interface and conditionals obeyed based on what was present in implementation. --- DropNet/Client/Client.cs | 48 +-- DropNet/Client/Files.Async.cs | 203 ------------ DropNet/Client/Files.Sync.cs | 171 ---------- DropNet/Client/IClient.cs | 608 ++++++++++++++++++++++++++++++++++ DropNet/Client/User.Async.cs | 21 -- DropNet/Client/User.Sync.cs | 18 - DropNet/DropNet.csproj | 1 + 7 files changed, 610 insertions(+), 460 deletions(-) create mode 100644 DropNet/Client/IClient.cs diff --git a/DropNet/Client/Client.cs b/DropNet/Client/Client.cs index bf2b9df..c6d00d3 100644 --- a/DropNet/Client/Client.cs +++ b/DropNet/Client/Client.cs @@ -12,7 +12,7 @@ namespace DropNet { - public partial class DropNetClient + public partial class DropNetClient : IDropNetClient { private const string ApiBaseUrl = "https://api.dropbox.com"; private const string ApiContentBaseUrl = "https://api-content.dropbox.com"; @@ -20,9 +20,6 @@ public partial class DropNetClient private UserLogin _userLogin; - /// - /// Contains the Users Token and Secret - /// public UserLogin UserLogin { get { return _userLogin; } @@ -33,9 +30,6 @@ public UserLogin UserLogin } } - /// - /// To use Dropbox API in sandbox mode (app folder access) set to true - /// public bool UseSandbox { get; set; } private const string SandboxRoot = "sandbox"; @@ -61,13 +55,6 @@ string Root get { return UseSandbox ? SandboxRoot : DropboxRoot; } } - /// - /// Default Constructor for the DropboxClient - /// - /// The Api Key to use for the Dropbox Requests - /// The Api Secret to use for the Dropbox Requests - /// The authentication method to use. - /// The proxy to use for web requests public DropNetClient(string apiKey, string appSecret, AuthenticationMethod authenticationMethod = AuthenticationMethod.OAuth1) { LoadClient(); @@ -77,27 +64,12 @@ public DropNetClient(string apiKey, string appSecret, AuthenticationMethod authe UserLogin = null; } - /// - /// Creates an instance of the DropNetClient given an API Key/Secret and an OAuth2 Access Token - /// - /// The Api Key to use for the Dropbox Requests - /// The Api Secret to use for the Dropbox Requests - /// The OAuth2 access token - /// The proxy to use for web requests public DropNetClient(string apiKey, string appSecret, string accessToken) : this(apiKey, appSecret, AuthenticationMethod.OAuth2) { UserLogin = new UserLogin { Token = accessToken }; } - /// - /// Creates an instance of the DropNetClient given an API Key/Secret and an OAuth1 User Token/Secret - /// - /// The Api Key to use for the Dropbox Requests - /// The Api Secret to use for the Dropbox Requests - /// The OAuth1 User authentication token - /// The OAuth1 Users matching secret - /// The proxy to use for web requests public DropNetClient(string apiKey, string appSecret, string userToken, string userSecret) :this(apiKey, appSecret) { @@ -125,22 +97,11 @@ private void LoadClient() UseSandbox = false; } - /// - /// Helper Method to Build up the Url to authorize a Token/Secret - /// - /// - /// public string BuildAuthorizeUrl(string callback = null) { return BuildAuthorizeUrl(UserLogin, callback); } - /// - /// Helper Method to Build up the Url to authorize a Token/Secret - /// - /// - /// - /// public string BuildAuthorizeUrl(UserLogin userLogin, string callback = null) { if (userLogin == null) @@ -151,13 +112,6 @@ public string BuildAuthorizeUrl(UserLogin userLogin, string callback = null) return _restClient.BuildUri(request).ToString(); } - /// - /// This starts the OAuth 2.0 authorization flow. This isn't an API call—it's the web page that lets the user sign in to Dropbox and authorize your app. The user must be redirected to the page over HTTPS and it should be presented to the user through their web browser. After the user decides whether or not to authorize your app, they will be redirected to the URL specified by the 'redirectUri'. - /// - /// The type of authorization flow to use. See the OAuth2AuthorizationFlow enum documentation for more information. - /// Where to redirect the user after authorization has completed. This must be the exact URI registered in the app console (https://www.dropbox.com/developers/apps), though localhost and 127.0.0.1 are always accepted. A redirect URI is required for a token flow, but optional for code. If the redirect URI is omitted, the code will be presented directly to the user and they will be invited to enter the information in your app. - /// Arbitrary data that will be passed back to your redirect URI. This parameter can be used to track a user through the authorization flow in order to prevent cross-site request forgery (CRSF) attacks. - /// A URL to which your app should redirect the user for authorization. After the user authorizes your app, they will be sent to your redirect URI. The type of response varies based on the 'oauth2AuthorizationFlow' argument. . public string BuildAuthorizeUrl(OAuth2AuthorizationFlow oAuth2AuthorizationFlow, string redirectUri, string state = null) { if (string.IsNullOrWhiteSpace(redirectUri)) diff --git a/DropNet/Client/Files.Async.cs b/DropNet/Client/Files.Async.cs index ba8533a..139a81d 100644 --- a/DropNet/Client/Files.Async.cs +++ b/DropNet/Client/Files.Async.cs @@ -9,12 +9,6 @@ namespace DropNet { public partial class DropNetClient { - /// - /// Gets MetaData for a File or Folder. For a folder this includes its contents. For a file, this includes details such as file size. - /// - /// The path of the file or folder - /// Success call back - /// Failure call back public void GetMetaDataAsync(string path, Action success, Action failure) { if (!string.IsNullOrEmpty(path) && !path.StartsWith("/")) @@ -27,15 +21,6 @@ public void GetMetaDataAsync(string path, Action success, Action - /// Gets MetaData for a File or Folder. For a folder this includes its contents. For a file, this includes details such as file size. - /// Optional 'hash' param returns HTTP code 304 (Directory contents have not changed) if contents have not changed since the - /// hash was retrieved on a previous call. - /// - /// The path of the file or folder - /// hash - Optional. Listing return values include a hash representing the state of the directory's contents. If you provide this argument to the metadata call, you give the service an opportunity to respond with a "304 Not Modified" status code instead of a full (potentially very large) directory listing. This argument is ignored if the specified path is associated with a file or if list=false. - /// Success callback - /// Failure callback public void GetMetaDataAsync(string path, string hash, Action success, Action failure) { if (path != "" && !path.StartsWith("/")) path = "/" + path; @@ -47,38 +32,17 @@ public void GetMetaDataAsync(string path, string hash, Action success, ExecuteAsync(ApiType.Base, request, success, failure); } - /// - /// Gets list of metadata for search string - /// - /// The search string - /// Success call back - /// Failure call back public void SearchAsync(string searchString, Action> success, Action failure) { SearchAsync(searchString, string.Empty, success, failure); } - /// - /// Gets list of metadata for search string - /// - /// The search string - /// The path of the file or folder - /// Success call back - /// Failure call back public void SearchAsync(string searchString, string path, Action> success, Action failure) { var request = _requestHelper.CreateSearchRequest(searchString, path, Root); ExecuteAsync(ApiType.Base, request, success, failure); } - - - /// - /// Downloads a File from dropbox given the path - /// - /// The path of the file to download - /// /// Success callback - /// Failure callback public void GetFileAsync(string path, Action success, Action failure) { @@ -89,15 +53,6 @@ public void GetFileAsync(string path, Action success, Action - /// Downloads a part of a File from dropbox given the path - /// - /// The path of the file to download - /// The index of the first byte to get. - /// The index of the last byte to get. - /// Revision of the file - /// Success callback - /// Failure callback public void GetFileAsync(string path, long startByte, long endByte, string rev, Action success, Action failure) { if (!path.StartsWith("/")) path = "/" + path; @@ -108,14 +63,6 @@ public void GetFileAsync(string path, long startByte, long endByte, string rev, } #if !WINDOWS_PHONE && !MONOTOUCH && !WINRT - /// - /// Uploads a File to Dropbox from the local file system to the specified folder - /// - /// The path of the folder to upload to - /// The local file to upload/// Success callback - /// Failure callback - /// Specify wether the file upload should replace an existing file - /// The revision of the file you're editing public void UploadFileAsync(string path, FileInfo localFile, Action success, Action failure, bool overwrite = true, string parentRevision = null) { //Get the file stream @@ -133,16 +80,6 @@ public void UploadFileAsync(string path, FileInfo localFile, Action su } #endif - /// - /// Uploads a File to Dropbox given the raw data. - /// - /// The path of the folder to upload to - /// The Name of the file to upload to dropbox - /// The file data - /// Success callback - /// Failure callback - /// Specify wether the file upload should replace an existing file - /// The revision of the file you're editing public void UploadFileAsync(string path, string filename, byte[] fileData, Action success, Action failure, bool overwrite = true, string parentRevision = null) { if (path != "" && !path.StartsWith("/")) path = "/" + path; @@ -152,16 +89,6 @@ public void UploadFileAsync(string path, string filename, byte[] fileData, Actio ExecuteAsync(ApiType.Content, request, success, failure); } - /// - /// Uploads a File to Dropbox given the raw data. - /// - /// The path of the folder to upload to - /// The Name of the file to upload to dropbox - /// The file data - /// The callback Action to perform on completion - /// The callback Action to perform on exception - /// Specify wether the file upload should replace an existing file - /// The revision of the file you're editing public void UploadFileAsync(string path, string filename, Stream fileStream, Action success, Action failure, bool overwrite = true, string parentRevision = null) { if (path != "" && !path.StartsWith("/")) path = "/" + path; @@ -171,30 +98,12 @@ public void UploadFileAsync(string path, string filename, Stream fileStream, Act ExecuteAsync(ApiType.Content, request, success, failure); } - /// - /// Uploads a File to Dropbox in chunks that are assembled into a single file when finished. - /// - /// The callback function that returns a byte array given an offset - /// The full path of the file to upload to - /// The callback Action to perform on completion - /// The callback Action to perform on exception - /// The optional callback Action that receives upload progress - /// Specify wether the file upload should replace an existing file - /// The revision of the file you're editing - /// The total size of the file if available - /// The number of times to retry uploading if a chunk fails, unlimited if null. public void UploadChunkedFileAsync(Func chunkNeeded, string path, Action success, Action failure, Action progress = null, bool overwrite = true, string parentRevision = null, long? fileSize = null, long? maxRetries = null) { var chunkedUploader = new DropNet.Helpers.ChunkedUploadHelper(this, chunkNeeded, path, success, failure, progress, overwrite, parentRevision, fileSize, maxRetries); chunkedUploader.Start(); } - /// - /// Starts a chunked upload to Dropbox given a byte array. - /// - /// The file data - /// The callback Action to perform on completion - /// The callback Action to perform on exception public void StartChunkedUploadAsync(byte[] fileData, Action success, Action failure) { var request = _requestHelper.CreateChunkedUploadRequest(fileData); @@ -202,13 +111,6 @@ public void StartChunkedUploadAsync(byte[] fileData, Action succe ExecuteAsync(ApiType.Content, request, success, failure); } - /// - /// Add data to a chunked upload given a byte array. - /// - /// A ChunkedUpload object received from the StartChunkedUpload method - /// The file data - /// The callback Action to perform on completion - /// The callback Action to perform on exception public void AppendChunkedUploadAsync(ChunkedUpload upload, byte[] fileData, Action success, Action failure) { var request = _requestHelper.CreateAppendChunkedUploadRequest(upload, fileData); @@ -216,15 +118,6 @@ public void AppendChunkedUploadAsync(ChunkedUpload upload, byte[] fileData, Act ExecuteAsync(ApiType.Content, request, success, failure); } - /// - /// Commit a completed chunked upload - /// - /// A ChunkedUpload object received from the StartChunkedUpload method - /// The full path of the file to upload to - /// The callback Action to perform on completion - /// The callback Action to perform on exception - /// Specify wether the file upload should replace an existing file - /// The revision of the file you're editing public void CommitChunkedUploadAsync(ChunkedUpload upload, string path, Action success, Action failure, bool overwrite = true, string parentRevision = null) { var request = _requestHelper.CreateCommitChunkedUploadRequest(upload, path, Root, overwrite, parentRevision); @@ -232,12 +125,6 @@ public void CommitChunkedUploadAsync(ChunkedUpload upload, string path, Action - /// Deletes the file or folder from dropbox with the given path - /// - /// The Path of the file or folder to delete. - /// Success callback - /// Failure callback public void DeleteAsync(string path, Action success, Action failure) { if (path != "" && !path.StartsWith("/")) path = "/" + path; @@ -247,13 +134,6 @@ public void DeleteAsync(string path, Action success, Action - /// Copies a file or folder on Dropbox - /// - /// The path to the file or folder to copy - /// The path to where the file or folder is getting copied - /// Success callback - /// Failure callback public void CopyAsync(string fromPath, string toPath, Action success, Action failure) { if (!fromPath.StartsWith("/")) fromPath = "/" + fromPath; @@ -264,13 +144,6 @@ public void CopyAsync(string fromPath, string toPath, Action succ ExecuteAsync(ApiType.Base, request, success, failure); } - /// - /// Copies a file or folder on Dropbox using a copy_ref as the source. - /// - /// Specifies a copy_ref generated from a previous /copy_ref call - /// The path to where the file or folder is getting copied - /// Success callback - /// Failure callback public void CopyFromCopyRefAsync(string fromCopyRef, string toPath, Action success, Action failure) { if (!toPath.StartsWith("/")) toPath = "/" + toPath; @@ -280,13 +153,6 @@ public void CopyFromCopyRefAsync(string fromCopyRef, string toPath, Action - /// Moves a file or folder on Dropbox - /// - /// The path to the file or folder to move - /// The path to where the file or folder is getting moved - /// Success callback - /// Failure callback public void MoveAsync(string fromPath, string toPath, Action success, Action failure) { if (!fromPath.StartsWith("/")) fromPath = "/" + fromPath; @@ -297,12 +163,6 @@ public void MoveAsync(string fromPath, string toPath, Action succ ExecuteAsync(ApiType.Base, request, success, failure); } - /// - /// Creates a folder on Dropbox - /// - /// The path to the folder to create - /// Success callback - /// Failure callback public void CreateFolderAsync(string path, Action success, Action failure) { if (!path.StartsWith("/")) path = "/" + path; @@ -312,26 +172,11 @@ public void CreateFolderAsync(string path, Action success, Action - /// Creates and returns a shareable link to files or folders. - /// Note: Links created by the /shares API call expire after thirty days. - /// - /// The path - /// Success callback - /// Failure callback public void GetShareAsync(string path, Action success, Action failure) { GetShareAsync(path, true, success, failure); } - /// - /// Creates and returns a shareable link to files or folders. - /// Note: Links created by the /shares API call expire after thirty days. - /// - /// The path - /// True to shorten the share url - /// Success callback - /// Failure callback public void GetShareAsync(string path, bool shortUrl, Action success, Action failure) { if (!path.StartsWith("/")) path = "/" + path; @@ -341,13 +186,6 @@ public void GetShareAsync(string path, bool shortUrl, Action succ ExecuteAsync(ApiType.Base, request, success, failure); } - /// - /// Returns a link directly to a file. - /// Similar to /shares. The difference is that this bypasses the Dropbox webserver, used to provide a preview of the file, so that you can effectively stream the contents of your media. - /// - /// The path - /// Success callback - /// Failure callback public void GetMediaAsync(string path, Action success, Action failure) { if (!path.StartsWith("/")) path = "/" + path; @@ -357,13 +195,6 @@ public void GetMediaAsync(string path, Action success, Action - /// The beta delta function, gets updates for a given folder - /// - /// - /// - /// - /// public void GetDeltaAsync(bool IKnowThisIsBetaOnly, string path, Action success, Action failure) { if (!IKnowThisIsBetaOnly) return; @@ -375,47 +206,21 @@ public void GetDeltaAsync(bool IKnowThisIsBetaOnly, string path, Action(ApiType.Base, request, success, failure); } - /// - /// Gets the thumbnail of an image given its MetaData - /// - /// The MetaData - /// Success callback - /// Failure callback public void GetThumbnailAsync(MetaData file, Action success, Action failure) { GetThumbnailAsync(file.Path, ThumbnailSize.Small, success, failure); } - /// - /// Gets the thumbnail of an image given its MetaData - /// - /// The metadat file - /// Thumbnail size - /// success callback - /// Failure callback public void GetThumbnailAsync(MetaData file, ThumbnailSize size, Action success, Action failure) { GetThumbnailAsync(file.Path, size, success, failure); } - /// - /// Gets the thumbnail of an image given its path - /// - /// The path - /// success callback - /// failure callback public void GetThumbnailAsync(string path, Action success, Action failure) { GetThumbnailAsync(path, ThumbnailSize.Small, success, failure); } - /// - /// Gets the thumbnail of an image given its path - /// - /// The path - /// Thumbnail size - /// success callback - /// failure callback public void GetThumbnailAsync(string path, ThumbnailSize size, Action success, Action failure) { if (!path.StartsWith("/")) path = "/" + path; @@ -427,14 +232,6 @@ public void GetThumbnailAsync(string path, ThumbnailSize size, Action su failure); } - /// - /// Creates and returns a copy_ref to a file. - /// - /// This reference string can be used to copy that file to another user's Dropbox by passing it in as the from_copy_ref parameter on /fileops/copy. - /// - /// The path - /// Success callback - /// Failure callback public void GetCopyRefAsync(string path, Action success, Action failure) { if (!path.StartsWith("/")) path = "/" + path; diff --git a/DropNet/Client/Files.Sync.cs b/DropNet/Client/Files.Sync.cs index e82b1e5..ae72583 100644 --- a/DropNet/Client/Files.Sync.cs +++ b/DropNet/Client/Files.Sync.cs @@ -14,21 +14,11 @@ namespace DropNet { public partial class DropNetClient { - - /// - /// Gets MetaData for the root folder. - /// - /// public MetaData GetMetaData() { return GetMetaData(string.Empty); } - /// - /// Gets MetaData for a File or Folder. For a folder this includes its contents. For a file, this includes details such as file size. - /// - /// The path of the file or folder - /// public MetaData GetMetaData(string path) { if (path != "" && !path.StartsWith("/")) path = "/" + path; @@ -38,12 +28,6 @@ public MetaData GetMetaData(string path) return Execute(ApiType.Base, request); } - /// - /// Gets List of MetaData for a File versions. Each metadata item contains info about file in certain version on Dropbox. - /// - /// The path of the file - /// Maximal number of versions to fetch. - /// public List GetVersions(string path, int limit) { var request = _requestHelper.CreateVersionsRequest(path, Root, limit); @@ -51,20 +35,11 @@ public List GetVersions(string path, int limit) return Execute>(ApiType.Base, request); } - /// - /// Gets list of metadata for search string - /// - /// The search string public List Search(string searchString) { return Search(searchString, string.Empty); } - /// - /// Gets list of metadata for search string - /// - /// The search string - /// The path of the file or folder public List Search(string searchString, string path) { var request = _requestHelper.CreateSearchRequest(searchString, path, Root); @@ -73,11 +48,6 @@ public List Search(string searchString, string path) } //TODO - Make class for this to return (instead of just a byte[]) - /// - /// Downloads a File from dropbox given the path - /// - /// The path of the file to download - /// The files raw bytes public byte[] GetFile(string path) { if (!path.StartsWith("/")) @@ -92,14 +62,6 @@ public byte[] GetFile(string path) } //TODO - Make class for this to return (instead of just a byte[]) - /// - /// Downloads a part of a File from dropbox given the path and a revision token. - /// - /// The path of the file to download - /// The index of the first byte to get. - /// The index of the last byte to get. - /// Revision string as featured by MetaData.Rev - /// The files raw bytes between and . public byte[] GetFile(string path, long startByte, long endByte, string rev) { if (!path.StartsWith("/")) @@ -113,11 +75,6 @@ public byte[] GetFile(string path, long startByte, long endByte, string rev) return response.RawBytes; } - /// - /// Retrieve the content of a file in the local file system - /// - /// The local file to upload - /// True on success public byte[] GetFileContentFromFS(FileInfo localFile) { //Get the file stream @@ -137,15 +94,6 @@ public byte[] GetFileContentFromFS(FileInfo localFile) return bytes; } - /// - /// Uploads a File to Dropbox given the raw data. - /// - /// The path of the folder to upload to - /// The Name of the file to upload to dropbox - /// The file data - /// Specify wether the file upload should replace an existing file - /// The revision of the file you're editing - /// True on success public MetaData UploadFilePUT(string path, string filename, byte[] fileData, bool overwrite = true, string parentRevision = null) { if (!path.StartsWith("/")) @@ -159,15 +107,6 @@ public MetaData UploadFilePUT(string path, string filename, byte[] fileData, boo return response.Data; } - /// - /// Uploads a File to Dropbox given the raw data. - /// - /// The path of the folder to upload to - /// The Name of the file to upload to dropbox - /// The file data - /// Specify wether the file upload should replace an existing file - /// The revision of the file you're editing - /// True on success public MetaData UploadFile(string path, string filename, byte[] fileData, bool overwrite = true, string parentRevision = null) { if (!path.StartsWith("/")) @@ -181,15 +120,6 @@ public MetaData UploadFile(string path, string filename, byte[] fileData, bool o return response.Data; } - /// - /// Uploads a File to Dropbox given the raw data. - /// - /// The path of the folder to upload to - /// The Name of the file to upload to dropbox - /// The file stream - /// Specify wether the file upload should replace an existing file - /// The revision of the file you're editing - /// True on success public MetaData UploadFile(string path, string filename, Stream stream, bool overwrite = true, string parentRevision = null) { if (!path.StartsWith("/")) @@ -203,11 +133,6 @@ public MetaData UploadFile(string path, string filename, Stream stream, bool ove return response.Data; } - /// - /// Starts a chunked upload to Dropbox given a byte array. - /// - /// The file data - /// A object representing the chunked upload on success public ChunkedUpload StartChunkedUpload(byte[] fileData) { var request = _requestHelper.CreateChunkedUploadRequest(fileData); @@ -215,12 +140,6 @@ public ChunkedUpload StartChunkedUpload(byte[] fileData) return response.Data; } - /// - /// Add data to a chunked upload given a byte array. - /// - /// A ChunkedUpload object received from the StartChunkedUpload method - /// The file data - /// A object representing the chunked upload on success public ChunkedUpload AppendChunkedUpload(ChunkedUpload upload, byte[] fileData) { var request = _requestHelper.CreateAppendChunkedUploadRequest(upload, fileData); @@ -228,14 +147,6 @@ public ChunkedUpload AppendChunkedUpload(ChunkedUpload upload, byte[] fileData) return response.Data; } - /// - /// Commit a completed chunked upload - /// - /// A ChunkedUpload object received from the StartChunkedUpload method - /// The full path of the file to upload to - /// Specify wether the file upload should replace an existing file - /// The revision of the file you're editing - /// A object representing the chunked upload on success public MetaData CommitChunkedUpload(ChunkedUpload upload, string path, bool overwrite = true, string parentRevision = null) { var request = _requestHelper.CreateCommitChunkedUploadRequest(upload, path, Root, overwrite, parentRevision); @@ -243,11 +154,6 @@ public MetaData CommitChunkedUpload(ChunkedUpload upload, string path, bool over return response.Data; } - /// - /// Deletes the file or folder from dropbox with the given path - /// - /// The Path of the file or folder to delete. - /// public MetaData Delete(string path) { if (!path.StartsWith("/")) @@ -258,12 +164,6 @@ public MetaData Delete(string path) return Execute(ApiType.Base, request); } - /// - /// Copies a file or folder on Dropbox - /// - /// The path to the file or folder to copy - /// The path to where the file or folder is getting copied - /// True on success public MetaData Copy(string fromPath, string toPath) { if (!fromPath.StartsWith("/")) @@ -280,12 +180,6 @@ public MetaData Copy(string fromPath, string toPath) return Execute(ApiType.Base, request); } - /// - /// Copies a file or folder on Dropbox using a copy_ref as the source. - /// - /// Specifies a copy_ref generated from a previous /copy_ref call - /// The path to where the file or folder is getting copied - /// True on success public MetaData CopyFromCopyRef(string fromCopyRef, string toPath) { if (!toPath.StartsWith("/")) @@ -297,12 +191,6 @@ public MetaData CopyFromCopyRef(string fromCopyRef, string toPath) return Execute(ApiType.Base, request); } - /// - /// Moves a file or folder on Dropbox - /// - /// The path to the file or folder to move - /// The path to where the file or folder is getting moved - /// True on success public MetaData Move(string fromPath, string toPath) { if (!fromPath.StartsWith("/")) @@ -319,11 +207,6 @@ public MetaData Move(string fromPath, string toPath) return Execute(ApiType.Base, request); } - /// - /// Creates a folder on Dropbox - /// - /// The path to the folder to create - /// MetaData of the newly created folder public MetaData CreateFolder(string path) { if (!path.StartsWith("/")) @@ -335,12 +218,6 @@ public MetaData CreateFolder(string path) return Execute(ApiType.Base, request); } - /// - /// Creates and returns a shareable link to files or folders. - /// Note: Links created by the /shares API call expire after thirty days. - /// - /// - /// public ShareResponse GetShare(string path, bool shortUrl = true) { if (!path.StartsWith("/")) @@ -353,12 +230,6 @@ public ShareResponse GetShare(string path, bool shortUrl = true) return Execute(ApiType.Base, request); } - /// - /// Returns a link directly to a file. - /// Similar to /shares. The difference is that this bypasses the Dropbox webserver, used to provide a preview of the file, so that you can effectively stream the contents of your media. - /// - /// - /// public ShareResponse GetMedia(string path) { if (!path.StartsWith("/")) @@ -370,43 +241,21 @@ public ShareResponse GetMedia(string path) return Execute(ApiType.Base, request); } - /// - /// Gets the thumbnail of an image given its MetaData - /// - /// - /// public byte[] GetThumbnail(MetaData file) { return GetThumbnail(file.Path, ThumbnailSize.Small); } - /// - /// Gets the thumbnail of an image given its MetaData - /// - /// - /// - /// public byte[] GetThumbnail(MetaData file, ThumbnailSize size) { return GetThumbnail(file.Path, size); } - /// - /// Gets the thumbnail of an image given its path - /// - /// - /// public byte[] GetThumbnail(string path) { return GetThumbnail(path, ThumbnailSize.Small); } - /// - /// Gets the thumbnail of an image given its path - /// - /// The path to the picture - /// The size to return the thumbnail - /// public byte[] GetThumbnail(string path, ThumbnailSize size) { if (!path.StartsWith("/")) @@ -420,13 +269,6 @@ public byte[] GetThumbnail(string path, ThumbnailSize size) return response.RawBytes; } - /// - /// Creates and returns a copy_ref to a file. - /// - /// This reference string can be used to copy that file to another user's Dropbox by passing it in as the from_copy_ref parameter on /fileops/copy. - /// - /// - /// public CopyRefResponse GetCopyRef(string path) { if (!path.StartsWith("/")) @@ -438,11 +280,6 @@ public CopyRefResponse GetCopyRef(string path) return Execute(ApiType.Base, request); } - /// - /// Gets the deltas for a user's folders and files. - /// - /// The value returned from the prior call to GetDelta or an empty string - /// public DeltaPage GetDelta(string cursor) { var request = _requestHelper.CreateDeltaRequest(cursor); @@ -465,11 +302,6 @@ public DeltaPage GetDelta(string cursor) return deltaPage; } - /// - /// Helper function to convert a stringlist to a DeltaEntry object - /// - /// - /// private DeltaEntry StringListToDeltaEntry(List stringList) { var deltaEntry = new DeltaEntry @@ -488,9 +320,6 @@ private DeltaEntry StringListToDeltaEntry(List stringList) return deltaEntry; } - /// - /// Private class used to deal with the DropBox API returning two different types in a given list - /// private class DeltaPageInternal { public string Cursor { get; set; } diff --git a/DropNet/Client/IClient.cs b/DropNet/Client/IClient.cs new file mode 100644 index 0000000..cb1aa87 --- /dev/null +++ b/DropNet/Client/IClient.cs @@ -0,0 +1,608 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Threading.Tasks; +using DropNet.Authenticators; +using DropNet.Exceptions; +using DropNet.Models; + +using RestSharp; + +namespace DropNet +{ + public interface IDropNetClient + { + /// + /// Contains the Users Token and Secret + /// + UserLogin UserLogin { get; set; } + + /// + /// To use Dropbox API in sandbox mode (app folder access) set to true + /// + bool UseSandbox { get; set; } + +#if !WINDOWS_PHONE && !WINRT + IWebProxy Proxy { get; set; } +#endif + + /// + /// Helper Method to Build up the Url to authorize a Token/Secret + /// + /// + /// + string BuildAuthorizeUrl(string callback = null); + + /// + /// Helper Method to Build up the Url to authorize a Token/Secret + /// + /// + /// + /// + string BuildAuthorizeUrl(UserLogin userLogin, string callback = null); + + /// + /// This starts the OAuth 2.0 authorization flow. This isn't an API call—it's the web page that lets the user sign in to Dropbox and authorize your app. The user must be redirected to the page over HTTPS and it should be presented to the user through their web browser. After the user decides whether or not to authorize your app, they will be redirected to the URL specified by the 'redirectUri'. + /// + /// The type of authorization flow to use. See the OAuth2AuthorizationFlow enum documentation for more information. + /// Where to redirect the user after authorization has completed. This must be the exact URI registered in the app console (https://www.dropbox.com/developers/apps), though localhost and 127.0.0.1 are always accepted. A redirect URI is required for a token flow, but optional for code. If the redirect URI is omitted, the code will be presented directly to the user and they will be invited to enter the information in your app. + /// Arbitrary data that will be passed back to your redirect URI. This parameter can be used to track a user through the authorization flow in order to prevent cross-site request forgery (CRSF) attacks. + /// A URL to which your app should redirect the user for authorization. After the user authorizes your app, they will be sent to your redirect URI. The type of response varies based on the 'oauth2AuthorizationFlow' argument. . + string BuildAuthorizeUrl(OAuth2AuthorizationFlow oAuth2AuthorizationFlow, string redirectUri, string state = null); + + /// + /// Gets MetaData for a File or Folder. For a folder this includes its contents. For a file, this includes details such as file size. + /// + /// The path of the file or folder + /// Success call back + /// Failure call back + void GetMetaDataAsync(string path, Action success, Action failure); + + /// + /// Gets MetaData for a File or Folder. For a folder this includes its contents. For a file, this includes details such as file size. + /// Optional 'hash' param returns HTTP code 304 (Directory contents have not changed) if contents have not changed since the + /// hash was retrieved on a previous call. + /// + /// The path of the file or folder + /// hash - Optional. Listing return values include a hash representing the state of the directory's contents. If you provide this argument to the metadata call, you give the service an opportunity to respond with a "304 Not Modified" status code instead of a full (potentially very large) directory listing. This argument is ignored if the specified path is associated with a file or if list=false. + /// Success callback + /// Failure callback + void GetMetaDataAsync(string path, string hash, Action success, Action failure); + + /// + /// Gets list of metadata for search string + /// + /// The search string + /// Success call back + /// Failure call back + void SearchAsync(string searchString, Action> success, Action failure); + + /// + /// Gets list of metadata for search string + /// + /// The search string + /// The path of the file or folder + /// Success call back + /// Failure call back + void SearchAsync(string searchString, string path, Action> success, Action failure); + + /// + /// Downloads a File from dropbox given the path + /// + /// The path of the file to download + /// /// Success callback + /// Failure callback + void GetFileAsync(string path, Action success, Action failure); + + /// + /// Downloads a part of a File from dropbox given the path + /// + /// The path of the file to download + /// The index of the first byte to get. + /// The index of the last byte to get. + /// Revision of the file + /// Success callback + /// Failure callback + void GetFileAsync(string path, long startByte, long endByte, string rev, Action success, Action failure); + +#if !WINDOWS_PHONE && !MONOTOUCH && !WINRT + /// + /// Uploads a File to Dropbox from the local file system to the specified folder + /// + /// The path of the folder to upload to + /// The local file to upload/// Success callback + /// Failure callback + /// Specify wether the file upload should replace an existing file + /// The revision of the file you're editing + void UploadFileAsync(string path, FileInfo localFile, Action success, Action failure, bool overwrite = true, string parentRevision = null); +#endif + + /// + /// Uploads a File to Dropbox given the raw data. + /// + /// The path of the folder to upload to + /// The Name of the file to upload to dropbox + /// The file data + /// Success callback + /// Failure callback + /// Specify wether the file upload should replace an existing file + /// The revision of the file you're editing + void UploadFileAsync(string path, string filename, byte[] fileData, Action success, Action failure, bool overwrite = true, string parentRevision = null); + + /// + /// Uploads a File to Dropbox given the raw data. + /// + /// The path of the folder to upload to + /// The Name of the file to upload to dropbox + /// The file data + /// The callback Action to perform on completion + /// The callback Action to perform on exception + /// Specify wether the file upload should replace an existing file + /// The revision of the file you're editing + void UploadFileAsync(string path, string filename, Stream fileStream, Action success, Action failure, bool overwrite = true, string parentRevision = null); + + /// + /// Uploads a File to Dropbox in chunks that are assembled into a single file when finished. + /// + /// The callback function that returns a byte array given an offset + /// The full path of the file to upload to + /// The callback Action to perform on completion + /// The callback Action to perform on exception + /// The optional callback Action that receives upload progress + /// Specify wether the file upload should replace an existing file + /// The revision of the file you're editing + /// The total size of the file if available + /// The number of times to retry uploading if a chunk fails, unlimited if null. + void UploadChunkedFileAsync(Func chunkNeeded, string path, Action success, Action failure, Action progress = null, bool overwrite = true, string parentRevision = null, long? fileSize = null, long? maxRetries = null); + + /// + /// Starts a chunked upload to Dropbox given a byte array. + /// + /// The file data + /// The callback Action to perform on completion + /// The callback Action to perform on exception + void StartChunkedUploadAsync(byte[] fileData, Action success, Action failure); + + /// + /// Add data to a chunked upload given a byte array. + /// + /// A ChunkedUpload object received from the StartChunkedUpload method + /// The file data + /// The callback Action to perform on completion + /// The callback Action to perform on exception + void AppendChunkedUploadAsync(ChunkedUpload upload, byte[] fileData, Action success, Action failure); + + /// + /// Commit a completed chunked upload + /// + /// A ChunkedUpload object received from the StartChunkedUpload method + /// The full path of the file to upload to + /// The callback Action to perform on completion + /// The callback Action to perform on exception + /// Specify wether the file upload should replace an existing file + /// The revision of the file you're editing + void CommitChunkedUploadAsync(ChunkedUpload upload, string path, Action success, Action failure, bool overwrite = true, string parentRevision = null); + + /// + /// Deletes the file or folder from dropbox with the given path + /// + /// The Path of the file or folder to delete. + /// Success callback + /// Failure callback + void DeleteAsync(string path, Action success, Action failure); + + /// + /// Copies a file or folder on Dropbox + /// + /// The path to the file or folder to copy + /// The path to where the file or folder is getting copied + /// Success callback + /// Failure callback + void CopyAsync(string fromPath, string toPath, Action success, Action failure); + + /// + /// Copies a file or folder on Dropbox using a copy_ref as the source. + /// + /// Specifies a copy_ref generated from a previous /copy_ref call + /// The path to where the file or folder is getting copied + /// Success callback + /// Failure callback + void CopyFromCopyRefAsync(string fromCopyRef, string toPath, Action success, Action failure); + + /// + /// Moves a file or folder on Dropbox + /// + /// The path to the file or folder to move + /// The path to where the file or folder is getting moved + /// Success callback + /// Failure callback + void MoveAsync(string fromPath, string toPath, Action success, Action failure); + + /// + /// Creates a folder on Dropbox + /// + /// The path to the folder to create + /// Success callback + /// Failure callback + void CreateFolderAsync(string path, Action success, Action failure); + + /// + /// Creates and returns a shareable link to files or folders. + /// Note: Links created by the /shares API call expire after thirty days. + /// + /// The path + /// Success callback + /// Failure callback + void GetShareAsync(string path, Action success, Action failure); + + /// + /// Creates and returns a shareable link to files or folders. + /// Note: Links created by the /shares API call expire after thirty days. + /// + /// The path + /// True to shorten the share url + /// Success callback + /// Failure callback + void GetShareAsync(string path, bool shortUrl, Action success, Action failure); + + /// + /// Returns a link directly to a file. + /// Similar to /shares. The difference is that this bypasses the Dropbox webserver, used to provide a preview of the file, so that you can effectively stream the contents of your media. + /// + /// The path + /// Success callback + /// Failure callback + void GetMediaAsync(string path, Action success, Action failure); + + /// + /// The beta delta function, gets updates for a given folder + /// + /// + /// + /// + /// + void GetDeltaAsync(bool IKnowThisIsBetaOnly, string path, Action success, Action failure); + + /// + /// Gets the thumbnail of an image given its MetaData + /// + /// The MetaData + /// Success callback + /// Failure callback + void GetThumbnailAsync(MetaData file, Action success, Action failure); + + /// + /// Gets the thumbnail of an image given its MetaData + /// + /// The metadat file + /// Thumbnail size + /// success callback + /// Failure callback + void GetThumbnailAsync(MetaData file, ThumbnailSize size, Action success, Action failure); + + /// + /// Gets the thumbnail of an image given its path + /// + /// The path + /// success callback + /// failure callback + void GetThumbnailAsync(string path, Action success, Action failure); + + /// + /// Gets the thumbnail of an image given its path + /// + /// The path + /// Thumbnail size + /// success callback + /// failure callback + void GetThumbnailAsync(string path, ThumbnailSize size, Action success, Action failure); + + /// + /// Creates and returns a copy_ref to a file. + /// + /// This reference string can be used to copy that file to another user's Dropbox by passing it in as the from_copy_ref parameter on /fileops/copy. + /// + /// The path + /// Success callback + /// Failure callback + void GetCopyRefAsync(string path, Action success, Action failure); + + Task GetMetaDataTask(string path); + Task GetMetaDataTask(string path, string hash); + Task> SearchTask(string searchString); + Task> SearchTask(string searchString, string path); + Task GetFileTask(string path); + Task UploadFileTask(string path, string filename, byte[] fileData, bool overwrite = true, string parentRevision = null); + Task UploadFileTask(string path, string filename, Stream fileStream, bool overwrite = true, string parentRevision = null); + Task DeleteTask(string path); + Task CopyTask(string fromPath, string toPath); + Task CopyFromCopyRefTask(string fromCopyRef, string toPath); + Task MoveTask(string fromPath, string toPath); + Task CreateFolderTask(string path, Action success, Action failure); + Task GetShareTask(string path, bool shortUrl = true); + Task GetMediaTask(string path); + Task GetThumbnailTask(MetaData file); + Task GetThumbnailTask(MetaData file, ThumbnailSize size); + Task GetThumbnailTask(string path); + Task GetThumbnailTask(string path, ThumbnailSize size); + Task GetCopyRefTask(string path); + +#if !WINDOWS_PHONE + /// + /// Gets MetaData for the root folder. + /// + /// + MetaData GetMetaData(); + + /// + /// Gets MetaData for a File or Folder. For a folder this includes its contents. For a file, this includes details such as file size. + /// + /// The path of the file or folder + /// + MetaData GetMetaData(string path); + + /// + /// Gets List of MetaData for a File versions. Each metadata item contains info about file in certain version on Dropbox. + /// + /// The path of the file + /// Maximal number of versions to fetch. + /// + List GetVersions(string path, int limit); + + /// + /// Gets list of metadata for search string + /// + /// The search string + List Search(string searchString); + + /// + /// Gets list of metadata for search string + /// + /// The search string + /// The path of the file or folder + List Search(string searchString, string path); + + /// + /// Downloads a File from dropbox given the path + /// + /// The path of the file to download + /// The files raw bytes + byte[] GetFile(string path); + + /// + /// Downloads a part of a File from dropbox given the path and a revision token. + /// + /// The path of the file to download + /// The index of the first byte to get. + /// The index of the last byte to get. + /// Revision string as featured by MetaData.Rev + /// The files raw bytes between and . + byte[] GetFile(string path, long startByte, long endByte, string rev); + + /// + /// Retrieve the content of a file in the local file system + /// + /// The local file to upload + /// True on success + byte[] GetFileContentFromFS(FileInfo localFile); + + /// + /// Uploads a File to Dropbox given the raw data. + /// + /// The path of the folder to upload to + /// The Name of the file to upload to dropbox + /// The file data + /// Specify wether the file upload should replace an existing file + /// The revision of the file you're editing + /// True on success + MetaData UploadFilePUT(string path, string filename, byte[] fileData, bool overwrite = true, string parentRevision = null); + + /// + /// Uploads a File to Dropbox given the raw data. + /// + /// The path of the folder to upload to + /// The Name of the file to upload to dropbox + /// The file data + /// Specify wether the file upload should replace an existing file + /// The revision of the file you're editing + /// True on success + MetaData UploadFile(string path, string filename, byte[] fileData, bool overwrite = true, string parentRevision = null); + + /// + /// Uploads a File to Dropbox given the raw data. + /// + /// The path of the folder to upload to + /// The Name of the file to upload to dropbox + /// The file stream + /// Specify wether the file upload should replace an existing file + /// The revision of the file you're editing + /// True on success + MetaData UploadFile(string path, string filename, Stream stream, bool overwrite = true, string parentRevision = null); + + /// + /// Starts a chunked upload to Dropbox given a byte array. + /// + /// The file data + /// A object representing the chunked upload on success + ChunkedUpload StartChunkedUpload(byte[] fileData); + + /// + /// Add data to a chunked upload given a byte array. + /// + /// A ChunkedUpload object received from the StartChunkedUpload method + /// The file data + /// A object representing the chunked upload on success + ChunkedUpload AppendChunkedUpload(ChunkedUpload upload, byte[] fileData); + + /// + /// Commit a completed chunked upload + /// + /// A ChunkedUpload object received from the StartChunkedUpload method + /// The full path of the file to upload to + /// Specify wether the file upload should replace an existing file + /// The revision of the file you're editing + /// A object representing the chunked upload on success + MetaData CommitChunkedUpload(ChunkedUpload upload, string path, bool overwrite = true, string parentRevision = null); + + /// + /// Deletes the file or folder from dropbox with the given path + /// + /// The Path of the file or folder to delete. + /// + MetaData Delete(string path); + + /// + /// Copies a file or folder on Dropbox + /// + /// The path to the file or folder to copy + /// The path to where the file or folder is getting copied + /// True on success + MetaData Copy(string fromPath, string toPath); + + /// + /// Copies a file or folder on Dropbox using a copy_ref as the source. + /// + /// Specifies a copy_ref generated from a previous /copy_ref call + /// The path to where the file or folder is getting copied + /// True on success + MetaData CopyFromCopyRef(string fromCopyRef, string toPath); + + /// + /// Moves a file or folder on Dropbox + /// + /// The path to the file or folder to move + /// The path to where the file or folder is getting moved + /// True on success + MetaData Move(string fromPath, string toPath); + + /// + /// Creates a folder on Dropbox + /// + /// The path to the folder to create + /// MetaData of the newly created folder + MetaData CreateFolder(string path); + + /// + /// Creates and returns a shareable link to files or folders. + /// Note: Links created by the /shares API call expire after thirty days. + /// + /// + /// + ShareResponse GetShare(string path, bool shortUrl = true); + + /// + /// Returns a link directly to a file. + /// Similar to /shares. The difference is that this bypasses the Dropbox webserver, used to provide a preview of the file, so that you can effectively stream the contents of your media. + /// + /// + /// + ShareResponse GetMedia(string path); + + /// + /// Gets the thumbnail of an image given its MetaData + /// + /// + /// + byte[] GetThumbnail(MetaData file); + + /// + /// Gets the thumbnail of an image given its MetaData + /// + /// + /// + /// + byte[] GetThumbnail(MetaData file, ThumbnailSize size); + + /// + /// Gets the thumbnail of an image given its path + /// + /// + /// + byte[] GetThumbnail(string path); + + /// + /// Gets the thumbnail of an image given its path + /// + /// The path to the picture + /// The size to return the thumbnail + /// + byte[] GetThumbnail(string path, ThumbnailSize size); + + /// + /// Creates and returns a copy_ref to a file. + /// + /// This reference string can be used to copy that file to another user's Dropbox by passing it in as the from_copy_ref parameter on /fileops/copy. + /// + /// + /// + CopyRefResponse GetCopyRef(string path); + + /// + /// Gets the deltas for a user's folders and files. + /// + /// The value returned from the prior call to GetDelta or an empty string + /// + DeltaPage GetDelta(string cursor); + + /// + /// Shorthand method to get an OAuth1 token from Dropbox and build the Url to authorize it. + /// + /// + string GetTokenAndBuildUrl(string callback = null); + + /// + /// Provisions an OAuth1 token from the almightly dropbox.com (Token cant be used until authorized!) + /// + /// + UserLogin GetToken(); + + /// + /// Authorizes the previously-requested OAuth1 token + /// + /// + UserLogin GetAccessToken(); + + /// + /// Acquire an OAuth2 bearer token once the user has authorized the app. This endpoint only applies to apps using the AuthorizationFlow.Code flow. + /// + /// The authorization code provided by Dropbox when the user was redirected back to your site. + /// The redirect Uri for your site. This is only used to validate that it matches the original /oauth2/authorize; the user will not be redirected again. + /// An OAuth2 bearer token. + UserLogin GetAccessToken(string code, string redirectUri); + + AccountInfo AccountInfo(); +#endif + + /// + /// Gets a token from the almightly dropbox.com (Token cant be used until authorized!) + /// + void GetTokenAsync(Action success, Action failure); + + /// + /// Converts a request token into an Access token after the user has authorized access via dropbox.com + /// + /// + /// + void GetAccessTokenAsync(Action success, Action failure); + + /// + /// Acquire an OAuth2 bearer token once the user has authorized the app. This endpoint only applies to apps using the AuthorizationFlow.Code flow. + /// + /// Action to perform with the OAuth2 access token + /// + /// The authorization code provided by Dropbox when the user was redirected back to your site. + /// The redirect Uri for your site. This is only used to validate that it matches the original /oauth2/authorize; the user will not be redirected again. + void GetAccessTokenAsync(Action success, Action failure, string code, string redirectUri); + + /// + /// Gets AccountInfo + /// + /// + /// + void AccountInfoAsync(Action success, Action failure); + + [Obsolete("No longer supported by Dropbox")] + void CreateAccountAsync(string email, string firstName, string lastName, string password, Action success, Action failure); + } +} \ No newline at end of file diff --git a/DropNet/Client/User.Async.cs b/DropNet/Client/User.Async.cs index 09b53a5..384c1c9 100644 --- a/DropNet/Client/User.Async.cs +++ b/DropNet/Client/User.Async.cs @@ -8,9 +8,6 @@ namespace DropNet { public partial class DropNetClient { - /// - /// Gets a token from the almightly dropbox.com (Token cant be used until authorized!) - /// public void GetTokenAsync(Action success, Action failure) { var request = _requestHelper.CreateTokenRequest(); @@ -22,11 +19,6 @@ public void GetTokenAsync(Action success, Action fa }, failure); } - /// - /// Converts a request token into an Access token after the user has authorized access via dropbox.com - /// - /// - /// public void GetAccessTokenAsync(Action success, Action failure) { var request = _requestHelper.CreateAccessTokenRequest(); @@ -38,14 +30,6 @@ public void GetAccessTokenAsync(Action success, Action - /// Acquire an OAuth2 bearer token once the user has authorized the app. This endpoint only applies to apps using the AuthorizationFlow.Code flow. - /// - /// Action to perform with the OAuth2 access token - /// - /// The authorization code provided by Dropbox when the user was redirected back to your site. - /// The redirect Uri for your site. This is only used to validate that it matches the original /oauth2/authorize; the user will not be redirected again. public void GetAccessTokenAsync(Action success, Action failure, string code, string redirectUri) { RestRequest request = _requestHelper.CreateOAuth2AccessTokenRequest(code, redirectUri, _apiKey, _appsecret); @@ -57,11 +41,6 @@ public void GetAccessTokenAsync(Action success, Action - /// Gets AccountInfo - /// - /// - /// public void AccountInfoAsync(Action success, Action failure) { //This has to be here as Dropbox change their base URL between calls diff --git a/DropNet/Client/User.Sync.cs b/DropNet/Client/User.Sync.cs index a4ee4bc..27d0a65 100644 --- a/DropNet/Client/User.Sync.cs +++ b/DropNet/Client/User.Sync.cs @@ -9,20 +9,12 @@ namespace DropNet { public partial class DropNetClient { - /// - /// Shorthand method to get an OAuth1 token from Dropbox and build the Url to authorize it. - /// - /// public string GetTokenAndBuildUrl(string callback = null) { GetToken(); return BuildAuthorizeUrl(callback); } - /// - /// Provisions an OAuth1 token from the almightly dropbox.com (Token cant be used until authorized!) - /// - /// public UserLogin GetToken() { var request = _requestHelper.CreateTokenRequest(); @@ -32,10 +24,6 @@ public UserLogin GetToken() return userLogin; } - /// - /// Authorizes the previously-requested OAuth1 token - /// - /// public UserLogin GetAccessToken() { var request = _requestHelper.CreateAccessTokenRequest(); @@ -46,12 +34,6 @@ public UserLogin GetAccessToken() return userLogin; } - /// - /// Acquire an OAuth2 bearer token once the user has authorized the app. This endpoint only applies to apps using the AuthorizationFlow.Code flow. - /// - /// The authorization code provided by Dropbox when the user was redirected back to your site. - /// The redirect Uri for your site. This is only used to validate that it matches the original /oauth2/authorize; the user will not be redirected again. - /// An OAuth2 bearer token. public UserLogin GetAccessToken(string code, string redirectUri) { RestRequest request = _requestHelper.CreateOAuth2AccessTokenRequest(code, redirectUri, _apiKey, _appsecret); diff --git a/DropNet/DropNet.csproj b/DropNet/DropNet.csproj index d53ab79..5f6f163 100644 --- a/DropNet/DropNet.csproj +++ b/DropNet/DropNet.csproj @@ -68,6 +68,7 @@ + From 72f6fe9568b177f6e33b330186c439b9a25ffff7 Mon Sep 17 00:00:00 2001 From: Jason Smith Date: Mon, 13 Jan 2014 13:47:02 +1100 Subject: [PATCH 07/43] Improvements to DropboxException. Improvements to DropboxException. Split out the base exception class and added descendant DropboxRestException. Also update message returned by DropboxRestException to have more information as to what caused the exception. This will break on compile as DropboxException does not have StatusCode or Response properties. --- DropNet/Client/Client.cs | 16 +++--- DropNet/Exceptions/DropboxException.cs | 58 ++++++++++++++++++---- DropNet/Extensions/RestClientExtensions.cs | 4 +- 3 files changed, 58 insertions(+), 20 deletions(-) diff --git a/DropNet/Client/Client.cs b/DropNet/Client/Client.cs index c6d00d3..f7a2bb2 100644 --- a/DropNet/Client/Client.cs +++ b/DropNet/Client/Client.cs @@ -132,7 +132,7 @@ public string BuildAuthorizeUrl(OAuth2AuthorizationFlow oAuth2AuthorizationFlow, if (response.StatusCode != HttpStatusCode.OK) { - throw new DropboxException(response); + throw new DropboxRestException(response, HttpStatusCode.OK); } } else @@ -141,7 +141,7 @@ public string BuildAuthorizeUrl(OAuth2AuthorizationFlow oAuth2AuthorizationFlow, if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.PartialContent) { - throw new DropboxException(response); + throw new DropboxRestException(response, HttpStatusCode.OK, HttpStatusCode.PartialContent); } } @@ -157,7 +157,7 @@ private IRestResponse Execute(ApiType apiType, IRestRequest request) if (response.StatusCode != HttpStatusCode.OK) { - throw new DropboxException(response); + throw new DropboxRestException(response, HttpStatusCode.OK); } } else @@ -166,7 +166,7 @@ private IRestResponse Execute(ApiType apiType, IRestRequest request) if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.PartialContent) { - throw new DropboxException(response); + throw new DropboxRestException(response, HttpStatusCode.OK, HttpStatusCode.PartialContent); } } @@ -194,7 +194,7 @@ private void ExecuteAsync(ApiType apiType, IRestRequest request, Action - /// The response of the error call (for Debugging use) - /// - public IRestResponse Response { get; private set; } - public DropboxException() { + } - public DropboxException(string message) - : base(message) + public DropboxException(string message) : base(message) { + } + } + public class DropboxRestException : DropboxException + { + /// + /// Returned status code from the request + /// + public HttpStatusCode StatusCode { get; private set; } + + /// + /// Expected status codes to have seen instead of the one recieved. + /// + public HttpStatusCode[] ExpectedCodes { get; private set; } + + /// + /// The response of the error call (for Debugging use) + /// + public IRestResponse Response { get; private set; } + + public DropboxRestException(string message) : base(message) + { } - public DropboxException(IRestResponse r) + /// + /// Creates a DropboxRestException with the rest response which caused the exception, and the status codes which were expected. + /// + /// Rest Response which was not expected. + /// The expected status codes which were not found. + public DropboxRestException(IRestResponse r, params HttpStatusCode[] expectedCodes) { Response = r; - StatusCode = r.StatusCode; + StatusCode = r.StatusCode; + ExpectedCodes = expectedCodes; } + /// + /// Overridden message for Dropbox Exception. + /// + /// The exception message in the format of "Received Response [{0}] : Expected to see [{1}]. The HTTP response was [{2}]. + /// + /// + public override string Message + { + get + { + return string.Format("Received Response [{0}] : Expected to see [{1}]. The HTTP response was [{2}].", + Response.StatusCode, + string.Join(", ", ExpectedCodes.Select(code => Enum.GetName(typeof(HttpStatusCode), code))), + Response.Content); + } + } } } diff --git a/DropNet/Extensions/RestClientExtensions.cs b/DropNet/Extensions/RestClientExtensions.cs index c105c32..670aa9c 100644 --- a/DropNet/Extensions/RestClientExtensions.cs +++ b/DropNet/Extensions/RestClientExtensions.cs @@ -42,7 +42,7 @@ public static Task ExecuteTask(this IRestClient client, { if (response.StatusCode != HttpStatusCode.OK) { - tcs.SetException(new DropboxException(response)); + tcs.SetException(new DropboxRestException(response, HttpStatusCode.OK)); } else { @@ -86,7 +86,7 @@ public static Task ExecuteTask(this IRestClient client, { if (response.StatusCode != HttpStatusCode.OK) { - tcs.SetException(new DropboxException(response)); + tcs.SetException(new DropboxRestException(response, HttpStatusCode.OK)); } else { From a36997cb380829ddde4d5b7216a4ab3dff723a5a Mon Sep 17 00:00:00 2001 From: Jason Smith Date: Mon, 13 Jan 2014 13:55:21 +1100 Subject: [PATCH 08/43] Revert "Improvements to DropboxException." This reverts commit 72f6fe9568b177f6e33b330186c439b9a25ffff7. --- DropNet/Client/Client.cs | 16 +++--- DropNet/Exceptions/DropboxException.cs | 58 ++++------------------ DropNet/Extensions/RestClientExtensions.cs | 4 +- 3 files changed, 20 insertions(+), 58 deletions(-) diff --git a/DropNet/Client/Client.cs b/DropNet/Client/Client.cs index f7a2bb2..c6d00d3 100644 --- a/DropNet/Client/Client.cs +++ b/DropNet/Client/Client.cs @@ -132,7 +132,7 @@ public string BuildAuthorizeUrl(OAuth2AuthorizationFlow oAuth2AuthorizationFlow, if (response.StatusCode != HttpStatusCode.OK) { - throw new DropboxRestException(response, HttpStatusCode.OK); + throw new DropboxException(response); } } else @@ -141,7 +141,7 @@ public string BuildAuthorizeUrl(OAuth2AuthorizationFlow oAuth2AuthorizationFlow, if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.PartialContent) { - throw new DropboxRestException(response, HttpStatusCode.OK, HttpStatusCode.PartialContent); + throw new DropboxException(response); } } @@ -157,7 +157,7 @@ private IRestResponse Execute(ApiType apiType, IRestRequest request) if (response.StatusCode != HttpStatusCode.OK) { - throw new DropboxRestException(response, HttpStatusCode.OK); + throw new DropboxException(response); } } else @@ -166,7 +166,7 @@ private IRestResponse Execute(ApiType apiType, IRestRequest request) if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.PartialContent) { - throw new DropboxRestException(response, HttpStatusCode.OK, HttpStatusCode.PartialContent); + throw new DropboxException(response); } } @@ -194,7 +194,7 @@ private void ExecuteAsync(ApiType apiType, IRestRequest request, Action + /// The response of the error call (for Debugging use) + /// + public IRestResponse Response { get; private set; } + public DropboxException() { - } - public DropboxException(string message) : base(message) + public DropboxException(string message) + : base(message) { - } - } - public class DropboxRestException : DropboxException - { - /// - /// Returned status code from the request - /// - public HttpStatusCode StatusCode { get; private set; } - - /// - /// Expected status codes to have seen instead of the one recieved. - /// - public HttpStatusCode[] ExpectedCodes { get; private set; } - - /// - /// The response of the error call (for Debugging use) - /// - public IRestResponse Response { get; private set; } - - public DropboxRestException(string message) : base(message) - { } - /// - /// Creates a DropboxRestException with the rest response which caused the exception, and the status codes which were expected. - /// - /// Rest Response which was not expected. - /// The expected status codes which were not found. - public DropboxRestException(IRestResponse r, params HttpStatusCode[] expectedCodes) + public DropboxException(IRestResponse r) { Response = r; - StatusCode = r.StatusCode; - ExpectedCodes = expectedCodes; + StatusCode = r.StatusCode; } - /// - /// Overridden message for Dropbox Exception. - /// - /// The exception message in the format of "Received Response [{0}] : Expected to see [{1}]. The HTTP response was [{2}]. - /// - /// - public override string Message - { - get - { - return string.Format("Received Response [{0}] : Expected to see [{1}]. The HTTP response was [{2}].", - Response.StatusCode, - string.Join(", ", ExpectedCodes.Select(code => Enum.GetName(typeof(HttpStatusCode), code))), - Response.Content); - } - } } } diff --git a/DropNet/Extensions/RestClientExtensions.cs b/DropNet/Extensions/RestClientExtensions.cs index 670aa9c..c105c32 100644 --- a/DropNet/Extensions/RestClientExtensions.cs +++ b/DropNet/Extensions/RestClientExtensions.cs @@ -42,7 +42,7 @@ public static Task ExecuteTask(this IRestClient client, { if (response.StatusCode != HttpStatusCode.OK) { - tcs.SetException(new DropboxRestException(response, HttpStatusCode.OK)); + tcs.SetException(new DropboxException(response)); } else { @@ -86,7 +86,7 @@ public static Task ExecuteTask(this IRestClient client, { if (response.StatusCode != HttpStatusCode.OK) { - tcs.SetException(new DropboxRestException(response, HttpStatusCode.OK)); + tcs.SetException(new DropboxException(response)); } else { From 4bcf4618e090fd3e8f7cff29b8c6d78b4c6664c0 Mon Sep 17 00:00:00 2001 From: Jason Smith Date: Mon, 13 Jan 2014 14:07:48 +1100 Subject: [PATCH 09/43] Improvements to DropboxException. Split out the base exception class and added descendant DropboxRestException. Also update message returned by DropboxRestException to have more information as to what caused the exception. This will break on compile as DropboxException does not have StatusCode or Response properties. --- DropNet/Client/Client.cs | 16 +++--- DropNet/Exceptions/DropboxException.cs | 58 ++++++++++++++++++---- DropNet/Extensions/RestClientExtensions.cs | 4 +- 3 files changed, 58 insertions(+), 20 deletions(-) diff --git a/DropNet/Client/Client.cs b/DropNet/Client/Client.cs index bf2b9df..aa246b9 100644 --- a/DropNet/Client/Client.cs +++ b/DropNet/Client/Client.cs @@ -178,7 +178,7 @@ public string BuildAuthorizeUrl(OAuth2AuthorizationFlow oAuth2AuthorizationFlow, if (response.StatusCode != HttpStatusCode.OK) { - throw new DropboxException(response); + throw new DropboxRestException(response, HttpStatusCode.OK); } } else @@ -187,7 +187,7 @@ public string BuildAuthorizeUrl(OAuth2AuthorizationFlow oAuth2AuthorizationFlow, if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.PartialContent) { - throw new DropboxException(response); + throw new DropboxRestException(response, HttpStatusCode.OK, HttpStatusCode.PartialContent); } } @@ -203,7 +203,7 @@ private IRestResponse Execute(ApiType apiType, IRestRequest request) if (response.StatusCode != HttpStatusCode.OK) { - throw new DropboxException(response); + throw new DropboxRestException(response, HttpStatusCode.OK); } } else @@ -212,7 +212,7 @@ private IRestResponse Execute(ApiType apiType, IRestRequest request) if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.PartialContent) { - throw new DropboxException(response); + throw new DropboxRestException(response, HttpStatusCode.OK, HttpStatusCode.PartialContent); } } @@ -240,7 +240,7 @@ private void ExecuteAsync(ApiType apiType, IRestRequest request, Action - /// The response of the error call (for Debugging use) - /// - public IRestResponse Response { get; private set; } - public DropboxException() { + } - public DropboxException(string message) - : base(message) + public DropboxException(string message) : base(message) { + } + } + public class DropboxRestException : DropboxException + { + /// + /// Returned status code from the request + /// + public HttpStatusCode StatusCode { get; private set; } + + /// + /// Expected status codes to have seen instead of the one recieved. + /// + public HttpStatusCode[] ExpectedCodes { get; private set; } + + /// + /// The response of the error call (for Debugging use) + /// + public IRestResponse Response { get; private set; } + + public DropboxRestException(string message) : base(message) + { } - public DropboxException(IRestResponse r) + /// + /// Creates a DropboxRestException with the rest response which caused the exception, and the status codes which were expected. + /// + /// Rest Response which was not expected. + /// The expected status codes which were not found. + public DropboxRestException(IRestResponse r, params HttpStatusCode[] expectedCodes) { Response = r; - StatusCode = r.StatusCode; + StatusCode = r.StatusCode; + ExpectedCodes = expectedCodes; } + /// + /// Overridden message for Dropbox Exception. + /// + /// The exception message in the format of "Received Response [{0}] : Expected to see [{1}]. The HTTP response was [{2}]. + /// + /// + public override string Message + { + get + { + return string.Format("Received Response [{0}] : Expected to see [{1}]. The HTTP response was [{2}].", + Response.StatusCode, + string.Join(", ", ExpectedCodes.Select(code => Enum.GetName(typeof(HttpStatusCode), code))), + Response.Content); + } + } } } diff --git a/DropNet/Extensions/RestClientExtensions.cs b/DropNet/Extensions/RestClientExtensions.cs index c105c32..670aa9c 100644 --- a/DropNet/Extensions/RestClientExtensions.cs +++ b/DropNet/Extensions/RestClientExtensions.cs @@ -42,7 +42,7 @@ public static Task ExecuteTask(this IRestClient client, { if (response.StatusCode != HttpStatusCode.OK) { - tcs.SetException(new DropboxException(response)); + tcs.SetException(new DropboxRestException(response, HttpStatusCode.OK)); } else { @@ -86,7 +86,7 @@ public static Task ExecuteTask(this IRestClient client, { if (response.StatusCode != HttpStatusCode.OK) { - tcs.SetException(new DropboxException(response)); + tcs.SetException(new DropboxRestException(response, HttpStatusCode.OK)); } else { From ba8718a0ecdc1d33bb1b69d2fba88fb30880b3f3 Mon Sep 17 00:00:00 2001 From: Jason Smith Date: Mon, 13 Jan 2014 14:57:26 +1100 Subject: [PATCH 10/43] Added Timeout and TimeoutMS to the dropnetclient class. Allows the caller to set the timeout for the RestClient in either milliseconds or timespan values. --- DropNet.Tests/UserTests1.cs | 11 +++++++++++ DropNet/Client/Client.cs | 12 ++++++++++++ 2 files changed, 23 insertions(+) diff --git a/DropNet.Tests/UserTests1.cs b/DropNet.Tests/UserTests1.cs index f2528e8..d0ae7b1 100644 --- a/DropNet.Tests/UserTests1.cs +++ b/DropNet.Tests/UserTests1.cs @@ -1,5 +1,6 @@ using System; using DropNet.Authenticators; +using DropNet.Exceptions; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace DropNet.Tests @@ -118,5 +119,15 @@ private void TestOAuth2AuthorizationUrl(OAuth2AuthorizationFlow oAuth2Authorizat Assert.IsNotNull(actual); Assert.AreEqual(expected, actual); } + + [TestMethod] + [ExpectedException(typeof(DropboxException))] + public void Timeout_Exception_Raised_On_Super_Short_Timeout() + { + var client = new DropNetClient("", ""); + client.TimeoutMS = 100; + + client.GetToken(); + } } } diff --git a/DropNet/Client/Client.cs b/DropNet/Client/Client.cs index bf2b9df..1028af3 100644 --- a/DropNet/Client/Client.cs +++ b/DropNet/Client/Client.cs @@ -33,6 +33,18 @@ public UserLogin UserLogin } } + public TimeSpan Timeout + { + get { return TimeSpan.FromMilliseconds(_restClient.Timeout); } + set { _restClient.Timeout = value.Milliseconds; } + } + + public int TimeoutMS + { + get { return _restClient.Timeout; } + set { _restClient.Timeout = value; } + } + /// /// To use Dropbox API in sandbox mode (app folder access) set to true /// From ad3c405e68ce6e29b87f426235104c12af8294a9 Mon Sep 17 00:00:00 2001 From: Victor Bello Date: Wed, 19 Mar 2014 10:59:54 -0700 Subject: [PATCH 11/43] Fixing problem with non-serializable class --- DropNet/Models/UserLogin.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/DropNet/Models/UserLogin.cs b/DropNet/Models/UserLogin.cs index c4f5b6a..d39c65b 100644 --- a/DropNet/Models/UserLogin.cs +++ b/DropNet/Models/UserLogin.cs @@ -1,5 +1,7 @@ -namespace DropNet.Models +using System; +namespace DropNet.Models { + [Serializable] public class UserLogin { public string Token { get; set; } From 7991e48dac14cfc4d508d86495cff687f6fd5113 Mon Sep 17 00:00:00 2001 From: "James B." Date: Wed, 19 Mar 2014 15:26:17 -0500 Subject: [PATCH 12/43] Add Team information to AccountInfo --- DropNet/Models/AccountInfo.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/DropNet/Models/AccountInfo.cs b/DropNet/Models/AccountInfo.cs index fd277fb..0333c93 100644 --- a/DropNet/Models/AccountInfo.cs +++ b/DropNet/Models/AccountInfo.cs @@ -8,6 +8,7 @@ public class AccountInfo public string display_name { get; set; } public QuotaInfo quota_info { get; set; } public long uid { get; set; } + public Team team { get; set; } } public class QuotaInfo @@ -16,4 +17,9 @@ public class QuotaInfo public long quota { get; set; } public long normal { get; set; } } + + public class Team + { + public string name { get; set; } + } } From 4b7231a6f0bd365994f6de9a04c78ba260a5b2b0 Mon Sep 17 00:00:00 2001 From: koichi Date: Sun, 20 Apr 2014 00:29:49 -0700 Subject: [PATCH 13/43] Added Client_Mtime to MetaData class --- DropNet/Models/MetaData.cs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/DropNet/Models/MetaData.cs b/DropNet/Models/MetaData.cs index a8e2263..163fcaa 100644 --- a/DropNet/Models/MetaData.cs +++ b/DropNet/Models/MetaData.cs @@ -9,6 +9,7 @@ public class MetaData public bool Thumb_Exists { get; set; } public long Bytes { get; set; } public string Modified { get; set; } + public string Client_Mtime { get; set; } public string Path { get; set; } public bool Is_Dir { get; set; } public bool Is_Deleted { get; set; } @@ -45,7 +46,31 @@ public DateTime UTCDateModified } } - + public DateTime Client_MtimeDate + { + get + { + //cast to datetime and return + return Client_Mtime == null ? DateTime.MinValue : DateTime.Parse(Client_Mtime); //RFC1123 format date codes are returned by API + } + } + + public DateTime UTCDateClient_Mtime + { + get + { + string str = Client_Mtime; + if (str == null) + return DateTime.MinValue; + if (str.EndsWith(" +0000")) str = str.Substring(0, str.Length - 6); + if (!str.EndsWith(" UTC")) str += " UTC"; + return DateTime.ParseExact(str, "ddd, d MMM yyyy HH:mm:ss UTC", System.Globalization.CultureInfo.InvariantCulture); + } + set + { + Client_Mtime = value.ToString("ddd, d MMM yyyy HH:mm:ss UTC"); + } + } public string Name { From 1995b62c856e2a7c8f3c97f58fa5b1419e87b287 Mon Sep 17 00:00:00 2001 From: koichi Date: Sun, 20 Apr 2014 00:54:25 -0700 Subject: [PATCH 14/43] Combined datetime related functionalities --- DropNet/Models/MetaData.cs | 47 +++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/DropNet/Models/MetaData.cs b/DropNet/Models/MetaData.cs index 163fcaa..37c2c9e 100644 --- a/DropNet/Models/MetaData.cs +++ b/DropNet/Models/MetaData.cs @@ -24,8 +24,7 @@ public DateTime ModifiedDate { get { - //cast to datetime and return - return Modified == null ? DateTime.MinValue : DateTime.Parse(Modified); //RFC1123 format date codes are returned by API + return GetDateTimeFromString(Modified); } } @@ -33,16 +32,11 @@ public DateTime UTCDateModified { get { - string str = Modified; - if (str == null) - return DateTime.MinValue; - if (str.EndsWith(" +0000")) str = str.Substring(0, str.Length - 6); - if (!str.EndsWith(" UTC")) str += " UTC"; - return DateTime.ParseExact(str, "ddd, d MMM yyyy HH:mm:ss UTC", System.Globalization.CultureInfo.InvariantCulture); + return GetUTCDateTimeFromString(Modified); } set { - Modified = value.ToString("ddd, d MMM yyyy HH:mm:ss UTC"); + Modified = GetStringFromDateTime(value); } } @@ -50,8 +44,7 @@ public DateTime Client_MtimeDate { get { - //cast to datetime and return - return Client_Mtime == null ? DateTime.MinValue : DateTime.Parse(Client_Mtime); //RFC1123 format date codes are returned by API + return GetDateTimeFromString(Client_Mtime); } } @@ -59,19 +52,14 @@ public DateTime UTCDateClient_Mtime { get { - string str = Client_Mtime; - if (str == null) - return DateTime.MinValue; - if (str.EndsWith(" +0000")) str = str.Substring(0, str.Length - 6); - if (!str.EndsWith(" UTC")) str += " UTC"; - return DateTime.ParseExact(str, "ddd, d MMM yyyy HH:mm:ss UTC", System.Globalization.CultureInfo.InvariantCulture); + return GetUTCDateTimeFromString(Client_Mtime); } set { - Client_Mtime = value.ToString("ddd, d MMM yyyy HH:mm:ss UTC"); + Client_Mtime = GetStringFromDateTime(value); } } - + public string Name { get @@ -107,6 +95,27 @@ public string Extension return Is_Dir ? string.Empty : Path.Substring(Path.LastIndexOf(".")); } } + + private static DateTime GetDateTimeFromString(string dateTimeStr) + { + //cast to datetime and return + return dateTimeStr == null ? DateTime.MinValue : DateTime.Parse(dateTimeStr); //RFC1123 format date codes are returned by API + } + + private static DateTime GetUTCDateTimeFromString(string dateTimeStr) + { + string str = dateTimeStr; + if (str == null) + return DateTime.MinValue; + if (str.EndsWith(" +0000")) str = str.Substring(0, str.Length - 6); + if (!str.EndsWith(" UTC")) str += " UTC"; + return DateTime.ParseExact(str, "ddd, d MMM yyyy HH:mm:ss UTC", System.Globalization.CultureInfo.InvariantCulture); + } + + private static string GetStringFromDateTime(DateTime dateTime) + { + return dateTime.ToString("ddd, d MMM yyyy HH:mm:ss UTC"); + } } } From 680027c2652ae1f7a997e88d00f4e99209230ada Mon Sep 17 00:00:00 2001 From: partyzone Date: Wed, 25 Jun 2014 08:16:13 +0400 Subject: [PATCH 15/43] Added realization of proxy support to client. --- DropNet/Client/Client.cs | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/DropNet/Client/Client.cs b/DropNet/Client/Client.cs index 1028af3..450d70a 100644 --- a/DropNet/Client/Client.cs +++ b/DropNet/Client/Client.cs @@ -62,7 +62,7 @@ public int TimeoutMS private RequestHelper _requestHelper; #if !WINDOWS_PHONE && !WINRT - public IWebProxy Proxy { get; set; } + private IWebProxy _proxy; #endif /// @@ -78,10 +78,11 @@ string Root /// /// The Api Key to use for the Dropbox Requests /// The Api Secret to use for the Dropbox Requests - /// The authentication method to use. /// The proxy to use for web requests - public DropNetClient(string apiKey, string appSecret, AuthenticationMethod authenticationMethod = AuthenticationMethod.OAuth1) + /// The authentication method to use. + public DropNetClient(string apiKey, string appSecret, IWebProxy proxy = null, AuthenticationMethod authenticationMethod = AuthenticationMethod.OAuth1) { + _proxy = proxy; LoadClient(); _apiKey = apiKey; _appsecret = appSecret; @@ -96,8 +97,8 @@ public DropNetClient(string apiKey, string appSecret, AuthenticationMethod authe /// The Api Secret to use for the Dropbox Requests /// The OAuth2 access token /// The proxy to use for web requests - public DropNetClient(string apiKey, string appSecret, string accessToken) - : this(apiKey, appSecret, AuthenticationMethod.OAuth2) + public DropNetClient(string apiKey, string appSecret, string accessToken, IWebProxy proxy) + : this(apiKey, appSecret, proxy, AuthenticationMethod.OAuth2) { UserLogin = new UserLogin { Token = accessToken }; } @@ -110,10 +111,10 @@ public DropNetClient(string apiKey, string appSecret, string accessToken) /// The OAuth1 User authentication token /// The OAuth1 Users matching secret /// The proxy to use for web requests - public DropNetClient(string apiKey, string appSecret, string userToken, string userSecret) - :this(apiKey, appSecret) + public DropNetClient(string apiKey, string appSecret, string userToken, string userSecret, IWebProxy proxy) + : this(apiKey, appSecret, proxy) { - UserLogin = new UserLogin { Token = userToken, Secret = userSecret }; + UserLogin = new UserLogin {Token = userToken, Secret = userSecret}; } private void LoadClient() @@ -121,13 +122,18 @@ private void LoadClient() _restClient = new RestClient(ApiBaseUrl); #if !WINDOWS_PHONE && !WINRT - _restClient.Proxy = Proxy; + _restClient.Proxy = _proxy; #endif _restClient.ClearHandlers(); _restClient.AddHandler("*", new JsonDeserializer()); _restClientContent = new RestClient(ApiContentBaseUrl); + +#if !WINDOWS_PHONE && !WINRT + _restClientContent.Proxy = _proxy; +#endif + _restClientContent.ClearHandlers(); _restClientContent.AddHandler("*", new JsonDeserializer()); From b5bac20e8f07d307c0d5ecd55170a59d7d57fb04 Mon Sep 17 00:00:00 2001 From: partyzone Date: Wed, 25 Jun 2014 11:04:13 +0400 Subject: [PATCH 16/43] Added longpoll_delta blocking request. --- DropNet/Client/Client.cs | 36 +++++++++++++++++++++++++++++--- DropNet/Client/Files.Sync.cs | 19 +++++++++++++++++ DropNet/Helpers/RequestHelper.cs | 12 +++++++++++ DropNet/Models/DeltaPage.cs | 13 ++++++++++++ 4 files changed, 77 insertions(+), 3 deletions(-) diff --git a/DropNet/Client/Client.cs b/DropNet/Client/Client.cs index 450d70a..0b089bf 100644 --- a/DropNet/Client/Client.cs +++ b/DropNet/Client/Client.cs @@ -16,6 +16,7 @@ public partial class DropNetClient { private const string ApiBaseUrl = "https://api.dropbox.com"; private const string ApiContentBaseUrl = "https://api-content.dropbox.com"; + private const string ApiNotifyUrl = "https://api-notify.dropbox.com"; private const string Version = "1"; private UserLogin _userLogin; @@ -59,6 +60,7 @@ public int TimeoutMS private RestClient _restClient; private RestClient _restClientContent; + private RestClient _restClientNotify; private RequestHelper _requestHelper; #if !WINDOWS_PHONE && !WINRT @@ -137,6 +139,15 @@ private void LoadClient() _restClientContent.ClearHandlers(); _restClientContent.AddHandler("*", new JsonDeserializer()); + _restClientNotify = new RestClient(ApiNotifyUrl); + +#if !WINDOWS_PHONE && !WINRT + _restClientNotify.Proxy = _proxy; +#endif + + _restClientNotify.ClearHandlers(); + _restClientNotify.AddHandler("*", new JsonDeserializer()); + _requestHelper = new RequestHelper(Version); //Default to full access @@ -199,7 +210,7 @@ public string BuildAuthorizeUrl(OAuth2AuthorizationFlow oAuth2AuthorizationFlow, throw new DropboxException(response); } } - else + else if (apiType == ApiType.Content) { response = _restClientContent.Execute(request); @@ -208,6 +219,15 @@ public string BuildAuthorizeUrl(OAuth2AuthorizationFlow oAuth2AuthorizationFlow, throw new DropboxException(response); } } + else + { + response = _restClientNotify.Execute(request); + + if (response.StatusCode != HttpStatusCode.OK) + { + throw new DropboxException(response); + } + } return response.Data; } @@ -224,7 +244,7 @@ private IRestResponse Execute(ApiType apiType, IRestRequest request) throw new DropboxException(response); } } - else + else if (apiType == ApiType.Content) { response = _restClientContent.Execute(request); @@ -233,6 +253,15 @@ private IRestResponse Execute(ApiType apiType, IRestRequest request) throw new DropboxException(response); } } + else + { + response = _restClientNotify.Execute(request); + + if (response.StatusCode != HttpStatusCode.OK) + { + throw new DropboxException(response); + } + } return response; } @@ -394,7 +423,8 @@ private IAuthenticator GetAuthenticator(string baseUrl) enum ApiType { Base, - Content + Content, + Notify } /// diff --git a/DropNet/Client/Files.Sync.cs b/DropNet/Client/Files.Sync.cs index e82b1e5..490c18b 100644 --- a/DropNet/Client/Files.Sync.cs +++ b/DropNet/Client/Files.Sync.cs @@ -438,6 +438,25 @@ public CopyRefResponse GetCopyRef(string path) return Execute(ApiType.Base, request); } + /// + /// A long-poll endpoint to wait for changes on an account. In conjunction with /delta, this call gives you a low-latency way to monitor an account for file changes. + /// + /// The value returned from the prior call to GetDelta. + /// An optional integer indicating a timeout, in seconds. + /// The default value is 30 seconds, which is also the minimum allowed value. The maximum is 480 seconds. + /// + public LongpollDeltaResult GetLongpollDelta(string cursor, int timeout = 30) + { + if (timeout < 30) + timeout = 30; + if (timeout > 480) + timeout = 480; + + var request = _requestHelper.CreateLongpollDeltaRequest(cursor, timeout); + + return Execute(ApiType.Notify, request); + } + /// /// Gets the deltas for a user's folders and files. /// diff --git a/DropNet/Helpers/RequestHelper.cs b/DropNet/Helpers/RequestHelper.cs index b900d17..53f8c07 100644 --- a/DropNet/Helpers/RequestHelper.cs +++ b/DropNet/Helpers/RequestHelper.cs @@ -407,6 +407,18 @@ public RestRequest CreateCreateFolderRequest(string path, string root) return request; } + internal RestRequest CreateLongpollDeltaRequest(string cursor, int timeout) + { + var request = new RestRequest(Method.GET); + request.Resource = "{version}/longpoll_delta"; + + request.AddParameter("version", _version, ParameterType.UrlSegment); + request.AddParameter("cursor", cursor); + request.AddParameter("timeout", timeout); + + return request; + } + internal RestRequest CreateDeltaRequest(string cursor) { var request = new RestRequest(Method.POST); diff --git a/DropNet/Models/DeltaPage.cs b/DropNet/Models/DeltaPage.cs index ba752d1..23bb66b 100644 --- a/DropNet/Models/DeltaPage.cs +++ b/DropNet/Models/DeltaPage.cs @@ -62,4 +62,17 @@ public class DeltaEntry public MetaData MetaData { get; set; } } + public class LongpollDeltaResult + { + /// + /// The value of the changes field indicates whether new changes are available. + /// If this value is true, you should call /delta to retrieve the changes. If this value is false, it means the call to /longpoll_delta timed out. + /// + public bool Changes { get; set; } + + /// + /// If present, the value of the backoff field indicates how many seconds your code should wait before calling /longpoll_delta again. + /// + public int Backoff { get; set; } + } } From b9fe6b646b7ad9ef3f31dbe92c5da556d1e1b62d Mon Sep 17 00:00:00 2001 From: partyzone Date: Wed, 25 Jun 2014 12:42:43 +0400 Subject: [PATCH 17/43] Added async function for longpoll_delta. Added request for restore (sync, async and task). --- DropNet/Client/Files.Async.cs | 30 ++++++++++++++++++++++++++++++ DropNet/Client/Files.Sync.cs | 13 +++++++++++++ DropNet/Client/Files.Task.cs | 7 +++++++ DropNet/Helpers/RequestHelper.cs | 15 +++++++++++++++ 4 files changed, 65 insertions(+) diff --git a/DropNet/Client/Files.Async.cs b/DropNet/Client/Files.Async.cs index ba8533a..20c0a8c 100644 --- a/DropNet/Client/Files.Async.cs +++ b/DropNet/Client/Files.Async.cs @@ -47,6 +47,20 @@ public void GetMetaDataAsync(string path, string hash, Action success, ExecuteAsync(ApiType.Base, request, success, failure); } + /// + /// Restores a file path to a previous revision. + /// + /// The revision of the file to restore. + /// The path to the file. + /// Success call back + /// Failure call back + public void RestoreAsync(string rev, string path, Action success, Action failure) + { + var request = _requestHelper.CreateRestoreRequest(rev, path, Root); + + ExecuteAsync(ApiType.Base, request, success, failure); + } + /// /// Gets list of metadata for search string /// @@ -357,6 +371,22 @@ public void GetMediaAsync(string path, Action success, Action + /// A long-poll endpoint to wait for changes on an account. In conjunction with /delta, this call gives you a low-latency way to monitor an account for file changes. + /// + /// The value returned from the prior call to GetDelta. + /// + /// + /// An optional integer indicating a timeout, in seconds. + /// The default value is 30 seconds, which is also the minimum allowed value. The maximum is 480 seconds. + public void GetLongpollDeltaAsync(string cursor, Action success, + Action failure, int timeout = 30) + { + var request = _requestHelper.CreateLongpollDeltaRequest(cursor, timeout); + + ExecuteAsync(ApiType.Base, request, success, failure); + } + /// /// The beta delta function, gets updates for a given folder /// diff --git a/DropNet/Client/Files.Sync.cs b/DropNet/Client/Files.Sync.cs index 490c18b..7ef8e30 100644 --- a/DropNet/Client/Files.Sync.cs +++ b/DropNet/Client/Files.Sync.cs @@ -60,6 +60,19 @@ public List Search(string searchString) return Search(searchString, string.Empty); } + /// + /// Restores a file path to a previous revision. + /// + /// The revision of the file to restore. + /// The path to the file. + /// The metadata of the restored file. + public MetaData Restore(string rev, string path) + { + var request = _requestHelper.CreateRestoreRequest(rev, path, Root); + + return Execute(ApiType.Base, request); + } + /// /// Gets list of metadata for search string /// diff --git a/DropNet/Client/Files.Task.cs b/DropNet/Client/Files.Task.cs index 6a1c4ee..06fcd68 100644 --- a/DropNet/Client/Files.Task.cs +++ b/DropNet/Client/Files.Task.cs @@ -34,6 +34,13 @@ public Task GetMetaDataTask(string path, string hash) return ExecuteTask(ApiType.Base, request); } + public Task RestoreTask(string rev, string path) + { + var request = _requestHelper.CreateRestoreRequest(rev, path, Root); + + return ExecuteTask(ApiType.Base, request); + } + public Task> SearchTask(string searchString) { return SearchTask(searchString, string.Empty); diff --git a/DropNet/Helpers/RequestHelper.cs b/DropNet/Helpers/RequestHelper.cs index 53f8c07..d05072d 100644 --- a/DropNet/Helpers/RequestHelper.cs +++ b/DropNet/Helpers/RequestHelper.cs @@ -461,6 +461,21 @@ private string ThumbnailSizeString(ThumbnailSize size) return "s"; } + public RestRequest CreateRestoreRequest(string rev, string path, string root) + { + var request = new RestRequest(Method.POST) + { + Resource = "{version}/restore/{root}{path}" + }; + + request.AddParameter("version", _version, ParameterType.UrlSegment); + request.AddParameter("path", path, ParameterType.UrlSegment); + request.AddParameter("root", root, ParameterType.UrlSegment); + request.AddParameter("rev", rev); + + return request; + } + public RestRequest CreateSearchRequest(string searchString, string path, string root) { var request = new RestRequest(Method.GET) From f0a12f0d8a8c42013f95361616ac52ef0515d9cd Mon Sep 17 00:00:00 2001 From: partyzone Date: Wed, 25 Jun 2014 14:16:42 +0400 Subject: [PATCH 18/43] Added case for ApiType.Notify in ExecuteAsync and ExecuteAsync. --- DropNet/Client/Client.cs | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/DropNet/Client/Client.cs b/DropNet/Client/Client.cs index 0b089bf..e3af52c 100644 --- a/DropNet/Client/Client.cs +++ b/DropNet/Client/Client.cs @@ -295,7 +295,7 @@ private void ExecuteAsync(ApiType apiType, IRestRequest request, Action { @@ -309,6 +309,20 @@ private void ExecuteAsync(ApiType apiType, IRestRequest request, Action + { + if (response.StatusCode != HttpStatusCode.OK) + { + failure(new DropboxException(response)); + } + else + { + success(response); + } + }); + } } private void ExecuteAsync(ApiType apiType, IRestRequest request, Action success, Action failure) where T : new() @@ -339,7 +353,7 @@ private void ExecuteAsync(ApiType apiType, IRestRequest request, Action(request, (response, asynchandle) => { @@ -353,6 +367,20 @@ private void ExecuteAsync(ApiType apiType, IRestRequest request, Action(request, (response, asynchandle) => + { + if (response.StatusCode != HttpStatusCode.OK) + { + failure(new DropboxException(response)); + } + else + { + success(response.Data); + } + }); + } } #if !WINRT From ab2c375e369eb7f64a6bdb2f3b55d3fbbb3adab5 Mon Sep 17 00:00:00 2001 From: partyzone Date: Wed, 25 Jun 2014 14:18:08 +0400 Subject: [PATCH 19/43] Changed ApiType for GetLongpollDeltaAsync. --- DropNet/Client/Files.Async.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DropNet/Client/Files.Async.cs b/DropNet/Client/Files.Async.cs index 20c0a8c..0be6357 100644 --- a/DropNet/Client/Files.Async.cs +++ b/DropNet/Client/Files.Async.cs @@ -384,7 +384,7 @@ public void GetLongpollDeltaAsync(string cursor, Action suc { var request = _requestHelper.CreateLongpollDeltaRequest(cursor, timeout); - ExecuteAsync(ApiType.Base, request, success, failure); + ExecuteAsync(ApiType.Notify, request, success, failure); } /// From 1c3b9429f2c436177d28c5f9297d10a8b6fdd012 Mon Sep 17 00:00:00 2001 From: partyzone Date: Wed, 25 Jun 2014 14:19:22 +0400 Subject: [PATCH 20/43] Check for min/max value of timeout param moved to RequestHelper.cs --- DropNet/Client/Files.Sync.cs | 5 ----- DropNet/Helpers/RequestHelper.cs | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/DropNet/Client/Files.Sync.cs b/DropNet/Client/Files.Sync.cs index 7ef8e30..dce5341 100644 --- a/DropNet/Client/Files.Sync.cs +++ b/DropNet/Client/Files.Sync.cs @@ -460,11 +460,6 @@ public CopyRefResponse GetCopyRef(string path) /// public LongpollDeltaResult GetLongpollDelta(string cursor, int timeout = 30) { - if (timeout < 30) - timeout = 30; - if (timeout > 480) - timeout = 480; - var request = _requestHelper.CreateLongpollDeltaRequest(cursor, timeout); return Execute(ApiType.Notify, request); diff --git a/DropNet/Helpers/RequestHelper.cs b/DropNet/Helpers/RequestHelper.cs index d05072d..400d0c1 100644 --- a/DropNet/Helpers/RequestHelper.cs +++ b/DropNet/Helpers/RequestHelper.cs @@ -414,6 +414,11 @@ internal RestRequest CreateLongpollDeltaRequest(string cursor, int timeout) request.AddParameter("version", _version, ParameterType.UrlSegment); request.AddParameter("cursor", cursor); + + if (timeout < 30) + timeout = 30; + if (timeout > 480) + timeout = 480; request.AddParameter("timeout", timeout); return request; From f7c01de4e8e8a651710755138770db4ed58964a1 Mon Sep 17 00:00:00 2001 From: partyzone Date: Wed, 24 Sep 2014 13:49:39 +0400 Subject: [PATCH 21/43] Added optional search parameter of file limit. --- DropNet/Client/Files.Async.cs | 11 ++++++++--- DropNet/Client/Files.Sync.cs | 13 +++++++++---- DropNet/Client/Files.Task.cs | 11 +++++++---- DropNet/Helpers/RequestHelper.cs | 3 ++- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/DropNet/Client/Files.Async.cs b/DropNet/Client/Files.Async.cs index 0be6357..10b1580 100644 --- a/DropNet/Client/Files.Async.cs +++ b/DropNet/Client/Files.Async.cs @@ -67,7 +67,8 @@ public void RestoreAsync(string rev, string path, Action success, Acti /// The search string /// Success call back /// Failure call back - public void SearchAsync(string searchString, Action> success, Action failure) + /// The maximum and default value is 1,000. No more than fileLimit search results will be returned. + public void SearchAsync(string searchString, Action> success, Action failure, uint fileLimit = 1000) { SearchAsync(searchString, string.Empty, success, failure); } @@ -79,9 +80,13 @@ public void SearchAsync(string searchString, Action> success, Act /// The path of the file or folder /// Success call back /// Failure call back - public void SearchAsync(string searchString, string path, Action> success, Action failure) + /// The maximum and default value is 1,000. No more than fileLimit search results will be returned. + public void SearchAsync(string searchString, string path, Action> success, Action failure, uint fileLimit = 1000) { - var request = _requestHelper.CreateSearchRequest(searchString, path, Root); + if (fileLimit > 1000) + fileLimit = 1000; + + var request = _requestHelper.CreateSearchRequest(searchString, path, Root, fileLimit); ExecuteAsync(ApiType.Base, request, success, failure); } diff --git a/DropNet/Client/Files.Sync.cs b/DropNet/Client/Files.Sync.cs index dce5341..17296e5 100644 --- a/DropNet/Client/Files.Sync.cs +++ b/DropNet/Client/Files.Sync.cs @@ -55,9 +55,10 @@ public List GetVersions(string path, int limit) /// Gets list of metadata for search string /// /// The search string - public List Search(string searchString) + /// The maximum and default value is 1,000. No more than fileLimit search results will be returned. + public List Search(string searchString, uint fileLimit = 1000) { - return Search(searchString, string.Empty); + return Search(searchString, string.Empty, fileLimit); } /// @@ -78,9 +79,13 @@ public MetaData Restore(string rev, string path) /// /// The search string /// The path of the file or folder - public List Search(string searchString, string path) + /// The maximum and default value is 1,000. No more than fileLimit search results will be returned. + public List Search(string searchString, string path, uint fileLimit = 1000) { - var request = _requestHelper.CreateSearchRequest(searchString, path, Root); + if (fileLimit > 1000) + fileLimit = 1000; + + var request = _requestHelper.CreateSearchRequest(searchString, path, Root, fileLimit); return Execute>(ApiType.Base, request); } diff --git a/DropNet/Client/Files.Task.cs b/DropNet/Client/Files.Task.cs index 06fcd68..90ea461 100644 --- a/DropNet/Client/Files.Task.cs +++ b/DropNet/Client/Files.Task.cs @@ -41,14 +41,17 @@ public Task RestoreTask(string rev, string path) return ExecuteTask(ApiType.Base, request); } - public Task> SearchTask(string searchString) + public Task> SearchTask(string searchString, uint fileLimit = 1000) { - return SearchTask(searchString, string.Empty); + return SearchTask(searchString, string.Empty, fileLimit); } - public Task> SearchTask(string searchString, string path) + public Task> SearchTask(string searchString, string path, uint fileLimit = 1000) { - var request = _requestHelper.CreateSearchRequest(searchString, path, Root); + if (fileLimit > 1000) + fileLimit = 1000; + + var request = _requestHelper.CreateSearchRequest(searchString, path, Root, fileLimit); return ExecuteTask>(ApiType.Base, request); } diff --git a/DropNet/Helpers/RequestHelper.cs b/DropNet/Helpers/RequestHelper.cs index 400d0c1..5f89ebc 100644 --- a/DropNet/Helpers/RequestHelper.cs +++ b/DropNet/Helpers/RequestHelper.cs @@ -481,7 +481,7 @@ public RestRequest CreateRestoreRequest(string rev, string path, string root) return request; } - public RestRequest CreateSearchRequest(string searchString, string path, string root) + public RestRequest CreateSearchRequest(string searchString, string path, string root, uint fileLimit) { var request = new RestRequest(Method.GET) { @@ -492,6 +492,7 @@ public RestRequest CreateSearchRequest(string searchString, string path, string request.AddParameter("path", path, ParameterType.UrlSegment); request.AddParameter("root", root, ParameterType.UrlSegment); request.AddParameter("query", searchString); + request.AddParameter("file_limit", fileLimit); return request; } From 04ca0ba295ea357d597c87b993ee9611c82e28b0 Mon Sep 17 00:00:00 2001 From: Christian Runeborg Date: Sat, 8 Nov 2014 23:28:04 +0100 Subject: [PATCH 22/43] Fixed issue where GetDeltaAsync parameter incorrectly was named path but was sent as cursor to RequestHelper Added parameters path_prefix, locale and include_media_info to GetDelta/GetDeltaAsync --- DropNet.Tests/FileSyncTests.cs | 2 +- DropNet.Tests/FileTests1.Sandbox.cs | 2 +- DropNet/Client/Files.Async.cs | 12 ++++++++---- DropNet/Client/Files.Sync.cs | 7 +++++-- DropNet/Helpers/RequestHelper.cs | 13 ++++++++++++- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/DropNet.Tests/FileSyncTests.cs b/DropNet.Tests/FileSyncTests.cs index ea090b4..b7f7f11 100644 --- a/DropNet.Tests/FileSyncTests.cs +++ b/DropNet.Tests/FileSyncTests.cs @@ -233,7 +233,7 @@ public void Can_Get_Media() [TestMethod] public void Can_Get_Delta() { - var delta = _client.GetDelta(""); + var delta = _client.GetDelta("", "", "", false); Assert.IsNotNull(delta); } diff --git a/DropNet.Tests/FileTests1.Sandbox.cs b/DropNet.Tests/FileTests1.Sandbox.cs index 3f19b28..66bf772 100644 --- a/DropNet.Tests/FileTests1.Sandbox.cs +++ b/DropNet.Tests/FileTests1.Sandbox.cs @@ -206,7 +206,7 @@ public void SANDBOX_Can_Get_Thumbnail() [TestMethod] public void SANDBOX_Can_Get_Delta() { - var deltaPage = _client.GetDelta(""); + var deltaPage = _client.GetDelta("", "", "", false); Assert.IsNotNull(deltaPage); diff --git a/DropNet/Client/Files.Async.cs b/DropNet/Client/Files.Async.cs index 0be6357..f78a4c5 100644 --- a/DropNet/Client/Files.Async.cs +++ b/DropNet/Client/Files.Async.cs @@ -391,16 +391,20 @@ public void GetLongpollDeltaAsync(string cursor, Action suc /// The beta delta function, gets updates for a given folder /// /// - /// + /// The value returned from the prior call to GetDelta or an empty string + /// If present, this parameter filters the response to only include entries at or under the specified path + /// If present the metadata returned will have its size field translated based on the given locale + /// If true, each file will include a photo_info dictionary for photos and a video_info dictionary for videos with additional media info. When include_media_info is specified, files will only appear in delta responses when the media info is ready. If you use the include_media_info parameter, you must continue to pass the same value on subsequent calls using the returned cursor. /// /// - public void GetDeltaAsync(bool IKnowThisIsBetaOnly, string path, Action success, Action failure) + public void GetDeltaAsync(bool IKnowThisIsBetaOnly, string cursor, string pathPrefix, + string locale, bool includeMediaInfo, Action success, Action failure) { if (!IKnowThisIsBetaOnly) return; - if (!path.StartsWith("/")) path = "/" + path; + if (!pathPrefix.StartsWith("/")) pathPrefix = "/" + pathPrefix; - var request = _requestHelper.CreateDeltaRequest(path); + var request = _requestHelper.CreateDeltaRequest(cursor, pathPrefix, locale, includeMediaInfo); ExecuteAsync(ApiType.Base, request, success, failure); } diff --git a/DropNet/Client/Files.Sync.cs b/DropNet/Client/Files.Sync.cs index dce5341..e823614 100644 --- a/DropNet/Client/Files.Sync.cs +++ b/DropNet/Client/Files.Sync.cs @@ -469,10 +469,13 @@ public LongpollDeltaResult GetLongpollDelta(string cursor, int timeout = 30) /// Gets the deltas for a user's folders and files. /// /// The value returned from the prior call to GetDelta or an empty string + /// If present, this parameter filters the response to only include entries at or under the specified path + /// If present the metadata returned will have its size field translated based on the given locale + /// If true, each file will include a photo_info dictionary for photos and a video_info dictionary for videos with additional media info. When include_media_info is specified, files will only appear in delta responses when the media info is ready. If you use the include_media_info parameter, you must continue to pass the same value on subsequent calls using the returned cursor. /// - public DeltaPage GetDelta(string cursor) + public DeltaPage GetDelta(string cursor, string pathPrefix, string locale, bool includeMediaInfo) { - var request = _requestHelper.CreateDeltaRequest(cursor); + var request = _requestHelper.CreateDeltaRequest(cursor, pathPrefix, locale, includeMediaInfo); var deltaResponse = Execute(ApiType.Base, request); diff --git a/DropNet/Helpers/RequestHelper.cs b/DropNet/Helpers/RequestHelper.cs index 400d0c1..a7dc5f2 100644 --- a/DropNet/Helpers/RequestHelper.cs +++ b/DropNet/Helpers/RequestHelper.cs @@ -424,13 +424,24 @@ internal RestRequest CreateLongpollDeltaRequest(string cursor, int timeout) return request; } - internal RestRequest CreateDeltaRequest(string cursor) + internal RestRequest CreateDeltaRequest(string cursor, string pathPrefix, string locale, bool includeMediaInfo) { var request = new RestRequest(Method.POST); request.Resource = "{version}/delta"; request.AddParameter("version", _version, ParameterType.UrlSegment); request.AddParameter("cursor", cursor); + request.AddParameter("include_media_info", includeMediaInfo); + + if (!string.IsNullOrEmpty(pathPrefix)) + { + request.AddParameter("path_prefix", pathPrefix); + } + + if (!string.IsNullOrEmpty(locale)) + { + request.AddParameter("locale", locale); + } return request; } From d6bf00b179931b16f7a8f0308794f06b4905f26d Mon Sep 17 00:00:00 2001 From: Christian Runeborg Date: Sat, 8 Nov 2014 23:36:14 +0100 Subject: [PATCH 23/43] Prepended path_prefix with / if there was no leading forward slash in synchronous call --- DropNet/Client/Files.Sync.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DropNet/Client/Files.Sync.cs b/DropNet/Client/Files.Sync.cs index e823614..a7f0466 100644 --- a/DropNet/Client/Files.Sync.cs +++ b/DropNet/Client/Files.Sync.cs @@ -475,6 +475,8 @@ public LongpollDeltaResult GetLongpollDelta(string cursor, int timeout = 30) /// public DeltaPage GetDelta(string cursor, string pathPrefix, string locale, bool includeMediaInfo) { + if (!pathPrefix.StartsWith("/")) pathPrefix = "/" + pathPrefix; + var request = _requestHelper.CreateDeltaRequest(cursor, pathPrefix, locale, includeMediaInfo); var deltaResponse = Execute(ApiType.Base, request); From 7c7342b40959f9b98cea1432c89f50571674ea68 Mon Sep 17 00:00:00 2001 From: Christian Runeborg Date: Tue, 11 Nov 2014 21:31:40 +0100 Subject: [PATCH 24/43] Added overload for GetDelta and GetDeltaAsync to not break old code --- DropNet/Client/Files.Async.cs | 16 ++++++++++++++++ DropNet/Client/Files.Sync.cs | 27 +++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/DropNet/Client/Files.Async.cs b/DropNet/Client/Files.Async.cs index f78a4c5..7fe8323 100644 --- a/DropNet/Client/Files.Async.cs +++ b/DropNet/Client/Files.Async.cs @@ -387,6 +387,22 @@ public void GetLongpollDeltaAsync(string cursor, Action suc ExecuteAsync(ApiType.Notify, request, success, failure); } + /// + /// The beta delta function, gets updates for a given folder + /// + /// + /// The value returned from the prior call to GetDelta or an empty string + /// + /// + public void GetDeltaAsync(bool IKnowThisIsBetaOnly, string cursor, Action success, Action failure) + { + if (!IKnowThisIsBetaOnly) return; + + var request = _requestHelper.CreateDeltaRequest(cursor, null, null, false); + + ExecuteAsync(ApiType.Base, request, success, failure); + } + /// /// The beta delta function, gets updates for a given folder /// diff --git a/DropNet/Client/Files.Sync.cs b/DropNet/Client/Files.Sync.cs index a7f0466..79fd922 100644 --- a/DropNet/Client/Files.Sync.cs +++ b/DropNet/Client/Files.Sync.cs @@ -465,6 +465,33 @@ public LongpollDeltaResult GetLongpollDelta(string cursor, int timeout = 30) return Execute(ApiType.Notify, request); } + /// + /// Gets the deltas for a user's folders and files. + /// + /// The value returned from the prior call to GetDelta or an empty string + /// + public DeltaPage GetDelta(string cursor) + { + var request = _requestHelper.CreateDeltaRequest(cursor, null, null, false); + + var deltaResponse = Execute(ApiType.Base, request); + + var deltaPage = new DeltaPage + { + Cursor = deltaResponse.Cursor, + Has_More = deltaResponse.Has_More, + Reset = deltaResponse.Reset, + Entries = new List() + }; + + foreach (var stringList in deltaResponse.Entries) + { + deltaPage.Entries.Add(StringListToDeltaEntry(stringList)); + } + + return deltaPage; + } + /// /// Gets the deltas for a user's folders and files. /// From 695baf013a9fcae3801f08b441e0f55965302f85 Mon Sep 17 00:00:00 2001 From: crackalak Date: Mon, 15 Dec 2014 11:54:32 +0000 Subject: [PATCH 25/43] Fix for RestSharp v105.0 breaking change BaseUrl now returns URI rather than a string --- DropNet/Client/Client.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DropNet/Client/Client.cs b/DropNet/Client/Client.cs index e3af52c..f7b4852 100644 --- a/DropNet/Client/Client.cs +++ b/DropNet/Client/Client.cs @@ -435,8 +435,8 @@ private UserLogin GetUserLoginFromParams(string urlParams) private void SetAuthProviders() { - _restClientContent.Authenticator = GetAuthenticator(_restClientContent.BaseUrl); - _restClient.Authenticator = GetAuthenticator(_restClient.BaseUrl); + _restClientContent.Authenticator = GetAuthenticator(_restClientContent.BaseUrl.ToString()); + _restClient.Authenticator = GetAuthenticator(_restClient.BaseUrl.ToString()); } private IAuthenticator GetAuthenticator(string baseUrl) From 0b672496975d2c2073846c4370313a616f152842 Mon Sep 17 00:00:00 2001 From: Damian Karzon Date: Fri, 19 Dec 2014 08:13:13 +1300 Subject: [PATCH 26/43] Fixed the Windows Phone build (Doesn't support proxy) --- DropNet/Client/Client.cs | 45 +++++++++++++++++++++++++++++++++++++ DropNet/Models/UserLogin.cs | 6 +++-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/DropNet/Client/Client.cs b/DropNet/Client/Client.cs index f7b4852..0e91a06 100644 --- a/DropNet/Client/Client.cs +++ b/DropNet/Client/Client.cs @@ -75,6 +75,50 @@ string Root get { return UseSandbox ? SandboxRoot : DropboxRoot; } } +#if WINDOWS_PHONE + /// + /// Default Constructor for the DropboxClient + /// + /// The Api Key to use for the Dropbox Requests + /// The Api Secret to use for the Dropbox Requests + /// The proxy to use for web requests + /// The authentication method to use. + public DropNetClient(string apiKey, string appSecret, AuthenticationMethod authenticationMethod = AuthenticationMethod.OAuth1) + { + LoadClient(); + _apiKey = apiKey; + _appsecret = appSecret; + _authenticationMethod = authenticationMethod; + UserLogin = null; + } + + /// + /// Creates an instance of the DropNetClient given an API Key/Secret and an OAuth2 Access Token + /// + /// The Api Key to use for the Dropbox Requests + /// The Api Secret to use for the Dropbox Requests + /// The OAuth2 access token + /// The proxy to use for web requests + public DropNetClient(string apiKey, string appSecret, string accessToken) + : this(apiKey, appSecret, AuthenticationMethod.OAuth2) + { + UserLogin = new UserLogin { Token = accessToken }; + } + + /// + /// Creates an instance of the DropNetClient given an API Key/Secret and an OAuth1 User Token/Secret + /// + /// The Api Key to use for the Dropbox Requests + /// The Api Secret to use for the Dropbox Requests + /// The OAuth1 User authentication token + /// The OAuth1 Users matching secret + /// The proxy to use for web requests + public DropNetClient(string apiKey, string appSecret, string userToken, string userSecret) + : this(apiKey, appSecret) + { + UserLogin = new UserLogin { Token = userToken, Secret = userSecret }; + } +#else /// /// Default Constructor for the DropboxClient /// @@ -118,6 +162,7 @@ public DropNetClient(string apiKey, string appSecret, string userToken, string u { UserLogin = new UserLogin {Token = userToken, Secret = userSecret}; } +#endif private void LoadClient() { diff --git a/DropNet/Models/UserLogin.cs b/DropNet/Models/UserLogin.cs index d39c65b..c7e6f39 100644 --- a/DropNet/Models/UserLogin.cs +++ b/DropNet/Models/UserLogin.cs @@ -1,7 +1,9 @@ using System; -namespace DropNet.Models -{ +namespace DropNet.Models +{ +#if !WINDOWS_PHONE [Serializable] +#endif public class UserLogin { public string Token { get; set; } From c7dce26e485e07215ddf81edd7050724dc50a07a Mon Sep 17 00:00:00 2001 From: Charlie Nevill Date: Thu, 1 Jan 2015 14:42:35 -0600 Subject: [PATCH 27/43] Fixed URL for OAuth2 login, and added token disable support --- DropNet/Client/Client.cs | 10 +++++++++- DropNet/Client/User.Async.cs | 9 +++++++++ DropNet/Client/User.Sync.cs | 9 +++++++++ DropNet/Helpers/RequestHelper.cs | 7 +++++++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/DropNet/Client/Client.cs b/DropNet/Client/Client.cs index 0e91a06..7a1f73f 100644 --- a/DropNet/Client/Client.cs +++ b/DropNet/Client/Client.cs @@ -14,6 +14,7 @@ namespace DropNet { public partial class DropNetClient { + private const string MainServerBaseUrl = "https://www.dropbox.com"; private const string ApiBaseUrl = "https://api.dropbox.com"; private const string ApiContentBaseUrl = "https://api-content.dropbox.com"; private const string ApiNotifyUrl = "https://api-notify.dropbox.com"; @@ -58,6 +59,7 @@ public int TimeoutMS private readonly string _appsecret; private readonly AuthenticationMethod _authenticationMethod; + private RestClient _restClientMainServer; private RestClient _restClient; private RestClient _restClientContent; private RestClient _restClientNotify; @@ -166,6 +168,12 @@ public DropNetClient(string apiKey, string appSecret, string userToken, string u private void LoadClient() { + _restClientMainServer = new RestClient(MainServerBaseUrl); + +#if !WINDOWS_PHONE && !WINRT + _restClientMainServer.Proxy = _proxy; +#endif + _restClient = new RestClient(ApiBaseUrl); #if !WINDOWS_PHONE && !WINRT @@ -239,7 +247,7 @@ public string BuildAuthorizeUrl(OAuth2AuthorizationFlow oAuth2AuthorizationFlow, throw new ArgumentNullException("redirectUri"); } RestRequest request = _requestHelper.BuildOAuth2AuthorizeUrl(oAuth2AuthorizationFlow, _apiKey, redirectUri, state); - return _restClient.BuildUri(request).ToString(); + return _restClientMainServer.BuildUri(request).ToString(); } #if !WINDOWS_PHONE && !WINRT diff --git a/DropNet/Client/User.Async.cs b/DropNet/Client/User.Async.cs index 09b53a5..5d35a2e 100644 --- a/DropNet/Client/User.Async.cs +++ b/DropNet/Client/User.Async.cs @@ -69,6 +69,15 @@ public void AccountInfoAsync(Action success, Action + /// Disables the current access token. + /// + public void DisableAccessTokenAsync(Action success, Action failure) + { + var request = _requestHelper.CreateDisableAccessTokenRequest(); + ExecuteAsync(ApiType.Base, request, _ => success(), failure); + } + [Obsolete("No longer supported by Dropbox")] public void CreateAccountAsync(string email, string firstName, string lastName, string password, Action success, Action failure) { diff --git a/DropNet/Client/User.Sync.cs b/DropNet/Client/User.Sync.cs index a4ee4bc..1e8f52f 100644 --- a/DropNet/Client/User.Sync.cs +++ b/DropNet/Client/User.Sync.cs @@ -67,6 +67,15 @@ public AccountInfo AccountInfo() return Execute(ApiType.Base, request); } + /// + /// Disables the current access token. + /// + public IRestResponse DisableAccessToken() + { + var request = _requestHelper.CreateDisableAccessTokenRequest(); + return Execute(ApiType.Base, request); + } + } } #endif \ No newline at end of file diff --git a/DropNet/Helpers/RequestHelper.cs b/DropNet/Helpers/RequestHelper.cs index a7dc5f2..4e2416d 100644 --- a/DropNet/Helpers/RequestHelper.cs +++ b/DropNet/Helpers/RequestHelper.cs @@ -386,6 +386,13 @@ public RestRequest CreateOAuth2AccessTokenRequest(string code, string redirectUr return request; } + public RestRequest CreateDisableAccessTokenRequest() + { + var request = new RestRequest("{version}/disable_access_token", Method.POST); + request.AddParameter("version", _version, ParameterType.UrlSegment); + return request; + } + public RestRequest CreateAccountInfoRequest() { var request = new RestRequest(Method.GET); From 8181cc671cafa4147e4a09c61bb7a835e80655ef Mon Sep 17 00:00:00 2001 From: Damian Karzon Date: Tue, 6 Jan 2015 17:31:53 +1300 Subject: [PATCH 28/43] Build config stuff --- DropNet.sln | 5 ----- DropNet/DropNet.csproj | 1 + dropnet.nuspec => DropNet/dropnet.nuspec | 12 ++++++------ appveyor.yml | 8 ++++++++ 4 files changed, 15 insertions(+), 11 deletions(-) rename dropnet.nuspec => DropNet/dropnet.nuspec (55%) create mode 100644 appveyor.yml diff --git a/DropNet.sln b/DropNet.sln index 50c68ad..98584c9 100644 --- a/DropNet.sln +++ b/DropNet.sln @@ -7,11 +7,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DropNet.WindowsPhone", "Dro EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DropNet.Tests", "DropNet.Tests\DropNet.Tests.csproj", "{06B6BC2F-94D5-456A-ABA7-F73FB28B4703}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NuGet", "NuGet", "{61EE82C6-B07F-4F79-81FD-E028D60D4977}" - ProjectSection(SolutionItems) = preProject - dropnet.nuspec = dropnet.nuspec - EndProjectSection -EndProject Global GlobalSection(TestCaseManagementSettings) = postSolution CategoryFile = DropNet.vsmdi diff --git a/DropNet/DropNet.csproj b/DropNet/DropNet.csproj index d53ab79..23d8cb9 100644 --- a/DropNet/DropNet.csproj +++ b/DropNet/DropNet.csproj @@ -108,6 +108,7 @@ + diff --git a/dropnet.nuspec b/DropNet/dropnet.nuspec similarity index 55% rename from dropnet.nuspec rename to DropNet/dropnet.nuspec index dd4eddf..2f0bb8e 100644 --- a/dropnet.nuspec +++ b/DropNet/dropnet.nuspec @@ -2,13 +2,13 @@ DropNet - 1.9.6 + $version$ Damian Karzon, Github Contributors Damian Karzon .NET Client for the Dropbox API (.NET 4 and Windows Phone) en-AU - http://dkdevelopment.net/what-im-doing/dropnet/ - https://github.com/dkarzon/DropNet/blob/master/LICENSE.txt + http://dropnet.github.io/ + https://github.com/dropnet/DropNet/blob/master/LICENSE.txt http://dkdevelopment.net/img/DropNetIcon.png DROPBOX API .NET WP7 @@ -16,8 +16,8 @@ - - - + + + \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..6a01012 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,8 @@ +version: 1.9.{build} + +assembly_info: + patch: true + file: AssemblyInfo.* + assembly_version: "{version}" + assembly_file_version: "{version}" + assembly_informational_version: "{version}" \ No newline at end of file From 918d0e952c161fd75cf2e1e8eba750c0a4bcc2f6 Mon Sep 17 00:00:00 2001 From: Damian Karzon Date: Tue, 6 Jan 2015 17:45:50 +1300 Subject: [PATCH 29/43] Build settings --- appveyor.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 6a01012..cff5acc 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,8 +1,18 @@ version: 1.9.{build} +configuration: Release +build: + project: DropNet.sln + publish_nuget: true + publish_nuget_symbols: true + assembly_info: patch: true file: AssemblyInfo.* assembly_version: "{version}" assembly_file_version: "{version}" - assembly_informational_version: "{version}" \ No newline at end of file + assembly_informational_version: "{version}" + + +# scripts to run before build +before_build: nuget restore \ No newline at end of file From c8c534a30defb4678551ea5a6b2fb2559585592b Mon Sep 17 00:00:00 2001 From: Damian Karzon Date: Tue, 6 Jan 2015 18:11:00 +1300 Subject: [PATCH 30/43] No auto running tests. --- appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/appveyor.yml b/appveyor.yml index cff5acc..ae1e197 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,7 @@ version: 1.9.{build} configuration: Release +test: off build: project: DropNet.sln publish_nuget: true From 4f0e1685b7b9c2125c64b26b47e545d3e493078a Mon Sep 17 00:00:00 2001 From: Damian Karzon Date: Sat, 24 Jan 2015 09:59:06 +1300 Subject: [PATCH 31/43] remove the sample project --- DropNet.Samples/DropNet.Samples.WP7/App.xaml | 19 --- .../DropNet.Samples.WP7/App.xaml.cs | 144 ------------------ .../DropNet.Samples.WP7/ApplicationIcon.png | Bin 1881 -> 0 bytes .../DropNet.Samples.WP7/Background.png | Bin 3521 -> 0 bytes .../Converters/BoolToNotVisConverter.cs | 28 ---- .../Converters/BoolToVisConverter.cs | 28 ---- .../DropNet.Samples.WP7.csproj | 124 --------------- .../DropNet.Samples.WP7/MainPage.xaml | 62 -------- .../DropNet.Samples.WP7/MainPage.xaml.cs | 111 -------------- .../Properties/AppManifest.xml | 6 - .../Properties/AssemblyInfo.cs | 37 ----- .../Properties/WMAppManifest.xml | 35 ----- .../SampleData/MainViewModelSampleData.xaml | 131 ---------------- .../DropNet.Samples.WP7/SplashScreenImage.jpg | Bin 9417 -> 0 bytes .../ViewModels/MainViewModel.cs | 61 -------- .../DropNet.Samples.WP7/packages.config | 5 - 16 files changed, 791 deletions(-) delete mode 100644 DropNet.Samples/DropNet.Samples.WP7/App.xaml delete mode 100644 DropNet.Samples/DropNet.Samples.WP7/App.xaml.cs delete mode 100644 DropNet.Samples/DropNet.Samples.WP7/ApplicationIcon.png delete mode 100644 DropNet.Samples/DropNet.Samples.WP7/Background.png delete mode 100644 DropNet.Samples/DropNet.Samples.WP7/Converters/BoolToNotVisConverter.cs delete mode 100644 DropNet.Samples/DropNet.Samples.WP7/Converters/BoolToVisConverter.cs delete mode 100644 DropNet.Samples/DropNet.Samples.WP7/DropNet.Samples.WP7.csproj delete mode 100644 DropNet.Samples/DropNet.Samples.WP7/MainPage.xaml delete mode 100644 DropNet.Samples/DropNet.Samples.WP7/MainPage.xaml.cs delete mode 100644 DropNet.Samples/DropNet.Samples.WP7/Properties/AppManifest.xml delete mode 100644 DropNet.Samples/DropNet.Samples.WP7/Properties/AssemblyInfo.cs delete mode 100644 DropNet.Samples/DropNet.Samples.WP7/Properties/WMAppManifest.xml delete mode 100644 DropNet.Samples/DropNet.Samples.WP7/SampleData/MainViewModelSampleData.xaml delete mode 100644 DropNet.Samples/DropNet.Samples.WP7/SplashScreenImage.jpg delete mode 100644 DropNet.Samples/DropNet.Samples.WP7/ViewModels/MainViewModel.cs delete mode 100644 DropNet.Samples/DropNet.Samples.WP7/packages.config diff --git a/DropNet.Samples/DropNet.Samples.WP7/App.xaml b/DropNet.Samples/DropNet.Samples.WP7/App.xaml deleted file mode 100644 index 2938a4b..0000000 --- a/DropNet.Samples/DropNet.Samples.WP7/App.xaml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/DropNet.Samples/DropNet.Samples.WP7/App.xaml.cs b/DropNet.Samples/DropNet.Samples.WP7/App.xaml.cs deleted file mode 100644 index 8809b17..0000000 --- a/DropNet.Samples/DropNet.Samples.WP7/App.xaml.cs +++ /dev/null @@ -1,144 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Animation; -using System.Windows.Navigation; -using System.Windows.Shapes; -using Microsoft.Phone.Controls; -using Microsoft.Phone.Shell; - -namespace DropNet.Samples.WP7 -{ - public partial class App : Application - { - /// - /// Provides easy access to the root frame of the Phone Application. - /// - /// The root frame of the Phone Application. - public PhoneApplicationFrame RootFrame { get; private set; } - - /// - /// Publically accessable DropNetClient - /// - public static DropNetClient DropNetClient { get; set; } - - /// - /// Constructor for the Application object. - /// - public App() - { - // Global handler for uncaught exceptions. - UnhandledException += Application_UnhandledException; - - // Standard Silverlight initialization - InitializeComponent(); - - // Phone-specific initialization - InitializePhoneApplication(); - - // Show graphics profiling information while debugging. - if (System.Diagnostics.Debugger.IsAttached) - { - // Display the current frame rate counters. - Application.Current.Host.Settings.EnableFrameRateCounter = true; - - PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled; - } - - //////////////////////////////////////////////////// - // NOTE: This key is a Development only key setup for this sample and will only work with my login. - // MAKE SURE YOU CHANGE IT OR IT WONT WORK! - //////////////////////////////////////////////////// - DropNetClient = new DropNetClient("9m6v782a7aeop0w", "dbd11uqce6hr8zg"); - - //NOTE: If user Token and Secret are stored from previous login session: - //DropNetClient.UserLogin = new Models.UserLogin { Token = "TokenFromStorage", Secret = "SecretFromStorage" }; - } - - // Code to execute when the application is launching (eg, from Start) - // This code will not execute when the application is reactivated - private void Application_Launching(object sender, LaunchingEventArgs e) - { - } - - // Code to execute when the application is activated (brought to foreground) - // This code will not execute when the application is first launched - private void Application_Activated(object sender, ActivatedEventArgs e) - { - } - - // Code to execute when the application is deactivated (sent to background) - // This code will not execute when the application is closing - private void Application_Deactivated(object sender, DeactivatedEventArgs e) - { - } - - // Code to execute when the application is closing (eg, user hit Back) - // This code will not execute when the application is deactivated - private void Application_Closing(object sender, ClosingEventArgs e) - { - } - - // Code to execute if a navigation fails - private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e) - { - if (System.Diagnostics.Debugger.IsAttached) - { - // A navigation has failed; break into the debugger - System.Diagnostics.Debugger.Break(); - } - } - - // Code to execute on Unhandled Exceptions - private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e) - { - if (System.Diagnostics.Debugger.IsAttached) - { - // An unhandled exception has occurred; break into the debugger - System.Diagnostics.Debugger.Break(); - } - } - - #region Phone application initialization - - // Avoid double-initialization - private bool phoneApplicationInitialized = false; - - // Do not add any additional code to this method - private void InitializePhoneApplication() - { - if (phoneApplicationInitialized) - return; - - // Create the frame but don't set it as RootVisual yet; this allows the splash - // screen to remain active until the application is ready to render. - RootFrame = new PhoneApplicationFrame(); - RootFrame.Navigated += CompleteInitializePhoneApplication; - - // Handle navigation failures - RootFrame.NavigationFailed += RootFrame_NavigationFailed; - - // Ensure we don't initialize again - phoneApplicationInitialized = true; - } - - // Do not add any additional code to this method - private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e) - { - // Set the root visual to allow the application to render - if (RootVisual != RootFrame) - RootVisual = RootFrame; - - // Remove this handler since it is no longer needed - RootFrame.Navigated -= CompleteInitializePhoneApplication; - } - - #endregion - } -} \ No newline at end of file diff --git a/DropNet.Samples/DropNet.Samples.WP7/ApplicationIcon.png b/DropNet.Samples/DropNet.Samples.WP7/ApplicationIcon.png deleted file mode 100644 index 5859393ca1056103ba35d225773352a9fa3ab754..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1881 zcmV-f2d4OmP)GXLPE9uD;d|3K9jFs0^O3no;*#kUHY6H}PH_^L3*aj} zl+rSw?L`W0p^tkju#a}u3PxyqFY3}?ZpgV`?z#P)?|kQbU67g4(Jt>MC@$|ToYbAv zoz$Jwoz$JwUyrEBh@^xBYY9T32$%4g4Eozd9YH8m>Im7iz@UwrH+y+`StMa0!Jlv1 zOs9{eP8~IOLbaYWZ(elNbZg1v$&=#~5`=udMY3Y~^2n$tPDrTrV}g_vPDsd`qdqj` z?(SZ2=x{`MxJ4Ea7yy62*t!)g2L{u*+?5%tV8G+?EYFApOLBK?H(-W0sdbrL7RKcs zEi7D+mK#@=wJ2&3^B#Z6SE|tW^ z&fa_A0KDdD7g}CkuGQ%*uYy_6tlm5}8JiaBN~M03ks%g~tMA@5>&#%lv|6osRa0w$GfX-lmv6;tg7E35t(xdFTQCUeAbpwWpTg5+|K7IY# zwbIg(hK5FUUmu3O*mrLl?KRUayoa}&LPcB<-$|3+(JUi7*{UTR~?sv$M1P1N>*rj)mLHrKNHON-lLA!%9m^1R@cPXUv=l zmwktfMx&WuVn$tE?SL(YK0XhFAR`119z6nm6Brlagxr7dz}8t~Yn@7=%#V+Eb8|(} zt{zpd`CNjX*sbr;=t5DIS`Dt#+slj1W=)+krM;u$iMZ8K>adS$jr!2xBjD^>TUvBF z9d0yoxm*IZ?l;-5Ain@y6NACvgojsGRpsU7j%^L&Y-U7+haE2}3J&Fvoey?)v}dhb zCu#eKuxQ%SD*0;n9-YaBlZv8a$Hv3kwrJWRlMUc_^1_AW@h&SVIeq4*!NEa-a~Q~4 z+oV!0nTl_2YVx!S#tzx~^ayTn&@|YYz@VU6F)=fuXV94}i1{Q@*QnG@O^x-nwNi;h z*`t)BXsbkOr-$)j`>g(C&HN({S~o10_f z;%IdG#4O<1vuEG#-(Pg%q)ef3=$L{Rf85e?x28HGf*TMRL^f|}YwPyhobszzVFAQ= zm~N%=UR|9)Ab@0*RDI`VXWyx=A<{WQ0h*baId@(Hx%~+Wg~envH8%FDRE|=IfS_Gc9lLglmM*of63B)(jlMWFl^Yh` z-PHwg&`!V3goKDr=Y)nNCGiA8A;+rnCkfqM=&e6)R#x6>e)2@4>Few7cQpMPZm{_I z@>5c?^YUI_#W{jAr%qkC_-ltu?lLq)WR>)^Tj}QN>OSs3Z67*1WyCi#!0z{cbAY@o z006~x)1!xywl>13BNU2g3IFKvB5+=0+j?T+{J*NJA&d|~9YF+(7w2r-hRPK^N~OV| z*K2jK7)uw$abO06sz<3-X}VB_(P)g1kH1%6r&4Pit&*rzYH08@48w6FjvxpyMqH5G z+#G(IkSOXBu{bAtE4UNjJv2Dv?d^r*xNNN6#<*(JR_RN|$7Zqo{R0Rz5+7e*D63_1 z1<}onQAk;|C^{yFKD+Wz{HrNFFf|SuX0K6dp!F8pg;@r>Y=rsCpr)?Z@)E?>v3>(o$ zrqR3^&og+a=b!w5N57jd;8|i|GIMu#V_YC94Rc^kd-O#lzDi#4-5>B z`F?^uj5UIS0&A+OHhi}J_wsTa!}NN6eQllj6z=lWJG4TH)* z?`+z*0Yy=!W5up*A7no6n!nw*wo>MkzI-d?@orCP?%cM_FCIaX9;>6gpovZ%<&lG0MhzAcYIoOgsb z0n|ss&CTu6!-opA%OZibfuXl|${hS;XMd^jw!!)D4NmG#>Q3rT>i;k5{|Ybw$j9Fp Tu#Z&K00000NkvXXu0mjfnP|DN diff --git a/DropNet.Samples/DropNet.Samples.WP7/Background.png b/DropNet.Samples/DropNet.Samples.WP7/Background.png deleted file mode 100644 index e46f21d9407f1ae4d6fedcf793778f32bae3f06d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3521 zcmcInXHZjHyQUKa0*D|z9EwQqn$QW&LN5a0(9}p#z|av07z0wI3P?4PNKpZi&_Sw4 zLlF)jASHB>Dnt^hfxGX|`|JMszCE+|nprb@t(o_I+M8@^ZNYs`CMWRa_{X2b%~(Y4zZGoHG0TeeRQ-3xz&pF>q?5Cn9|4FxbFSa1h; zjwu3)x4dE>KCH#zaAiRhDpgE3ysD%`9LDRo_6rwxdbIRUYCu4MRTEfTM@v$&tGk!E%3QMmgErV+_P0kPK2#3KPgk)p2??OnY?$-L(8itp8(PcD%WG=V4eWeBKBB#C zYZDE~%gLz^-$tmtn#cNPvSc8RfwlV(hoa{9zk~VXLOJ)XhsB7pKkMPS13jV&n4D9_wYu%NS)+IVL>be8L z3lCzHhQWlZ1CPyKy?QlPZpCbaLm$6cOzHuOJ$0hK@cyq$ScTc?U#gQegC6dd{;vrR%RV6J^?a&mHfe4OM1g~1BwAX}4N5{V?qJ|QqI zp&z;YIW1|_&(AO7*Q`33kv{G#TgY8<64uGNou)Awsz128yVz^RF5sp7a~Q|Nnaq60 zqqbE-FEW1Y%X*a36;G18RtF2oVS$H%vu@y_}E#CqsT z*9Ls0Gv-J`(#VciRP|v&8 zwU<;qJ94No{r$#1K5`l#?2-?0K8j)ju(hCWp^iujym;A|0tZ)}N84q)ww`j*_h*92 z%F33w9!N^$YqNvFU^NxY{Cmk78!R~_B;;g^IQ&pzAllK%DWQieOxijkAVB#K!jMbg zk4d*!b93`E3H|BeVH@Fx)cyVajVvNDWshOoBN=3^$94i_QtlO|5})p2)z;IU&NB~pcX2+xSF`q)vNkq154L9_4t}{) zc*bx2L9<;*Nlm5jU(WwXv9%0~i16%)Ia(VbR9!sQI4OVq`gKKxTXa<|4?x`DAN>NZ zV3$J5lh)Q&lc!)mEfM+j#>g9V!B-9xhd#5l|sSNfhq|G_}y`Vo+0&t%P%Q4H8cna3Z{ftN~J3f7sL47AuM>F$MMFa3U~{b{Hs9{g%FgKoSdAh zs*MrYbddAw*RP=0plb6BQIaB5RHk{RDTt6A^LyobY^?rXk6~^`#xRDJQ&838nW>^K zdqYFRmvr&ANQxA1g-y(MeP*-Hk+udK}w!Xf;TGlGjGtX{see|E^(o!iI8B?j5q*BUg*-hYXi}5bXlMcIx zh=Z{T8&MIFdtVD>|0%m<^pJi`3+kjde)wQ_&c7_V-l4)eEj5+6uc;6ljtF=FH!&Ia zZ_pA*JEU~=_AW1H7|zupZ`#^sD)AIAL+uXCO-&hQEixpMZ08FR%#Jad&WVKp;f?Nza~fjeu=TXOKQVPm2*A9tMH4 z(73oWbR>3ax`BB^9E+Wuo!!{*zd5F>A>m?KgGQt8d`T~XqLyY`LiF|ZKbY6NdYzu0 zo|l(bRaG@OI9OU*3WyS??#!H*{OWmg$HTgD*Oio|BUUNK|%q zc4Om}5l*q>)f{uv1o~XP-&kkBQ=1z$HbDUaP80Z}TsgN|uRC{$0AqJ| zAM&LOIxPY1Q&doRm)(LL0n( zzXi5k#U>OjPNtk1raWvr}= zb54>WojL~CaD@#nJro}&83#xxJ6KH33@b+cXe&Kfbd`r()7%VIR^DFyT2wiqqoc#i zmeaKFqARiBwwngh19-^;G0=$bFABUhaLd*YK<&S|Ego#{V165a8ys{C4OG_}) z*w{ECqRCD_QHIPD(X9AH(Dy+=MqyD=#LnEuxU*B>j^;_C&+v@{LAE|+u`wdcEe=^kAuRLCkTjaF`>qUibf8Uv`-5LR1rx}U&lZEbD-bz*ch z7&x)2N~r;%AF^sm>=@qKet#&LO$P)SKslLArZKV z0X#fBJly*^yb1Bh8)EA~Q5X#PN*XFF*MK@Y*Zi$M%i{TF#P`piKh*ob<~uumh9&-u zzhqJWy%|O5_(JH*vZ6-!aG=lV2SBFtjG-hD2!sXI@yM}dMh&JL(E9mF&$s}VZv4yZ z7q}Ep0KV_cwh&ue5l6I7$^4g@Xeg$Zt~C{hPw^1+q4#8syBCvMpDy;nt;Xz*$*!t@ z_4*|-zdS$FPfs2YPj|ps-Mc7{`(+ zaPeYMY?js@h8NSa`7xldu<+l>p!ts2#U55-G!qz`@+AX8D2rD0l#TWLS+vA|cEtpXb}@)WHY-Vw4#Wd98N+omYttII7v_He)|{>c diff --git a/DropNet.Samples/DropNet.Samples.WP7/Converters/BoolToNotVisConverter.cs b/DropNet.Samples/DropNet.Samples.WP7/Converters/BoolToNotVisConverter.cs deleted file mode 100644 index 269a80e..0000000 --- a/DropNet.Samples/DropNet.Samples.WP7/Converters/BoolToNotVisConverter.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Net; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Documents; -using System.Windows.Ink; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Animation; -using System.Windows.Shapes; -using System.Windows.Data; -using System.Globalization; - -namespace DropNet.Samples.WP7.Converters -{ - public class BoolToNotVisConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - return System.Convert.ToBoolean(value) ? Visibility.Collapsed : Visibility.Visible; - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - return value.Equals(Visibility.Visible); - } - } -} diff --git a/DropNet.Samples/DropNet.Samples.WP7/Converters/BoolToVisConverter.cs b/DropNet.Samples/DropNet.Samples.WP7/Converters/BoolToVisConverter.cs deleted file mode 100644 index f6c7882..0000000 --- a/DropNet.Samples/DropNet.Samples.WP7/Converters/BoolToVisConverter.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Net; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Documents; -using System.Windows.Ink; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Animation; -using System.Windows.Shapes; -using System.Windows.Data; -using System.Globalization; - -namespace DropNet.Samples.WP7.Converters -{ - public class BoolToVisConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - return System.Convert.ToBoolean(value) ? Visibility.Visible : Visibility.Collapsed; - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - return value.Equals(Visibility.Visible); - } - } -} diff --git a/DropNet.Samples/DropNet.Samples.WP7/DropNet.Samples.WP7.csproj b/DropNet.Samples/DropNet.Samples.WP7/DropNet.Samples.WP7.csproj deleted file mode 100644 index c273000..0000000 --- a/DropNet.Samples/DropNet.Samples.WP7/DropNet.Samples.WP7.csproj +++ /dev/null @@ -1,124 +0,0 @@ - - - - Debug - AnyCPU - 10.0.20506 - 2.0 - {59706E1F-E8C9-4889-A0DD-1FD2D4FFB475} - {C089C8C0-30E0-4E22-80C0-CE093F111A43};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} - Library - Properties - DropNet.Samples.WP7 - DropNet.Samples.WP7 - v4.0 - $(TargetFrameworkVersion) - WindowsPhone71 - Silverlight - true - - - true - true - DropNet.Samples.WP7.xap - Properties\AppManifest.xml - DropNet.Samples.WP7.App - true - true - true - 4.0.30816.0 - - - true - full - false - Bin\Debug - DEBUG;TRACE;SILVERLIGHT;WINDOWS_PHONE - true - true - prompt - 4 - - - pdbonly - true - Bin\Release - TRACE;SILVERLIGHT;WINDOWS_PHONE - true - true - prompt - 4 - - - - False - ..\packages\DropNet.1.8.3\lib\sl4-wp71\DropNet.WindowsPhone.dll - - - - - False - ..\packages\Newtonsoft.Json.4.0.5\lib\sl4-windowsphone71\Newtonsoft.Json.dll - - - ..\packages\DropNet.1.8.3\lib\sl4-wp71\RestSharp.WindowsPhoneMango.dll - - - - - - - - - - - App.xaml - - - - - MainPage.xaml - - - - - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - - - - - - - - PreserveNewest - - - PreserveNewest - - - - - - MSBuild:MarkupCompilePass1 - - - - - - - \ No newline at end of file diff --git a/DropNet.Samples/DropNet.Samples.WP7/MainPage.xaml b/DropNet.Samples/DropNet.Samples.WP7/MainPage.xaml deleted file mode 100644 index f598d52..0000000 --- a/DropNet.Samples/DropNet.Samples.WP7/MainPage.xaml +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/DropNet.Samples/DropNet.Samples.WP7/MainPage.xaml.cs b/DropNet.Samples/DropNet.Samples.WP7/MainPage.xaml.cs deleted file mode 100644 index 68af509..0000000 --- a/DropNet.Samples/DropNet.Samples.WP7/MainPage.xaml.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Animation; -using System.Windows.Shapes; -using Microsoft.Phone.Controls; -using DropNet.Samples.WP7.ViewModels; - -namespace DropNet.Samples.WP7 -{ - public partial class MainPage : PhoneApplicationPage - { - private MainViewModel _model; - - // Constructor - public MainPage() - { - InitializeComponent(); - } - - protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) - { - base.OnNavigatedTo(e); - - //Basic MVVM stuff - _model = new MainViewModel(); - _model.ShowLogin = true; - this.DataContext = _model; - } - - private void btnStart_Click(object sender, RoutedEventArgs e) - { - App.DropNetClient.GetTokenAsync(userToken => - { - //Dont really need to do anything with the usertoken yet as its stored inside the client for the session - - //Now we want to use the new Request token we have to generate an Authorize Url - var tokenUrl = App.DropNetClient.BuildAuthorizeUrl("http://dkdevelopment.net/BoxShotLogin.htm"); //Spelt correctly in v1.8.1 - //Capture the LoadCompleted event from the browser so we can check when the user has logged in - loginBrowser.LoadCompleted += new System.Windows.Navigation.LoadCompletedEventHandler(loginBrowser_LoadCompleted); - //Open a browser with the URL - loginBrowser.Navigate(new Uri(tokenUrl)); - }, - (error) => - { - //OH DEAR GOD WHAT HAPPENED?! - Deployment.Current.Dispatcher.BeginInvoke(() => - { - MessageBox.Show(error.Message); - }); - }); - } - - void loginBrowser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e) - { - //Check for the callback path here (or just check it against "/1/oauth/authorize") - if (e.Uri.AbsolutePath == "/BoxShotLogin.htm") - { - //The User has logged in! - //Now to convert the Request Token into an Access Token - App.DropNetClient.GetAccessTokenAsync(response => - { - //GREAT SUCCESS! - //Now we should save the Token and Secret so the user doesnt have to login next time - //response.Token; - //response.Secret; - - //Now lets load the root contents and hide the login on the page - _model.ShowContents = true; - _model.ShowLogin = false; - - LoadContents(); - }, - (error) => - { - //OH DEAR GOD WHAT HAPPENED?! - Deployment.Current.Dispatcher.BeginInvoke(() => - { - MessageBox.Show(error.Message); - }); - }); - } - else - { - //Probably the login page loading, ignore - } - } - - private void LoadContents() - { - App.DropNetClient.GetMetaDataAsync("/", (response) => - { - _model.Meta = response; - }, - (error) => - { - //OH DEAR GOD WHAT HAPPENED?! - Deployment.Current.Dispatcher.BeginInvoke(() => - { - MessageBox.Show(error.Message); - }); - }); - } - } -} \ No newline at end of file diff --git a/DropNet.Samples/DropNet.Samples.WP7/Properties/AppManifest.xml b/DropNet.Samples/DropNet.Samples.WP7/Properties/AppManifest.xml deleted file mode 100644 index 6712a11..0000000 --- a/DropNet.Samples/DropNet.Samples.WP7/Properties/AppManifest.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - diff --git a/DropNet.Samples/DropNet.Samples.WP7/Properties/AssemblyInfo.cs b/DropNet.Samples/DropNet.Samples.WP7/Properties/AssemblyInfo.cs deleted file mode 100644 index fad9d33..0000000 --- a/DropNet.Samples/DropNet.Samples.WP7/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Resources; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("DropNet.Samples.WP7")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("DropNet.Samples.WP7")] -[assembly: AssemblyCopyright("Copyright © Microsoft 2011")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("82abe712-5532-4df6-b5e1-97bfcb061519")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] -[assembly: NeutralResourcesLanguageAttribute("en-US")] diff --git a/DropNet.Samples/DropNet.Samples.WP7/Properties/WMAppManifest.xml b/DropNet.Samples/DropNet.Samples.WP7/Properties/WMAppManifest.xml deleted file mode 100644 index 16c97b7..0000000 --- a/DropNet.Samples/DropNet.Samples.WP7/Properties/WMAppManifest.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - ApplicationIcon.png - - - - - - - - - - - - - - - - - - - - - - - Background.png - 0 - DropNet.Samples.WP7 - - - - - diff --git a/DropNet.Samples/DropNet.Samples.WP7/SampleData/MainViewModelSampleData.xaml b/DropNet.Samples/DropNet.Samples.WP7/SampleData/MainViewModelSampleData.xaml deleted file mode 100644 index 0e6c59f..0000000 --- a/DropNet.Samples/DropNet.Samples.WP7/SampleData/MainViewModelSampleData.xaml +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/DropNet.Samples/DropNet.Samples.WP7/SplashScreenImage.jpg b/DropNet.Samples/DropNet.Samples.WP7/SplashScreenImage.jpg deleted file mode 100644 index 353b1927b9d397aac7f23098e427739615db19fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9417 zcmeH}dpK0v|HtDPw1DzpdZ%obNxsKYq{ma-Qe=JhS%m*?Xpd@ukwIs*Fu0FVSw2n-+r=Mb=+L2UaoABxxu zAiuvCgDVXH_zuX!cENe`_qMQ00C1KE#J{&$&!hj5hl}g!G;Hh5zCTX{;3J~-ezJDk z8DpepqGt?`W&*HUAKSl_)}8!I4%R;w{tC!TB6lKYkci!Ym^=b0j}X!THF)$A|LYqT z@jW5Lkm3>>P?Ay`rQrq*n*lKd5-BE*l#mdI1A$0@>j80j3G^-l%MA+70jS;Q6%8-v z+?P~8`m|liWdPJLI&&deYNN8smaQ1gJz9IU_ZgcUG(B|K%<7o6jqPzedsjDi4^J;| zpTMBA!67(&XjC*ICYBg?@ygYdYpH4J8M(J^=aKV&xl>T`;Nhdvvhv3jwRQCkjZM#< zzv$?sb#?c=eD!*8XqZ027#$mDvS#1Uefa(3r+M}tU%swzR-tce>$(sC^3Ra{pSt8> zU1H+mNO9Dee<1@p zmpZ1D+4@=Lwk1TX_Ho%7R%-m~! zQ-|56f$_1fO+ybENjnH(u)A6Q9c&<9%Z`oZDd}_4>G5*2lSey-e1>3G)UjF_xgJuz ztM{oY&x22Rj%@2i#tt#aeDx-}x-3k$JnX2p`KZg`SzKt45J)B`b_f9}bzcQeI9#$x z>^EC3Jag>`Nl7q@>2Bp(5u3dBz4^fP92_t=DDkrY^#fkfJz}& z`q0hoSmA-LY`HW-@4^iyZ-zZ>y7$9^xVc>KExCP; z3726V3{BEZ3F!%5JQ;hgcewEKAf)TYG>TqXy{+fezm|pB@&Lheisd zLMm{z%XTGDAgJXHS=M~h?Uas0=YAS{-F=8Tp>8`?0mj}bj zTb|jQV4*|#0@tnF(?Vd9N?Oq6p=-L#fVD52W_~IOr$73j>qSUvn;{h1?IcUA7@nuf z2=+nx?v3o&j>wEewP?HQmCpe5yS*XahyM2`4vK?5`Ax%%o#ic0uk1Vd-i+_YPr*i1 zBReokj72;*czhnKOgf#NX*z%xXn=Ez)92W>i{Dsb9V2U=J#v@Vss~T`68&iw%FTE5 z8>*FGQf{$)cSTm~RXr^7pXT**e-^xK+t1G+;jjwvTiF{b@vOJ9tyy`qPAUFq<6=E0 zxp-H|ku?$Z7*gvQm!P2?BXx`FN=@@(w;R4}^l2!4aK^i>Pc_NnSV_iS;4d)bij_ce z6}0M5QxpQ{WK3C3UB1SlSfmgLnihkmIaN@rIQWfh`a-V#uIvJBO*ZA?@~enlY}9q# zdQ}Tt#FidH5aY>~M;?Tl6d{1C$tp7CmnI(Oxk2C9%7Sp)Zmd#E7=_sBnd|N6Rwo#4 z$#sy~@wPAcz^4M`g8g5^_tBm5@uj0a6UUSf-Ig1E3uy)QGK---wmju8EX{(vk+0KN zNwq4SVcr9zgdOSZ%vnk^GaKDOIqVg2E__!OGjV}t5uuVzdjaSyMM8Uecn=*oGD4v4 zCI1d}B?{7O)2^wf&J+$=MG6548U9s@UhuW?DYXd|4vu^&Gd(a_a(DKu{uPW}aDm71 zk_;1xB0E)QMde^X;Rm&FQag?M$1iUuP=Y0{5b%zi$xGB`EZg$76PU%DasHqubv)8z z#5lpqamYO6K|G4BlA>Ru`|uirW~N%a$Ok(+OfORMjFR%n9s(_pnij2HmR8&I7`Mu) zI!0bbF zu_c?9vDVDl!7p2>8J*@-LIzyxPs%lqC*m#GL59Sd&iUzPwr7$_Z&o=VqjfkqOtou2aJ%D7LCHS|B zU22~F3~Bwo zu&>IXTMmOJVm~yVo<0S0^|P`5XoV2qJbenyanU?aF#85im1|Et`gT?=yG4SDqqy<* zLzh`8jdX&;r4J9%6dD#%`bNNYo==XRM3cz)-_#%bl3j- zx@Wz&&537sEg>yOT3jhO!B%i8KY>C_rD5)7W#0cdezqn5Vpe5kXsm%ZevNRWYTw{* zzEi&aO06vhkK;6R+-)2a`{CYg^}ZI5!m7^l@4|Z)IdKbpzdkQvCftKG?!=)FN1uGQ zd~TYP$^MWklbs^i>KGe#q?0&};vvm1{&er5Im&aG2hmiVPj%l@OCNT&1{D7SQ(Ak) zRTYdid1NQ+d9!#eZuU&D|E3Ic%kyc!5EOS75oN zF0Q+vdyW34hHJ(PVTUB?60}@vAjdt8j6^l4bmz;UCbn&oxpia(WaXEIduORWk1=QL z-auqMOEWN8+e`&L{p3rTa6< z#h389yo`yUXV=D+G%b&xkZ=ch$7^uVR=DpdeyMqQ8P5ztfi>OJN-crq{o9>C?T~#} zW8z<{ab0mLbalYScv9}i)FaCT$1}@4KQ&z6s;3wDgAdhp7kq9>hkG|PH>{2WKMN#N z!AwVnO4P(;ydA&B!i;xjK)tZScnZU|NWljZHvT=LF*iVg;yH)P-Ucz@J?AR_iG?;~ zZa=iNO{V*i7aE~AExt5 zUrCr@ZS4sZ9ph09stY8k0dcHKsxlG9xe1Tzkwe)je47loni5ezjp1$Pr|T1Rw34}9 zZ95t2Di|ycn>Fs++D9H&zI8gnSWRkLrS(}Z{(ky0eA?pvhQ8KJ#$?KFmPf5pK?)W=_QKorGU6lW0wA_hbZh!_wtAYwqo UfQSJR10n`Q4E%c;KnlnH2jCM6ivR!s diff --git a/DropNet.Samples/DropNet.Samples.WP7/ViewModels/MainViewModel.cs b/DropNet.Samples/DropNet.Samples.WP7/ViewModels/MainViewModel.cs deleted file mode 100644 index 2caf40f..0000000 --- a/DropNet.Samples/DropNet.Samples.WP7/ViewModels/MainViewModel.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Net; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Documents; -using System.Windows.Ink; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Animation; -using System.Windows.Shapes; -using System.ComponentModel; -using DropNet.Models; - -namespace DropNet.Samples.WP7.ViewModels -{ - public class MainViewModel : INotifyPropertyChanged - { - private bool _showLogin; - public bool ShowLogin - { - get { return _showLogin; } - set - { - _showLogin = value; - NotifyPropertyChanged("ShowLogin"); - } - } - - private bool _showContents; - public bool ShowContents - { - get { return _showContents; } - set - { - _showContents = value; - NotifyPropertyChanged("ShowContents"); - } - } - - private MetaData _meta; - public MetaData Meta - { - get { return _meta; } - set - { - _meta = value; - NotifyPropertyChanged("Meta"); - } - } - - public event PropertyChangedEventHandler PropertyChanged; - protected void NotifyPropertyChanged(String propertyName) - { - if (PropertyChanged != null) - { - Deployment.Current.Dispatcher.BeginInvoke(() => - PropertyChanged(this, new PropertyChangedEventArgs(propertyName))); - } - } - } -} diff --git a/DropNet.Samples/DropNet.Samples.WP7/packages.config b/DropNet.Samples/DropNet.Samples.WP7/packages.config deleted file mode 100644 index 68c0e92..0000000 --- a/DropNet.Samples/DropNet.Samples.WP7/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file From aecee0a8fb3fe06c27cf5e6fe7a693253b16631c Mon Sep 17 00:00:00 2001 From: Damian Karzon Date: Sat, 24 Jan 2015 10:15:50 +1300 Subject: [PATCH 32/43] Sample projects are now in https://github.com/DropNet/DropNet.Samples --- DropNet.Samples/DropNet.Samples.VB/App.config | 6 - .../DropNet.Samples.VB.vbproj | 140 - .../DropNet.Samples.VB/Form1.Designer.vb | 50 - DropNet.Samples/DropNet.Samples.VB/Form1.resx | 120 - DropNet.Samples/DropNet.Samples.VB/Form1.vb | 17 - .../My Project/Application.Designer.vb | 38 - .../My Project/Application.myapp | 11 - .../My Project/AssemblyInfo.vb | 35 - .../My Project/Resources.Designer.vb | 62 - .../My Project/Resources.resx | 117 - .../My Project/Settings.Designer.vb | 73 - .../My Project/Settings.settings | 7 - .../DropNet.Samples.VB/packages.config | 5 - .../DropNet.Samples.Web/About.aspx | 13 - .../DropNet.Samples.Web/About.aspx.cs | 17 - .../About.aspx.designer.cs | 17 - .../Account/ChangePassword.aspx | 60 - .../Account/ChangePassword.aspx.cs | 17 - .../Account/ChangePassword.aspx.designer.cs | 26 - .../Account/ChangePasswordSuccess.aspx | 13 - .../Account/ChangePasswordSuccess.aspx.cs | 17 - .../ChangePasswordSuccess.aspx.designer.cs | 17 - .../DropNet.Samples.Web/Account/Login.aspx | 49 - .../DropNet.Samples.Web/Account/Login.aspx.cs | 17 - .../Account/Login.aspx.designer.cs | 35 - .../DropNet.Samples.Web/Account/Register.aspx | 75 - .../Account/Register.aspx.cs | 32 - .../Account/Register.aspx.designer.cs | 35 - .../DropNet.Samples.Web/Account/Web.config | 18 - .../DropNet.Samples.Web/Default.aspx | 12 - .../DropNet.Samples.Web/Default.aspx.cs | 47 - .../Default.aspx.designer.cs | 33 - .../DropNet.Samples.Web.csproj | 175 - .../DropNet.Samples.Web/Global.asax | 1 - .../DropNet.Samples.Web/Global.asax.cs | 47 - .../Properties/AssemblyInfo.cs | 35 - .../Scripts/jquery-1.4.1-vsdoc.js | 8061 ----------------- .../Scripts/jquery-1.4.1.js | 6111 ------------- .../Scripts/jquery-1.4.1.min.js | 167 - .../DropNet.Samples.Web/Site.Master | 43 - .../DropNet.Samples.Web/Site.Master.cs | 17 - .../Site.Master.designer.cs | 42 - .../DropNet.Samples.Web/Styles/Site.css | 294 - .../DropNet.Samples.Web/Web.Debug.config | 30 - .../DropNet.Samples.Web/Web.Release.config | 31 - .../DropNet.Samples.Web/Web.config | 52 - .../DropNet.Samples.Web/packages.config | 5 - .../DropNet.Samples.WinForms.sln | 20 - .../DropNet.Samples.WinForms.csproj | 92 - .../Form1.Designer.cs | 72 - .../DropNet.Samples.WinForms/Form1.cs | 95 - .../DropNet.Samples.WinForms/Form1.resx | 120 - .../DropNet.Samples.WinForms/Program.cs | 21 - .../Properties/AssemblyInfo.cs | 36 - .../Properties/Resources.Designer.cs | 71 - .../Properties/Resources.resx | 117 - .../Properties/Settings.Designer.cs | 30 - .../Properties/Settings.settings | 7 - .../DropNet.Samples.WinForms/packages.config | 4 - .../DropNet.1.9.3/DropNet.1.9.3.nupkg | Bin 163396 -> 0 bytes .../DropNet.1.9.3/lib/net35/DropNet.dll | Bin 32768 -> 0 bytes .../DropNet.1.9.3/lib/net35/RestSharp.dll | Bin 157184 -> 0 bytes .../lib/sl4-wp71/DropNet.WindowsPhone.dll | Bin 29696 -> 0 bytes .../lib/sl4-wp71/RestSharp.WindowsPhone.dll | Bin 178176 -> 0 bytes .../packages/repositories.config | 4 - DropNet.Samples/DropNet.Samples.sln | 58 - .../DropNet.1.8.3/DropNet.1.8.3.nupkg | Bin 235147 -> 0 bytes .../DropNet.1.8.3/lib/net35/DropNet.dll | Bin 33280 -> 0 bytes .../DropNet.1.8.3/lib/net35/RestSharp.dll | Bin 128512 -> 0 bytes .../lib/sl3-wp/DropNet.WindowsPhone.dll | Bin 29184 -> 0 bytes .../lib/sl3-wp/RestSharp.WindowsPhone.dll | Bin 106496 -> 0 bytes .../lib/sl4-wp71/DropNet.WindowsPhone.dll | Bin 29184 -> 0 bytes .../sl4-wp71/RestSharp.WindowsPhoneMango.dll | Bin 106496 -> 0 bytes .../Newtonsoft.Json.4.0.5.nupkg | Bin 3249991 -> 0 bytes .../lib/net20/Newtonsoft.Json.dll | Bin 375296 -> 0 bytes .../lib/net20/Newtonsoft.Json.xml | 7859 ---------------- .../lib/net35/Newtonsoft.Json.dll | Bin 335360 -> 0 bytes .../lib/net35/Newtonsoft.Json.xml | 6982 -------------- .../lib/net40/Newtonsoft.Json.dll | Bin 358400 -> 0 bytes .../lib/net40/Newtonsoft.Json.xml | 7141 --------------- .../lib/sl3-wp/Newtonsoft.Json.dll | Bin 305152 -> 0 bytes .../lib/sl3-wp/Newtonsoft.Json.xml | 6574 -------------- .../sl4-windowsphone71/Newtonsoft.Json.dll | Bin 305152 -> 0 bytes .../sl4-windowsphone71/Newtonsoft.Json.xml | 6574 -------------- .../lib/sl4/Newtonsoft.Json.dll | Bin 308736 -> 0 bytes .../lib/sl4/Newtonsoft.Json.xml | 6604 -------------- DropNet.Samples/packages/repositories.config | 6 - 87 files changed, 58829 deletions(-) delete mode 100644 DropNet.Samples/DropNet.Samples.VB/App.config delete mode 100644 DropNet.Samples/DropNet.Samples.VB/DropNet.Samples.VB.vbproj delete mode 100644 DropNet.Samples/DropNet.Samples.VB/Form1.Designer.vb delete mode 100644 DropNet.Samples/DropNet.Samples.VB/Form1.resx delete mode 100644 DropNet.Samples/DropNet.Samples.VB/Form1.vb delete mode 100644 DropNet.Samples/DropNet.Samples.VB/My Project/Application.Designer.vb delete mode 100644 DropNet.Samples/DropNet.Samples.VB/My Project/Application.myapp delete mode 100644 DropNet.Samples/DropNet.Samples.VB/My Project/AssemblyInfo.vb delete mode 100644 DropNet.Samples/DropNet.Samples.VB/My Project/Resources.Designer.vb delete mode 100644 DropNet.Samples/DropNet.Samples.VB/My Project/Resources.resx delete mode 100644 DropNet.Samples/DropNet.Samples.VB/My Project/Settings.Designer.vb delete mode 100644 DropNet.Samples/DropNet.Samples.VB/My Project/Settings.settings delete mode 100644 DropNet.Samples/DropNet.Samples.VB/packages.config delete mode 100644 DropNet.Samples/DropNet.Samples.Web/About.aspx delete mode 100644 DropNet.Samples/DropNet.Samples.Web/About.aspx.cs delete mode 100644 DropNet.Samples/DropNet.Samples.Web/About.aspx.designer.cs delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Account/ChangePassword.aspx delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Account/ChangePassword.aspx.cs delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Account/ChangePassword.aspx.designer.cs delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Account/ChangePasswordSuccess.aspx delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Account/ChangePasswordSuccess.aspx.cs delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Account/ChangePasswordSuccess.aspx.designer.cs delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Account/Login.aspx delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Account/Login.aspx.cs delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Account/Login.aspx.designer.cs delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Account/Register.aspx delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Account/Register.aspx.cs delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Account/Register.aspx.designer.cs delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Account/Web.config delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Default.aspx delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Default.aspx.cs delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Default.aspx.designer.cs delete mode 100644 DropNet.Samples/DropNet.Samples.Web/DropNet.Samples.Web.csproj delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Global.asax delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Global.asax.cs delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Properties/AssemblyInfo.cs delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Scripts/jquery-1.4.1-vsdoc.js delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Scripts/jquery-1.4.1.js delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Scripts/jquery-1.4.1.min.js delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Site.Master delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Site.Master.cs delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Site.Master.designer.cs delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Styles/Site.css delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Web.Debug.config delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Web.Release.config delete mode 100644 DropNet.Samples/DropNet.Samples.Web/Web.config delete mode 100644 DropNet.Samples/DropNet.Samples.Web/packages.config delete mode 100644 DropNet.Samples/DropNet.Samples.WinForms/DropNet.Samples.WinForms.sln delete mode 100644 DropNet.Samples/DropNet.Samples.WinForms/DropNet.Samples.WinForms/DropNet.Samples.WinForms.csproj delete mode 100644 DropNet.Samples/DropNet.Samples.WinForms/DropNet.Samples.WinForms/Form1.Designer.cs delete mode 100644 DropNet.Samples/DropNet.Samples.WinForms/DropNet.Samples.WinForms/Form1.cs delete mode 100644 DropNet.Samples/DropNet.Samples.WinForms/DropNet.Samples.WinForms/Form1.resx delete mode 100644 DropNet.Samples/DropNet.Samples.WinForms/DropNet.Samples.WinForms/Program.cs delete mode 100644 DropNet.Samples/DropNet.Samples.WinForms/DropNet.Samples.WinForms/Properties/AssemblyInfo.cs delete mode 100644 DropNet.Samples/DropNet.Samples.WinForms/DropNet.Samples.WinForms/Properties/Resources.Designer.cs delete mode 100644 DropNet.Samples/DropNet.Samples.WinForms/DropNet.Samples.WinForms/Properties/Resources.resx delete mode 100644 DropNet.Samples/DropNet.Samples.WinForms/DropNet.Samples.WinForms/Properties/Settings.Designer.cs delete mode 100644 DropNet.Samples/DropNet.Samples.WinForms/DropNet.Samples.WinForms/Properties/Settings.settings delete mode 100644 DropNet.Samples/DropNet.Samples.WinForms/DropNet.Samples.WinForms/packages.config delete mode 100644 DropNet.Samples/DropNet.Samples.WinForms/packages/DropNet.1.9.3/DropNet.1.9.3.nupkg delete mode 100644 DropNet.Samples/DropNet.Samples.WinForms/packages/DropNet.1.9.3/lib/net35/DropNet.dll delete mode 100644 DropNet.Samples/DropNet.Samples.WinForms/packages/DropNet.1.9.3/lib/net35/RestSharp.dll delete mode 100644 DropNet.Samples/DropNet.Samples.WinForms/packages/DropNet.1.9.3/lib/sl4-wp71/DropNet.WindowsPhone.dll delete mode 100644 DropNet.Samples/DropNet.Samples.WinForms/packages/DropNet.1.9.3/lib/sl4-wp71/RestSharp.WindowsPhone.dll delete mode 100644 DropNet.Samples/DropNet.Samples.WinForms/packages/repositories.config delete mode 100644 DropNet.Samples/DropNet.Samples.sln delete mode 100644 DropNet.Samples/packages/DropNet.1.8.3/DropNet.1.8.3.nupkg delete mode 100644 DropNet.Samples/packages/DropNet.1.8.3/lib/net35/DropNet.dll delete mode 100644 DropNet.Samples/packages/DropNet.1.8.3/lib/net35/RestSharp.dll delete mode 100644 DropNet.Samples/packages/DropNet.1.8.3/lib/sl3-wp/DropNet.WindowsPhone.dll delete mode 100644 DropNet.Samples/packages/DropNet.1.8.3/lib/sl3-wp/RestSharp.WindowsPhone.dll delete mode 100644 DropNet.Samples/packages/DropNet.1.8.3/lib/sl4-wp71/DropNet.WindowsPhone.dll delete mode 100644 DropNet.Samples/packages/DropNet.1.8.3/lib/sl4-wp71/RestSharp.WindowsPhoneMango.dll delete mode 100644 DropNet.Samples/packages/Newtonsoft.Json.4.0.5/Newtonsoft.Json.4.0.5.nupkg delete mode 100644 DropNet.Samples/packages/Newtonsoft.Json.4.0.5/lib/net20/Newtonsoft.Json.dll delete mode 100644 DropNet.Samples/packages/Newtonsoft.Json.4.0.5/lib/net20/Newtonsoft.Json.xml delete mode 100644 DropNet.Samples/packages/Newtonsoft.Json.4.0.5/lib/net35/Newtonsoft.Json.dll delete mode 100644 DropNet.Samples/packages/Newtonsoft.Json.4.0.5/lib/net35/Newtonsoft.Json.xml delete mode 100644 DropNet.Samples/packages/Newtonsoft.Json.4.0.5/lib/net40/Newtonsoft.Json.dll delete mode 100644 DropNet.Samples/packages/Newtonsoft.Json.4.0.5/lib/net40/Newtonsoft.Json.xml delete mode 100644 DropNet.Samples/packages/Newtonsoft.Json.4.0.5/lib/sl3-wp/Newtonsoft.Json.dll delete mode 100644 DropNet.Samples/packages/Newtonsoft.Json.4.0.5/lib/sl3-wp/Newtonsoft.Json.xml delete mode 100644 DropNet.Samples/packages/Newtonsoft.Json.4.0.5/lib/sl4-windowsphone71/Newtonsoft.Json.dll delete mode 100644 DropNet.Samples/packages/Newtonsoft.Json.4.0.5/lib/sl4-windowsphone71/Newtonsoft.Json.xml delete mode 100644 DropNet.Samples/packages/Newtonsoft.Json.4.0.5/lib/sl4/Newtonsoft.Json.dll delete mode 100644 DropNet.Samples/packages/Newtonsoft.Json.4.0.5/lib/sl4/Newtonsoft.Json.xml delete mode 100644 DropNet.Samples/packages/repositories.config diff --git a/DropNet.Samples/DropNet.Samples.VB/App.config b/DropNet.Samples/DropNet.Samples.VB/App.config deleted file mode 100644 index 64f3722..0000000 --- a/DropNet.Samples/DropNet.Samples.VB/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/DropNet.Samples/DropNet.Samples.VB/DropNet.Samples.VB.vbproj b/DropNet.Samples/DropNet.Samples.VB/DropNet.Samples.VB.vbproj deleted file mode 100644 index 681dff9..0000000 --- a/DropNet.Samples/DropNet.Samples.VB/DropNet.Samples.VB.vbproj +++ /dev/null @@ -1,140 +0,0 @@ - - - - Debug - x86 - - - 2.0 - {87DEB9FD-4BD8-44A5-839E-E4FADE7E1AF5} - WinExe - DropNet.Samples.VB.My.MyApplication - DropNet.Samples.VB - DropNet.Samples.VB - 512 - WindowsForms - v4.0 - Client - - - x86 - true - full - true - true - bin\Debug\ - DropNet.Samples.VB.xml - 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 - - - x86 - pdbonly - false - true - true - bin\Release\ - DropNet.Samples.VB.xml - 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 - - - On - - - Binary - - - Off - - - On - - - - False - ..\packages\DropNet.1.8.3\lib\net35\DropNet.dll - - - False - ..\packages\Newtonsoft.Json.4.0.5\lib\net40\Newtonsoft.Json.dll - - - ..\packages\DropNet.1.8.3\lib\net35\RestSharp.dll - - - - - - - - - - - - - - - - - - - - - - - - - - Form - - - Form1.vb - Form - - - - True - Application.myapp - - - True - True - Resources.resx - - - True - Settings.settings - True - - - - - Form1.vb - - - VbMyResourcesResXFileCodeGenerator - Resources.Designer.vb - My.Resources - Designer - - - - - MyApplicationCodeGenerator - Application.Designer.vb - - - SettingsSingleFileGenerator - My - Settings.Designer.vb - - - - - - \ No newline at end of file diff --git a/DropNet.Samples/DropNet.Samples.VB/Form1.Designer.vb b/DropNet.Samples/DropNet.Samples.VB/Form1.Designer.vb deleted file mode 100644 index c5e8b58..0000000 --- a/DropNet.Samples/DropNet.Samples.VB/Form1.Designer.vb +++ /dev/null @@ -1,50 +0,0 @@ - _ -Partial Class Form1 - Inherits System.Windows.Forms.Form - - 'Form overrides dispose to clean up the component list. - _ - Protected Overrides Sub Dispose(ByVal disposing As Boolean) - Try - If disposing AndAlso components IsNot Nothing Then - components.Dispose() - End If - Finally - MyBase.Dispose(disposing) - End Try - End Sub - - 'Required by the Windows Form Designer - Private components As System.ComponentModel.IContainer - - 'NOTE: The following procedure is required by the Windows Form Designer - 'It can be modified using the Windows Form Designer. - 'Do not modify it using the code editor. - _ - Private Sub InitializeComponent() - Me.Button1 = New System.Windows.Forms.Button() - Me.SuspendLayout() - ' - 'Button1 - ' - Me.Button1.Location = New System.Drawing.Point(12, 12) - Me.Button1.Name = "Button1" - Me.Button1.Size = New System.Drawing.Size(75, 23) - Me.Button1.TabIndex = 0 - Me.Button1.Text = "TEST" - Me.Button1.UseVisualStyleBackColor = True - ' - 'Form1 - ' - Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) - Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font - Me.ClientSize = New System.Drawing.Size(284, 261) - Me.Controls.Add(Me.Button1) - Me.Name = "Form1" - Me.Text = "Form1" - Me.ResumeLayout(False) - - End Sub - Friend WithEvents Button1 As System.Windows.Forms.Button - -End Class diff --git a/DropNet.Samples/DropNet.Samples.VB/Form1.resx b/DropNet.Samples/DropNet.Samples.VB/Form1.resx deleted file mode 100644 index 1af7de1..0000000 --- a/DropNet.Samples/DropNet.Samples.VB/Form1.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/DropNet.Samples/DropNet.Samples.VB/Form1.vb b/DropNet.Samples/DropNet.Samples.VB/Form1.vb deleted file mode 100644 index dd7386d..0000000 --- a/DropNet.Samples/DropNet.Samples.VB/Form1.vb +++ /dev/null @@ -1,17 +0,0 @@ -Public Class Form1 - - Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click - Dim client As New DropNetClient("API", "SECRET") - - client.Account_InfoAsync(AddressOf AccountInfo_Success, AddressOf AccountInfo_Fail) - End Sub - - Private Sub AccountInfo_Success(accountInfo As DropNet.Models.AccountInfo) - 'Do something with accountInfo - End Sub - - Private Sub AccountInfo_Fail(ex As DropNet.Exceptions.DropboxException) - 'Failed to get AccountInfo - End Sub - -End Class diff --git a/DropNet.Samples/DropNet.Samples.VB/My Project/Application.Designer.vb b/DropNet.Samples/DropNet.Samples.VB/My Project/Application.Designer.vb deleted file mode 100644 index 41510ec..0000000 --- a/DropNet.Samples/DropNet.Samples.VB/My Project/Application.Designer.vb +++ /dev/null @@ -1,38 +0,0 @@ -'------------------------------------------------------------------------------ -' -' This code was generated by a tool. -' Runtime Version:4.0.30319.431 -' -' Changes to this file may cause incorrect behavior and will be lost if -' the code is regenerated. -' -'------------------------------------------------------------------------------ - -Option Strict On -Option Explicit On - - -Namespace My - - 'NOTE: This file is auto-generated; do not modify it directly. To make changes, - ' or if you encounter build errors in this file, go to the Project Designer - ' (go to Project Properties or double-click the My Project node in - ' Solution Explorer), and make changes on the Application tab. - ' - Partial Friend Class MyApplication - - _ - Public Sub New() - MyBase.New(Global.Microsoft.VisualBasic.ApplicationServices.AuthenticationMode.Windows) - Me.IsSingleInstance = false - Me.EnableVisualStyles = true - Me.SaveMySettingsOnExit = true - Me.ShutDownStyle = Global.Microsoft.VisualBasic.ApplicationServices.ShutdownMode.AfterMainFormCloses - End Sub - - _ - Protected Overrides Sub OnCreateMainForm() - Me.MainForm = Global.DropNet.Samples.VB.Form1 - End Sub - End Class -End Namespace diff --git a/DropNet.Samples/DropNet.Samples.VB/My Project/Application.myapp b/DropNet.Samples/DropNet.Samples.VB/My Project/Application.myapp deleted file mode 100644 index 1243847..0000000 --- a/DropNet.Samples/DropNet.Samples.VB/My Project/Application.myapp +++ /dev/null @@ -1,11 +0,0 @@ - - - true - Form1 - false - 0 - true - 0 - 0 - true - diff --git a/DropNet.Samples/DropNet.Samples.VB/My Project/AssemblyInfo.vb b/DropNet.Samples/DropNet.Samples.VB/My Project/AssemblyInfo.vb deleted file mode 100644 index 9692e65..0000000 --- a/DropNet.Samples/DropNet.Samples.VB/My Project/AssemblyInfo.vb +++ /dev/null @@ -1,35 +0,0 @@ -Imports System -Imports System.Reflection -Imports System.Runtime.InteropServices - -' General Information about an assembly is controlled through the following -' set of attributes. Change these attribute values to modify the information -' associated with an assembly. - -' Review the values of the assembly attributes - - - - - - - - - - -'The following GUID is for the ID of the typelib if this project is exposed to COM - - -' Version information for an assembly consists of the following four values: -' -' Major Version -' Minor Version -' Build Number -' Revision -' -' You can specify all the values or you can default the Build and Revision Numbers -' by using the '*' as shown below: -' - - - diff --git a/DropNet.Samples/DropNet.Samples.VB/My Project/Resources.Designer.vb b/DropNet.Samples/DropNet.Samples.VB/My Project/Resources.Designer.vb deleted file mode 100644 index acbecb3..0000000 --- a/DropNet.Samples/DropNet.Samples.VB/My Project/Resources.Designer.vb +++ /dev/null @@ -1,62 +0,0 @@ -'------------------------------------------------------------------------------ -' -' This code was generated by a tool. -' Runtime Version:4.0.30319.431 -' -' Changes to this file may cause incorrect behavior and will be lost if -' the code is regenerated. -' -'------------------------------------------------------------------------------ - -Option Strict On -Option Explicit On - - -Namespace My.Resources - - 'This class was auto-generated by the StronglyTypedResourceBuilder - 'class via a tool like ResGen or Visual Studio. - 'To add or remove a member, edit your .ResX file then rerun ResGen - 'with the /str option, or rebuild your VS project. - ''' - ''' A strongly-typed resource class, for looking up localized strings, etc. - ''' - _ - Friend Module Resources - - Private resourceMan As Global.System.Resources.ResourceManager - - Private resourceCulture As Global.System.Globalization.CultureInfo - - ''' - ''' Returns the cached ResourceManager instance used by this class. - ''' - _ - Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager - Get - If Object.ReferenceEquals(resourceMan, Nothing) Then - Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("DropNet.Samples.VB.Resources", GetType(Resources).Assembly) - resourceMan = temp - End If - Return resourceMan - End Get - End Property - - ''' - ''' Overrides the current thread's CurrentUICulture property for all - ''' resource lookups using this strongly typed resource class. - ''' - _ - Friend Property Culture() As Global.System.Globalization.CultureInfo - Get - Return resourceCulture - End Get - Set(ByVal value As Global.System.Globalization.CultureInfo) - resourceCulture = value - End Set - End Property - End Module -End Namespace diff --git a/DropNet.Samples/DropNet.Samples.VB/My Project/Resources.resx b/DropNet.Samples/DropNet.Samples.VB/My Project/Resources.resx deleted file mode 100644 index af7dbeb..0000000 --- a/DropNet.Samples/DropNet.Samples.VB/My Project/Resources.resx +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/DropNet.Samples/DropNet.Samples.VB/My Project/Settings.Designer.vb b/DropNet.Samples/DropNet.Samples.VB/My Project/Settings.Designer.vb deleted file mode 100644 index aba0e6f..0000000 --- a/DropNet.Samples/DropNet.Samples.VB/My Project/Settings.Designer.vb +++ /dev/null @@ -1,73 +0,0 @@ -'------------------------------------------------------------------------------ -' -' This code was generated by a tool. -' Runtime Version:4.0.30319.431 -' -' Changes to this file may cause incorrect behavior and will be lost if -' the code is regenerated. -' -'------------------------------------------------------------------------------ - -Option Strict On -Option Explicit On - - -Namespace My - - _ - Partial Friend NotInheritable Class MySettings - Inherits Global.System.Configuration.ApplicationSettingsBase - - Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) - -#Region "My.Settings Auto-Save Functionality" -#If _MyType = "WindowsForms" Then - Private Shared addedHandler As Boolean - - Private Shared addedHandlerLockObject As New Object - - _ - Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs) - If My.Application.SaveMySettingsOnExit Then - My.Settings.Save() - End If - End Sub -#End If -#End Region - - Public Shared ReadOnly Property [Default]() As MySettings - Get - -#If _MyType = "WindowsForms" Then - If Not addedHandler Then - SyncLock addedHandlerLockObject - If Not addedHandler Then - AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings - addedHandler = True - End If - End SyncLock - End If -#End If - Return defaultInstance - End Get - End Property - End Class -End Namespace - -Namespace My - - _ - Friend Module MySettingsProperty - - _ - Friend ReadOnly Property Settings() As Global.DropNet.Samples.VB.My.MySettings - Get - Return Global.DropNet.Samples.VB.My.MySettings.Default - End Get - End Property - End Module -End Namespace diff --git a/DropNet.Samples/DropNet.Samples.VB/My Project/Settings.settings b/DropNet.Samples/DropNet.Samples.VB/My Project/Settings.settings deleted file mode 100644 index 85b890b..0000000 --- a/DropNet.Samples/DropNet.Samples.VB/My Project/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/DropNet.Samples/DropNet.Samples.VB/packages.config b/DropNet.Samples/DropNet.Samples.VB/packages.config deleted file mode 100644 index 68c0e92..0000000 --- a/DropNet.Samples/DropNet.Samples.VB/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/DropNet.Samples/DropNet.Samples.Web/About.aspx b/DropNet.Samples/DropNet.Samples.Web/About.aspx deleted file mode 100644 index 8856366..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/About.aspx +++ /dev/null @@ -1,13 +0,0 @@ -<%@ Page Title="About Us" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" - CodeBehind="About.aspx.cs" Inherits="DropNet.Samples.Web.About" %> - - - - -

- About -

-

- Put content here. -

-
diff --git a/DropNet.Samples/DropNet.Samples.Web/About.aspx.cs b/DropNet.Samples/DropNet.Samples.Web/About.aspx.cs deleted file mode 100644 index 219edd4..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/About.aspx.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using System.Web.UI; -using System.Web.UI.WebControls; - -namespace DropNet.Samples.Web -{ - public partial class About : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - - } - } -} diff --git a/DropNet.Samples/DropNet.Samples.Web/About.aspx.designer.cs b/DropNet.Samples/DropNet.Samples.Web/About.aspx.designer.cs deleted file mode 100644 index 499d88b..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/About.aspx.designer.cs +++ /dev/null @@ -1,17 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace DropNet.Samples.Web -{ - - - public partial class About - { - } -} diff --git a/DropNet.Samples/DropNet.Samples.Web/Account/ChangePassword.aspx b/DropNet.Samples/DropNet.Samples.Web/Account/ChangePassword.aspx deleted file mode 100644 index 64f2eeb..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/Account/ChangePassword.aspx +++ /dev/null @@ -1,60 +0,0 @@ -<%@ Page Title="Change Password" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" - CodeBehind="ChangePassword.aspx.cs" Inherits="DropNet.Samples.Web.Account.ChangePassword" %> - - - - -

- Change Password -

-

- Use the form below to change your password. -

-

- New passwords are required to be a minimum of <%= Membership.MinRequiredPasswordLength %> characters in length. -

- - - - - - -
-
- Account Information -

- Old Password: - - * -

-

- New Password: - - * -

-

- Confirm New Password: - - * - * -

-
-

- - -

-
-
-
-
diff --git a/DropNet.Samples/DropNet.Samples.Web/Account/ChangePassword.aspx.cs b/DropNet.Samples/DropNet.Samples.Web/Account/ChangePassword.aspx.cs deleted file mode 100644 index 23f1772..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/Account/ChangePassword.aspx.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using System.Web.UI; -using System.Web.UI.WebControls; - -namespace DropNet.Samples.Web.Account -{ - public partial class ChangePassword : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - - } - } -} diff --git a/DropNet.Samples/DropNet.Samples.Web/Account/ChangePassword.aspx.designer.cs b/DropNet.Samples/DropNet.Samples.Web/Account/ChangePassword.aspx.designer.cs deleted file mode 100644 index ebfec85..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/Account/ChangePassword.aspx.designer.cs +++ /dev/null @@ -1,26 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace DropNet.Samples.Web.Account -{ - - - public partial class ChangePassword - { - - /// - /// ChangeUserPassword control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.ChangePassword ChangeUserPassword; - } -} diff --git a/DropNet.Samples/DropNet.Samples.Web/Account/ChangePasswordSuccess.aspx b/DropNet.Samples/DropNet.Samples.Web/Account/ChangePasswordSuccess.aspx deleted file mode 100644 index 125b845..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/Account/ChangePasswordSuccess.aspx +++ /dev/null @@ -1,13 +0,0 @@ -<%@ Page Title="Change Password" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" - CodeBehind="ChangePasswordSuccess.aspx.cs" Inherits="DropNet.Samples.Web.Account.ChangePasswordSuccess" %> - - - - -

- Change Password -

-

- Your password has been changed successfully. -

-
diff --git a/DropNet.Samples/DropNet.Samples.Web/Account/ChangePasswordSuccess.aspx.cs b/DropNet.Samples/DropNet.Samples.Web/Account/ChangePasswordSuccess.aspx.cs deleted file mode 100644 index 3b1b265..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/Account/ChangePasswordSuccess.aspx.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using System.Web.UI; -using System.Web.UI.WebControls; - -namespace DropNet.Samples.Web.Account -{ - public partial class ChangePasswordSuccess : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - - } - } -} diff --git a/DropNet.Samples/DropNet.Samples.Web/Account/ChangePasswordSuccess.aspx.designer.cs b/DropNet.Samples/DropNet.Samples.Web/Account/ChangePasswordSuccess.aspx.designer.cs deleted file mode 100644 index 4e4a230..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/Account/ChangePasswordSuccess.aspx.designer.cs +++ /dev/null @@ -1,17 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace DropNet.Samples.Web.Account -{ - - - public partial class ChangePasswordSuccess - { - } -} diff --git a/DropNet.Samples/DropNet.Samples.Web/Account/Login.aspx b/DropNet.Samples/DropNet.Samples.Web/Account/Login.aspx deleted file mode 100644 index ad00826..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/Account/Login.aspx +++ /dev/null @@ -1,49 +0,0 @@ -<%@ Page Title="Log In" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" - CodeBehind="Login.aspx.cs" Inherits="DropNet.Samples.Web.Account.Login" %> - - - - -

- Log In -

-

- Please enter your username and password. - Register if you don't have an account. -

- - - - - - -
- -

- -

-
-
-
-
diff --git a/DropNet.Samples/DropNet.Samples.Web/Account/Login.aspx.cs b/DropNet.Samples/DropNet.Samples.Web/Account/Login.aspx.cs deleted file mode 100644 index dbd3aec..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/Account/Login.aspx.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using System.Web.UI; -using System.Web.UI.WebControls; - -namespace DropNet.Samples.Web.Account -{ - public partial class Login : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - RegisterHyperLink.NavigateUrl = "Register.aspx?ReturnUrl=" + HttpUtility.UrlEncode(Request.QueryString["ReturnUrl"]); - } - } -} diff --git a/DropNet.Samples/DropNet.Samples.Web/Account/Login.aspx.designer.cs b/DropNet.Samples/DropNet.Samples.Web/Account/Login.aspx.designer.cs deleted file mode 100644 index 11f4c23..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/Account/Login.aspx.designer.cs +++ /dev/null @@ -1,35 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace DropNet.Samples.Web.Account -{ - - - public partial class Login - { - - /// - /// RegisterHyperLink control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.HyperLink RegisterHyperLink; - - /// - /// LoginUser control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Login LoginUser; - } -} diff --git a/DropNet.Samples/DropNet.Samples.Web/Account/Register.aspx b/DropNet.Samples/DropNet.Samples.Web/Account/Register.aspx deleted file mode 100644 index cbd8b17..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/Account/Register.aspx +++ /dev/null @@ -1,75 +0,0 @@ -<%@ Page Title="Register" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" - CodeBehind="Register.aspx.cs" Inherits="DropNet.Samples.Web.Account.Register" %> - - - - - - - - - - - - -

- Create a New Account -

-

- Use the form below to create a new account. -

-

- Passwords are required to be a minimum of <%= Membership.MinRequiredPasswordLength %> characters in length. -

- - - - -
-
- Account Information -

- User Name: - - * -

-

- E-mail: - - * -

-

- Password: - - * -

-

- Confirm Password: - - * - * -

-
-

- -

-
-
- - -
-
-
-
diff --git a/DropNet.Samples/DropNet.Samples.Web/Account/Register.aspx.cs b/DropNet.Samples/DropNet.Samples.Web/Account/Register.aspx.cs deleted file mode 100644 index 0ee3846..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/Account/Register.aspx.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using System.Web.Security; -using System.Web.UI; -using System.Web.UI.WebControls; - -namespace DropNet.Samples.Web.Account -{ - public partial class Register : System.Web.UI.Page - { - - protected void Page_Load(object sender, EventArgs e) - { - RegisterUser.ContinueDestinationPageUrl = Request.QueryString["ReturnUrl"]; - } - - protected void RegisterUser_CreatedUser(object sender, EventArgs e) - { - FormsAuthentication.SetAuthCookie(RegisterUser.UserName, false /* createPersistentCookie */); - - string continueUrl = RegisterUser.ContinueDestinationPageUrl; - if (String.IsNullOrEmpty(continueUrl)) - { - continueUrl = "~/"; - } - Response.Redirect(continueUrl); - } - - } -} diff --git a/DropNet.Samples/DropNet.Samples.Web/Account/Register.aspx.designer.cs b/DropNet.Samples/DropNet.Samples.Web/Account/Register.aspx.designer.cs deleted file mode 100644 index ea3ed4b..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/Account/Register.aspx.designer.cs +++ /dev/null @@ -1,35 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace DropNet.Samples.Web.Account -{ - - - public partial class Register - { - - /// - /// RegisterUser control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.CreateUserWizard RegisterUser; - - /// - /// RegisterUserWizardStep control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.CreateUserWizardStep RegisterUserWizardStep; - } -} diff --git a/DropNet.Samples/DropNet.Samples.Web/Account/Web.config b/DropNet.Samples/DropNet.Samples.Web/Account/Web.config deleted file mode 100644 index 84a802a..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/Account/Web.config +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/DropNet.Samples/DropNet.Samples.Web/Default.aspx b/DropNet.Samples/DropNet.Samples.Web/Default.aspx deleted file mode 100644 index d7a97e7..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/Default.aspx +++ /dev/null @@ -1,12 +0,0 @@ -<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" - CodeBehind="Default.aspx.cs" Inherits="DropNet.Samples.Web._Default" %> - - - - -

- Click the button to start. -

- - -
diff --git a/DropNet.Samples/DropNet.Samples.Web/Default.aspx.cs b/DropNet.Samples/DropNet.Samples.Web/Default.aspx.cs deleted file mode 100644 index 4f568eb..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/Default.aspx.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using System.Web.UI; -using System.Web.UI.WebControls; - -namespace DropNet.Samples.Web -{ - public partial class _Default : System.Web.UI.Page - { - //////////////////////////////////////////////////// - // NOTE: This key is a Development only key setup for this sample and will only work with my login. - // MAKE SURE YOU CHANGE IT OR IT WONT WORK! - //////////////////////////////////////////////////// - DropNetClient _client = new DropNetClient("9m6v782a7aeop0w", "dbd11uqce6hr8zg"); - - protected void Page_Load(object sender, EventArgs e) - { - if (Request.Params["dropboxcallback"] == "1") - { - //Its a callback from dropbox! - if (Session["DropNetUserLogin"] != null) - { - _client.UserLogin = Session["DropNetUserLogin"] as DropNet.Models.UserLogin; - Session["DropNetUserLogin"] = _client.GetAccessToken(); - - var accountinfo = _client.Account_Info(); - litOutput.Text = accountinfo.quota_info.quota.ToString(); - } - else - { - litOutput.Text = "Session expired..."; - } - } - } - - protected void btnStart_Click(object sender, EventArgs e) - { - Session["DropNetUserLogin"] = _client.GetToken(); - - var url = _client.BuildAuthorizeUrl(Request.Url.ToString() + "?dropboxcallback=1"); - - Response.Redirect(url); - } - } -} diff --git a/DropNet.Samples/DropNet.Samples.Web/Default.aspx.designer.cs b/DropNet.Samples/DropNet.Samples.Web/Default.aspx.designer.cs deleted file mode 100644 index 0678954..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/Default.aspx.designer.cs +++ /dev/null @@ -1,33 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace DropNet.Samples.Web { - - - public partial class _Default { - - /// - /// litOutput control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Literal litOutput; - - /// - /// btnStart control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Button btnStart; - } -} diff --git a/DropNet.Samples/DropNet.Samples.Web/DropNet.Samples.Web.csproj b/DropNet.Samples/DropNet.Samples.Web/DropNet.Samples.Web.csproj deleted file mode 100644 index 8475674..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/DropNet.Samples.Web.csproj +++ /dev/null @@ -1,175 +0,0 @@ - - - - Debug - AnyCPU - - - 2.0 - {0C9AB699-2554-46AE-82FC-5017BB675072} - {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} - Library - Properties - DropNet.Samples.Web - DropNet.Samples.Web - v4.0 - false - - - true - full - false - bin\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\ - TRACE - prompt - 4 - - - - ..\packages\DropNet.1.8.3\lib\net35\DropNet.dll - - - - ..\packages\Newtonsoft.Json.4.0.5\lib\net40\Newtonsoft.Json.dll - - - ..\packages\DropNet.1.8.3\lib\net35\RestSharp.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Web.config - - - Web.config - - - - - About.aspx - ASPXCodeBehind - - - About.aspx - - - ChangePassword.aspx - ASPXCodeBehind - - - ChangePassword.aspx - - - ChangePasswordSuccess.aspx - ASPXCodeBehind - - - ChangePasswordSuccess.aspx - - - Login.aspx - ASPXCodeBehind - - - Login.aspx - - - Register.aspx - ASPXCodeBehind - - - Register.aspx - - - Default.aspx - ASPXCodeBehind - - - Default.aspx - - - Global.asax - - - - Site.Master - ASPXCodeBehind - - - Site.Master - - - - - - - - - - - - - - - - - - - False - True - 61847 - / - - - False - False - - - False - - - - - - \ No newline at end of file diff --git a/DropNet.Samples/DropNet.Samples.Web/Global.asax b/DropNet.Samples/DropNet.Samples.Web/Global.asax deleted file mode 100644 index 2b61048..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/Global.asax +++ /dev/null @@ -1 +0,0 @@ -<%@ Application Codebehind="Global.asax.cs" Inherits="DropNet.Samples.Web.Global" Language="C#" %> diff --git a/DropNet.Samples/DropNet.Samples.Web/Global.asax.cs b/DropNet.Samples/DropNet.Samples.Web/Global.asax.cs deleted file mode 100644 index 295ae04..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/Global.asax.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using System.Web.Security; -using System.Web.SessionState; - -namespace DropNet.Samples.Web -{ - public class Global : System.Web.HttpApplication - { - - void Application_Start(object sender, EventArgs e) - { - // Code that runs on application startup - - } - - void Application_End(object sender, EventArgs e) - { - // Code that runs on application shutdown - - } - - void Application_Error(object sender, EventArgs e) - { - // Code that runs when an unhandled error occurs - - } - - void Session_Start(object sender, EventArgs e) - { - // Code that runs when a new session is started - - } - - void Session_End(object sender, EventArgs e) - { - // Code that runs when a session ends. - // Note: The Session_End event is raised only when the sessionstate mode - // is set to InProc in the Web.config file. If session mode is set to StateServer - // or SQLServer, the event is not raised. - - } - - } -} diff --git a/DropNet.Samples/DropNet.Samples.Web/Properties/AssemblyInfo.cs b/DropNet.Samples/DropNet.Samples.Web/Properties/AssemblyInfo.cs deleted file mode 100644 index 51de48b..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("DropNet.Samples.Web")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("DropNet.Samples.Web")] -[assembly: AssemblyCopyright("Copyright © Microsoft 2012")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("d6179f39-7cd5-4371-995b-b8cb2d0b5a0e")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/DropNet.Samples/DropNet.Samples.Web/Scripts/jquery-1.4.1-vsdoc.js b/DropNet.Samples/DropNet.Samples.Web/Scripts/jquery-1.4.1-vsdoc.js deleted file mode 100644 index 681241d..0000000 --- a/DropNet.Samples/DropNet.Samples.Web/Scripts/jquery-1.4.1-vsdoc.js +++ /dev/null @@ -1,8061 +0,0 @@ -/* - * This file has been commented to support Visual Studio Intellisense. - * You should not use this file at runtime inside the browser--it is only - * intended to be used only for design-time IntelliSense. Please use the - * standard jQuery library for all production use. - * - * Comment version: 1.4.1a - */ - -/*! - * jQuery JavaScript Library v1.4.1 - * http://jquery.com/ - * - * Distributed in whole under the terms of the MIT - * - * Copyright 2010, John Resig - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * Copyright 2010, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * - * Date: Mon Jan 25 19:43:33 2010 -0500 - */ - -(function( window, undefined ) { - -// Define a local copy of jQuery -var jQuery = function( selector, context ) { - /// - /// 1: $(expression, context) - This function accepts a string containing a CSS selector which is then used to match a set of elements. - /// 2: $(html) - Create DOM elements on-the-fly from the provided String of raw HTML. - /// 3: $(elements) - Wrap jQuery functionality around a single or multiple DOM Element(s). - /// 4: $(callback) - A shorthand for $(document).ready(). - /// 5: $() - As of jQuery 1.4, if you pass no arguments in to the jQuery() method, an empty jQuery set will be returned. - /// - /// - /// 1: expression - An expression to search with. - /// 2: html - A string of HTML to create on the fly. - /// 3: elements - DOM element(s) to be encapsulated by a jQuery object. - /// 4: callback - The function to execute when the DOM is ready. - /// - /// - /// 1: context - A DOM Element, Document or jQuery to use as context. - /// - /// - - // The jQuery object is actually just the init constructor 'enhanced' - return new jQuery.fn.init( selector, context ); - }, - - // Map over jQuery in case of overwrite - _jQuery = window.jQuery, - - // Map over the $ in case of overwrite - _$ = window.$, - - // Use the correct document accordingly with window argument (sandbox) - document = window.document, - - // A central reference to the root jQuery(document) - rootjQuery, - - // A simple way to check for HTML strings or ID strings - // (both of which we optimize for) - quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/, - - // Is it a simple selector - isSimple = /^.[^:#\[\.,]*$/, - - // Check if a string has a non-whitespace character in it - rnotwhite = /\S/, - - // Used for trimming whitespace - rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g, - - // Match a standalone tag - rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, - - // Keep a UserAgent string for use with jQuery.browser - userAgent = navigator.userAgent, - - // For matching the engine and version of the browser - browserMatch, - - // Has the ready events already been bound? - readyBound = false, - - // The functions to execute on DOM ready - readyList = [], - - // The ready event handler - DOMContentLoaded, - - // Save a reference to some core methods - toString = Object.prototype.toString, - hasOwnProperty = Object.prototype.hasOwnProperty, - push = Array.prototype.push, - slice = Array.prototype.slice, - indexOf = Array.prototype.indexOf; - -jQuery.fn = jQuery.prototype = { - init: function( selector, context ) { - - var match, elem, ret, doc; - - // Handle $(""), $(null), or $(undefined) - if ( !selector ) { - return this; - } - - // Handle $(DOMElement) - if ( selector.nodeType ) { - this.context = this[0] = selector; - this.length = 1; - return this; - } - - // Handle HTML strings - if ( typeof selector === "string" ) { - // Are we dealing with HTML string or an ID? - match = quickExpr.exec( selector ); - - // Verify a match, and that no context was specified for #id - if ( match && (match[1] || !context) ) { - - // HANDLE: $(html) -> $(array) - if ( match[1] ) { - doc = (context ? context.ownerDocument || context : document); - - // If a single string is passed in and it's a single tag - // just do a createElement and skip the rest - ret = rsingleTag.exec( selector ); - - if ( ret ) { - if ( jQuery.isPlainObject( context ) ) { - selector = [ document.createElement( ret[1] ) ]; - jQuery.fn.attr.call( selector, context, true ); - - } else { - selector = [ doc.createElement( ret[1] ) ]; - } - - } else { - ret = buildFragment( [ match[1] ], [ doc ] ); - selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes; - } - - // HANDLE: $("#id") - } else { - elem = document.getElementById( match[2] ); - - if ( elem ) { - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id !== match[2] ) { - return rootjQuery.find( selector ); - } - - // Otherwise, we inject the element directly into the jQuery object - this.length = 1; - this[0] = elem; - } - - this.context = document; - this.selector = selector; - return this; - } - - // HANDLE: $("TAG") - } else if ( !context && /^\w+$/.test( selector ) ) { - this.selector = selector; - this.context = document; - selector = document.getElementsByTagName( selector ); - - // 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 jQuery( context ).find( selector ); - } - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) { - return rootjQuery.ready( selector ); - } - - if (selector.selector !== undefined) { - this.selector = selector.selector; - this.context = selector.context; - } - - return jQuery.isArray( selector ) ? - this.setArray( selector ) : - jQuery.makeArray( selector, this ); - }, - - // Start with an empty selector - selector: "", - - // The current version of jQuery being used - jquery: "1.4.1", - - // The default length of a jQuery object is 0 - length: 0, - - // The number of elements contained in the matched element set - size: function() { - /// - /// The number of elements currently matched. - /// Part of Core - /// - /// - - return this.length; - }, - - toArray: function() { - /// - /// Retrieve all the DOM elements contained in the jQuery set, as an array. - /// - /// - return slice.call( this, 0 ); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - /// - /// Access a single matched element. num is used to access the - /// Nth element matched. - /// Part of Core - /// - /// - /// - /// Access the element in the Nth position. - /// - - return num == null ? - - // Return a 'clean' array - this.toArray() : - - // Return just the object - ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] ); - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems, name, selector ) { - /// - /// Set the jQuery object to an array of elements, while maintaining - /// the stack. - /// Part of Core - /// - /// - /// - /// An array of elements - /// - - // Build a new jQuery matched element set - var ret = jQuery( elems || null ); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - - ret.context = this.context; - - if ( name === "find" ) { - ret.selector = this.selector + (this.selector ? " " : "") + selector; - } else if ( name ) { - ret.selector = this.selector + "." + name + "(" + selector + ")"; - } - - // Return the newly-formed element set - return ret; - }, - - // Force the current matched set of elements to become - // the specified array of elements (destroying the stack in the process) - // You should use pushStack() in order to do this, but maintain the stack - setArray: function( elems ) { - /// - /// Set the jQuery object to an array of elements. This operation is - /// completely destructive - be sure to use .pushStack() if you wish to maintain - /// the jQuery stack. - /// Part of Core - /// - /// - /// - /// An array of elements - /// - - // Resetting the length to 0, then using the native Array push - // is a super-fast way to populate an object with array-like properties - this.length = 0; - push.apply( this, elems ); - - return this; - }, - - // 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 ) { - /// - /// Execute a function within the context of every matched element. - /// This means that every time the passed-in function is executed - /// (which is once for every element matched) the 'this' keyword - /// points to the specific element. - /// Additionally, the function, when executed, is passed a single - /// argument representing the position of the element in the matched - /// set. - /// Part of Core - /// - /// - /// - /// A function to execute - /// - - return jQuery.each( this, callback, args ); - }, - - ready: function( fn ) { - /// - /// Binds a function to be executed whenever the DOM is ready to be traversed and manipulated. - /// - /// The function to be executed when the DOM is ready. - - // Attach the listeners - jQuery.bindReady(); - - // If the DOM is already ready - if ( jQuery.isReady ) { - // Execute the function immediately - fn.call( document, jQuery ); - - // Otherwise, remember the function for later - } else if ( readyList ) { - // Add the function to the wait list - readyList.push( fn ); - } - - return this; - }, - - eq: function( i ) { - /// - /// Reduce the set of matched elements to a single element. - /// The position of the element in the set of matched elements - /// starts at 0 and goes to length - 1. - /// Part of Core - /// - /// - /// - /// pos The index of the element that you wish to limit to. - /// - - return i === -1 ? - this.slice( i ) : - this.slice( i, +i + 1 ); - }, - - first: function() { - /// - /// Reduce the set of matched elements to the first in the set. - /// - /// - - return this.eq( 0 ); - }, - - last: function() { - /// - /// Reduce the set of matched elements to the final one in the set. - /// - /// - - return this.eq( -1 ); - }, - - slice: function() { - /// - /// Selects a subset of the matched elements. Behaves exactly like the built-in Array slice method. - /// - /// Where to start the subset (0-based). - /// Where to end the subset (not including the end element itself). - /// If omitted, ends at the end of the selection - /// The sliced elements - - return this.pushStack( slice.apply( this, arguments ), - "slice", slice.call(arguments).join(",") ); - }, - - map: function( callback ) { - /// - /// This member is internal. - /// - /// - /// - - return this.pushStack( jQuery.map(this, function( elem, i ) { - return callback.call( elem, i, elem ); - })); - }, - - end: function() { - /// - /// End the most recent 'destructive' operation, reverting the list of matched elements - /// back to its previous state. After an end operation, the list of matched elements will - /// revert to the last state of matched elements. - /// If there was no destructive operation before, an empty set is returned. - /// Part of DOM/Traversing - /// - /// - - return this.prevObject || jQuery(null); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: [].sort, - splice: [].splice -}; - -// Give the init function the jQuery prototype for later instantiation -jQuery.fn.init.prototype = jQuery.fn; - -jQuery.extend = jQuery.fn.extend = function() { - /// - /// Extend one object with one or more others, returning the original, - /// modified, object. This is a great utility for simple inheritance. - /// jQuery.extend(settings, options); - /// var settings = jQuery.extend({}, defaults, options); - /// Part of JavaScript - /// - /// - /// The object to extend - /// - /// - /// The object that will be merged into the first. - /// - /// - /// (optional) More objects to merge into the first - /// - /// - - // copy reference to target object - var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - - // 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 ( length === i ) { - 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 object literal values or arrays - if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) { - var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src - : jQuery.isArray(copy) ? [] : {}; - - // 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({ - noConflict: function( deep ) { - /// - /// Run this function to give control of the $ variable back - /// to whichever library first implemented it. This helps to make - /// sure that jQuery doesn't conflict with the $ object - /// of other libraries. - /// By using this function, you will only be able to access jQuery - /// using the 'jQuery' variable. For example, where you used to do - /// $("div p"), you now must do jQuery("div p"). - /// Part of Core - /// - /// - - window.$ = _$; - - if ( deep ) { - window.jQuery = _jQuery; - } - - return jQuery; - }, - - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // Handle when the DOM is ready - ready: function() { - /// - /// This method is internal. - /// - /// - - // Make sure that the DOM is not already loaded - if ( !jQuery.isReady ) { - // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( !document.body ) { - return setTimeout( jQuery.ready, 13 ); - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If there are functions bound, to execute - if ( readyList ) { - // Execute all of them - var fn, i = 0; - while ( (fn = readyList[ i++ ]) ) { - fn.call( document, jQuery ); - } - - // Reset the list of functions - readyList = null; - } - - // Trigger any bound ready events - if ( jQuery.fn.triggerHandler ) { - jQuery( document ).triggerHandler( "ready" ); - } - } - }, - - bindReady: function() { - if ( readyBound ) { - return; - } - - readyBound = true; - - // Catch cases where $(document).ready() is called after the - // browser event has already occurred. - if ( document.readyState === "complete" ) { - return jQuery.ready(); - } - - // Mozilla, Opera and webkit nightlies currently support this event - if ( document.addEventListener ) { - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); - - // A fallback to window.onload, that will always work - window.addEventListener( "load", jQuery.ready, false ); - - // If IE event model is used - } else if ( document.attachEvent ) { - // ensure firing before onload, - // maybe late but safe also for iframes - document.attachEvent("onreadystatechange", DOMContentLoaded); - - // A fallback to window.onload, that will always work - window.attachEvent( "onload", jQuery.ready ); - - // If IE and not a frame - // continually check to see if the document is ready - var toplevel = false; - - try { - toplevel = window.frameElement == null; - } catch(e) {} - - if ( document.documentElement.doScroll && toplevel ) { - doScrollCheck(); - } - } - }, - - // 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 ) { - /// - /// Determines if the parameter passed is a function. - /// - /// The object to check - /// True if the parameter is a function; otherwise false. - - return toString.call(obj) === "[object Function]"; - }, - - isArray: function( obj ) { - /// - /// Determine if the parameter passed is an array. - /// - /// Object to test whether or not it is an array. - /// True if the parameter is a function; otherwise false. - - return toString.call(obj) === "[object Array]"; - }, - - isPlainObject: function( obj ) { - /// - /// Check to see if an object is a plain object (created using "{}" or "new Object"). - /// - /// - /// The object that will be checked to see if it's a plain object. - /// - /// - - // Must be an Object. - // Because of IE, we also have to check the presence of the constructor property. - // Make sure that DOM nodes and window objects don't pass through, as well - if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) { - return false; - } - - // Not own constructor property must be Object - if ( obj.constructor - && !hasOwnProperty.call(obj, "constructor") - && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) { - return false; - } - - // Own properties are enumerated firstly, so to speed up, - // if last one is own, then all properties are own. - - var key; - for ( key in obj ) {} - - return key === undefined || hasOwnProperty.call( obj, key ); - }, - - isEmptyObject: function( obj ) { - /// - /// Check to see if an object is empty (contains no properties). - /// - /// - /// The object that will be checked to see if it's empty. - /// - /// - - for ( var name in obj ) { - return false; - } - return true; - }, - - error: function( msg ) { - throw msg; - }, - - parseJSON: function( data ) { - if ( typeof data !== "string" || !data ) { - return null; - } - - // Make sure the incoming data is actual JSON - // Logic borrowed from http://json.org/json2.js - if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@") - .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]") - .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) { - - // Try to use the native JSON parser first - return window.JSON && window.JSON.parse ? - window.JSON.parse( data ) : - (new Function("return " + data))(); - - } else { - jQuery.error( "Invalid JSON: " + data ); - } - }, - - noop: function() { - /// - /// An empty function. - /// - /// - }, - - // Evalulates a script in a global context - globalEval: function( data ) { - /// - /// Internally evaluates a script in a global context. - /// - /// - - if ( data && rnotwhite.test(data) ) { - // Inspired by code by Andrea Giammarchi - // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html - var head = document.getElementsByTagName("head")[0] || document.documentElement, - script = document.createElement("script"); - - script.type = "text/javascript"; - - if ( jQuery.support.scriptEval ) { - script.appendChild( document.createTextNode( data ) ); - } else { - script.text = data; - } - - // Use insertBefore instead of appendChild to circumvent an IE6 bug. - // This arises when a base node is used (#2709). - head.insertBefore( script, head.firstChild ); - head.removeChild( script ); - } - }, - - nodeName: function( elem, name ) { - /// - /// Checks whether the specified element has the specified DOM node name. - /// - /// The element to examine - /// The node name to check - /// True if the specified node name matches the node's DOM node name; otherwise false - - return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); - }, - - // args is for internal usage only - each: function( object, callback, args ) { - /// - /// A generic iterator function, which can be used to seemlessly - /// iterate over both objects and arrays. This function is not the same - /// as $().each() - which is used to iterate, exclusively, over a jQuery - /// object. This function can be used to iterate over anything. - /// The callback has two arguments:the key (objects) or index (arrays) as first - /// the first, and the value as the second. - /// Part of JavaScript - /// - /// - /// The object, or array, to iterate over. - /// - /// - /// The function that will be executed on every object. - /// - /// - - var name, i = 0, - length = object.length, - isObj = length === undefined || jQuery.isFunction(object); - - if ( args ) { - if ( isObj ) { - for ( name in object ) { - if ( callback.apply( object[ name ], args ) === false ) { - break; - } - } - } else { - for ( ; i < length; ) { - if ( callback.apply( object[ i++ ], args ) === false ) { - break; - } - } - } - - // A special, fast, case for the most common use of each - } else { - if ( isObj ) { - for ( name in object ) { - if ( callback.call( object[ name ], name, object[ name ] ) === false ) { - break; - } - } - } else { - for ( var value = object[0]; - i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {} - } - } - - return object; - }, - - trim: function( text ) { - /// - /// Remove the whitespace from the beginning and end of a string. - /// Part of JavaScript - /// - /// - /// - /// The string to trim. - /// - - return (text || "").replace( rtrim, "" ); - }, - - // results is for internal usage only - makeArray: function( array, results ) { - /// - /// Turns anything into a true array. This is an internal method. - /// - /// Anything to turn into an actual Array - /// - /// - - var ret = results || []; - - if ( array != null ) { - // The window, strings (and functions) also have 'length' - // The extra typeof function check is to prevent crashes - // in Safari 2 (See: #3039) - if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) { - push.call( ret, array ); - } else { - jQuery.merge( ret, array ); - } - } - - return ret; - }, - - inArray: function( elem, array ) { - if ( array.indexOf ) { - return array.indexOf( elem ); - } - - for ( var i = 0, length = array.length; i < length; i++ ) { - if ( array[ i ] === elem ) { - return i; - } - } - - return -1; - }, - - merge: function( first, second ) { - /// - /// Merge two arrays together, removing all duplicates. - /// The new array is: All the results from the first array, followed - /// by the unique results from the second array. - /// Part of JavaScript - /// - /// - /// - /// The first array to merge. - /// - /// - /// The second array to merge. - /// - - var i = first.length, j = 0; - - if ( typeof second.length === "number" ) { - for ( var l = second.length; j < l; j++ ) { - first[ i++ ] = second[ j ]; - } - } else { - while ( second[j] !== undefined ) { - first[ i++ ] = second[ j++ ]; - } - } - - first.length = i; - - return first; - }, - - grep: function( elems, callback, inv ) { - /// - /// Filter items out of an array, by using a filter function. - /// The specified function will be passed two arguments: The - /// current array item and the index of the item in the array. The - /// function must return 'true' to keep the item in the array, - /// false to remove it. - /// }); - /// Part of JavaScript - /// - /// - /// - /// array The Array to find items in. - /// - /// - /// The function to process each item against. - /// - /// - /// Invert the selection - select the opposite of the function. - /// - - var ret = []; - - // Go through the array, only saving the items - // that pass the validator function - for ( var i = 0, length = elems.length; i < length; i++ ) { - if ( !inv !== !callback( elems[ i ], i ) ) { - ret.push( elems[ i ] ); - } - } - - return ret; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - /// - /// Translate all items in an array to another array of items. - /// The translation function that is provided to this method is - /// called for each item in the array and is passed one argument: - /// The item to be translated. - /// The function can then return the translated value, 'null' - /// (to remove the item), or an array of values - which will - /// be flattened into the full array. - /// Part of JavaScript - /// - /// - /// - /// array The Array to translate. - /// - /// - /// The function to process each item against. - /// - - var ret = [], value; - - // Go through the array, translating each of the items to their - // new value (or values). - for ( var i = 0, length = elems.length; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret[ ret.length ] = value; - } - } - - return ret.concat.apply( [], ret ); - }, - - // A global GUID counter for objects - guid: 1, - - proxy: function( fn, proxy, thisObject ) { - /// - /// Takes a function and returns a new one that will always have a particular scope. - /// - /// - /// The function whose scope will be changed. - /// - /// - /// The object to which the scope of the function should be set. - /// - /// - - if ( arguments.length === 2 ) { - if ( typeof proxy === "string" ) { - thisObject = fn; - fn = thisObject[ proxy ]; - proxy = undefined; - - } else if ( proxy && !jQuery.isFunction( proxy ) ) { - thisObject = proxy; - proxy = undefined; - } - } - - if ( !proxy && fn ) { - proxy = function() { - return fn.apply( thisObject || this, arguments ); - }; - } - - // Set the guid of unique handler to the same of original handler, so it can be removed - if ( fn ) { - proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; - } - - // So proxy can be declared as an argument - return proxy; - }, - - // Use of jQuery.browser is frowned upon. - // More details: http://docs.jquery.com/Utilities/jQuery.browser - uaMatch: function( ua ) { - ua = ua.toLowerCase(); - - var match = /(webkit)[ \/]([\w.]+)/.exec( ua ) || - /(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) || - /(msie) ([\w.]+)/.exec( ua ) || - !/compatible/.test( ua ) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) || - []; - - return { browser: match[1] || "", version: match[2] || "0" }; - }, - - browser: {} -}); - -browserMatch = jQuery.uaMatch( userAgent ); -if ( browserMatch.browser ) { - jQuery.browser[ browserMatch.browser ] = true; - jQuery.browser.version = browserMatch.version; -} - -// Deprecated, use jQuery.browser.webkit instead -if ( jQuery.browser.webkit ) { - jQuery.browser.safari = true; -} - -if ( indexOf ) { - jQuery.inArray = function( elem, array ) { - /// - /// Determines the index of the first parameter in the array. - /// - /// The value to see if it exists in the array. - /// The array to look through for the value - /// The 0-based index of the item if it was found, otherwise -1. - - return indexOf.call( array, elem ); - }; -} - -// All jQuery objects should point back to these -rootjQuery = jQuery(document); - -// Cleanup functions for the document ready method -if ( document.addEventListener ) { - DOMContentLoaded = function() { - document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); - jQuery.ready(); - }; - -} else if ( document.attachEvent ) { - DOMContentLoaded = function() { - // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( document.readyState === "complete" ) { - document.detachEvent( "onreadystatechange", DOMContentLoaded ); - jQuery.ready(); - } - }; -} - -// The DOM ready check for Internet Explorer -function doScrollCheck() { - if ( jQuery.isReady ) { - return; - } - - try { - // If IE is used, use the trick by Diego Perini - // http://javascript.nwbox.com/IEContentLoaded/ - document.documentElement.doScroll("left"); - } catch( error ) { - setTimeout( doScrollCheck, 1 ); - return; - } - - // and execute any waiting functions - jQuery.ready(); -} - -function evalScript( i, elem ) { - /// - /// This method is internal. - /// - /// - - if ( elem.src ) { - jQuery.ajax({ - url: elem.src, - async: false, - dataType: "script" - }); - } else { - jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); - } - - if ( elem.parentNode ) { - elem.parentNode.removeChild( elem ); - } -} - -// Mutifunctional method to get and set values to a collection -// The value/s can be optionally by executed if its a function -function access( elems, key, value, exec, fn, pass ) { - var length = elems.length; - - // Setting many attributes - if ( typeof key === "object" ) { - for ( var k in key ) { - access( elems, k, key[k], exec, fn, value ); - } - return elems; - } - - // Setting one attribute - if ( value !== undefined ) { - // Optionally, function values get executed if exec is true - exec = !pass && exec && jQuery.isFunction(value); - - for ( var i = 0; i < length; i++ ) { - fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); - } - - return elems; - } - - // Getting an attribute - return length ? fn( elems[0], key ) : null; -} - -function now() { - /// - /// Gets the current date. - /// - /// The current date. - - return (new Date).getTime(); -} - -// [vsdoc] The following function has been modified for IntelliSense. -// [vsdoc] Stubbing support properties to "false" for IntelliSense compat. -(function() { - - jQuery.support = {}; - - // var root = document.documentElement, - // script = document.createElement("script"), - // div = document.createElement("div"), - // id = "script" + now(); - - // div.style.display = "none"; - // div.innerHTML = "
a"; - - // var all = div.getElementsByTagName("*"), - // a = div.getElementsByTagName("a")[0]; - - // // Can't get basic test support - // if ( !all || !all.length || !a ) { - // return; - // } - - jQuery.support = { - // IE strips leading whitespace when .innerHTML is used - leadingWhitespace: false, - - // Make sure that tbody elements aren't automatically inserted - // IE will insert them into empty tables - tbody: false, - - // Make sure that link elements get serialized correctly by innerHTML - // This requires a wrapper element in IE - htmlSerialize: false, - - // Get the style information from getAttribute - // (IE uses .cssText insted) - style: false, - - // Make sure that URLs aren't manipulated - // (IE normalizes it by default) - hrefNormalized: false, - - // Make sure that element opacity exists - // (IE uses filter instead) - // Use a regex to work around a WebKit issue. See #5145 - opacity: false, - - // Verify style float existence - // (IE uses styleFloat instead of cssFloat) - cssFloat: false, - - // Make sure that if no value is specified for a checkbox - // that it defaults to "on". - // (WebKit defaults to "" instead) - checkOn: false, - - // Make sure that a selected-by-default option has a working selected property. - // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) - optSelected: false, - - // Will be defined later - checkClone: false, - scriptEval: false, - noCloneEvent: false, - boxModel: false - }; - - // script.type = "text/javascript"; - // try { - // script.appendChild( document.createTextNode( "window." + id + "=1;" ) ); - // } catch(e) {} - - // root.insertBefore( script, root.firstChild ); - - // // Make sure that the execution of code works by injecting a script - // // tag with appendChild/createTextNode - // // (IE doesn't support this, fails, and uses .text instead) - // if ( window[ id ] ) { - // jQuery.support.scriptEval = true; - // delete window[ id ]; - // } - - // root.removeChild( script ); - - // if ( div.attachEvent && div.fireEvent ) { - // div.attachEvent("onclick", function click() { - // // Cloning a node shouldn't copy over any - // // bound event handlers (IE does this) - // jQuery.support.noCloneEvent = false; - // div.detachEvent("onclick", click); - // }); - // div.cloneNode(true).fireEvent("onclick"); - // } - - // div = document.createElement("div"); - // div.innerHTML = ""; - - // var fragment = document.createDocumentFragment(); - // fragment.appendChild( div.firstChild ); - - // // WebKit doesn't clone checked state correctly in fragments - // jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked; - - // // Figure out if the W3C box model works as expected - // // document.body must exist before we can do this - // jQuery(function() { - // var div = document.createElement("div"); - // div.style.width = div.style.paddingLeft = "1px"; - - // document.body.appendChild( div ); - // jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2; - // document.body.removeChild( div ).style.display = 'none'; - // div = null; - // }); - - // // Technique from Juriy Zaytsev - // // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/ - // var eventSupported = function( eventName ) { - // var el = document.createElement("div"); - // eventName = "on" + eventName; - - // var isSupported = (eventName in el); - // if ( !isSupported ) { - // el.setAttribute(eventName, "return;"); - // isSupported = typeof el[eventName] === "function"; - // } - // el = null; - - // return isSupported; - // }; - - jQuery.support.submitBubbles = false; - jQuery.support.changeBubbles = false; - - // // release memory in IE - // root = script = div = all = a = null; -})(); - -jQuery.props = { - "for": "htmlFor", - "class": "className", - readonly: "readOnly", - maxlength: "maxLength", - cellspacing: "cellSpacing", - rowspan: "rowSpan", - colspan: "colSpan", - tabindex: "tabIndex", - usemap: "useMap", - frameborder: "frameBorder" -}; -var expando = "jQuery" + now(), uuid = 0, windowData = {}; -var emptyObject = {}; - -jQuery.extend({ - cache: {}, - - expando:expando, - - // The following elements throw uncatchable exceptions if you - // attempt to add expando properties to them. - noData: { - "embed": true, - "object": true, - "applet": true - }, - - data: function( elem, name, data ) { - /// - /// Store arbitrary data associated with the specified element. - /// - /// - /// The DOM element to associate with the data. - /// - /// - /// A string naming the piece of data to set. - /// - /// - /// The new data value. - /// - /// - - if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) { - return; - } - - elem = elem == window ? - windowData : - elem; - - var id = elem[ expando ], cache = jQuery.cache, thisCache; - - // Handle the case where there's no name immediately - if ( !name && !id ) { - return null; - } - - // Compute a unique ID for the element - if ( !id ) { - id = ++uuid; - } - - // Avoid generating a new cache unless none exists and we - // want to manipulate it. - if ( typeof name === "object" ) { - elem[ expando ] = id; - thisCache = cache[ id ] = jQuery.extend(true, {}, name); - } else if ( cache[ id ] ) { - thisCache = cache[ id ]; - } else if ( typeof data === "undefined" ) { - thisCache = emptyObject; - } else { - thisCache = cache[ id ] = {}; - } - - // Prevent overriding the named cache with undefined values - if ( data !== undefined ) { - elem[ expando ] = id; - thisCache[ name ] = data; - } - - return typeof name === "string" ? thisCache[ name ] : thisCache; - }, - - removeData: function( elem, name ) { - if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) { - return; - } - - elem = elem == window ? - windowData : - elem; - - var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ]; - - // If we want to remove a specific section of the element's data - if ( name ) { - if ( thisCache ) { - // Remove the section of cache data - delete thisCache[ name ]; - - // If we've removed all the data, remove the element's cache - if ( jQuery.isEmptyObject(thisCache) ) { - jQuery.removeData( elem ); - } - } - - // Otherwise, we want to remove all of the element's data - } else { - // Clean up the element expando - try { - delete elem[ expando ]; - } catch( e ) { - // IE has trouble directly removing the expando - // but it's ok with using removeAttribute - if ( elem.removeAttribute ) { - elem.removeAttribute( expando ); - } - } - - // Completely remove the data cache - delete cache[ id ]; - } - } -}); - -jQuery.fn.extend({ - data: function( key, value ) { - /// - /// Store arbitrary data associated with the matched elements. - /// - /// - /// A string naming the piece of data to set. - /// - /// - /// The new data value. - /// - /// - - if ( typeof key === "undefined" && this.length ) { - return jQuery.data( this[0] ); - - } else if ( typeof key === "object" ) { - return this.each(function() { - jQuery.data( this, key ); - }); - } - - var parts = key.split("."); - parts[1] = parts[1] ? "." + parts[1] : ""; - - if ( value === undefined ) { - var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); - - if ( data === undefined && this.length ) { - data = jQuery.data( this[0], key ); - } - return data === undefined && parts[1] ? - this.data( parts[0] ) : - data; - } else { - return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() { - jQuery.data( this, key, value ); - }); - } - }, - - removeData: function( key ) { - return this.each(function() { - jQuery.removeData( this, key ); - }); - } -}); -jQuery.extend({ - queue: function( elem, type, data ) { - if ( !elem ) { - return; - } - - type = (type || "fx") + "queue"; - var q = jQuery.data( elem, type ); - - // Speed up dequeue by getting out quickly if this is just a lookup - if ( !data ) { - return q || []; - } - - if ( !q || jQuery.isArray(data) ) { - q = jQuery.data( elem, type, jQuery.makeArray(data) ); - - } else { - q.push( data ); - } - - return q; - }, - - dequeue: function( elem, type ) { - type = type || "fx"; - - var queue = jQuery.queue( elem, type ), fn = queue.shift(); - - // If the fx queue is dequeued, always remove the progress sentinel - if ( fn === "inprogress" ) { - fn = queue.shift(); - } - - if ( fn ) { - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if ( type === "fx" ) { - queue.unshift("inprogress"); - } - - fn.call(elem, function() { - jQuery.dequeue(elem, type); - }); - } - } -}); - -jQuery.fn.extend({ - queue: function( type, data ) { - /// - /// 1: queue() - Returns a reference to the first element's queue (which is an array of functions). - /// 2: queue(callback) - Adds a new function, to be executed, onto the end of the queue of all matched elements. - /// 3: queue(queue) - Replaces the queue of all matched element with this new queue (the array of functions). - /// - /// The function to add to the queue. - /// - - if ( typeof type !== "string" ) { - data = type; - type = "fx"; - } - - if ( data === undefined ) { - return jQuery.queue( this[0], type ); - } - return this.each(function( i, elem ) { - var queue = jQuery.queue( this, type, data ); - - if ( type === "fx" && queue[0] !== "inprogress" ) { - jQuery.dequeue( this, type ); - } - }); - }, - dequeue: function( type ) { - /// - /// Removes a queued function from the front of the queue and executes it. - /// - /// The type of queue to access. - /// - - return this.each(function() { - jQuery.dequeue( this, type ); - }); - }, - - // Based off of the plugin by Clint Helfers, with permission. - // http://blindsignals.com/index.php/2009/07/jquery-delay/ - delay: function( time, type ) { - /// - /// Set a timer to delay execution of subsequent items in the queue. - /// - /// - /// An integer indicating the number of milliseconds to delay execution of the next item in the queue. - /// - /// - /// A string containing the name of the queue. Defaults to fx, the standard effects queue. - /// - /// - - time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; - type = type || "fx"; - - return this.queue( type, function() { - var elem = this; - setTimeout(function() { - jQuery.dequeue( elem, type ); - }, time ); - }); - }, - - clearQueue: function( type ) { - /// - /// Remove from the queue all items that have not yet been run. - /// - /// - /// A string containing the name of the queue. Defaults to fx, the standard effects queue. - /// - /// - - return this.queue( type || "fx", [] ); - } -}); -var rclass = /[\n\t]/g, - rspace = /\s+/, - rreturn = /\r/g, - rspecialurl = /href|src|style/, - rtype = /(button|input)/i, - rfocusable = /(button|input|object|select|textarea)/i, - rclickable = /^(a|area)$/i, - rradiocheck = /radio|checkbox/; - -jQuery.fn.extend({ - attr: function( name, value ) { - /// - /// Set a single property to a computed value, on all matched elements. - /// Instead of a value, a function is provided, that computes the value. - /// Part of DOM/Attributes - /// - /// - /// - /// The name of the property to set. - /// - /// - /// A function returning the value to set. - /// - - return access( this, name, value, true, jQuery.attr ); - }, - - removeAttr: function( name, fn ) { - /// - /// Remove an attribute from each of the matched elements. - /// Part of DOM/Attributes - /// - /// - /// An attribute to remove. - /// - /// - - return this.each(function(){ - jQuery.attr( this, name, "" ); - if ( this.nodeType === 1 ) { - this.removeAttribute( name ); - } - }); - }, - - addClass: function( value ) { - /// - /// Adds the specified class(es) to each of the set of matched elements. - /// Part of DOM/Attributes - /// - /// - /// One or more class names to be added to the class attribute of each matched element. - /// - /// - - if ( jQuery.isFunction(value) ) { - return this.each(function(i) { - var self = jQuery(this); - self.addClass( value.call(this, i, self.attr("class")) ); - }); - } - - if ( value && typeof value === "string" ) { - var classNames = (value || "").split( rspace ); - - for ( var i = 0, l = this.length; i < l; i++ ) { - var elem = this[i]; - - if ( elem.nodeType === 1 ) { - if ( !elem.className ) { - elem.className = value; - - } else { - var className = " " + elem.className + " "; - for ( var c = 0, cl = classNames.length; c < cl; c++ ) { - if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) { - elem.className += " " + classNames[c]; - } - } - } - } - } - } - - return this; - }, - - removeClass: function( value ) { - /// - /// Removes all or the specified class(es) from the set of matched elements. - /// Part of DOM/Attributes - /// - /// - /// (Optional) A class name to be removed from the class attribute of each matched element. - /// - /// - - if ( jQuery.isFunction(value) ) { - return this.each(function(i) { - var self = jQuery(this); - self.removeClass( value.call(this, i, self.attr("class")) ); - }); - } - - if ( (value && typeof value === "string") || value === undefined ) { - var classNames = (value || "").split(rspace); - - for ( var i = 0, l = this.length; i < l; i++ ) { - var elem = this[i]; - - if ( elem.nodeType === 1 && elem.className ) { - if ( value ) { - var className = (" " + elem.className + " ").replace(rclass, " "); - for ( var c = 0, cl = classNames.length; c < cl; c++ ) { - className = className.replace(" " + classNames[c] + " ", " "); - } - elem.className = className.substring(1, className.length - 1); - - } else { - elem.className = ""; - } - } - } - } - - return this; - }, - - toggleClass: function( value, stateVal ) { - /// - /// Add or remove a class from each element in the set of matched elements, depending - /// on either the class's presence or the value of the switch argument. - /// - /// - /// A class name to be toggled for each element in the matched set. - /// - /// - /// A boolean value to determine whether the class should be added or removed. - /// - /// - - var type = typeof value, isBool = typeof stateVal === "boolean"; - - if ( jQuery.isFunction( value ) ) { - return this.each(function(i) { - var self = jQuery(this); - self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal ); - }); - } - - return this.each(function() { - if ( type === "string" ) { - // toggle individual class names - var className, i = 0, self = jQuery(this), - state = stateVal, - classNames = value.split( rspace ); - - while ( (className = classNames[ i++ ]) ) { - // check each className given, space seperated list - state = isBool ? state : !self.hasClass( className ); - self[ state ? "addClass" : "removeClass" ]( className ); - } - - } else if ( type === "undefined" || type === "boolean" ) { - if ( this.className ) { - // store className if set - jQuery.data( this, "__className__", this.className ); - } - - // toggle whole className - this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || ""; - } - }); - }, - - hasClass: function( selector ) { - /// - /// Checks the current selection against a class and returns whether at least one selection has a given class. - /// - /// The class to check against - /// True if at least one element in the selection has the class, otherwise false. - - var className = " " + selector + " "; - for ( var i = 0, l = this.length; i < l; i++ ) { - if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { - return true; - } - } - - return false; - }, - - val: function( value ) { - /// - /// Set the value of every matched element. - /// Part of DOM/Attributes - /// - /// - /// - /// A string of text or an array of strings to set as the value property of each - /// matched element. - /// - - if ( value === undefined ) { - var elem = this[0]; - - if ( elem ) { - if ( jQuery.nodeName( elem, "option" ) ) { - return (elem.attributes.value || {}).specified ? elem.value : elem.text; - } - - // We need to handle select boxes special - if ( jQuery.nodeName( elem, "select" ) ) { - var index = elem.selectedIndex, - values = [], - options = elem.options, - one = elem.type === "select-one"; - - // Nothing was selected - if ( index < 0 ) { - return null; - } - - // Loop through all the selected options - for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { - var option = options[ i ]; - - if ( option.selected ) { - // Get the specifc value for the option - value = jQuery(option).val(); - - // We don't need an array for one selects - if ( one ) { - return value; - } - - // Multi-Selects return an array - values.push( value ); - } - } - - return values; - } - - // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified - if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) { - return elem.getAttribute("value") === null ? "on" : elem.value; - } - - - // Everything else, we just grab the value - return (elem.value || "").replace(rreturn, ""); - - } - - return undefined; - } - - var isFunction = jQuery.isFunction(value); - - return this.each(function(i) { - var self = jQuery(this), val = value; - - if ( this.nodeType !== 1 ) { - return; - } - - if ( isFunction ) { - val = value.call(this, i, self.val()); - } - - // Typecast each time if the value is a Function and the appended - // value is therefore different each time. - if ( typeof val === "number" ) { - val += ""; - } - - if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) { - this.checked = jQuery.inArray( self.val(), val ) >= 0; - - } else if ( jQuery.nodeName( this, "select" ) ) { - var values = jQuery.makeArray(val); - - jQuery( "option", this ).each(function() { - this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; - }); - - if ( !values.length ) { - this.selectedIndex = -1; - } - - } else { - this.value = val; - } - }); - } -}); - -jQuery.extend({ - attrFn: { - val: true, - css: true, - html: true, - text: true, - data: true, - width: true, - height: true, - offset: true - }, - - attr: function( elem, name, value, pass ) { - /// - /// This method is internal. - /// - /// - - // don't set attributes on text and comment nodes - if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { - return undefined; - } - - if ( pass && name in jQuery.attrFn ) { - return jQuery(elem)[name](value); - } - - var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ), - // Whether we are setting (or getting) - set = value !== undefined; - - // Try to normalize/fix the name - name = notxml && jQuery.props[ name ] || name; - - // Only do all the following if this is a node (faster for style) - if ( elem.nodeType === 1 ) { - // These attributes require special treatment - var special = rspecialurl.test( name ); - - // Safari mis-reports the default selected property of an option - // Accessing the parent's selectedIndex property fixes it - if ( name === "selected" && !jQuery.support.optSelected ) { - var parent = elem.parentNode; - if ( parent ) { - parent.selectedIndex; - - // Make sure that it also works with optgroups, see #5701 - if ( parent.parentNode ) { - parent.parentNode.selectedIndex; - } - } - } - - // If applicable, access the attribute via the DOM 0 way - if ( name in elem && notxml && !special ) { - if ( set ) { - // We can't allow the type property to be changed (since it causes problems in IE) - if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) { - jQuery.error( "type property can't be changed" ); - } - - elem[ name ] = value; - } - - // browsers index elements by id/name on forms, give priority to attributes. - if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) { - return elem.getAttributeNode( name ).nodeValue; - } - - // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set - // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ - if ( name === "tabIndex" ) { - var attributeNode = elem.getAttributeNode( "tabIndex" ); - - return attributeNode && attributeNode.specified ? - attributeNode.value : - rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? - 0 : - undefined; - } - - return elem[ name ]; - } - - if ( !jQuery.support.style && notxml && name === "style" ) { - if ( set ) { - elem.style.cssText = "" + value; - } - - return elem.style.cssText; - } - - if ( set ) { - // convert the value to a string (all browsers do this but IE) see #1070 - elem.setAttribute( name, "" + value ); - } - - var attr = !jQuery.support.hrefNormalized && notxml && special ? - // Some attributes require a special call on IE - elem.getAttribute( name, 2 ) : - elem.getAttribute( name ); - - // Non-existent attributes return null, we normalize to undefined - return attr === null ? undefined : attr; - } - - // elem is actually elem.style ... set the style - // Using attr for specific style information is now deprecated. Use style insead. - return jQuery.style( elem, name, value ); - } -}); -var fcleanup = function( nm ) { - return nm.replace(/[^\w\s\.\|`]/g, function( ch ) { - return "\\" + ch; - }); -}; - -/* - * A number of helper functions used for managing events. - * Many of the ideas behind this code originated from - * Dean Edwards' addEvent library. - */ -jQuery.event = { - - // Bind an event to an element - // Original by Dean Edwards - add: function( elem, types, handler, data ) { - /// - /// This method is internal. - /// - /// - - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - // For whatever reason, IE has trouble passing the window object - // around, causing it to be cloned in the process - if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) { - elem = window; - } - - // Make sure that the function being executed has a unique ID - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // if data is passed, bind to handler - if ( data !== undefined ) { - // Create temporary function pointer to original handler - var fn = handler; - - // Create unique handler function, wrapped around original handler - handler = jQuery.proxy( fn ); - - // Store data in unique handler - handler.data = data; - } - - // Init the element's event structure - var events = jQuery.data( elem, "events" ) || jQuery.data( elem, "events", {} ), - handle = jQuery.data( elem, "handle" ), eventHandle; - - if ( !handle ) { - eventHandle = function() { - // Handle the second event of a trigger and when - // an event is called after a page has unloaded - return typeof jQuery !== "undefined" && !jQuery.event.triggered ? - jQuery.event.handle.apply( eventHandle.elem, arguments ) : - undefined; - }; - - handle = jQuery.data( elem, "handle", eventHandle ); - } - - // If no handle is found then we must be trying to bind to one of the - // banned noData elements - if ( !handle ) { - return; - } - - // Add elem as a property of the handle function - // This is to prevent a memory leak with non-native - // event in IE. - handle.elem = elem; - - // Handle multiple events separated by a space - // jQuery(...).bind("mouseover mouseout", fn); - types = types.split( /\s+/ ); - - var type, i = 0; - - while ( (type = types[ i++ ]) ) { - // Namespaced event handlers - var namespaces = type.split("."); - type = namespaces.shift(); - - if ( i > 1 ) { - handler = jQuery.proxy( handler ); - - if ( data !== undefined ) { - handler.data = data; - } - } - - handler.type = namespaces.slice(0).sort().join("."); - - // Get the current list of functions bound to this event - var handlers = events[ type ], - special = this.special[ type ] || {}; - - // Init the event handler queue - if ( !handlers ) { - handlers = events[ type ] = {}; - - // Check for a special event handler - // Only use addEventListener/attachEvent if the special - // events handler returns false - if ( !special.setup || special.setup.call( elem, data, namespaces, handler) === false ) { - // Bind the global event handler to the element - if ( elem.addEventListener ) { - elem.addEventListener( type, handle, false ); - } else if ( elem.attachEvent ) { - elem.attachEvent( "on" + type, handle ); - } - } - } - - if ( special.add ) { - var modifiedHandler = special.add.call( elem, handler, data, namespaces, handlers ); - if ( modifiedHandler && jQuery.isFunction( modifiedHandler ) ) { - modifiedHandler.guid = modifiedHandler.guid || handler.guid; - modifiedHandler.data = modifiedHandler.data || handler.data; - modifiedHandler.type = modifiedHandler.type || handler.type; - handler = modifiedHandler; - } - } - - // Add the function to the element's handler list - handlers[ handler.guid ] = handler; - - // Keep track of which events have been used, for global triggering - this.global[ type ] = true; - } - - // Nullify elem to prevent memory leaks in IE - elem = null; - }, - - global: {}, - - // Detach an event or set of events from an element - remove: function( elem, types, handler ) { - /// - /// This method is internal. - /// - /// - - // don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - var events = jQuery.data( elem, "events" ), ret, type, fn; - - if ( events ) { - // Unbind all events for the element - if ( types === undefined || (typeof types === "string" && types.charAt(0) === ".") ) { - for ( type in events ) { - this.remove( elem, type + (types || "") ); - } - } else { - // types is actually an event object here - if ( types.type ) { - handler = types.handler; - types = types.type; - } - - // Handle multiple events separated by a space - // jQuery(...).unbind("mouseover mouseout", fn); - types = types.split(/\s+/); - var i = 0; - while ( (type = types[ i++ ]) ) { - // Namespaced event handlers - var namespaces = type.split("."); - type = namespaces.shift(); - var all = !namespaces.length, - cleaned = jQuery.map( namespaces.slice(0).sort(), fcleanup ), - namespace = new RegExp("(^|\\.)" + cleaned.join("\\.(?:.*\\.)?") + "(\\.|$)"), - special = this.special[ type ] || {}; - - if ( events[ type ] ) { - // remove the given handler for the given type - if ( handler ) { - fn = events[ type ][ handler.guid ]; - delete events[ type ][ handler.guid ]; - - // remove all handlers for the given type - } else { - for ( var handle in events[ type ] ) { - // Handle the removal of namespaced events - if ( all || namespace.test( events[ type ][ handle ].type ) ) { - delete events[ type ][ handle ]; - } - } - } - - if ( special.remove ) { - special.remove.call( elem, namespaces, fn); - } - - // remove generic event handler if no more handlers exist - for ( ret in events[ type ] ) { - break; - } - if ( !ret ) { - if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { - if ( elem.removeEventListener ) { - elem.removeEventListener( type, jQuery.data( elem, "handle" ), false ); - } else if ( elem.detachEvent ) { - elem.detachEvent( "on" + type, jQuery.data( elem, "handle" ) ); - } - } - ret = null; - delete events[ type ]; - } - } - } - } - - // Remove the expando if it's no longer used - for ( ret in events ) { - break; - } - if ( !ret ) { - var handle = jQuery.data( elem, "handle" ); - if ( handle ) { - handle.elem = null; - } - jQuery.removeData( elem, "events" ); - jQuery.removeData( elem, "handle" ); - } - } - }, - - // bubbling is internal - trigger: function( event, data, elem /*, bubbling */ ) { - /// - /// This method is internal. - /// - /// - - // Event object or event type - var type = event.type || event, - bubbling = arguments[3]; - - if ( !bubbling ) { - event = typeof event === "object" ? - // jQuery.Event object - event[expando] ? event : - // Object literal - jQuery.extend( jQuery.Event(type), event ) : - // Just the event type (string) - jQuery.Event(type); - - if ( type.indexOf("!") >= 0 ) { - event.type = type = type.slice(0, -1); - event.exclusive = true; - } - - // Handle a global trigger - if ( !elem ) { - // Don't bubble custom events when global (to avoid too much overhead) - event.stopPropagation(); - - // Only trigger if we've ever bound an event for it - if ( this.global[ type ] ) { - jQuery.each( jQuery.cache, function() { - if ( this.events && this.events[type] ) { - jQuery.event.trigger( event, data, this.handle.elem ); - } - }); - } - } - - // Handle triggering a single element - - // don't do events on text and comment nodes - if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { - return undefined; - } - - // Clean up in case it is reused - event.result = undefined; - event.target = elem; - - // Clone the incoming data, if any - data = jQuery.makeArray( data ); - data.unshift( event ); - } - - event.currentTarget = elem; - - // Trigger the event, it is assumed that "handle" is a function - var handle = jQuery.data( elem, "handle" ); - if ( handle ) { - handle.apply( elem, data ); - } - - var parent = elem.parentNode || elem.ownerDocument; - - // Trigger an inline bound script - try { - if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) { - if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) { - event.result = false; - } - } - - // prevent IE from throwing an error for some elements with some event types, see #3533 - } catch (e) {} - - if ( !event.isPropagationStopped() && parent ) { - jQuery.event.trigger( event, data, parent, true ); - - } else if ( !event.isDefaultPrevented() ) { - var target = event.target, old, - isClick = jQuery.nodeName(target, "a") && type === "click"; - - if ( !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) { - try { - if ( target[ type ] ) { - // Make sure that we don't accidentally re-trigger the onFOO events - old = target[ "on" + type ]; - - if ( old ) { - target[ "on" + type ] = null; - } - - this.triggered = true; - target[ type ](); - } - - // prevent IE from throwing an error for some elements with some event types, see #3533 - } catch (e) {} - - if ( old ) { - target[ "on" + type ] = old; - } - - this.triggered = false; - } - } - }, - - handle: function( event ) { - /// - /// This method is internal. - /// - /// - - // returned undefined or false - var all, handlers; - - event = arguments[0] = jQuery.event.fix( event || window.event ); - event.currentTarget = this; - - // Namespaced event handlers - var namespaces = event.type.split("."); - event.type = namespaces.shift(); - - // Cache this now, all = true means, any handler - all = !namespaces.length && !event.exclusive; - - var namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)"); - - handlers = ( jQuery.data(this, "events") || {} )[ event.type ]; - - for ( var j in handlers ) { - var handler = handlers[ j ]; - - // Filter the functions by class - if ( all || namespace.test(handler.type) ) { - // Pass in a reference to the handler function itself - // So that we can later remove it - event.handler = handler; - event.data = handler.data; - - var ret = handler.apply( this, arguments ); - - if ( ret !== undefined ) { - event.result = ret; - if ( ret === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - - if ( event.isImmediatePropagationStopped() ) { - break; - } - - } - } - - return event.result; - }, - - props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "), - - fix: function( event ) { - /// - /// This method is internal. - /// - /// - - if ( event[ expando ] ) { - return event; - } - - // store a copy of the original event object - // and "clone" to set read-only properties - var originalEvent = event; - event = jQuery.Event( originalEvent ); - - for ( var i = this.props.length, prop; i; ) { - prop = this.props[ --i ]; - event[ prop ] = originalEvent[ prop ]; - } - - // Fix target property, if necessary - if ( !event.target ) { - event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either - } - - // check if target is a textnode (safari) - if ( event.target.nodeType === 3 ) { - event.target = event.target.parentNode; - } - - // Add relatedTarget, if necessary - if ( !event.relatedTarget && event.fromElement ) { - event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; - } - - // Calculate pageX/Y if missing and clientX/Y available - if ( event.pageX == null && event.clientX != null ) { - var doc = document.documentElement, body = document.body; - event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); - event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); - } - - // Add which for key events - if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) { - event.which = event.charCode || event.keyCode; - } - - // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) - if ( !event.metaKey && event.ctrlKey ) { - event.metaKey = event.ctrlKey; - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - // Note: button is not normalized, so don't use it - if ( !event.which && event.button !== undefined ) { - event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); - } - - return event; - }, - - // Deprecated, use jQuery.guid instead - guid: 1E8, - - // Deprecated, use jQuery.proxy instead - proxy: jQuery.proxy, - - special: { - ready: { - // Make sure the ready event is setup - setup: jQuery.bindReady, - teardown: jQuery.noop - }, - - live: { - add: function( proxy, data, namespaces, live ) { - jQuery.extend( proxy, data || {} ); - - proxy.guid += data.selector + data.live; - data.liveProxy = proxy; - - jQuery.event.add( this, data.live, liveHandler, data ); - - }, - - remove: function( namespaces ) { - if ( namespaces.length ) { - var remove = 0, name = new RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)"); - - jQuery.each( (jQuery.data(this, "events").live || {}), function() { - if ( name.test(this.type) ) { - remove++; - } - }); - - if ( remove < 1 ) { - jQuery.event.remove( this, namespaces[0], liveHandler ); - } - } - }, - special: {} - }, - beforeunload: { - setup: function( data, namespaces, fn ) { - // We only want to do this special case on windows - if ( this.setInterval ) { - this.onbeforeunload = fn; - } - - return false; - }, - teardown: function( namespaces, fn ) { - if ( this.onbeforeunload === fn ) { - this.onbeforeunload = null; - } - } - } - } -}; - -jQuery.Event = function( src ) { - // Allow instantiation without the 'new' keyword - if ( !this.preventDefault ) { - return new jQuery.Event( src ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - // Event type - } else { - this.type = src; - } - - // timeStamp is buggy for some events on Firefox(#3843) - // So we won't rely on the native value - this.timeStamp = now(); - - // Mark it as fixed - this[ expando ] = true; -}; - -function returnFalse() { - return false; -} -function returnTrue() { - return 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 = { - preventDefault: function() { - this.isDefaultPrevented = returnTrue; - - var e = this.originalEvent; - if ( !e ) { - return; - } - - // if preventDefault exists run it on the original event - if ( e.preventDefault ) { - e.preventDefault(); - } - // otherwise set the returnValue property of the original event to false (IE) - e.returnValue = false; - }, - stopPropagation: function() { - this.isPropagationStopped = returnTrue; - - var e = this.originalEvent; - if ( !e ) { - return; - } - // if stopPropagation exists run it on the original event - if ( e.stopPropagation ) { - e.stopPropagation(); - } - // otherwise set the cancelBubble property of the original event to true (IE) - e.cancelBubble = true; - }, - stopImmediatePropagation: function() { - this.isImmediatePropagationStopped = returnTrue; - this.stopPropagation(); - }, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse -}; - -// Checks if an event happened on an element within another element -// Used in jQuery.event.special.mouseenter and mouseleave handlers -var withinElement = function( event ) { - // Check if mouse(over|out) are still within the same parent element - var parent = event.relatedTarget; - - // Traverse up the tree - while ( parent && parent !== this ) { - // Firefox sometimes assigns relatedTarget a XUL element - // which we cannot access the parentNode property of - try { - parent = parent.parentNode; - - // assuming we've left the element since we most likely mousedover a xul element - } catch(e) { - break; - } - } - - if ( parent !== this ) { - // set the correct event type - event.type = event.data; - - // handle event if we actually just moused on to a non sub-element - jQuery.event.handle.apply( this, arguments ); - } - -}, - -// In case of event delegation, we only need to rename the event.type, -// liveHandler will take care of the rest. -delegate = function( event ) { - event.type = event.data; - jQuery.event.handle.apply( this, arguments ); -}; - -// Create mouseenter and mouseleave events -jQuery.each({ - mouseenter: "mouseover", - mouseleave: "mouseout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - setup: function( data ) { - jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig ); - }, - teardown: function( data ) { - jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement ); - } - }; -}); - -// submit delegation -if ( !jQuery.support.submitBubbles ) { - -jQuery.event.special.submit = { - setup: function( data, namespaces, fn ) { - if ( this.nodeName.toLowerCase() !== "form" ) { - jQuery.event.add(this, "click.specialSubmit." + fn.guid, function( e ) { - var elem = e.target, type = elem.type; - - if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) { - return trigger( "submit", this, arguments ); - } - }); - - jQuery.event.add(this, "keypress.specialSubmit." + fn.guid, function( e ) { - var elem = e.target, type = elem.type; - - if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) { - return trigger( "submit", this, arguments ); - } - }); - - } else { - return false; - } - }, - - remove: function( namespaces, fn ) { - jQuery.event.remove( this, "click.specialSubmit" + (fn ? "."+fn.guid : "") ); - jQuery.event.remove( this, "keypress.specialSubmit" + (fn ? "."+fn.guid : "") ); - } -}; - -} - -// change delegation, happens here so we have bind. -if ( !jQuery.support.changeBubbles ) { - -var formElems = /textarea|input|select/i; - -function getVal( elem ) { - var type = elem.type, val = elem.value; - - if ( type === "radio" || type === "checkbox" ) { - val = elem.checked; - - } else if ( type === "select-multiple" ) { - val = elem.selectedIndex > -1 ? - jQuery.map( elem.options, function( elem ) { - return elem.selected; - }).join("-") : - ""; - - } else if ( elem.nodeName.toLowerCase() === "select" ) { - val = elem.selectedIndex; - } - - return val; -} - -function testChange( e ) { - var elem = e.target, data, val; - - if ( !formElems.test( elem.nodeName ) || elem.readOnly ) { - return; - } - - data = jQuery.data( elem, "_change_data" ); - val = getVal(elem); - - // the current data will be also retrieved by beforeactivate - if ( e.type !== "focusout" || elem.type !== "radio" ) { - jQuery.data( elem, "_change_data", val ); - } - - if ( data === undefined || val === data ) { - return; - } - - if ( data != null || val ) { - e.type = "change"; - return jQuery.event.trigger( e, arguments[1], elem ); - } -} - -jQuery.event.special.change = { - filters: { - focusout: testChange, - - click: function( e ) { - var elem = e.target, type = elem.type; - - if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) { - return testChange.call( this, e ); - } - }, - - // Change has to be called before submit - // Keydown will be called before keypress, which is used in submit-event delegation - keydown: function( e ) { - var elem = e.target, type = elem.type; - - if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") || - (e.keyCode === 32 && (type === "checkbox" || type === "radio")) || - type === "select-multiple" ) { - return testChange.call( this, e ); - } - }, - - // Beforeactivate happens also before the previous element is blurred - // with this event you can't trigger a change event, but you can store - // information/focus[in] is not needed anymore - beforeactivate: function( e ) { - var elem = e.target; - - if ( elem.nodeName.toLowerCase() === "input" && elem.type === "radio" ) { - jQuery.data( elem, "_change_data", getVal(elem) ); - } - } - }, - setup: function( data, namespaces, fn ) { - for ( var type in changeFilters ) { - jQuery.event.add( this, type + ".specialChange." + fn.guid, changeFilters[type] ); - } - - return formElems.test( this.nodeName ); - }, - remove: function( namespaces, fn ) { - for ( var type in changeFilters ) { - jQuery.event.remove( this, type + ".specialChange" + (fn ? "."+fn.guid : ""), changeFilters[type] ); - } - - return formElems.test( this.nodeName ); - } -}; - -var changeFilters = jQuery.event.special.change.filters; - -} - -function trigger( type, elem, args ) { - args[0].type = type; - return jQuery.event.handle.apply( elem, args ); -} - -// Create "bubbling" focus and blur events -if ( document.addEventListener ) { - jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { - jQuery.event.special[ fix ] = { - setup: function() { - /// - /// This method is internal. - /// - /// - - this.addEventListener( orig, handler, true ); - }, - teardown: function() { - /// - /// This method is internal. - /// - /// - - this.removeEventListener( orig, handler, true ); - } - }; - - function handler( e ) { - e = jQuery.event.fix( e ); - e.type = fix; - return jQuery.event.handle.call( this, e ); - } - }); -} - -// jQuery.each(["bind", "one"], function( i, name ) { -// jQuery.fn[ name ] = function( type, data, fn ) { -// // Handle object literals -// if ( typeof type === "object" ) { -// for ( var key in type ) { -// this[ name ](key, data, type[key], fn); -// } -// return this; -// } -// -// if ( jQuery.isFunction( data ) ) { -// fn = data; -// data = undefined; -// } -// -// var handler = name === "one" ? jQuery.proxy( fn, function( event ) { -// jQuery( this ).unbind( event, handler ); -// return fn.apply( this, arguments ); -// }) : fn; -// -// return type === "unload" && name !== "one" ? -// this.one( type, data, fn ) : -// this.each(function() { -// jQuery.event.add( this, type, handler, data ); -// }); -// }; -// }); - -jQuery.fn[ "bind" ] = function( type, data, fn ) { - /// - /// Binds a handler to one or more events for each matched element. Can also bind custom events. - /// - /// One or more event types separated by a space. Built-in event type values are: blur, focus, load, resize, scroll, unload, click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter, mouseleave, change, select, submit, keydown, keypress, keyup, error . - /// Additional data passed to the event handler as event.data - /// A function to bind to the event on each of the set of matched elements. function callback(eventObject) such that this corresponds to the dom element. - - // Handle object literals - if ( typeof type === "object" ) { - for ( var key in type ) { - this[ "bind" ](key, data, type[key], fn); - } - return this; - } - - if ( jQuery.isFunction( data ) ) { - fn = data; - data = undefined; - } - - var handler = "bind" === "one" ? jQuery.proxy( fn, function( event ) { - jQuery( this ).unbind( event, handler ); - return fn.apply( this, arguments ); - }) : fn; - - return type === "unload" && "bind" !== "one" ? - this.one( type, data, fn ) : - this.each(function() { - jQuery.event.add( this, type, handler, data ); - }); -}; - -jQuery.fn[ "one" ] = function( type, data, fn ) { - /// - /// Binds a handler to one or more events to be executed exactly once for each matched element. - /// - /// One or more event types separated by a space. Built-in event type values are: blur, focus, load, resize, scroll, unload, click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter, mouseleave, change, select, submit, keydown, keypress, keyup, error . - /// Additional data passed to the event handler as event.data - /// A function to bind to the event on each of the set of matched elements. function callback(eventObject) such that this corresponds to the dom element. - - // Handle object literals - if ( typeof type === "object" ) { - for ( var key in type ) { - this[ "one" ](key, data, type[key], fn); - } - return this; - } - - if ( jQuery.isFunction( data ) ) { - fn = data; - data = undefined; - } - - var handler = "one" === "one" ? jQuery.proxy( fn, function( event ) { - jQuery( this ).unbind( event, handler ); - return fn.apply( this, arguments ); - }) : fn; - - return type === "unload" && "one" !== "one" ? - this.one( type, data, fn ) : - this.each(function() { - jQuery.event.add( this, type, handler, data ); - }); -}; - -jQuery.fn.extend({ - unbind: function( type, fn ) { - /// - /// Unbinds a handler from one or more events for each matched element. - /// - /// One or more event types separated by a space. Built-in event type values are: blur, focus, load, resize, scroll, unload, click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter, mouseleave, change, select, submit, keydown, keypress, keyup, error . - /// A function to bind to the event on each of the set of matched elements. function callback(eventObject) such that this corresponds to the dom element. - - // Handle object literals - if ( typeof type === "object" && !type.preventDefault ) { - for ( var key in type ) { - this.unbind(key, type[key]); - } - return this; - } - - return this.each(function() { - jQuery.event.remove( this, type, fn ); - }); - }, - trigger: function( type, data ) { - /// - /// Triggers a type of event on every matched element. - /// - /// One or more event types separated by a space. Built-in event type values are: blur, focus, load, resize, scroll, unload, click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter, mouseleave, change, select, submit, keydown, keypress, keyup, error . - /// Additional data passed to the event handler as additional arguments. - /// This parameter is undocumented. - - return this.each(function() { - jQuery.event.trigger( type, data, this ); - }); - }, - - triggerHandler: function( type, data ) { - /// - /// Triggers all bound event handlers on an element for a specific event type without executing the browser's default actions. - /// - /// One or more event types separated by a space. Built-in event type values are: blur, focus, load, resize, scroll, unload, click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter, mouseleave, change, select, submit, keydown, keypress, keyup, error . - /// Additional data passed to the event handler as additional arguments. - /// This parameter is undocumented. - - if ( this[0] ) { - var event = jQuery.Event( type ); - event.preventDefault(); - event.stopPropagation(); - jQuery.event.trigger( event, data, this[0] ); - return event.result; - } - }, - - toggle: function( fn ) { - /// - /// Toggles among two or more function calls every other click. - /// - /// The functions among which to toggle execution - - // Save reference to arguments for access in closure - var args = arguments, i = 1; - - // link all the functions, so any of them can unbind this click handler - while ( i < args.length ) { - jQuery.proxy( fn, args[ i++ ] ); - } - - return this.click( jQuery.proxy( fn, function( event ) { - // Figure out which function to execute - var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i; - jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 ); - - // Make sure that clicks stop - event.preventDefault(); - - // and execute the function - return args[ lastToggle ].apply( this, arguments ) || false; - })); - }, - - hover: function( fnOver, fnOut ) { - /// - /// Simulates hovering (moving the mouse on or off of an object). - /// - /// The function to fire when the mouse is moved over a matched element. - /// The function to fire when the mouse is moved off of a matched element. - - return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); - } -}); - -// jQuery.each(["live", "die"], function( i, name ) { -// jQuery.fn[ name ] = function( types, data, fn ) { -// var type, i = 0; -// -// if ( jQuery.isFunction( data ) ) { -// fn = data; -// data = undefined; -// } -// -// types = (types || "").split( /\s+/ ); -// -// while ( (type = types[ i++ ]) != null ) { -// type = type === "focus" ? "focusin" : // focus --> focusin -// type === "blur" ? "focusout" : // blur --> focusout -// type === "hover" ? types.push("mouseleave") && "mouseenter" : // hover support -// type; -// -// if ( name === "live" ) { -// // bind live handler -// jQuery( this.context ).bind( liveConvert( type, this.selector ), { -// data: data, selector: this.selector, live: type -// }, fn ); -// -// } else { -// // unbind live handler -// jQuery( this.context ).unbind( liveConvert( type, this.selector ), fn ? { guid: fn.guid + this.selector + type } : null ); -// } -// } -// -// return this; -// } -// }); - -jQuery.fn[ "live" ] = function( types, data, fn ) { - /// - /// Attach a handler to the event for all elements which match the current selector, now or - /// in the future. - /// - /// - /// A string containing a JavaScript event type, such as "click" or "keydown". - /// - /// - /// A map of data that will be passed to the event handler. - /// - /// - /// A function to execute at the time the event is triggered. - /// - /// - - var type, i = 0; - - if ( jQuery.isFunction( data ) ) { - fn = data; - data = undefined; - } - - types = (types || "").split( /\s+/ ); - - while ( (type = types[ i++ ]) != null ) { - type = type === "focus" ? "focusin" : // focus --> focusin - type === "blur" ? "focusout" : // blur --> focusout - type === "hover" ? types.push("mouseleave") && "mouseenter" : // hover support - type; - - if ( "live" === "live" ) { - // bind live handler - jQuery( this.context ).bind( liveConvert( type, this.selector ), { - data: data, selector: this.selector, live: type - }, fn ); - - } else { - // unbind live handler - jQuery( this.context ).unbind( liveConvert( type, this.selector ), fn ? { guid: fn.guid + this.selector + type } : null ); - } - } - - return this; -} - -jQuery.fn[ "die" ] = function( types, data, fn ) { - /// - /// Remove all event handlers previously attached using .live() from the elements. - /// - /// - /// A string containing a JavaScript event type, such as click or keydown. - /// - /// - /// The function that is to be no longer executed. - /// - /// - - var type, i = 0; - - if ( jQuery.isFunction( data ) ) { - fn = data; - data = undefined; - } - - types = (types || "").split( /\s+/ ); - - while ( (type = types[ i++ ]) != null ) { - type = type === "focus" ? "focusin" : // focus --> focusin - type === "blur" ? "focusout" : // blur --> focusout - type === "hover" ? types.push("mouseleave") && "mouseenter" : // hover support - type; - - if ( "die" === "live" ) { - // bind live handler - jQuery( this.context ).bind( liveConvert( type, this.selector ), { - data: data, selector: this.selector, live: type - }, fn ); - - } else { - // unbind live handler - jQuery( this.context ).unbind( liveConvert( type, this.selector ), fn ? { guid: fn.guid + this.selector + type } : null ); - } - } - - return this; -} - -function liveHandler( event ) { - var stop, elems = [], selectors = [], args = arguments, - related, match, fn, elem, j, i, l, data, - live = jQuery.extend({}, jQuery.data( this, "events" ).live); - - // Make sure we avoid non-left-click bubbling in Firefox (#3861) - if ( event.button && event.type === "click" ) { - return; - } - - for ( j in live ) { - fn = live[j]; - if ( fn.live === event.type || - fn.altLive && jQuery.inArray(event.type, fn.altLive) > -1 ) { - - data = fn.data; - if ( !(data.beforeFilter && data.beforeFilter[event.type] && - !data.beforeFilter[event.type](event)) ) { - selectors.push( fn.selector ); - } - } else { - delete live[j]; - } - } - - match = jQuery( event.target ).closest( selectors, event.currentTarget ); - - for ( i = 0, l = match.length; i < l; i++ ) { - for ( j in live ) { - fn = live[j]; - elem = match[i].elem; - related = null; - - if ( match[i].selector === fn.selector ) { - // Those two events require additional checking - if ( fn.live === "mouseenter" || fn.live === "mouseleave" ) { - related = jQuery( event.relatedTarget ).closest( fn.selector )[0]; - } - - if ( !related || related !== elem ) { - elems.push({ elem: elem, fn: fn }); - } - } - } - } - - for ( i = 0, l = elems.length; i < l; i++ ) { - match = elems[i]; - event.currentTarget = match.elem; - event.data = match.fn.data; - if ( match.fn.apply( match.elem, args ) === false ) { - stop = false; - break; - } - } - - return stop; -} - -function liveConvert( type, selector ) { - return "live." + (type ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&"); -} - -// jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + -// "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + -// "change select submit keydown keypress keyup error").split(" "), function( i, name ) { -// -// // Handle event binding -// jQuery.fn[ name ] = function( fn ) { -// return fn ? this.bind( name, fn ) : this.trigger( name ); -// }; -// -// if ( jQuery.attrFn ) { -// jQuery.attrFn[ name ] = true; -// } -// }); - -jQuery.fn[ "blur" ] = function( fn ) { - /// - /// 1: blur() - Triggers the blur event of each matched element. - /// 2: blur(fn) - Binds a function to the blur event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "blur", fn ) : this.trigger( "blur" ); -}; - -jQuery.fn[ "focus" ] = function( fn ) { - /// - /// 1: focus() - Triggers the focus event of each matched element. - /// 2: focus(fn) - Binds a function to the focus event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "focus", fn ) : this.trigger( "focus" ); -}; - -jQuery.fn[ "focusin" ] = function( fn ) { - /// - /// Bind an event handler to the "focusin" JavaScript event. - /// - /// - /// A function to execute each time the event is triggered. - /// - /// - - return fn ? this.bind( "focusin", fn ) : this.trigger( "focusin" ); -}; - -jQuery.fn[ "focusout" ] = function( fn ) { - /// - /// Bind an event handler to the "focusout" JavaScript event. - /// - /// - /// A function to execute each time the event is triggered. - /// - /// - - return fn ? this.bind( "focusout", fn ) : this.trigger( "focusout" ); -}; - -jQuery.fn[ "load" ] = function( fn ) { - /// - /// 1: load() - Triggers the load event of each matched element. - /// 2: load(fn) - Binds a function to the load event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "load", fn ) : this.trigger( "load" ); -}; - -jQuery.fn[ "resize" ] = function( fn ) { - /// - /// 1: resize() - Triggers the resize event of each matched element. - /// 2: resize(fn) - Binds a function to the resize event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "resize", fn ) : this.trigger( "resize" ); -}; - -jQuery.fn[ "scroll" ] = function( fn ) { - /// - /// 1: scroll() - Triggers the scroll event of each matched element. - /// 2: scroll(fn) - Binds a function to the scroll event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "scroll", fn ) : this.trigger( "scroll" ); -}; - -jQuery.fn[ "unload" ] = function( fn ) { - /// - /// 1: unload() - Triggers the unload event of each matched element. - /// 2: unload(fn) - Binds a function to the unload event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "unload", fn ) : this.trigger( "unload" ); -}; - -jQuery.fn[ "click" ] = function( fn ) { - /// - /// 1: click() - Triggers the click event of each matched element. - /// 2: click(fn) - Binds a function to the click event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "click", fn ) : this.trigger( "click" ); -}; - -jQuery.fn[ "dblclick" ] = function( fn ) { - /// - /// 1: dblclick() - Triggers the dblclick event of each matched element. - /// 2: dblclick(fn) - Binds a function to the dblclick event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "dblclick", fn ) : this.trigger( "dblclick" ); -}; - -jQuery.fn[ "mousedown" ] = function( fn ) { - /// - /// Binds a function to the mousedown event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "mousedown", fn ) : this.trigger( "mousedown" ); -}; - -jQuery.fn[ "mouseup" ] = function( fn ) { - /// - /// Bind a function to the mouseup event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "mouseup", fn ) : this.trigger( "mouseup" ); -}; - -jQuery.fn[ "mousemove" ] = function( fn ) { - /// - /// Bind a function to the mousemove event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "mousemove", fn ) : this.trigger( "mousemove" ); -}; - -jQuery.fn[ "mouseover" ] = function( fn ) { - /// - /// Bind a function to the mouseover event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "mouseover", fn ) : this.trigger( "mouseover" ); -}; - -jQuery.fn[ "mouseout" ] = function( fn ) { - /// - /// Bind a function to the mouseout event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "mouseout", fn ) : this.trigger( "mouseout" ); -}; - -jQuery.fn[ "mouseenter" ] = function( fn ) { - /// - /// Bind a function to the mouseenter event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "mouseenter", fn ) : this.trigger( "mouseenter" ); -}; - -jQuery.fn[ "mouseleave" ] = function( fn ) { - /// - /// Bind a function to the mouseleave event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "mouseleave", fn ) : this.trigger( "mouseleave" ); -}; - -jQuery.fn[ "change" ] = function( fn ) { - /// - /// 1: change() - Triggers the change event of each matched element. - /// 2: change(fn) - Binds a function to the change event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "change", fn ) : this.trigger( "change" ); -}; - -jQuery.fn[ "select" ] = function( fn ) { - /// - /// 1: select() - Triggers the select event of each matched element. - /// 2: select(fn) - Binds a function to the select event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "select", fn ) : this.trigger( "select" ); -}; - -jQuery.fn[ "submit" ] = function( fn ) { - /// - /// 1: submit() - Triggers the submit event of each matched element. - /// 2: submit(fn) - Binds a function to the submit event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "submit", fn ) : this.trigger( "submit" ); -}; - -jQuery.fn[ "keydown" ] = function( fn ) { - /// - /// 1: keydown() - Triggers the keydown event of each matched element. - /// 2: keydown(fn) - Binds a function to the keydown event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "keydown", fn ) : this.trigger( "keydown" ); -}; - -jQuery.fn[ "keypress" ] = function( fn ) { - /// - /// 1: keypress() - Triggers the keypress event of each matched element. - /// 2: keypress(fn) - Binds a function to the keypress event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "keypress", fn ) : this.trigger( "keypress" ); -}; - -jQuery.fn[ "keyup" ] = function( fn ) { - /// - /// 1: keyup() - Triggers the keyup event of each matched element. - /// 2: keyup(fn) - Binds a function to the keyup event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "keyup", fn ) : this.trigger( "keyup" ); -}; - -jQuery.fn[ "error" ] = function( fn ) { - /// - /// 1: error() - Triggers the error event of each matched element. - /// 2: error(fn) - Binds a function to the error event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "error", fn ) : this.trigger( "error" ); -}; - -// Prevent memory leaks in IE -// Window isn't included so as not to unbind existing unload events -// More info: -// - http://isaacschlueter.com/2006/10/msie-memory-leaks/ -if ( window.attachEvent && !window.addEventListener ) { - window.attachEvent("onunload", function() { - for ( var id in jQuery.cache ) { - if ( jQuery.cache[ id ].handle ) { - // Try/Catch is to handle iframes being unloaded, see #4280 - try { - jQuery.event.remove( jQuery.cache[ id ].handle.elem ); - } catch(e) {} - } - } - }); -} -/*! - * Sizzle CSS Selector Engine - v1.0 - * Copyright 2009, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * More information: http://sizzlejs.com/ - */ -(function(){ - -var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, - done = 0, - toString = Object.prototype.toString, - hasDuplicate = false, - baseHasDuplicate = true; - -// Here we check if the JavaScript engine is using some sort of -// optimization where it does not always call our comparision -// function. If that is the case, discard the hasDuplicate value. -// Thus far that includes Google Chrome. -[0, 0].sort(function(){ - baseHasDuplicate = false; - return 0; -}); - -var Sizzle = function(selector, context, results, seed) { - results = results || []; - var origContext = context = context || document; - - if ( context.nodeType !== 1 && context.nodeType !== 9 ) { - return []; - } - - if ( !selector || typeof selector !== "string" ) { - return results; - } - - var parts = [], m, set, checkSet, extra, prune = true, contextXML = isXML(context), - soFar = selector; - - // Reset the position of the chunker regexp (start from head) - while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) { - soFar = m[3]; - - parts.push( m[1] ); - - if ( m[2] ) { - extra = m[3]; - break; - } - } - - if ( parts.length > 1 && origPOS.exec( selector ) ) { - if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { - set = posProcess( parts[0] + parts[1], context ); - } else { - set = Expr.relative[ parts[0] ] ? - [ context ] : - Sizzle( parts.shift(), context ); - - while ( parts.length ) { - selector = parts.shift(); - - if ( Expr.relative[ selector ] ) { - selector += parts.shift(); - } - - set = posProcess( selector, set ); - } - } - } else { - // Take a shortcut and set the context if the root selector is an ID - // (but not if it'll be faster if the inner selector is an ID) - if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && - Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { - var ret = Sizzle.find( parts.shift(), context, contextXML ); - context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0]; - } - - if ( context ) { - var ret = seed ? - { expr: parts.pop(), set: makeArray(seed) } : - Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); - set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set; - - if ( parts.length > 0 ) { - checkSet = makeArray(set); - } else { - prune = false; - } - - while ( parts.length ) { - var cur = parts.pop(), pop = cur; - - if ( !Expr.relative[ cur ] ) { - cur = ""; - } else { - pop = parts.pop(); - } - - if ( pop == null ) { - pop = context; - } - - Expr.relative[ cur ]( checkSet, pop, contextXML ); - } - } else { - checkSet = parts = []; - } - } - - if ( !checkSet ) { - checkSet = set; - } - - if ( !checkSet ) { - Sizzle.error( cur || selector ); - } - - if ( toString.call(checkSet) === "[object Array]" ) { - if ( !prune ) { - results.push.apply( results, checkSet ); - } else if ( context && context.nodeType === 1 ) { - for ( var i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) { - results.push( set[i] ); - } - } - } else { - for ( var i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && checkSet[i].nodeType === 1 ) { - results.push( set[i] ); - } - } - } - } else { - makeArray( checkSet, results ); - } - - if ( extra ) { - Sizzle( extra, origContext, results, seed ); - Sizzle.uniqueSort( results ); - } - - return results; -}; - -Sizzle.uniqueSort = function(results){ - /// - /// Removes all duplicate elements from an array of elements. - /// - /// The array to translate - /// The array after translation. - - if ( sortOrder ) { - hasDuplicate = baseHasDuplicate; - results.sort(sortOrder); - - if ( hasDuplicate ) { - for ( var i = 1; i < results.length; i++ ) { - if ( results[i] === results[i-1] ) { - results.splice(i--, 1); - } - } - } - } - - return results; -}; - -Sizzle.matches = function(expr, set){ - return Sizzle(expr, null, null, set); -}; - -Sizzle.find = function(expr, context, isXML){ - var set, match; - - if ( !expr ) { - return []; - } - - for ( var i = 0, l = Expr.order.length; i < l; i++ ) { - var type = Expr.order[i], match; - - if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { - var left = match[1]; - match.splice(1,1); - - if ( left.substr( left.length - 1 ) !== "\\" ) { - match[1] = (match[1] || "").replace(/\\/g, ""); - set = Expr.find[ type ]( match, context, isXML ); - if ( set != null ) { - expr = expr.replace( Expr.match[ type ], "" ); - break; - } - } - } - } - - if ( !set ) { - set = context.getElementsByTagName("*"); - } - - return {set: set, expr: expr}; -}; - -Sizzle.filter = function(expr, set, inplace, not){ - var old = expr, result = [], curLoop = set, match, anyFound, - isXMLFilter = set && set[0] && isXML(set[0]); - - while ( expr && set.length ) { - for ( var type in Expr.filter ) { - if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { - var filter = Expr.filter[ type ], found, item, left = match[1]; - anyFound = false; - - match.splice(1,1); - - if ( left.substr( left.length - 1 ) === "\\" ) { - continue; - } - - if ( curLoop === result ) { - result = []; - } - - if ( Expr.preFilter[ type ] ) { - match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); - - if ( !match ) { - anyFound = found = true; - } else if ( match === true ) { - continue; - } - } - - if ( match ) { - for ( var i = 0; (item = curLoop[i]) != null; i++ ) { - if ( item ) { - found = filter( item, match, i, curLoop ); - var pass = not ^ !!found; - - if ( inplace && found != null ) { - if ( pass ) { - anyFound = true; - } else { - curLoop[i] = false; - } - } else if ( pass ) { - result.push( item ); - anyFound = true; - } - } - } - } - - if ( found !== undefined ) { - if ( !inplace ) { - curLoop = result; - } - - expr = expr.replace( Expr.match[ type ], "" ); - - if ( !anyFound ) { - return []; - } - - break; - } - } - } - - // Improper expression - if ( expr === old ) { - if ( anyFound == null ) { - Sizzle.error( expr ); - } else { - break; - } - } - - old = expr; - } - - return curLoop; -}; - -Sizzle.error = function( msg ) { - throw "Syntax error, unrecognized expression: " + msg; -}; - -var Expr = Sizzle.selectors = { - order: [ "ID", "NAME", "TAG" ], - match: { - ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/, - CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/, - NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/, - ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/, - TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/, - CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/, - POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/, - PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ - }, - leftMatch: {}, - attrMap: { - "class": "className", - "for": "htmlFor" - }, - attrHandle: { - href: function(elem){ - return elem.getAttribute("href"); - } - }, - relative: { - "+": function(checkSet, part){ - var isPartStr = typeof part === "string", - isTag = isPartStr && !/\W/.test(part), - isPartStrNotTag = isPartStr && !isTag; - - if ( isTag ) { - part = part.toLowerCase(); - } - - for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { - if ( (elem = checkSet[i]) ) { - while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} - - checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? - elem || false : - elem === part; - } - } - - if ( isPartStrNotTag ) { - Sizzle.filter( part, checkSet, true ); - } - }, - ">": function(checkSet, part){ - var isPartStr = typeof part === "string"; - - if ( isPartStr && !/\W/.test(part) ) { - part = part.toLowerCase(); - - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - if ( elem ) { - var parent = elem.parentNode; - checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; - } - } - } else { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - if ( elem ) { - checkSet[i] = isPartStr ? - elem.parentNode : - elem.parentNode === part; - } - } - - if ( isPartStr ) { - Sizzle.filter( part, checkSet, true ); - } - } - }, - "": function(checkSet, part, isXML){ - var doneName = done++, checkFn = dirCheck; - - if ( typeof part === "string" && !/\W/.test(part) ) { - var nodeCheck = part = part.toLowerCase(); - checkFn = dirNodeCheck; - } - - checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML); - }, - "~": function(checkSet, part, isXML){ - var doneName = done++, checkFn = dirCheck; - - if ( typeof part === "string" && !/\W/.test(part) ) { - var nodeCheck = part = part.toLowerCase(); - checkFn = dirNodeCheck; - } - - checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML); - } - }, - find: { - ID: function(match, context, isXML){ - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - return m ? [m] : []; - } - }, - NAME: function(match, context){ - if ( typeof context.getElementsByName !== "undefined" ) { - var ret = [], results = context.getElementsByName(match[1]); - - for ( var i = 0, l = results.length; i < l; i++ ) { - if ( results[i].getAttribute("name") === match[1] ) { - ret.push( results[i] ); - } - } - - return ret.length === 0 ? null : ret; - } - }, - TAG: function(match, context){ - return context.getElementsByTagName(match[1]); - } - }, - preFilter: { - CLASS: function(match, curLoop, inplace, result, not, isXML){ - match = " " + match[1].replace(/\\/g, "") + " "; - - if ( isXML ) { - return match; - } - - for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { - if ( elem ) { - if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) { - if ( !inplace ) { - result.push( elem ); - } - } else if ( inplace ) { - curLoop[i] = false; - } - } - } - - return false; - }, - ID: function(match){ - return match[1].replace(/\\/g, ""); - }, - TAG: function(match, curLoop){ - return match[1].toLowerCase(); - }, - CHILD: function(match){ - if ( match[1] === "nth" ) { - // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' - var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec( - match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || - !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); - - // calculate the numbers (first)n+(last) including if they are negative - match[2] = (test[1] + (test[2] || 1)) - 0; - match[3] = test[3] - 0; - } - - // TODO: Move to normal caching system - match[0] = done++; - - return match; - }, - ATTR: function(match, curLoop, inplace, result, not, isXML){ - var name = match[1].replace(/\\/g, ""); - - if ( !isXML && Expr.attrMap[name] ) { - match[1] = Expr.attrMap[name]; - } - - if ( match[2] === "~=" ) { - match[4] = " " + match[4] + " "; - } - - return match; - }, - PSEUDO: function(match, curLoop, inplace, result, not){ - if ( match[1] === "not" ) { - // If we're dealing with a complex expression, or a simple one - if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { - match[3] = Sizzle(match[3], null, null, curLoop); - } else { - var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); - if ( !inplace ) { - result.push.apply( result, ret ); - } - return false; - } - } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { - return true; - } - - return match; - }, - POS: function(match){ - match.unshift( true ); - return match; - } - }, - filters: { - enabled: function(elem){ - return elem.disabled === false && elem.type !== "hidden"; - }, - disabled: function(elem){ - return elem.disabled === true; - }, - checked: function(elem){ - return elem.checked === true; - }, - selected: function(elem){ - // Accessing this property makes selected-by-default - // options in Safari work properly - elem.parentNode.selectedIndex; - return elem.selected === true; - }, - parent: function(elem){ - return !!elem.firstChild; - }, - empty: function(elem){ - return !elem.firstChild; - }, - has: function(elem, i, match){ - /// - /// Internal use only; use hasClass('class') - /// - /// - - return !!Sizzle( match[3], elem ).length; - }, - header: function(elem){ - return /h\d/i.test( elem.nodeName ); - }, - text: function(elem){ - return "text" === elem.type; - }, - radio: function(elem){ - return "radio" === elem.type; - }, - checkbox: function(elem){ - return "checkbox" === elem.type; - }, - file: function(elem){ - return "file" === elem.type; - }, - password: function(elem){ - return "password" === elem.type; - }, - submit: function(elem){ - return "submit" === elem.type; - }, - image: function(elem){ - return "image" === elem.type; - }, - reset: function(elem){ - return "reset" === elem.type; - }, - button: function(elem){ - return "button" === elem.type || elem.nodeName.toLowerCase() === "button"; - }, - input: function(elem){ - return /input|select|textarea|button/i.test(elem.nodeName); - } - }, - setFilters: { - first: function(elem, i){ - return i === 0; - }, - last: function(elem, i, match, array){ - return i === array.length - 1; - }, - even: function(elem, i){ - return i % 2 === 0; - }, - odd: function(elem, i){ - return i % 2 === 1; - }, - lt: function(elem, i, match){ - return i < match[3] - 0; - }, - gt: function(elem, i, match){ - return i > match[3] - 0; - }, - nth: function(elem, i, match){ - return match[3] - 0 === i; - }, - eq: function(elem, i, match){ - return match[3] - 0 === i; - } - }, - filter: { - PSEUDO: function(elem, match, i, array){ - var name = match[1], filter = Expr.filters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - } else if ( name === "contains" ) { - return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; - } else if ( name === "not" ) { - var not = match[3]; - - for ( var i = 0, l = not.length; i < l; i++ ) { - if ( not[i] === elem ) { - return false; - } - } - - return true; - } else { - Sizzle.error( "Syntax error, unrecognized expression: " + name ); - } - }, - CHILD: function(elem, match){ - var type = match[1], node = elem; - switch (type) { - case 'only': - case 'first': - while ( (node = node.previousSibling) ) { - if ( node.nodeType === 1 ) { - return false; - } - } - if ( type === "first" ) { - return true; - } - node = elem; - case 'last': - while ( (node = node.nextSibling) ) { - if ( node.nodeType === 1 ) { - return false; - } - } - return true; - case 'nth': - var first = match[2], last = match[3]; - - if ( first === 1 && last === 0 ) { - return true; - } - - var doneName = match[0], - parent = elem.parentNode; - - if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { - var count = 0; - for ( node = parent.firstChild; node; node = node.nextSibling ) { - if ( node.nodeType === 1 ) { - node.nodeIndex = ++count; - } - } - parent.sizcache = doneName; - } - - var diff = elem.nodeIndex - last; - if ( first === 0 ) { - return diff === 0; - } else { - return ( diff % first === 0 && diff / first >= 0 ); - } - } - }, - ID: function(elem, match){ - return elem.nodeType === 1 && elem.getAttribute("id") === match; - }, - TAG: function(elem, match){ - return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match; - }, - CLASS: function(elem, match){ - return (" " + (elem.className || elem.getAttribute("class")) + " ") - .indexOf( match ) > -1; - }, - ATTR: function(elem, match){ - var name = match[1], - result = Expr.attrHandle[ name ] ? - Expr.attrHandle[ name ]( elem ) : - elem[ name ] != null ? - elem[ name ] : - elem.getAttribute( name ), - value = result + "", - type = match[2], - check = match[4]; - - return result == null ? - type === "!=" : - type === "=" ? - value === check : - type === "*=" ? - value.indexOf(check) >= 0 : - type === "~=" ? - (" " + value + " ").indexOf(check) >= 0 : - !check ? - value && result !== false : - type === "!=" ? - value !== check : - type === "^=" ? - value.indexOf(check) === 0 : - type === "$=" ? - value.substr(value.length - check.length) === check : - type === "|=" ? - value === check || value.substr(0, check.length + 1) === check + "-" : - false; - }, - POS: function(elem, match, i, array){ - var name = match[2], filter = Expr.setFilters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - } - } - } -}; - -var origPOS = Expr.match.POS; - -for ( var type in Expr.match ) { - Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source ); - Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, function(all, num){ - return "\\" + (num - 0 + 1); - })); -} - -var makeArray = function(array, results) { - array = Array.prototype.slice.call( array, 0 ); - - if ( results ) { - results.push.apply( results, array ); - return results; - } - - return array; -}; - -// Perform a simple check to determine if the browser is capable of -// converting a NodeList to an array using builtin methods. -try { - Array.prototype.slice.call( document.documentElement.childNodes, 0 ); - -// Provide a fallback method if it does not work -} catch(e){ - makeArray = function(array, results) { - var ret = results || []; - - if ( toString.call(array) === "[object Array]" ) { - Array.prototype.push.apply( ret, array ); - } else { - if ( typeof array.length === "number" ) { - for ( var i = 0, l = array.length; i < l; i++ ) { - ret.push( array[i] ); - } - } else { - for ( var i = 0; array[i]; i++ ) { - ret.push( array[i] ); - } - } - } - - return ret; - }; -} - -var sortOrder; - -if ( document.documentElement.compareDocumentPosition ) { - sortOrder = function( a, b ) { - if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { - if ( a == b ) { - hasDuplicate = true; - } - return a.compareDocumentPosition ? -1 : 1; - } - - var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1; - if ( ret === 0 ) { - hasDuplicate = true; - } - return ret; - }; -} else if ( "sourceIndex" in document.documentElement ) { - sortOrder = function( a, b ) { - if ( !a.sourceIndex || !b.sourceIndex ) { - if ( a == b ) { - hasDuplicate = true; - } - return a.sourceIndex ? -1 : 1; - } - - var ret = a.sourceIndex - b.sourceIndex; - if ( ret === 0 ) { - hasDuplicate = true; - } - return ret; - }; -} else if ( document.createRange ) { - sortOrder = function( a, b ) { - if ( !a.ownerDocument || !b.ownerDocument ) { - if ( a == b ) { - hasDuplicate = true; - } - return a.ownerDocument ? -1 : 1; - } - - var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange(); - aRange.setStart(a, 0); - aRange.setEnd(a, 0); - bRange.setStart(b, 0); - bRange.setEnd(b, 0); - var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange); - if ( ret === 0 ) { - hasDuplicate = true; - } - return ret; - }; -} - -// Utility function for retreiving the text value of an array of DOM nodes -function getText( elems ) { - var ret = "", elem; - - for ( var i = 0; elems[i]; i++ ) { - elem = elems[i]; - - // Get the text from text nodes and CDATA nodes - if ( elem.nodeType === 3 || elem.nodeType === 4 ) { - ret += elem.nodeValue; - - // Traverse everything else, except comment nodes - } else if ( elem.nodeType !== 8 ) { - ret += getText( elem.childNodes ); - } - } - - return ret; -} - -// [vsdoc] The following function has been modified for IntelliSense. -// Check to see if the browser returns elements by name when -// querying by getElementById (and provide a workaround) -(function(){ - // We're going to inject a fake input element with a specified name - // var form = document.createElement("div"), - // id = "script" + (new Date).getTime(); - // form.innerHTML = ""; - - // // Inject it into the root element, check its status, and remove it quickly - // var root = document.documentElement; - // root.insertBefore( form, root.firstChild ); - - // The workaround has to do additional checks after a getElementById - // Which slows things down for other browsers (hence the branching) - // if ( document.getElementById( id ) ) { - Expr.find.ID = function(match, context, isXML){ - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : []; - } - }; - - Expr.filter.ID = function(elem, match){ - var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); - return elem.nodeType === 1 && node && node.nodeValue === match; - }; - // } - - // root.removeChild( form ); - root = form = null; // release memory in IE -})(); - -// [vsdoc] The following function has been modified for IntelliSense. -(function(){ - // Check to see if the browser returns only elements - // when doing getElementsByTagName("*") - - // Create a fake element - // var div = document.createElement("div"); - // div.appendChild( document.createComment("") ); - - // Make sure no comments are found - // if ( div.getElementsByTagName("*").length > 0 ) { - Expr.find.TAG = function(match, context){ - var results = context.getElementsByTagName(match[1]); - - // Filter out possible comments - if ( match[1] === "*" ) { - var tmp = []; - - for ( var i = 0; results[i]; i++ ) { - if ( results[i].nodeType === 1 ) { - tmp.push( results[i] ); - } - } - - results = tmp; - } - - return results; - }; - // } - - // Check to see if an attribute returns normalized href attributes - // div.innerHTML = ""; - // if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && - // div.firstChild.getAttribute("href") !== "#" ) { - Expr.attrHandle.href = function(elem){ - return elem.getAttribute("href", 2); - }; - // } - - div = null; // release memory in IE -})(); - -if ( document.querySelectorAll ) { - (function(){ - var oldSizzle = Sizzle, div = document.createElement("div"); - div.innerHTML = "

"; - - // Safari can't handle uppercase or unicode characters when - // in quirks mode. - if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { - return; - } - - Sizzle = function(query, context, extra, seed){ - context = context || document; - - // Only use querySelectorAll on non-XML documents - // (ID selectors don't work in non-HTML documents) - if ( !seed && context.nodeType === 9 && !isXML(context) ) { - try { - return makeArray( context.querySelectorAll(query), extra ); - } catch(e){} - } - - return oldSizzle(query, context, extra, seed); - }; - - for ( var prop in oldSizzle ) { - Sizzle[ prop ] = oldSizzle[ prop ]; - } - - div = null; // release memory in IE - })(); -} - -(function(){ - var div = document.createElement("div"); - - div.innerHTML = "
"; - - // Opera can't find a second classname (in 9.6) - // Also, make sure that getElementsByClassName actually exists - if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { - return; - } - - // Safari caches class attributes, doesn't catch changes (in 3.2) - div.lastChild.className = "e"; - - if ( div.getElementsByClassName("e").length === 1 ) { - return; - } - - Expr.order.splice(1, 0, "CLASS"); - Expr.find.CLASS = function(match, context, isXML) { - if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { - return context.getElementsByClassName(match[1]); - } - }; - - div = null; // release memory in IE -})(); - -function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - if ( elem ) { - elem = elem[dir]; - var match = false; - - while ( elem ) { - if ( elem.sizcache === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 && !isXML ){ - elem.sizcache = doneName; - elem.sizset = i; - } - - if ( elem.nodeName.toLowerCase() === cur ) { - match = elem; - break; - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - if ( elem ) { - elem = elem[dir]; - var match = false; - - while ( elem ) { - if ( elem.sizcache === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 ) { - if ( !isXML ) { - elem.sizcache = doneName; - elem.sizset = i; - } - if ( typeof cur !== "string" ) { - if ( elem === cur ) { - match = true; - break; - } - - } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { - match = elem; - break; - } - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -var contains = document.compareDocumentPosition ? function(a, b){ - /// - /// Check to see if a DOM node is within another DOM node. - /// - /// - /// The DOM element that may contain the other element. - /// - /// - /// The DOM node that may be contained by the other element. - /// - /// - - return a.compareDocumentPosition(b) & 16; -} : function(a, b){ - /// - /// Check to see if a DOM node is within another DOM node. - /// - /// - /// The DOM element that may contain the other element. - /// - /// - /// The DOM node that may be contained by the other element. - /// - /// - - return a !== b && (a.contains ? a.contains(b) : true); -}; - -var isXML = function(elem){ - /// - /// Determines if the parameter passed is an XML document. - /// - /// The object to test - /// True if the parameter is an XML document; otherwise false. - - // documentElement is verified for cases where it doesn't yet exist - // (such as loading iframes in IE - #4833) - var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; - return documentElement ? documentElement.nodeName !== "HTML" : false; -}; - -var posProcess = function(selector, context){ - var tmpSet = [], later = "", match, - root = context.nodeType ? [context] : context; - - // Position selectors must be done after the filter - // And so must :not(positional) so we move all PSEUDOs to the end - while ( (match = Expr.match.PSEUDO.exec( selector )) ) { - later += match[0]; - selector = selector.replace( Expr.match.PSEUDO, "" ); - } - - selector = Expr.relative[selector] ? selector + "*" : selector; - - for ( var i = 0, l = root.length; i < l; i++ ) { - Sizzle( selector, root[i], tmpSet ); - } - - return Sizzle.filter( later, tmpSet ); -}; - -// EXPOSE -jQuery.find = Sizzle; -jQuery.expr = Sizzle.selectors; -jQuery.expr[":"] = jQuery.expr.filters; -jQuery.unique = Sizzle.uniqueSort; -jQuery.getText = getText; -jQuery.isXMLDoc = isXML; -jQuery.contains = contains; - -return; - -window.Sizzle = Sizzle; - -})(); -var runtil = /Until$/, - rparentsprev = /^(?:parents|prevUntil|prevAll)/, - // Note: This RegExp should be improved, or likely pulled from Sizzle - rmultiselector = /,/, - slice = Array.prototype.slice; - -// Implement the identical functionality for filter and not -var winnow = function( elements, qualifier, keep ) { - if ( jQuery.isFunction( qualifier ) ) { - return jQuery.grep(elements, function( elem, i ) { - return !!qualifier.call( elem, i, elem ) === keep; - }); - - } else if ( qualifier.nodeType ) { - return jQuery.grep(elements, function( elem, i ) { - return (elem === qualifier) === keep; - }); - - } else if ( typeof qualifier === "string" ) { - var filtered = jQuery.grep(elements, function( elem ) { - return elem.nodeType === 1; - }); - - if ( isSimple.test( qualifier ) ) { - return jQuery.filter(qualifier, filtered, !keep); - } else { - qualifier = jQuery.filter( qualifier, filtered ); - } - } - - return jQuery.grep(elements, function( elem, i ) { - return (jQuery.inArray( elem, qualifier ) >= 0) === keep; - }); -}; - -jQuery.fn.extend({ - find: function( selector ) { - /// - /// Searches for all elements that match the specified expression. - /// This method is a good way to find additional descendant - /// elements with which to process. - /// All searching is done using a jQuery expression. The expression can be - /// written using CSS 1-3 Selector syntax, or basic XPath. - /// Part of DOM/Traversing - /// - /// - /// - /// An expression to search with. - /// - /// - - var ret = this.pushStack( "", "find", selector ), length = 0; - - for ( var i = 0, l = this.length; i < l; i++ ) { - length = ret.length; - jQuery.find( selector, this[i], ret ); - - if ( i > 0 ) { - // Make sure that the results are unique - for ( var n = length; n < ret.length; n++ ) { - for ( var r = 0; r < length; r++ ) { - if ( ret[r] === ret[n] ) { - ret.splice(n--, 1); - break; - } - } - } - } - } - - return ret; - }, - - has: function( target ) { - /// - /// Reduce the set of matched elements to those that have a descendant that matches the - /// selector or DOM element. - /// - /// - /// A string containing a selector expression to match elements against. - /// - /// - - var targets = jQuery( target ); - return this.filter(function() { - for ( var i = 0, l = targets.length; i < l; i++ ) { - if ( jQuery.contains( this, targets[i] ) ) { - return true; - } - } - }); - }, - - not: function( selector ) { - /// - /// Removes any elements inside the array of elements from the set - /// of matched elements. This method is used to remove one or more - /// elements from a jQuery object. - /// Part of DOM/Traversing - /// - /// - /// A set of elements to remove from the jQuery set of matched elements. - /// - /// - - return this.pushStack( winnow(this, selector, false), "not", selector); - }, - - filter: function( selector ) { - /// - /// Removes all elements from the set of matched elements that do not - /// pass the specified filter. This method is used to narrow down - /// the results of a search. - /// }) - /// Part of DOM/Traversing - /// - /// - /// - /// A function to use for filtering - /// - /// - - return this.pushStack( winnow(this, selector, true), "filter", selector ); - }, - - is: function( selector ) { - /// - /// Checks the current selection against an expression and returns true, - /// if at least one element of the selection fits the given expression. - /// Does return false, if no element fits or the expression is not valid. - /// filter(String) is used internally, therefore all rules that apply there - /// apply here, too. - /// Part of DOM/Traversing - /// - /// - /// - /// The expression with which to filter - /// - - return !!selector && jQuery.filter( selector, this ).length > 0; - }, - - closest: function( selectors, context ) { - /// - /// Get a set of elements containing the closest parent element that matches the specified selector, the starting element included. - /// - /// - /// A string containing a selector expression to match elements against. - /// - /// - /// A DOM element within which a matching element may be found. If no context is passed - /// in then the context of the jQuery set will be used instead. - /// - /// - - if ( jQuery.isArray( selectors ) ) { - var ret = [], cur = this[0], match, matches = {}, selector; - - if ( cur && selectors.length ) { - for ( var i = 0, l = selectors.length; i < l; i++ ) { - selector = selectors[i]; - - if ( !matches[selector] ) { - matches[selector] = jQuery.expr.match.POS.test( selector ) ? - jQuery( selector, context || this.context ) : - selector; - } - } - - while ( cur && cur.ownerDocument && cur !== context ) { - for ( selector in matches ) { - match = matches[selector]; - - if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) { - ret.push({ selector: selector, elem: cur }); - delete matches[selector]; - } - } - cur = cur.parentNode; - } - } - - return ret; - } - - var pos = jQuery.expr.match.POS.test( selectors ) ? - jQuery( selectors, context || this.context ) : null; - - return this.map(function( i, cur ) { - while ( cur && cur.ownerDocument && cur !== context ) { - if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selectors) ) { - return cur; - } - cur = cur.parentNode; - } - return null; - }); - }, - - // Determine the position of an element within - // the matched set of elements - index: function( elem ) { - /// - /// Searches every matched element for the object and returns - /// the index of the element, if found, starting with zero. - /// Returns -1 if the object wasn't found. - /// Part of Core - /// - /// - /// - /// Object to search for - /// - - if ( !elem || typeof elem === "string" ) { - return jQuery.inArray( this[0], - // If it receives a string, the selector is used - // If it receives nothing, the siblings are used - elem ? jQuery( elem ) : this.parent().children() ); - } - // Locate the position of the desired element - return jQuery.inArray( - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[0] : elem, this ); - }, - - add: function( selector, context ) { - /// - /// Adds one or more Elements to the set of matched elements. - /// Part of DOM/Traversing - /// - /// - /// A string containing a selector expression to match additional elements against. - /// - /// - /// Add some elements rooted against the specified context. - /// - /// - - var set = typeof selector === "string" ? - jQuery( selector, context || this.context ) : - jQuery.makeArray( selector ), - all = jQuery.merge( this.get(), set ); - - return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? - all : - jQuery.unique( all ) ); - }, - - andSelf: function() { - /// - /// Adds the previous selection to the current selection. - /// - /// - - return this.add( this.prevObject ); - } -}); - -// A painfully simple check to see if an element is disconnected -// from a document (should be improved, where feasible). -function isDisconnected( node ) { - return !node || !node.parentNode || node.parentNode.nodeType === 11; -} - -jQuery.each({ - parent: function( elem ) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function( elem ) { - return jQuery.dir( elem, "parentNode" ); - }, - next: function( elem ) { - return jQuery.nth( elem, 2, "nextSibling" ); - }, - prev: function( elem ) { - return jQuery.nth( elem, 2, "previousSibling" ); - }, - nextAll: function( elem ) { - return jQuery.dir( elem, "nextSibling" ); - }, - prevAll: function( elem ) { - return jQuery.dir( elem, "previousSibling" ); - }, - siblings: function( elem ) { - return jQuery.sibling( elem.parentNode.firstChild, elem ); - }, - children: function( elem ) { - return jQuery.sibling( elem.firstChild ); - }, - contents: function( elem ) { - return jQuery.nodeName( elem, "iframe" ) ? - elem.contentDocument || elem.contentWindow.document : - jQuery.makeArray( elem.childNodes ); - } -}, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var ret = jQuery.map( this, fn, until ); - - if ( !runtil.test( name ) ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - ret = jQuery.filter( selector, ret ); - } - - ret = this.length > 1 ? jQuery.unique( ret ) : ret; - - if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { - ret = ret.reverse(); - } - - return this.pushStack( ret, name, slice.call(arguments).join(",") ); - }; -}); - -jQuery.fn[ "parentsUntil" ] = function( until, selector ) { - /// - /// Get the ancestors of each element in the current set of matched elements, up to but not - /// including the element matched by the selector. - /// - /// - /// A string containing a selector expression to indicate where to stop matching ancestor - /// elements. - /// - /// - - var fn = function( elem, i, until ) { - return jQuery.dir( elem, "parentNode", until ); - } - - var ret = jQuery.map( this, fn, until ); - - if ( !runtil.test( "parentsUntil" ) ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - ret = jQuery.filter( selector, ret ); - } - - ret = this.length > 1 ? jQuery.unique( ret ) : ret; - - if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( "parentsUntil" ) ) { - ret = ret.reverse(); - } - - return this.pushStack( ret, "parentsUntil", slice.call(arguments).join(",") ); -}; - -jQuery.fn[ "nextUntil" ] = function( until, selector ) { - /// - /// Get all following siblings of each element up to but not including the element matched - /// by the selector. - /// - /// - /// A string containing a selector expression to indicate where to stop matching following - /// sibling elements. - /// - /// - - var fn = function( elem, i, until ) { - return jQuery.dir( elem, "nextSibling", until ); - } - - var ret = jQuery.map( this, fn, until ); - - if ( !runtil.test( "nextUntil" ) ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - ret = jQuery.filter( selector, ret ); - } - - ret = this.length > 1 ? jQuery.unique( ret ) : ret; - - if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( "nextUntil" ) ) { - ret = ret.reverse(); - } - - return this.pushStack( ret, "nextUntil", slice.call(arguments).join(",") ); -}; - -jQuery.fn[ "prevUntil" ] = function( until, selector ) { - /// - /// Get all preceding siblings of each element up to but not including the element matched - /// by the selector. - /// - /// - /// A string containing a selector expression to indicate where to stop matching preceding - /// sibling elements. - /// - /// - - var fn = function( elem, i, until ) { - return jQuery.dir( elem, "previousSibling", until ); - } - - var ret = jQuery.map( this, fn, until ); - - if ( !runtil.test( "prevUntil" ) ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - ret = jQuery.filter( selector, ret ); - } - - ret = this.length > 1 ? jQuery.unique( ret ) : ret; - - if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( "prevUntil" ) ) { - ret = ret.reverse(); - } - - return this.pushStack( ret, "prevUntil", slice.call(arguments).join(",") ); -}; - -jQuery.extend({ - filter: function( expr, elems, not ) { - if ( not ) { - expr = ":not(" + expr + ")"; - } - - return jQuery.find.matches(expr, elems); - }, - - dir: function( elem, dir, until ) { - /// - /// This member is internal only. - /// - /// - - var matched = [], cur = elem[dir]; - while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { - if ( cur.nodeType === 1 ) { - matched.push( cur ); - } - cur = cur[dir]; - } - return matched; - }, - - nth: function( cur, result, dir, elem ) { - /// - /// This member is internal only. - /// - /// - - result = result || 1; - var num = 0; - - for ( ; cur; cur = cur[dir] ) { - if ( cur.nodeType === 1 && ++num === result ) { - break; - } - } - - return cur; - }, - - sibling: function( n, elem ) { - /// - /// This member is internal only. - /// - /// - - var r = []; - - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - r.push( n ); - } - } - - return r; - } -}); -var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, - rleadingWhitespace = /^\s+/, - rxhtmlTag = /(<([\w:]+)[^>]*?)\/>/g, - rselfClosing = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i, - rtagName = /<([\w:]+)/, - rtbody = /"; - }, - wrapMap = { - option: [ 1, "" ], - legend: [ 1, "
", "
" ], - thead: [ 1, "", "
" ], - tr: [ 2, "", "
" ], - td: [ 3, "", "
" ], - col: [ 2, "", "
" ], - area: [ 1, "", "" ], - _default: [ 0, "", "" ] - }; - -wrapMap.optgroup = wrapMap.option; -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - -// IE can't serialize and