OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /////////////////////////////////////////////////////////////////////////////// | 5 /////////////////////////////////////////////////////////////////////////////// |
6 // Helper functions | 6 // Helper functions |
7 function $(o) {return document.getElementById(o);} | 7 function $(o) {return document.getElementById(o);} |
8 | 8 |
9 /** | 9 /** |
10 * Sets the display style of a node. | 10 * Sets the display style of a node. |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 this.nodeSince_ = createElementWithClassName('div', 'since'); | 180 this.nodeSince_ = createElementWithClassName('div', 'since'); |
181 this.nodeDate_ = createElementWithClassName('div', 'date'); | 181 this.nodeDate_ = createElementWithClassName('div', 'date'); |
182 this.dateContainer_.appendChild(this.nodeSince_); | 182 this.dateContainer_.appendChild(this.nodeSince_); |
183 this.dateContainer_.appendChild(this.nodeDate_); | 183 this.dateContainer_.appendChild(this.nodeDate_); |
184 | 184 |
185 // Container for all 'safe download' UI. | 185 // Container for all 'safe download' UI. |
186 this.safe_ = createElementWithClassName('div', 'safe'); | 186 this.safe_ = createElementWithClassName('div', 'safe'); |
187 this.safe_.ondragstart = this.drag_.bind(this); | 187 this.safe_.ondragstart = this.drag_.bind(this); |
188 this.node.appendChild(this.safe_); | 188 this.node.appendChild(this.safe_); |
189 | 189 |
190 if (download.state != Download.States.COMPLETE) { | 190 if (this.state_ != Download.States.COMPLETE || this.fileExternallyRemoved_) { |
191 this.nodeProgressBackground_ = | 191 this.nodeProgressBackground_ = |
192 createElementWithClassName('div', 'progress background'); | 192 createElementWithClassName('div', 'progress background'); |
193 this.safe_.appendChild(this.nodeProgressBackground_); | 193 this.safe_.appendChild(this.nodeProgressBackground_); |
194 | 194 |
195 this.canvasProgress_ = | 195 this.canvasProgress_ = |
196 document.getCSSCanvasContext('2d', 'canvas_' + download.id, | 196 document.getCSSCanvasContext('2d', 'canvas_' + download.id, |
197 Download.Progress.width, | 197 Download.Progress.width, |
198 Download.Progress.height); | 198 Download.Progress.height); |
199 | 199 |
200 this.nodeProgressForeground_ = | 200 this.nodeProgressForeground_ = |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 /** | 322 /** |
323 * Updates the download to reflect new data. | 323 * Updates the download to reflect new data. |
324 * @param {Object} download A backend download object (see downloads_ui.cc) | 324 * @param {Object} download A backend download object (see downloads_ui.cc) |
325 */ | 325 */ |
326 Download.prototype.update = function(download) { | 326 Download.prototype.update = function(download) { |
327 this.id_ = download.id; | 327 this.id_ = download.id; |
328 this.filePath_ = download.file_path; | 328 this.filePath_ = download.file_path; |
329 this.fileName_ = download.file_name; | 329 this.fileName_ = download.file_name; |
330 this.url_ = download.url; | 330 this.url_ = download.url; |
331 this.state_ = download.state; | 331 this.state_ = download.state; |
| 332 this.fileExternallyRemoved_ = download.file_externally_removed; |
332 this.dangerType_ = download.danger_type; | 333 this.dangerType_ = download.danger_type; |
333 | 334 |
334 this.since_ = download.since_string; | 335 this.since_ = download.since_string; |
335 this.date_ = download.date_string; | 336 this.date_ = download.date_string; |
336 | 337 |
337 // See DownloadItem::PercentComplete | 338 // See DownloadItem::PercentComplete |
338 this.percent_ = Math.max(download.percent, 0); | 339 this.percent_ = Math.max(download.percent, 0); |
339 this.progressStatusText_ = download.progress_status_text; | 340 this.progressStatusText_ = download.progress_status_text; |
340 this.received_ = download.received; | 341 this.received_ = download.received; |
341 | 342 |
342 if (this.state_ == Download.States.DANGEROUS) { | 343 if (this.state_ == Download.States.DANGEROUS) { |
343 if (this.dangerType_ == Download.DangerType.DANGEROUS_FILE) { | 344 if (this.dangerType_ == Download.DangerType.DANGEROUS_FILE) { |
344 this.dangerDesc_.innerHTML = localStrings.getStringF('danger_file_desc', | 345 this.dangerDesc_.innerHTML = localStrings.getStringF('danger_file_desc', |
345 this.fileName_); | 346 this.fileName_); |
346 } else { | 347 } else { |
347 this.dangerDesc_.innerHTML = localStrings.getString('danger_url_desc'); | 348 this.dangerDesc_.innerHTML = localStrings.getString('danger_url_desc'); |
348 } | 349 } |
349 this.danger_.style.display = 'block'; | 350 this.danger_.style.display = 'block'; |
350 this.safe_.style.display = 'none'; | 351 this.safe_.style.display = 'none'; |
351 } else { | 352 } else { |
352 this.nodeImg_.src = 'chrome://fileicon/' + this.filePath_; | 353 this.nodeImg_.src = 'chrome://fileicon/' + this.filePath_; |
353 | 354 |
354 if (this.state_ == Download.States.COMPLETE) { | 355 if (this.state_ == Download.States.COMPLETE && |
| 356 !this.fileExternallyRemoved_) { |
355 this.nodeFileLink_.innerHTML = this.fileName_; | 357 this.nodeFileLink_.innerHTML = this.fileName_; |
356 this.nodeFileLink_.href = this.filePath_; | 358 this.nodeFileLink_.href = this.filePath_; |
357 } else { | 359 } else { |
358 this.nodeFileName_.innerHTML = this.fileName_; | 360 this.nodeFileName_.innerHTML = this.fileName_; |
359 } | 361 } |
360 | 362 |
361 showInline(this.nodeFileLink_, this.state_ == Download.States.COMPLETE); | 363 showInline(this.nodeFileLink_, |
| 364 this.state_ == Download.States.COMPLETE && |
| 365 !this.fileExternallyRemoved_); |
362 // nodeFileName_ has to be inline-block to avoid the 'interaction' with | 366 // nodeFileName_ has to be inline-block to avoid the 'interaction' with |
363 // nodeStatus_. If both are inline, it appears that their text contents | 367 // nodeStatus_. If both are inline, it appears that their text contents |
364 // are merged before the bidi algorithm is applied leading to an | 368 // are merged before the bidi algorithm is applied leading to an |
365 // undesirable reordering. http://crbug.com/13216 | 369 // undesirable reordering. http://crbug.com/13216 |
366 showInlineBlock(this.nodeFileName_, this.state_ != Download.States.COMPLETE)
; | 370 showInlineBlock(this.nodeFileName_, |
| 371 this.state_ != Download.States.COMPLETE || |
| 372 this.fileExternallyRemoved_); |
367 | 373 |
368 if (this.state_ == Download.States.IN_PROGRESS) { | 374 if (this.state_ == Download.States.IN_PROGRESS) { |
369 this.nodeProgressForeground_.style.display = 'block'; | 375 this.nodeProgressForeground_.style.display = 'block'; |
370 this.nodeProgressBackground_.style.display = 'block'; | 376 this.nodeProgressBackground_.style.display = 'block'; |
371 | 377 |
372 // Draw a pie-slice for the progress. | 378 // Draw a pie-slice for the progress. |
373 this.canvasProgress_.clearRect(0, 0, | 379 this.canvasProgress_.clearRect(0, 0, |
374 Download.Progress.width, | 380 Download.Progress.width, |
375 Download.Progress.height); | 381 Download.Progress.height); |
376 this.canvasProgress_.beginPath(); | 382 this.canvasProgress_.beginPath(); |
(...skipping 12 matching lines...) Expand all Loading... |
389 this.canvasProgress_.lineTo(Download.Progress.centerX, | 395 this.canvasProgress_.lineTo(Download.Progress.centerX, |
390 Download.Progress.centerY); | 396 Download.Progress.centerY); |
391 this.canvasProgress_.fill(); | 397 this.canvasProgress_.fill(); |
392 this.canvasProgress_.closePath(); | 398 this.canvasProgress_.closePath(); |
393 } else if (this.nodeProgressBackground_) { | 399 } else if (this.nodeProgressBackground_) { |
394 this.nodeProgressForeground_.style.display = 'none'; | 400 this.nodeProgressForeground_.style.display = 'none'; |
395 this.nodeProgressBackground_.style.display = 'none'; | 401 this.nodeProgressBackground_.style.display = 'none'; |
396 } | 402 } |
397 | 403 |
398 if (this.controlShow_) { | 404 if (this.controlShow_) { |
399 showInline(this.controlShow_, this.state_ == Download.States.COMPLETE); | 405 showInline(this.controlShow_, |
| 406 this.state_ == Download.States.COMPLETE && |
| 407 !this.fileExternallyRemoved_); |
400 } | 408 } |
401 showInline(this.controlRetry_, this.state_ == Download.States.CANCELLED); | 409 showInline(this.controlRetry_, this.state_ == Download.States.CANCELLED); |
402 this.controlRetry_.href = this.url_; | 410 this.controlRetry_.href = this.url_; |
403 showInline(this.controlPause_, this.state_ == Download.States.IN_PROGRESS); | 411 showInline(this.controlPause_, this.state_ == Download.States.IN_PROGRESS); |
404 showInline(this.controlResume_, this.state_ == Download.States.PAUSED); | 412 showInline(this.controlResume_, this.state_ == Download.States.PAUSED); |
405 var showCancel = this.state_ == Download.States.IN_PROGRESS || | 413 var showCancel = this.state_ == Download.States.IN_PROGRESS || |
406 this.state_ == Download.States.PAUSED; | 414 this.state_ == Download.States.PAUSED; |
407 showInline(this.controlCancel_, showCancel); | 415 showInline(this.controlCancel_, showCancel); |
408 showInline(this.controlRemove_, !showCancel); | 416 showInline(this.controlRemove_, !showCancel); |
409 | 417 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 return localStrings.getString('status_cancelled'); | 458 return localStrings.getString('status_cancelled'); |
451 case Download.States.PAUSED: | 459 case Download.States.PAUSED: |
452 return localStrings.getString('status_paused'); | 460 return localStrings.getString('status_paused'); |
453 case Download.States.DANGEROUS: | 461 case Download.States.DANGEROUS: |
454 var desc = this.dangerType_ == Download.DangerType.DANGEROUS_FILE ? | 462 var desc = this.dangerType_ == Download.DangerType.DANGEROUS_FILE ? |
455 'danger_file_desc' : 'danger_url_desc'; | 463 'danger_file_desc' : 'danger_url_desc'; |
456 return localStrings.getString(desc); | 464 return localStrings.getString(desc); |
457 case Download.States.INTERRUPTED: | 465 case Download.States.INTERRUPTED: |
458 return localStrings.getString('status_interrupted'); | 466 return localStrings.getString('status_interrupted'); |
459 case Download.States.COMPLETE: | 467 case Download.States.COMPLETE: |
460 return ''; | 468 return this.fileExternallyRemoved_ ? |
| 469 localStrings.getString('status_removed') : ''; |
461 } | 470 } |
462 } | 471 } |
463 | 472 |
464 /** | 473 /** |
465 * Tells the backend to initiate a drag, allowing users to drag | 474 * Tells the backend to initiate a drag, allowing users to drag |
466 * files from the download page and have them appear as native file | 475 * files from the download page and have them appear as native file |
467 * drags. | 476 * drags. |
468 */ | 477 */ |
469 Download.prototype.drag_ = function() { | 478 Download.prototype.drag_ = function() { |
470 chrome.send('drag', [this.id_.toString()]); | 479 chrome.send('drag', [this.id_.toString()]); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 */ | 534 */ |
526 Download.prototype.cancel_ = function() { | 535 Download.prototype.cancel_ = function() { |
527 chrome.send('cancel', [this.id_.toString()]); | 536 chrome.send('cancel', [this.id_.toString()]); |
528 return false; | 537 return false; |
529 } | 538 } |
530 | 539 |
531 /////////////////////////////////////////////////////////////////////////////// | 540 /////////////////////////////////////////////////////////////////////////////// |
532 // Page: | 541 // Page: |
533 var downloads, localStrings, resultsTimeout; | 542 var downloads, localStrings, resultsTimeout; |
534 | 543 |
| 544 /** |
| 545 * The FIFO array that stores updates of download files to be appeared |
| 546 * on the download page. It is guaranteed that the updates in this array |
| 547 * are reflected to the download page in a FIFO order. |
| 548 */ |
| 549 var fifo_results; |
| 550 |
535 function load() { | 551 function load() { |
| 552 fifo_results = new Array(); |
536 localStrings = new LocalStrings(); | 553 localStrings = new LocalStrings(); |
537 downloads = new Downloads(); | 554 downloads = new Downloads(); |
538 $('term').focus(); | 555 $('term').focus(); |
539 setSearch(''); | 556 setSearch(''); |
540 } | 557 } |
541 | 558 |
542 function setSearch(searchText) { | 559 function setSearch(searchText) { |
| 560 fifo_results.length = 0; |
543 downloads.clear(); | 561 downloads.clear(); |
544 downloads.setSearchText(searchText); | 562 downloads.setSearchText(searchText); |
545 chrome.send('getDownloads', [searchText.toString()]); | 563 chrome.send('getDownloads', [searchText.toString()]); |
546 } | 564 } |
547 | 565 |
548 function clearAll() { | 566 function clearAll() { |
| 567 fifo_results.length = 0; |
549 downloads.clear(); | 568 downloads.clear(); |
550 downloads.setSearchText(''); | 569 downloads.setSearchText(''); |
551 chrome.send('clearAll', []); | 570 chrome.send('clearAll', []); |
552 return false; | 571 return false; |
553 } | 572 } |
554 | 573 |
555 /////////////////////////////////////////////////////////////////////////////// | 574 /////////////////////////////////////////////////////////////////////////////// |
556 // Chrome callbacks: | 575 // Chrome callbacks: |
557 /** | 576 /** |
558 * Our history system calls this function with results from searches or when | 577 * Our history system calls this function with results from searches or when |
559 * downloads are added or removed. | 578 * downloads are added or removed. |
560 */ | 579 */ |
561 function downloadsList(results) { | 580 function downloadsList(results) { |
562 if (resultsTimeout) | 581 if (resultsTimeout) |
563 clearTimeout(resultsTimeout); | 582 clearTimeout(resultsTimeout); |
564 window.console.log('results'); | 583 window.console.log('results'); |
| 584 fifo_results.length = 0; |
565 downloads.clear(); | 585 downloads.clear(); |
566 downloadUpdated(results); | 586 downloadUpdated(results); |
567 downloads.updateSummary(); | 587 downloads.updateSummary(); |
568 } | 588 } |
569 | 589 |
570 /** | 590 /** |
571 * When a download is updated (progress, state change), this is called. | 591 * When a download is updated (progress, state change), this is called. |
572 */ | 592 */ |
573 function downloadUpdated(results) { | 593 function downloadUpdated(results) { |
574 // Sometimes this can get called too early. | 594 // Sometimes this can get called too early. |
575 if (!downloads) | 595 if (!downloads) |
576 return; | 596 return; |
577 | 597 |
| 598 fifo_results = fifo_results.concat(results); |
| 599 tryDownloadUpdatedPeriodically(); |
| 600 } |
| 601 |
| 602 /** |
| 603 * Try to reflect as much updates as possible within 50ms. |
| 604 * This function is scheduled again and again until all updates are reflected. |
| 605 */ |
| 606 function tryDownloadUpdatedPeriodically() { |
578 var start = Date.now(); | 607 var start = Date.now(); |
579 for (var i = 0; i < results.length; i++) { | 608 while (fifo_results.length) { |
580 downloads.updated(results[i]); | 609 var result = fifo_results.shift(); |
| 610 downloads.updated(result); |
581 // Do as much as we can in 50ms. | 611 // Do as much as we can in 50ms. |
582 if (Date.now() - start > 50) { | 612 if (Date.now() - start > 50) { |
583 clearTimeout(resultsTimeout); | 613 clearTimeout(resultsTimeout); |
584 resultsTimeout = setTimeout(downloadUpdated, 5, results.slice(i + 1)); | 614 resultsTimeout = setTimeout(tryDownloadUpdatedPeriodically, 5); |
585 break; | 615 break; |
586 } | 616 } |
587 } | 617 } |
588 } | 618 } |
589 | 619 |
590 // Add handlers to HTML elements. | 620 // Add handlers to HTML elements. |
591 document.body.onload = load; | 621 document.body.onload = load; |
592 $('clear-all').onclick = function () { clearAll(''); }; | 622 $('clear-all').onclick = function () { clearAll(''); }; |
593 $('search-link').onclick = function () { | 623 $('search-link').onclick = function () { |
594 setSearch(''); | 624 setSearch(''); |
595 return false; | 625 return false; |
596 }; | 626 }; |
597 $('search-form').onsubmit = function () { | 627 $('search-form').onsubmit = function () { |
598 setSearch(this.term.value); | 628 setSearch(this.term.value); |
599 return false; | 629 return false; |
600 }; | 630 }; |
601 | 631 |
OLD | NEW |