summaryrefslogtreecommitdiffstats
path: root/chromium/chrome/browser/resources/file_manager/foreground
diff options
context:
space:
mode:
authorJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-08 14:30:41 +0200
committerJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-12 13:49:54 +0200
commitab0a50979b9eb4dfa3320eff7e187e41efedf7a9 (patch)
tree498dfb8a97ff3361a9f7486863a52bb4e26bb898 /chromium/chrome/browser/resources/file_manager/foreground
parent4ce69f7403811819800e7c5ae1318b2647e778d1 (diff)
Update Chromium to beta version 37.0.2062.68
Change-Id: I188e3b5aff1bec75566014291b654eb19f5bc8ca Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/chrome/browser/resources/file_manager/foreground')
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/css/action_choice.css172
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/css/audio_player.css404
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/css/combobutton.css34
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/css/common.css501
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/css/drive_welcome.css188
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/css/file_manager.css2075
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/css/file_types.css477
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/css/gallery.css1374
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/css/list.css73
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/css/media_controls.css605
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/css/menu.css38
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/css/table.css64
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/css/tree.css83
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/css/video_player.css103
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/bubble_point_white.pngbin192 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/check_no_box.pngbin313 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/checkbox_white_checked.pngbin404 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/checkbox_white_unchecked.pngbin166 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/close_x_gray.pngbin217 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/disclosure_arrow_dk_grey.pngbin104 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/common/bubble_point_white.pngbin138 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/common/check_no_box.pngbin191 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/common/checkbox_white_checked.pngbin195 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/common/checkbox_white_unchecked.pngbin95 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/common/close_x_gray.pngbin169 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/common/disclosure_arrow_dk_grey.pngbin91 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/common/spinner.svg13
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/black_folder.pngbin138 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/breadcrumb-separator.pngbin197 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/button_list_view.pngbin99 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/button_list_view_white.pngbin94 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/button_mosaic_view.pngbin99 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/button_mosaic_view_white.pngbin97 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/close_bar.pngbin197 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/drive_logo.pngbin11287 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/eject.pngbin155 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/hashed_bg.gifbin47 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/icon_search.pngbin442 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/offline.pngbin475 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/onbutton_trash.pngbin191 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_closed.pngbin121 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_closed_hover.pngbin121 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_closed_pressed.pngbin121 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_opened.pngbin121 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_opened_hover.pngbin122 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_opened_pressed.pngbin122 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/search_clear.pngbin271 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/search_clear_hover.pngbin272 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/search_clear_pressed.pngbin272 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/search_icon_active.pngbin540 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/search_icon_inactive.pngbin506 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/select_checkbox.pngbin138 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/select_checkbox_checked.pngbin261 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/sort_asc.pngbin103 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/sort_desc.pngbin106 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/vertical_separator.pngbin77 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/warning_icon_square.pngbin1878 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/white_folder.pngbin132 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/black_folder.pngbin103 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/breadcrumb-separator.pngbin134 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/button_list_view.pngbin95 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/button_list_view_white.pngbin83 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/button_mosaic_view.pngbin92 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/button_mosaic_view_white.pngbin88 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/close_bar.pngbin136 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/drive_logo.pngbin5711 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/eject.pngbin129 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/hashed_bg.gifbin1100 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/offline.pngbin255 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/onbutton_trash.pngbin195 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_closed.pngbin102 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_closed_hover.pngbin102 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_closed_pressed.pngbin102 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_opened.pngbin104 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_opened_hover.pngbin104 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_opened_pressed.pngbin104 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/search_clear.pngbin161 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/search_clear_hover.pngbin161 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/search_clear_pressed.pngbin160 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/search_icon_active.pngbin295 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/search_icon_inactive.pngbin278 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/select_checkbox.pngbin109 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/select_checkbox_checked.pngbin174 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/sort_asc.pngbin93 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/sort_desc.pngbin92 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/vertical_separator.pngbin70 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/view_thumbs_black.pngbin91 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/warning_icon_square.pngbin849 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/white_folder.pngbin100 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/arrow_left.pngbin3180 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/arrow_right.pngbin3166 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/back_to_files.pngbin1943 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/bubble_point.pngbin135 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/butterbar_close_button.pngbin146 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_crop.pngbin831 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_leftright.pngbin801 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_move.pngbin1217 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_nwse.pngbin914 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_swne.pngbin903 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_updown.pngbin786 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_1up.pngbin253 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_1up_selected.pngbin249 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_autofix.pngbin563 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_autofix_selected.pngbin579 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_brightness.pngbin412 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_brightness_selected.pngbin398 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_contrast.pngbin524 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_crop.pngbin122 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_crop_selected.pngbin125 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_delete.pngbin142 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_delete_selected.pngbin148 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_edit.pngbin230 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_edit_selected.pngbin238 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_mosaic.pngbin166 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_mosaic_selected.pngbin168 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_print.pngbin175 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_print_selected.pngbin184 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_redo.pngbin369 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_redo_selected.pngbin381 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_rotate.pngbin723 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_rotate_left.pngbin721 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_rotate_left_selected.pngbin738 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_rotate_selected.pngbin743 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_share.pngbin261 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_share_selected.pngbin267 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_slideshow.pngbin257 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_slideshow_selected.pngbin256 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_undo.pngbin371 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_undo_selected.pngbin388 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/slider_thumb.pngbin392 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/slideshow-end.pngbin3098 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/slideshow-pause.pngbin1099 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/slideshow-play.pngbin1727 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/arrow_left.pngbin1773 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/arrow_right.pngbin1772 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/back_to_files.pngbin688 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/bubble_point.pngbin102 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/butterbar_close_button.pngbin139 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_crop.pngbin410 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_leftright.pngbin373 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_move.pngbin484 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_nwse.pngbin459 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_swne.pngbin454 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_updown.pngbin366 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_1up.pngbin162 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_1up_selected.pngbin162 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_autofix.pngbin292 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_autofix_selected.pngbin292 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_brightness.pngbin266 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_brightness_selected.pngbin257 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_contrast.pngbin305 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_crop.pngbin102 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_crop_selected.pngbin108 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_delete.pngbin112 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_delete_selected.pngbin119 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_edit.pngbin161 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_edit_selected.pngbin164 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_mosaic.pngbin124 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_mosaic_selected.pngbin126 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_print.pngbin144 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_print_selected.pngbin148 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_redo.pngbin243 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_redo_selected.pngbin245 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_rotate.pngbin367 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_rotate_left.pngbin368 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_rotate_left_selected.pngbin382 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_rotate_selected.pngbin382 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_share.pngbin165 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_share_selected.pngbin170 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_slideshow.pngbin173 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_slideshow_selected.pngbin172 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_undo.pngbin240 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_undo_selected.pngbin243 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/slider_thumb.pngbin221 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/slideshow-end.pngbin1717 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/slideshow-pause.pngbin648 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/gallery/slideshow-play.pngbin1080 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/audio_player.pngbin6721 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/drive.pngbin2756 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/error.pngbin2694 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_close.pngbin151 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_collapse.pngbin115 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_expand.pngbin117 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_fullscreen.pngbin579 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_fullscreen_disabled.pngbin387 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_fullscreen_down.pngbin1790 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_fullscreen_hover.pngbin1726 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_loop.pngbin516 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_loop_down.pngbin2321 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_loop_hover.pngbin2259 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_next.pngbin409 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_next_down.pngbin1905 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_next_hover.pngbin1880 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause.pngbin387 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause_audio.pngbin148 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause_audio_down.pngbin1087 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause_audio_hover.pngbin1019 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause_down.pngbin1580 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause_hover.pngbin1518 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play.pngbin471 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_audio.pngbin364 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_audio_down.pngbin1655 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_audio_hover.pngbin1642 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_disabled.pngbin480 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_down.pngbin2071 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_hover.pngbin2027 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_previous.pngbin427 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_previous_down.pngbin1917 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_previous_hover.pngbin1864 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_slider_thumb.pngbin1544 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_slider_thumb_down.pngbin2011 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_slider_thumb_hover.pngbin1959 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_disabled.pngbin520 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_disabled_down.pngbin2385 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_disabled_hover.pngbin2357 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_full.pngbin743 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_full_disabled.pngbin739 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_full_down.pngbin2802 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_full_hover.pngbin2779 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level1.pngbin453 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level1_down.pngbin1932 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level1_hover.pngbin1885 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level2.pngbin575 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level2_down.pngbin2314 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level2_hover.pngbin2280 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_volume_slider_thumb.pngbin1394 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_volume_slider_thumb_down.pngbin1795 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_volume_slider_thumb_hover.pngbin1782 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/watch.pngbin370 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/audio_player.pngbin3172 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/drive.pngbin1197 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/error.pngbin1026 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_close.pngbin112 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_collapse.pngbin95 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_expand.pngbin97 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_fullscreen.pngbin237 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_fullscreen_disabled.pngbin244 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_fullscreen_down.pngbin890 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_fullscreen_hover.pngbin873 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_loop.pngbin309 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_loop_down.pngbin1147 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_loop_hover.pngbin1178 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_next.pngbin226 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_next_down.pngbin874 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_next_hover.pngbin866 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause.pngbin199 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause_audio.pngbin132 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause_audio_down.pngbin567 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause_audio_hover.pngbin555 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause_down.pngbin743 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause_hover.pngbin742 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play.pngbin269 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_audio.pngbin203 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_audio_down.pngbin756 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_audio_hover.pngbin771 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_disabled.pngbin276 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_down.pngbin940 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_hover.pngbin952 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_previous.pngbin229 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_previous_down.pngbin883 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_previous_hover.pngbin880 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_slider_thumb.pngbin678 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_slider_thumb_down.pngbin861 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_slider_thumb_hover.pngbin842 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_disabled.pngbin285 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_disabled_down.pngbin1074 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_disabled_hover.pngbin1104 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_full.pngbin380 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_full_disabled.pngbin372 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_full_down.pngbin1278 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_full_hover.pngbin1273 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level1.pngbin257 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level1_down.pngbin955 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level1_hover.pngbin953 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level2.pngbin313 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level2_down.pngbin1105 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level2_hover.pngbin1113 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_volume_slider_thumb.pngbin627 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_volume_slider_thumb_down.pngbin815 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/media_volume_slider_thumb_hover.pngbin806 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/media/watch.pngbin266 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/archive.pngbin156 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_archive.pngbin156 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_downloads.pngbin200 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_drive.pngbin332 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_hdd.pngbin203 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_offline.pngbin474 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_optical.pngbin539 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_phone.pngbin141 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_recent.pngbin499 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_sd.pngbin154 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_shared.pngbin535 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_trash.pngbin111 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_usb.pngbin169 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_hd.pngbin203 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_optical.pngbin539 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_sd.pngbin154 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_sd_large.pngbin2304 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_usb.pngbin169 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_usb_large.pngbin4103 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/downloads.pngbin200 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/drive.pngbin332 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/drive_offline.pngbin474 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/drive_recent.pngbin499 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/drive_shared.pngbin537 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/folder.pngbin138 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_archive.pngbin151 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_downloads.pngbin193 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_drive.pngbin329 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_hdd.pngbin174 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_offline.pngbin457 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_optical.pngbin562 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_phone.pngbin139 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_recent.pngbin478 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_sd.pngbin146 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_shared.pngbin498 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_trash.pngbin103 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_usb.pngbin137 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_archive.pngbin108 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_downloads.pngbin117 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_drive.pngbin182 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_folder.pngbin103 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_hdd.pngbin116 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_offline.pngbin258 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_optical.pngbin281 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_phone.pngbin112 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_recent.pngbin287 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_sd.pngbin110 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_shared.pngbin289 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_trash.pngbin102 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_usb.pngbin120 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/device_sd_large.pngbin1117 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/device_usb_large.pngbin1642 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_archive.pngbin106 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_downloads.pngbin116 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_drive.pngbin179 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_folder.pngbin100 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_hdd.pngbin108 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_offline.pngbin248 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_optical.pngbin263 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_phone.pngbin114 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_recent.pngbin268 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_sd.pngbin110 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_shared.pngbin262 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_trash.pngbin101 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_usb.pngbin112 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/app_installer.js79
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/combobutton.js154
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/commandbutton.js136
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/cws_container_client.js249
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/default_action_dialog.js157
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/directory_contents.js770
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/directory_model.js1186
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/directory_tree.js676
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/drag_selector.js244
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/drive_banners.js660
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/error_counter.js16
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/error_dialog.js29
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/file_grid.js302
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/file_manager.js3688
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/file_manager_commands.js828
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/file_operation_manager_wrapper.js56
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/file_selection.js360
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/file_table.js1036
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/file_tasks.js834
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/file_transfer_controller.js860
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/file_type.js294
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/file_watcher.js227
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/folder_shortcuts_data_model.js293
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/commands.js455
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/exif_encoder.js569
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/filter.js612
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_adjust.js248
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_buffer.js184
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_editor.js1177
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_encoder.js228
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_transform.js493
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_util.js701
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_view.js1065
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/viewport.js430
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/main.js41
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/main_scripts.js132
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/media/audio_player.js628
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/media/media_controls.js1245
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/media/media_util.js421
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/media/mediaplayer_scripts.js33
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/media/player_testapi.js193
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/media/util.js179
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/media/video_player.js289
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/media/video_player_scripts.js34
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/metadata/byte_reader.js535
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/metadata/exif_parser.js439
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/metadata/function_parallel.js82
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/metadata/function_sequence.js133
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/metadata/id3_parser.js708
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/metadata/image_parsers.js198
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/metadata/metadata_cache.js1042
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/metadata/metadata_dispatcher.js226
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/metadata/metadata_parser.js62
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/metadata/mpeg_parser.js317
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/metrics.js131
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/navigation_list_model.js350
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/photo/gallery.js867
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/photo/gallery_item.js227
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/photo/gallery_scripts.js70
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/photo/mosaic_mode.js2012
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/photo/ribbon.js366
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/photo/slide_mode.js1354
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/scrollbar.js294
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/share_client.js188
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/share_dialog.js314
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/suggest_apps_dialog.js554
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/text_measure.js50
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/tree.css.js59
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/ui/breadcrumbs_controller.js262
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/ui/conflict_dialog.js132
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/ui/file_manager_dialog_base.js122
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/ui/file_manager_ui.js190
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/ui/navigation_list.js386
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/ui/preview_panel.js518
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/ui/progress_center_panel.js329
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/ui/search_box.js202
-rw-r--r--chromium/chrome/browser/resources/file_manager/foreground/js/volume_manager_wrapper.js334
423 files changed, 0 insertions, 41748 deletions
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/css/action_choice.css b/chromium/chrome/browser/resources/file_manager/foreground/css/action_choice.css
deleted file mode 100644
index 508809c520d..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/css/action_choice.css
+++ /dev/null
@@ -1,172 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-input:focus,
-button:focus {
- outline-color: rgb(77, 144, 254);
-}
-
-.action-choice {
- -webkit-box-align: center;
- -webkit-box-pack: center;
- -webkit-user-select: none;
- background: white;
- bottom: 0;
- color: black;
- display: -webkit-box;
- font-family: Open Sans, Droid Sans Fallback, sans-serif;
- font-size: 84%;
- left: 0;
- margin: 0;
- overflow: hidden;
- padding: 10px;
- position: absolute;
- right: 0;
- top: 0;
-}
-
-.action-choice[loading] .content,
-.action-choice:not([loading]) .loading {
- display: none;
-}
-
-.action-choice h1 {
- font-size: 14px;
- font-weight: normal;
- line-height: 1.5;
- margin: 5px 3px;
-}
-
-/* The loading preview */
-
-.loading {
- -webkit-box-align: center;
- -webkit-box-orient: vertical;
- color: #333;
- display: -webkit-box;
- font-size: 12px;
-}
-
-.spinner {
- background-image: url('../images/common/spinner.svg');
- background-size: 100%;
- height: 21px;
- left: 44px;
- margin-left: -10px;
- margin-top: -10px;
- opacity: 0.5;
- position: absolute;
- top: 29px;
- width: 21px;
-}
-
-.device-type {
- height: 64px;
- position: relative;
- width: 116px;
-}
-
-.device-type[device-type=usb] {
- background-image: -webkit-image-set(
- url('../images/volumes/device_usb_large.png') 1x,
- url('../images/volumes/2x/device_usb_large.png') 2x);
-}
-
-.device-type[device-type=sd] {
- -webkit-transform: rotate(-90deg);
- background-image: -webkit-image-set(
- url('../images/volumes/device_sd_large.png') 1x,
- url('../images/volumes/2x/device_sd_large.png') 2x);
- bottom: 10px; /* Adjust the rotated image to not overlap with element below */
-}
-
-/* The action choice content */
-
-.content {
- -webkit-box-align: start;
- -webkit-box-orient: vertical;
- display: -webkit-box;
- height: 100%;
- overflow: hidden;
- position: relative;
- width: 100%;
-}
-
-.previews {
- -webkit-box-orient: horizontal;
- -webkit-mask-image: linear-gradient(to left, rgba(0, 0, 0, 0) 0,
- rgba(0, 0, 0, 1) 80px);
- display: -webkit-box;
- position: relative;
- width: 100%;
-}
-
-.img-container {
- height: 120px;
- margin: 0 2px;
- overflow: hidden;
- position: relative;
- width: 120px;
-}
-
-.img-container > img {
- -webkit-user-drag: none;
- position: absolute;
-}
-
-.counter {
- color: #808080;
- margin: 5px 3px;
- width: 100%;
-}
-
-.choices {
- width: 100%;
-}
-
-/* Padding counterweights negative margins of items, thus eliminating scroll
- bar when it's not needed. Max height is set to fit 8 items before showing
- scroll bar. */
-#actions-list {
- display: block;
- max-height: 328px;
- outline: none;
- overflow: auto;
- padding: 1px 0;
- position: relative;
-}
-
-#actions-list > li {
- cursor: default;
- list-style-type: none;
-}
-
-#actions-list > li > div {
- background-position: 5px center;
- background-repeat: no-repeat;
- line-height: 39px;
- padding-left: 43px;
-}
-
-#actions-list > [selected] {
- background-color: #dedede;
-}
-
-#actions-list:focus > [selected] {
- background-color: rgb(203, 219, 241);
-}
-
-#actions-list > [selected]:hover {
- background-color: rgb(193, 211, 236);
- border-color: hsl(214, 91%, 85%);
-}
-
-#actions-list > :hover {
- background-color: #f1f1f1;
- border-color: hsl(214, 91%, 85%);
-}
-
-#actions-list > li > div.disabled {
- opacity: 0.5;
-}
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/css/audio_player.css b/chromium/chrome/browser/resources/file_manager/foreground/css/audio_player.css
deleted file mode 100644
index 1f6b7bbfb91..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/css/audio_player.css
+++ /dev/null
@@ -1,404 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-body {
- -webkit-user-select: none;
- overflow: hidden;
- padding: 0;
-}
-
-.audio-player {
- background-color: #1d1d1d;
- bottom: 0;
- color: white;
- cursor: default;
- font-family: Open Sans, Droid Sans Fallback, sans-serif;
- font-size: 10pt;
- left: 0;
- position: absolute;
- right: 0;
- top: 0;
-}
-
-/* Title buttons.
- * In the collapsed/single-track mode they overlap the first track. */
-
-.title-button {
- background-position: center center;
- background-repeat: no-repeat;
- cursor: pointer;
- height: 29px;
- opacity: 0.4;
- position: absolute;
- top: 0;
- width: 29px;
- z-index: 2;
-}
-
-.title-button:hover {
- background-color: rgb(60, 126, 255) !important;
- opacity: 1;
-}
-
-.audio-player:not(.collapsed):not(.single-track) > .title-button {
- background-color: #1f1f1f;
-}
-
-.title-button.close {
- background-image: -webkit-image-set(
- url('../images/media/media_close.png') 1x,
- url('../images/media/2x/media_close.png') 2x);
- right: 0;
-}
-
-.title-button.collapse {
- background-image: -webkit-image-set(
- url('../images/media/media_collapse.png') 1x,
- url('../images/media/2x/media_collapse.png') 2x);
- right: 0;
-}
-
-.audio-player:not(.frameless) .title-button.close {
- display: none;
-}
-
-.audio-player.frameless .title-button.collapse {
- right: 29px;
-}
-
-.collapsed .title-button.collapse {
- background-image: -webkit-image-set(
- url('../images/media/media_expand.png') 1x,
- url('../images/media/2x/media_expand.png') 2x);
-}
-
-.single-track .title-button.collapse {
- display: none;
-}
-
-/* Common properties for track containers. */
-.audio-player > .track-list,
-.audio-player > .track-stack {
- bottom: 35px; /* Room for the controls bar. */
- left: 0;
- position: absolute;
- right: 0;
-}
-
-/* Scrollable list of tracks.
- * Displayed in expanded mode if there is more than one track. */
-.audio-player > .track-list {
- -webkit-box-align: center;
- -webkit-box-orient: vertical;
- -webkit-box-pack: start;
- display: -webkit-box;
- overflow-x: hidden;
- overflow-y: auto;
- top: 0;
-}
-
-/* A single track container.
- * Displayed in the compact mode or when there is only one track. */
-.audio-player > .track-stack {
- height: 58px;
-}
-
-.audio-player.collapsed > .track-list,
-.audio-player.single_track > .track-list,
-.audio-player:not(.collapsed):not(.single-track) > .track-stack {
- opacity: 0;
- pointer-events: none;
-}
-
-/* Track item. */
-.track {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: start;
- display: -webkit-box;
- height: 58px;
- width: 100%;
-}
-
-/* In the expanded mode the selected track is highlighted. */
-.track-list .track.selected {
- background-color: #2d2d2d;
-}
-
-.track-list .track:hover {
- background-color: #272727 !important;
-}
-
-.track-list .track:not(.selected) .data {
- opacity: 0.7;
-}
-
-/* In the compact mode all tracks are in the same position, only the selected
- is visible.*/
-.track-stack > .track {
- position: absolute;
- top: 0;
-}
-
-.track-stack > .track.selected {
- z-index: 1;
-}
-
-/* Opacity transition is controlled differently for the text and the artwork.
- * Text transition looks better if fade-in and fade-out go in parallel.
- * For the artwork we start fading out the old icon only after the new one
- * is completely opaque (otherwise when transitioning between identical icons
- * we see some fading because the background transpires). */
-.track-stack > .track:not(.selected) .data,
-.track-stack > .track:not(.visible) .art {
- opacity: 0;
- transition: opacity 220ms ease-out;
-}
-
-/* Track data. */
-
-.track .art {
- box-sizing: border-box;
- height: 48px;
- margin: 4px 0 6px 4px;
- position: relative;
- width: 48px;
-}
-
-.track .art.blank {
- background-color: #111;
- border: 1px solid #333;
-}
-
-.track .art img {
- height: 100%;
- width: 100%;
-}
-
-.track .art.blank img {
- display: none;
-}
-
-.track .art.error {
- background-image: -webkit-image-set(
- url('../images/media/error.png') 1x,
- url('../images/media/2x/error.png') 2x);
- background-position: center center;
- background-repeat: no-repeat;
-}
-
-.noart .track .art {
- display: none;
-}
-
-.track .data {
- -webkit-box-flex: 1;
- -webkit-box-orient: vertical;
- -webkit-box-pack: center;
- display: -webkit-box;
- margin-left: 8px;
- margin-right: 4px;
-}
-
-.track .data .data-title,
-.track .data .data-artist {
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.track .data .data-title {
- font-weight: bold;
-}
-
-/* TODO(kaznacheev): Set to 20px when the audio player is title-less. */
-.single-track .data-title {
- padding-right: 0;
-}
-
-/* TODO(kaznacheev): Set to 50px when the audio player is title-less. */
-.collapsed:not(.single-track) .data-title {
- padding-right: 20px;
-}
-
-/* Controls bar. */
-
-.audio-controls {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: center;
- background-color: #2D2D2D;
- border-top: 1px solid rgba(255, 255, 255, 0.1);
- bottom: 0;
- display: -webkit-box;
- height: 30px;
- left: 0;
- padding: 0 0 4px 13px;
- position: absolute;
- right: 0;
-}
-
-.audio-controls .media-button {
- height: 29px;
- margin-top: 1px;
- width: 29px;
-}
-
-.audio-controls .media-button.play {
- margin-left: -10px;
- margin-right: -8px;
-}
-
-.audio-controls .media-button.play > .default.normal,
-.audio-controls .media-button.play > .ended.normal {
- background-image: -webkit-image-set(
- url('../images/media/media_play_audio.png') 1x,
- url('../images/media/2x/media_play_audio.png') 2x);
-}
-
-.audio-controls .media-button.play > .default.hover,
-.audio-controls .media-button.play > .ended.hover {
- background-image: -webkit-image-set(
- url('../images/media/media_play_audio_hover.png') 1x,
- url('../images/media/2x/media_play_audio_hover.png') 2x);
-}
-
-.audio-controls .media-button.play > .default.active,
-.audio-controls .media-button.play > .ended.active {
- background-image: -webkit-image-set(
- url('../images/media/media_play_audio_down.png') 1x,
- url('../images/media/2x/media_play_audio_down.png') 2x);
-}
-
-.audio-controls .media-button.play > .playing.normal {
- background-image: -webkit-image-set(
- url('../images/media/media_pause_audio.png') 1x,
- url('../images/media/2x/media_pause_audio.png') 2x);
-}
-
-.audio-controls .media-button.play > .playing.hover {
- background-image: -webkit-image-set(
- url('../images/media/media_pause_audio_hover.png') 1x,
- url('../images/media/2x/media_pause_audio_hover.png') 2x);
-}
-
-.audio-controls .media-button.play > .playing.active {
- background-image: -webkit-image-set(
- url('../images/media/media_pause_audio_down.png') 1x,
- url('../images/media/2x/media_pause_audio_down.png') 2x);
-}
-
-.audio-controls .time-controls {
- margin-left: 10px;
- margin-right: 9px;
-}
-
-.audio-controls .time-controls .time {
- margin-left: 11px;
-}
-
-.media-button.previous {
- margin-left: -2px;
-}
-
-.media-button.previous > .normal {
- background-image: -webkit-image-set(
- url('../images/media/media_previous.png') 1x,
- url('../images/media/2x/media_previous.png') 2x);
-}
-
-.media-button.previous > .hover {
- background-image: -webkit-image-set(
- url('../images/media/media_previous_hover.png') 1x,
- url('../images/media/2x/media_previous_hover.png') 2x);
-}
-
-.media-button.previous > .active {
- background-image: -webkit-image-set(
- url('../images/media/media_previous_down.png') 1x,
- url('../images/media/2x/media_previous_down.png') 2x);
-}
-
-.media-button.next {
- margin-right: -2px;
-}
-
-.media-button.next > .normal {
- background-image: -webkit-image-set(
- url('../images/media/media_next.png') 1x,
- url('../images/media/2x/media_next.png') 2x);
-}
-
-.media-button.next > .hover {
- background-image: -webkit-image-set(
- url('../images/media/media_next_hover.png') 1x,
- url('../images/media/2x/media_next_hover.png') 2x);
-}
-
-.media-button.next > .active {
- background-image: -webkit-image-set(
- url('../images/media/media_next_down.png') 1x,
- url('../images/media/2x/media_next_down.png') 2x);
-}
-
-.single-track .media-button.next,
-.single-track .media-button.previous {
- display: none;
-}
-
-/* Customized scrollbar for the playlist. */
-
-::-webkit-scrollbar {
- height: 16px;
- width: 16px;
-}
-
-::-webkit-scrollbar-button {
- height: 0;
- width: 0;
-}
-
-::-webkit-scrollbar-thumb {
- background-clip: padding-box;
- background-color: rgba(255, 255, 255, 0.15);
- box-shadow: inset 1px 1px 0 rgba(0, 0, 0, 0.10),
- inset 0 -1px 0 rgba(0, 0, 0, 0.07);
- min-height: 28px;
- padding-top: 100px;
-}
-
-::-webkit-scrollbar-thumb:hover {
- background-color: rgba(255,255,255,0.20);
- box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25);
-}
-
-::-webkit-scrollbar-thumb:active {
- background-color: rgba(255, 255, 255, 0.25);
- box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.35);
-}
-
-::-webkit-scrollbar-thumb:vertical {
- border-bottom: 0 solid transparent;
- border-left: 5px solid transparent;
- border-right: 0 solid transparent;
- border-top: 0 solid transparent;
-}
-
-::-webkit-scrollbar-track:hover {
- background-color: rgba(0, 0, 0, 0.05);
- box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.10);
-}
-
-::-webkit-scrollbar-track:active {
- background-color: rgba(0, 0, 0, 0.05);
- box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.14),
- inset -1px -1px 0 rgba(0, 0, 0, 0.07);
-}
-
-::-webkit-scrollbar-track:vertical {
- background-clip: padding-box;
- background-color: transparent;
- border-left: 5px solid transparent;
- border-right: 0 solid transparent;
-}
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/css/combobutton.css b/chromium/chrome/browser/resources/file_manager/foreground/css/combobutton.css
deleted file mode 100644
index 2651aad6bbb..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/css/combobutton.css
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-.buttonbar button.combobutton {
- -webkit-box-align: stretch;
- display: -webkit-box;
-}
-
-.buttonbar .combobutton > .action {
- background-position: left center;
- background-repeat: no-repeat;
- background-size: 16px 16px;
- padding-left: 21px;
-}
-
-.buttonbar .combobutton > .trigger {
- border-left: solid 1px #dcdcdc;
- margin-left: 8px;
- margin-right: -8px;
- width: 22px;
-}
-
-.buttonbar .combobutton:not([multiple]) > .trigger {
- display: none;
-}
-
-.buttonbar .combobutton > div > span.disclosureindicator {
- -webkit-transform: rotate(90deg);
-}
-
-.buttonbar .combobutton[hidden] {
- display: none;
-}
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/css/common.css b/chromium/chrome/browser/resources/file_manager/foreground/css/common.css
deleted file mode 100644
index e9051864258..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/css/common.css
+++ /dev/null
@@ -1,501 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-/* Special attribute to hide elements. */
-[hidden] {
- display: none !important;
-}
-
-/* This file contains "borrowed" copy of standard styles. To simplify merging,
- * when altering, please preserve original property value by adding comments. */
-input.common[type='checkbox'],
-input.common[type='radio'] {
- -webkit-appearance: none;
- border: 1px solid #555;
- border-radius: 1px;
- box-sizing: border-box;
- cursor: default;
- height: 13px;
- margin: 0;
- opacity: 0.4;
- width: 13px;
-}
-
-input.common[type='checkbox']:hover,
-input.common[type='checkbox']:checked,
-input.common[type='radio']:hover,
-input.common[type='radio']:checked {
- opacity: 1;
-}
-
-input.common[type='checkbox'] {
- position: relative;
-}
-
-input.common[type='checkbox']:checked::after {
- background-image: -webkit-image-set(
- url('../images/common/check_no_box.png') 1x,
- url('../images/common/2x/check_no_box.png') 2x);
- background-position: -3px -4px;
- background-repeat: no-repeat;
-}
-
-input.common[type='checkbox'].white {
- border: none;
-}
-
-input.common[type='checkbox'].white:not(:checked)::after {
- background-image: -webkit-image-set(
- url('../images/common/checkbox_white_unchecked.png') 1x,
- url('../images/common/2x/checkbox_white_unchecked.png') 2x);
- background-position: -1px 0;
-}
-
-input.common[type='checkbox'].white:checked::after {
- background-image: -webkit-image-set(
- url('../images/common/checkbox_white_checked.png') 1x,
- url('../images/common/2x/checkbox_white_checked.png') 2x);
- background-position: -1px 0;
-}
-
-input.common[type='checkbox']::after {
- content: '';
- display: -webkit-box;
- height: 15px;
- left: -2px;
- position: absolute;
- top: -2px;
- width: 17px;
-}
-
-.bubble {
- background: #FFF;
- border-radius: 2px;
- cursor: default;
- outline: 1px solid rgba(0, 0, 0, 0.2);
- padding: 16px;
-}
-
-.bubble .pointer {
- background: -webkit-image-set(
- url('../images/common/bubble_point_white.png') 1x,
- url('../images/common/2x/bubble_point_white.png') 2x);
- display: block;
- height: 11px;
- left: 24px;
- margin: 0 0 0 -5px;
- outline: none;
- position: absolute;
- width: 17px;
-}
-
-.bubble .pointer:not(.bottom) {
- top: -11px;
-}
-
-.bubble .pointer.bottom {
- -webkit-transform: rotate(180deg);
- bottom: -11px;
-}
-
-.bubble .close-x {
- background: -webkit-image-set(
- url('../images/common/close_x_gray.png') 1x,
- url('../images/common/2x/close_x_gray.png') 2x);
- height: 21px;
- opacity: 0.3;
- position: absolute;
- right: 3px;
- top: 3px;
- width: 21px;
-}
-
-.bubble .close-x:hover {
- opacity: 0.7;
-}
-
-.buttonbar {
- display: -webkit-box;
- height: 31px;
-}
-
-.buttonbar button:active img {
- opacity: 1.0;
-}
-
-.buttonbar button:hover img {
- opacity: 0.72;
-}
-
-.buttonbar button[disabled] img {
- opacity: 0.9;
-}
-
-.buttonbar button img {
- display: inline-block;
- margin: -3px 0 0;
- opacity: 0.55;
- vertical-align: middle;
-}
-
-.buttonbar button.menubutton span.disclosureindicator {
- -webkit-transform: rotate(90deg);
- float: right;
- margin-left: 7px;
- margin-top: 10px;
- opacity: .8;
- transition: none;
-}
-
-span.disclosureindicator {
- background-image: -webkit-image-set(
- url('../images/common/disclosure_arrow_dk_grey.png') 1x,
- url('../images/common/2x/disclosure_arrow_dk_grey.png') 2x);
- background-position: center;
- background-repeat: no-repeat;
- display: inline-block;
- height: 7px;
- width: 5px;
-}
-
-/* "chrome-menu" class overrides some standard menu.css styles, to make custom
- menus in FileBrowser look like native ChromeOS menus. */
-
-menu.chrome-menu {
- background-color: rgb(250, 250, 250);
- border-radius: 3px;
- box-shadow: 0 1px 4px 0 rgba(0, 0, 0, .5);
- color: rgb(34, 34, 34);
- outline: none;
- overflow: hidden;
- padding: 5px 0;
- transition: opacity 200ms ease-in;
- z-index: 600; /* Must be below the overlay pane (1000). */
-}
-
-menu.chrome-menu[hidden] {
- display: block !important; /* Overrides default [hidden] for animation. */
- opacity: 0;
- pointer-events: none;
- visibility: hidden;
-}
-
-menu.chrome-menu.hide-delayed[hidden] {
- transition-delay: 120ms;
- transition-property: opacity, visibility;
-}
-
-menu.chrome-menu > :not(hr) {
- background-position: right 10px center;
- background-repeat: no-repeat;
- line-height: 30px;
- padding-left: 20px;
- padding-right: 20px;
-}
-
-menu.chrome-menu > .menuitem-button {
- background-position: center;
- background-repeat: no-repeat;
- border: 1px solid rgb(235, 235, 235);
- height: 42px;
- margin: -36px -1px -1px 0;
- min-width: 60px;
- padding: 0;
- position: absolute;
- width: 60px;
-}
-
-menu.chrome-menu > .menuitem-button[checked] {
- background-color: rgb(235, 235, 235);
-}
-
-menu.chrome-menu > .menuitem-button.left {
- right: 59px;
-}
-
-menu.chrome-menu > .menuitem-button.right {
- right: 0;
-}
-
-menu.chrome-menu > menuitem[disabled] {
- color: rgb(153, 153, 153);
-}
-
-menu.chrome-menu > menuitem:not([disabled])[selected],
-menu.chrome-menu > menuitem:not([disabled])[selected]:active {
- background-color: rgb(66, 129, 244);
- color: white;
-}
-
-menu.chrome-menu > hr {
- background: rgb(235, 235, 235);
- height: 1px;
- margin: 5px 0;
-}
-
-menu.chrome-menu > menuitem[checked] {
- background-image: -webkit-image-set(
- url('../images/common/check_no_box.png') 1x,
- url('../images/common/2x/check_no_box.png') 2x);
-}
-
-menu.chrome-menu > [checked]::before {
- display: none;
-}
-
-menu[showShortcuts] > menuitem[shortcutText][selected]:not([disabled])::after {
- color: white;
-}
-
-/**
- * Ok/Cancel style buttons
- * Height: 31px (content:21px + border:5px * 2)
- **/
-button,
-input[type='button'],
-input[type='submit'],
-select {
- background-color: rgb(250, 250, 250);
- background-image: none;
- background-position: center;
- background-repeat: no-repeat;
- border: 5px solid transparent;
- border-image: -webkit-image-set(
- url('chrome://resources/images/apps/button.png') 1x,
- url('chrome://resources/images/2x/apps/button.png')
- 2x) 5 / 5px / 2px repeat;
- box-sizing: content-box;
- color: rgb(34, 34, 34);
- cursor: default;
- height: 21px;
- line-height: 21px;
- margin: 0;
- min-height: 21px;
- min-width: 55px;
- padding: 0 10px;
- position: relative;
- text-align: center;
- z-index: 1;
-}
-
-.buttonbar button {
- -webkit-margin-start: 10px;
-}
-
-button:hover,
-input[type='button']:hover,
-input[type='submit']:hover,
-select:hover {
- border-image: -webkit-image-set(
- url('chrome://resources/images/apps/button_hover.png') 1x,
- url('chrome://resources/images/2x/apps/button_hover.png')
- 2x) 5 fill / 5px / 2px repeat;
- color: #222;
-}
-
-button:active,
-input[type='button']:active,
-input[type='submit']:active {
- border-image: -webkit-image-set(
- url('chrome://resources/images/apps/button_pressed.png') 1x,
- url('chrome://resources/images/2x/apps/button_pressed.png')
- 2x) 5 fill / 5px / 2px repeat;
- color: #333;
-}
-
-button[disabled],
-input[type='button'][disabled],
-input[type='submit'][disabled],
-button[disabled]:hover,
-input[type='button'][disabled]:hover,
-input[type='submit'][disabled]:hover {
- background-color: rgb(250, 250, 250);
- background-image: none;
- border-image: -webkit-image-set(
- url('chrome://resources/images/apps/button.png') 1x,
- url('chrome://resources/images/2x/apps/button.png')
- 2x) 5 fill / 5px / 2px repeat;
- color: rgb(150, 150, 150);
-}
-
-/* Gray progress bar. */
-.progress-bar {
- background-color: #e6e6e6;
- border-radius: 3px;
- height: 6px;
-}
-
-.progress-track {
- background-color: #888;
- border-radius: 3px;
- height: 6px;
- min-width: 6px;
-}
-
-.progress-track.smoothed {
- transition: width 1s linear;
-}
-
-/* Icons for the action choice dialog and choosing the default app. */
-div.import-photos-to-drive-icon {
- background-image: -webkit-image-set(
- url('../images/media/drive.png') 1x,
- url('../images/media/2x/drive.png') 2x);
-}
-
-div.view-files-icon {
- background-image: -webkit-image-set(
- url('../../common/images/icon32.png') 1x,
- url('../../common/images/icon64.png') 2x);
-}
-
-div.watch-single-video-icon {
- background-image: -webkit-image-set(
- url('../images/media/watch.png') 1x,
- url('../images/media/2x/watch.png') 2x);
-}
-
-/* Pop-up dialogs. */
-
-.cr-dialog-container {
- -webkit-box-align: center;
- -webkit-box-pack: center;
- -webkit-user-select: none;
- display: -webkit-box;
- height: 100%;
- left: 0;
- overflow: hidden;
- position: absolute;
- top: 0;
- transition: opacity 250ms linear;
- width: 100%;
- z-index: 9999;
-}
-
-.cr-dialog-frame {
- -webkit-box-orient: vertical;
- background-color: rgb(250, 250, 250);
- border: 1px solid rgb(255, 255, 255);
- border-radius: 2px;
- box-shadow: 0 1px 4px 0 rgba(0, 0, 0, .5);
- color: rgb(34, 34, 34);
- cursor: default;
- display: -webkit-box;
- padding: 20px;
- position: relative;
- width: 460px;
-}
-
-.cr-dialog-frame:focus {
- outline: none;
-}
-
-@-webkit-keyframes pulse {
- 0% {
- -webkit-transform: scale(1);
- }
- 40% {
- -webkit-transform: scale(1.02);
- }
- 60% {
- -webkit-transform: scale(1.02);
- }
- 100% {
- -webkit-transform: scale(1);
- }
-}
-
-.cr-dialog-frame.pulse {
- -webkit-animation-duration: 180ms;
- -webkit-animation-iteration-count: 1;
- -webkit-animation-name: pulse;
- -webkit-animation-timing-function: ease-in-out;
-}
-
-.shown > .cr-dialog-frame {
- -webkit-transform: perspective(500px) scale(1)
- translateY(0) rotateX(0);
- opacity: 1;
-}
-
-.cr-dialog-frame {
- -webkit-transform: perspective(500px) scale(0.99)
- translateY(-20px) rotateX(5deg);
- opacity: 0;
- transition: all 180ms;
- transition-duration: 250ms;
-}
-
-.cr-dialog-shield {
- background-color: white;
- bottom: 0;
- display: block;
- left: 0;
- opacity: 0;
- pointer-events: none;
- position: absolute;
- right: 0;
- top: 0;
- transition: opacity 500ms;
-}
-
-.shown > .cr-dialog-shield {
- opacity: 0.5;
- transition: opacity 500ms;
-}
-
-.cr-dialog-title {
- -webkit-margin-after: 10px;
- -webkit-margin-end: 20px;
- display: block;
- font-size: 125%;
- white-space: nowrap;
- word-wrap: normal;
-}
-
-.cr-dialog-text {
- margin: 13px 0;
-}
-
-.cr-dialog-text,
-.cr-dialog-title {
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.cr-dialog-frame input {
- box-sizing: border-box;
- width: 100%;
-}
-
-.cr-dialog-buttons {
- -webkit-box-orient: horizontal;
- -webkit-box-pack: end;
- display: -webkit-box;
- padding-top: 10px;
-}
-
-.cr-dialog-buttons button {
- -webkit-margin-start: 8px;
- line-height: 1.8;
-}
-
-.cr-dialog-close {
- background: url('chrome://theme/IDR_CLOSE_DIALOG') center no-repeat;
- display: inline-block;
- height: 44px;
- opacity: 0.7;
- position: absolute;
- right: 0;
- top: 0;
- width: 44px;
-}
-
-.cr-dialog-close:hover {
- background-image: url('chrome://theme/IDR_CLOSE_DIALOG_H');
-}
-
-.cr-dialog-close:active {
- background-image: url('chrome://theme/IDR_CLOSE_DIALOG_P');
-}
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/css/drive_welcome.css b/chromium/chrome/browser/resources/file_manager/foreground/css/drive_welcome.css
deleted file mode 100644
index a3c5ddb8999..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/css/drive_welcome.css
+++ /dev/null
@@ -1,188 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-/* Google Drive welcome banners.*/
-.drive-welcome-wrapper {
- /* This image looks good in high DPI as is. */
- background-image: url(chrome://resources/images/clouds.png);
- background-repeat: repeat-x;
- color: #333;
-}
-
-.drive-welcome-icon {
- background-image: -webkit-image-set(
- url('../images/files/ui/drive_logo.png') 1x,
- url('../images/files/ui/2x/drive_logo.png') 2x);
- background-repeat: no-repeat;
-}
-
-.drive-welcome-links {
- -webkit-box-orient: horizontal;
- display: -webkit-box;
-}
-
-.drive-welcome-button {
- -webkit-user-select: none;
- background-image: linear-gradient(to bottom, #f5f5f5, #f1f1f1);
- border: 1px solid rgba(0,0,0,0.1);
- border-radius: 2px;
- color: #444;
- cursor: default;
- display: inline-block;
- font-size: 13px;
- font-weight: bold;
- height: 27px;
- line-height: 27px;
- padding: 0 8px;
- text-align: center;
- transition: all 218ms;
-}
-
-.drive-welcome-button:hover {
- background-image: linear-gradient(to bottom, #f8f8f8, #f1f1f1);
- border-color: #C6C6C6;
- box-shadow: 0 1px 1px rgba(0,0,0,0.1);
- color: #222;
- transition: all 0;
-}
-
-.drive-welcome-button:active {
- background-image: linear-gradient(to bottom, #f6f6f6, #f1f1f1);
- box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);
-}
-
-
-.drive-welcome-button.drive-welcome-start {
- background-image:
- linear-gradient(to bottom, rgb(77, 144, 254), rgb(71, 135, 237));
- border-color: rgb(48, 121, 237);
- color: white;
- text-decoration: none;
-}
-
-.drive-welcome-button.drive-welcome-start:hover {
- background-image:
- linear-gradient(to bottom, rgb(77, 144, 254), rgb(53, 122, 232));
- border-color: rgb(47, 91, 183);
- box-shadow: 0 1px 1px rgba(0,0,0,0.1);
-}
-
-/* Header welcome banner. */
-.drive-welcome.header {
- -webkit-box-flex: 0;
- height: 100px;
- overflow: hidden;
- position: relative;
- transition: height 180ms ease, visibility 0 linear 180ms;
-}
-
-.dialog-container:not([drive-welcome='header']) .drive-welcome.header {
- height: 0;
- visibility: hidden;
-}
-
-.drive-welcome.header .drive-welcome-wrapper {
- -webkit-box-orient: horizontal;
- background-size: 308px 100px;
- bottom: 0;
- display: -webkit-box;
- left: 0;
- position: absolute;
- right: 0;
- top: 0;
-}
-
-.drive-welcome.header .drive-welcome-icon {
- background-position: center 18px;
- background-size: 51px 44px;
- width: 120px;
-}
-
-.drive-welcome.header .drive-welcome-message {
- -webkit-box-flex: 1;
- -webkit-box-orient: vertical;
- display: -webkit-box;
-}
-
-.drive-welcome.header .drive-welcome-title {
- font-size: 140%;
- margin-bottom: 4px;
- margin-top: 14px;
-}
-
-.drive-welcome.header .drive-welcome-text {
- margin-bottom: 6px;
-}
-
-.drive-welcome.header .drive-welcome-dismiss {
- display: none;
-}
-
-/* Full page welcome banner. */
-.drive-welcome.page {
- bottom: 0;
- left: 0;
- position: absolute;
- right: 0;
- top: 0;
-}
-
-.dialog-container:not([drive-welcome='page']) .drive-welcome.page {
- display: none;
-}
-
-.drive-welcome.page .cr-dialog-close {
- display: none;
-}
-
-.drive-welcome.page .drive-welcome-wrapper {
- -webkit-box-align: center;
- -webkit-box-orient: vertical;
- background-size: 520px 173px;
- bottom: 0;
- display: -webkit-box;
- font-size: 120%;
- left: 0;
- overflow: hidden;
- position: absolute;
- right: 0;
- top: 0;
-}
-
-.drive-welcome.page .drive-welcome-icon {
- background-position: center center;
- height: 240px;
- left: 0;
- right: 0;
- top: 0;
- width: 100%;
-}
-
-.drive-welcome.page .drive-welcome-message {
- margin-left: 10px;
- margin-right: 10px;
- max-width: 525px;
-}
-
-.drive-welcome.page .drive-welcome-title {
- font-size: 133%;
- margin-bottom: 30px;
- text-align: center;
-}
-
-.drive-welcome.page .drive-welcome-text {
- margin-bottom: 24px;
-}
-
-.drive-welcome.page .drive-welcome-dismiss {
- margin-left: 20px;
-}
-
-body:not([type='full-page']) .drive-welcome.page .drive-welcome-wrapper {
- background-position: 0 0;
-}
-
-body:not([type='full-page']) .drive-welcome.page .drive-welcome-icon {
- height: 200px;
-}
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/css/file_manager.css b/chromium/chrome/browser/resources/file_manager/foreground/css/file_manager.css
deleted file mode 100644
index 560cef7e9a5..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/css/file_manager.css
+++ /dev/null
@@ -1,2075 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-/* The order of z-index:
- * - 2: drag-selection-bodrder
- * - 3: preview-panel
- * - 500: scrollbar
- * - 500: splitter
- * - 525: spinner
- * - 550: autocomplete-suggestions
- * - 600: menus
- * - 600: tooltip
- * - 1000: preview thumbnail popup
- * - 1000: overlay panel (ie. image editor)
- */
-
-/* Special attribute used in HTML to hide elements. */
-body[type='folder'] [invisibleif~='folder'],
-body[type='upload-folder'] [invisibleif~='upload-folder'],
-body[type='saveas-file'] [invisibleif~='saveas-file'],
-body[type='open-file'] [invisibleif~='open-file'],
-body[type='open-multi-file'] [invisibleif~='open-multi-file'],
-body[type='full-page'] [invisibleif~='full-page'],
-
-body[type='folder'] [visibleif]:not([visibleif~='folder']),
-body[type='upload-folder'] [visibleif]:not([visibleif~='upload-folder']),
-body[type='saveas-file'] [visibleif]:not([visibleif~='saveas-file']),
-body[type='open-file'] [visibleif]:not([visibleif~='open-file']),
-body[type='open-multi-file'] [visibleif]:not([visibleif~='open-multi-file']),
-body[type='full-page'] [visibleif]:not([visibleif~='full-page']) {
- display: none !important;
-}
-
-html {
- height: 100%;
-}
-
-html.col-resize * {
- cursor: col-resize !important;
-}
-
-/* Outer frame of the dialog. */
-body {
- -webkit-box-flex: 1;
- -webkit-box-orient: vertical;
- -webkit-tap-highlight-color: transparent;
- -webkit-user-select: none;
- cursor: default;
- display: -webkit-box;
- height: 100%;
- margin: 0;
- padding: 0;
- width: 100%;
-}
-
-/* Drop opacity of selected rows to give a visual feedback on copy/cut
- * operation. */
-.blink {
- opacity: 0.8;
-}
-
-::-webkit-scrollbar {
- height: 0;
- width: 0;
-}
-
-/* TODO(mtomasz): Flip scrollbars to the opposite side for RTL languages. */
-.scrollbar-vertical {
- bottom: 0;
- position: absolute;
- right: 0;
- top: 0;
- width: 10px;
- z-index: 500; /* Must be below the contextmenu (600). */
-}
-
-.scrollbar-button {
- background-color: black;
- border: 1px solid #ccc;
- border-radius: 3px;
- box-sizing: border-box;
- height: 50%;
- margin-right: 2px;
- opacity: 0;
- position: absolute;
- transition: opacity 100ms;
- width: 8px;
-}
-
-:hover > .scrollbar-vertical > .scrollbar-button {
- opacity: 0.3;
-}
-
-.scrollbar-vertical > .scrollbar-button:hover {
- opacity: 0.4;
-}
-
-.scrollbar-vertical > .scrollbar-button.pressed {
- opacity: 0.5;
-}
-
-/* Main part of the dialog between header and footer. */
-.dialog-container {
- -webkit-box-align: stretch;
- -webkit-box-flex: 1;
- -webkit-box-orient: horizontal;
- background-color: white; /* Makes #drag-container invisible. */
- border-radius: 2px;
- display: -webkit-box;
- overflow: hidden;
- position: relative;
-}
-
-/* The style applied when a modal dialog box overlap the dialog container. */
-.dialog-container.disable-header-drag .dialog-navigation-list-header,
-.dialog-container.disable-header-drag .dialog-header {
- -webkit-app-region: no-drag;
-}
-
-/* List/grid and preview are inside this container. */
-.dialog-main {
- -webkit-box-align: stretch;
- -webkit-box-flex: 1;
- -webkit-box-orient: vertical;
- display: -webkit-box;
-}
-
-/* Directory tree at the left. */
-.dialog-navigation-list {
- -webkit-border-end: 1px solid rgba(20, 20, 22, 0.1);
- -webkit-box-flex: 0;
- -webkit-box-orient: vertical;
- background-color: #f1f1f1;
- display: flex;
- flex-direction: column;
- max-width: 50%;
- min-width: 100px;
- overflow: hidden;
- position: relative;
- width: 150px;
-}
-
-.dialog-navigation-list-header {
- -webkit-app-region: drag;
- flex: none;
- height: 48px; /* Keep in sync with #dialog-header. */
- line-height: 45px;
-}
-
-.dialog-navigation-list-header #app-name {
- -webkit-margin-start: 15px;
- color: #303030;
- font-size: 130%;
-}
-
-.dialog-navigation-list-contents {
- display: -webkit-box;
- flex: 1 1 auto;
- position: relative;
-}
-
-.dialog-navigation-list-footer {
- display: -webkit-flex;
- flex: none;
- flex-direction: column;
-}
-
-/* A vertical splitter between the roots list and the file list. It is actually
- a transparent area centered on the roots list right border.*/
-div.splitter {
- -webkit-box-flex: 0;
- cursor: col-resize;
- margin-left: -3px;
- margin-right: -3px;
- position: relative;
- width: 6px;
- z-index: 500; /* Must be below the contextmenu (600). */
-}
-
-#navigation-list {
- -webkit-box-flex: 1;
- -webkit-box-orient: vertical;
- display: -webkit-box;
-}
-
-#navigation-list > * {
- height: 40px;
- padding: 0 5px;
-}
-
-#navigation-list > .accepts,
-#navigation-list > [lead][selected],
-#navigation-list > [lead],
-#navigation-list > [selected],
-#navigation-list > [anchor] {
- background-color: rgb(225, 225, 225);
-}
-
-#navigation-list:focus > .accepts,
-#navigation-list:focus > [lead][selected],
-#navigation-list:focus > [lead],
-#navigation-list:focus > [selected],
-#navigation-list:focus > [anchor] {
- background-color: rgb(66, 129, 244);
- color: white;
-}
-
-#navigation-list li.root-item {
- -webkit-box-align: center;
- display: -webkit-box;
- line-height: 22px; /* To accomodate for icons. */
- padding-left: 11px;
-}
-
-#navigation-list li.root-item > .root-label {
- -webkit-box-flex: 1;
- margin: 0 2px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-#navigation-list .volume-icon {
- background-position: center 2px;
- background-repeat: no-repeat;
- height: 24px;
- width: 24px;
-}
-
-#middlebar-header {
- -webkit-border-end: 1px solid rgba(20, 20, 22, 0.1);
- -webkit-box-sizing: border-box;
- -webkit-padding-start: 20px;
- color: rgb(100, 100, 100);
- height: 47px;
- line-height: 40px;
- overflow-x: hidden;
- position: absolute;
- text-overflow: ellipsis;
- width: 100%;
-}
-
-#directory-tree {
- -webkit-border-end: 1px solid rgba(20, 20, 22, 0.1);
- bottom: 0;
- left: 0;
- overflow-x: hidden;
- overflow-y: auto;
- padding-bottom: 0; /* For the preview panel. Will be overridden by JS. */
- position: absolute;
- right: 0;
- top: 47px;
-}
-
-#directory-tree .tree-row {
- cursor: pointer;
- display: -webkit-box;
- line-height: 29px;
- padding: 0 3px;
-}
-
-/* For rows of subitems (non-top items) */
-#directory-tree .tree-children .tree-row {
- line-height: 29px;
-}
-
-#directory-tree .tree-row > .expand-icon {
- height: 37px;
- left: 3px;
- margin: -13px;
- right: 3px;
- top: 0;
- vertical-align: middle;
- width: 37px;
-}
-
-#directory-tree:focus .tree-row[selected] > .expand-icon {
- background-image: -webkit-canvas(tree-triangle-inverted);
-}
-
-#directory-tree .tree-row > .volume-icon {
- background-position: center 2px;
- background-repeat: no-repeat;
- height: 24px;
- vertical-align: middle;
- width: 24px;
-}
-
-#directory-tree .tree-row > .label {
- -webkit-box-flex: 1;
- display: block;
- margin: 0 3px;
- overflow-x: hidden;
- text-overflow: ellipsis;
-}
-
-#directory-tree .tree-item.accepts > .tree-row,
-#directory-tree .tree-row[lead][selected],
-#directory-tree .tree-row[lead],
-#directory-tree .tree-row[selected],
-#directory-tree .tree-row[anchor] {
- background-color: rgb(204, 204, 204);
-}
-
-#directory-tree .tree-item.accepts > .tree-row,
-#directory-tree .tree-row[lead][selected],
-#directory-tree .tree-row[lead],
-#directory-tree .tree-row[selected],
-#directory-tree .tree-row[anchor] {
- background-color: rgb(225, 225, 225);
-}
-
-#directory-tree:focus .tree-item.accepts > .tree-row,
-#directory-tree:focus .tree-row[lead][selected],
-#directory-tree:focus .tree-row[lead],
-#directory-tree:focus .tree-row[selected],
-#directory-tree:focus .tree-row[anchor] {
- background-color: rgb(193, 209, 232);
-}
-
-#directory-tree:focus .tree-item.accepts > .tree-row,
-#directory-tree:focus .tree-row[lead][selected],
-#directory-tree:focus .tree-row[lead],
-#directory-tree:focus .tree-row[selected],
-#directory-tree:focus .tree-row[anchor] {
- background-color: rgb(66, 129, 244);
- color: white;
-}
-
-#navigation-list .root-item > div.root-eject {
- background-image: -webkit-image-set(
- url('../images/files/ui/eject.png') 1x,
- url('../images/files/ui/2x/eject.png') 2x);
- background-position: center center;
- background-repeat: no-repeat;
- cursor: pointer;
- height: 20px;
- margin-right: 6px;
- opacity: 0.7;
- transition: opacity 70ms linear;
- vertical-align: middle;
- width: 20px;
-}
-
-#navigation-list:focus .root-item[selected] > div.root-eject {
- -webkit-filter: brightness(0) invert();
- opacity: 1;
-}
-
-#directory-tree .root-item[disabled] {
- opacity: 0.5;
- pointer-events: none;
-}
-
-/* Breadcrumbs and things under the title but above the list view. */
-.dialog-header {
- -webkit-app-region: drag;
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- display: flex;
- height: 48px;
- margin: 0;
- transition: all 180ms ease;
-}
-
-/* Search box */
-
-#search-box {
- display: flex;
- flex: auto;
-}
-
-#search-box.too-short {
- visibility: hidden;
-}
-
-#search-box .icon {
- -webkit-app-region: no-drag;
- -webkit-padding-end: 0;
- -webkit-padding-start: 10px;
- background: transparent -webkit-image-set(
- url(../images/files/ui/search_icon_inactive.png) 1x,
- url(../images/files/ui/2x/search_icon_inactive.png) 2x)
- no-repeat center;
- flex: none;
- height: 32px;
- padding-bottom: 8px;
- padding-top: 8px;
- width: 32px;
-}
-
-#search-box .icon:hover,
-#search-box.has-cursor .icon,
-#search-box.has-text .icon {
- background-image: -webkit-image-set(
- url(../images/files/ui/search_icon_active.png) 1x,
- url(../images/files/ui/2x/search_icon_active.png) 2x);
-}
-
-#search-box .full-size {
- flex: 1 0 0;
-}
-
-#search-box input {
- -webkit-app-region: no-drag;
- background-color: #fff;
- border-style: none;
- color: #333;
- cursor: default;
- display: block;
- height: 48px;
- line-height: 1em;
- margin: 0;
- max-width: 100%;
- outline: none;
- padding: 0;
-}
-
-#search-box input::-webkit-search-cancel-button {
- -webkit-appearance: none;
-}
-
-#search-box.has-cursor input,
-#search-box.has-text input {
- cursor: text;
-}
-
-#search-box .clear {
- -webkit-app-region: no-drag;
- -webkit-margin-end: 30px;
- align-self: center;
- background: -webkit-image-set(
- url(../images/files/ui/search_clear.png) 1x,
- url(../images/files/ui/2x/search_clear.png) 2x)
- no-repeat center;
- border: none;
- display: none;
- flex: none;
- height: 12px;
- min-height: 0;
- min-width: 0;
- outline: none;
- padding: 0;
- width: 12px;
-}
-
-#search-box.has-text .clear {
- display: block;
-}
-
-#search-box .clear:hover {
- background-image: -webkit-image-set(
- url(../images/files/ui/search_clear_hover.png) 1x,
- url(../images/files/ui/2x/search_clear_hover.png) 2x);
-}
-
-#search-box .clear:active {
- background-image: -webkit-image-set(
- url(../images/files/ui/search_clear_pressed.png) 1x,
- url(../images/files/ui/2x/search_clear_pressed.png) 2x);
-}
-
-.topbutton-bar {
- flex: none;
-}
-
-/* Container for the detail and thumbnail list views. */
-.dialog-body {
- -webkit-box-flex: 1;
- -webkit-transition: all 180ms ease;
- border-top: 1px solid rgba(20, 20, 22, 0.1);
- position: relative;
-}
-
-.main-panel {
- bottom: 0;
- display: -webkit-box;
- left: 0;
- position: absolute;
- right: 0;
- top: 0;
-}
-
-.dialog-middlebar-contents {
- display: -webkit-box;
- max-width: 50%;
- min-width: 45px;
- position: relative;
- width: 180px;
-}
-
-/* Container for the ok/cancel buttons. */
-.dialog-footer {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- border-top: 1px solid rgb(225, 225, 225);
- display: -webkit-box;
- outline: none;
- padding: 10px;
-}
-
-.progressable:not([progress]) .progress-bar,
-.progressable:not([progress]) .preparing-label {
- display: none;
-}
-
-.progressable[progress] .ok,
-.progressable[progress] #filename-input-box,
-.progressable[progress] #preview-lines,
-.progressable[progress] .file-type {
- display: none;
-}
-
-.progressable .progress-bar {
- -webkit-box-flex: 1;
- -webkit-margin-end: 20px;
- -webkit-margin-start: 20px;
-}
-
-select.file-type:hover {
- /* Original value is '5 fill', which hides the dropdown triangle. */
- border-image-slice: 5;
-}
-
-/* The container for breadcrumb elements. */
-.breadcrumbs {
- -webkit-box-align: center;
- -webkit-box-flex: 1;
- -webkit-box-orient: horizontal;
- display: -webkit-box;
- line-height: 20px;
- overflow: hidden;
- padding-top: 1px;
-}
-
-#dir-breadcrumbs {
- -webkit-margin-end: 5px;
- -webkit-margin-start: 10px;
-}
-
-/* The icon for offline mode */
-.offline-icon {
- -webkit-margin-end: 0;
- -webkit-margin-start: 10px;
- background-image: -webkit-image-set(
- url('../images/files/ui/offline.png') 1x,
- url('../images/files/ui/2x/offline.png') 2x);
- height: 16px;
- opacity: 0;
- transition-duration: 200ms;
- transition-property: opacity;
- transition-timing-function: ease-out;
- width: 16px;
-}
-
-/* Transition for '-webkit-margin-start' (or -end) property is not working.
- * So I added .offline-icon-space to animate 'width' property. */
-.offline-icon-space {
- -webkit-margin-end: 0;
- -webkit-margin-start: -26px; /* Clear width of .offline-icon */
- transition-duration: 200ms;
- transition-property: width;
- transition-timing-function: ease-out;
- width: 0;
-}
-
-body[drive] .dialog-container[connection='offline'] .offline-icon,
-body[drive] .dialog-container[connection='metered'] .offline-icon {
- opacity: 1;
-}
-
-body[drive] .dialog-container[connection='offline'] .offline-icon-space,
-body[drive] .dialog-container[connection='metered'] .offline-icon-space {
- width: 26px;
-}
-
-.breadcrumbs > [collapsed]::before {
- content: '...';
-}
-
-.breadcrumbs > [collapsed] {
- width: 1em;
-}
-
-/* A single directory name in the list of path breadcrumbs. */
-.breadcrumb-path {
- color: #969696;
- cursor: pointer;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-/* The final breadcrumb, representing the current directory. */
-#search-breadcrumbs .breadcrumb-path.breadcrumb-last {
- color: #141414;
- cursor: default;
-}
-
-/* The > arrow between breadcrumbs. */
-
-.breadcrumbs .separator {
- background-image: -webkit-image-set(
- url('../images/files/ui/breadcrumb-separator.png') 1x,
- url('../images/files/ui/2x/breadcrumb-separator.png') 2x);
- background-position: center center;
- background-repeat: no-repeat;
- height: 10px;
- overflow: hidden;
- width: 25px;
-}
-
-#filename-input-box input {
- border: 1px solid #c8c8c8;
- border-radius: 1px;
- box-sizing: border-box;
- height: 31px; /* border-box */
- margin-right: 30px;
-}
-
-.filelist-panel {
- -webkit-box-flex: 1;
- -webkit-box-orient: vertical;
- display: -webkit-box;
-}
-
-#list-container {
- -webkit-box-flex: 1;
- -webkit-box-orient: vertical;
- display: -webkit-box;
- position: relative;
-}
-
-#detail-table {
- -webkit-box-flex: 1;
- -webkit-box-orient: vertical;
- display: -webkit-box;
-}
-
-#detail-table > list,
-.thumbnail-grid {
- -webkit-box-flex: 1;
- padding-bottom: 0; /* For the preview panel. Will be overridden by JS. */
-}
-
-#file-list .drag-selection-border {
- -webkit-box-sizing: border-box;
- background-color: rgba(255, 255, 255, 0.3);
- border: 2px solid rgba(255, 255, 255, 0.6);
- outline: 1px solid rgba(0, 0, 0, 0.1);
- position: absolute;
- z-index: 2;
-}
-
-.spinner {
- background: 100% url(../images/common/spinner.svg);
- height: 16px;
- left: 50%;
- margin-left: -8px;
- margin-top: -8px;
- opacity: 0.5;
- position: absolute;
- top: 50%;
- width: 16px;
-}
-
-.spinner-layer {
- background: url(../images/common/spinner.svg) center / 16px no-repeat;
- bottom: 0;
- left: 0;
- position: absolute;
- right: 0;
- top: 0;
- z-index: 525;
-}
-
-.downloads-warning {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- background-color: #f0f0f0;
- background-image: -webkit-image-set(
- url('../images/files/ui/warning_icon_square.png') 1x,
- url('../images/files/ui/2x/warning_icon_square.png') 2x);
- background-position: 15px center;
- background-repeat: no-repeat;
- color: #666;
- display: -webkit-box;
- font-size: 13px;
- height: 57px;
- overflow: hidden;
- padding-left: 57px; /* Make space for the icon. */
- transition: height 70ms linear;
-}
-
-.downloads-warning[hidden] {
- display: -webkit-box !important; /* Overrides [hidden] for animation. */
- height: 0;
-}
-
-@-webkit-keyframes heightAnimation {
- 0% {
- height: 0;
- display: -webkit-box;
- }
-}
-
-/* Drive space warning banner. */
-.volume-warning {
- -webkit-animation: heightAnimation 70ms linear;
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- background-image: url(chrome://resources/images/clouds.png);
- background-repeat: repeat-x;
- background-size: 150px 44px;
- color: #333;
- display: -webkit-box;
- font-size: 13px;
- height: 44px;
- overflow: hidden;
- position: relative;
-}
-
-.volume-warning[hidden] {
- border-top-width: 0;
- height: 0;
-}
-
-.volume-warning .drive-icon {
- background-image: -webkit-image-set(
- url('../images/files/ui/drive_logo.png') 1x,
- url('../images/files/ui/2x/drive_logo.png') 2x);
- background-position: center;
- background-repeat: no-repeat;
- background-size: 25px 22px;
- height: 44px;
- width: 50px;
-}
-
-.volume-warning .drive-text {
- margin-right: 11px;
-}
-
-/* The cr.ui.Grid representing the detailed file list. */
-.thumbnail-grid {
- overflow-y: auto;
- padding-bottom: 0; /* For the preview panel. Will be overridden by JS. */
- width: 100%;
-}
-
-body[type='full-page'] .thumbnail-frame > .img-container {
- position: relative;
-}
-
-body[type='full-page'] .thumbnail-frame > .img-container,
-body[type='full-page'] .detail-name .detail-icon {
- cursor: pointer;
-}
-
-.img-container > img {
- -webkit-user-drag: none;
- position: absolute;
-}
-
-.img-container > img:not(.cached):not(.drag-thumbnail) {
- -webkit-animation: fadeIn 250ms linear;
-}
-
-.thumbnail-bottom {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: center;
- bottom: 0;
- cursor: auto;
- display: -webkit-box;
- left: 0;
- padding: 0 10px;
- position: absolute;
- right: 0;
-}
-
-.thumbnail-bottom .filename-label {
- -webkit-box-flex: 1;
-}
-
-/* Styles specific for the grid view. */
-
-.thumbnail-grid .thumbnail-item {
- -webkit-margin-start: 21px;
- border: 3px solid transparent; /* Selection will make the border visible. */
- margin-top: 20px;
- position: relative;
-}
-
-.thumbnail-grid .thumbnail-frame {
- background-color: rgb(245, 245, 245);
- height: 120px;
- overflow: hidden;
- position: relative;
- width: 160px;
-}
-
-.thumbnail-grid .thumbnail-item[selected] .thumbnail-frame,
-.thumbnail-grid .thumbnail-item.accepts .thumbnail-frame {
- border-color: white;
-}
-
-.thumbnail-grid .img-container {
- height: 100%;
- width: 100%;
-}
-
-.thumbnail-grid .thumbnail-bottom {
- background: rgba(0, 0, 0, 0.55);
- color: #fff;
- height: 30px;
-}
-
-/* Padding counterweights negative margins of items, thus eliminating scroll
- bar when it's not needed. Max height is set to fit 8 items before showing
- scroll bar. */
-#default-actions-list {
- max-height: 328px;
- padding: 1px 0;
-}
-
-#default-actions-list > li > * {
- background-position: 5px center;
- background-repeat: no-repeat;
- background-size: 16px 16px;
- padding-left: 26px;
-}
-
-#list-container list > li[selected],
-#list-container grid > li[selected],
-#default-actions-list > li[selected] {
- background-color: rgb(225, 225, 225);
-}
-
-#list-container list:focus > li[selected],
-#list-container grid:focus > li[selected],
-#default-actions-list:focus > li[selected] {
- background-color: rgb(66, 129, 244);
- color: white;
-}
-
-#list-container list > li.accepts[selected],
-#list-container grid > li.accepts[selected] {
- background-color: rgb(215, 215, 215);
-}
-
-#list-container list:focus > li.accepts[selected],
-#list-container grid:focus > li.accepts[selected] {
- background-color: rgb(48, 125, 254);
-}
-
-#list-container list > li.accepts,
-#list-container grid > li.accepts {
- background-color: #f1f1f1;
-}
-
-#list-container.nohover grid > .accepts {
- background-color: transparent;
-}
-
-#directory-tree .tree-item.accepts > .tree-row,
-#navigation-list > .accepts,
-#list-container list > li.accepts,
-#list-container grid > li.accepts {
- -webkit-animation: acceptsBlink 200ms linear 1s 3;
-}
-
-@-webkit-keyframes acceptsBlink {
- 0% {
- background-color: transparent;
- }
-}
-
-.table-row-cell .selection-label {
- -webkit-margin-end: 10px;
- height: 15px;
-}
-
-.table-row-cell .filename-label,
-.thumbnail-item .filename-label,
-/* Show ellipsis in cells. The name column has different structure and overrides
- this rule. */
-.table-row-cell > div {
- display: block;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-/* Text box used for renaming in the detail list. */
-.table-row-cell input.rename {
- border-width: 0;
- padding: 2px 0;
-}
-
-input.rename:focus {
- outline-color: rgb(77, 144, 254);
-}
-
-input.rename {
- font: inherit;
- line-height: 1;
- text-align: inherit;
-}
-
-.table-row-cell .filename-label,
-.table-row-cell input.rename {
- -webkit-box-flex: 1;
-}
-
-[renaming] > .filename-label {
- display: none;
-}
-
-/* Text box used for renaming in the thumbnail list. */
-.thumbnail-grid input.rename {
- -webkit-margin-start: -1px;
- box-sizing: border-box;
- height: 20px;
- width: 114px;
-}
-
-/* The cr.ui.Table representing the detailed file list. */
-.detail-table {
- width: 100%;
-}
-
-/* Bottom pane describing current selection. */
-.preview-panel {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-transition: background-color 150ms ease;
- background: linear-gradient(
- to bottom, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 1));
- border-top: 1px solid rgba(20, 20, 22, 0.1);
- bottom: 0;
- display: -webkit-box;
- height: 51px;
- left: 0;
- opacity: 1;
- padding: 0 10px 0 7px;
- position: absolute;
- right: 0;
- z-index: 3;
-}
-
-.preview-panel[visibility=hiding] {
- -webkit-transform: translate(0, 5px);
- opacity: 0;
- /* Using all seems to cause preview panel and checkbox flicking issue. */
- transition: opacity 220ms ease,
- -webkit-transform 220ms ease;
-}
-
-.preview-panel[visibility=hidden] {
- display: none;
- opacity: 0;
-}
-
-.preview-panel > .left,
-.dialog-footer > .left {
- -webkit-box-align: center;
- -webkit-box-flex: 1;
- -webkit-box-orient: horizontal;
- display: -webkit-box;
-}
-
-.preview-panel > .right,
-.dialog-footer > .right {
- -webkit-box-pack: end;
-}
-
-.preview-panel .preparing-label {
- -webkit-margin-start: 30px;
-}
-
-.preview-panel .progress-bar {
- -webkit-box-flex: 1;
-}
-
-.preview-thumbnails {
- -webkit-box-orient: horizontal;
- display: -webkit-box;
- padding-left: 25px;
-}
-
-.preview-thumbnails > .img-container {
- background-color: white;
- background-size: 35px 35px; /* For file icons. */
- border: 2px solid white;
- box-shadow: 0 1px 1px rgba(80, 80, 80, 0.5);
- box-sizing: border-box;
- cursor: pointer;
- height: 35px;
- margin: 0 0 0 -25px; /* Overlapped images. */
- overflow: hidden;
- position: relative;
- width: 35px;
-}
-
-.preview-thumbnails > .popup {
- -webkit-transform: translate(0, 3px) scale(0.95);
- background-color: #f2f2f2;
- border: 2px solid #fff;
- bottom: 8px;
- box-shadow: 0 0 0 1px #F0F0F0,
- 0 0 0 2px #D0D0D0,
- 2px 2px 6px rgba(0, 0, 0, 0.2);
- display: -webkit-flex;
- left: -8px;
- opacity: 0;
- pointer-events: none;
- position: absolute;
- transition: opacity 180ms ease-in 300ms,
- -webkit-transform 180ms ease-in 300ms;
- z-index: 1000;
-}
-
-.preview-thumbnails.has-zoom:hover > .popup {
- -webkit-transform: translate(0, 0) scale(1.0);
- opacity: 1;
- pointer-events: auto;
-}
-
-@-webkit-keyframes fadeIn {
- from {
- opacity: 0;
- }
- to {
- opacity: 1;
- }
-}
-
-.preview-thumbnails img {
- -webkit-animation: fadeIn 180ms ease-in-out;
-}
-
-.preview-thumbnails > .popup > img {
- -webkit-flex: 1 1 0;
- -webkit-user-drag: none;
-}
-
-/* Table splitter element */
-.table-header-splitter {
- background-image: -webkit-image-set(
- url('../images/files/ui/vertical_separator.png') 1x,
- url('../images/files/ui/2x/vertical_separator.png') 2x);
- background-position: center;
- background-repeat: repeat-y;
- height: 20px;
- top: 10px;
- width: 5px;
-}
-
-.table-header-splitter:last-child {
- display: none;
-}
-
-/* Container for a table header. */
-.table-header {
- box-sizing: border-box;
- height: 47px;
-}
-
-.table-header-sort-image-desc::after {
- -webkit-padding-start: 13px;
- background-image: -webkit-image-set(
- url('../images/files/ui/sort_desc.png') 1x,
- url('../images/files/ui/2x/sort_desc.png') 2x);
- background-position: center center;
- background-repeat: no-repeat;
- color: #888;
- content: '\00a0';
- position: relative;
- top: 1px;
-}
-
-.table-header-sort-image-asc::after {
- -webkit-padding-start: 13px;
- background-image: -webkit-image-set(
- url('../images/files/ui/sort_asc.png') 1x,
- url('../images/files/ui/2x/sort_asc.png') 2x);
- background-position: center center;
- background-repeat: no-repeat;
- color: #888;
- content: '\00a0';
- position: relative;
- top: -1px;
-}
-
-.preview-container .table-header {
- border-radius: 0 4px 0 0;
-}
-
-/* Text label in a table header. */
-.table-header-label {
- color: rgb(100, 100, 100);
- line-height: 40px;
- margin: 0 7px;
-}
-
-.table-row-cell > * {
- -webkit-box-align: center;
- -webkit-box-flex: 1;
- -webkit-box-orient: horizontal;
- padding: 0 10px;
-}
-
-.table-row-cell {
- color: rgb(100, 100, 100);
-}
-
-.table-row-cell > .detail-name {
- display: -webkit-box;
-}
-
-.table-row-cell > .detail-name {
- color: rgb(0, 0, 0);
-}
-
-
-#list-container list:focus > [selected] .table-row-cell,
-#list-container list:focus > [selected] .detail-name {
- color: white;
-}
-
-.table-row-cell {
- -webkit-box-align: center;
-}
-
-.file-checkbox {
- -webkit-margin-end: 0;
- -webkit-margin-start: 0;
- position: relative;
- z-index: 2;
-}
-
-#select-all-checkbox {
- -webkit-margin-end: 13px;
- -webkit-margin-start: 3px;
- margin-bottom: 0;
- margin-top: 0;
- vertical-align: middle;
-}
-
-#list-container .table-header #select-all-checkbox,
-#list-container li.table-row .file-checkbox {
- -webkit-appearance: none;
- background-image: -webkit-image-set(
- url('../images/files/ui/select_checkbox.png') 1x,
- url('../images/files/ui/2x/select_checkbox.png') 2x);
- background-position: center;
- background-repeat: no-repeat;
- border-style: none;
- height: 15px;
- width: 15px;
-}
-
-#list-container li.table-row .file-checkbox {
- vertical-align: top;
-}
-
-#list-container .table-header #select-all-checkbox::after,
-#list-container li.table-row .file-checkbox::after {
- content: none;
-}
-
-#list-container .table-header #select-all-checkbox:checked,
-#list-container li.table-row .file-checkbox:checked {
- background-image: -webkit-image-set(
- url('../images/files/ui/select_checkbox_checked.png') 1x,
- url('../images/files/ui/2x/select_checkbox_checked.png') 2x);
-}
-
-#list-container .table-header #select-all-checkbox:checked,
-#list-container list li.table-row[selected] .file-checkbox {
- -webkit-filter: brightness(0) opacity(40%);
-}
-
-#list-container list:focus li.table-row[selected] .file-checkbox {
- -webkit-filter: brightness(0) invert();
-}
-
-#list-container li.table-row,
-#default-actions-list li {
- height: 29px;
- line-height: 29px;
-}
-
-/* The icon in the name column. See file_types.css for specific icons. */
-.detail-icon {
- height: 24px;
- width: 24px;
-}
-
-#detail-table .detail-icon {
- /* To shift the icon position. */
- margin-bottom: 2px;
-}
-
-.metadata-item {
- -webkit-box-flex: 1;
- -webkit-box-orient: horizontal;
- -webkit-padding-start: 8px;
- display: -webkit-box;
-}
-
-.metadata-label {
- -webkit-margin-end: 6px;
-}
-
-.preview-panel .spacer {
- -webkit-box-flex: 1;
-}
-
-#delete-button {
- min-width: 21px; /* overrride */
- padding: 0; /* overrride */
- width: 21px;
-}
-
-#delete-button::before {
- /* Background image should be specified in the before pseudo element because
- * border image fill is specified to delete-button. */
- background: -webkit-image-set(
- url(../images/files/ui/onbutton_trash.png) 1x,
- url(../images/files/ui/2x/onbutton_trash.png) 2x) no-repeat center;
- content: '';
- display: block;
- height: 100%;
- width: 100%;
-}
-
-#delete-button[disabled] {
- display: none;
-}
-
-#tasks-menu menuitem:not(.change-default) {
- background-position: left 10px center;
- padding-left: 32px;
-}
-
-#share-button {
- display: block;
- min-width: 0; /* overrride */
-}
-
-#preview-lines {
- -webkit-box-flex: 1;
- -webkit-margin-end: 10px;
- -webkit-margin-start: 10px;
- vertical-align: middle;
-}
-
-/* The selection summary text at the bottom of the preview pane. */
-.preview-summary {
- color: #666;
- overflow: hidden;
- text-overflow: ellipsis;
- vertical-align: middle;
- white-space: nowrap;
-}
-
-.preview-summary .calculating-size {
- margin-left: 5px;
- opacity: 0.5;
-}
-
-.detail-name > * {
- -webkit-box-align: center;
- display: -webkit-box;
-}
-
-/* Overriding input.common[type='checkbox'] rule in common.css. */
-.detail-name > input.common[type='checkbox'] {
- -webkit-margin-end: 4px;
- -webkit-margin-start: -1px;
- border-color: #444;
-}
-
-list .detail-name > .file-checkbox::before,
-.pin::before {
- /* Invisible area that reacts on mouse events. */
- content: '';
- display: -webkit-box;
- height: 38px;
- left: -8px;
- position: absolute;
- right: -9px;
- top: -14px;
-}
-
-#filename-input-box {
- -webkit-box-align: center;
- -webkit-box-flex: 1;
- display: -webkit-box;
-}
-
-#filename-input-box input {
- -webkit-box-flex: 1;
- display: -webkit-box;
- padding: 1px 2px;
-}
-
-#filename-input-box .filename-label {
- -webkit-box-orient: horizontal;
- background-color: white;
- color: #333;
- display: -webkit-box;
- padding-right: 4px;
-}
-
-body:not([type='saveas-file']) #filename-input-box {
- display: none;
-}
-
-/* A vertical spring. */
-.vertical-spacer {
- -webkit-box-flex: 1;
- -webkit-box-orient: vertical;
- display: -webkit-box;
-}
-
-/* Dimmed items */
-
-body[type='folder'] .file,
-body[type='upload-folder'] .file,
-body[drive] .dialog-container[connection='offline'] .dim-offline {
- opacity: 0.4;
-}
-
-/* Overlay pane covering the entire file manager window (e.g. image editor)*/
-.overlay-pane {
- -webkit-app-region: no-drag;
- border: none;
- height: 100%;
- left: 0;
- position: absolute;
- top: 0;
- width: 100%;
- z-index: 1000; /* Must be above all elements in file manager container. */
-}
-
-/* When the overlay pane is visible hide everything else so that the tab order
- is not confused. */
-body[overlay-visible] > :not(.overlay-pane) {
- display: none !important;
-}
-
-/* Invisible container for elements representing files while dragging. */
-#drag-container {
- left: 0;
- /* Hack for extra margins caused by setDragImage(). */
- padding: 1000px 0 0 1000px;
- position: fixed;
- top: 0;
- z-index: -1; /* below .dialog-container */
-}
-
-#drag-container .drag-contents {
- -webkit-box-orient: horizontal;
- background-color: #fafafa;
- border: 1px solid #bbb;
- border-radius: 3px;
- box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .2);
- display: -webkit-box;
- margin-bottom: 5px;
- padding: 6px;
- transition: opacity 200ms ease-in;
-}
-
-#drag-container .drag-contents.for-image {
- padding: 2px;
-}
-
-#drag-container .thumbnail-item {
- -webkit-box-orient: horizontal;
- display: -webkit-box;
-}
-
-/* When changing these properties please preserve these conditions:
- 1. width == height (so that the rotated thumbnail does not look off-center)
- 2. width % 8 == 0 (to minimize rounding errors in the centering code) */
-#drag-container .img-container {
- -webkit-box-flex: 0;
- display: -webkit-box;
- height: 64px;
- overflow: hidden;
- position: relative;
- width: 64px;
-}
-
-#drag-container .label {
- -webkit-box-flex: 1;
- font-weight: bold;
- line-height: 24px;
- max-width: 320px;
- overflow: hidden;
- padding: 0 5px;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-menu.file-context-menu {
- z-index: 600; /* Must be below the overlay pane (1000). */
-}
-
-menu.chrome-menu hr {
- color: transparent;
- font-size: 0;
-}
-
-div.offline {
- -webkit-box-pack: center;
- display: -webkit-box;
-}
-
-div.offline > * {
- -webkit-box-align: center;
- display: -webkit-box;
-}
-
-div.shade {
- /* transition: opacity 1000ms linear; */
- background-color: rgba(255, 255, 255, 0.8);
- bottom: 0;
- left: 0;
- opacity: 0;
- position: absolute;
- right: 0;
- top: 0;
-}
-
-div.shade[fadein] {
- opacity: 1;
-}
-
-/* Message panel for unmounted Drive */
-#unmounted-panel,
-#format-panel {
- bottom: 0;
- color: #333;
- display: none;
- left: 0;
- padding-left: 50px;
- padding-top: 20px;
- position: absolute;
- right: 0;
- top: 0;
-}
-
-body[drive='mounting'] .dialog-container #unmounted-panel,
-body[drive='error'] .dialog-container #unmounted-panel,
-body[unformatted] .dialog-container #format-panel {
- display: block;
-}
-
-body[drive='unmounted'] .dialog-container .filelist-panel,
-body[drive='mounting'] .dialog-container .filelist-panel,
-body[drive='error'] .dialog-container .filelist-panel,
-body[unformatted] .dialog-container .filelist-panel {
- /* Hide file list when Drive is not mounted.
- Use opacity to avoid manual resizing.*/
- opacity: 0;
-}
-
-#unmounted-panel > *,
-#format-panel > * {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: start;
- display: none;
- height: 22px;
- margin-bottom: 10px;
-}
-
-#unmounted-panel > .loading {
- position: relative;
-}
-
-#unmounted-panel > .loading > .spinner-box {
- bottom: 0;
- position: absolute;
- right: 100%;
- top: 0;
- width: 40px;
-}
-
-body[unformatted] #format-panel > .error,
-body[drive='mounting'] #unmounted-panel > .loading,
-body[drive='error'] #unmounted-panel > .error,
-#format-panel > #format-button,
-#unmounted-panel.retry-enabled > .learn-more {
- display: -webkit-box;
-}
-
-.plain-link {
- color: rgb(17, 85, 204);
- cursor: pointer;
- text-decoration: none;
-}
-
-.buttonbar > * {
- position: relative;
-}
-
-.buttonbar .tooltip,
-.topbutton-bar .tooltip {
- right: -12px;
- top: 35px;
-}
-
-/* Tooltips */
-.tooltip {
- background: #2d2d2d;
- border-radius: 0;
- box-shadow: 1px 2px 4px #ccc;
- box-sizing: border-box;
- color: white;
- display: block;
- font-size: 11px;
- font-weight: bold;
- height: 29px;
- line-height: 29px;
- margin-left: -20px;
- min-width: 50px;
- opacity: 0;
- outline: 1px solid rgba(255, 255, 255, 0.5);
- padding: 0 10px;
- pointer-events: none;
- position: absolute;
- text-align: center;
- top: 5px;
- white-space: nowrap;
- z-index: 600; /* Must be below the overlay pane (1000). */
-}
-
-.tooltip::after,
-.tooltip::before {
- border-left: 5px solid transparent;
- border-right: 5px solid transparent;
- border-top: transparent;
- content: '';
- display: block;
- margin-left: -5px;
- position: absolute;
- right: 24px;
- top: -5px;
-}
-
-.tooltip::after {
- border-bottom: 5px solid #2d2d2d;
-}
-
-.tooltip::before {
- border-bottom: 5px solid rgba(255, 255, 255, 0.5);
-}
-
-/* Show with delay, disappear instantly */
-@-webkit-keyframes tooltip-show {
- 0% { opacity: 0; }
- 90% { opacity: 0; }
- 100% { opacity: 1; }
-}
-
-:hover > .tooltip {
- -webkit-animation-duration: 800ms;
- -webkit-animation-iteration-count: 1;
- -webkit-animation-name: tooltip-show;
- -webkit-animation-timing-function: linear;
- opacity: 1;
-}
-
-#no-search-results {
- bottom: 0;
- display: none;
- left: 0;
- padding: 10px;
- position: absolute;
- right: 0;
- top: 28px; /* Leave room for the file list header. */
-}
-
-.dialog-container:not([drive-welcome='page']) #no-search-results[show] {
- display: block;
-}
-
-#volume-space-info-contents {
- -webkit-box-align: center;
- display: -webkit-box;
-}
-
-#volume-space-info-contents > div {
- -webkit-box-flex: 1;
- -webkit-margin-start: 15px;
- display: -webkit-box;
-}
-
-#list-container .table-header-inner {
- height: 100%;
-}
-
-#list-container .table-header-cell:hover {
- background-color: inherit;
-}
-
-#list-container .table-header-cell:first-child {
- -webkit-box-sizing: border-box;
- -webkit-padding-start: 8px;
-}
-
-button:focus {
- outline-color: rgb(77, 144, 254);
-}
-
-#new-folder-button {
- margin-right: 30px;
-}
-
-#default-action-dialog {
- min-width: 300px;
- width: auto;
-}
-
-.drive-welcome-wrapper {
- /* drive_welcome.css will override it once loaded. */
- display: none;
-}
-
-list.autocomplete-suggestions {
- -webkit-margin-before: -7px;
- -webkit-margin-start: -38px;
- background-color: rgb(250, 250, 250);
- border-radius: 3px;
- box-shadow: 0 1px 4px 0 rgba(0, 0, 0, .5);
- box-sizing: border-box; /* To match the width with the search box's. */
- color: rgb(34, 34, 34);
- overflow: hidden;
- padding: 5px 0;
- position: fixed;
- width: 300px !important; /* This overrides the value specified by script. */
- z-index: 550;
-}
-
-list.autocomplete-suggestions > li {
- -webkit-box-align: center;
- display: -webkit-box;
- padding: 3px 0;
-}
-
-list.autocomplete-suggestions > li > div.detail-icon {
- -webkit-margin-end: 6px;
- -webkit-margin-start: 6px;
-}
-
-list.autocomplete-suggestions > li > div.detail-text {
- -webkit-box-flex: 1;
- overflow-x: hidden;
- text-overflow: ellipsis;
-}
-
-list.autocomplete-suggestions > li > div.detail-text em {
- color: rgb(150, 150, 150);
- font-style: normal;
-}
-
-list.autocomplete-suggestions > li > div[search-icon] {
- background: -webkit-image-set(
- url('../images/files/ui/search_icon_active.png') 1x,
- url('../images/files/ui/2x/search_icon_active.png') 2x);
- background-position: center;
- background-repeat: no-repeat;
-}
-
-list.autocomplete-suggestions > li[selected] > div[search-icon],
-list.autocomplete-suggestions > li[lead] > div[search-icon] {
- -webkit-filter: brightness(0) invert();
-}
-
-list.autocomplete-suggestions > [selected],
-list.autocomplete-suggestions > [lead] {
- background-color: rgb(66, 129, 244);
- color: white;
-}
-
-list.autocomplete-suggestions > [selected] > div.detail-text em,
-list.autocomplete-suggestions > [lead] > div.detail-text em {
- color: white;
-}
-
-#gear-menu {
- margin-top: 8px;
-}
-
-#gear-menu > menuitem:not(.menuitem-button) {
- margin-right: 50px;
-}
-
-/* View buttons in the gear menu. */
-
-menuitem#detail-view {
- background-image: -webkit-image-set(
- url('../images/files/ui/button_list_view.png') 1x,
- url('../images/files/ui/2x/button_list_view.png') 2x);
-}
-
-menuitem#detail-view[selected]:not([disabled]),
-menuitem#detail-view[lead]:not([disabled]) {
- background-image: -webkit-image-set(
- url('../images/files/ui/button_list_view_white.png') 1x,
- url('../images/files/ui/2x/button_list_view_white.png') 2x);
-}
-
-menuitem#thumbnail-view {
- background-image: -webkit-image-set(
- url('../images/files/ui/button_mosaic_view.png') 1x,
- url('../images/files/ui/2x/button_mosaic_view.png') 2x);
-}
-
-menuitem#thumbnail-view[selected]:not([disabled]),
-menuitem#thumbnail-view[lead]:not([disabled]) {
- background-image: -webkit-image-set(
- url('../images/files/ui/button_mosaic_view_white.png') 1x,
- url('../images/files/ui/2x/button_mosaic_view_white.png') 2x);
-}
-
-#iframe-drag-area {
- -webkit-app-region: drag;
- height: 48px;
- left: 64px;
- position: absolute;
- right: 92px;
- top: 0;
- width: auto;
- z-index: 101;
-}
-
-#suggest-app-dialog {
- background-color: #fff;
- border: 0;
- padding: 0;
- width: auto;
-}
-
-#suggest-app-dialog .cr-dialog-title {
- /* Entire height: 44px (content-box 22px + padding 11px * 2) */
- font-size: 16px;
- height: 22px;
- margin: 0;
- padding: 11px 18px;
-}
-
-#suggest-app-dialog #webview-container {
- border-bottom: solid 1px #bbb;
- border-top: solid 1px #bbb;
- position: relative;
-}
-
-#suggest-app-dialog.show-spinner #webview-container webview {
- pointer-events: none;
-}
-
-#suggest-app-dialog:not(.show-spinner) .spinner-layer {
- display: none;
-}
-
-#suggest-app-dialog .spinner-layer {
- background-color: rgba(255, 255, 255, 0.7);
-}
-
-#suggest-app-dialog .cr-dialog-buttons,
-#suggest-app-dialog .cr-dialog-ok,
-#suggest-app-dialog .cr-dialog-cancel {
- display: none;
-}
-
-#suggest-app-dialog .cr-dialog-text {
- -webkit-padding-after: 10px;
- -webkit-padding-before: 0;
- -webkit-padding-end: 20px;
- -webkit-padding-start: 20px;
- margin: 0;
-}
-
-#suggest-app-dialog #buttons {
- background: #eee;
- width: 100%;
-}
-
-#suggest-app-dialog #buttons > #webstore-button {
- -webkit-padding-after: 10px;
- -webkit-padding-before: 10px;
- -webkit-padding-end: 10px;
- -webkit-padding-start: 36px;
- background-image: -webkit-image-set(
- url('chrome://theme/IDR_WEBSTORE_ICON_16') 1x,
- url('chrome://theme/IDR_WEBSTORE_ICON_16@2x') 2x);
- background-position: 12px center;
- background-repeat: no-repeat;
- color: #00f;
- cursor: pointer;
- display: inline-block;
- height: 16px;
-}
-
-.cr-dialog-frame.error-dialog-frame {
- width: 300px;
-}
-
-.error-dialog-frame .error-dialog-img {
- background-image: -webkit-image-set(
- url('chrome://theme/IDR_ERROR_NETWORK_GENERIC') 1x,
- url('chrome://theme/IDR_ERROR_NETWORK_GENERIC@2x') 2x);
- background-position: center;
- background-repeat: no-repeat;
- height: 40px;
-}
-
-.error-dialog-frame .cr-dialog-cancel {
- display: none;
-}
-
-.error-dialog-frame .cr-dialog-close,
-.error-dialog-frame .cr-dialog-title {
- display: none;
-}
-
-.error-dialog-frame .cr-dialog-text {
- text-align: center;
-}
-
-.cr-dialog-frame.share-dialog-frame {
- background-color: white;
- width: auto;
-}
-
-.share-dialog-webview-wrapper {
- height: 100px;
- margin-top: 10px;
- min-width: 300px;
- overflow: hidden;
- transition: height 200ms ease;
-}
-
-.share-dialog-webview {
- height: 100%;
- width: 100%;
-}
-
-.share-dialog-webview-wrapper:not(.loaded) .share-dialog-webview {
- visibility: hidden;
-}
-
-.share-dialog-frame .cr-dialog-text,
-.share-dialog-frame .cr-dialog-buttons {
- display: none;
-}
-
-#conflict-confirm-dialog .cr-dialog-buttons {
- align-items: baseline;
- display: flex;
-}
-
-#conflict-confirm-dialog input[type=checkbox] {
- -webkit-margin-start: -2px;
- width: auto;
-}
-
-#conflict-confirm-dialog label {
- flex: 1 0 auto;
-}
-
-/* Progress center */
-
-@-webkit-keyframes progress-center-toggle {
- /* Height values of each frame are set by script. */
- from {
- }
- to {
- }
-}
-
-#progress-center {
- background-color: transparent;
- border-top: 1px solid transparent;
- overflow: hidden;
- position: relative;
- transition: background-color 300ms linear,
- border 300ms linear;
-}
-
-#progress-center.opened {
- background-color: #ebebeb;
- border-top: 1px solid #d8d8d8;
-}
-
-#progress-center.animated {
- -webkit-animation: progress-center-toggle 300ms ease-out;
-}
-
-#progress-center-open-view {
- opacity: 1;
- padding-top: 42px;
- transition: opacity 300ms linear;
-}
-
-#progress-center:not(.opened) #progress-center-open-view {
- opacity: 0;
- pointer-events: none;
- position: absolute;
-}
-
-#progress-center-close-view {
- opacity: 1;
- transition: opacity 300ms linear;
-}
-
-#progress-center.opened #progress-center-close-view {
- opacity: 0;
- pointer-events: none;
- position: absolute;
-}
-
-#progress-center.animated #progress-center-open-view,
-#progress-center.animated #progress-center-close-view {
- left: 0;
- pointer-events: none;
- position: absolute;
- right: 0;
- top: 0;
- z-index: 1;
-}
-
-#progress-center li {
- display: block;
- min-height: 29px; /* label 17px + frame 12px */
- padding-bottom: 20px;
-}
-
-#progress-center label {
- color: #777;
- display: block;
- font: 12px/17px normal;
- min-height: 17px;
- overflow: hidden;
- padding: 0 20px;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-#progress-center li.error label {
- white-space: normal;
-}
-
-#progress-center .progress-frame {
- -webkit-padding-end: 10px;
- -webkit-padding-start: 20px;
- align-items: center;
- display: flex;
- margin-top: 4px;
-}
-
-#progress-center li.error .progress-frame {
- height: 0;
-}
-
-#progress-center .progress-bar {
- -webkit-margin-end: 24px;
- background: #d8d8d8;
- border-radius: 3px;
- flex: 1 0 0;
- height: 6px;
- opacity: 1;
- overflow: hidden;
-}
-
-#progress-center li.error .progress-bar,
-#progress-center li.canceled .progress-bar {
- visibility: hidden;
-}
-
-#progress-center .progress-track {
- background: #787878;
- height: 100%;
-}
-
-#progress-center .progress-track.animated {
- transition: width 300ms linear;
-}
-
-#progress-center button {
- background: orange;
- border: none;
- cursor: pointer;
- flex: 0 0 auto;
- height: 12px;
- min-height: 0;
- min-width: 0;
- outline: none;
- padding: 0;
- width: 12px;
- z-index: 0;
-}
-
-#progress-center button.toggle {
- background: -webkit-image-set(
- url(../images/files/ui/process_drawer_button_opened.png) 1x,
- url(../images/files/ui/2x/process_drawer_button_opened.png) 2x)
- no-repeat;
- position: absolute;
- right: 10px;
- top: 17px; /* label height */
- transition: top 300ms ease-out;
- z-index: 1;
-}
-
-#progress-center button.toggle:hover {
- background: -webkit-image-set(
- url(../images/files/ui/process_drawer_button_opened_hover.png) 1x,
- url(../images/files/ui/2x/process_drawer_button_opened_hover.png) 2x)
- no-repeat;
-}
-
-#progress-center button.toggle:active {
- background: -webkit-image-set(
- url(../images/files/ui/process_drawer_button_opened_pressed.png) 1x,
- url(../images/files/ui/2x/process_drawer_button_opened_pressed.png) 2x)
- no-repeat;
-}
-
-/*
- * If the closed progress center has only one item,
- * toggle button turned into cancel button the item.
- */
-#progress-center:not(.opened) #progress-center-close-view.single ~
- button.toggle,
-#progress-center button.cancel {
- background: -webkit-image-set(
- url(../images/files/ui/close_bar.png) 1x,
- url(../images/files/ui/2x/close_bar.png) 2x)
- no-repeat;
-}
-
-#progress-center:not(.opened)
- #progress-center-close-view.single:not(.cancelable) button.toggle,
-#progress-center li:not(.cancelable) button.cancel {
- visibility: hidden;
-}
-
-#progress-center.opened button.toggle {
- background: -webkit-image-set(
- url(../images/files/ui/process_drawer_button_closed.png) 1x,
- url(../images/files/ui/2x/process_drawer_button_closed.png) 2x)
- no-repeat;
- top: 10px;
-}
-
-#progress-center.opened button.toggle:hover {
- background: -webkit-image-set(
- url(../images/files/ui/process_drawer_button_closed_hover.png) 1x,
- url(../images/files/ui/2x/process_drawer_button_closed_hover.png) 2x)
- no-repeat;
-}
-
-#progress-center.opened button.toggle:active {
- background: -webkit-image-set(
- url(../images/files/ui/process_drawer_button_closed_pressed.png) 1x,
- url(../images/files/ui/2x/process_drawer_button_closed_pressed.png) 2x)
- no-repeat;
-}
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/css/file_types.css b/chromium/chrome/browser/resources/file_manager/foreground/css/file_types.css
deleted file mode 100644
index 75603497f07..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/css/file_types.css
+++ /dev/null
@@ -1,477 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-/* Small icons for file types, used in lists and menus. */
-[file-type-icon] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/generic.png') 1x,
- url('../../common/images/file_types/200/generic.png') 2x);
- background-position: center;
- background-repeat: no-repeat;
-}
-
-tree:focus .tree-item[selected] > .tree-row > [file-type-icon],
-list:focus [selected] [file-type-icon],
-list.autocomplete-suggestions [selected] [file-type-icon] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/generic_white.png') 1x,
- url('../../common/images/file_types/200/generic_white.png') 2x);
-}
-
-[file-type-icon='archive'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/archive.png') 1x,
- url('../../common/images/file_types/200/archive.png') 2x);
-}
-
-tree:focus .tree-item[selected] > .tree-row > [file-type-icon='archive'],
-list:focus [selected] [file-type-icon='archive'],
-list.autocomplete-suggestions [selected] [file-type-icon='archive'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/archive_white.png') 1x,
- url('../../common/images/file_types/200/archive_white.png') 2x);
-}
-
-[file-type-icon='audio'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/audio.png') 1x,
- url('../../common/images/file_types/200/audio.png') 2x);
-}
-
-tree:focus .tree-item[selected] > .tree-row > [file-type-icon='audio'],
-list:focus [selected] [file-type-icon='audio'],
-list.autocomplete-suggestions [selected] [file-type-icon='audio'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/audio_white.png') 1x,
- url('../../common/images/file_types/200/audio_white.png') 2x);
-}
-
-[file-type-icon='excel'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/excel.png') 1x,
- url('../../common/images/file_types/200/excel.png') 2x);
-}
-
-tree:focus .tree-item[selected] > .tree-row > [file-type-icon='excel'],
-list:focus [selected] [file-type-icon='excel'],
-list.autocomplete-suggestions [selected] [file-type-icon='excel'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/excel_white.png') 1x,
- url('../../common/images/file_types/200/excel_white.png') 2x);
-}
-
-[file-type-icon='folder'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/folder.png') 1x,
- url('../../common/images/file_types/200/folder.png') 2x);
-}
-
-tree:focus .tree-item[selected] > .tree-row > [file-type-icon='folder'],
-list:focus [selected] [file-type-icon='folder'],
-list.autocomplete-suggestions [selected] [file-type-icon='folder'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/folder_white.png') 1x,
- url('../../common/images/file_types/200/folder_white.png') 2x);
-}
-
-[file-type-icon='form'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/form.png') 1x,
- url('../../common/images/file_types/200/form.png') 2x);
-}
-
-tree:focus .tree-item[selected] > .tree-row > [file-type-icon='form'],
-list:focus [selected] [file-type-icon='form'],
-list.autocomplete-suggestions [selected] [file-type-icon='form'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/form_white.png') 1x,
- url('../../common/images/file_types/200/form_white.png') 2x);
-}
-
-[file-type-icon='gdoc'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/gdoc.png') 1x,
- url('../../common/images/file_types/200/gdoc.png') 2x);
-}
-
-tree:focus .tree-item[selected] > .tree-row > [file-type-icon='gdoc'],
-list:focus [selected] [file-type-icon='gdoc'],
-list.autocomplete-suggestions [selected] [file-type-icon='gdoc'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/gdoc_white.png') 1x,
- url('../../common/images/file_types/200/gdoc_white.png') 2x);
-}
-
-[file-type-icon='gdraw'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/gdraw.png') 1x,
- url('../../common/images/file_types/200/gdraw.png') 2x);
-}
-
-tree:focus .tree-item[selected] > .tree-row > [file-type-icon='gdraw'],
-list:focus [selected] [file-type-icon='gdraw'],
-list.autocomplete-suggestions [selected] [file-type-icon='gdraw'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/gdraw_white.png') 1x,
- url('../../common/images/file_types/200/gdraw_white.png') 2x);
-}
-
-[file-type-icon='glink'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/glink.png') 1x,
- url('../../common/images/file_types/200/glink.png') 2x);
-}
-
-tree:focus .tree-item[selected] > .tree-row > [file-type-icon='glink'],
-list:focus [selected] [file-type-icon='glink'],
-list.autocomplete-suggestions [selected] [file-type-icon='glink'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/glink_white.png') 1x,
- url('../../common/images/file_types/200/glink_white.png') 2x);
-}
-
-[file-type-icon='gsheet'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/gsheet.png') 1x,
- url('../../common/images/file_types/200/gsheet.png') 2x);
-}
-
-tree:focus .tree-item[selected] > .tree-row > [file-type-icon='gsheet'],
-list:focus [selected] [file-type-icon='gsheet'],
-list.autocomplete-suggestions [selected] [file-type-icon='gsheet'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/gsheet_white.png') 1x,
- url('../../common/images/file_types/200/gsheet_white.png') 2x);
-}
-
-[file-type-icon='gslides'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/gslides.png') 1x,
- url('../../common/images/file_types/200/gslides.png') 2x);
-}
-
-tree:focus .tree-item[selected] > .tree-row > [file-type-icon='gslides'],
-list:focus [selected] [file-type-icon='gslides'],
-list.autocomplete-suggestions [selected] [file-type-icon='gslides'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/gslides_white.png') 1x,
- url('../../common/images/file_types/200/gslides_white.png') 2x);
-}
-
-[file-type-icon='gtable'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/gtable.png') 1x,
- url('../../common/images/file_types/200/gtable.png') 2x);
-}
-
-tree:focus .tree-item[selected] > .tree-row > [file-type-icon='gtable'],
-list:focus [selected] [file-type-icon='gtable'],
-list.autocomplete-suggestions [selected] [file-type-icon='gtable'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/gtable_white.png') 1x,
- url('../../common/images/file_types/200/gtable_white.png') 2x);
-}
-
-[file-type-icon='gform'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/form.png') 1x,
- url('../../common/images/file_types/200/form.png') 2x);
-}
-
-tree:focus .tree-item[selected] > .tree-row > [file-type-icon='gform'],
-list:focus [selected] [file-type-icon='gform'],
-list.autocomplete-suggestions [selected] [file-type-icon='gform'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/form_white.png') 1x,
- url('../../common/images/file_types/200/form_white.png') 2x);
-}
-
-[file-type-icon='image'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/image.png') 1x,
- url('../../common/images/file_types/200/image.png') 2x);
-}
-
-tree:focus .tree-item[selected] > .tree-row > [file-type-icon='image'],
-list:focus [selected] [file-type-icon='image'],
-list.autocomplete-suggestions [selected] [file-type-icon='image'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/image_white.png') 1x,
- url('../../common/images/file_types/200/image_white.png') 2x);
-}
-
-[file-type-icon='pdf'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/pdf.png') 1x,
- url('../../common/images/file_types/200/pdf.png') 2x);
-}
-
-tree:focus .tree-item[selected] > .tree-row > [file-type-icon='pdf'],
-list:focus [selected] [file-type-icon='pdf'],
-list.autocomplete-suggestions [selected] [file-type-icon='pdf'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/pdf_white.png') 1x,
- url('../../common/images/file_types/200/pdf_white.png') 2x);
-}
-
-[file-type-icon='ppt'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/ppt.png') 1x,
- url('../../common/images/file_types/200/ppt.png') 2x);
-}
-
-tree:focus .tree-item[selected] > .tree-row > [file-type-icon='ppt'],
-list:focus [selected] [file-type-icon='ppt'],
-list.autocomplete-suggestions [selected] [file-type-icon='ppt'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/ppt_white.png') 1x,
- url('../../common/images/file_types/200/ppt_white.png') 2x);
-}
-
-[file-type-icon='script'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/script.png') 1x,
- url('../../common/images/file_types/200/script.png') 2x);
-}
-
-tree:focus .tree-item[selected] > .tree-row > [file-type-icon='script'],
-list:focus [selected] [file-type-icon='script'],
-list.autocomplete-suggestions [selected] [file-type-icon='script'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/script_white.png') 1x,
- url('../../common/images/file_types/200/script_white.png') 2x);
-}
-
-[file-type-icon='sites'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/sites.png') 1x,
- url('../../common/images/file_types/200/sites.png') 2x);
-}
-
-tree:focus .tree-item[selected] > .tree-row > [file-type-icon='sites'],
-list:focus [selected] [file-type-icon='sites'],
-list.autocomplete-suggestions [selected] [file-type-icon='sites'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/sites_white.png') 1x,
- url('../../common/images/file_types/200/sites_white.png') 2x);
-}
-
-[file-type-icon='video'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/video.png') 1x,
- url('../../common/images/file_types/200/video.png') 2x);
-}
-
-tree:focus .tree-item[selected] > .tree-row > [file-type-icon='video'],
-list:focus [selected] [file-type-icon='video'],
-list.autocomplete-suggestions [selected] [file-type-icon='video'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/video_white.png') 1x,
- url('../../common/images/file_types/200/video_white.png') 2x);
-}
-
-[file-type-icon='word'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/word.png') 1x,
- url('../../common/images/file_types/200/word.png') 2x);
-}
-
-tree:focus .tree-item[selected] > .tree-row > [file-type-icon='word'],
-list:focus [selected] [file-type-icon='word'],
-list.autocomplete-suggestions [selected] [file-type-icon='word'] {
- background-image: -webkit-image-set(
- url('../../common/images/file_types/100/word_white.png') 1x,
- url('../../common/images/file_types/200/word_white.png') 2x);
-}
-
-[file-type-icon='drive'] {
- background-image: -webkit-image-set(
- url('chrome://theme/IDR_FILE_MANAGER_IMG_FILETYPE_DRIVE') 1x,
- url('chrome://theme/IDR_FILE_MANAGER_IMG_FILETYPE_DRIVE@2x') 2x);
-}
-
-/* Large generic thumbnails, used when a file does not have a thumbnail. */
-[generic-thumbnail] {
- background-image: -webkit-image-set(
- url('chrome://theme/IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_GENERIC') 1x,
- url('chrome://theme/IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_GENERIC@2x') 2x);
- background-position: center center;
- background-repeat: no-repeat;
-}
-
-[generic-thumbnail='audio'] {
- background-image: -webkit-image-set(
- url('chrome://theme/IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_AUDIO') 1x,
- url('chrome://theme/IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_AUDIO@2x') 2x);
-}
-
-[generic-thumbnail='folder'] {
- background-image: -webkit-image-set(
- url('chrome://theme/IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_FOLDER') 1x,
- url('chrome://theme/IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_FOLDER@2x') 2x);
-}
-
-[generic-thumbnail='image'] {
- background-image: -webkit-image-set(
- url('chrome://theme/IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_IMAGE') 1x,
- url('chrome://theme/IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_IMAGE@2x') 2x);
-}
-
-[generic-thumbnail='video'] {
- background-image: -webkit-image-set(
- url('chrome://theme/IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_VIDEO') 1x,
- url('chrome://theme/IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_VIDEO@2x') 2x);
-}
-
-/* Icons for volume types. */
-
-[volume-type-icon='archive'] {
- background-image: -webkit-image-set(
- url('../images/volumes/black_archive.png') 1x,
- url('../images/volumes/2x/black_archive.png') 2x);
-}
-
-list:focus li[selected] [volume-type-icon='archive'],
-tree:focus .tree-item[selected] > .tree-row > [volume-type-icon='archive'] {
- background-image: -webkit-image-set(
- url('../images/volumes/white_archive.png') 1x,
- url('../images/volumes/2x/white_archive.png') 2x);
-}
-
-[volume-type-icon='downloads'] {
- background-image: -webkit-image-set(
- url('../images/volumes/black_downloads.png') 1x,
- url('../images/volumes/2x/black_downloads.png') 2x);
-}
-
-list:focus li[selected] [volume-type-icon='downloads'],
-tree:focus .tree-item[selected] > .tree-row > [volume-type-icon='downloads'] {
- background-image: -webkit-image-set(
- url('../images/volumes/white_downloads.png') 1x,
- url('../images/volumes/2x/white_downloads.png') 2x);
-}
-
-[volume-type-icon='drive'] {
- background-image: -webkit-image-set(
- url('../images/volumes/black_drive.png') 1x,
- url('../images/volumes/2x/black_drive.png') 2x);
-}
-
-list:focus li[selected] [volume-type-icon='drive'],
-tree:focus .tree-item[selected] > .tree-row > [volume-type-icon='drive'] {
- background-image: -webkit-image-set(
- url('../images/volumes/white_drive.png') 1x,
- url('../images/volumes/2x/white_drive.png') 2x);
-}
-
-[volume-type-icon='drive_offline'] {
- background-image: -webkit-image-set(
- url('../images/volumes/black_offline.png') 1x,
- url('../images/volumes/2x/black_offline.png') 2x);
-}
-
-list:focus li[selected] [volume-type-icon='drive_offline'],
-tree:focus .tree-item[selected] > .tree-row >
- [volume-type-icon='drive_offline'] {
- background-image: -webkit-image-set(
- url('../images/volumes/white_offline.png') 1x,
- url('../images/volumes/2x/white_offline.png') 2x);
-}
-
-[volume-type-icon='drive_shared_with_me'] {
- background-image: -webkit-image-set(
- url('../images/volumes/black_shared.png') 1x,
- url('../images/volumes/2x/black_shared.png') 2x);
-}
-
-list:focus li[selected] [volume-type-icon='drive_shared_with_me'],
-tree:focus .tree-item[selected] > .tree-row >
- [volume-type-icon='drive_shared_with_me'] {
- background-image: -webkit-image-set(
- url('../images/volumes/white_shared.png') 1x,
- url('../images/volumes/2x/white_shared.png') 2x);
-}
-
-[volume-type-icon='drive_recent'] {
- background-image: -webkit-image-set(
- url('../images/volumes/black_recent.png') 1x,
- url('../images/volumes/2x/black_recent.png') 2x);
-}
-
-list:focus li[selected] [volume-type-icon='drive_recent'],
-tree:focus .tree-item[selected] > .tree-row >
- [volume-type-icon='drive_recent'] {
- background-image: -webkit-image-set(
- url('../images/volumes/white_recent.png') 1x,
- url('../images/volumes/2x/white_recent.png') 2x);
-}
-
-[volume-type-icon='removable'] {
- background-image: -webkit-image-set(
- url('../images/volumes/black_usb.png') 1x,
- url('../images/volumes/2x/black_usb.png') 2x);
-}
-
-list:focus li[selected] [volume-type-icon='removable'],
-tree:focus .tree-item[selected] > .tree-row >
- [volume-type-icon='removable'] {
- background-image: -webkit-image-set(
- url('../images/volumes/white_usb.png') 1x,
- url('../images/volumes/2x/white_usb.png') 2x);
-}
-
-[volume-type-icon='removable'][volume-subtype='sd'] {
- background-image: -webkit-image-set(
- url('../images/volumes/black_sd.png') 1x,
- url('../images/volumes/2x/black_sd.png') 2x);
-}
-
-list:focus li[selected] [volume-type-icon='removable'][volume-subtype='sd'],
-tree:focus .tree-item[selected] > .tree-row >
- [volume-type-icon='removable'][volume-subtype='sd'] {
- background-image: -webkit-image-set(
- url('../images/volumes/white_sd.png') 1x,
- url('../images/volumes/2x/white_sd.png') 2x);
-}
-
-[volume-type-icon='removable'][volume-subtype='optical'] {
- background-image: -webkit-image-set(
- url('../images/volumes/black_optical.png') 1x,
- url('../images/volumes/2x/black_optical.png') 2x);
-}
-
-list:focus div[selected]
- [volume-type-icon='removable'][volume-subtype='optical'],
-tree:focus .tree-item[selected] > .tree-row >
- [volume-type-icon='removable'][volume-subtype='optical'] {
- background-image: -webkit-image-set(
- url('../images/volumes/white_optical.png') 1x,
- url('../images/volumes/2x/white_optical.png') 2x);
-}
-
-list:focus li[selected]
- [volume-type-icon='removable'][volume-subtype='optical'],
-tree:focus .tree-item[selected] > .tree-row >
- [volume-type-icon='removable'][volume-subtype='optical'] {
- background-image: -webkit-image-set(
- url('../images/volumes/white_optical.png') 1x,
- url('../images/volumes/2x/white_optical.png') 2x);
-}
-
-/* TODO(kaznacheev): consider a better icon for volume-subtype=unknown.
- Also find out if we need an icon for volume-subtype=mobile */
-[volume-type-icon='removable'][volume-subtype='unknown'] {
- background-image: -webkit-image-set(
- url('../images/volumes/black_hdd.png') 1x,
- url('../images/volumes/2x/black_hdd.png') 2x);
-}
-
-list:focus li[selected]
- [volume-type-icon='removable'][volume-subtype='unknown'],
-tree:focus .tree-item[selected] > .tree-row >
- [volume-type-icon='removable'][volume-subtype='unknown'] {
- background-image: -webkit-image-set(
- url('../images/volumes/white_hdd.png') 1x,
- url('../images/volumes/2x/white_hdd.png') 2x);
-}
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/css/gallery.css b/chromium/chrome/browser/resources/file_manager/foreground/css/gallery.css
deleted file mode 100644
index 7680f4d3100..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/css/gallery.css
+++ /dev/null
@@ -1,1374 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-body {
- -webkit-user-select: none;
- font-family: Open Sans, Droid Sans Fallback, sans-serif;
- font-size: 84%;
- margin: 0;
-}
-
-.gallery,
-.gallery .content {
- bottom: 0;
- left: 0;
- overflow: hidden;
- position: absolute;
- right: 0;
- top: 0;
-}
-
-/* Common background for both mosaic and slide mode. */
-.gallery .content {
- background-color: black;
-}
-
-/* Close button */
-
-/* We actually want (left,top) to be (0,0) but for some weird reason
- this triggers :hover style on page reload which is ugly. */
-.gallery > .back-button {
- cursor: pointer;
- left: 1px;
- position: absolute;
- top: 1px;
- z-index: 200;
-}
-
-/* The close icon is in a nested div so that its opacity can be manipulated
- independently from its parent (which can be dimmed when the crop frame
- overlaps it) */
-.gallery > .back-button div {
- background-image: -webkit-image-set(
- url('../images/gallery/back_to_files.png') 1x,
- url('../images/gallery/2x/back_to_files.png') 2x);
- background-position: center center;
- background-repeat: no-repeat;
- height: 40px;
- opacity: 0;
- width: 64px;
-}
-
-.gallery[tools] > .back-button div {
- opacity: 0.5;
-}
-
-.gallery[tools] > .back-button div:hover {
- opacity: 1;
-}
-
-/* Image container and canvas elements */
-
-.gallery .image-container {
- cursor: none; /* Only visible when the toolbar is active */
- height: 100%;
- position: absolute;
- width: 100%;
-}
-
-.gallery[tools] .image-container[cursor='default'] {
- cursor: default;
-}
-
-.gallery[tools] .image-container[cursor='move'] {
- cursor: -webkit-image-set(
- url('../images/gallery/cursor_move.png') 1x,
- url('../images/gallery/2x/cursor_move.png') 2x) 15 15, auto;
-}
-
-.gallery[tools] .image-container[cursor='crop'] {
- cursor: -webkit-image-set(
- url('../images/gallery/cursor_crop.png') 1x,
- url('../images/gallery/2x/cursor_crop.png') 2x) 15 15, auto;
-}
-
-.gallery[tools] .image-container[cursor='n-resize'],
-.gallery[tools] .image-container[cursor='s-resize'] {
- cursor: -webkit-image-set(
- url('../images/gallery/cursor_updown.png') 1x,
- url('../images/gallery/2x/cursor_updown.png') 2x) 15 15, auto;
-}
-
-.gallery[tools] .image-container[cursor='e-resize'],
-.gallery[tools] .image-container[cursor='w-resize'] {
- cursor: -webkit-image-set(
- url('../images/gallery/cursor_leftright.png') 1x,
- url('../images/gallery/2x/cursor_leftright.png') 2x) 15 15, auto;
-}
-
-.gallery[tools] .image-container[cursor='nw-resize'],
-.gallery[tools] .image-container[cursor='se-resize'] {
- cursor: -webkit-image-set(
- url('../images/gallery/cursor_nwse.png') 1x,
- url('../images/gallery/2x/cursor_nwse.png') 2x) 15 15, auto;
-}
-
-.gallery[tools] .image-container[cursor='ne-resize'],
-.gallery[tools] .image-container[cursor='sw-resize'] {
- cursor: -webkit-image-set(
- url('../images/gallery/cursor_swne.png') 1x,
- url('../images/gallery/2x/cursor_swne.png') 2x) 15 15, auto;
-}
-
-.gallery .image-container > .image {
- pointer-events: none;
- position: absolute;
- /* Duration and timing function are set in Javascript. */
- transition-property: -webkit-transform, opacity;
-}
-
-.gallery .image-container > .image[fade] {
- opacity: 0;
-}
-
-/* Full resolution image is invisible unless printing. */
-.gallery .image-container > canvas.fullres {
- display: none;
-}
-
-@media print {
- /* Do not print anything but the image content. */
- .gallery > :not(.content) {
- display: none !important;
- }
-
- /* Center the printed image. */
- .gallery .image-container {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: center;
- display: -webkit-box;
- }
-
- /* Do not print the screen resolution image. */
- .gallery .image-container > canvas.image {
- display: none !important;
- }
-
- /* Print the full resolution image instead. */
- .gallery .image-container > canvas.fullres {
- display: block !important;
- max-height: 100%;
- max-width: 100%;
- }
-
- /* Print video at the center of the page */
- .gallery .image-container > video.image {
- position: auto !important;
- }
-}
-
-/* Toolbar */
-
-.gallery > .header,
-.gallery > .toolbar {
- -webkit-box-align: stretch;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: start;
- background-color: rgba(30, 30, 30, 0.8);
- display: -webkit-box;
- left: 0;
- opacity: 0;
- padding: 0 10px;
- pointer-events: none;
- position: absolute;
- right: 0;
- transition: opacity 300ms ease;
-}
-
-.gallery > .header {
- -webkit-box-align: center;
- -webkit-box-pack: end;
- border-bottom: 1px solid rgba(50, 50, 50, 0.8);
- display: -webkit-box;
- height: 45px;
- top: 0;
-}
-
-.gallery > .toolbar {
- border-top: 1px solid rgba(50, 50, 50, 0.8);
- bottom: 0;
- height: 55px;
- min-width: 800px;
-}
-
-.gallery[tools]:not([slideshow]) > .header,
-.gallery[tools]:not([slideshow]) > .toolbar {
- opacity: 1;
- pointer-events: auto;
-}
-
-/* Hide immediately when entering the slideshow. */
-.gallery[tools][slideshow] > .toolbar {
- transition-duration: 0;
-}
-
-.gallery[tools][locked] > .toolbar {
- pointer-events: none;
-}
-
-.gallery .arrow-box {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: center;
- display: -webkit-box;
- height: 100%;
- pointer-events: none;
- position: absolute;
- width: 100%;
- z-index: 100;
-}
-
-.gallery .arrow-box .arrow {
- opacity: 0;
- pointer-events: none;
-}
-
-.gallery .arrow-box .arrow-spacer {
- -webkit-box-flex: 1;
- pointer-events: none;
-}
-
-.gallery[tools] .arrow-box[active] .arrow {
- cursor: pointer;
- opacity: 1;
- pointer-events: auto;
-}
-
-/* The arrow icons are in nested divs so that their opacity can be manipulated
- * independently from their parent (which can be dimmed when the crop frame
- * overlaps it) */
-.gallery .arrow div {
- background-position: center center;
- background-repeat: no-repeat;
- height: 193px;
- opacity: 0;
- width: 105px;
-}
-
-.gallery[tools] .arrow-box[active] .arrow div {
- opacity: 0.25;
-}
-
-.gallery[tools] .arrow-box[active] .arrow div:hover {
- opacity: 1;
-}
-
-.gallery .arrow.left div {
- background-image: -webkit-image-set(
- url('../images/gallery/arrow_left.png') 1x,
- url('../images/gallery/2x/arrow_left.png') 2x);
-}
-
-.gallery .arrow.right div {
- background-image: -webkit-image-set(
- url('../images/gallery/arrow_right.png') 1x,
- url('../images/gallery/2x/arrow_right.png') 2x);
-}
-
-/* Special behavior on mouse drag.
- Redundant .gallery attributes included to make the rules more specific */
-
-/* Everything but the image container should become mouse-transparent */
-.gallery[tools][editing][mousedrag] * {
- pointer-events: none;
-}
-
-.gallery[tools][editing][mousedrag] .image-container {
- pointer-events: auto;
-}
-
-/* The editor marks elements with 'dimmed' attribute to get them out of the way
- of the crop frame */
-.gallery[tools][editing] [dimmed],
-.gallery[tools][editing] [dimmed] * {
- pointer-events: none;
-}
-
-.gallery[tools][editing] [dimmed] {
- opacity: 0.2;
-}
-
-/* Filename */
-
-.gallery .filename-spacer {
- position: relative;
- width: 270px;
-}
-
-.gallery .filename-spacer > * {
- background-color: transparent;
- overflow: hidden;
- position: absolute;
- transition: visibility 0 linear 180ms, all 180ms linear;
- width: 260px;
-}
-
-.gallery .filename-spacer * {
- color: white;
-}
-
-.gallery .filename-spacer .namebox {
- height: 22px;
- top: 15px;
-}
-
-.gallery[editing] .filename-spacer .namebox {
- height: 21px;
- top: 5px;
-}
-
-
-.gallery .filename-spacer .namebox {
- background-color: transparent;
- border: none;
- box-sizing: border-box;
- cursor: pointer;
- display: block;
- font-size: 120%;
- outline: none;
- overflow: hidden;
- padding: 0 3px;
- position: absolute;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.gallery .filename-spacer .namebox[disabled] {
- -webkit-user-select: none;
- cursor: default;
-}
-
-.gallery .filename-spacer .namebox:not([disabled]):not(:focus):hover {
- background-color: rgba(48, 48, 48, 1.0);
-}
-
-.gallery .filename-spacer .namebox:focus {
- background-color: white;
- color: black;
- cursor: text;
-}
-
-.gallery .filename-spacer .options {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: start;
- display: -webkit-box;
- opacity: 0;
- top: 50px;
- visibility: hidden;
-}
-
-.gallery[editing] .filename-spacer .options {
- opacity: 1;
- top: 28px;
- visibility: visible;
-}
-
-.gallery .filename-spacer .saved,
-.gallery .filename-spacer .overwrite-original {
- cursor: inherit;
- font-size: 90%;
- margin-left: 3px;
- margin-right: 18px;
- opacity: 0;
- pointer-events: none;
- transition: all linear 120ms;
-}
-
-.gallery[editing] .filename-spacer .saved {
- color: white;
- opacity: 0.5;
-}
-
-.gallery[editing] .filename-spacer .overwrite-original,
-.gallery[editing] .filename-spacer .overwrite-original > * {
- cursor: pointer;
- opacity: 1;
- pointer-events: auto;
-}
-
-.gallery[editing] .options[saved] .overwrite-original {
- opacity: 0.5;
-}
-
-.gallery[editing] .options[saved] .overwrite-original,
-.gallery[editing] .options[saved] .overwrite-original > * {
- cursor: default;
- pointer-events: none;
-}
-
-.gallery .filename-spacer .overwrite-original input {
- margin-bottom: -2px;
- margin-right: 6px;
-}
-
-.gallery .filename-spacer .saved[highlighted] {
- -webkit-transform: scaleX(1.1) scaleY(1.1) rotate(0);
- opacity: 1;
-}
-
-/* Bubble */
-.gallery .toolbar .bubble {
- bottom: 65px;
- font-size: 85%;
- left: 50px;
- position: absolute;
- width: 220px;
-}
-
-.gallery:not([editing]) .toolbar .bubble {
- display: none;
-}
-
-/* Toolbar buttons */
-
-.gallery .button-spacer {
- -webkit-box-flex: 1;
- display: -webkit-box;
-}
-
-/* Thumbnails */
-
-.gallery .ribbon-spacer {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: center;
- display: -webkit-box;
- height: 100%;
- left: 280px;
- position: absolute;
- right: 280px;
-}
-
-.gallery .toolbar .ribbon {
- -webkit-box-flex: 0;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: start;
- display: -webkit-box;
- height: 100%;
- overflow: hidden;
- transition: opacity 180ms linear, visibility 0 linear;
- z-index: 0;
-}
-
-.gallery[editing] .toolbar .ribbon {
- opacity: 0;
- transition-delay: 0, 180ms;
- visibility: hidden;
-}
-
-.gallery .ribbon-image {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: center;
- border: 2px solid rgba(255, 255, 255, 0); /* transparent white */
- cursor: pointer;
- display: -webkit-box;
- height: 47px;
- margin: 2px;
- overflow: hidden;
- transition: all 180ms linear;
- width: 47px;
-}
-
-.ribbon-image[vanishing='smooth'] {
- border-left-width: 0;
- border-right-width: 0;
- margin-left: 0;
- margin-right: 0;
- width: 0;
-}
-
-.gallery .ribbon-image[selected] {
- border: 2px solid rgba(255, 233, 168, 1);
-}
-
-.gallery .toolbar .ribbon.fade-left {
- -webkit-mask-image: linear-gradient(to right, rgba(0, 0, 0, 0) 0,
- rgba(0, 0, 0, 1) 40px);
-}
-
-.gallery .toolbar .ribbon.fade-right {
- -webkit-mask-image: linear-gradient(to left, rgba(0, 0, 0, 0) 0,
- rgba(0, 0, 0, 1) 40px);
-}
-
-.gallery .toolbar .ribbon.fade-left.fade-right {
- -webkit-mask-image: linear-gradient(to right, rgba(0, 0, 0, 0) 0,
- rgba(0, 0, 0, 1) 40px,
- rgba(0, 0, 0, 1) 230px,
- rgba(0, 0, 0, 0) 100%);
-}
-
-.gallery .image-wrapper {
- background-size: 45px 45px;
- border: 1px solid rgba(0, 0, 0, 0); /* transparent black */
- height: 45px;
- overflow: hidden;
- position: relative;
- width: 45px;
-}
-
-.gallery .image-wrapper > img {
- position: absolute;
-}
-
-.gallery .image-wrapper > img:not(.cached) {
- -webkit-animation: fadeIn 500ms ease-in;
-}
-
-/* Editor buttons */
-
-.gallery .edit-bar-spacer {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: center;
- display: -webkit-box;
- height: 100%;
- left: 280px;
- opacity: 0;
- position: absolute;
- right: 280px;
- transition: opacity 180ms linear, visibility 0 linear 180ms;
- visibility: hidden;
-}
-
-.gallery .toolbar .edit-main {
- -webkit-box-orient: horizontal;
- -webkit-box-pack: center;
- color: white;
- display: -webkit-box;
- height: 55px;
- overflow: visible;
-}
-
-.gallery[editing] .edit-bar-spacer {
- opacity: 1.0;
- pointer-events: auto;
- transition-delay: 100ms, 100ms;
- visibility: visible;
-}
-
-.gallery .header button,
-.gallery .toolbar button,
-.gallery .header button[disabled],
-.gallery .toolbar button[disabled] {
- -webkit-box-align: center;
- -webkit-box-flex: 0;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: end;
- background-color: rgba(0, 0, 0, 0);
- background-position: center;
- background-repeat: no-repeat;
- border: none;
- box-shadow: none;
- color: white;
- cursor: pointer;
- display: -webkit-box;
- opacity: 0.99; /* Workaround for http://crosbug.com/21065 */
- padding: 1px; /* Instead of a border. */
- position: relative;
- z-index: 10;
-}
-
-.gallery .header button,
-.gallery .toolbar button {
- height: 40px;
- margin: 6px 0;
- min-width: 40px; /* Reset. */
- width: 40px;
-}
-
-/* By default, labels are hidden. */
-.gallery > .toolbar button span {
- display: none;
-}
-
-/* Show labels if there is enough space. */
-@media (min-width: 1180px) {
-
- .gallery .edit-main button,
- .gallery .edit-main button[disabled] {
- background-position: 5px center;
- max-width: 60px;
- min-width: 0; /* Reset. */
- padding: 0 10px 0 35px;
- width: auto;
- }
-
- .gallery > .toolbar button span {
- display: inline;
- }
-
-}
-
-.gallery .header button:hover,
-.gallery .toolbar button:hover {
- background-color: rgba(31, 31, 31, 1);
- color: white;
-}
-
-.gallery .header button:active,
-.gallery .toolbar button:active,
-.gallery .header button[pressed],
-.gallery .toolbar button[pressed],
-.gallery .header button[pressed]:hover,
-.gallery .toolbar button[pressed]:hover {
- background-color: rgba(240, 240, 240, 1);
- color: black;
-}
-
-.gallery > .toolbar button.autofix {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_autofix.png') 1x,
- url('../images/gallery/2x/icon_autofix.png') 2x);
-}
-
-.gallery > .toolbar button.autofix:active,
-.gallery > .toolbar button.autofix[pressed] {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_autofix_selected.png') 1x,
- url('../images/gallery/2x/icon_autofix_selected.png') 2x);
-}
-
-.gallery > .toolbar button.crop {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_crop.png') 1x,
- url('../images/gallery/2x/icon_crop.png') 2x);
-}
-
-.gallery > .toolbar button.crop:active,
-.gallery > .toolbar button.crop[pressed] {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_crop_selected.png') 1x,
- url('../images/gallery/2x/icon_crop_selected.png') 2x);
-}
-
-.gallery > .toolbar button.exposure {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_brightness.png') 1x,
- url('../images/gallery/2x/icon_brightness.png') 2x);
-}
-
-.gallery > .toolbar button.exposure:active,
-.gallery > .toolbar button.exposure[pressed] {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_brightness_selected.png') 1x,
- url('../images/gallery/2x/icon_brightness_selected.png') 2x);
-}
-
-.gallery > .toolbar button.rotate_right {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_rotate.png') 1x,
- url('../images/gallery/2x/icon_rotate.png') 2x);
-}
-
-.gallery > .toolbar button.rotate_right:active,
-.gallery > .toolbar button.rotate_right[pressed] {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_rotate_selected.png') 1x,
- url('../images/gallery/2x/icon_rotate_selected.png') 2x);
-}
-
-.gallery > .toolbar button.rotate_left {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_rotate_left.png') 1x,
- url('../images/gallery/2x/icon_rotate_left.png') 2x);
-}
-
-.gallery > .toolbar button.rotate_left:active,
-.gallery > .toolbar button.rotate_left[pressed] {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_rotate_left_selected.png') 1x,
- url('../images/gallery/2x/icon_rotate_left_selected.png') 2x);
-}
-
-.gallery > .toolbar button.undo {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_undo.png') 1x,
- url('../images/gallery/2x/icon_undo.png') 2x);
-}
-
-.gallery > .toolbar button.undo:active,
-.gallery > .toolbar button.undo[pressed] {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_undo_selected.png') 1x,
- url('../images/gallery/2x/icon_undo_selected.png') 2x);
-}
-
-.gallery > .toolbar button.redo {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_redo.png') 1x,
- url('../images/gallery/2x/icon_redo.png') 2x);
- position: absolute; /* Exclude from center-packing*/
-}
-
-.gallery > .toolbar button.redo:active,
-.gallery > .toolbar button.redo[pressed] {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_redo_selected.png') 1x,
- url('../images/gallery/2x/icon_redo_selected.png') 2x);
-}
-
-.gallery > .toolbar button[disabled],
-.gallery[tools][locked] > .toolbar button {
- opacity: 0.5;
- pointer-events: none;
-}
-
-.gallery > .toolbar button[hidden] {
- display: none;
-}
-
-.gallery[mode='slide'] > .toolbar > button.mode {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_mosaic.png') 1x,
- url('../images/gallery/2x/icon_mosaic.png') 2x);
-}
-
-.gallery[mode='slide'] > .toolbar > button.mode:active {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_mosaic_selected.png') 1x,
- url('../images/gallery/2x/icon_mosaic_selected.png') 2x);
-}
-
-.gallery[mode='mosaic'] > .toolbar > button.mode {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_1up.png') 1x,
- url('../images/gallery/2x/icon_1up.png') 2x);
-}
-
-.gallery[mode='mosaic'] > .toolbar > button.mode:active {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_1up_selected.png') 1x,
- url('../images/gallery/2x/icon_1up_selected.png') 2x);
-}
-
-.gallery > .toolbar > button.slideshow {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_slideshow.png') 1x,
- url('../images/gallery/2x/icon_slideshow.png') 2x);
-}
-
-.gallery > .toolbar > button.slideshow:active,
-.gallery > .toolbar > button.slideshow[pressed] {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_slideshow_selected.png') 1x,
- url('../images/gallery/2x/icon_slideshow_selected.png') 2x);
-}
-
-.gallery > .toolbar > button.delete {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_delete.png') 1x,
- url('../images/gallery/2x/icon_delete.png') 2x);
-}
-
-.gallery > .toolbar > button.delete:active {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_delete_selected.png') 1x,
- url('../images/gallery/2x/icon_delete_selected.png') 2x);
-}
-
-.gallery > .toolbar > button.edit {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_edit.png') 1x,
- url('../images/gallery/2x/icon_edit.png') 2x);
-}
-
-.gallery > .toolbar > button.edit:active,
-.gallery > .toolbar > button.edit[pressed] {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_edit_selected.png') 1x,
- url('../images/gallery/2x/icon_edit_selected.png') 2x);
-}
-
-.gallery > .toolbar > button.print {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_print.png') 1x,
- url('../images/gallery/2x/icon_print.png') 2x);
-}
-
-.gallery > .toolbar > button.print:active,
-.gallery > .toolbar > button.print[pressed] {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_print_selected.png') 1x,
- url('../images/gallery/2x/icon_print_selected.png') 2x);
-}
-
-.gallery > .toolbar > button.share {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_share.png') 1x,
- url('../images/gallery/2x/icon_share.png') 2x);
-}
-
-.gallery > .toolbar > button.share:active,
-.gallery > .toolbar > button.share[pressed] {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_share_selected.png') 1x,
- url('../images/gallery/2x/icon_share_selected.png') 2x);
-}
-
-.gallery > .toolbar > button.share[disabled] {
- display: none;
-}
-
-/* Secondary toolbar (mode-specific tools) */
-
-.gallery .edit-modal {
- -webkit-box-orient: horizontal;
- -webkit-box-pack: center;
- bottom: 80px;
- display: -webkit-box;
- height: 40px;
- pointer-events: none;
- position: absolute;
- width: 100%;
-}
-
-.gallery .edit-modal-wrapper[hidden] {
- display: none;
-}
-
-.gallery .edit-modal-wrapper {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: center;
- background-color: rgba(0, 0, 0, 0.75);
- color: white;
- display: -webkit-box;
- padding-right: 5px;
- pointer-events: auto;
-}
-
-.gallery .edit-modal .label {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- background-position: 20px center;
- background-repeat: no-repeat;
- display: -webkit-box;
- height: 20px;
- padding-left: 50px;
- padding-right: 10px;
-}
-
-.gallery .edit-modal .label.brightness {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_brightness.png') 1x,
- url('../images/gallery/2x/icon_brightness.png') 2x);
-}
-
-.gallery .edit-modal .label.contrast {
- background-image: -webkit-image-set(
- url('../images/gallery/icon_contrast.png') 1x,
- url('../images/gallery/2x/icon_contrast.png') 2x);
- height: 24px;
- margin-left: 15px;
-}
-
-.gallery .edit-modal .range {
- -webkit-appearance: none !important;
- height: 3px;
- margin-right: 10px;
- margin-top: 1px;
-}
-
-.gallery .edit-modal .range::-webkit-slider-thumb {
- -webkit-appearance: none;
- background-image: -webkit-image-set(
- url('../images/gallery/slider_thumb.png') 1x,
- url('../images/gallery/2x/slider_thumb.png') 2x);
- height: 29px;
- width: 16px;
-}
-
-/* Crop frame */
-
-.gallery .crop-overlay {
- -webkit-box-orient: vertical;
- display: -webkit-box;
- pointer-events: none;
- position: absolute;
-}
-
-.gallery .crop-overlay .shadow {
- background-color: rgba(0, 0, 0, 0.65);
-}
-
-.gallery .crop-overlay .middle-box {
- -webkit-box-flex: 1;
- -webkit-box-orient: horizontal;
- display: -webkit-box;
-}
-
-.gallery .crop-frame {
- -webkit-box-flex: 1;
- display: -webkit-box;
- position: relative;
-}
-
-.gallery .crop-frame div {
- background-color: rgba(255, 255, 255, 1);
- box-shadow: 0 0 3px rgba(0, 0, 0, 0.75);
- position: absolute;
-}
-
-.gallery .crop-frame .horizontal {
- height: 1px;
- left: 7px;
- right: 7px;
-}
-
-.gallery .crop-frame .horizontal.top {
- top: 0;
-}
-
-.gallery .crop-frame .horizontal.bottom {
- bottom: 0;
-}
-
-.gallery .crop-frame .vertical {
- bottom: 7px;
- top: 7px;
- width: 1px;
-}
-
-.gallery .crop-frame .vertical.left {
- left: 0;
-}
-
-.gallery .crop-frame .vertical.right {
- right: 0;
-}
-
-.gallery .crop-frame .corner {
- border-radius: 6px;
- height: 13px;
- width: 13px;
-}
-
-.gallery .crop-frame .corner.left {
- left: -6px;
-}
-
-.gallery .crop-frame .corner.right {
- right: -6px;
-}
-
-.gallery .crop-frame .corner.top {
- top: -6px;
-}
-
-.gallery .crop-frame .corner.bottom {
- bottom: -6px;
-}
-
-/* Prompt/notification panel */
-
-.gallery .prompt-wrapper {
- -webkit-box-orient: horizontal;
- -webkit-box-pack: center;
- display: -webkit-box;
- height: 100%;
- pointer-events: none;
- position: absolute;
- width: 100%;
-}
-
-.gallery .prompt-wrapper[pos=top] {
- -webkit-box-align: start;
-}
-
-.gallery .prompt-wrapper[pos=center] {
- -webkit-box-align: center;
-}
-
-.gallery .prompt-wrapper[pos=center] .back-button {
- display: none;
-}
-
-.gallery .prompt-wrapper > div.dimmable {
- opacity: 1;
- transition: opacity 220ms ease;
-}
-
-.gallery .prompt {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- background-color: rgba(0, 0, 0, 0.8);
- color: white;
- display: -webkit-box;
- font-size: 120%;
- height: 40px;
- opacity: 0;
- padding: 0 20px;
- position: relative;
- top: 5px;
- transition: all 180ms ease;
-}
-
-.gallery .prompt[state='fadein'] {
- opacity: 1;
- top: 0;
-}
-
-.gallery .prompt[state='fadeout'] {
- opacity: 0;
- top: 0;
-}
-
-.gallery .prompt-wrapper[pos=top] .prompt {
- padding-right: 10px;
-}
-
-.gallery .prompt .back-button {
- background-image: -webkit-image-set(
- url('../images/gallery/butterbar_close_button.png') 1x,
- url('../images/gallery/2x/butterbar_close_button.png') 2x);
- background-position: center center;
- background-repeat: no-repeat;
- height: 16px;
- margin-left: 16px;
- opacity: 0.65;
- pointer-events: auto;
- width: 16px;
-}
-
-.gallery .prompt .back-button:hover {
- background-color: rgba(81, 81, 81, 1);
- opacity: 1.0;
-}
-
-.gallery .share-menu {
- -webkit-box-align: stretch;
- -webkit-box-orient: vertical;
- -webkit-box-pack: start;
- background-color: white;
- border: 1px solid #7f7f7f;
- border-radius: 1px;
- bottom: 60px;
- display: -webkit-box;
- opacity: 1.0;
- padding: 8px;
- position: absolute;
- right: 10px;
- transition: opacity 500ms ease-in-out;
-}
-
-.gallery .share-menu .bubble-point {
- background-image: -webkit-image-set(
- url('../images/gallery/bubble_point.png') 1x,
- url('../images/gallery/2x/bubble_point.png') 2x);
- background-position: center top;
- background-repeat: no-repeat;
- bottom: -8px;
- height: 8px;
- padding: 0;
- position: absolute;
- right: 20px;
- width: 20px;
-}
-
-.gallery .share-menu[hidden] {
- bottom: -100%; /* Offscreen so that 'dimmed' attribute does not show it. */
- opacity: 0;
- pointer-events: none;
-}
-
-.gallery .share-menu > .item {
- background-color: rgba(0, 0, 0, 0);
- background-position: 5px center;
- background-repeat: no-repeat;
- cursor: pointer;
- padding: 5px;
- padding-left: 26px;
-}
-
-.gallery .share-menu > .item:hover {
- background-color: rgba(240, 240, 240, 1);
-}
-
-.gallery .share-menu > div > img {
- display: block;
- margin-right: 5px;
-}
-
-/* Load spinner and error banner. */
-
-.gallery .spinner {
- background-image: url(../images/common/spinner.svg);
- background-size: 100%;
- height: 16px;
- left: 50%;
- margin-left: -8px;
- margin-top: -8px;
- position: absolute;
- top: 50%;
- width: 16px;
-}
-
-.gallery:not([spinner]) .spinner {
- display: none;
-}
-
-.gallery .error-banner {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: center;
- background-color: rgba(24, 24, 24, 1);
- background-image: -webkit-image-set(
- url('../images/media/error.png') 1x,
- url('../images/media/2x/error.png') 2x);
- background-position: 25px center;
- background-repeat: no-repeat;
- color: white;
- display: -webkit-box;
- height: 54px;
- padding-left: 70px;
- padding-right: 35px;
-}
-
-.gallery:not([error]) .error-banner {
- display: none;
-}
-
-/* Video playback support. */
-
-.gallery video {
- height: 100%;
- position: absolute;
- width: 100%;
-}
-
-.gallery .video-controls-spacer {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: center;
- bottom: 60px; /* Just above the toolbar */
- display: -webkit-box;
- height: 30px;
- left: 0;
- opacity: 0;
- pointer-events: none;
- position: absolute;
- right: 0;
-}
-
-.gallery[video] .video-controls-spacer {
- /* Animate opacity on 'tools' attribute toggle. */
- /* Change opacity immediately on 'video' attribute change. */
- transition: opacity 280ms ease;
-}
-
-.gallery[video][tools] .video-controls-spacer {
- opacity: 1;
-}
-
-.gallery .video-controls {
- display: none;
- max-width: 800px;
-}
-
-.gallery[video] .video-controls {
- -webkit-box-flex: 1;
- display: -webkit-box;
-}
-
-.gallery[video] > .toolbar .edit-main {
- display: none;
-}
-
-/* Mosaic view. */
-.mosaic {
- bottom: 55px; /* Toolbar height. */
- left: 0;
- overflow-x: scroll;
- overflow-y: hidden;
- position: absolute;
- right: 0;
- top: 0;
-
- /* transition-duration is set in Javascript. */
- transition-property: -webkit-transform;
- transition-timing-function: linear;
-}
-
-.mosaic::-webkit-scrollbar {
- background: transparent;
-}
-
-.mosaic::-webkit-scrollbar-thumb {
- background: rgb(31, 31, 31);
-}
-
-.gallery:not([mode='mosaic']) .mosaic::-webkit-scrollbar-thumb {
- background: transparent;
-}
-
-.mosaic-tile {
- position: absolute;
- /* Tile's zoom factor is animated on hover. We apply the transform to
- the entire tile so that the image outline is included into the animation. */
- transition: -webkit-transform 150ms linear;
-}
-
-/* Mosaic tile's opacity is controlled by |visible| attribute which changes
- separately from .gallery[mode] */
-.mosaic:not([visible]) .mosaic-tile .img-border {
- opacity: 0;
-}
-
-/* Animate tile's opacity, except for the selected tile which should show/hide
- instantly (this looks better when zooming to/from the slide mode). */
-.mosaic-tile:not([selected]) .img-border {
- transition: opacity 350ms linear;
-}
-
-/* Must be in sync with mosaic_mode.js.
- Mosaic.Layout.SPACING should be equal to
- top + bottom + border-top-width + border-bottom-width AND
- left + right + border-left-width + border-right-width */
-.mosaic-tile .img-border {
- border: 1px solid black; /* Space between the outline and the image. */
- bottom: 4px;
- left: 4px;
- outline: 2px solid transparent;
- overflow: hidden;
- position: absolute;
- right: 4px;
- top: 4px;
-}
-
-/* Selected and hover state are only visible when zoom transition is over. */
-.mosaic[visible='normal'] .mosaic-tile[selected] .img-border {
- outline-color: rgb(51, 153, 255);
-}
-
-.mosaic[visible='normal'].hover-visible .mosaic-tile:hover {
- -webkit-transform: scale(1.05);
- z-index: 50;
-}
-
-.mosaic[visible='normal'].hover-visible
- .mosaic-tile:hover:not([selected]) .img-border {
- outline-color: rgb(182, 212, 252);
-}
-
-.mosaic-tile .img-wrapper {
- bottom: 0;
- left: 0;
- position: absolute;
- right: 0;
- top: 0;
-}
-
-.mosaic-tile .img-wrapper[generic-thumbnail],
-.mosaic-tile .img-wrapper.animated:not([generic-thumbnail])
- canvas:not(.cached) {
- -webkit-animation: fadeIn ease-in 1;
- -webkit-animation-duration: 500ms;
- -webkit-animation-fill-mode: forwards;
-}
-
-@-webkit-keyframes fadeIn {
- from {
- opacity: 0;
- }
- to {
- opacity: 1;
- }
-}
-
-/* In order to do mode animated transitions smoothly we keep both mosaic and
- image-container but transparent. */
-.gallery:not([mode='mosaic']) .mosaic,
-.gallery:not([mode='slide']) .image-container {
- pointer-events: none;
-}
-
-.gallery:not([mode='slide']) .ribbon,
-.gallery:not([mode='slide']) .arrow-box {
- opacity: 0;
- pointer-events: none;
-}
-
-/* Temporary. Remove this along with the delete confirmation dialog
- when Undo delete is implemented. */
-.cr-dialog-shield {
- background-color: black;
-}
-
-/* Slideshow controls */
-
-.slideshow-toolbar {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: center;
- bottom: 0;
- display: none;
- left: 0;
- padding-bottom: 6px;
- pointer-events: none;
- position: absolute;
- right: 0;
-}
-
-.gallery[tools][slideshow] .slideshow-toolbar {
- display: -webkit-box;
-}
-
-.slideshow-toolbar > div {
- background-position: center;
- background-repeat: no-repeat;
- height: 68px;
- opacity: 0.5;
- pointer-events: auto;
- width: 68px;
-}
-
-.slideshow-toolbar > div:hover {
- opacity: 1;
-}
-
-.slideshow-toolbar > .slideshow-play {
- background-image: -webkit-image-set(
- url('../images/gallery/slideshow-play.png') 1x,
- url('../images/gallery/2x/slideshow-play.png') 2x);
- margin-right: -2px;
-}
-
-.gallery[slideshow='playing'] .slideshow-toolbar > .slideshow-play {
- background-image: -webkit-image-set(
- url('../images/gallery/slideshow-pause.png') 1x,
- url('../images/gallery/2x/slideshow-pause.png') 2x);
-}
-
-.slideshow-toolbar > .slideshow-end {
- background-image: -webkit-image-set(
- url('../images/gallery/slideshow-end.png') 1x,
- url('../images/gallery/2x/slideshow-end.png') 2x);
- margin-left: -2px;
-}
-
-.gallery > .header > button {
- -webkit-margin-start: 10px;
- cursor: default;
- height: 32px;
- min-width: 32px;
- width: 32px;
-}
-
-.gallery > .header > .maximize-button {
- background: -webkit-image-set(
- url('chrome://resources/images/apps/topbar_button_maximize.png') 1x,
- url('chrome://resources/images/2x/apps/topbar_button_maximize.png') 2x)
- center;
-}
-
-.gallery > .header > .close-button {
- background: -webkit-image-set(
- url('chrome://resources/images/apps/topbar_button_close.png') 1x,
- url('chrome://resources/images/2x/apps/topbar_button_close.png') 2x)
- center;
-}
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/css/list.css b/chromium/chrome/browser/resources/file_manager/foreground/css/list.css
deleted file mode 100644
index d102d696dcd..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/css/list.css
+++ /dev/null
@@ -1,73 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-/* Derived from /ui/webui/resources/css/list.css. */
-
-list,
-grid {
- display: block;
- outline: none;
- overflow: auto;
- position: relative; /* Make sure that item offsets are relative to the
- list. */
-}
-
-list > *,
-grid > * {
- -webkit-user-select: none;
- position: relative; /* to allow overlap */
- text-overflow: ellipsis;
- white-space: pre;
-}
-
-list > * {
- display: block;
-}
-
-grid > * {
- display: inline-block;
-}
-
-list:focus > [lead],
-grid:focus > [lead] {
- z-index: 2;
-}
-
-list:not([disabled]) > :hover,
-grid:not([disabled]) > :hover {
- z-index: 1;
-}
-
-list > [selected],
-grid > [selected] {
- z-index: 2;
-}
-
-list > .spacer,
-grid > .spacer {
- box-sizing: border-box;
- display: block;
- overflow: hidden;
- visibility: hidden;
-}
-
-list :-webkit-any(
- input[type='input'],
- input[type='password'],
- input[type='search'],
- input[type='text'],
- input[type='url']),
-list :-webkit-any(
- button,
- input[type='button'],
- input[type='submit'],
- select):not(.custom-appearance):not(.link-button) {
- line-height: normal;
- vertical-align: middle;
-}
-
-list > [hidden],
-grid > [hidden] {
- display: none;
-}
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/css/media_controls.css b/chromium/chrome/browser/resources/file_manager/foreground/css/media_controls.css
deleted file mode 100644
index ba167eec138..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/css/media_controls.css
+++ /dev/null
@@ -1,605 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-.media-button {
- height: 28px;
- position: relative;
- width: 26px;
-}
-
-.media-button > div {
- height: 100%;
- opacity: 0;
- pointer-events: none;
- position: absolute;
- transition: opacity 100ms linear;
- width: 100%;
-}
-
-.media-button[state='default']:not(.disabled):not(:hover):not(:active) >
- .default.normal,
-.media-button[state='default']:not(.disabled):hover > .default.hover,
-.media-button[state='default']:not(.disabled):active > .default.active,
-.media-button[state='playing']:not(.disabled):not(:hover):not(:active) >
- .playing.normal,
-.media-button[state='playing']:not(.disabled):hover > .playing.hover,
-.media-button[state='playing']:not(.disabled):active > .playing.active,
-.media-button[state='ended']:not(.disabled):not(:hover):not(:active) >
- .ended.normal,
-.media-button[state='ended']:not(.disabled):hover > .ended.hover,
-.media-button[state='ended']:not(.disabled):active > .ended.active,
-.media-button.disabled > .disabled {
- opacity: 1;
-}
-
-/* Custom sliders for progress and volume. */
-
-/* Customize the standard input[type='range']. */
-.custom-slider > input[type='range'] {
- -webkit-appearance: none !important; /* Hide the default thumb icon. */
- background: transparent; /* Hide the standard slider bar */
- height: 100%;
- left: -2px; /* Required to align the input element with the parent. */
- outline: none;
- position: absolute;
- top: -2px;
- width: 100%;
-}
-
-/* Custom thumb icon. */
-.custom-slider > input[type='range']::-webkit-slider-thumb {
- -webkit-appearance: none;
- background-position: center center;
- background-repeat: no-repeat;
- height: 24px;
- position: relative;
- z-index: 2;
-}
-
-/* Custom slider bar (we hide the standard one). */
-.custom-slider > .bar {
- /* In order to match the horizontal position of the standard slider bar
- left and right must be equal to 1/2 of the thumb icon width. */
- border-bottom-style: solid;
- border-top-style: solid;
- border-width: 1px;
- bottom: 11px;
- pointer-events: none; /* Mouse events pass through to the standard input. */
- position: absolute;
- top: 11px;
-}
-
-.custom-slider > .bar > .filled,
-.custom-slider > .bar > .cap {
- border-style: solid;
- border-width: 1px;
- bottom: -1px;
- position: absolute;
- top: -1px;
-}
-
-/* The filled portion of the slider bar to the left of the thumb. */
-.custom-slider > .bar > .filled {
- border-left-style: none;
- border-right-style: none;
- left: 0;
- width: 0; /* The element style.width is manipulated from the code. */
-}
-
-/* Rounded caps to the left and right of the slider bar. */
-.custom-slider > .bar > .cap {
- width: 4px;
-}
-
-/* Left cap is always filled, should be the same color as .filled. */
-.custom-slider > .bar > .cap.left {
- border-bottom-left-radius: 4px;
- border-right-style: none;
- border-top-left-radius: 4px;
- right: 100%;
-}
-
-/* Right cap is always not filled. */
-.custom-slider > .bar > .cap.right {
- border-bottom-right-radius: 4px;
- border-left-style: none;
- border-top-right-radius: 4px;
- left: 100%;
-}
-
-.custom-slider > .bar,
-.custom-slider > .bar > .cap.right {
- background-color: rgba(0, 0, 0, 0.5);
- border-color: #808080;
-}
-
-.custom-slider > .bar > .filled,
-.custom-slider > .bar > .cap.left {
- background-image: linear-gradient(#c3c3c3, #d9d9d9);
- border-color: #d9d9d9;
-}
-
-.custom-slider.disabled > .bar > .filled,
-.custom-slider.disabled > .bar > .cap.left {
- background-color: rgba(0, 0, 0, 0.5);
- background-image: none;
-}
-
-.custom-slider.disabled > .bar,
-.custom-slider.disabled > .bar > .filled,
-.custom-slider.disabled > .bar > .cap {
- border-color: #404040;
-}
-
-.media-button.disabled,
-.custom-slider.disabled,
-.custom-slider.readonly {
- pointer-events: none;
-}
-
-/* Progress seek marker (precise time shown on mouse hover. */
-
-/* Thin vertical line across the slider bar */
-.custom-slider > .bar > .seek-mark {
- background-color: #202020;
- bottom: -1px;
- left: 0;
- position: absolute;
- top: -1px;
- width: 0;
-}
-
-.custom-slider > .bar > .seek-mark.visible {
- width: 1px;
-}
-
-.custom-slider > .bar > .seek-mark.inverted {
- background-color: #808080;
-}
-
-/* Text label giving the precise time corresponding to the hover position. */
-.custom-slider > .bar > .seek-mark > .seek-label {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: center;
- background: #202020;
- border-top-left-radius: 2px;
- border-top-right-radius: 2px;
- bottom: 19px;
- color: white;
- display: -webkit-box;
- font-size: 13px;
- height: 15px;
- left: 0;
- opacity: 0;
- overflow: hidden;
- position: absolute;
- transition: opacity 150ms ease;
-}
-
-.custom-slider > .bar > .seek-mark.visible > .seek-label {
- opacity: 1;
-}
-
-/* Media controls in order of appearance. */
-
-/* Play/pause button. */
-
-.media-button.play {
- margin-left: -7px;
- margin-right: -7px;
-}
-
-.media-button.play > .default.normal {
- background-image: -webkit-image-set(
- url('../images/media/media_play.png') 1x,
- url('../images/media/2x/media_play.png') 2x);
-}
-
-.media-button.play > .default.hover {
- background-image: -webkit-image-set(
- url('../images/media/media_play_hover.png') 1x,
- url('../images/media/2x/media_play_hover.png') 2x);
-}
-
-.media-button.play > .default.active {
- background-image: -webkit-image-set(
- url('../images/media/media_play_down.png') 1x,
- url('../images/media/2x/media_play_down.png') 2x);
-}
-
-.media-button.play > .playing.normal {
- background-image: -webkit-image-set(
- url('../images/media/media_pause.png') 1x,
- url('../images/media/2x/media_pause.png') 2x);
-}
-
-.media-button.play > .playing.hover {
- background-image: -webkit-image-set(
- url('../images/media/media_pause_hover.png') 1x,
- url('../images/media/2x/media_pause_hover.png') 2x);
-}
-
-.media-button.play > .playing.active {
- background-image: -webkit-image-set(
- url('../images/media/media_pause_down.png') 1x,
- url('../images/media/2x/media_pause_down.png') 2x);
-}
-
-.media-button.play > .ended.normal {
- background-image: -webkit-image-set(
- url('../images/media/media_loop.png') 1x,
- url('../images/media/2x/media_loop.png') 2x);
-}
-
-.media-button.play > .ended.hover {
- background-image: -webkit-image-set(
- url('../images/media/media_loop_hover.png') 1x,
- url('../images/media/2x/media_loop_hover.png') 2x);
-}
-
-.media-button.play > .ended.active {
- background-image: -webkit-image-set(
- url('../images/media/media_loop_down.png') 1x,
- url('../images/media/2x/media_loop_down.png') 2x);
-}
-
-.media-button.play > .disabled {
- background-image: -webkit-image-set(
- url('../images/media/media_play_disabled.png') 1x,
- url('../images/media/2x/media_play_disabled.png') 2x);
-}
-
-/* Time controls: a slider and a text time display. */
-
-.time-controls {
- -webkit-box-align: center;
- -webkit-box-flex: 1;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: center;
- display: -webkit-box;
- height: 100%;
-}
-
-.custom-slider.progress {
- -webkit-box-flex: 1;
- display: -webkit-box;
- height: 100%;
- margin-left: -9px; /* Set the margins at the edges of the slider bar. */
- margin-right: -9px;
- position: relative;
-}
-
-.custom-slider.progress > input[type='range']::-webkit-slider-thumb {
- background-image: -webkit-image-set(
- url('../images/media/media_slider_thumb.png') 1x,
- url('../images/media/2x/media_slider_thumb.png') 2x);
- width: 28px;
-}
-
-.custom-slider.progress > input[type='range']::-webkit-slider-thumb:hover {
- background-image: -webkit-image-set(
- url('../images/media/media_slider_thumb_hover.png') 1x,
- url('../images/media/2x/media_slider_thumb_hover.png') 2x);
-}
-
-.custom-slider.progress > input[type='range']::-webkit-slider-thumb:active {
- background-image: -webkit-image-set(
- url('../images/media/media_slider_thumb_down.png') 1x,
- url('../images/media/2x/media_slider_thumb_down.png') 2x);
-}
-
-.custom-slider.progress.disabled > input[type='range']::-webkit-slider-thumb {
- background-image: none;
-}
-
-.custom-slider.progress > .bar {
- left: 14px; /* Exactly 1/2 of the thumb width */
- right: 14px;
-}
-
-/* Time display. */
-
-.time-controls > .time {
- cursor: default;
- height: 100%;
- margin-left: 15px;
- position: relative;
-}
-
-.time-controls > .time.disabled {
- opacity: 0;
-}
-
-/* Invisible div used to compute the width required for the elapsed time. */
-.time-controls > .time > .duration {
- color: transparent;
-}
-
-.time-controls > .time > .current {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: end;
- color: white;
- display: -webkit-box;
- height: 100%;
- position: absolute;
- right: 0;
- top: -1px;
-}
-
-/* Volume controls: sound button and volume slider */
-
-.volume-controls {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: center;
- display: -webkit-box;
- height: 100%;
-}
-
-/* Sound button */
-
-.media-button.sound {
- margin-left: -4px;
- width: 31px;
-}
-
-.media-button.sound[level='0'] > .normal {
- background-image: -webkit-image-set(
- url('../images/media/media_sound_disabled.png') 1x,
- url('../images/media/2x/media_sound_disabled.png') 2x);
-}
-
-.media-button.sound[level='0'] > .hover {
- background-image: -webkit-image-set(
- url('../images/media/media_sound_disabled_hover.png') 1x,
- url('../images/media/2x/media_sound_disabled_hover.png') 2x);
-}
-
-.media-button.sound[level='0'] > .active {
- background-image: -webkit-image-set(
- url('../images/media/media_sound_disabled_down.png') 1x,
- url('../images/media/2x/media_sound_disabled_down.png') 2x);
-}
-
-
-.media-button.sound[level='1'] > .normal {
- background-image: -webkit-image-set(
- url('../images/media/media_sound_level1.png') 1x,
- url('../images/media/2x/media_sound_level1.png') 2x);
-}
-
-.media-button.sound[level='1'] > .hover {
- background-image: -webkit-image-set(
- url('../images/media/media_sound_level1_hover.png') 1x,
- url('../images/media/2x/media_sound_level1_hover.png') 2x);
-}
-
-.media-button.sound[level='1'] > .active {
- background-image: -webkit-image-set(
- url('../images/media/media_sound_level1_down.png') 1x,
- url('../images/media/2x/media_sound_level1_down.png') 2x);
-}
-
-
-.media-button.sound[level='2'] > .normal {
- background-image: -webkit-image-set(
- url('../images/media/media_sound_level2.png') 1x,
- url('../images/media/2x/media_sound_level2.png') 2x);
-}
-
-.media-button.sound[level='2'] > .hover {
- background-image: -webkit-image-set(
- url('../images/media/media_sound_level2_hover.png') 1x,
- url('../images/media/2x/media_sound_level2_hover.png') 2x);
-}
-
-.media-button.sound[level='2'] > .active {
- background-image: -webkit-image-set(
- url('../images/media/media_sound_level2_down.png') 1x,
- url('../images/media/2x/media_sound_level2_down.png') 2x);
-}
-
-
-.media-button.sound[level='3'] > .normal {
- background-image: -webkit-image-set(
- url('../images/media/media_sound_full.png') 1x,
- url('../images/media/2x/media_sound_full.png') 2x);
-}
-
-.media-button.sound[level='3'] > .hover {
- background-image: -webkit-image-set(
- url('../images/media/media_sound_full_hover.png') 1x,
- url('../images/media/2x/media_sound_full_hover.png') 2x);
-}
-
-.media-button.sound[level='3'] > .active {
- background-image: -webkit-image-set(
- url('../images/media/media_sound_full_down.png') 1x,
- url('../images/media/2x/media_sound_full_down.png') 2x);
-}
-
-
-.media-button.sound > .disabled {
- background-image: -webkit-image-set(
- url('../images/media/media_sound_full_disabled.png') 1x,
- url('../images/media/2x/media_sound_full_disabled.png') 2x);
-}
-
-/* Volume slider. */
-
-.custom-slider.volume {
- height: 100%;
- margin-left: -4px;
- margin-right: -4px;
- position: relative;
- width: 60px;
-}
-
-.custom-slider.volume > input[type='range']::-webkit-slider-thumb {
- background-image: -webkit-image-set(
- url('../images/media/media_volume_slider_thumb.png') 1x,
- url('../images/media/2x/media_volume_slider_thumb.png') 2x);
- width: 20px;
-}
-
-.custom-slider.volume > input[type='range']::-webkit-slider-thumb:hover {
- background-image: -webkit-image-set(
- url('../images/media/media_volume_slider_thumb_hover.png') 1x,
- url('../images/media/2x/media_volume_slider_thumb_hover.png') 2x);
-}
-
-.custom-slider.volume > input[type='range']::-webkit-slider-thumb:active {
- background-image: -webkit-image-set(
- url('../images/media/media_volume_slider_thumb_down.png') 1x,
- url('../images/media/2x/media_volume_slider_thumb_down.png') 2x);
-}
-
-.custom-slider.volume.disabled > input[type='range']::-webkit-slider-thumb {
- background-image: none;
-}
-
-.custom-slider.volume > .bar {
- left: 10px; /* Exactly 1/2 of the thumb width */
- right: 10px;
-}
-
-/* Horizontal video control bar, all controls in a row. */
-
-.video-controls {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: center;
- background: #202020;
- border-radius: 5px;
- display: -webkit-box;
- font-size: 15px;
- height: 30px;
- opacity: 0.8;
- padding-left: 15px;
- padding-right: 15px;
- pointer-events: auto;
-}
-
-.video-controls .time-controls,
-.video-controls .volume-controls {
- margin-left: 15px;
-}
-
-/* Fullscreen button. */
-/* There is no final decision whether we need a separate icon when toggled. */
-
-.media-button.fullscreen {
- margin-left: 9px; /* 15px visible margin - 6px whitespace in the icon. */
- margin-right: -6px;
-}
-
-.media-button.fullscreen > .normal {
- background-image: -webkit-image-set(
- url('../images/media/media_fullscreen.png') 1x,
- url('../images/media/2x/media_fullscreen.png') 2x);
-}
-
-.media-button.fullscreen > .hover {
- background-image: -webkit-image-set(
- url('../images/media/media_fullscreen_hover.png') 1x,
- url('../images/media/2x/media_fullscreen_hover.png') 2x);
-}
-
-.media-button.fullscreen > .active {
- background-image: -webkit-image-set(
- url('../images/media/media_fullscreen_down.png') 1x,
- url('../images/media/2x/media_fullscreen_down.png') 2x);
-}
-
-.media-button.fullscreen > .disabled {
- background-image: -webkit-image-set(
- url('../images/media/media_fullscreen_disabled.png') 1x,
- url('../images/media/2x/media_fullscreen_disabled.png') 2x);
-}
-
-.playback-state-icon {
- background-color: #202020;
- background-position: center center;
- background-repeat: no-repeat;
- border-radius: 2.5px;
- height: 32px;
- left: 50%;
- margin-left: -16px;
- margin-top: -16px;
- opacity: 0;
- pointer-events: none;
- position: absolute;
- top: 50%;
- width: 32px;
- z-index: 2;
-}
-
-.text-banner {
- background-color: black;
- border-radius: 10px;
- color: white;
- font-size: 18px;
- left: 50%;
- margin-left: -250px;
- opacity: 0;
- padding: 10px;
- pointer-events: none;
- position: absolute;
- text-align: center;
- text-shadow: 0 0 10px black;
- top: 20%;
- width: 500px;
- z-index: 2;
-}
-
-.text-banner[visible] {
- -webkit-animation: text-banner-blowup 3000ms;
-}
-
-.playback-state-icon[state] {
- -webkit-animation: blowup 500ms;
-}
-
-@-webkit-keyframes blowup {
- from {
- opacity: 1;
- }
- to {
- -webkit-transform: scale(3);
- opacity: 0;
- }
-}
-
-@-webkit-keyframes text-banner-blowup {
- from {
- -webkit-transform: scale(0.5);
- opacity: 0;
- }
- 20% {
- -webkit-transform: scale(1);
- opacity: 0.75;
- }
- 80% {
- -webkit-transform: scale(1);
- opacity: 0.75;
- }
- to {
- -webkit-transform: scale(3);
- opacity: 0;
- }
-}
-
-.playback-state-icon[state='play'] {
- background-image: -webkit-image-set(
- url('../images/media/media_play.png') 1x,
- url('../images/media/2x/media_play.png') 2x);
-}
-
-.playback-state-icon[state='pause'] {
- background-image: -webkit-image-set(
- url('../images/media/media_pause.png') 1x,
- url('../images/media/2x/media_pause.png') 2x);
-}
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/css/menu.css b/chromium/chrome/browser/resources/file_manager/foreground/css/menu.css
deleted file mode 100644
index 2f32d05752f..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/css/menu.css
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-/* Derived from /ui/webui/resources/css/menu.css. */
-
-menu {
- position: fixed;
- white-space: nowrap;
- z-index: 3;
-}
-
-menu:not(.decorated) {
- display: none;
-}
-
-menu > * {
- box-sizing: border-box;
- display: block;
- text-align: start;
- width: 100%;
-}
-
-menu > hr {
- border: 0;
- height: 1px;
-}
-
-menu > [hidden] {
- display: none;
-}
-
-menu > [shortcutText]::after {
- -webkit-padding-start: 30px;
- color: #999;
- content: attr(shortcutText);
- float: right;
-}
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/css/table.css b/chromium/chrome/browser/resources/file_manager/foreground/css/table.css
deleted file mode 100644
index 83516993103..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/css/table.css
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-/* Derived from /ui/webui/resources/css/table.css. */
-
-html.col-resize * {
- cursor: col-resize !important;
-}
-
-.table[hasElementFocus] > list > [lead] {
- z-index: 2;
-}
-
-.table-row {
- display: -webkit-box;
- text-align: start;
- width: 100%;
-}
-
-.table-row-cell {
- display: -webkit-box;
- overflow: hidden;
-}
-
-.table-row-cell > * {
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.table-header {
- overflow: hidden;
- position: relative;
-}
-
-.table-header-inner {
- -webkit-user-select: none;
- cursor: default;
- display: -webkit-box;
- position: relative;
- text-align: start;
-}
-
-.table-header-cell {
- font-weight: normal;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.table-header-label {
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.table-header-splitter {
- cursor: col-resize;
- height: 100%;
- left: 0;
- position: absolute;
- top: 0;
-}
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/css/tree.css b/chromium/chrome/browser/resources/file_manager/foreground/css/tree.css
deleted file mode 100644
index e151977f754..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/css/tree.css
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-/* Derived from /ui/webui/resources/css/table.css. */
-
-tree {
- display: block;
- outline: none;
- overflow: auto;
-}
-
-.tree-item > .tree-row {
- -webkit-user-select: none;
- cursor: default;
- position: relative;
- white-space: nowrap;
-}
-
-.expand-icon {
- -webkit-transform: rotate(-90deg);
- -webkit-transition: all 150ms;
- background-image: -webkit-canvas(tree-triangle);
- background-position: 50% 50%;
- background-repeat: no-repeat;
- background-size: 8px 5px;
- display: inline-block;
- height: 16px;
- position: relative;
- vertical-align: top;
-}
-
-html[dir=rtl] .expand-icon {
- -webkit-transform: rotate(90deg);
-}
-
-.tree-item[expanded] > .tree-row > .expand-icon {
- -webkit-transform: rotate(0);
- background-image: -webkit-canvas(tree-triangle);
-}
-
-.tree-row .expand-icon {
- visibility: hidden;
-}
-
-.tree-row[may-have-children] .expand-icon {
- visibility: visible;
-}
-
-.tree-row[has-children=false] .expand-icon {
- visibility: hidden;
-}
-
-.tree-row[selected] {
- z-index: 2;
-}
-
-.tree-children[expanded] {
- display: block;
-}
-
-.tree-children {
- display: none;
-}
-
-.tree-item > .tree-row > * {
- display: inline-block;
-}
-
-.tree-label {
- white-space: pre;
-}
-
-/* We need to ensure that even empty labels take up space */
-.tree-label:empty::after {
- content: ' ';
- white-space: pre;
-}
-
-.tree-rename > .tree-row > .tree-label {
- -webkit-user-modify: read-write-plaintext-only;
- -webkit-user-select: auto;
-}
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/css/video_player.css b/chromium/chrome/browser/resources/file_manager/foreground/css/video_player.css
deleted file mode 100644
index decb63dfee8..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/css/video_player.css
+++ /dev/null
@@ -1,103 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-body {
- -webkit-user-select: none;
- background: black;
- font-family: Noto Sans UI,Droid Sans Fallback,sans-serif;
- font-size: 84%;
- margin: 0;
- overflow: hidden;
-}
-
-#video-player {
- height: 100%;
- left: 0;
- position: absolute;
- top: 0;
- width: 100%;
-}
-
-#video-container {
- height: 100%;
- left: 0;
- position: absolute;
- top: 0;
- width: 100%;
-}
-
-video {
- height: 100%;
- left: 0;
- pointer-events: none;
- position: absolute;
- top: 0;
- width: 100%;
-}
-
-#controls-wrapper {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: center;
- bottom: 0;
- display: -webkit-box;
- left: 0;
- position: absolute;
- right: 0;
-}
-
-#controls {
- -webkit-box-flex: 1;
- display: -webkit-box;
-}
-
-#video-player:not([tools]) .tool {
- opacity: 0;
-}
-
-#video-player:not([tools]) {
- cursor: none;
-}
-
-#video-player[disabled] .tool {
- display: none;
-}
-
-.tool {
- transition: opacity 180ms linear;
-}
-
-#error-wrapper {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: center;
- display: -webkit-box;
- height: 100%;
- left: 0;
- pointer-events: none;
- position: absolute;
- top: 0;
- width: 100%;
-}
-
-#error {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: center;
- background-color: rgba(24, 24, 24, 1);
- background-image: -webkit-image-set(
- url('../images/media/error.png') 1x,
- url('../images/media/2x/error.png') 2x);
- background-position: 25px center;
- background-repeat: no-repeat;
- color: white;
- display: -webkit-box;
- height: 54px;
- padding-left: 70px;
- padding-right: 35px;
-}
-
-#error:not([visible]) {
- display: none;
-}
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/bubble_point_white.png b/chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/bubble_point_white.png
deleted file mode 100644
index 643847baee3..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/bubble_point_white.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/check_no_box.png b/chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/check_no_box.png
deleted file mode 100644
index 8dddff8fa17..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/check_no_box.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/checkbox_white_checked.png b/chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/checkbox_white_checked.png
deleted file mode 100644
index 466fa2266b3..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/checkbox_white_checked.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/checkbox_white_unchecked.png b/chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/checkbox_white_unchecked.png
deleted file mode 100644
index 88d97d7dd15..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/checkbox_white_unchecked.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/close_x_gray.png b/chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/close_x_gray.png
deleted file mode 100644
index 8a2930af8bd..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/close_x_gray.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/disclosure_arrow_dk_grey.png b/chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/disclosure_arrow_dk_grey.png
deleted file mode 100644
index 8f3531966e3..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/common/2x/disclosure_arrow_dk_grey.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/common/bubble_point_white.png b/chromium/chrome/browser/resources/file_manager/foreground/images/common/bubble_point_white.png
deleted file mode 100644
index ec5dbe9580e..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/common/bubble_point_white.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/common/check_no_box.png b/chromium/chrome/browser/resources/file_manager/foreground/images/common/check_no_box.png
deleted file mode 100644
index 3006dcd62f9..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/common/check_no_box.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/common/checkbox_white_checked.png b/chromium/chrome/browser/resources/file_manager/foreground/images/common/checkbox_white_checked.png
deleted file mode 100644
index b24de30f8c8..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/common/checkbox_white_checked.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/common/checkbox_white_unchecked.png b/chromium/chrome/browser/resources/file_manager/foreground/images/common/checkbox_white_unchecked.png
deleted file mode 100644
index c92eaaa2d91..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/common/checkbox_white_unchecked.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/common/close_x_gray.png b/chromium/chrome/browser/resources/file_manager/foreground/images/common/close_x_gray.png
deleted file mode 100644
index 3ee375a32b5..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/common/close_x_gray.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/common/disclosure_arrow_dk_grey.png b/chromium/chrome/browser/resources/file_manager/foreground/images/common/disclosure_arrow_dk_grey.png
deleted file mode 100644
index dd2f925b573..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/common/disclosure_arrow_dk_grey.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/common/spinner.svg b/chromium/chrome/browser/resources/file_manager/foreground/images/common/spinner.svg
deleted file mode 100644
index 66b05c38ad2..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/common/spinner.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg viewBox="0 0 32 32" version="1.1"
- xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-
-<g>
- <animateTransform attributeName="transform" type="translate"
- values="0 0; -32 0; -64 0; -96 0; -128 0; -160 0; -192 0; -224 0; -256 0; -288 0; -320 0; -352 0; -384 0; -416 0; -448 0; -480 0; -512 0; -544 0; -576 0; -608 0; -640 0; -672 0; -704 0; -736 0; -768 0; -800 0; -832 0; -864 0; -896 0; -928 0; -960 0; -992 0; -1024 0; -1056 0; -1088 0; -1120 0"
- dur="1s" calcMode="discrete" repeatCount="indefinite" />
- <image width="1152" height="32" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABIAAAAAgCAYAAABq+wOnAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAQa9JREFUeNrsnQd8FFX+wKduTTaFQAghhBZ6R5oCFkBUBJWTZgHP3u487Hf27p2eXTw8CzZAxIKCgBRBOJVDEAXpoff0um3K//dLXnAz+ybZ3ew87q87Hx5JdmfmO6/+yrz3e3xGRgsuwoOH5IBkgyRnDX8iN6XLpc8JkqM/fGXjdK1M1/X9nK7+xAnCMp6XFsF5FY3ddOuMNjHxIUn4We64D/o6W552B8+Lybqu/KyrgVW6pi2QnOkVkdy0qXzynQ5JgRTsMHFpji2tg86Ltq3kc6Z8SAFIvm43H9BPRf7r+JHkPcojwU/wE/wEP8FP8BP8BD9mPuhGUcNBTzql/GDVcZdoS7qe0/Ucb8HPn+9fMHkHS76/eKdNcmVcIMjuqYBtpVYXfLbzvSHvsOIHyg86IP8X8pJ9JOj63TlBbAs/m6PtoQWrPt332cRbfQWbqyNtf9E+g+ItTuYF4SLQ688C26YX2DgteU5Iwa90XS0B++cY/NwJ9bMJymamnNLW35B+HS1fC1Rm6Jx2MS/IZ/KC1IXj+RaQ/wz4SgRmqa4pe3UtuEFX/SvUQNVimyfH15CeHwO/GfAnAP8M4PerYfNCGhSzDv/KgJ8P9tdPuuJfrqmBL2V3ZnVj9kY0z6Ap3tZQxsCXzoG67w58MFx5d02b07ViKPvjkP8fdTW4QtfUzxqz//A5ouFDuXaCPI6H/J8Fdd8N2kBOyLdB+G432r6a4v8K6uYz0eYpidT2iuQ5IE9DOF0Zz/ES1L/QjeQ99IQCeIaNUAYroF7mCpLzYCz2n8mz8MAfDvyJwD+bF8Q8Mv6FPkAl2N2/6Jp/KZTNPOgnv8Rqf1KeAfnDgD8Fyv9syB/yBQPfD/zNcM438P0cOO+Hptq/oc8B5ToA/rsS8j+K5F80nK7C97vgvK/hnNlwztp42d/4HCh/2l78UVtny35vQ95OJzLI2Ejygb8K+JB/cWUkMliK4BnxnCRIzhCBw6V0ufR5aGTDfq0iIYPnORiQxP7w19XA9kKF/Bse5B/w9+EmCH4qH4+M/rdmuLPPmAvs5FoNwTaAk1zXANsHQmG25it9QkrO3tNExcOUb1BObJ2v3fIydPzJpMNuhXHhWV50oJDUWPBJwoFBP7zsVq3FoLsdsqfNflb5D+VD8kKqhMarNLEDNIlPFJNTlv8EP8FP8BP8BD/BT/CjN/xAPzil+Q+W7WstJWW93O2mfedoqv+Xyr1L7z207M+72fH354iujDtkV/OrQM9FhwPnzh5yS+64OZfu/3zKRkb8u+1pHa8AfurJRpGcPajD5OXF+XNHLrSSr3iLOgqS4x6bp/VEwHho5wiye3zOuTO+3fXBsDnx5qu+km5gzP5FcqZNMuPzvJAOPzpAIZxR84GLGwXt9sq48P1lfYB/u2BzT6p50U5/gEw4B9NgTnbfItpTyzXFuwiMwefAHvmhSfxA+WmCaL8P+BfQ+TzymwO7Odhfg8H+ukHUtTK0vxRfyTO25NZ7m8KH+5zFC9J9YGueE2701xwytMtMHpMg94LRaho6I+C6D8H+e7Kp9p+mVI+B+97Di/ahkEzGH16Gc7rCo3QVRQfYf/qrcN08Leh7SnKm72iK01tXfVPg9n8DO7p7uM8h9EwB62A0JvjrKV31L4bx6iGo/41N4UM7mswLtoeB36lBPscnwTmDeME1CP54ANreal0NPA59c0UT+ROBfz/cu0cjfDuccxqcA4m7HfjfA/9h4C9tSv2j/Ol8zeYHRHvKg42cKkIddIE20gV+vwns/826FngU2u38pspfeIYa+edo3uM1dAA30AY6AL8D/HZNrTMq8CgvOj5oyBEkNFSikHDAa14zpBmELwzK/RqpOydUyJ/hl3xITxMBHlXlN8THIzXvkjPqnD+GSx1Q8VdLya22a4HKf4IQt8fS+Brjhx65F83tX+f8qa0LEQSH4y1oCBuhIfa0mh96gGAelz3q5d2yp80+4H8H/B4s+eRcvKY5NF4PeXt2SvjkHgl+gp/gJ/gJfoL/u+ejA6axdKrzjzMuFG/hTR0vW31TcttRGaz5VUe+k1R/6X1ySu52UKovBoXOA8r8kOT2F7zMgu87sVlWAxUPyylttoEue1ud86fO2AFjYLKVfNSZCX8n8G8Ndf6ctEzcmcOt4uOMI9DdnwUDeivwrzVzvpwE2pLaxTX/VcddWrDqedGR9hPwr2uMb3BIXdis7w2tm8KvmXGj+t4Hw3MjtLsrTZ0/dEMQ2+oUUU5aXr7rs7xY9G/Ie3Nd9c8Dm2ZdTfuPjp8CZXCTLTl7K+TjHzh7KQbHSxbwP4f7fA38kY3YqmHOCLjuGrD/fgH2U9iWouVD2bfRteBXguRaCEb3sOjqkHfCddMkZ9pm4D+Hs9ei5/s7gu32LRrwtc6fqA4RyuxCqLv1UI6v41gaY/5XQzuaXev8iU524UwpqIPl2IZiqX9ss9AGXwD+3FrnT5QPIMiDgb8E+J9iW45F/qLt6kjv1Eq0e+6Jni/2hGf/CMpwJZRlbjzkPy/Z+0bxAHnQdt6DNrQWyiAvWgcQvnXBSksya/ia4ovUs4jOFyhAfR387Bip16sxPh6BykP7GikFWbAl3S4lZ/8XOkHnaLxukfDruaGdzXNMGkJvXpTXQSP4o5X8uiOl49gke3reP3EQJPzBwF/Pih96dLryu+u63rRnR9cb9+7QFO8k1nxybRK5l2Si6DLjn+r8J/gJfoKf4Cf4CX4jyreU1Obs7FPFB4OtJRi+GyRnxgxbaruXWo9+bYGr1SA7K36gdE+2K7Pf16I99XHjUgtetPWwmh8sP5Brb9Z5rWhLfihsqUedgaap1Zbxy/ZDA2hVxzc1XvVA5S4r+KirQ72vA939DtThI7hE9Rfv+CpefDVQ3k9yNfsFDMi/RNlv60rGW7X/6/JY+WAwDxFk189gwF3epP7HCymOjJ7nR80PVp0JxutPvGifEJ3jJewBHFCHd/Gy4/vKA197ouCfI4iOX4A/lmvSUcO/F9rS99HYfzWzfkT7Jl6QRzWRj/bndDmp5bpg5ZEOUfAvhHHmR7TdmsbnBEFyXYdjqeor7hpF/8/hBdtG4vhqWglAG4L63wB9qn808seZ2b8V9IGb4sC/GNryZjVQMTAm+SvYsP+JsXdB+Wwoyx+hTY9sqvzXg751MTiiToe2hI7AMWagMF8GpGYmHV/laqdW+mGQmgYF+zr8jm8BIvCw8jgLBtfF4YD0Y0O+lEj4KCcOLJy2pNtN+x6BXN7X0ACHUwMlR+p/YBA4T3KmNzYlMmI+9+vSLlENVH4OVfQI0CjeTt4Jg/mbuur3QIN80Qo+SXZP3kUdwpUG3lHLD+A0wX9YyedqZ3qJ7ScsOkdKzn6EiOGWvOCcA/nPgvy/wIIfelFqp0vS03pOHQqK5QZ7eqcDrPnkntguirjadfIJfoKf4Cf4Cf7vkN/QEihQfk9p/sFQGNT1pj1zeV7K1VXf+hPrX7i2aOOMIlb8QPnBtmCwLQPFtWOI06Vb1vAnRubPHfm51fxg5dE8OaXNcsh/GxPHywZyH0v4SvWJ7lJyqyXAb92Ag+EwpytPwi9HreDLnhyMI5LZiJNjvqZrfyd1Ecf2VzIYdPUva+PLNHjgvTC8QYGmeF/fv2Dy0rjwA+WjRFvyp2aON0NfxPvhMi8PuX9NEYIBfb+veKcSCx/sqrGCzT2vIceb4RnKCZ9qpAarj++NgT8/qhk/jVl+vNTBltR6Ioxt7zTGhzHnMjD8Z0Xo+IvUCO8rOdN+hLY1QnSkfdcI/wpBcr3F0WKsxM7vJblbrFW8RedLzmabGnb+eCcD//0InQ56JA5CjFkj2lPXRGL/ovzJm/r9lXBRs8b8RKTty8RR0VD9t4E+tVL1l40V7SnfRCJ/9WCFSNq3WT1gjKsS0udTG3RUwlgm2pJWQN++RLR5lkcj/32FW4Kqr/QdaDfXGM4r4GpjHNvJ+Y4G+GnQphdB35og2JI+j1X/KN4862/N+lwvgTwcAn9Wk2fA81BWNDBe8imC5PwU2hb6bOY05ACSTOB1A403RHnBgaXOQ4oV0I44gy6GdKZJw0ShggM1BjHabeKQapBf90HIczwM6RVIZ0NCj/VFVIcUNGgQLEuUisMDG1gXGjE/9CBxbg6RfD8HaTS1H4j256ESThgroal8oowo8BwojGGA0/cBrm043/a0rgWLYEB6M958UgbIL4dBxCknZ59Gyz8MsKW86JgVLz5pBwpJJ/l1QjH3orkD3K0Gv8XVrNPWgzgTiqyLjJlPUeBN+aHeeHLvwtC4SIYYSE2q/zo+UYJM+Zz5uvQEP8FP8BP8BP8U8Em8G1M+yA1TPlzbZL7vxOYMe/Ou8+qcHyAnB2b0u/n+oo0z/mzGJ/IrLvn3FWxpbs/oshL47cIqxt2iCvjHTeRmXPiBkvxWcmruauBnmZTz12BMXUP0rNBniA+/4lA7Oanlsgb4aLy9BjUzT3K1qCTBQePGBwM1T3SmL2/A+YMbmzwDCYwYvtjmyakLUBoXPhjo3cFAXFJ/uVu9A2OJvgrpY0g7T95YctbpZH54lpj5YKCdDobqAnxha8Ivg4ROjPmkLkL7AxpgvSDt2vXB8JKY+Djzxeb+uAHnRymk2ZAw7hKuwDhBnAAisb+GQsJZQyOwOJXqEy/sXzB5QxT8EY3wsWw/gfQFyf8xrjboNua1C7F/cKZ/2GwPNVhV3Shfqb5AkFzvNuD8wPzPg/QlpE2ErxHnFs6wOQvSZZAos10wJIl8B7SPyWZxSXHmDfBnNcBHBxraDjjbbDOkI2Rsxp2UukE6h5R/O4oTpKXkTF+jBirQwfi9SfmfKciudxrgo42Jz7cK0s+kLPHc5oQ/ivBbm9q/3qLBkrPZ7obknx6oKjX5fj3J/3LS/+qceVj/uDwJJ3dMg9SSUv4e0e75QvUVDxYd6dsak7/oQFWqC16Cce7ukO/XQML2sZr4D+pi2zgJ/0JIUyFlU/hJUO6fqYHyM0WbZ0M08j9/zlkPdLjsm9UwNnUm9b6SOF9Cr0P+BZCupZY/x9ugb82FMWakYEv6Nhb9I6P/rUcIg3Zg/7uEw/g/tX3ByJcFyfEOtLFjuKwydFA6eQYZxASKp+1EA8pPXcfEWT0vEkdMP9JJaUdzMoAbB9mm8LEjfARpIimID008cc1Ed4uPg5VHaQN8U/ihAvI8Ugb51CeQambidLOIT5QB/lzSUMPHIUF6VdeCfSzkozD2CnYP1dMOSuVM4Pe1ml93jatlv/trnT+1nYAX7W8CvzcrfujnLc94sHX2iOd6mqzJjhufnEu7RiCMBD/BT/AT/N81nxLzxpSPY3qEsXMa5dPGf4wT0eW6be92u3n/vq435n/b7pJPTzfy45V/Gr9g/fOCvVne+8aZL2Bcd2HGT+/4Ec35g7qMaE/91Eo+xtyRPTmfmThfjhG9Dg28vVbwMeaO7M5cYMIvI4r9AEg4O6Ey3vyaXbbsnvloqJro97dA6k0M0OJ488HYc4Nh9LGJ8wf7AMbhwFlhT4U6f+I1/mCcEDC+PzFx/gQJtxWk24gharx3CTFMj5jpfw3ylepW0Nc+NHG+oGPtCUi5pB4WQzoeYgCrxCCeRZwAzRVvcfrOWac9GQU/q/bFtCn/ScL/I3ECHSDOnzrH0H+Jc/A04ojZElK2yw4smvpNo/kXHWYzX7AcH4KEY9MNkBZwtbO//KRucCYcri55HBLGy8GlY2HBl3Vd9Zm1P9xlDPL/ngkfZ3rcCSmH1P8ikn+F1AHWBRrVD5A2OoU8X5gTghfEh2h8/AxssydMZl6hs+FqSG0JYwX5rG73vaPks3uJ8+lG0mfD7V+75zOTmEQn5d+h5bctgqL6b8h3O4lzZyCx8X/h6s/kKidt/17SRv5MxqwwJ5BgS1mAfT0S+Q/t90V/8c5xnK5NJ05FnGDyBjpZufqBjbF9oFPlb8T5cZsJ3w19fL5JTCRT+a94S46J9hRsG/cT30IB5QUQOsceIeU/3YTv5GXHnGj5Ecrf7WSM6kLqv4TuBHLOgf7YItTjVHfgQxk7fxU9I40e6J0dQ4TWDC58Rk4vUlh3W8BHAT2ZDBKzjGxekPtAJ3iSVBJnUf5XkYFwPvHG12sEHC++Db8MNjTiePJ3kc46m3gFQ/l2aGNvEWVCtYiPHu95ZCC+3PCVjedF7Ex9DG8C4sqHDqPXdAJdSzPmH/gfsOLDwK4KkiM576ofnq0LEu7pOHY+aaMRl38MW6ee5HP1p2giIxnuV04EjyX5r+OTPIbxidCwqv8l+Al+gp/gR8V3pHdyGpZu4KwTJnzRkfpXQXZPITpKrrNl33+n5I3rkj3qlWIW/LQeU2/hRcfocJtBXkJkmaX89J5XTQc+bYcTnDE+MUoHYNR8ObXtA7xoG0C5Dxo7FxCDz7r6d2Y8DmXd00SxR+Nrn5V8yZn+dM0uSuEHGn8XEp3SMr5gc78EfFqcFjSkcVb/T1bywfh+3WTmE26njasaotpNKVT/i4jPSzhLnRYs9wDh/xgFvgjqs252VqT8t3EnKRN7alyoQyeCA50BOAlgeKBkt7h7zjlbIuSnmbQ/zP+2KOp9IXGI/Puk/aFrBZX7lv/LnC/CuXwqzflM+JHuJoYzkuZytRMg3iVt12B/mco/mmNkJRn/iiLko/yaCWkJVztb5wzDeN5dcqQ9ThxaVPmLy57y546akHvh+/3klFwfeYZAhHw872VSB/NJOwjhi3mC7Ho8Uvvbnt7piyj7PToFX+JqZ6l9QRyCoe2srSA7MAzKTZHwY5D/WP4vECfh58QhE8pvEw0f9Z8obb+6+l9KnqGbQaBnQh28ROzPk94midL4vE1QvuoOXGo0iaOv+/wL9+tUJSv4c0jnC2u4oGjdoniLQyObW8EvJQPnf8KVKnGgpnjHW8zHjjuBdEQjv6+u+q60mK8Tr/USiie6u64Fr7OYX8f6wIR/PQs+Olo6TFo2vN4OcaL9UuBfxYpPUZ7dZLmB9eVPXzrhNjifE/wEP8FP8E8J31+4rUWX67fPbz95+Z6uN+avyR03B5VWbxOcP43yQ8ffin3LkkXZfaNBRqVmj3olnQUfl36BUfCIifHxkNX8QPGuLNGRSuPgW+jxFGMpvvyKQ+1EW9KdlGvR6XJmDM6fqPg1W53b3H+mXIuzOobH4PyJkl/c2STgKnJHxOD8iYqv+st6465JlGtxycuwGJw/UfExQGvtTlem/I2W8muCDttGmzifhkbp/Ila/8OlZyb8XYS/JQY02nwrbGkdv2ps/AX+ecA/l3KPLYS/LQY+Mq+ANChYfuDKo6vuHnZ4xfQ9JvyzgH8e5R7rSf3vibHe/8DVvoSvM4kUf9GON4zlT353K5XHjKFB0Il0fhTOH6PjdCRHWYmDY40WqBzakPwNlO2vkFNyPyP2WyAGPjoOz4K0jmJ/34rLTRuT/02Uv3tJ3YWthIGx5lpDUHAr+LvI2L2bwr8uEn4T9R8cu8+hjd286JioBspP40I6gXG3B5WjTSGL7fiM0zXcxnKG4XP0duG0zust5GPjvZ2rjRFUjy3IDpwudpXF+cd1r+i9xfWazerrdxJOl/vYYj7eZxoRoPXXJfIy8mdZzMeB41Ku9i1abn1PqHgn8VRqFre/J4kjsLeBfwf8+BcDPid7csKmVQP/IVL+qtV8ci9bmzHv9HVlDbgR4C61unAmg/ZXj8/9Or22bneM0gQ/wU/wf598ULBKiQJM5ccw67HeETK7scH8yyltHgelbFStXJbbu7IHzcy9+MNcVuXvatn/TwBuYbjmCEePkxh3vuxpfSvl7TsaHRhPw2c1X0zKBB2NN06Lx2VOk4gOZSlfcqTdS1n64yMGXJHVfEF2PUhZ+hEgumOB9XzHXyn8INHdDlnOlxyPceFLb5B/CXGCWMoH45/mfMSZBOM46lKeOPMF+X4T22Eco/w/ZuLAGEvGIav591KuwdlbF8ah/f931/tD0ZHTwrz8pdsp1x0n5d8UIxzl2BW6rsxXqgt7eY+u/+bQV7fsMJO/uz4Y9n77CYuOyJ42Z4u25PXwYG9yjW9a0NBRNwkA4zV1DTX+OEHECRhrLZb/FaQPI79VqMMD+jyMOTUTBKzkYxu6gDhQM+rxZQe2uT9azC8gDjx0IIfKN1GQ7NjmbrCYf5z0Ycy/s575KchY/n+QCNhJ6fw6F6+DF/6la+olvCAat9W7ovM1P9+1481eVvJfJY1wRH0vnHOS6i+9jfs1aJ1VfBxAHyTPEVIk8mm6GuhFPJRW8nEKOTq73q3PFzvrWnAQV/uWzUo+TmPD6X6fGNpEe2gTZ3G1a2et5KMgx7drqyl89JAvY9D+0RH5z3qdnBdyCP8rq/k4Hbn6yDqXq9XAj3Adck37T3GfA3z0kH/fEL+pRhg5dBKcMdTIcIYIV2vLv/ZeCX6Cn+BHyI9x2Y+ZI4bKh89r+B0mLRsvp7S5mtO1ssr9K58FJfn7ePLN8l/H73rTnnp6Cc9LrdythqDCeIwJ/8b8qyjX3NVE5T8ifvMB0/mM0/50HeWaR4gCaSk/9+IPRXfWoKmUa3CHqX1W8ztdtcEluTIup1zzHNe0mR8R8TtfuyUVjL1LKde8yDVh5kek/C7Xbk0XbO5JlGtwmcAGy/nXbWshyG7a7ItXiOFoKb/rDbs786JtKOWaJ1mUP/C7A3+wCX9TvPQ/mv5Vy9/ViRftp1Muw/AcO6zn72zDi47hlMumx8n51iAff+ly/Y4kSlC62+I0/usgTz7d9c7AJZHI3z0fjcFZlx9HGXOtoQMdiTi+rq/3qaYKIbGIrJT/GJ/oZg4ngoTa37Lr0mDl0VuIk8pKPjqw8WX/Owb7/1KluuBWUj5W6l/4EuevnGESCuT/csVbjJMgKi3mYx++n9ifIfl3jFUDFem4BMxB8T7Fq/H92gkEETuUZvjcqauBixjw76FY5ZBvfhyj/L/B/bpl56+FoivjGfFxGVT4NEZdY8XHzh8euE9XJjLiYwC6NRT+pYz4OIV1aThfncSIz7laDTq7zvlDDhHyP5UVnwg0Nef8f3fNm7ruhvYTFo2Q3S2drPjknqExl3jCTvAT/AQ/hB9H5bNRft609aPszTq/AQrZGWAIXuDpMOYj4MvM+JevOQ3jAhjO3RNH50fD/CvWDuAFOY+itM5jwU/tOvlMdHgZzi0mOovlfHtqh1GU2U+VxAFhOZ8X5YsoW35XEQeQ9f1P1y+mzD7Cc59mwdc51AHDthxnxudql+nIFKP1MSb515UplHOLjQaThfyJlHOPsOOrfzAxWt+0Qv8z8jXFN5QLDwqNm+m8x4KPKVi69z2Dwb0k3uNvQ3wG8hcdqf8KMTwqq47+dyZD/oJw+4tPFmTnRYz4WL+GZaQYkFsaw0j/wrI2vEnn3TxfMymFBR+dT4cNfBns/3E4A8hOGSisOLbpWnA1KDtn13eCaPj3cov5+CYDPaD1gvxBA8DB5wsG+cfpvLgW9I56fF4cxKj8NeIEeqB+GxCGMeLj4DqLq32rEcKXBjNsfzigD6ufffkshnws//pvunhxCEN+2FReyP8IhnwOjL2RsjuzZptLOSmL63DZ14O3/7vr/TR+nGYe1dcqZrTBe4c6wewmipJVR4Kf4P9P8V1ZA+XsUS/fIto9/VV/+Q9HVt7+PEs+KIGjuPozI3GpNMrlL5nw7ckjKOfN4eI7A8ucb0ui8XFprsKG7x5JOe9TzjonZD0+LzlHUc7D4JnlTPiijZZ/1AmLGPHPNcl/MRO+INP4+MKukA1fGkY5D4PHljDK/1km/b+KEZ+Wf9wNy8eEz4tnUM57k9X4EyjO3+PM6q8bjOAXuPDJApbJ3/x55y3NvWjuJfb0zqN4XtgrOtJeZTX+M5T/NwXL9n8B9nZexd6la45/9+Qxxvy3jPaXIDkxDu0SRvbnDOKICTG/bDjz7CsGfOxLr3G1u3SF8O0Yo2cVI/8Dbjx1f32+PBwdQJLhZL9V2p+uBecbHUDwGL0Z8T8LcwDV7vrAKv/LwhxAtbs+sOKvNDqAQPh2Zcj/JtwBIXRhyP+aC3+ADq6Wp7mqj/3Agr8mHC928nQY4ynPX6Qw4H9LyX9eWrcpaSVb5/hZ9H/Z3QKn9Z5c6y/Irmuh/J9kVP4195bdLVNaDLm3bfXhb0+UbJtHC25nKd+gAEgJfoJvPMcK5yceW2e0CePnjHnrcdHmub62P7pHt7nwXVz6dCOr/IMBkk057ygzvmjvTTlvBTO+5Ogfiaywii+INhp/FUN+n1Na/oLcj3LeV+z4Eq39LWbHt9F2HlvCsPxPo5y3iGH59zSxFViNfz0o533ETP7Qdz5jlv+9n16yK+/yNffKnpy7OZ736JryOrSJt1jL3/0LJuMEAUxFIH/9rPks9I9dHwzDcXXTKeJ/ThwhIUzdwdD+wzaNs6D4EPt/IEP+4jAHkCCz5C8McwDxUneaA0jhrDu+p7iF2jDih7Fh8G3DMP+bKQZ4luRMsyneEhZ8SiR/PjW53eiUir1LvQz4Wyl8e3LuOZ6K/St9DPi09cxCUtuRWdXHfjjKgI/rmXFqsyuU78oa2Ko8f9EBBnx8o4pe/3oBqZ2ZfXNKts7Zzab/8x5j/Xs6jsmB8j/Igp83bX2m5ExfBgNvp5RO45WMAbc/suvdwW8wHP+M95YiOCfB/43zs0e+0MGZ0bOn98SPmw6vvPM4S74gu84zKCWXW+gACuPzgtiKct52hvw2lPN2M+PzUjsTWcGm/fFiu8hktUV8gcrfzK78qfxt7Nqf1J5y3iaG7b8D5bwNLPio+8KAQ+v//2XB97Q/H/QRnrb1+EYWfGeL3k7K1u9BlvUfrDo+x5bcOsQJrK+GMmE2/hLHBM54el90pAqqr/Rot5sPqKdS/odsHvC75FvELuZ07RVo73+p4/iLd7/B0P4+wdUurc4J0XX6M7S/UaZhzKeUX60/IYth/sPjmQlCdl0Q6NBDs6r1cbp+mPKphxH/EMUBk8Yw/yeoDoics5JLd35awYBPndJrS22L69+9DPjYy3Bgr7fbgzNrYLOK/SsPM+ArYR0QDtmVgX8fZdL+a8vAVW8EdjXDNniAEb/A6AAS7J4UZv2fsqOC5MzA/B9kwZfdmegB71SHlpNaPdis381fFG2cEbrThGbhDAxj3iixBy0t/wQ/Aj7L+u84ZeU4W1pHnHIu2tLzFE/n8eiAmccs/7ruNZRCgG35CzQDzMuMz4vNKOeVs+PzKZHKaov4nlPJ5zkhlXJeEbv8C54IdbW4892thmAcStoyjKMs+J4OY5JMjMBjLPgpXaekmYzBTPLvzh6SbqKjFLPgOzP7uk3yrrBq/7vfO312h0lflcvJrc9Vg5W7ecH2pORMPyXyV/WVagn947fL3/pa29vbT1i0QXRmdPCe2LTm0JIbtjH1P9TO8Mr51R2hHFC8Jcblh5qFZY+KZc9fhZ+YyjD/ASLXM0L4yRLH8Kg68HVhcocLw9xCjPCU7UR1lWH2qYN69fGN1Yz41MCagZI9rPg2LnyrT4xGrzOsA0cYPljtZ8h3hTdBnWX+KQoHzzPkO8M+EW02hvxexj7hTO+MU6ALWMA7/XFTEgw59wi2pB6g7Kzbv2Dia4Gy/WHjgoUOCC5xmAwM6Z2kQPkBVVN8TLlySu4dIeMizgjB4KvzGD6CUeFIYloAPC+bjFNVrJ6A8pmHa9r2v03ly8yKnxNoDgg7w/qn6aBMZKLoSBNMvmKiEwh2j2jyFRO9VLS5xWh01bjnX3Ka2R9BFvxA1THvqap7PIo3zyrLPOOB3bwgdwz5eBVr2Zf/4bm45K5u2V2lVfpHQk9JHGSXs5Wngq0p3r/wvNiRF229dF054T22cTrjRzC8XOPdjoweNl/hliAjPupUGSG2p18iwjZUCRGsEkC2tE60t13Gt21W8WnGdwXD/GdR9JwKMACDhGk1vzlN0FbsW1bJiN+C2iIPrS1kVP/NaYotGH2ljPjJXP1tIGs1reqCYkZ8dLS0DtM0vYVFjPiobLY/hXw8csPK31dcxoovOdPegqGmZstfIcl5TrtLv8jY8WavB1mNv4Z+Hmpo/U/xrZoCDoplGF9OyhLbT1zyuOhIvRzkgU/X1Xu52oCBbPLP80YHaDvSVwNM+LpaYvA32IisOsqIX0Hxd+Bbuu1s+DrN0YTLUg4y4tOC3eIszV0s+DqnlfHhs7AyWfFryp/nkyj532s1X/WVqJyulZCZ4EZd5bDV/Iq9S6u4sLgYNQcq6UVW8ysPrqmk6L944JvpMqv53mMbzBiY/xOWl3/+l2WZg+81zkpPs9AAC2v/FfuWX5Oce87zvCDnasHqb4OVR6bb0zsx49PkL8jJ37X+8Xvn/1brf/vrnXEjnPOb9b42DexetL0DbMtfP1YPpWvlvsItfkb2Nx7u+sJfLRW4yNYFxqf2bUmU9cb8Pkb8vHD/j7qXYf67hfE1ZQ9Dfv9wvnpK+fAAR6uOfFfJiE8J9qiXFP30xnFGfEqwQ726ePOs/Qz5RmNTLd+9iFX/w4DjxhlAWsXe5azyn8sZlr9h24f8H2TEB6OCHx/6gWjzjGU5/na+5ufzu1y79dXOV//0WNbwJ9oQNjM+R1/vfEr5uRfPHys60q6q2RaTF5JBEX+ZtFUmfF3x/4dy3mBmfE2lOTqGMuPr2sHIxkqr+ArtdfcQdu1foxm6A5jxNe1IZLLSqvKntr++7Pg6bblbb4btj1b+3Vnwg5VH/aCD0RxdPVjwKw+sqkQdkHJeRxb8QNk+H5S/If+6Vcu/qPV/aMkNW7fNzBu79bW2vba/0e3G/Lkjq1jyf+/yP8H//fHB5ishM++Z8mG8fRjGuzp5owSrjj/EkI+2T4bB/j4ikQcINQxxloQl0yAFyUnZclD/xfCBVfzTw/0PwZ8Z5j9su1NdDWxgyD87PP9M+edSyp8lP3ztoaZsZMi/iML/OVBes+OAiwH//HC+uq3q8LdVjPjjKPydlQe+rmTEv4TGrz72QzXD/Nd7AwLGzyGW/U+0p+JODDWvIFK7TzkvULZ3IAjDKiPfql0wts5oY6coAJzsbulsN2Hhn+D5YIzQ0Sl/F2dNIN4wvuhIMc5Kwzq6mLMmEGwYX1P8Pwqy+zLD51M5yq6JVvB11f8zVMAkSl/5iAlf8W3iJNcfDJ+jo/R9NvkHHUAKG5tHc7VbEVtf/2rgF1F0GMfmMZCeY5J/0IF40WbUjS6A9BIbvrKNshMU1scMNvzABl5wGl8OngVpFgs+p6k/c6JkXPOCW9N/wqj+t/Ki3TgzeARnzU5cNP5m4GdR+N+y4CvVhY+C/PkXMbxU+Pt+ydXcKhuQKv9Y2V8JfoL//4FPdiv9zeV/17uDd3ran396eq+re3qP/7jv+HdP7mHIR71fC7VBdF0rkggs1ADCt/SWBEEUZOellOdaZvjACj5mfiLFAbOSUf6xnC+jOECWMeJjo5pC4X/NiO+klr+mLGXEd1PLXw0sZ8THKe5XnML6x9hH14R9qisrGPFxgLuBwl/IiI9rTG6i8Fcx4uOge2s4X1vNcPx9mAvdApOXWmX0vxUdQEsY8ft1vubn67Wgt7Bww0vvl/zyQXmdoGv7hwV3Sa4Wd5Hz8O07voHuwsV/KqxxBppfC1R9Kdo8dxk+x7byPCSf5Xxv0UouPOjmZEh3Qiq1nO+vWCY60p8wfI4OGSuWgYXx1WD1CuA/RnGA4DKwg5bnP1i9WrSnPEBxAOGM3a1W83XFt4qzee40fI4va3AWxG7L+agDye4bKQY4OiUOMOB/zUnOKyn5x2Vox63mwxj8H9LfjO0fx+tKy/OvKV/zot34cmoCJIwN5mXEN76cQ10Rl8IGGPBXUPjogH7MAhkUxt/1zsDZ2SOe3+Fq2f+06qPr1x9eecduC2PghLe/2qOe/AUDuPxU8jnrguAn+An+75pfvmdxFaTvTwH/qBqomCfakoms032qr/QViSi5oeuARfIQcRU+MKg5u928v4/hY1WQ7AtJAVjJv4ALm1aqV+matoBR/i/jQqKPE+OvDIwhVvxbuLDlL7qP0/X5jPg3c8bpZ5yOsY9Y8THYl9HKUjhe+IAR/3ZIYbvN8Lz4HiP+vRwtBhUvvMuI/ydiUBj5sxm2v/CF9bw0l8avHasOxJM/laMtK+ClTxjxcUZF2LIWQU7aFcrPPP3+rJROF0/WVZ+fFx2vx9EAHAZpuWhPtUHiWg59ZLz3xM/n+Qo21zhYREfqMMP5OFZfDenf8ZQ/XP1YD5hn3653B63uesPubbxoC132lUP67JNW83fPHfFj1xvzd/CC3DnkO3RYPwrpz1bzS3d+siGj/617gR+6HTY6bHF6cjy3g6fyy7Z/tC7jtD8d4nmptYGPBuBVVvMD5ftWy+7MEzAWhcaow754P0d5aRBvvh6sXg66QCnwUw38xymOibjzNTWwSOT0akCGKqGoF6JT7Dqr+SADP4dfA8APfQuKDvu7iRPEUn6tDqI/V7ME9NcjifT/Ry3PvyCiDvQMV392KOpK10N6kQF/Dvx8wsBvScbff1le/rU62ONc/UBgeRYZf7T65w6vmJ4PP/ZYKH8b5LOwvxL8BD/Bj44f52DkpzT/OKYJkuPOduM/+0pwpLXzHvth+aGvbllTFwTaa/BCeUIMg3jAMXMeTfFtFCRnqLK/ZsebvcpI5q3iyzRBCs/yieRMr9t+3cr8o+H/93C+d5aclOVlwM8hylx9frB6tmhPKWXAR2PuYVr5C7L7GAM+vsm9z/ihrvoXQ1s8yIDfx4S/nBftuxjwBxAHkMH/GFwPRt9GRvxHw/nqRuD/aMaHMcMHSlg8+L1ohjwufwPld63Z+BdHPiqzL1D4vwD/Wwb5R8P6NWr5i7Ytdfxmva/NhrQYFPK6+e84YwuXZuxvIh/v9x4XMs0VnS2tR77Yy5bWscbBpAYqNhAnUejxLCR8O9/UWRiCrivj8qau61a5b/nKo9/cV+fU8taVr+ItfhNkwbOG69ABgjPk1sVL/hk+PslXfcVviY70v1OclgvIM1jJ11VfyduiI83YR9EA/RLS53Fogw3zA+XvijbP3yhOUzSOF1rMV6D9vS/akm83fI/OFzSOv7CY79eCVe+BLPyT4XucMTubQflXa0r1PEFyGZ1t6ADAZXirLeYXgS60EGTxeMP3fyb532Ax/xjI4i9BFhuXAd4DCV8Q7LSYfwD4OAtnhOF71Jk+5eLjhG+Ivx/4K4E/0vD94yT/pRbzD0P9fxFa/9Afvt7+7658nOSfKT9Ev6HKXy5+u9FFzY+n/ZXgJ/gJ/u+XH+J/0fPnnbeUfFyN42ud17/SAEMvVGocHVB4L7F06+w7YLBfw9W8cdJRsb2KAR/jDhmDTwe1YHWowmsV306UKOPsmyq1uuBZBnxsVB+F30uvBv5DDPi46xvOcjDu8qHoivdhBvwWxIgybv+O2z0/wIDfmuTfGHxZ19Xggwz4bQjfHu6ACrDgtyV8Vzjfdw8DfntiQIXztcBjIUyr+DnEgEyh8J+g5T+pzdnOTn/c9FjXG/PR8YBvYJs10fmykKPswAf8p0L56T2mnRvi/MEjg5RdiybwPST/Ybuvie7MgrrfAyX5j1OCoeK1i2jXRnFgv1/A89KnclLWE2k9rliRe9Hc/qSsTy7v8B75diaFbyPP3i1e8i+0+EP5vsKtM6FCjMGA8fyPuVoHsqX8YPmh12p2QwpXWtAB0tdqvlJ++EXcEIfCR9nZz2o+yMLnanUSav4HWZ5/X8nz8JGfwp/FxScgb4N8Leh7mgsPRikQB0AHq/m6FnyKouxKRHfJtpyvBp+h8F3EAZnCgP8IhY/XvBZP/TtKPsqdSSz4wbIDN6uB8tmgk2xR/aXvH1/70F1W2B9mfFb2T4Kf4Cf4CX60fJyJ1JRkxsfv6hxAKPyN0eed8RB+APGQe3HH1j5yePvrnSdvnZGbBfoNvnHYbzW/+tgPlRTjc7bkbBa6vt4qPr5FOc/4oeov/7uc0vaQxXw04JbSFFg1UPkMAz46vdDJ19P4hRaofFF0pG+3mI/G/xqOsqOEplS/LtpTfrKYjzNPcAZDO0r7myPYkr6zmI+zN9ZylK3fddW/QJDdSyzmDzHnB74E/vLG+DB2NIWPgU2/pTkQwOBYLUjOOQ3xHRk9PMGqYxg36U8xGiF1+e9M4a8F/lwaP/vclx+TnOnX8YKMM6duIH0olinxPUn7603hfwP8+XV/d7v5gMJJjhMmbZg2OyeSAw3HVbTxB2NfibbkkzNrnJl9ipTqortNHIjrOUoA+QjHn6+4esHfeZezea9pWNY1eSZHcocLK1VvyQMmDjQcQ0bHwMfthF/QNXVD52u3vNKs1x9DFYp6fHfroWWKt+ivlHtg+1/NUQLYxyJ/zfiOFj0LVX/ZE5TL0QjGOHkXWMm3Z3Q9ATLxWZP8L4+x/EMdiWH8UIeHLbX9YZCJtKDLuBQPZ0GdH29+aP5tya33aoGqV03aEOZ/qJV8GG92gEycadKHvuaatitWo3zR5vkBZOK7lGvbkfbXw0o+yOL/AP9DkzH0Cy58++J489cAfy7l2vMp11rBXwv8D4wXBquOa3Ewfhrv/806H9/xRo+bts3sOHrHm73uKdk2ryIO8j/i/m+l/ZHgJ/gJfoL/v8oPFWw46AYpChDGTuFj8EbxkFCBMc7+QEZFiHcqKn4UimcNf98n44+o/tKTyoWuK+j4eIhySdz5YOiMoBj/q3xFW5+ymI8Fu5GmOILx/b2vcMvjFvLx3HHEcKRsPR/cqHoL77OQj236GpL/ThT+VtVfcaeFfJxtg8bc9xwl7g20v72a4r/FQn4yVxtTAB1MOVx4ARzRNeW6SPnQjtPJFMJID5wx8gpxfmRT+AVQBtdGw9eCVS2IERDJFonocHqJGM6ZFH4xdIJpDfFFR6rQdvzHs2V3yzfIvdBZeR9HmUlEObJI/r+h1T/yofwxtohO4wuy60zD52h8obPyWeKQaOxAx+8/IP1AdxzpJbT8q1Un5sHYtMKkPNEIe5GjxZEKP9DRgTMKNnPU2SN6GfDD6n/XOwNmQz3PM3HCLIb0NhfZbAQUdti/tlAdV4IgkbKud+yc1f9tMII/o9wvnfDfpPan8APftFxJ8n8bL4j9wMC9rPmgu18MlX8m/MUmAhyN0HeIQyyS8XcEtLOHgmX7LzOTv8aLijfPel5X/WtM6hNnkb0bYf3Xk7+R8kEmPgmyaZ2JEwSdMDMibP8n+eTaiPiat+hxkA2bTOof8/8cFxbHrtF6iJivBqseAP52yn0yiRPmMcq94sbXgr6/wrhMW+6JbR4d6RhHT7aMrwamE93MeKAMx3ZxdZQ6UFR8XVVuNeEP0zV1SAyKd7T5vwX4BwyyomjXOwPdUcrfGOvfi/zdIXriliMrpq+IQf7HxI+j/hFXfqz6f4Kf4Cf4Cf7/Oj/UoEKDpIQoOaGOIQcx6jAydaSBiZxEcRWNcoYwaGvb4sYnAS9P8ne82euvrUe9/Lac3CZDDZR+ldTm7HIWfF3x7+Ntct8Q4/9AoHT/ZHerIYqVfFDk7+FFew7N+QBGwXgL+VjeaERR31hj/oOVx/5gS2nrt4CPbysvI86fbib8o8AfY/PkVMeZLxBD/RLCb0WvGK1YC1ReJNpTS6Pl484QDQQmRCMNZ1qMJWWQZtIyytUg8G2eghj5WK64JAXjsuA22aWkr2NbQyX5PFIGdhO+VwtWXyzYko5Gys+7/Jupgux6mtwTFWScubMKfQZot5JBMpOU/xhSBiaGiu7XFO9kQXbvb4jfevS/ThMkZ+jWyDiIotP0LtK+VxAHQxlp85nE2YEzVUZHwA/b3QjX40IZl+hqcCcvSa0o4ykGRMW4MLhzHM7e+gXSCTKgY9vH2TqjSB2YvDXWg8C/UpBc+4zfOFr0DFYe+Hq8O3vIYl50GLeFRjmBMTlwd6ylJG0ifIHkvwthn9uAo0wF/hTgH6DlH/jXubPPyONFW19K/7qKq91JbylxCKCDpYAIszTSLtHhM5Eznb6r+zlNe4YWW4LwpwF/NfD7UIQpGqDTiDNoEXGwocHoJ0K6E2l742mOR6jzsyRnGqd4S6jyD/ne45uudDTvvoYX5K6Uh8eYOFNI3WMbxJlR2I4qSf7xmuFcbeya7hwvcHJKLtfpjz++vPPtvk83Jn+bD5iuBYp3TZLT2q3jeSmHkn90auHuRJ+QMkBnEfbjABkjOpPy76D6ir8hToOI5T/KpED5wclycta3wM+i1P9NpAwwLgrOXsPZbYUh3+MzVNPkfyR8GWSS4i2aKDnSvoOya0bhTydtAGdqfEScEpWx6D+09ie7M6sVb/HFkiP1v8D3UPofBqW+kTgisQzwBYsSLz7GQ1T9ZReLdg/UHZ9s+NpFHGB/4WrjCb7bFP2PxgeZVKIGyi8RbcnId1L4b5L8NsaOiQ8yqUgNVIwXbUnLgV+v/KuPfO/c//mUaAIDx5Z/f9k4yP9SqP9M0BXKfYXb7gxWHbNFIP+bzneklVcd+W6A7GwxRVcDwcMr71jmK9wSjFD/iFr/pwRYbVT/+P9ifyT4CX6Cn+D/f+DzGRlhIR7QeGnG0ae9quQh/EQYayEKkkSMNCcFXAcvoni5mPJBiAUNzhrL+LirTnrPaW/wor0Pvl3T/OWTREf6Oqv5Xa7d+jooNOPq+x6Cu5TqwgvkpKzdVvE7Xvnthbbk1vNNnC/7laqCUcDfFW9+pz9ubCc5m30Pzdn0DTE6f1RvybmSq/mWePG73rC7CxiLb3G1M53EBp1yyPeVjwVFe0NT+MltR6qtz5v5LBiJfyDGl5OLZJq4rpWCgj1OtKeuiYXf8Yr/TLV5cp6M0RuND1AJCvbFoOiuiJSf1nVictbZz/xs2CEmxkOv1gJVk6BfLGyMn3vR3JHu7NO/5OJ66D41UHkpKPiLaPy6rWeDlUc6SM6Mz6Bd9Ygvn0PnzxWC5Jxn5IduewtGQIYrs++XvOgYYAF/mmHpXdjhPbqhhaNFz+WQ/55xLn/g+8Lybzz8xTvb2FLbLYb+1S2udBj/tr3WPg/lj7HMQw+l4nB7MSlzJc9LuXEi+3d/MLxToGx/IFT+mvGDVce7SK5mK4DfKkIA3jesfwbKD/5t9/tnvGMm/03z7y3sJTnSlxl25TI7qgg/raaIteB/Cje8ckPB+udLI9E/aM+g+ooHwBi5BPjpjRUscUDtAoP5xW0zOy6IVP9paJtp1V86FMbIRRQnkPE4AW3qFmhTH0erfzXMLztTtHs+NzpB6p0TqLh8xxvdP4xV/2uQHyg/B8bILwy7kpEXW75V22Z2uqip+mc05a8Fq1bufLvvVAygGS/9tyF+6bYPkyV35sCy7R8dLNv9RaUV+ndDfBibftP6f4Kf4Cf4CX6CX3vQllQEiWKTxoW/ycYbJ3HRTUWuu2cJZ/7Gihk/gq3d4sY//u3jRyGN8XQYI5XnLzoSuu7ZSr6/JP8jZ2bvsXXGOiio/w2U5I/FWAtW8nlNoRotoLitCZTun4Brva3h89MbdP6o/jVK5bEr5JTcA3Hl8zwq/Y0uS4Hy36BUHh0fD37WWU/fDsbptKhMQC24TcO3m/XjLkXFtyVn3xWr80fX1F1asOIPYFhtjobvaNEnPR7OH5zargW9l4Fhsb6xc4mBvqzL9dsXC5LrfC4eh64d0YLVk4C/trFT5aRW+RX5C4e4c856VbAlTY0T/4SmeCcIsvubxk51txpSCPxz3G3OfgvOnxAnfjHwLzfEnaK/usjqf6LqyHfDnS16z45j+ZcA/7JI+Pb0Tgd8JzafaW+W9yEvOs6JV/nrin+a8eUD7ZCSs/cEy/YNlZJafcyLtoHxoGPEb9KnGpU/sjtze6Di0FD4+SmMM5HEfrHR23HLq7jaZWtRyX/JmfGz4i0eJtqTFwC/S2PNlaTa0ViQhzbrfd2jBeuf/3Os+geMketVX8lwAfm81NDYjmMhypzmWE+tz5s5+tCSG7Y3Vf+BMXItOmEEmxv5DSkrLXhe/KBZv5t3FG2cURQv/Uu0p6xWA+UjBNn1sRmf5/hLudpZmHHX/0SbZyXwzwT+p8CvFz9OUwMFVuufWP6Kt7CfrimXav7y0sPL/7KEOH+Y6L+pXSdheITVVurfjejAv2n9P8FP8BP8BD/B/9VzRDsU8hDG6NTRK5+19yiMMPO/SX55/qKDETp/4sLf+/HYld5jGyeDIjlLDVQ8AmlEhM6fJvFLt3+8Ateth2S/HJTp2ws3vnZWhM6fWPm8meGp+kvvrdy37OwInS8R89O6X+4Bg6MR549eCfx7Kvd9NShefDBio9gVSPdpgcq/ByuP9YvQ+UPlC5KD56KL/1DHD2rBqpdAoe4TofOnHv/o6r/9oqu+b5vQ/5D/glJd1DsS50+IE0ip2r9ybLDy6BW6FtzTBL6iKdVvqMGqnhhoM9KLMCjx9je6XVXD15XDTfJ9qb7ZmuLtGYnzpx7/310nKdUnpuHMtSZ5H9TAF5rq7x2J8yXECVVa9OPMC1Vf8W2U3ami5S/VtUCfaPgYFBnGrFHQd/9K2Z0qWv5iTfX1BX7E22ljgP7q4xvOgHH7IcruUFEdGPA/UH7weDTyB4MSK9WFQ7DvRCk3Q1teIFb5KznTd6q+0tOg77wWLZ+X7D2aKv9FR9ovMG72h77zToTyR3K26DMsXvqHaE/ZpAWr+2DfbZjP25JyhreLt/6DQZm1QFVv4L9H48N4st9K/Yvwe0L947IvrbY5Kccq8hc/z0L/k5wZ+bveGfiP/Lkj5/gKtwTirX9GsGtLQv9O8BP8BD/BT/At5UuNXIzrzqqJx8nJRT4DAK/1ErjShIf/zfAjmHkUV/7eTy7GHXA+idLx1CR+wYYXC6SkzLGeDhdcwYt2TVP8L6My33zAdEv5lfuWf5DaZcKVddO2MZgjKJBvBssOvILGHBi0ceeX7fi4ouWwR3fzgtwx3PYBfrD6XdzeGB1v8eSDUfYTGJPnNmx7Kce1oHe25i1+AR1PNltSk/ia4ktSvIUzJVeLOyO7UisEI+FDxVfyTzQm4XmjhpM4BeW+E5svklNz7xJEx2hetPWOkF8O/LeB/2KsfKgznG75QcH65z9O6375NaI99bqI+ZyO/E90xff3KB1vxvx/UJG/cIEza9C1oiP1JmhrnSLkB6DOvsDtlcGY2sCLMfPfBf4nruzTbxXsnluMb+Qb8jvoqn+5rilPoeMjlmljGJMGfrwE9T8b61+Uk66G/h1pEF5cDrQG0tOC5FrMxc5/2l+8c5acnH2fIDlxfIl4VwZgfw/pMeB/yXPRT2IjcdoeDZQffBfG0PsF2XU5dH9HFPw1uhp4RLQlr2hoyYepEyopC+XXdNVf+haM5Q9C/nHpTaRO4GCw+gTGHSpA+ROD7OMkV3Nc3nWz6it+iZecjwAfl7w22pJhfFwfD/kP/R3je12lBSpf50X5figDjO1luhuUUnl0ezz1D4wJAz8uVwPl/xRE+8PAHxPG17UCGJ82W6H/iPYUXEY3VQ1UvCqItrth7BsL7U+Gfr2x6MfX3rBa/yL8axVv0dOar6TLsbUP/1J58JtInaEN8iNsjwn9N8FP8BP8BD/B/83yaTGATM/lagMS2YnjSAp5IJ2AMKGQ9jXRc5Xg/z/n0wIN0o4ojIMG+a3OfiYzqe2oUbwgngiWHZiDQW2t5rce9XJecvvRT3OC1B6MrR/A4F8Hhvfq0m0f/ocYkHHnJ+UMT84ePeMRMAjHcJqGHRw4WglYvMd1NbhNC1avCJTvW2sS6Dtqfp3xiDtxdLrqh/N4QR4IqT0niNk8L6bXlolWpuMyF03ZDPzVmr98tT29U6ApfKPRivz2ExZ1kdwtzwNjsB8vSrkcL7aoKRddLSL8nbriX6MHq76S6YHGG+WbGcvI7zBxaXfRnQl8e18ogzyO51Mh2Thd98EzHNY19RdoB6s1NbAYg7pGw2/MSEd+3hVrBwi25NG8ZB/A8xLUgZDKc4JN19UKeIZjYPRvgTJYC93hc2LARsSPxEFQkb9QdGT2x6UpI8Ag7A9lnwf1n0KcAgG9Jv/KNniG1bwgfS5IriPxHHx8JzbLoitjKPDPF0THcGC043iheW39Q/vntGJo/5vg9zXw3UIwmPPjyQ9WHXdBvY8DQxj7QB9g5NWLU6Jrh3GHQSiHVVA3n8B525ta5vU8av4ybGsTgX0OL9j6wTjXjgt9gVPT/oObgP8d1MscyP+Ohtp6tHwtWIWBrSdAmZ8piPbB8LOlgQ99UN0E7X85PNtcXnTsa6iPR81XvNnAmALlPrJmaVot/+TXNcssVf+qsh3z7zi6+r4CElQ9orEtIo1K9eVC/4byl87moO/xgtCGBCtWVF/J27veG3IfjH3BSORvLA45yH9ryCPyh8HY2wM+OF51+LtHDyyctjla+R8TP1jVPFhxuNW+Ty45oAYqxKboH7HwyU5QCf0rwU/wE/wEP8FP8OPA/z8BBgB0NyAnicwKswAAAABJRU5ErkJggg==" />
-</g>
-
-</svg>
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/black_folder.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/black_folder.png
deleted file mode 100644
index 01ac4929616..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/black_folder.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/breadcrumb-separator.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/breadcrumb-separator.png
deleted file mode 100644
index bbbfbffcf82..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/breadcrumb-separator.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/button_list_view.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/button_list_view.png
deleted file mode 100644
index 09aa2fd3a58..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/button_list_view.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/button_list_view_white.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/button_list_view_white.png
deleted file mode 100644
index f89199a7e40..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/button_list_view_white.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/button_mosaic_view.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/button_mosaic_view.png
deleted file mode 100644
index 1961e46e121..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/button_mosaic_view.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/button_mosaic_view_white.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/button_mosaic_view_white.png
deleted file mode 100644
index ad6f856c651..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/button_mosaic_view_white.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/close_bar.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/close_bar.png
deleted file mode 100644
index 3f9e4528983..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/close_bar.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/drive_logo.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/drive_logo.png
deleted file mode 100644
index be900c88b2b..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/drive_logo.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/eject.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/eject.png
deleted file mode 100644
index f764c0c4c0f..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/eject.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/hashed_bg.gif b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/hashed_bg.gif
deleted file mode 100644
index 03651e6ef82..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/hashed_bg.gif
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/icon_search.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/icon_search.png
deleted file mode 100644
index 7f2ff27ceef..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/icon_search.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/offline.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/offline.png
deleted file mode 100644
index 6fe2d25de02..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/offline.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/onbutton_trash.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/onbutton_trash.png
deleted file mode 100644
index 593f53fdba4..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/onbutton_trash.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_closed.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_closed.png
deleted file mode 100644
index 92e9e784015..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_closed.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_closed_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_closed_hover.png
deleted file mode 100644
index 326f26f6ce2..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_closed_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_closed_pressed.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_closed_pressed.png
deleted file mode 100644
index 98aca06f061..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_closed_pressed.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_opened.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_opened.png
deleted file mode 100644
index 2e019075159..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_opened.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_opened_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_opened_hover.png
deleted file mode 100644
index 18481ce2989..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_opened_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_opened_pressed.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_opened_pressed.png
deleted file mode 100644
index 6f4e637d152..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/process_drawer_button_opened_pressed.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/search_clear.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/search_clear.png
deleted file mode 100644
index a76574afb43..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/search_clear.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/search_clear_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/search_clear_hover.png
deleted file mode 100644
index ed7155a8362..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/search_clear_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/search_clear_pressed.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/search_clear_pressed.png
deleted file mode 100644
index 2237a085992..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/search_clear_pressed.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/search_icon_active.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/search_icon_active.png
deleted file mode 100644
index d58cd100d67..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/search_icon_active.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/search_icon_inactive.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/search_icon_inactive.png
deleted file mode 100644
index 553ebbb1a68..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/search_icon_inactive.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/select_checkbox.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/select_checkbox.png
deleted file mode 100644
index e85e010f33b..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/select_checkbox.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/select_checkbox_checked.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/select_checkbox_checked.png
deleted file mode 100644
index e8792487a26..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/select_checkbox_checked.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/sort_asc.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/sort_asc.png
deleted file mode 100644
index 419b29ed735..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/sort_asc.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/sort_desc.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/sort_desc.png
deleted file mode 100644
index e7e74c58769..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/sort_desc.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/vertical_separator.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/vertical_separator.png
deleted file mode 100644
index 9d14b688ebf..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/vertical_separator.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/warning_icon_square.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/warning_icon_square.png
deleted file mode 100644
index 52a8b5a4298..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/warning_icon_square.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/white_folder.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/white_folder.png
deleted file mode 100644
index 9124621632c..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/2x/white_folder.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/black_folder.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/black_folder.png
deleted file mode 100644
index 539f67759a5..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/black_folder.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/breadcrumb-separator.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/breadcrumb-separator.png
deleted file mode 100644
index ed941270f61..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/breadcrumb-separator.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/button_list_view.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/button_list_view.png
deleted file mode 100644
index c553781c5e1..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/button_list_view.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/button_list_view_white.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/button_list_view_white.png
deleted file mode 100644
index 798df51a9c7..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/button_list_view_white.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/button_mosaic_view.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/button_mosaic_view.png
deleted file mode 100644
index 5690834ac3b..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/button_mosaic_view.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/button_mosaic_view_white.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/button_mosaic_view_white.png
deleted file mode 100644
index 9d4d518bfaa..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/button_mosaic_view_white.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/close_bar.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/close_bar.png
deleted file mode 100644
index f7232012fc1..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/close_bar.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/drive_logo.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/drive_logo.png
deleted file mode 100644
index b9ec5168cac..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/drive_logo.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/eject.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/eject.png
deleted file mode 100644
index dbbdb7f6fcb..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/eject.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/hashed_bg.gif b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/hashed_bg.gif
deleted file mode 100644
index 1e5bcfa09f8..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/hashed_bg.gif
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/offline.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/offline.png
deleted file mode 100644
index 259d3b20e78..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/offline.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/onbutton_trash.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/onbutton_trash.png
deleted file mode 100644
index 20ab756dc43..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/onbutton_trash.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_closed.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_closed.png
deleted file mode 100644
index 020e2e65f7c..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_closed.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_closed_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_closed_hover.png
deleted file mode 100644
index 193a49b37c4..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_closed_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_closed_pressed.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_closed_pressed.png
deleted file mode 100644
index bfee4b01376..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_closed_pressed.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_opened.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_opened.png
deleted file mode 100644
index c03e33708fb..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_opened.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_opened_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_opened_hover.png
deleted file mode 100644
index bf1aad74d5d..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_opened_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_opened_pressed.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_opened_pressed.png
deleted file mode 100644
index dbce527cd8b..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/process_drawer_button_opened_pressed.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/search_clear.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/search_clear.png
deleted file mode 100644
index 6755c4e8b17..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/search_clear.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/search_clear_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/search_clear_hover.png
deleted file mode 100644
index bbfd15f4867..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/search_clear_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/search_clear_pressed.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/search_clear_pressed.png
deleted file mode 100644
index 1825168c5c9..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/search_clear_pressed.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/search_icon_active.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/search_icon_active.png
deleted file mode 100644
index f59dfe340a7..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/search_icon_active.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/search_icon_inactive.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/search_icon_inactive.png
deleted file mode 100644
index 2f17e7c8c16..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/search_icon_inactive.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/select_checkbox.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/select_checkbox.png
deleted file mode 100644
index 4010b5c7212..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/select_checkbox.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/select_checkbox_checked.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/select_checkbox_checked.png
deleted file mode 100644
index d63f1a44143..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/select_checkbox_checked.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/sort_asc.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/sort_asc.png
deleted file mode 100644
index ed8c7d5b8af..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/sort_asc.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/sort_desc.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/sort_desc.png
deleted file mode 100644
index f0b2af0a667..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/sort_desc.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/vertical_separator.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/vertical_separator.png
deleted file mode 100644
index 512f37f09d6..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/vertical_separator.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/view_thumbs_black.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/view_thumbs_black.png
deleted file mode 100644
index 54448aee6a0..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/view_thumbs_black.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/warning_icon_square.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/warning_icon_square.png
deleted file mode 100644
index 90d6b608fdb..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/warning_icon_square.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/white_folder.png b/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/white_folder.png
deleted file mode 100644
index 07b6aa21f7f..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/files/ui/white_folder.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/arrow_left.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/arrow_left.png
deleted file mode 100644
index 6e4fb6659a7..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/arrow_left.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/arrow_right.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/arrow_right.png
deleted file mode 100644
index 22a6c739432..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/arrow_right.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/back_to_files.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/back_to_files.png
deleted file mode 100644
index e04d9d317c2..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/back_to_files.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/bubble_point.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/bubble_point.png
deleted file mode 100644
index 161e4c06be4..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/bubble_point.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/butterbar_close_button.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/butterbar_close_button.png
deleted file mode 100644
index aa6c816938d..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/butterbar_close_button.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_crop.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_crop.png
deleted file mode 100644
index 6202fa978a8..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_crop.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_leftright.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_leftright.png
deleted file mode 100644
index a7ee09c632e..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_leftright.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_move.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_move.png
deleted file mode 100644
index faa3c8ac398..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_move.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_nwse.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_nwse.png
deleted file mode 100644
index 0cd6399da7e..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_nwse.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_swne.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_swne.png
deleted file mode 100644
index 04d9dc02702..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_swne.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_updown.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_updown.png
deleted file mode 100644
index 1e9adfb5165..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/cursor_updown.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_1up.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_1up.png
deleted file mode 100644
index 58cbc28c4cb..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_1up.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_1up_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_1up_selected.png
deleted file mode 100644
index a0ca726fa0d..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_1up_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_autofix.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_autofix.png
deleted file mode 100644
index 8ce4917d4d2..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_autofix.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_autofix_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_autofix_selected.png
deleted file mode 100644
index 8838d5ce5fd..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_autofix_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_brightness.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_brightness.png
deleted file mode 100644
index ffcd3852947..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_brightness.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_brightness_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_brightness_selected.png
deleted file mode 100644
index 90bf03bbd82..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_brightness_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_contrast.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_contrast.png
deleted file mode 100644
index eec931d56de..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_contrast.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_crop.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_crop.png
deleted file mode 100644
index 7c12fb54231..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_crop.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_crop_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_crop_selected.png
deleted file mode 100644
index bb2e9e6cc0f..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_crop_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_delete.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_delete.png
deleted file mode 100644
index a55ac6c8086..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_delete.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_delete_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_delete_selected.png
deleted file mode 100644
index af54168a2e6..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_delete_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_edit.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_edit.png
deleted file mode 100644
index 288bc5b7e47..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_edit.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_edit_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_edit_selected.png
deleted file mode 100644
index bcf993396dc..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_edit_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_mosaic.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_mosaic.png
deleted file mode 100644
index 3e1a621b559..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_mosaic.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_mosaic_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_mosaic_selected.png
deleted file mode 100644
index d9e329d9070..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_mosaic_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_print.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_print.png
deleted file mode 100644
index b5a9be0c6ba..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_print.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_print_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_print_selected.png
deleted file mode 100644
index 048a34172ec..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_print_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_redo.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_redo.png
deleted file mode 100644
index 075275da898..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_redo.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_redo_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_redo_selected.png
deleted file mode 100644
index beed584ffe3..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_redo_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_rotate.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_rotate.png
deleted file mode 100644
index db2c0b09f9f..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_rotate.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_rotate_left.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_rotate_left.png
deleted file mode 100644
index da57329d898..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_rotate_left.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_rotate_left_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_rotate_left_selected.png
deleted file mode 100644
index d1b00a7e732..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_rotate_left_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_rotate_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_rotate_selected.png
deleted file mode 100644
index b3a9bf60a28..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_rotate_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_share.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_share.png
deleted file mode 100644
index b1da6d96d47..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_share.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_share_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_share_selected.png
deleted file mode 100644
index b3cd00f1118..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_share_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_slideshow.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_slideshow.png
deleted file mode 100644
index fec87c0ae9a..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_slideshow.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_slideshow_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_slideshow_selected.png
deleted file mode 100644
index 4e1ed5aabfa..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_slideshow_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_undo.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_undo.png
deleted file mode 100644
index c51fd6258ec..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_undo.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_undo_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_undo_selected.png
deleted file mode 100644
index 92d3a01d8e1..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/icon_undo_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/slider_thumb.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/slider_thumb.png
deleted file mode 100644
index e100da62618..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/slider_thumb.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/slideshow-end.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/slideshow-end.png
deleted file mode 100644
index 5e19f8d002b..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/slideshow-end.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/slideshow-pause.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/slideshow-pause.png
deleted file mode 100644
index 13457d999fa..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/slideshow-pause.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/slideshow-play.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/slideshow-play.png
deleted file mode 100644
index aa9bd88fc8d..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/2x/slideshow-play.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/arrow_left.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/arrow_left.png
deleted file mode 100644
index 85e687a1168..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/arrow_left.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/arrow_right.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/arrow_right.png
deleted file mode 100644
index 0361556bd20..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/arrow_right.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/back_to_files.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/back_to_files.png
deleted file mode 100644
index 96e420a657f..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/back_to_files.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/bubble_point.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/bubble_point.png
deleted file mode 100644
index a4a44e0cf09..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/bubble_point.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/butterbar_close_button.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/butterbar_close_button.png
deleted file mode 100644
index 3c65c230151..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/butterbar_close_button.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_crop.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_crop.png
deleted file mode 100644
index 6084188e0a7..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_crop.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_leftright.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_leftright.png
deleted file mode 100644
index 30eeb03accf..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_leftright.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_move.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_move.png
deleted file mode 100644
index c5026d1b419..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_move.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_nwse.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_nwse.png
deleted file mode 100644
index 87fb564ba66..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_nwse.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_swne.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_swne.png
deleted file mode 100644
index 5e34475c863..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_swne.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_updown.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_updown.png
deleted file mode 100644
index f3a422477c8..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/cursor_updown.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_1up.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_1up.png
deleted file mode 100644
index 546e87ae49f..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_1up.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_1up_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_1up_selected.png
deleted file mode 100644
index a3043a8a05a..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_1up_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_autofix.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_autofix.png
deleted file mode 100644
index 0fb5b827d76..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_autofix.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_autofix_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_autofix_selected.png
deleted file mode 100644
index fb5972d4d9d..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_autofix_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_brightness.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_brightness.png
deleted file mode 100644
index ec9c114d245..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_brightness.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_brightness_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_brightness_selected.png
deleted file mode 100644
index 88ee72290aa..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_brightness_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_contrast.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_contrast.png
deleted file mode 100644
index 0188d483448..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_contrast.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_crop.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_crop.png
deleted file mode 100644
index efff5ba58ff..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_crop.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_crop_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_crop_selected.png
deleted file mode 100644
index 18b8317cbac..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_crop_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_delete.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_delete.png
deleted file mode 100644
index efb132aa722..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_delete.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_delete_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_delete_selected.png
deleted file mode 100644
index f2f88d8d0f9..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_delete_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_edit.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_edit.png
deleted file mode 100644
index fc72ecf3b60..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_edit.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_edit_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_edit_selected.png
deleted file mode 100644
index 61540b5b467..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_edit_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_mosaic.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_mosaic.png
deleted file mode 100644
index 6e49d3c929a..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_mosaic.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_mosaic_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_mosaic_selected.png
deleted file mode 100644
index 86edb6e1ec0..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_mosaic_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_print.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_print.png
deleted file mode 100644
index b2355367c25..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_print.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_print_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_print_selected.png
deleted file mode 100644
index 657b9c8e290..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_print_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_redo.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_redo.png
deleted file mode 100644
index 7b4703b6188..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_redo.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_redo_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_redo_selected.png
deleted file mode 100644
index 0022a136d09..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_redo_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_rotate.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_rotate.png
deleted file mode 100644
index c60f258f6be..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_rotate.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_rotate_left.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_rotate_left.png
deleted file mode 100644
index ef2f21f4356..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_rotate_left.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_rotate_left_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_rotate_left_selected.png
deleted file mode 100644
index 1e4c1d6d62f..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_rotate_left_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_rotate_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_rotate_selected.png
deleted file mode 100644
index 445350fcaf6..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_rotate_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_share.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_share.png
deleted file mode 100644
index 36bb2218a82..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_share.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_share_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_share_selected.png
deleted file mode 100644
index 438e8a2599a..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_share_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_slideshow.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_slideshow.png
deleted file mode 100644
index 72763d44ed1..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_slideshow.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_slideshow_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_slideshow_selected.png
deleted file mode 100644
index 4f80a48d403..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_slideshow_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_undo.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_undo.png
deleted file mode 100644
index 79e3fddf26b..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_undo.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_undo_selected.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_undo_selected.png
deleted file mode 100644
index d5d13a71a9f..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/icon_undo_selected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/slider_thumb.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/slider_thumb.png
deleted file mode 100644
index cb2d712068f..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/slider_thumb.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/slideshow-end.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/slideshow-end.png
deleted file mode 100644
index f4371115363..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/slideshow-end.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/slideshow-pause.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/slideshow-pause.png
deleted file mode 100644
index 2170ce90cfc..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/slideshow-pause.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/slideshow-play.png b/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/slideshow-play.png
deleted file mode 100644
index f949121d245..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/gallery/slideshow-play.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/audio_player.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/audio_player.png
deleted file mode 100644
index ce5fa1ab7a9..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/audio_player.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/drive.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/drive.png
deleted file mode 100644
index b2cef7191e7..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/drive.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/error.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/error.png
deleted file mode 100644
index 200baf571a3..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/error.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_close.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_close.png
deleted file mode 100644
index 2e19603f5cd..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_close.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_collapse.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_collapse.png
deleted file mode 100644
index a9400612019..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_collapse.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_expand.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_expand.png
deleted file mode 100644
index 20c234003fd..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_expand.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_fullscreen.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_fullscreen.png
deleted file mode 100644
index 090c8257ae6..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_fullscreen.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_fullscreen_disabled.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_fullscreen_disabled.png
deleted file mode 100644
index 96b3f635a83..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_fullscreen_disabled.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_fullscreen_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_fullscreen_down.png
deleted file mode 100644
index 14cbeecaa87..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_fullscreen_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_fullscreen_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_fullscreen_hover.png
deleted file mode 100644
index 25daa4fb6e6..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_fullscreen_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_loop.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_loop.png
deleted file mode 100644
index 6bea029799a..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_loop.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_loop_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_loop_down.png
deleted file mode 100644
index 0e4b6e26d00..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_loop_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_loop_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_loop_hover.png
deleted file mode 100644
index b3a6c144a3e..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_loop_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_next.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_next.png
deleted file mode 100644
index 012af925e4a..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_next.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_next_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_next_down.png
deleted file mode 100644
index 58d5bf724e5..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_next_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_next_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_next_hover.png
deleted file mode 100644
index d8d199575dc..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_next_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause.png
deleted file mode 100644
index acebff9d4a0..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause_audio.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause_audio.png
deleted file mode 100644
index 7489a7ed43a..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause_audio.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause_audio_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause_audio_down.png
deleted file mode 100644
index f9242360d7d..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause_audio_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause_audio_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause_audio_hover.png
deleted file mode 100644
index 160d3d11145..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause_audio_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause_down.png
deleted file mode 100644
index 9caaf7a0e19..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause_hover.png
deleted file mode 100644
index beb86f2e89a..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_pause_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play.png
deleted file mode 100644
index 28e8a25c032..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_audio.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_audio.png
deleted file mode 100644
index 16f663260c9..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_audio.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_audio_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_audio_down.png
deleted file mode 100644
index 01dcc462306..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_audio_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_audio_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_audio_hover.png
deleted file mode 100644
index c64070f4a24..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_audio_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_disabled.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_disabled.png
deleted file mode 100644
index 77ea7c01091..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_disabled.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_down.png
deleted file mode 100644
index 7c68787119f..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_hover.png
deleted file mode 100644
index 28ca18b0551..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_play_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_previous.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_previous.png
deleted file mode 100644
index 399e5a00e43..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_previous.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_previous_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_previous_down.png
deleted file mode 100644
index 94741583314..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_previous_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_previous_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_previous_hover.png
deleted file mode 100644
index 0a8a919c330..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_previous_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_slider_thumb.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_slider_thumb.png
deleted file mode 100644
index cd20aa2967f..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_slider_thumb.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_slider_thumb_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_slider_thumb_down.png
deleted file mode 100644
index 931850f3f52..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_slider_thumb_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_slider_thumb_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_slider_thumb_hover.png
deleted file mode 100644
index 9fe30ef7442..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_slider_thumb_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_disabled.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_disabled.png
deleted file mode 100644
index acbaa71be9b..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_disabled.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_disabled_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_disabled_down.png
deleted file mode 100644
index f594f47e774..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_disabled_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_disabled_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_disabled_hover.png
deleted file mode 100644
index f4cc7b350f5..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_disabled_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_full.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_full.png
deleted file mode 100644
index a093e9f6cd0..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_full.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_full_disabled.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_full_disabled.png
deleted file mode 100644
index 56635f1d9b7..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_full_disabled.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_full_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_full_down.png
deleted file mode 100644
index 7d2a2395049..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_full_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_full_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_full_hover.png
deleted file mode 100644
index f183edd7362..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_full_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level1.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level1.png
deleted file mode 100644
index 25904c0d176..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level1.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level1_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level1_down.png
deleted file mode 100644
index 0ba2886fbfb..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level1_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level1_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level1_hover.png
deleted file mode 100644
index be56fc17e6a..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level1_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level2.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level2.png
deleted file mode 100644
index 24f7ea805c1..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level2.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level2_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level2_down.png
deleted file mode 100644
index 34fce547aa9..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level2_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level2_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level2_hover.png
deleted file mode 100644
index 2e3f2e80cd5..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_sound_level2_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_volume_slider_thumb.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_volume_slider_thumb.png
deleted file mode 100644
index d5cf0c56e52..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_volume_slider_thumb.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_volume_slider_thumb_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_volume_slider_thumb_down.png
deleted file mode 100644
index 034c7b807c3..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_volume_slider_thumb_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_volume_slider_thumb_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_volume_slider_thumb_hover.png
deleted file mode 100644
index 4d4243d0f0c..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/media_volume_slider_thumb_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/watch.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/watch.png
deleted file mode 100644
index f47751be542..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/2x/watch.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/audio_player.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/audio_player.png
deleted file mode 100644
index 6921db2f33d..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/audio_player.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/drive.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/drive.png
deleted file mode 100644
index 8f4b64ee8bd..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/drive.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/error.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/error.png
deleted file mode 100644
index 125c0b75899..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/error.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_close.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_close.png
deleted file mode 100644
index 5980ea7504a..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_close.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_collapse.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_collapse.png
deleted file mode 100644
index 3ab1add2a9c..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_collapse.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_expand.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_expand.png
deleted file mode 100644
index a228fbdf275..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_expand.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_fullscreen.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_fullscreen.png
deleted file mode 100644
index 24f2ecf2f1d..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_fullscreen.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_fullscreen_disabled.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_fullscreen_disabled.png
deleted file mode 100644
index bf74390888c..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_fullscreen_disabled.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_fullscreen_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_fullscreen_down.png
deleted file mode 100644
index dd318cec7d6..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_fullscreen_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_fullscreen_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_fullscreen_hover.png
deleted file mode 100644
index 42327397887..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_fullscreen_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_loop.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_loop.png
deleted file mode 100644
index f3e35dd9d4a..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_loop.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_loop_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_loop_down.png
deleted file mode 100644
index dda8af53979..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_loop_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_loop_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_loop_hover.png
deleted file mode 100644
index a0ed21fccb8..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_loop_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_next.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_next.png
deleted file mode 100644
index aec4ee676a8..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_next.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_next_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_next_down.png
deleted file mode 100644
index 53cc1062da0..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_next_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_next_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_next_hover.png
deleted file mode 100644
index bea50b59347..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_next_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause.png
deleted file mode 100644
index 0a304e4bd04..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause_audio.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause_audio.png
deleted file mode 100644
index 8e2e87be5c4..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause_audio.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause_audio_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause_audio_down.png
deleted file mode 100644
index 11789840f5b..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause_audio_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause_audio_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause_audio_hover.png
deleted file mode 100644
index 52b6bbcbf37..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause_audio_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause_down.png
deleted file mode 100644
index 6e65195cbea..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause_hover.png
deleted file mode 100644
index 993ee50a4f3..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_pause_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play.png
deleted file mode 100644
index 47bcdc29b17..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_audio.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_audio.png
deleted file mode 100644
index eceaa5bb82b..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_audio.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_audio_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_audio_down.png
deleted file mode 100644
index 98ebeeaa120..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_audio_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_audio_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_audio_hover.png
deleted file mode 100644
index f9d97d7714a..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_audio_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_disabled.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_disabled.png
deleted file mode 100644
index 6e96d4c9c67..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_disabled.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_down.png
deleted file mode 100644
index 1759ec39afa..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_hover.png
deleted file mode 100644
index 3942d462656..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_play_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_previous.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_previous.png
deleted file mode 100644
index 4fded35ad47..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_previous.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_previous_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_previous_down.png
deleted file mode 100644
index 2c63184167e..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_previous_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_previous_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_previous_hover.png
deleted file mode 100644
index 45ea61b3b59..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_previous_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_slider_thumb.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_slider_thumb.png
deleted file mode 100644
index e55b2c25128..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_slider_thumb.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_slider_thumb_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_slider_thumb_down.png
deleted file mode 100644
index f0b2be7d653..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_slider_thumb_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_slider_thumb_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_slider_thumb_hover.png
deleted file mode 100644
index e216ae6ffbd..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_slider_thumb_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_disabled.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_disabled.png
deleted file mode 100644
index 42126de9330..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_disabled.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_disabled_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_disabled_down.png
deleted file mode 100644
index 2b494b93652..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_disabled_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_disabled_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_disabled_hover.png
deleted file mode 100644
index 5040f8078d3..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_disabled_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_full.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_full.png
deleted file mode 100644
index 4a034029d5c..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_full.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_full_disabled.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_full_disabled.png
deleted file mode 100644
index cef4bc4c6d0..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_full_disabled.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_full_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_full_down.png
deleted file mode 100644
index 55d77e4d496..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_full_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_full_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_full_hover.png
deleted file mode 100644
index 881e84305fb..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_full_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level1.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level1.png
deleted file mode 100644
index 2f7ceea32e4..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level1.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level1_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level1_down.png
deleted file mode 100644
index 9777c9b5a0b..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level1_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level1_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level1_hover.png
deleted file mode 100644
index fdf3bc1331b..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level1_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level2.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level2.png
deleted file mode 100644
index 9379a038ba9..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level2.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level2_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level2_down.png
deleted file mode 100644
index 422b43518be..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level2_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level2_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level2_hover.png
deleted file mode 100644
index 8bf6157edf4..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_sound_level2_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_volume_slider_thumb.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_volume_slider_thumb.png
deleted file mode 100644
index a1bf0577905..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_volume_slider_thumb.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_volume_slider_thumb_down.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_volume_slider_thumb_down.png
deleted file mode 100644
index a4560f0ffc2..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_volume_slider_thumb_down.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_volume_slider_thumb_hover.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_volume_slider_thumb_hover.png
deleted file mode 100644
index 159e2e71f3e..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/media_volume_slider_thumb_hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/media/watch.png b/chromium/chrome/browser/resources/file_manager/foreground/images/media/watch.png
deleted file mode 100644
index 92b628497fb..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/media/watch.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/archive.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/archive.png
deleted file mode 100644
index b5821d4da5b..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/archive.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_archive.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_archive.png
deleted file mode 100644
index 6927bdd188e..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_archive.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_downloads.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_downloads.png
deleted file mode 100644
index ab37f07104c..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_downloads.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_drive.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_drive.png
deleted file mode 100644
index a17a0b19330..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_drive.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_hdd.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_hdd.png
deleted file mode 100644
index e0ec6965c2a..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_hdd.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_offline.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_offline.png
deleted file mode 100644
index 87029a9355c..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_offline.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_optical.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_optical.png
deleted file mode 100644
index 5077474e3b1..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_optical.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_phone.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_phone.png
deleted file mode 100644
index c4521dec634..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_phone.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_recent.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_recent.png
deleted file mode 100644
index e1b86212136..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_recent.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_sd.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_sd.png
deleted file mode 100644
index 5679089adcf..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_sd.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_shared.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_shared.png
deleted file mode 100644
index ec7c3e4779a..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_shared.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_trash.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_trash.png
deleted file mode 100644
index 67f261f460a..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_trash.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_usb.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_usb.png
deleted file mode 100644
index 2cceca66e9c..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/black_usb.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_hd.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_hd.png
deleted file mode 100644
index e0ec6965c2a..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_hd.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_optical.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_optical.png
deleted file mode 100644
index 5077474e3b1..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_optical.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_sd.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_sd.png
deleted file mode 100644
index 5679089adcf..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_sd.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_sd_large.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_sd_large.png
deleted file mode 100644
index 6fa0c756dce..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_sd_large.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_usb.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_usb.png
deleted file mode 100644
index 70e9686f3a2..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_usb.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_usb_large.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_usb_large.png
deleted file mode 100644
index 17a8fee01f7..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/device_usb_large.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/downloads.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/downloads.png
deleted file mode 100644
index 22e66179190..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/downloads.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/drive.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/drive.png
deleted file mode 100644
index a17a0b19330..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/drive.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/drive_offline.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/drive_offline.png
deleted file mode 100644
index 75981854cd6..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/drive_offline.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/drive_recent.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/drive_recent.png
deleted file mode 100644
index 756e36a2e38..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/drive_recent.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/drive_shared.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/drive_shared.png
deleted file mode 100644
index c2eb5dafb30..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/drive_shared.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/folder.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/folder.png
deleted file mode 100644
index 01ac4929616..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/folder.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_archive.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_archive.png
deleted file mode 100644
index 481c40b89f1..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_archive.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_downloads.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_downloads.png
deleted file mode 100644
index 5262bb910a8..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_downloads.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_drive.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_drive.png
deleted file mode 100644
index 5f43989d923..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_drive.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_hdd.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_hdd.png
deleted file mode 100644
index bc5e8c417d9..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_hdd.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_offline.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_offline.png
deleted file mode 100644
index 9d65b392094..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_offline.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_optical.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_optical.png
deleted file mode 100644
index c67537714dd..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_optical.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_phone.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_phone.png
deleted file mode 100644
index 2dfb8f27d61..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_phone.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_recent.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_recent.png
deleted file mode 100644
index a80eae2c8b3..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_recent.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_sd.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_sd.png
deleted file mode 100644
index 282de9aa9af..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_sd.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_shared.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_shared.png
deleted file mode 100644
index 24ea1676b15..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_shared.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_trash.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_trash.png
deleted file mode 100644
index f6c5ccb03f4..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_trash.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_usb.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_usb.png
deleted file mode 100644
index f296f4e0245..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/2x/white_usb.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_archive.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_archive.png
deleted file mode 100644
index e4514206fbd..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_archive.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_downloads.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_downloads.png
deleted file mode 100644
index e25c8756b32..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_downloads.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_drive.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_drive.png
deleted file mode 100644
index 891ec480c47..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_drive.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_folder.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_folder.png
deleted file mode 100644
index 539f67759a5..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_folder.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_hdd.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_hdd.png
deleted file mode 100644
index 53c02b4c48c..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_hdd.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_offline.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_offline.png
deleted file mode 100644
index a07ef0cb483..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_offline.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_optical.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_optical.png
deleted file mode 100644
index 30a905fbc9c..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_optical.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_phone.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_phone.png
deleted file mode 100644
index aa3aa9deb7c..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_phone.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_recent.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_recent.png
deleted file mode 100644
index 6e5d3636bff..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_recent.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_sd.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_sd.png
deleted file mode 100644
index f24b4cefb74..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_sd.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_shared.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_shared.png
deleted file mode 100644
index 10a1553b9b0..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_shared.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_trash.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_trash.png
deleted file mode 100644
index 7708ae555a6..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_trash.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_usb.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_usb.png
deleted file mode 100644
index ba7ef472471..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/black_usb.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/device_sd_large.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/device_sd_large.png
deleted file mode 100644
index 39d2fe90a49..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/device_sd_large.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/device_usb_large.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/device_usb_large.png
deleted file mode 100644
index 6b68508f7d8..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/device_usb_large.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_archive.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_archive.png
deleted file mode 100644
index 3b542deac45..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_archive.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_downloads.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_downloads.png
deleted file mode 100644
index 8b1cfdf7400..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_downloads.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_drive.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_drive.png
deleted file mode 100644
index 0226fbd14ed..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_drive.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_folder.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_folder.png
deleted file mode 100644
index 07b6aa21f7f..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_folder.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_hdd.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_hdd.png
deleted file mode 100644
index b7c4a485c94..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_hdd.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_offline.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_offline.png
deleted file mode 100644
index 503ed67f82f..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_offline.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_optical.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_optical.png
deleted file mode 100644
index 3f13f723af4..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_optical.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_phone.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_phone.png
deleted file mode 100644
index d187ef0951b..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_phone.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_recent.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_recent.png
deleted file mode 100644
index 23c526ad8b2..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_recent.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_sd.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_sd.png
deleted file mode 100644
index f7f465c430b..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_sd.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_shared.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_shared.png
deleted file mode 100644
index 051191e6de1..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_shared.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_trash.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_trash.png
deleted file mode 100644
index f95d0215ee4..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_trash.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_usb.png b/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_usb.png
deleted file mode 100644
index 954a3c6dae3..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/images/volumes/white_usb.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/app_installer.js b/chromium/chrome/browser/resources/file_manager/foreground/js/app_installer.js
deleted file mode 100644
index 7914d6e458f..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/app_installer.js
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Manage the installation of apps.
- *
- * @param {string} itemId Item id to be installed.
- * @constructor
- * @extends {cr.EventType}
- */
-function AppInstaller(itemId) {
- this.itemId_ = itemId;
- this.callback_ = null;
-
- Object.seal(this);
-}
-
-AppInstaller.prototype = {
-};
-
-/**
- * Type of result.
- *
- * @enum {string}
- * @const
- */
-AppInstaller.Result = {
- SUCCESS: 'AppInstaller.success',
- CANCELLED: 'AppInstaller.cancelled',
- ERROR: 'AppInstaller.error'
-};
-Object.freeze(AppInstaller.Result);
-
-/**
- * Error message for user cancellation. This must be match with the constant
- * 'kUserCancelledError' in C/B/extensions/webstore_standalone_installer.cc.
- * @type {string}
- * @const
- * @private
- */
-AppInstaller.USER_CANCELLED_ERROR_STR_ = 'User cancelled install';
-
-/**
- * Start an installation.
- * @param {function(boolean, string)} callback Called when the installation is
- * finished.
- */
-AppInstaller.prototype.install = function(callback) {
- this.callback_ = callback;
- chrome.fileBrowserPrivate.installWebstoreItem(
- this.itemId_,
- function() {
- this.onInstallCompleted_(chrome.runtime.lastError);
- }.bind(this));
-};
-
-/**
- * Called when the installation is completed.
- *
- * @param {{message: string}?} error Null if the installation is success,
- * otherwise an object which contains error message.
- * @private
- */
-AppInstaller.prototype.onInstallCompleted_ = function(error) {
- var installerResult = AppInstaller.Result.SUCCESS;
- var errorMessage = '';
- if (error) {
- installerResult =
- error.message == AppInstaller.USER_CANCELLED_ERROR_STR_ ?
- AppInstaller.Result.CANCELLED :
- AppInstaller.Result.ERROR;
- errorMessage = error.message;
- }
- this.callback_(installerResult, errorMessage);
- this.callback_ = null;
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/combobutton.js b/chromium/chrome/browser/resources/file_manager/foreground/js/combobutton.js
deleted file mode 100644
index 59ae9f2b6ed..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/combobutton.js
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * @fileoverview This implements a combobutton control.
- */
-
-cr.define('cr.ui', function() {
- /**
- * Creates a new combobutton element.
- * @param {Object=} opt_propertyBag Optional properties.
- * @constructor
- * @extends {HTMLUListElement}
- */
- var ComboButton = cr.ui.define(cr.ui.MenuButton);
-
-
- ComboButton.prototype = {
- __proto__: cr.ui.MenuButton.prototype,
-
- defaultItem_: null,
-
- /**
- * Truncates drop-down list.
- */
- clear: function() {
- this.menu.clear();
- this.multiple = false;
- },
-
- addDropDownItem: function(item) {
- this.multiple = true;
- var menuitem = this.menu.addMenuItem(item);
- menuitem.data = item;
- if (item.iconType) {
- menuitem.style.backgroundImage = '';
- menuitem.setAttribute('file-type-icon', item.iconType);
- }
- if (item.bold) {
- menuitem.style.fontWeight = 'bold';
- }
- return menuitem;
- },
-
- /**
- * Adds separator to drop-down list.
- */
- addSeparator: function() {
- this.menu.addSeparator();
- },
-
- /**
- * Default item to fire on combobox click
- */
- get defaultItem() {
- return this.defaultItem_;
- },
- set defaultItem(defaultItem) {
- this.defaultItem_ = defaultItem;
-
- this.actionNode_.textContent = defaultItem.label || '';
-
- if (defaultItem.iconType) {
- this.actionNode_.style.backgroundImage = '';
- this.actionNode_.setAttribute('file-type-icon', defaultItem.iconType);
- } else if (defaultItem.iconUrl) {
- this.actionNode_.style.backgroundImage =
- 'url(' + defaultItem.iconUrl + ')';
- } else {
- this.actionNode_.style.backgroundImage = '';
- }
- },
-
- /**
- * Initializes the element.
- */
- decorate: function() {
- cr.ui.MenuButton.prototype.decorate.call(this);
-
- this.classList.add('combobutton');
-
- this.actionNode_ = this.ownerDocument.createElement('div');
- this.actionNode_.classList.add('action');
- this.appendChild(this.actionNode_);
-
- var triggerIcon = this.ownerDocument.createElement('span');
- triggerIcon.className = 'disclosureindicator';
- this.trigger_ = this.ownerDocument.createElement('div');
- this.trigger_.classList.add('trigger');
- this.trigger_.appendChild(triggerIcon);
-
- this.appendChild(this.trigger_);
-
- this.addEventListener('click', this.handleButtonClick_.bind(this));
-
- this.trigger_.addEventListener('click',
- this.handleTriggerClicked_.bind(this));
-
- this.menu.addEventListener('activate',
- this.handleMenuActivate_.bind(this));
-
- // Remove mousedown event listener created by MenuButton::decorate,
- // and move it down to trigger_.
- this.removeEventListener('mousedown', this);
- this.trigger_.addEventListener('mousedown', this);
- },
-
- /**
- * Handles the keydown event for the menu button.
- */
- handleKeyDown: function(e) {
- switch (e.keyIdentifier) {
- case 'Down':
- case 'Up':
- if (!this.isMenuShown())
- this.showMenu();
- e.preventDefault();
- break;
- case 'Esc':
- case 'U+001B': // Maybe this is remote desktop playing a prank?
- this.hideMenu();
- break;
- }
- },
-
- handleTriggerClicked_: function(event) {
- event.stopPropagation();
- },
-
- handleMenuActivate_: function(event) {
- this.dispatchSelectEvent(event.target.data);
- },
-
- handleButtonClick_: function() {
- this.dispatchSelectEvent(this.defaultItem_);
- },
-
- dispatchSelectEvent: function(item) {
- var selectEvent = new Event('select');
- selectEvent.item = item;
- this.dispatchEvent(selectEvent);
- }
- };
-
- cr.defineProperty(ComboButton, 'disabled', cr.PropertyKind.BOOL_ATTR);
- cr.defineProperty(ComboButton, 'multiple', cr.PropertyKind.BOOL_ATTR);
-
- return {
- ComboButton: ComboButton
- };
-});
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/commandbutton.js b/chromium/chrome/browser/resources/file_manager/foreground/js/commandbutton.js
deleted file mode 100644
index b6f2b916cd3..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/commandbutton.js
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * @fileoverview This implements a common button control, bound to command.
- */
-
-/**
- * Creates a new button element.
- * @param {Object=} opt_propertyBag Optional properties.
- * @constructor
- * @extends {HTMLDivElement}
- */
- var CommandButton = cr.ui.define('button');
-
-/** @override */
-CommandButton.prototype.__proto__ = HTMLButtonElement.prototype;
-
-/**
- * Associated command.
- * @type {Command}
- * @private
- */
-CommandButton.prototype.command_ = null;
-
-/**
- * Initializes the menu item.
- */
-CommandButton.prototype.decorate = function() {
- var commandId;
- if ((commandId = this.getAttribute('command')))
- this.setCommand(commandId);
-
- this.addEventListener('click', this.handleClick_.bind(this));
-};
-
-/**
- * Returns associated command.
- * @return {cr.ui.Command} associated command.
- */
-CommandButton.prototype.getCommand = function() {
- return this.command_;
-};
-
-/**
- * Associates command with this button.
- * @param {string|cr.ui.Command} command Command id, or command object to
- * associate with this button.
- */
-CommandButton.prototype.setCommand = function(command) {
- if (this.command_) {
- this.command_.removeEventListener('labelChange', this);
- this.command_.removeEventListener('disabledChange', this);
- this.command_.removeEventListener('hiddenChange', this);
- }
-
- if (typeof command == 'string' && command[0] == '#') {
- command = this.ownerDocument.getElementById(command.slice(1));
- cr.ui.decorate(command, cr.ui.Command);
- }
-
- this.command_ = command;
- if (command) {
- if (command.id)
- this.setAttribute('command', '#' + command.id);
-
- this.setLabel(command.label);
- this.disabled = command.disabled;
- this.hidden = command.hidden;
-
- this.command_.addEventListener('labelChange', this);
- this.command_.addEventListener('disabledChange', this);
- this.command_.addEventListener('hiddenChange', this);
- }
-};
-
-/**
- * Returns button label
- * @return {string} Button label.
- */
-CommandButton.prototype.getLabel = function() {
- return this.textContent;
-};
-
-/**
- * Sets button label.
- * @param {string} label New button label.
- */
-CommandButton.prototype.setLabel = function(label) {
- this.textContent = label;
-};
-
-/**
- * Handles click event and dispatches associated command.
- * @param {Event} e The mouseup event object.
- * @private
- */
-CommandButton.prototype.handleClick_ = function(e) {
- if (!this.disabled && this.command_)
- this.command_.execute(this);
-};
-
-/**
- * Handles changes to the associated command.
- * @param {Event} e The event object.
- */
-CommandButton.prototype.handleEvent = function(e) {
- switch (e.type) {
- case 'disabledChange':
- this.disabled = this.command_.disabled;
- break;
- case 'hiddenChange':
- this.hidden = this.command_.hidden;
- break;
- case 'labelChange':
- this.setLabel(this.command_.label);
- break;
- }
-};
-
-/**
- * Whether the button is disabled or not.
- * @type {boolean}
- */
-cr.defineProperty(CommandButton, 'disabled',
- cr.PropertyKind.BOOL_ATTR);
-
-/**
- * Whether the button is hidden or not.
- * @type {boolean}
- */
-cr.defineProperty(CommandButton, 'hidden',
- cr.PropertyKind.BOOL_ATTR);
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/cws_container_client.js b/chromium/chrome/browser/resources/file_manager/foreground/js/cws_container_client.js
deleted file mode 100644
index fae6787a5ad..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/cws_container_client.js
+++ /dev/null
@@ -1,249 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * @param {WebView} webView Web View tag.
- * @param {?string} ext File extension.
- * @param {?string} mime File mime type.
- * @param {?string} searchQuery Search query.
- * @param {number} width Width of the CWS widget.
- * @param {number} height Height of the CWS widget.
- * @param {string} url Share Url for an entry.
- * @param {string} target Target (scheme + host + port) of the widget.
- * @constructor
- */
-function CWSContainerClient(
- webView, ext, mime, searchQuery, width, height, url, target) {
- this.webView_ = webView;
- this.ext_ = (ext && ext[0] == '.') ? ext.substr(1) : ext;
- this.mime_ = mime;
- this.searchQuery_ = searchQuery;
- this.width_ = width;
- this.height_ = height;
- this.url_ = url;
- this.target_ = target;
-
- this.loaded_ = false;
- this.loading_ = false;
-
- this.onMessageBound_ = this.onMessage_.bind(this);
- this.onLoadStopBound_ = this.onLoadStop_.bind(this);
- this.onLoadAbortBound_ = this.onLoadAbort_.bind(this);
-}
-
-CWSContainerClient.prototype = {
- __proto__: cr.EventTarget.prototype
-};
-
-/**
- * Events CWSContainerClient fires
- *
- * @enum {string}
- * @const
- */
-CWSContainerClient.Events = {
- LOADED: 'CWSContainerClient.Events.LOADED',
- LOAD_FAILED: 'CWSContainerClient.Events.LOAD_FAILED',
- REQUEST_INSTALL: 'CWSContainerClient.Events.REQUEST_INSTALL'
-};
-Object.freeze(CWSContainerClient.Events);
-
-/**
- * Handles messages from the widget
- * @param {Event} event Message event.
- * @private
- */
-CWSContainerClient.prototype.onMessage_ = function(event) {
- if (event.origin != this.target_)
- return;
-
- var data = event.data;
- switch (data['message']) {
- case 'widget_loaded':
- this.onWidgetLoaded_();
- break;
- case 'widget_load_failed':
- this.onWidgetLoadFailed_();
- break;
- case 'before_install':
- this.sendInstallRequest_(data['item_id']);
- break;
- default:
- console.error('Unexpected message: ' + data['message'], data);
- }
-};
-
-/**
- * Called when receiving 'loadstop' event from the <wevview>.
- * @param {Event} event Message event.
- * @private
- */
-CWSContainerClient.prototype.onLoadStop_ = function(event) {
- if (this.url_ == this.webView_.src && !this.loaded_) {
- this.loaded_ = true;
- this.postInitializeMessage_();
- }
-};
-
-/**
- * Called when the widget is loaded successfully.
- * @private
- */
-CWSContainerClient.prototype.onWidgetLoaded_ = function() {
- cr.dispatchSimpleEvent(this, CWSContainerClient.Events.LOADED);
-};
-
-/**
- * Called when the widget is failed to load.
- * @private
- */
-CWSContainerClient.prototype.onWidgetLoadFailed_ = function() {
- this.sendWidgetLoadFailed_();
-};
-
-/**
- * Called when receiving the 'loadabort' event from <webview>.
- * @param {Event} event Message event.
- * @private
- */
-CWSContainerClient.prototype.onLoadAbort_ = function(event) {
- this.sendWidgetLoadFailed_();
-};
-
-/**
- * Called when the installation is completed from the suggest-app dialog.
- *
- * @param {boolean} result True if the installation is success, false if failed.
- * @param {string} itemId Item id to be installed.
- */
-CWSContainerClient.prototype.onInstallCompleted = function(result, itemId) {
- if (result)
- this.postInstallSuccessMessage_(itemId);
- else
- this.postInstallFailureMessage_(itemId);
-};
-
-/**
- * Send the fail message to the suggest-app dialog.
- * @private
- */
-CWSContainerClient.prototype.sendWidgetLoadFailed_ = function() {
- cr.dispatchSimpleEvent(this, CWSContainerClient.Events.LOAD_FAILED);
-};
-
-/**
- * Send the install request to the suggest-app dialog.
- *
- * @param {string} itemId Item id to be installed.
- * @private
- */
-CWSContainerClient.prototype.sendInstallRequest_ = function(itemId) {
- var event = new Event(CWSContainerClient.Events.REQUEST_INSTALL);
- event.itemId = itemId;
- this.dispatchEvent(event);
-};
-
-/**
- * Send the 'install_failure' message to the widget.
- *
- * @param {string} itemId Item id to be installed.
- * @private
- */
-CWSContainerClient.prototype.postInstallFailureMessage_ = function(itemId) {
- var message = {
- message: 'install_failure',
- item_id: itemId,
- v: 1
- };
-
- this.postMessage_(message);
-};
-
-/**
- * Send the 'install_success' message to the widget.
- *
- * @param {string} itemId Item id to be installed.
- * @private
- */
-CWSContainerClient.prototype.postInstallSuccessMessage_ = function(itemId) {
- var message = {
- message: 'install_success',
- item_id: itemId,
- v: 1
- };
-
- this.postMessage_(message);
-};
-
-/**
- * Send the 'initialize' message to the widget.
- * @private
- */
-CWSContainerClient.prototype.postInitializeMessage_ = function() {
- var message = {
- message: 'initialize',
- hl: util.getCurrentLocaleOrDefault(),
- widgth: this.width_,
- height: this.height_,
- v: 1
- };
-
- if (this.searchQuery_) {
- message['search_query'] = this.searchQuery_;
- } else {
- message['file_extension'] = this.ext_;
- message['mime_type'] = this.mime_;
- }
-
- this.postMessage_(message);
-};
-
-/**
- * Send a message to the widget. This method shouldn't be called directly,
- * should from more specified posting function (eg. postXyzMessage_()).
- *
- * @param {object} message Message object to be posted.
- * @private
- */
-CWSContainerClient.prototype.postMessage_ = function(message) {
- if (!this.webView_.contentWindow)
- return;
-
- this.webView_.contentWindow.postMessage(message, this.target_);
-};
-
-/**
- * Loads the page to <webview>. Can be called only once.
- */
-CWSContainerClient.prototype.load = function() {
- if (this.loading_ || this.loaded_)
- throw new Error('Already loaded.');
- this.loading_ = true;
- this.loaded_ = false;
-
- window.addEventListener('message', this.onMessageBound_);
- this.webView_.addEventListener('loadstop', this.onLoadStopBound_);
- this.webView_.addEventListener('loadabort', this.onLoadAbortBound_);
- this.webView_.setAttribute('src', this.url_);
-};
-
-/**
- * Aborts loading of the embedded dialog and performs cleanup.
- */
-CWSContainerClient.prototype.abort = function() {
- window.removeEventListener('message', this.onMessageBound_);
- this.webView_.removeEventListener('loadstop', this.onLoadStopBound_);
- this.webView_.removeEventListener(
- 'loadabort', this.onLoadAbortBound_);
- this.webView_.stop();
-};
-
-/**
- * Cleans the dialog by removing all handlers.
- */
-CWSContainerClient.prototype.dispose = function() {
- this.abort();
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/default_action_dialog.js b/chromium/chrome/browser/resources/file_manager/foreground/js/default_action_dialog.js
deleted file mode 100644
index a5c8290a239..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/default_action_dialog.js
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-
-/**
- * DefaultActionDialog contains a message, a list box, an ok button, and a
- * cancel button.
- * This dialog should be used as action picker for file operations.
- */
-cr.define('cr.filebrowser', function() {
-
- /**
- * Creates dialog in DOM tree.
- *
- * @param {HTMLElement} parentNode Node to be parent for this dialog.
- * @constructor
- * @extends {FileManagerDialogBase}
- */
- function DefaultActionDialog(parentNode) {
- FileManagerDialogBase.call(this, parentNode);
-
- this.frame_.id = 'default-action-dialog';
-
- this.list_ = new cr.ui.List();
- this.list_.id = 'default-actions-list';
- this.frame_.insertBefore(this.list_, this.text_.nextSibling);
-
- this.selectionModel_ = this.list_.selectionModel =
- new cr.ui.ListSingleSelectionModel();
- this.dataModel_ = this.list_.dataModel = new cr.ui.ArrayDataModel([]);
-
- // List has max-height defined at css, so that list grows automatically,
- // but doesn't exceed predefined size.
- this.list_.autoExpands = true;
- this.list_.activateItemAtIndex = this.activateItemAtIndex_.bind(this);
-
- this.initialFocusElement_ = this.list_;
-
- var self = this;
-
- // Binding stuff doesn't work with constructors, so we have to create
- // closure here.
- this.list_.itemConstructor = function(item) {
- return self.renderItem(item);
- };
- }
-
- DefaultActionDialog.prototype = {
- __proto__: FileManagerDialogBase.prototype
- };
-
- /**
- * @override
- */
- DefaultActionDialog.prototype.onInputFocus = function() {
- this.list_.select();
- };
-
- /**
- * Renders item for list.
- * @param {Object} item Item to render.
- */
- DefaultActionDialog.prototype.renderItem = function(item) {
- var result = this.document_.createElement('li');
-
- var div = this.document_.createElement('div');
- div.textContent = item.label;
-
- if (item.iconType) {
- div.setAttribute('file-type-icon', item.iconType);
- } else if (item.iconUrl) {
- div.style.backgroundImage = 'url(' + item.iconUrl + ')';
- }
-
- if (item.class)
- div.classList.add(item.class);
-
- result.appendChild(div);
-
- cr.defineProperty(result, 'lead', cr.PropertyKind.BOOL_ATTR);
- cr.defineProperty(result, 'selected', cr.PropertyKind.BOOL_ATTR);
-
- return result;
- };
-
- /**
- * Shows dialog.
- *
- * @param {string} title Title in dialog caption.
- * @param {string} message Message in dialog caption.
- * @param {Array.<Object>} items Items to render in the list.
- * @param {number} defaultIndex Item to select by default.
- * @param {function(Object=)} opt_onOk OK callback with the selected item.
- * @param {function()=} opt_onCancel Cancel callback.
- */
- DefaultActionDialog.prototype.show = function(title, message, items,
- defaultIndex, opt_onOk, opt_onCancel) {
-
- var show = FileManagerDialogBase.prototype.showOkCancelDialog.call(
- this, title, message, opt_onOk, opt_onCancel);
-
- if (!show) {
- console.error('DefaultActionDialog can\'t be shown.');
- return;
- }
-
- if (!message) {
- this.text_.setAttribute('hidden', 'hidden');
- } else {
- this.text_.removeAttribute('hidden');
- }
-
- this.list_.startBatchUpdates();
- this.dataModel_.splice(0, this.dataModel_.length);
- for (var i = 0; i < items.length; i++) {
- this.dataModel_.push(items[i]);
- }
- this.selectionModel_.selectedIndex = defaultIndex;
- this.list_.endBatchUpdates();
- };
-
- /**
- * List activation handler. Closes dialog and calls 'ok' callback.
- * @param {number} index Activated index.
- */
- DefaultActionDialog.prototype.activateItemAtIndex_ = function(index) {
- this.hide();
- this.onOk_(this.dataModel_.item(index));
- };
-
- /**
- * Closes dialog and invokes callback with currently-selected item.
- * @override
- */
- DefaultActionDialog.prototype.onOkClick_ = function() {
- this.activateItemAtIndex_(this.selectionModel_.selectedIndex);
- };
-
- /**
- * @override
- */
- DefaultActionDialog.prototype.onContainerKeyDown_ = function(event) {
- // Handle Escape.
- if (event.keyCode == 27) {
- this.onCancelClick_(event);
- event.preventDefault();
- } else if (event.keyCode == 32 || event.keyCode == 13) {
- this.onOkClick_();
- event.preventDefault();
- }
- };
-
- return {DefaultActionDialog: DefaultActionDialog};
-});
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/directory_contents.js b/chromium/chrome/browser/resources/file_manager/foreground/js/directory_contents.js
deleted file mode 100644
index be69b66af90..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/directory_contents.js
+++ /dev/null
@@ -1,770 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Scanner of the entries.
- * @constructor
- */
-function ContentScanner() {
- this.cancelled_ = false;
-}
-
-/**
- * Starts to scan the entries. For example, starts to read the entries in a
- * directory, or starts to search with some query on a file system.
- * Derived classes must override this method.
- *
- * @param {function(Array.<Entry>)} entriesCallback Called when some chunk of
- * entries are read. This can be called a couple of times until the
- * completion.
- * @param {function()} successCallback Called when the scan is completed
- * successfully.
- * @param {function(FileError)} errorCallback Called an error occurs.
- */
-ContentScanner.prototype.scan = function(
- entriesCallback, successCallback, errorCallback) {
-};
-
-/**
- * Request cancelling of the running scan. When the cancelling is done,
- * an error will be reported from errorCallback passed to scan().
- */
-ContentScanner.prototype.cancel = function() {
- this.cancelled_ = true;
-};
-
-/**
- * Scanner of the entries in a directory.
- * @param {DirectoryEntry} entry The directory to be read.
- * @constructor
- * @extends {ContentScanner}
- */
-function DirectoryContentScanner(entry) {
- ContentScanner.call(this);
- this.entry_ = entry;
-}
-
-/**
- * Extends ContentScanner.
- */
-DirectoryContentScanner.prototype.__proto__ = ContentScanner.prototype;
-
-/**
- * Starts to read the entries in the directory.
- * @override
- */
-DirectoryContentScanner.prototype.scan = function(
- entriesCallback, successCallback, errorCallback) {
- if (!this.entry_ || this.entry_ === DirectoryModel.fakeDriveEntry_) {
- // If entry is not specified or a fake, we cannot read it.
- errorCallback(util.createFileError(FileError.INVALID_MODIFICATION_ERR));
- return;
- }
-
- metrics.startInterval('DirectoryScan');
- var reader = this.entry_.createReader();
- var readEntries = function() {
- reader.readEntries(
- function(entries) {
- if (this.cancelled_) {
- errorCallback(util.createFileError(FileError.ABORT_ERR));
- return;
- }
-
- if (entries.length === 0) {
- // All entries are read.
- metrics.recordInterval('DirectoryScan');
- successCallback();
- return;
- }
-
- entriesCallback(entries);
- readEntries();
- }.bind(this),
- errorCallback);
- }.bind(this);
- readEntries();
-};
-
-/**
- * Scanner of the entries for the search results on Drive File System.
- * @param {string} query The query string.
- * @constructor
- * @extends {ContentScanner}
- */
-function DriveSearchContentScanner(query) {
- ContentScanner.call(this);
- this.query_ = query;
-}
-
-/**
- * Extends ContentScanner.
- */
-DriveSearchContentScanner.prototype.__proto__ = ContentScanner.prototype;
-
-/**
- * Delay in milliseconds to be used for drive search scan, in order to reduce
- * the number of server requests while user is typing the query.
- * @type {number}
- * @private
- * @const
- */
-DriveSearchContentScanner.SCAN_DELAY_ = 200;
-
-/**
- * Maximum number of results which is shown on the search.
- * @type {number}
- * @private
- * @const
- */
-DriveSearchContentScanner.MAX_RESULTS_ = 100;
-
-/**
- * Starts to search on Drive File System.
- * @override
- */
-DriveSearchContentScanner.prototype.scan = function(
- entriesCallback, successCallback, errorCallback) {
- var numReadEntries = 0;
- var readEntries = function(nextFeed) {
- chrome.fileBrowserPrivate.searchDrive(
- {query: this.query_, nextFeed: nextFeed},
- function(entries, nextFeed) {
- if (this.cancelled_) {
- errorCallback(util.createFileError(FileError.ABORT_ERR));
- return;
- }
-
- // TODO(tbarzic): Improve error handling.
- if (!entries) {
- console.error('Drive search encountered an error.');
- errorCallback(util.createFileError(
- FileError.INVALID_MODIFICATION_ERR));
- return;
- }
-
- var numRemainingEntries =
- DriveSearchContentScanner.MAX_RESULTS_ - numReadEntries;
- if (entries.length >= numRemainingEntries) {
- // The limit is hit, so quit the scan here.
- entries = entries.slice(0, numRemainingEntries);
- nextFeed = '';
- }
-
- numReadEntries += entries.length;
- if (entries.length > 0)
- entriesCallback(entries);
-
- if (nextFeed === '')
- successCallback();
- else
- readEntries(nextFeed);
- }.bind(this));
- }.bind(this);
-
- // Let's give another search a chance to cancel us before we begin.
- setTimeout(
- function() {
- // Check cancelled state before read the entries.
- if (this.cancelled_) {
- errorCallback(util.createFileError(FileError.ABORT_ERR));
- return;
- }
- readEntries('');
- }.bind(this),
- DriveSearchContentScanner.SCAN_DELAY_);
-};
-
-/**
- * Scanner of the entries of the file name search on the directory tree, whose
- * root is entry.
- * @param {DirectoryEntry} entry The root of the search target directory tree.
- * @param {string} query The query of the search.
- * @constructor
- * @extends {ContentScanner}
- */
-function LocalSearchContentScanner(entry, query) {
- ContentScanner.call(this);
- this.entry_ = entry;
- this.query_ = query.toLowerCase();
-}
-
-/**
- * Extedns ContentScanner.
- */
-LocalSearchContentScanner.prototype.__proto__ = ContentScanner.prototype;
-
-/**
- * Starts the file name search.
- * @override
- */
-LocalSearchContentScanner.prototype.scan = function(
- entriesCallback, successCallback, errorCallback) {
- var numRunningTasks = 0;
- var error = null;
- var maybeRunCallback = function() {
- if (numRunningTasks === 0) {
- if (this.cancelled_)
- errorCallback(util.createFileError(FileError.ABORT_ERR));
- else if (error)
- errorCallback(error);
- else
- successCallback();
- }
- }.bind(this);
-
- var processEntry = function(entry) {
- numRunningTasks++;
- var onError = function(fileError) {
- if (!error)
- error = fileError;
- numRunningTasks--;
- maybeRunCallback();
- };
-
- var onSuccess = function(entries) {
- if (this.cancelled_ || error || entries.length === 0) {
- numRunningTasks--;
- maybeRunCallback();
- return;
- }
-
- // Filters by the query, and if found, run entriesCallback.
- var foundEntries = entries.filter(function(entry) {
- return entry.name.toLowerCase().indexOf(this.query_) >= 0;
- }.bind(this));
- if (foundEntries.length > 0)
- entriesCallback(foundEntries);
-
- // Start to process sub directories.
- for (var i = 0; i < entries.length; i++) {
- if (entries[i].isDirectory)
- processEntry(entries[i]);
- }
-
- // Read remaining entries.
- reader.readEntries(onSuccess, onError);
- }.bind(this);
-
- var reader = entry.createReader();
- reader.readEntries(onSuccess, onError);
- }.bind(this);
-
- processEntry(this.entry_);
-};
-
-/**
- * Scanner of the entries for the metadata search on Drive File System.
- * @param {string} query The query of the search.
- * @param {DriveMetadataSearchContentScanner.SearchType} searchType The option
- * of the search.
- * @constructor
- * @extends {ContentScanner}
- */
-function DriveMetadataSearchContentScanner(query, searchType) {
- ContentScanner.call(this);
- this.query_ = query;
- this.searchType_ = searchType;
-}
-
-/**
- * Extends ContentScanner.
- */
-DriveMetadataSearchContentScanner.prototype.__proto__ =
- ContentScanner.prototype;
-
-/**
- * The search types on the Drive File System.
- * @enum {string}
- */
-DriveMetadataSearchContentScanner.SearchType = Object.freeze({
- SEARCH_ALL: 'ALL',
- SEARCH_SHARED_WITH_ME: 'SHARED_WITH_ME',
- SEARCH_RECENT_FILES: 'EXCLUDE_DIRECTORIES',
- SEARCH_OFFLINE: 'OFFLINE'
-});
-
-/**
- * Starts to metadata-search on Drive File System.
- * @override
- */
-DriveMetadataSearchContentScanner.prototype.scan = function(
- entriesCallback, successCallback, errorCallback) {
- chrome.fileBrowserPrivate.searchDriveMetadata(
- {query: this.query_, types: this.searchType_, maxResults: 500},
- function(results) {
- if (this.cancelled_) {
- errorCallback(util.createFileError(FileError.ABORT_ERR));
- return;
- }
-
- if (!results) {
- console.error('Drive search encountered an error.');
- errorCallback(util.createFileError(
- FileError.INVALID_MODIFICATION_ERR));
- return;
- }
-
- var entries = results.map(function(result) { return result.entry; });
- if (entries.length > 0)
- entriesCallback(entries);
- successCallback();
- }.bind(this));
-};
-
-/**
- * This class manages filters and determines a file should be shown or not.
- * When filters are changed, a 'changed' event is fired.
- *
- * @param {MetadataCache} metadataCache Metadata cache service.
- * @param {boolean} showHidden If files starting with '.' are shown.
- * @constructor
- * @extends {cr.EventTarget}
- */
-function FileFilter(metadataCache, showHidden) {
- /**
- * @type {MetadataCache}
- * @private
- */
- this.metadataCache_ = metadataCache;
-
- /**
- * @type Object.<string, Function>
- * @private
- */
- this.filters_ = {};
- this.setFilterHidden(!showHidden);
-
- // Do not show entries marked as 'deleted'.
- this.addFilter('deleted', function(entry) {
- var internal = this.metadataCache_.getCached(entry, 'internal');
- return !(internal && internal.deleted);
- }.bind(this));
-}
-
-/*
- * FileFilter extends cr.EventTarget.
- */
-FileFilter.prototype = {__proto__: cr.EventTarget.prototype};
-
-/**
- * @param {string} name Filter identifier.
- * @param {function(Entry)} callback A filter — a function receiving an Entry,
- * and returning bool.
- */
-FileFilter.prototype.addFilter = function(name, callback) {
- this.filters_[name] = callback;
- cr.dispatchSimpleEvent(this, 'changed');
-};
-
-/**
- * @param {string} name Filter identifier.
- */
-FileFilter.prototype.removeFilter = function(name) {
- delete this.filters_[name];
- cr.dispatchSimpleEvent(this, 'changed');
-};
-
-/**
- * @param {boolean} value If do not show hidden files.
- */
-FileFilter.prototype.setFilterHidden = function(value) {
- if (value) {
- this.addFilter(
- 'hidden',
- function(entry) { return entry.name.substr(0, 1) !== '.'; }
- );
- } else {
- this.removeFilter('hidden');
- }
-};
-
-/**
- * @return {boolean} If the files with names starting with "." are not shown.
- */
-FileFilter.prototype.isFilterHiddenOn = function() {
- return 'hidden' in this.filters_;
-};
-
-/**
- * @param {Entry} entry File entry.
- * @return {boolean} True if the file should be shown, false otherwise.
- */
-FileFilter.prototype.filter = function(entry) {
- for (var name in this.filters_) {
- if (!this.filters_[name](entry))
- return false;
- }
- return true;
-};
-
-/**
- * A context of DirectoryContents.
- * TODO(yoshiki): remove this. crbug.com/224869.
- *
- * @param {FileFilter} fileFilter The file-filter context.
- * @param {MetadataCache} metadataCache Metadata cache service.
- * @constructor
- */
-function FileListContext(fileFilter, metadataCache) {
- /**
- * @type {cr.ui.ArrayDataModel}
- */
- this.fileList = new cr.ui.ArrayDataModel([]);
-
- /**
- * @type {MetadataCache}
- */
- this.metadataCache = metadataCache;
-
- /**
- * @type {FileFilter}
- */
- this.fileFilter = fileFilter;
-}
-
-/**
- * This class is responsible for scanning directory (or search results),
- * and filling the fileList. Different descendants handle various types of
- * directory contents shown: basic directory, drive search results, local search
- * results.
- * TODO(hidehiko): Remove EventTarget from this.
- *
- * @param {FileListContext} context The file list context.
- * @param {boolean} isSearch True for search directory contents, otherwise
- * false.
- * @param {DirectoryEntry} directoryEntry The entry of the current directory.
- * @param {DirectoryEntry} lastNonSearchDirectoryEntry The entry of the last
- * non-search directory.
- * @param {function():ContentScanner} scannerFactory The factory to create
- * ContentScanner instance.
- * @constructor
- * @extends {cr.EventTarget}
- */
-function DirectoryContents(context, isSearch, directoryEntry,
- lastNonSearchDirectoryEntry,
- scannerFactory) {
- this.context_ = context;
- this.fileList_ = context.fileList;
-
- this.isSearch_ = isSearch;
- this.directoryEntry_ = directoryEntry;
- this.lastNonSearchDirectoryEntry_ = lastNonSearchDirectoryEntry;
-
- this.scannerFactory_ = scannerFactory;
- this.scanner_ = null;
- this.prefetchMetadataQueue_ = new AsyncUtil.Queue();
- this.scanCancelled_ = false;
-}
-
-/**
- * DirectoryContents extends cr.EventTarget.
- */
-DirectoryContents.prototype.__proto__ = cr.EventTarget.prototype;
-
-/**
- * Create the copy of the object, but without scan started.
- * @return {DirectoryContents} Object copy.
- */
-DirectoryContents.prototype.clone = function() {
- return new DirectoryContents(
- this.context_, this.isSearch_, this.directoryEntry_,
- this.lastNonSearchDirectoryEntry_, this.scannerFactory_);
-};
-
-/**
- * Use a given fileList instead of the fileList from the context.
- * @param {Array|cr.ui.ArrayDataModel} fileList The new file list.
- */
-DirectoryContents.prototype.setFileList = function(fileList) {
- if (fileList instanceof cr.ui.ArrayDataModel)
- this.fileList_ = fileList;
- else
- this.fileList_ = new cr.ui.ArrayDataModel(fileList);
- this.context_.metadataCache.setCacheSize(this.fileList_.length);
-};
-
-/**
- * Use the filelist from the context and replace its contents with the entries
- * from the current fileList.
- */
-DirectoryContents.prototype.replaceContextFileList = function() {
- if (this.context_.fileList !== this.fileList_) {
- var spliceArgs = this.fileList_.slice();
- var fileList = this.context_.fileList;
- spliceArgs.unshift(0, fileList.length);
- fileList.splice.apply(fileList, spliceArgs);
- this.fileList_ = fileList;
- this.context_.metadataCache.setCacheSize(this.fileList_.length);
- }
-};
-
-/**
- * @return {boolean} If the scan is active.
- */
-DirectoryContents.prototype.isScanning = function() {
- return this.scanner_ || this.prefetchMetadataQueue_.isRunning();
-};
-
-/**
- * @return {boolean} True if search results (drive or local).
- */
-DirectoryContents.prototype.isSearch = function() {
- return this.isSearch_;
-};
-
-/**
- * @return {DirectoryEntry} A DirectoryEntry for current directory. In case of
- * search -- the top directory from which search is run.
- */
-DirectoryContents.prototype.getDirectoryEntry = function() {
- return this.directoryEntry_;
-};
-
-/**
- * @return {DirectoryEntry} A DirectoryEntry for the last non search contents.
- */
-DirectoryContents.prototype.getLastNonSearchDirectoryEntry = function() {
- return this.lastNonSearchDirectoryEntry_;
-};
-
-/**
- * Start directory scan/search operation. Either 'scan-completed' or
- * 'scan-failed' event will be fired upon completion.
- */
-DirectoryContents.prototype.scan = function() {
- // TODO(hidehiko,mtomasz): this scan method must be called at most once.
- // Remove such a limitation.
- this.scanner_ = this.scannerFactory_();
- this.scanner_.scan(this.onNewEntries_.bind(this),
- this.onScanCompleted_.bind(this),
- this.onScanError_.bind(this));
-};
-
-/**
- * Cancels the running scan.
- */
-DirectoryContents.prototype.cancelScan = function() {
- if (this.scanCancelled_)
- return;
- this.scanCancelled_ = true;
- if (this.scanner_)
- this.scanner_.cancel();
-
- this.prefetchMetadataQueue_.cancel();
- cr.dispatchSimpleEvent(this, 'scan-cancelled');
-};
-
-/**
- * Called when the scanning by scanner_ is done.
- * @private
- */
-DirectoryContents.prototype.onScanCompleted_ = function() {
- this.scanner_ = null;
- if (this.scanCancelled_)
- return;
-
- this.prefetchMetadataQueue_.run(function(callback) {
- // Call callback first, so isScanning() returns false in the event handlers.
- callback();
- cr.dispatchSimpleEvent(this, 'scan-completed');
- }.bind(this));
-};
-
-/**
- * Called in case scan has failed. Should send the event.
- * @private
- */
-DirectoryContents.prototype.onScanError_ = function() {
- this.scanner_ = null;
- if (this.scanCancelled_)
- return;
-
- this.prefetchMetadataQueue_.run(function(callback) {
- // Call callback first, so isScanning() returns false in the event handlers.
- callback();
- cr.dispatchSimpleEvent(this, 'scan-failed');
- }.bind(this));
-};
-
-/**
- * Called when some chunk of entries are read by scanner.
- * @param {Array.<Entry>} entries The list of the scanned entries.
- * @private
- */
-DirectoryContents.prototype.onNewEntries_ = function(entries) {
- if (this.scanCancelled_)
- return;
-
- var entriesFiltered = [].filter.call(
- entries, this.context_.fileFilter.filter.bind(this.context_.fileFilter));
-
- // Update the filelist without waiting the metadata.
- this.fileList_.push.apply(this.fileList_, entriesFiltered);
- cr.dispatchSimpleEvent(this, 'scan-updated');
-
- this.context_.metadataCache.setCacheSize(this.fileList_.length);
-
- // Because the prefetchMetadata can be slow, throttling by splitting entries
- // into smaller chunks to reduce UI latency.
- // TODO(hidehiko,mtomasz): This should be handled in MetadataCache.
- var MAX_CHUNK_SIZE = 50;
- for (var i = 0; i < entriesFiltered.length; i += MAX_CHUNK_SIZE) {
- var chunk = entriesFiltered.slice(i, i + MAX_CHUNK_SIZE);
- this.prefetchMetadataQueue_.run(function(chunk, callback) {
- this.prefetchMetadata(chunk, function() {
- if (this.scanCancelled_) {
- // Do nothing if the scanning is cancelled.
- callback();
- return;
- }
-
- // TODO(yoshiki): Here we should fire the update event of changed
- // items. Currently we have a method this.fileList_.updateIndex() to
- // fire an event, but this method takes only 1 argument and invokes sort
- // one by one. It is obviously time wasting. Instead, we call sort
- // directory.
- // In future, we should implement a good method like updateIndexes and
- // use it here.
- var status = this.fileList_.sortStatus;
- this.fileList_.sort(status.field, status.direction);
-
- cr.dispatchSimpleEvent(this, 'scan-updated');
- callback();
- }.bind(this));
- }.bind(this, chunk));
- }
-};
-
-/**
- * @param {Array.<Entry>} entries Files.
- * @param {function(Object)} callback Callback on done.
- */
-DirectoryContents.prototype.prefetchMetadata = function(entries, callback) {
- this.context_.metadataCache.get(entries, 'filesystem', callback);
-};
-
-/**
- * @param {Array.<Entry>} entries Files.
- * @param {function(Object)} callback Callback on done.
- */
-DirectoryContents.prototype.reloadMetadata = function(entries, callback) {
- this.context_.metadataCache.clear(entries, '*');
- this.context_.metadataCache.get(entries, 'filesystem', callback);
-};
-
-/**
- * @param {string} name Directory name.
- * @param {function(DirectoryEntry)} successCallback Called on success.
- * @param {function(FileError)} errorCallback On error.
- */
-DirectoryContents.prototype.createDirectory = function(
- name, successCallback, errorCallback) {
- // TODO(hidehiko): createDirectory should not be the part of
- // DirectoryContent.
- if (this.isSearch_ || !this.directoryEntry_) {
- errorCallback(util.createFileError(FileError.INVALID_MODIFICATION_ERR));
- return;
- }
-
- var onSuccess = function(newEntry) {
- this.reloadMetadata([newEntry], function() {
- successCallback(newEntry);
- });
- };
-
- this.directoryEntry_.getDirectory(name, {create: true, exclusive: true},
- onSuccess.bind(this), errorCallback);
-};
-
-/**
- * Creates a DirectoryContents instance to show entries in a directory.
- *
- * @param {FileListContext} context File list context.
- * @param {DirectoryEntry} directoryEntry The current directory entry.
- * @return {DirectoryContents} Created DirectoryContents instance.
- */
-DirectoryContents.createForDirectory = function(context, directoryEntry) {
- return new DirectoryContents(
- context,
- false, // Non search.
- directoryEntry,
- directoryEntry,
- function() {
- return new DirectoryContentScanner(directoryEntry);
- });
-};
-
-/**
- * Creates a DirectoryContents instance to show the result of the search on
- * Drive File System.
- *
- * @param {FileListContext} context File list context.
- * @param {DirectoryEntry} directoryEntry The current directory entry.
- * @param {DirectoryEntry} previousDirectoryEntry The DirectoryEntry that was
- * current before the search.
- * @param {string} query Search query.
- * @return {DirectoryContents} Created DirectoryContents instance.
- */
-DirectoryContents.createForDriveSearch = function(
- context, directoryEntry, previousDirectoryEntry, query) {
- return new DirectoryContents(
- context,
- true, // Search.
- directoryEntry,
- previousDirectoryEntry,
- function() {
- return new DriveSearchContentScanner(query);
- });
-};
-
-/**
- * Creates a DirectoryContents instance to show the result of the search on
- * Local File System.
- *
- * @param {FileListContext} context File list context.
- * @param {DirectoryEntry} directoryEntry The current directory entry.
- * @param {string} query Search query.
- * @return {DirectoryContents} Created DirectoryContents instance.
- */
-DirectoryContents.createForLocalSearch = function(
- context, directoryEntry, query) {
- return new DirectoryContents(
- context,
- true, // Search.
- directoryEntry,
- directoryEntry,
- function() {
- return new LocalSearchContentScanner(directoryEntry, query);
- });
-};
-
-/**
- * Creates a DirectoryContents instance to show the result of metadata search
- * on Drive File System.
- *
- * @param {FileListContext} context File list context.
- * @param {DirectoryEntry} fakeDirectoryEntry Fake directory entry representing
- * the set of result entries. This serves as a top directory for the
- * search.
- * @param {DirectoryEntry} driveDirectoryEntry Directory for the actual drive.
- * @param {string} query Search query.
- * @param {DriveMetadataSearchContentScanner.SearchType} searchType The type of
- * the search. The scanner will restricts the entries based on the given
- * type.
- * @return {DirectoryContents} Created DirectoryContents instance.
- */
-DirectoryContents.createForDriveMetadataSearch = function(
- context, fakeDirectoryEntry, driveDirectoryEntry, query, searchType) {
- return new DirectoryContents(
- context,
- true, // Search
- fakeDirectoryEntry,
- driveDirectoryEntry,
- function() {
- return new DriveMetadataSearchContentScanner(query, searchType);
- });
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/directory_model.js b/chromium/chrome/browser/resources/file_manager/foreground/js/directory_model.js
deleted file mode 100644
index fde41e8c321..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/directory_model.js
+++ /dev/null
@@ -1,1186 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-// If directory files changes too often, don't rescan directory more than once
-// per specified interval
-var SIMULTANEOUS_RESCAN_INTERVAL = 1000;
-// Used for operations that require almost instant rescan.
-var SHORT_RESCAN_INTERVAL = 100;
-
-/**
- * Data model of the file manager.
- *
- * @param {boolean} singleSelection True if only one file could be selected
- * at the time.
- * @param {FileFilter} fileFilter Instance of FileFilter.
- * @param {FileWatcher} fileWatcher Instance of FileWatcher.
- * @param {MetadataCache} metadataCache The metadata cache service.
- * @param {VolumeManagerWrapper} volumeManager The volume manager.
- * @constructor
- */
-function DirectoryModel(singleSelection, fileFilter, fileWatcher,
- metadataCache, volumeManager) {
- this.fileListSelection_ = singleSelection ?
- new cr.ui.ListSingleSelectionModel() : new cr.ui.ListSelectionModel();
-
- this.runningScan_ = null;
- this.pendingScan_ = null;
- this.rescanTime_ = null;
- this.scanFailures_ = 0;
- this.changeDirectorySequence_ = 0;
-
- this.fileFilter_ = fileFilter;
- this.fileFilter_.addEventListener('changed',
- this.onFilterChanged_.bind(this));
-
- this.currentFileListContext_ = new FileListContext(
- fileFilter, metadataCache);
- this.currentDirContents_ =
- DirectoryContents.createForDirectory(this.currentFileListContext_, null);
-
- this.volumeManager_ = volumeManager;
- this.volumeManager_.volumeInfoList.addEventListener(
- 'splice', this.onVolumeInfoListUpdated_.bind(this));
-
- this.fileWatcher_ = fileWatcher;
- this.fileWatcher_.addEventListener(
- 'watcher-directory-changed',
- this.onWatcherDirectoryChanged_.bind(this));
-}
-
-/**
- * Fake entry to be used in currentDirEntry_ when current directory is
- * unmounted DRIVE. TODO(haruki): Support "drive/root" and "drive/other".
- * @type {Object}
- * @const
- * @private
- */
-DirectoryModel.fakeDriveEntry_ = {
- fullPath: RootDirectory.DRIVE + '/' + DriveSubRootDirectory.ROOT,
- isDirectory: true,
- rootType: RootType.DRIVE
-};
-
-/**
- * Fake entry representing a psuedo directory, which contains Drive files
- * available offline. This entry works as a trigger to start a search for
- * offline files.
- * @type {Object}
- * @const
- * @private
- */
-DirectoryModel.fakeDriveOfflineEntry_ = {
- fullPath: RootDirectory.DRIVE_OFFLINE,
- isDirectory: true,
- rootType: RootType.DRIVE_OFFLINE
-};
-
-/**
- * Fake entry representing a pseudo directory, which contains shared-with-me
- * Drive files. This entry works as a trigger to start a search for
- * shared-with-me files.
- * @type {Object}
- * @const
- * @private
- */
-DirectoryModel.fakeDriveSharedWithMeEntry_ = {
- fullPath: RootDirectory.DRIVE_SHARED_WITH_ME,
- isDirectory: true,
- rootType: RootType.DRIVE_SHARED_WITH_ME
-};
-
-/**
- * Fake entry representing a pseudo directory, which contains Drive files
- * accessed recently. This entry works as a trigger to start a metadata search
- * implemented as DirectoryContentsDriveRecent.
- * DirectoryModel is responsible to start the search when the UI tries to open
- * this fake entry (e.g. changeDirectory()).
- * @type {Object}
- * @const
- * @private
- */
-DirectoryModel.fakeDriveRecentEntry_ = {
- fullPath: RootDirectory.DRIVE_RECENT,
- isDirectory: true,
- rootType: RootType.DRIVE_RECENT
-};
-
-/**
- * List of fake entries for special searches.
- *
- * @type {Array.<Object>}
- * @const
- */
-DirectoryModel.FAKE_DRIVE_SPECIAL_SEARCH_ENTRIES = [
- DirectoryModel.fakeDriveSharedWithMeEntry_,
- DirectoryModel.fakeDriveRecentEntry_,
- DirectoryModel.fakeDriveOfflineEntry_
-];
-
-/**
- * DirectoryModel extends cr.EventTarget.
- */
-DirectoryModel.prototype.__proto__ = cr.EventTarget.prototype;
-
-/**
- * Disposes the directory model by removing file watchers.
- */
-DirectoryModel.prototype.dispose = function() {
- this.fileWatcher_.dispose();
-};
-
-/**
- * @return {cr.ui.ArrayDataModel} Files in the current directory.
- */
-DirectoryModel.prototype.getFileList = function() {
- return this.currentFileListContext_.fileList;
-};
-
-/**
- * Sort the file list.
- * @param {string} sortField Sort field.
- * @param {string} sortDirection "asc" or "desc".
- */
-DirectoryModel.prototype.sortFileList = function(sortField, sortDirection) {
- this.getFileList().sort(sortField, sortDirection);
-};
-
-/**
- * @return {cr.ui.ListSelectionModel|cr.ui.ListSingleSelectionModel} Selection
- * in the fileList.
- */
-DirectoryModel.prototype.getFileListSelection = function() {
- return this.fileListSelection_;
-};
-
-/**
- * @return {RootType} Root type of current root.
- */
-DirectoryModel.prototype.getCurrentRootType = function() {
- var entry = this.currentDirContents_.getDirectoryEntry();
- return PathUtil.getRootType(entry ? entry.fullPath : '');
-};
-
-/**
- * @return {string} Root path.
- */
-DirectoryModel.prototype.getCurrentRootPath = function() {
- var entry = this.currentDirContents_.getDirectoryEntry();
- return entry ? PathUtil.getRootPath(entry.fullPath) : '';
-};
-
-/**
- * @return {string} Filesystem URL representing the mountpoint for the current
- * contents.
- */
-DirectoryModel.prototype.getCurrentMountPointUrl = function() {
- var rootPath = this.getCurrentRootPath();
- // Special search roots are just showing a search results from DRIVE.
- if (PathUtil.getRootType(rootPath) == RootType.DRIVE ||
- PathUtil.isSpecialSearchRoot(rootPath))
- return util.makeFilesystemUrl(RootDirectory.DRIVE);
-
- return util.makeFilesystemUrl(rootPath);
-};
-
-/**
- * @return {boolean} on True if offline.
- */
-DirectoryModel.prototype.isDriveOffline = function() {
- var connection = this.volumeManager_.getDriveConnectionState();
- return connection.type == util.DriveConnectionType.OFFLINE;
-};
-
-/**
- * TODO(haruki): This actually checks the current root. Fix the method name and
- * related code.
- * @return {boolean} True if the root for the current directory is read only.
- */
-DirectoryModel.prototype.isReadOnly = function() {
- return this.isPathReadOnly(this.getCurrentRootPath());
-};
-
-/**
- * @return {boolean} True if the a scan is active.
- */
-DirectoryModel.prototype.isScanning = function() {
- return this.currentDirContents_.isScanning();
-};
-
-/**
- * @return {boolean} True if search is in progress.
- */
-DirectoryModel.prototype.isSearching = function() {
- return this.currentDirContents_.isSearch();
-};
-
-/**
- * @param {string} path Path to check.
- * @return {boolean} True if the |path| is read only.
- */
-DirectoryModel.prototype.isPathReadOnly = function(path) {
- // TODO(hidehiko): Migrate this into VolumeInfo.
- switch (PathUtil.getRootType(path)) {
- case RootType.REMOVABLE:
- var volumeInfo = this.volumeManager_.getVolumeInfo(path);
- // Returns true if the volume is actually read only, or if an error
- // is found during the mounting.
- // TODO(hidehiko): Remove "error" check here, by removing error'ed volume
- // info from VolumeManager.
- return volumeInfo && (volumeInfo.isReadOnly || !!volumeInfo.error);
- case RootType.ARCHIVE:
- return true;
- case RootType.DOWNLOADS:
- return false;
- case RootType.DRIVE:
- // TODO(haruki): Maybe add DRIVE_OFFLINE as well to allow renaming in the
- // offline tab.
- return this.isDriveOffline();
- default:
- return true;
- }
-};
-
-/**
- * Updates the selection by using the updateFunc and publish the change event.
- * If updateFunc returns true, it force to dispatch the change event even if the
- * selection index is not changed.
- *
- * @param {cr.ui.ListSelectionModel|cr.ui.ListSingleSelectionModel} selection
- * Selection to be updated.
- * @param {function(): boolean} updateFunc Function updating the selection.
- * @private
- */
-DirectoryModel.prototype.updateSelectionAndPublishEvent_ =
- function(selection, updateFunc) {
- // Begin change.
- selection.beginChange();
-
- // If dispatchNeeded is true, we should ensure the change event is
- // dispatched.
- var dispatchNeeded = updateFunc();
-
- // Check if the change event is dispatched in the endChange function
- // or not.
- var eventDispatched = function() { dispatchNeeded = false; };
- selection.addEventListener('change', eventDispatched);
- selection.endChange();
- selection.removeEventListener('change', eventDispatched);
-
- // If the change event have been already dispatched, dispatchNeeded is false.
- if (dispatchNeeded) {
- var event = new Event('change');
- // The selection status (selected or not) is not changed because
- // this event is caused by the change of selected item.
- event.changes = [];
- selection.dispatchEvent(event);
- }
-};
-
-/**
- * Invoked when a change in the directory is detected by the watcher.
- * @private
- */
-DirectoryModel.prototype.onWatcherDirectoryChanged_ = function() {
- this.rescanSoon();
-};
-
-/**
- * Invoked when filters are changed.
- * @private
- */
-DirectoryModel.prototype.onFilterChanged_ = function() {
- this.rescanSoon();
-};
-
-/**
- * Returns the filter.
- * @return {FileFilter} The file filter.
- */
-DirectoryModel.prototype.getFileFilter = function() {
- return this.fileFilter_;
-};
-
-/**
- * @return {DirectoryEntry} Current directory.
- */
-DirectoryModel.prototype.getCurrentDirEntry = function() {
- return this.currentDirContents_.getDirectoryEntry();
-};
-
-/**
- * @return {string} URL of the current directory. or null if unavailable.
- */
-DirectoryModel.prototype.getCurrentDirectoryURL = function() {
- var entry = this.currentDirContents_.getDirectoryEntry();
- if (!entry)
- return null;
- if (entry === DirectoryModel.fakeDriveOfflineEntry_)
- return util.makeFilesystemUrl(entry.fullPath);
- return entry.toURL();
-};
-
-/**
- * @return {string} Path for the current directory, or empty string if the
- * current directory is not yet set.
- */
-DirectoryModel.prototype.getCurrentDirPath = function() {
- var entry = this.currentDirContents_.getDirectoryEntry();
- return entry ? entry.fullPath : '';
-};
-
-/**
- * @return {Array.<string>} File paths of selected files.
- * @private
- */
-DirectoryModel.prototype.getSelectedPaths_ = function() {
- var indexes = this.fileListSelection_.selectedIndexes;
- var fileList = this.getFileList();
- if (fileList) {
- return indexes.map(function(i) {
- return fileList.item(i).fullPath;
- });
- }
- return [];
-};
-
-/**
- * @param {Array.<string>} value List of file paths of selected files.
- * @private
- */
-DirectoryModel.prototype.setSelectedPaths_ = function(value) {
- var indexes = [];
- var fileList = this.getFileList();
-
- var safeKey = function(key) {
- // The transformation must:
- // 1. Never generate a reserved name ('__proto__')
- // 2. Keep different keys different.
- return '#' + key;
- };
-
- var hash = {};
-
- for (var i = 0; i < value.length; i++)
- hash[safeKey(value[i])] = 1;
-
- for (var i = 0; i < fileList.length; i++) {
- if (hash.hasOwnProperty(safeKey(fileList.item(i).fullPath)))
- indexes.push(i);
- }
- this.fileListSelection_.selectedIndexes = indexes;
-};
-
-/**
- * @return {string} Lead item file path.
- * @private
- */
-DirectoryModel.prototype.getLeadPath_ = function() {
- var index = this.fileListSelection_.leadIndex;
- return index >= 0 && this.getFileList().item(index).fullPath;
-};
-
-/**
- * @param {string} value The name of new lead index.
- * @private
- */
-DirectoryModel.prototype.setLeadPath_ = function(value) {
- var fileList = this.getFileList();
- for (var i = 0; i < fileList.length; i++) {
- if (fileList.item(i).fullPath === value) {
- this.fileListSelection_.leadIndex = i;
- return;
- }
- }
-};
-
-/**
- * Schedule rescan with short delay.
- */
-DirectoryModel.prototype.rescanSoon = function() {
- this.scheduleRescan(SHORT_RESCAN_INTERVAL);
-};
-
-/**
- * Schedule rescan with delay. Designed to handle directory change
- * notification.
- */
-DirectoryModel.prototype.rescanLater = function() {
- this.scheduleRescan(SIMULTANEOUS_RESCAN_INTERVAL);
-};
-
-/**
- * Schedule rescan with delay. If another rescan has been scheduled does
- * nothing. File operation may cause a few notifications what should cause
- * a single refresh.
- * @param {number} delay Delay in ms after which the rescan will be performed.
- */
-DirectoryModel.prototype.scheduleRescan = function(delay) {
- if (this.rescanTime_) {
- if (this.rescanTime_ <= Date.now() + delay)
- return;
- clearTimeout(this.rescanTimeoutId_);
- }
-
- this.rescanTime_ = Date.now() + delay;
- this.rescanTimeoutId_ = setTimeout(this.rescan.bind(this), delay);
-};
-
-/**
- * Cancel a rescan on timeout if it is scheduled.
- * @private
- */
-DirectoryModel.prototype.clearRescanTimeout_ = function() {
- this.rescanTime_ = null;
- if (this.rescanTimeoutId_) {
- clearTimeout(this.rescanTimeoutId_);
- this.rescanTimeoutId_ = null;
- }
-};
-
-/**
- * Rescan current directory. May be called indirectly through rescanLater or
- * directly in order to reflect user action. Will first cache all the directory
- * contents in an array, then seamlessly substitute the fileList contents,
- * preserving the select element etc.
- *
- * This should be to scan the contents of current directory (or search).
- */
-DirectoryModel.prototype.rescan = function() {
- this.clearRescanTimeout_();
- if (this.runningScan_) {
- this.pendingRescan_ = true;
- return;
- }
-
- var dirContents = this.currentDirContents_.clone();
- dirContents.setFileList([]);
-
- var successCallback = (function() {
- this.replaceDirectoryContents_(dirContents);
- cr.dispatchSimpleEvent(this, 'rescan-completed');
- }).bind(this);
-
- this.scan_(dirContents,
- successCallback, function() {}, function() {}, function() {});
-};
-
-/**
- * Run scan on the current DirectoryContents. The active fileList is cleared and
- * the entries are added directly.
- *
- * This should be used when changing directory or initiating a new search.
- *
- * @param {DirectoryContentes} newDirContents New DirectoryContents instance to
- * replace currentDirContents_.
- * @param {function()=} opt_callback Called on success.
- * @private
- */
-DirectoryModel.prototype.clearAndScan_ = function(newDirContents,
- opt_callback) {
- if (this.currentDirContents_.isScanning())
- this.currentDirContents_.cancelScan();
- this.currentDirContents_ = newDirContents;
- this.clearRescanTimeout_();
-
- if (this.pendingScan_)
- this.pendingScan_ = false;
-
- if (this.runningScan_) {
- if (this.runningScan_.isScanning())
- this.runningScan_.cancelScan();
- this.runningScan_ = null;
- }
-
- var onDone = function() {
- cr.dispatchSimpleEvent(this, 'scan-completed');
- if (opt_callback)
- opt_callback();
- }.bind(this);
-
- var onFailed = function() {
- cr.dispatchSimpleEvent(this, 'scan-failed');
- }.bind(this);
-
- var onUpdated = function() {
- cr.dispatchSimpleEvent(this, 'scan-updated');
- }.bind(this);
-
- var onCancelled = function() {
- cr.dispatchSimpleEvent(this, 'scan-cancelled');
- }.bind(this);
-
- // Clear the table, and start scanning.
- cr.dispatchSimpleEvent(this, 'scan-started');
- var fileList = this.getFileList();
- fileList.splice(0, fileList.length);
- this.scan_(this.currentDirContents_,
- onDone, onFailed, onUpdated, onCancelled);
-};
-
-/**
- * Perform a directory contents scan. Should be called only from rescan() and
- * clearAndScan_().
- *
- * @param {DirectoryContents} dirContents DirectoryContents instance on which
- * the scan will be run.
- * @param {function()} successCallback Callback on success.
- * @param {function()} failureCallback Callback on failure.
- * @param {function()} updatedCallback Callback on update. Only on the last
- * update, {@code successCallback} is called instead of this.
- * @param {function()} cancelledCallback Callback on cancel.
- * @private
- */
-DirectoryModel.prototype.scan_ = function(
- dirContents,
- successCallback, failureCallback, updatedCallback, cancelledCallback) {
- var self = this;
-
- /**
- * Runs pending scan if there is one.
- *
- * @return {boolean} Did pending scan exist.
- */
- var maybeRunPendingRescan = function() {
- if (this.pendingRescan_) {
- this.rescanSoon();
- this.pendingRescan_ = false;
- return true;
- }
- return false;
- }.bind(this);
-
- var onSuccess = function() {
- // Record metric for Downloads directory.
- if (!dirContents.isSearch()) {
- var locationInfo =
- this.volumeManager_.getLocationInfo(dirContents.getDirectoryEntry());
- if (locationInfo.volumeInfo.volumeType === util.VolumeType.DOWNLOADS &&
- locationInfo.isRootEntry) {
- metrics.recordMediumCount('DownloadsCount',
- dirContents.fileList_.length);
- }
- }
-
- this.runningScan_ = null;
- successCallback();
- this.scanFailures_ = 0;
- maybeRunPendingRescan();
- }.bind(this);
-
- var onFailure = function() {
- this.runningScan_ = null;
- this.scanFailures_++;
- failureCallback();
-
- if (maybeRunPendingRescan())
- return;
-
- if (this.scanFailures_ <= 1)
- this.rescanLater();
- }.bind(this);
-
- this.runningScan_ = dirContents;
-
- dirContents.addEventListener('scan-completed', onSuccess);
- dirContents.addEventListener('scan-updated', updatedCallback);
- dirContents.addEventListener('scan-failed', onFailure);
- dirContents.addEventListener('scan-cancelled', cancelledCallback);
- dirContents.scan();
-};
-
-/**
- * @param {DirectoryContents} dirContents DirectoryContents instance.
- * @private
- */
-DirectoryModel.prototype.replaceDirectoryContents_ = function(dirContents) {
- cr.dispatchSimpleEvent(this, 'begin-update-files');
- this.updateSelectionAndPublishEvent_(this.fileListSelection_, function() {
- var selectedPaths = this.getSelectedPaths_();
- var selectedIndices = this.fileListSelection_.selectedIndexes;
-
- // Restore leadIndex in case leadName no longer exists.
- var leadIndex = this.fileListSelection_.leadIndex;
- var leadPath = this.getLeadPath_();
-
- this.currentDirContents_ = dirContents;
- dirContents.replaceContextFileList();
-
- this.setSelectedPaths_(selectedPaths);
- this.fileListSelection_.leadIndex = leadIndex;
- this.setLeadPath_(leadPath);
-
- // If nothing is selected after update, then select file next to the
- // latest selection
- var forceChangeEvent = false;
- if (this.fileListSelection_.selectedIndexes.length == 0 &&
- selectedIndices.length != 0) {
- var maxIdx = Math.max.apply(null, selectedIndices);
- this.selectIndex(Math.min(maxIdx - selectedIndices.length + 2,
- this.getFileList().length) - 1);
- forceChangeEvent = true;
- }
- return forceChangeEvent;
- }.bind(this));
-
- cr.dispatchSimpleEvent(this, 'end-update-files');
-};
-
-/**
- * Callback when an entry is changed.
- * @param {util.EntryChangedKind} kind How the entry is changed.
- * @param {Entry} entry The changed entry.
- */
-DirectoryModel.prototype.onEntryChanged = function(kind, entry) {
- // TODO(hidehiko): We should update directory model even the search result
- // is shown.
- var rootType = this.getCurrentRootType();
- if ((rootType === RootType.DRIVE ||
- rootType === RootType.DRIVE_SHARED_WITH_ME ||
- rootType === RootType.DRIVE_RECENT ||
- rootType === RootType.DRIVE_OFFLINE) &&
- this.isSearching())
- return;
-
- if (kind == util.EntryChangedKind.CREATED) {
- entry.getParent(function(parentEntry) {
- if (this.getCurrentDirEntry().fullPath != parentEntry.fullPath) {
- // Do nothing if current directory changed during async operations.
- return;
- }
- this.currentDirContents_.prefetchMetadata([entry], function() {
- if (this.getCurrentDirEntry().fullPath != parentEntry.fullPath) {
- // Do nothing if current directory changed during async operations.
- return;
- }
-
- var index = this.findIndexByEntry_(entry);
- if (index >= 0)
- this.getFileList().splice(index, 1, entry);
- else
- this.getFileList().push(entry);
- }.bind(this));
- }.bind(this));
- } else {
- // This is the delete event.
- var index = this.findIndexByEntry_(entry);
- if (index >= 0)
- this.getFileList().splice(index, 1);
- }
-};
-
-/**
- * @param {Entry} entry The entry to be searched.
- * @return {number} The index in the fileList, or -1 if not found.
- * @private
- */
-DirectoryModel.prototype.findIndexByEntry_ = function(entry) {
- var fileList = this.getFileList();
- for (var i = 0; i < fileList.length; i++) {
- if (util.isSameEntry(fileList.item(i), entry))
- return i;
- }
- return -1;
-};
-
-/**
- * Called when rename is done successfully.
- * Note: conceptually, DirectoryModel should work without this, because entries
- * can be renamed by other systems anytime and Files.app should reflect it
- * correctly.
- * TODO(hidehiko): investigate more background, and remove this if possible.
- *
- * @param {Entry} oldEntry The old entry.
- * @param {Entry} newEntry The new entry.
- * @param {function()} opt_callback Called on completion.
- */
-DirectoryModel.prototype.onRenameEntry = function(
- oldEntry, newEntry, opt_callback) {
- this.currentDirContents_.prefetchMetadata([newEntry], function() {
- // If the current directory is the old entry, then quietly change to the
- // new one.
- if (util.isSameEntry(oldEntry, this.getCurrentDirEntry()))
- this.changeDirectory(newEntry.fullPath);
-
- // Look for the old entry.
- // If the entry doesn't exist in the list, it has been updated from
- // outside (probably by directory rescan).
- var index = this.findIndexByEntry_(oldEntry);
- if (index >= 0) {
- // Update the content list and selection status.
- var wasSelected = this.fileListSelection_.getIndexSelected(index);
- this.updateSelectionAndPublishEvent_(this.fileListSelection_, function() {
- this.fileListSelection_.setIndexSelected(index, false);
- this.getFileList().splice(index, 1, newEntry);
- if (wasSelected) {
- // We re-search the index, because splice may trigger sorting so that
- // index may be stale.
- this.fileListSelection_.setIndexSelected(
- this.findIndexByEntry_(newEntry), true);
- }
- return true;
- }.bind(this));
- }
-
- // Run callback, finally.
- if (opt_callback)
- opt_callback();
- }.bind(this));
-};
-
-/**
- * Creates directory and updates the file list.
- *
- * @param {string} name Directory name.
- * @param {function(DirectoryEntry)} successCallback Callback on success.
- * @param {function(FileError)} errorCallback Callback on failure.
- */
-DirectoryModel.prototype.createDirectory = function(name, successCallback,
- errorCallback) {
- var entry = this.getCurrentDirEntry();
- if (!entry) {
- errorCallback(util.createFileError(FileError.INVALID_MODIFICATION_ERR));
- return;
- }
-
- var tracker = this.createDirectoryChangeTracker();
- tracker.start();
-
- var onSuccess = function(newEntry) {
- // Do not change anything or call the callback if current
- // directory changed.
- tracker.stop();
- if (tracker.hasChanged)
- return;
-
- var existing = this.getFileList().slice().filter(
- function(e) {return e.name == name;});
-
- if (existing.length) {
- this.selectEntry(newEntry);
- successCallback(existing[0]);
- } else {
- this.fileListSelection_.beginChange();
- this.getFileList().splice(0, 0, newEntry);
- this.selectEntry(newEntry);
- this.fileListSelection_.endChange();
- successCallback(newEntry);
- }
- };
-
- this.currentDirContents_.createDirectory(name, onSuccess.bind(this),
- errorCallback);
-};
-
-/**
- * Changes directory. Causes 'directory-change' event.
- *
- * The directory will not be changed, if another request is started before it is
- * finished. The error callback will not be called, and the event for the first
- * request will not be invoked.
- *
- * @param {string} path New current directory path.
- * @param {function(FileError)=} opt_errorCallback Executed if the change
- * directory failed.
- */
-DirectoryModel.prototype.changeDirectory = function(path, opt_errorCallback) {
- this.changeDirectorySequence_++;
-
- if (PathUtil.isSpecialSearchRoot(path)) {
- this.specialSearch(path, '');
- return;
- }
-
- this.resolveDirectory(
- path,
- function(sequence, directoryEntry) {
- if (this.changeDirectorySequence_ === sequence)
- this.changeDirectoryEntry(directoryEntry);
- }.bind(this, this.changeDirectorySequence_),
- function(error) {
- console.error('Error changing directory to ' + path + ': ', error);
- if (opt_errorCallback)
- opt_errorCallback(error);
- });
-};
-
-/**
- * Resolves absolute directory path. Handles Drive stub. If the drive is
- * mounting, callbacks will be called after the mount is completed.
- *
- * @param {string} path Path to the directory.
- * @param {function(DirectoryEntry)} successCallback Success callback.
- * @param {function(FileError)} errorCallback Error callback.
- */
-DirectoryModel.prototype.resolveDirectory = function(
- path, successCallback, errorCallback) {
- if (PathUtil.getRootType(path) == RootType.DRIVE) {
- if (!this.volumeManager_.getVolumeInfo(RootDirectory.DRIVE)) {
- errorCallback(util.createFileError(FileError.NOT_FOUND_ERR));
- return;
- }
- }
-
- var onError = function(error) {
- // Handle the special case, when in offline mode, and there are no cached
- // contents on the C++ side. In such case, let's display the stub.
- // The INVALID_STATE_ERR error code is returned from the drive filesystem
- // in such situation.
- //
- // TODO(mtomasz, hashimoto): Consider rewriting this logic.
- // crbug.com/253464.
- if (PathUtil.getRootType(path) == RootType.DRIVE &&
- error.code == FileError.INVALID_STATE_ERR) {
- successCallback(DirectoryModel.fakeDriveEntry_);
- return;
- }
- errorCallback(error);
- }.bind(this);
-
- // TODO(mtomasz): Use Entry instead of a path.
- this.volumeManager_.resolveAbsolutePath(
- path,
- function(entry) {
- if (entry.isFile) {
- onError(util.createFileError(FileError.TYPE_MISMATCH_ERR));
- return;
- }
- successCallback(entry);
- },
- onError);
-};
-
-/**
- * @param {DirectoryEntry} dirEntry The absolute path to the new directory.
- * @param {function()=} opt_callback Executed if the directory loads
- * successfully.
- * @private
- */
-DirectoryModel.prototype.changeDirectoryEntrySilent_ = function(dirEntry,
- opt_callback) {
- var onScanComplete = function() {
- if (opt_callback)
- opt_callback();
- // For tests that open the dialog to empty directories, everything
- // is loaded at this point.
- chrome.test.sendMessage('directory-change-complete');
- };
- this.clearAndScan_(
- DirectoryContents.createForDirectory(this.currentFileListContext_,
- dirEntry),
- onScanComplete.bind(this));
-};
-
-/**
- * Change the current directory to the directory represented by a
- * DirectoryEntry.
- *
- * Dispatches the 'directory-changed' event when the directory is successfully
- * changed.
- *
- * @param {DirectoryEntry} dirEntry The absolute path to the new directory.
- * @param {function()=} opt_callback Executed if the directory loads
- * successfully.
- */
-DirectoryModel.prototype.changeDirectoryEntry = function(
- dirEntry, opt_callback) {
- this.fileWatcher_.changeWatchedDirectory(dirEntry, function(sequence) {
- if (this.changeDirectorySequence_ !== sequence)
- return;
- var previous = this.currentDirContents_.getDirectoryEntry();
- this.clearSearch_();
- this.changeDirectoryEntrySilent_(dirEntry, opt_callback);
-
- var e = new Event('directory-changed');
- e.previousDirEntry = previous;
- e.newDirEntry = dirEntry;
- this.dispatchEvent(e);
- }.bind(this, this.changeDirectorySequence_));
-};
-
-/**
- * Creates an object which could say whether directory has changed while it has
- * been active or not. Designed for long operations that should be cancelled
- * if the used change current directory.
- * @return {Object} Created object.
- */
-DirectoryModel.prototype.createDirectoryChangeTracker = function() {
- var tracker = {
- dm_: this,
- active_: false,
- hasChanged: false,
-
- start: function() {
- if (!this.active_) {
- this.dm_.addEventListener('directory-changed',
- this.onDirectoryChange_);
- this.active_ = true;
- this.hasChanged = false;
- }
- },
-
- stop: function() {
- if (this.active_) {
- this.dm_.removeEventListener('directory-changed',
- this.onDirectoryChange_);
- this.active_ = false;
- }
- },
-
- onDirectoryChange_: function(event) {
- tracker.stop();
- tracker.hasChanged = true;
- }
- };
- return tracker;
-};
-
-/**
- * @param {Entry} entry Entry to be selected.
- */
-DirectoryModel.prototype.selectEntry = function(entry) {
- var fileList = this.getFileList();
- for (var i = 0; i < fileList.length; i++) {
- if (fileList.item(i).toURL() === entry.toURL()) {
- this.selectIndex(i);
- return;
- }
- }
-};
-
-/**
- * @param {Array.<string>} entries Array of entries.
- */
-DirectoryModel.prototype.selectEntries = function(entries) {
- // URLs are needed here, since we are comparing Entries by URLs.
- var urls = util.entriesToURLs(entries);
- var fileList = this.getFileList();
- this.fileListSelection_.beginChange();
- this.fileListSelection_.unselectAll();
- for (var i = 0; i < fileList.length; i++) {
- if (urls.indexOf(fileList.item(i).toURL()) >= 0)
- this.fileListSelection_.setIndexSelected(i, true);
- }
- this.fileListSelection_.endChange();
-};
-
-/**
- * @param {number} index Index of file.
- */
-DirectoryModel.prototype.selectIndex = function(index) {
- // this.focusCurrentList_();
- if (index >= this.getFileList().length)
- return;
-
- // If a list bound with the model it will do scrollIndexIntoView(index).
- this.fileListSelection_.selectedIndex = index;
-};
-
-/**
- * Called when VolumeInfoList is updated.
- *
- * @param {Event} event Event of VolumeInfoList's 'splice'.
- * @private
- */
-DirectoryModel.prototype.onVolumeInfoListUpdated_ = function(event) {
- var driveVolume = this.volumeManager_.getVolumeInfo(RootDirectory.DRIVE);
- if (driveVolume && !driveVolume.error) {
- var currentDirEntry = this.getCurrentDirEntry();
- if (currentDirEntry) {
- if (currentDirEntry === DirectoryModel.fakeDriveEntry_) {
- // Replace the fake entry by real DirectoryEntry silently.
- this.volumeManager_.resolveAbsolutePath(
- DirectoryModel.fakeDriveEntry_.fullPath,
- function(entry) {
- // If the current entry is still fake drive entry, replace it.
- if (this.getCurrentDirEntry() === DirectoryModel.fakeDriveEntry_)
- this.changeDirectoryEntrySilent_(entry);
- },
- function(error) {});
- } else if (PathUtil.isSpecialSearchRoot(currentDirEntry.fullPath)) {
- for (var i = 0; i < event.added.length; i++) {
- if (event.added[i].volumeType == util.VolumeType.DRIVE) {
- // If the Drive volume is newly mounted, rescan it.
- this.rescan();
- break;
- }
- }
- }
- }
- }
-
- // When the volume where we are is unmounted, fallback to
- // DEFAULT_MOUNT_POINT. If current directory path is empty, stop the fallback
- // since the current directory is initializing now.
- // TODO(mtomasz): DEFAULT_MOUNT_POINT is deprecated. Use VolumeManager::
- // getDefaultVolume() after it is implemented.
- if (this.getCurrentDirPath() &&
- !this.volumeManager_.getVolumeInfo(this.getCurrentDirPath()))
- this.changeDirectory(PathUtil.DEFAULT_MOUNT_POINT);
-};
-
-/**
- * Check if the root of the given path is mountable or not.
- *
- * @param {string} path Path.
- * @return {boolean} Return true, if the given path is under mountable root.
- * Otherwise, return false.
- */
-DirectoryModel.isMountableRoot = function(path) {
- var rootType = PathUtil.getRootType(path);
- switch (rootType) {
- case RootType.DOWNLOADS:
- return false;
- case RootType.ARCHIVE:
- case RootType.REMOVABLE:
- case RootType.DRIVE:
- return true;
- default:
- throw new Error('Unknown root type!');
- }
-};
-
-/**
- * Performs search and displays results. The search type is dependent on the
- * current directory. If we are currently on drive, server side content search
- * over drive mount point. If the current directory is not on the drive, file
- * name search over current directory will be performed.
- *
- * @param {string} query Query that will be searched for.
- * @param {function(Event)} onSearchRescan Function that will be called when the
- * search directory is rescanned (i.e. search results are displayed).
- * @param {function()} onClearSearch Function to be called when search state
- * gets cleared.
- * TODO(olege): Change callbacks to events.
- */
-DirectoryModel.prototype.search = function(query,
- onSearchRescan,
- onClearSearch) {
- query = query.trimLeft();
-
- this.clearSearch_();
-
- var currentDirEntry = this.getCurrentDirEntry();
- if (!currentDirEntry) {
- // Not yet initialized. Do nothing.
- return;
- }
-
- if (!query) {
- if (this.isSearching()) {
- var newDirContents = DirectoryContents.createForDirectory(
- this.currentFileListContext_,
- this.currentDirContents_.getLastNonSearchDirectoryEntry());
- this.clearAndScan_(newDirContents);
- }
- return;
- }
-
- this.onSearchCompleted_ = onSearchRescan;
- this.onClearSearch_ = onClearSearch;
-
- this.addEventListener('scan-completed', this.onSearchCompleted_);
-
- // If we are offline, let's fallback to file name search inside dir.
- // A search initiated from directories in Drive or special search results
- // should trigger Drive search.
- var newDirContents;
- if (!this.isDriveOffline() &&
- PathUtil.isDriveBasedPath(currentDirEntry.fullPath)) {
- // Drive search is performed over the whole drive, so pass drive root as
- // |directoryEntry|.
- newDirContents = DirectoryContents.createForDriveSearch(
- this.currentFileListContext_,
- currentDirEntry,
- this.currentDirContents_.getLastNonSearchDirectoryEntry(),
- query);
- } else {
- newDirContents = DirectoryContents.createForLocalSearch(
- this.currentFileListContext_, currentDirEntry, query);
- }
- this.clearAndScan_(newDirContents);
-};
-
-/**
- * Performs special search and displays results. e.g. Drive files available
- * offline, shared-with-me files, recently modified files.
- * @param {string} path Path string representing special search. See fake
- * entries in PathUtil.RootDirectory.
- * @param {string=} opt_query Query string used for the search.
- */
-DirectoryModel.prototype.specialSearch = function(path, opt_query) {
- var query = opt_query || '';
-
- this.clearSearch_();
-
- this.onSearchCompleted_ = null;
- this.onClearSearch_ = null;
-
- var onDriveDirectoryResolved = function(sequence, driveRoot) {
- if (this.changeDirectorySequence_ !== sequence)
- return;
- if (!driveRoot || driveRoot == DirectoryModel.fakeDriveEntry_) {
- // Drive root not available or not ready. onVolumeInfoListUpdated_()
- // handles the rescan if necessary.
- driveRoot = null;
- }
-
- var specialSearchType = PathUtil.getRootType(path);
- var searchOption;
- var dirEntry;
- if (specialSearchType == RootType.DRIVE_OFFLINE) {
- dirEntry = DirectoryModel.fakeDriveOfflineEntry_;
- searchOption =
- DriveMetadataSearchContentScanner.SearchType.SEARCH_OFFLINE;
- } else if (specialSearchType == RootType.DRIVE_SHARED_WITH_ME) {
- dirEntry = DirectoryModel.fakeDriveSharedWithMeEntry_;
- searchOption =
- DriveMetadataSearchContentScanner.SearchType.SEARCH_SHARED_WITH_ME;
- } else if (specialSearchType == RootType.DRIVE_RECENT) {
- dirEntry = DirectoryModel.fakeDriveRecentEntry_;
- searchOption =
- DriveMetadataSearchContentScanner.SearchType.SEARCH_RECENT_FILES;
- } else {
- // Unknown path.
- throw new Error('Unknown path for special search.');
- }
-
- var newDirContents = DirectoryContents.createForDriveMetadataSearch(
- this.currentFileListContext_,
- dirEntry, driveRoot, query, searchOption);
- var previous = this.currentDirContents_.getDirectoryEntry();
- this.clearAndScan_(newDirContents);
-
- var e = new Event('directory-changed');
- e.previousDirEntry = previous;
- e.newDirEntry = dirEntry;
- this.dispatchEvent(e);
- }.bind(this, this.changeDirectorySequence_);
-
- this.resolveDirectory(DirectoryModel.fakeDriveEntry_.fullPath,
- onDriveDirectoryResolved /* success */,
- function() {} /* failed */);
-};
-
-/**
- * In case the search was active, remove listeners and send notifications on
- * its canceling.
- * @private
- */
-DirectoryModel.prototype.clearSearch_ = function() {
- if (!this.isSearching())
- return;
-
- if (this.onSearchCompleted_) {
- this.removeEventListener('scan-completed', this.onSearchCompleted_);
- this.onSearchCompleted_ = null;
- }
-
- if (this.onClearSearch_) {
- this.onClearSearch_();
- this.onClearSearch_ = null;
- }
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/directory_tree.js b/chromium/chrome/browser/resources/file_manager/foreground/js/directory_tree.js
deleted file mode 100644
index 5c9de7aa0fe..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/directory_tree.js
+++ /dev/null
@@ -1,676 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-////////////////////////////////////////////////////////////////////////////////
-// DirectoryTreeUtil
-
-/**
- * Utility methods. They are intended for use only in this file.
- */
-var DirectoryTreeUtil = {};
-
-/**
- * Generate a list of the directory entries for the top level on the tree.
- * @return {Array.<DirectoryEntry>} Entries for the top level on the tree.
- */
-DirectoryTreeUtil.generateTopLevelEntries = function() {
- var entries = [
- DirectoryModel.fakeDriveEntry_,
- DirectoryModel.fakeDriveOfflineEntry_,
- DirectoryModel.fakeDriveSharedWithMeEntry_,
- DirectoryModel.fakeDriveRecentEntry_,
- ];
-
- for (var i = 0; i < entries.length; i++) {
- entries[i]['label'] = PathUtil.getRootLabel(entries[i].fullPath);
- }
-
- return entries;
-};
-
-/**
- * Checks if the given directory can be on the tree or not.
- *
- * @param {string} path Path to be checked.
- * @return {boolean} True if the path is eligible for the directory tree.
- * Otherwise, false.
- */
-DirectoryTreeUtil.isEligiblePathForDirectoryTree = function(path) {
- return PathUtil.isDriveBasedPath(path);
-};
-
-Object.freeze(DirectoryTreeUtil);
-
-////////////////////////////////////////////////////////////////////////////////
-// DirectoryTreeBase
-
-/**
- * Implementation of methods for DirectoryTree and DirectoryItem. These classes
- * inherits cr.ui.Tree/TreeItem so we can't make them inherit this class.
- * Instead, we separate their implementations to this separate object and call
- * it with setting 'this' from DirectoryTree/Item.
- */
-var DirectoryItemTreeBaseMethods = {};
-
-/**
- * Updates sub-elements of {@code this} reading {@code DirectoryEntry}.
- * The list of {@code DirectoryEntry} are not updated by this method.
- *
- * @param {boolean} recursive True if the all visible sub-directories are
- * updated recursively including left arrows. If false, the update walks
- * only immediate child directories without arrows.
- */
-DirectoryItemTreeBaseMethods.updateSubElementsFromList = function(recursive) {
- var index = 0;
- var tree = this.parentTree_ || this; // If no parent, 'this' itself is tree.
- while (this.entries_[index]) {
- var currentEntry = this.entries_[index];
- var currentElement = this.items[index];
-
- if (index >= this.items.length) {
- var item = new DirectoryItem(currentEntry, this, tree);
- this.add(item);
- index++;
- } else if (currentEntry.fullPath == currentElement.fullPath) {
- if (recursive && this.expanded)
- currentElement.updateSubDirectories(true /* recursive */);
-
- index++;
- } else if (currentEntry.fullPath < currentElement.fullPath) {
- var item = new DirectoryItem(currentEntry, this, tree);
- this.addAt(item, index);
- index++;
- } else if (currentEntry.fullPath > currentElement.fullPath) {
- this.remove(currentElement);
- }
- }
-
- var removedChild;
- while (removedChild = this.items[index]) {
- this.remove(removedChild);
- }
-
- if (index == 0) {
- this.hasChildren = false;
- this.expanded = false;
- } else {
- this.hasChildren = true;
- }
-};
-
-/**
- * Finds a parent directory of the {@code entry} in {@code this}, and
- * invokes the DirectoryItem.selectByEntry() of the found directory.
- *
- * @param {DirectoryEntry|Object} entry The entry to be searched for. Can be
- * a fake.
- * @return {boolean} True if the parent item is found.
- */
-DirectoryItemTreeBaseMethods.searchAndSelectByEntry = function(entry) {
- for (var i = 0; i < this.items.length; i++) {
- var item = this.items[i];
- if (util.isParentEntry(item.entry, entry)) {
- item.selectByEntry(entry);
- return true;
- }
- }
- return false;
-};
-
-Object.freeze(DirectoryItemTreeBaseMethods);
-
-////////////////////////////////////////////////////////////////////////////////
-// DirectoryItem
-
-/**
- * A directory in the tree. Each element represents one directory.
- *
- * @param {DirectoryEntry} dirEntry DirectoryEntry of this item.
- * @param {DirectoryItem|DirectoryTree} parentDirItem Parent of this item.
- * @param {DirectoryTree} tree Current tree, which contains this item.
- * @extends {cr.ui.TreeItem}
- * @constructor
- */
-function DirectoryItem(dirEntry, parentDirItem, tree) {
- var item = cr.doc.createElement('div');
- DirectoryItem.decorate(item, dirEntry, parentDirItem, tree);
- return item;
-}
-
-/**
- * @param {HTMLElement} el Element to be DirectoryItem.
- * @param {DirectoryEntry} dirEntry DirectoryEntry of this item.
- * @param {DirectoryItem|DirectoryTree} parentDirItem Parent of this item.
- * @param {DirectoryTree} tree Current tree, which contains this item.
- */
-DirectoryItem.decorate =
- function(el, dirEntry, parentDirItem, tree) {
- el.__proto__ = DirectoryItem.prototype;
- (/** @type {DirectoryItem} */ el).decorate(
- dirEntry, parentDirItem, tree);
-};
-
-DirectoryItem.prototype = {
- __proto__: cr.ui.TreeItem.prototype,
-
- /**
- * The DirectoryEntry corresponding to this DirectoryItem. This may be
- * a dummy DirectoryEntry.
- * @type {DirectoryEntry|Object}
- */
- get entry() {
- return this.dirEntry_;
- },
-
- /**
- * The element containing the label text and the icon.
- * @type {!HTMLElement}
- * @override
- */
- get labelElement() {
- return this.firstElementChild.querySelector('.label');
- }
-};
-
-/**
- * Calls DirectoryItemTreeBaseMethods.updateSubElementsFromList().
- *
- * @param {boolean} recursive True if the all visible sub-directories are
- * updated recursively including left arrows. If false, the update walks
- * only immediate child directories without arrows.
- */
-DirectoryItem.prototype.updateSubElementsFromList = function(recursive) {
- DirectoryItemTreeBaseMethods.updateSubElementsFromList.call(this, recursive);
-};
-
-/**
- * Calls DirectoryItemTreeBaseMethods.updateSubElementsFromList().
- * @param {DirectoryEntry|Object} entry The entry to be searched for. Can be
- * a fake.
- * @return {boolean} True if the parent item is found.
- */
-DirectoryItem.prototype.searchAndSelectByEntry = function(entry) {
- return DirectoryItemTreeBaseMethods.searchAndSelectByEntry.call(this, entry);
-};
-
-/**
- * @param {DirectoryEntry} dirEntry DirectoryEntry of this item.
- * @param {DirectoryItem|DirectoryTree} parentDirItem Parent of this item.
- * @param {DirectoryTree} tree Current tree, which contains this item.
- */
-DirectoryItem.prototype.decorate = function(
- dirEntry, parentDirItem, tree) {
- var path = dirEntry.fullPath;
- var label;
- label = dirEntry.label ? dirEntry.label : dirEntry.name;
-
- this.className = 'tree-item';
- this.innerHTML =
- '<div class="tree-row">' +
- ' <span class="expand-icon"></span>' +
- ' <span class="icon"></span>' +
- ' <span class="label"></span>' +
- '</div>' +
- '<div class="tree-children"></div>';
- this.setAttribute('role', 'treeitem');
-
- this.parentTree_ = tree;
- this.directoryModel_ = tree.directoryModel;
- this.parent_ = parentDirItem;
- this.label = label;
- this.fullPath = path;
- this.dirEntry_ = dirEntry;
- this.fileFilter_ = this.directoryModel_.getFileFilter();
-
- // Sets hasChildren=false tentatively. This will be overridden after
- // scanning sub-directories in DirectoryTreeUtil.updateSubElementsFromList.
- this.hasChildren = false;
-
- this.addEventListener('expand', this.onExpand_.bind(this), false);
- var icon = this.querySelector('.icon');
- icon.classList.add('volume-icon');
- var iconType = PathUtil.getRootType(path);
- if (iconType && PathUtil.isRootPath(path))
- icon.setAttribute('volume-type-icon', iconType);
- else
- icon.setAttribute('file-type-icon', 'folder');
-
- if (this.parentTree_.contextMenuForSubitems)
- this.setContextMenu(this.parentTree_.contextMenuForSubitems);
- // Adds handler for future change.
- this.parentTree_.addEventListener(
- 'contextMenuForSubitemsChange',
- function(e) { this.setContextMenu(e.newValue); }.bind(this));
-
- if (parentDirItem.expanded)
- this.updateSubDirectories(false /* recursive */);
-};
-
-/**
- * Overrides WebKit's scrollIntoViewIfNeeded, which doesn't work well with
- * a complex layout. This call is not necessary, so we are ignoring it.
- *
- * @param {boolean} unused Unused.
- * @override
- */
-DirectoryItem.prototype.scrollIntoViewIfNeeded = function(unused) {
-};
-
-/**
- * Removes the child node, but without selecting the parent item, to avoid
- * unintended changing of directories. Removing is done externally, and other
- * code will navigate to another directory.
- *
- * @param {!cr.ui.TreeItem} child The tree item child to remove.
- * @override
- */
-DirectoryItem.prototype.remove = function(child) {
- this.lastElementChild.removeChild(child);
- if (this.items.length == 0)
- this.hasChildren = false;
-};
-
-/**
- * Invoked when the item is being expanded.
- * @param {!UIEvent} e Event.
- * @private
- **/
-DirectoryItem.prototype.onExpand_ = function(e) {
- this.updateSubDirectories(
- true /* recursive */,
- function() {},
- function() {
- this.expanded = false;
- }.bind(this));
-
- e.stopPropagation();
-};
-
-/**
- * Retrieves the latest subdirectories and update them on the tree.
- * @param {boolean} recursive True if the update is recursively.
- * @param {function()=} opt_successCallback Callback called on success.
- * @param {function()=} opt_errorCallback Callback called on error.
- */
-DirectoryItem.prototype.updateSubDirectories = function(
- recursive, opt_successCallback, opt_errorCallback) {
- if (util.isFakeEntry(this.entry)) {
- if (opt_errorCallback)
- opt_errorCallback();
- return;
- }
-
- var sortEntries = function(fileFilter, entries) {
- entries.sort(function(a, b) {
- return (a.name.toLowerCase() > b.name.toLowerCase()) ? 1 : -1;
- });
- return entries.filter(fileFilter.filter.bind(fileFilter));
- };
-
- var onSuccess = function(entries) {
- this.entries_ = entries;
- this.redrawSubDirectoryList_(recursive);
- opt_successCallback && opt_successCallback();
- }.bind(this);
-
- var reader = this.entry.createReader();
- var entries = [];
- var readEntry = function() {
- reader.readEntries(function(results) {
- if (!results.length) {
- onSuccess(sortEntries(this.fileFilter_, entries));
- return;
- }
-
- for (var i = 0; i < results.length; i++) {
- var entry = results[i];
- if (entry.isDirectory)
- entries.push(entry);
- }
- readEntry();
- }.bind(this));
- }.bind(this);
- readEntry();
-};
-
-/**
- * Updates sub-elements of {@code parentElement} reading {@code DirectoryEntry}
- * with calling {@code iterator}.
- *
- * @param {string} changedDirectryPath The path of the changed directory.
- */
-DirectoryItem.prototype.updateItemByPath = function(changedDirectryPath) {
- if (changedDirectryPath === this.entry.fullPath) {
- this.updateSubDirectories(false /* recursive */);
- return;
- }
-
- for (var i = 0; i < this.items.length; i++) {
- var item = this.items[i];
- if (PathUtil.isParentPath(item.entry.fullPath, changedDirectryPath)) {
- item.updateItemByPath(changedDirectryPath);
- break;
- }
- }
-};
-
-/**
- * Redraw subitems with the latest information. The items are sorted in
- * alphabetical order, case insensitive.
- * @param {boolean} recursive True if the update is recursively.
- * @private
- */
-DirectoryItem.prototype.redrawSubDirectoryList_ = function(recursive) {
- this.updateSubElementsFromList(recursive);
-};
-
-/**
- * Select the item corresponding to the given {@code entry}.
- * @param {DirectoryEntry|Object} entry The entry to be selected. Can be a fake.
- */
-DirectoryItem.prototype.selectByEntry = function(entry) {
- if (util.isSameEntry(entry, this.entry)) {
- this.selected = true;
- return;
- }
-
- if (this.searchAndSelectByEntry(entry))
- return;
-
- // If the path doesn't exist, updates sub directories and tryes again.
- this.updateSubDirectories(
- false /* recursive */,
- this.searchAndSelectByEntry.bind(this, entry));
-};
-
-/**
- * Executes the assigned action as a drop target.
- */
-DirectoryItem.prototype.doDropTargetAction = function() {
- this.expanded = true;
-};
-
-/**
- * Executes the assigned action. DirectoryItem performs changeDirectory.
- */
-DirectoryItem.prototype.doAction = function() {
- if (this.fullPath != this.directoryModel_.getCurrentDirPath())
- this.directoryModel_.changeDirectory(this.fullPath);
-};
-
-/**
- * Sets the context menu for directory tree.
- * @param {cr.ui.Menu} menu Menu to be set.
- */
-DirectoryItem.prototype.setContextMenu = function(menu) {
- if (this.entry && PathUtil.isEligibleForFolderShortcut(this.entry.fullPath))
- cr.ui.contextMenuHandler.setContextMenu(this, menu);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// DirectoryTree
-
-/**
- * Tree of directories on the middle bar. This element is also the root of
- * items, in other words, this is the parent of the top-level items.
- *
- * @constructor
- * @extends {cr.ui.Tree}
- */
-function DirectoryTree() {}
-
-/**
- * Decorates an element.
- * @param {HTMLElement} el Element to be DirectoryTree.
- * @param {DirectoryModel} directoryModel Current DirectoryModel.
- * @param {VolumeManagerWrapper} volumeManager VolumeManager of the system.
- */
-DirectoryTree.decorate = function(el, directoryModel, volumeManager) {
- el.__proto__ = DirectoryTree.prototype;
- (/** @type {DirectoryTree} */ el).decorate(directoryModel, volumeManager);
-};
-
-DirectoryTree.prototype = {
- __proto__: cr.ui.Tree.prototype,
-
- // DirectoryTree is always expanded.
- get expanded() { return true; },
- /**
- * @param {boolean} value Not used.
- */
- set expanded(value) {},
-
- /**
- * The DirectoryEntry corresponding to this DirectoryItem. This may be
- * a dummy DirectoryEntry.
- * @type {DirectoryEntry|Object}
- * @override
- **/
- get entry() {
- return this.dirEntry_;
- },
-
- /**
- * The DirectoryModel this tree corresponds to.
- * @type {DirectoryModel}
- */
- get directoryModel() {
- return this.directoryModel_;
- },
-
- /**
- * The VolumeManager instance of the system.
- * @type {VolumeManager}
- */
- get volumeManager() {
- return this.volumeManager_;
- },
-};
-
-cr.defineProperty(DirectoryTree, 'contextMenuForSubitems', cr.PropertyKind.JS);
-
-/**
- * Calls DirectoryItemTreeBaseMethods.updateSubElementsFromList().
- *
- * @param {boolean} recursive True if the all visible sub-directories are
- * updated recursively including left arrows. If false, the update walks
- * only immediate child directories without arrows.
- */
-DirectoryTree.prototype.updateSubElementsFromList = function(recursive) {
- DirectoryItemTreeBaseMethods.updateSubElementsFromList.call(this, recursive);
-};
-
-/**
- * Calls DirectoryItemTreeBaseMethods.updateSubElementsFromList().
- * @param {DirectoryEntry|Object} entry The entry to be searched for. Can be
- * a fake.
- * @return {boolean} True if the parent item is found.
- */
-DirectoryTree.prototype.searchAndSelectByEntry = function(entry) {
- return DirectoryItemTreeBaseMethods.searchAndSelectByEntry.call(this, entry);
-};
-
-/**
- * Decorates an element.
- * @param {DirectoryModel} directoryModel Current DirectoryModel.
- * @param {VolumeManagerWrapper} volumeManager VolumeManager of the system.
- */
-DirectoryTree.prototype.decorate = function(directoryModel, volumeManager) {
- cr.ui.Tree.prototype.decorate.call(this);
-
- this.directoryModel_ = directoryModel;
- this.volumeManager_ = volumeManager;
- this.entries_ = DirectoryTreeUtil.generateTopLevelEntries();
-
- this.fileFilter_ = this.directoryModel_.getFileFilter();
- this.fileFilter_.addEventListener('changed',
- this.onFilterChanged_.bind(this));
-
- this.directoryModel_.addEventListener('directory-changed',
- this.onCurrentDirectoryChanged_.bind(this));
-
- // Add a handler for directory change.
- this.addEventListener('change', function() {
- if (this.selectedItem &&
- (!this.currentEntry_ ||
- !util.isSameEntry(this.currentEntry_, this.selectedItem.entry))) {
- this.currentEntry_ = this.selectedItem.entry;
- this.selectedItem.doAction();
- return;
- }
- }.bind(this));
-
- this.privateOnDirectoryChangedBound_ =
- this.onDirectoryContentChanged_.bind(this);
- chrome.fileBrowserPrivate.onDirectoryChanged.addListener(
- this.privateOnDirectoryChangedBound_);
-
- this.scrollBar_ = MainPanelScrollBar();
- this.scrollBar_.initialize(this.parentNode, this);
-
- // Once, draws the list with the fake '/drive/' entry.
- this.redraw(false /* recursive */);
- // Resolves 'My Drive' entry and replaces the fake with the true one.
- this.maybeResolveMyDriveRoot_(function() {
- // After the true entry is resolved, draws the list again.
- this.redraw(true /* recursive */);
- }.bind(this));
-};
-
-/**
- * Select the item corresponding to the given entry.
- * @param {DirectoryEntry|Object} entry The directory entry to be selected. Can
- * be a fake.
- */
-DirectoryTree.prototype.selectByEntry = function(entry) {
- // If the target directory is not in the tree, do nothing.
- if (!DirectoryTreeUtil.isEligiblePathForDirectoryTree(entry.fullPath))
- return;
-
- this.maybeResolveMyDriveRoot_(function() {
- if (this.selectedItem && util.isSameEntry(entry, this.selectedItem.entry))
- return;
-
- if (this.searchAndSelectByEntry(entry))
- return;
-
- this.selectedItem = null;
- this.updateSubDirectories(
- false /* recursive */,
- // Success callback, failure is not handled.
- function() {
- if (!this.searchAndSelectByEntry(entry))
- this.selectedItem = null;
- }.bind(this));
- }.bind(this));
-};
-
-/**
- * Resolves the My Drive root's entry, if it is a fake. If the entry is already
- * resolved to a DirectoryEntry, completionCallback() will be called
- * immediately.
- * @param {function()} completionCallback Called when the resolving is
- * done (or the entry is already resolved), regardless if it is
- * successfully done or not.
- * @private
- */
-DirectoryTree.prototype.maybeResolveMyDriveRoot_ = function(
- completionCallback) {
- var myDriveItem = this.items[0];
- if (!util.isFakeEntry(myDriveItem.entry)) {
- // The entry is already resolved. Don't need to try again.
- completionCallback();
- return;
- }
-
- // The entry is a fake.
- this.directoryModel_.resolveDirectory(
- myDriveItem.fullPath,
- function(entry) {
- if (!util.isFakeEntry(entry))
- myDriveItem.dirEntry_ = entry;
-
- completionCallback();
- },
- completionCallback);
-};
-
-/**
- * Retrieves the latest subdirectories and update them on the tree.
- * @param {boolean} recursive True if the update is recursively.
- * @param {function()=} opt_successCallback Callback called on success.
- * @param {function()=} opt_errorCallback Callback called on error.
- */
-DirectoryTree.prototype.updateSubDirectories = function(
- recursive, opt_successCallback, opt_errorCallback) {
- this.entries_ = DirectoryTreeUtil.generateTopLevelEntries();
- this.redraw(recursive);
- if (opt_successCallback)
- opt_successCallback();
-};
-
-/**
- * Redraw the list.
- * @param {boolean} recursive True if the update is recursively. False if the
- * only root items are updated.
- */
-DirectoryTree.prototype.redraw = function(recursive) {
- this.updateSubElementsFromList(recursive);
-};
-
-/**
- * Invoked when the filter is changed.
- * @private
- */
-DirectoryTree.prototype.onFilterChanged_ = function() {
- // Returns immediately, if the tree is hidden.
- if (this.hidden)
- return;
-
- this.redraw(true /* recursive */);
-};
-
-/**
- * Invoked when a directory is changed.
- * @param {!UIEvent} event Event.
- * @private
- */
-DirectoryTree.prototype.onDirectoryContentChanged_ = function(event) {
- if (event.eventType == 'changed') {
- // TODO: Use Entry instead of urls. This will stop working once migrating
- // to separate file systems. See: crbug.com/325052.
- if (!DirectoryTreeUtil.isEligiblePathForDirectoryTree(event.entry.fullPath))
- return;
-
- var myDriveItem = this.items[0];
- myDriveItem.updateItemByPath(event.entry.fullPath);
- }
-};
-
-/**
- * Invoked when the current directory is changed.
- * @param {!UIEvent} event Event.
- * @private
- */
-DirectoryTree.prototype.onCurrentDirectoryChanged_ = function(event) {
- this.selectByEntry(event.newDirEntry);
-};
-
-/**
- * Sets the margin height for the transparent preview panel at the bottom.
- * @param {number} margin Margin to be set in px.
- */
-DirectoryTree.prototype.setBottomMarginForPanel = function(margin) {
- this.style.paddingBottom = margin + 'px';
- this.scrollBar_.setBottomMarginForPanel(margin);
-};
-
-/**
- * Updates the UI after the layout has changed.
- */
-DirectoryTree.prototype.relayout = function() {
- cr.dispatchSimpleEvent(this, 'relayout');
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/drag_selector.js b/chromium/chrome/browser/resources/file_manager/foreground/js/drag_selector.js
deleted file mode 100644
index edc55165dfb..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/drag_selector.js
+++ /dev/null
@@ -1,244 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Drag selector used on the file list or the grid table.
- * TODO(hirono): Support drag selection for grid view. crbug.com/224832
- * @constructor
- */
-function DragSelector() {
- /**
- * Target list of drag selection.
- * @type {cr.ui.List}
- * @private
- */
- this.target_ = null;
-
- /**
- * Border element of drag handle.
- * @type {HtmlElement}
- * @private
- */
- this.border_ = null;
-
- /**
- * Start point of dragging.
- * @type {number?}
- * @private
- */
- this.startX_ = null;
-
- /**
- * Start point of dragging.
- * @type {number?}
- * @private
- */
- this.startY_ = null;
-
- /**
- * Indexes of selected items by dragging at the last update.
- * @type {Array.<number>!}
- * @private
- */
- this.lastSelection_ = [];
-
- /**
- * Indexes of selected items at the start of dragging.
- * @type {Array.<number>!}
- * @private
- */
- this.originalSelection_ = [];
-
- // Bind handlers to make them removable.
- this.onMouseMoveBound_ = this.onMouseMove_.bind(this);
- this.onMouseUpBound_ = this.onMouseUp_.bind(this);
-
- Object.seal(this);
-}
-
-/**
- * Flag that shows whether the item is included in the selection or not.
- * @enum {number}
- * @private
- */
-DragSelector.SelectionFlag_ = {
- IN_LAST_SELECTION: 1 << 0,
- IN_CURRENT_SELECTION: 1 << 1
-};
-
-/**
- * Obtains the scrolled position in the element of mouse pointer from the mouse
- * event.
- *
- * @param {HTMLElement} element Element that has the scroll bars.
- * @param {Event} event The mouse event.
- * @return {object} Scrolled position.
- */
-DragSelector.getScrolledPosition = function(element, event) {
- if (!element.cachedBounds) {
- element.cachedBounds = element.getBoundingClientRect();
- if (!element.cachedBounds)
- return null;
- }
- var rect = element.cachedBounds;
- return {
- x: event.clientX - rect.left + element.scrollLeft,
- y: event.clientY - rect.top + element.scrollTop
- };
-};
-
-/**
- * Starts drag selection by reacting dragstart event.
- * This function must be called from handlers of dragstart event.
- *
- * @this {DragSelector}
- * @param {cr.ui.List} list List where the drag selection starts.
- * @param {Event} event The dragstart event.
- */
-DragSelector.prototype.startDragSelection = function(list, event) {
- // Precondition check
- if (!list.selectionModel_.multiple || this.target_)
- return;
-
- // Set the target of the drag selection
- this.target_ = list;
-
- // Prevent the default action.
- event.preventDefault();
-
- // Save the start state.
- var startPos = DragSelector.getScrolledPosition(list, event);
- if (!startPos)
- return;
- this.startX_ = startPos.x;
- this.startY_ = startPos.y;
- this.lastSelection_ = [];
- this.originalSelection_ = this.target_.selectionModel_.selectedIndexes;
-
- // Create and add the border element
- if (!this.border_) {
- this.border_ = this.target_.ownerDocument.createElement('div');
- this.border_.className = 'drag-selection-border';
- }
- this.border_.style.left = this.startX_ + 'px';
- this.border_.style.top = this.startY_ + 'px';
- this.border_.style.width = '0';
- this.border_.style.height = '0';
- list.appendChild(this.border_);
-
- // If no modifier key is pressed, clear the original selection.
- if (!event.shiftKey && !event.ctrlKey)
- this.target_.selectionModel_.unselectAll();
-
- // Register event handlers.
- // The handlers are bounded at the constructor.
- this.target_.ownerDocument.addEventListener(
- 'mousemove', this.onMouseMoveBound_, true);
- this.target_.ownerDocument.addEventListener(
- 'mouseup', this.onMouseUpBound_, true);
-};
-
-/**
- * Handles the mousemove event.
- * @private
- * @param {MouseEvent} event The mousemove event.
- */
-DragSelector.prototype.onMouseMove_ = function(event) {
- // Get the selection bounds.
- var pos = DragSelector.getScrolledPosition(this.target_, event);
- var borderBounds = {
- left: Math.max(Math.min(this.startX_, pos.x), 0),
- top: Math.max(Math.min(this.startY_, pos.y), 0),
- right: Math.min(Math.max(this.startX_, pos.x), this.target_.scrollWidth),
- bottom: Math.min(Math.max(this.startY_, pos.y), this.target_.scrollHeight)
- };
- borderBounds.width = borderBounds.right - borderBounds.left;
- borderBounds.height = borderBounds.bottom - borderBounds.top;
-
- // Collect items within the selection rect.
- var currentSelection = this.target_.getHitElements(
- borderBounds.left,
- borderBounds.top,
- borderBounds.width,
- borderBounds.height);
- var pointedElements = this.target_.getHitElements(pos.x, pos.y);
- var leadIndex = pointedElements.length ? pointedElements[0] : -1;
-
- // Diff the selection between currentSelection and this.lastSelection_.
- var selectionFlag = [];
- for (var i = 0; i < this.lastSelection_.length; i++) {
- var index = this.lastSelection_[i];
- // Bit operator can be used for undefined value.
- selectionFlag[index] =
- selectionFlag[index] | DragSelector.SelectionFlag_.IN_LAST_SELECTION;
- }
- for (var i = 0; i < currentSelection.length; i++) {
- var index = currentSelection[i];
- // Bit operator can be used for undefined value.
- selectionFlag[index] =
- selectionFlag[index] | DragSelector.SelectionFlag_.IN_CURRENT_SELECTION;
- }
-
- // Update the selection
- this.target_.selectionModel_.beginChange();
- for (var name in selectionFlag) {
- var index = parseInt(name);
- var flag = selectionFlag[name];
- // The flag may be one of followings:
- // - IN_LAST_SELECTION | IN_CURRENT_SELECTION
- // - IN_LAST_SELECTION
- // - IN_CURRENT_SELECTION
- // - undefined
-
- // If the flag equals to (IN_LAST_SELECTION | IN_CURRENT_SELECTION),
- // this is included in both the last selection and the current selection.
- // We have nothing to do for this item.
-
- if (flag == DragSelector.SelectionFlag_.IN_LAST_SELECTION) {
- // If the flag equals to IN_LAST_SELECTION,
- // then the item is included in lastSelection but not in currentSelection.
- // Revert the selection state to this.originalSelection_.
- this.target_.selectionModel_.setIndexSelected(
- index, this.originalSelection_.indexOf(index) != -1);
- } else if (flag == DragSelector.SelectionFlag_.IN_CURRENT_SELECTION) {
- // If the flag equals to IN_CURRENT_SELECTION,
- // this is included in currentSelection but not in lastSelection.
- this.target_.selectionModel_.setIndexSelected(index, true);
- }
- }
- if (leadIndex != -1) {
- this.target_.selectionModel_.leadIndex = leadIndex;
- this.target_.selectionModel_.anchorIndex = leadIndex;
- }
- this.target_.selectionModel_.endChange();
- this.lastSelection_ = currentSelection;
-
- // Update the size of border
- this.border_.style.left = borderBounds.left + 'px';
- this.border_.style.top = borderBounds.top + 'px';
- this.border_.style.width = borderBounds.width + 'px';
- this.border_.style.height = borderBounds.height + 'px';
-};
-
-/**
- * Handle the mouseup event.
- * @private
- * @param {MouseEvent} event The mouseup event.
- */
-DragSelector.prototype.onMouseUp_ = function(event) {
- this.onMouseMove_(event);
- this.target_.removeChild(this.border_);
- this.target_.ownerDocument.removeEventListener(
- 'mousemove', this.onMouseMoveBound_, true);
- this.target_.ownerDocument.removeEventListener(
- 'mouseup', this.onMouseUpBound_, true);
- cr.dispatchSimpleEvent(this.target_, 'dragselectionend');
- this.target_.cachedBounds = null;
- this.target_ = null;
- // The target may select an item by reacting to the mouseup event.
- // This suppress to the selecting behavior.
- event.stopPropagation();
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/drive_banners.js b/chromium/chrome/browser/resources/file_manager/foreground/js/drive_banners.js
deleted file mode 100644
index dc1cd924d7a..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/drive_banners.js
+++ /dev/null
@@ -1,660 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Responsible for showing following banners in the file list.
- * - WelcomeBanner
- * - AuthFailBanner
- * @param {DirectoryModel} directoryModel The model.
- * @param {VolumeManagerWrapper} volumeManager The manager.
- * @param {DOMDocument} document HTML document.
- * @param {boolean} showOffers True if we should show offer banners.
- * @constructor
- */
-function FileListBannerController(
- directoryModel, volumeManager, document, showOffers) {
- this.directoryModel_ = directoryModel;
- this.volumeManager_ = volumeManager;
- this.document_ = document;
- this.showOffers_ = showOffers;
- this.driveEnabled_ = false;
-
- this.initializeWelcomeBanner_();
- this.privateOnDirectoryChangedBound_ =
- this.privateOnDirectoryChanged_.bind(this);
-
- var handler = this.checkSpaceAndMaybeShowWelcomeBanner_.bind(this);
- this.directoryModel_.addEventListener('scan-completed', handler);
- this.directoryModel_.addEventListener('rescan-completed', handler);
- this.directoryModel_.addEventListener('directory-changed',
- this.onDirectoryChanged_.bind(this));
-
- this.unmountedPanel_ = this.document_.querySelector('#unmounted-panel');
- this.volumeManager_.volumeInfoList.addEventListener(
- 'splice', this.onVolumeInfoListSplice_.bind(this));
- this.volumeManager_.addEventListener('drive-connection-changed',
- this.onDriveConnectionChanged_.bind(this));
-
- chrome.storage.onChanged.addListener(this.onStorageChange_.bind(this));
- this.welcomeHeaderCounter_ = WELCOME_HEADER_COUNTER_LIMIT;
- this.warningDismissedCounter_ = 0;
- chrome.storage.local.get([WELCOME_HEADER_COUNTER_KEY, WARNING_DISMISSED_KEY],
- function(values) {
- this.welcomeHeaderCounter_ =
- parseInt(values[WELCOME_HEADER_COUNTER_KEY]) || 0;
- this.warningDismissedCounter_ =
- parseInt(values[WARNING_DISMISSED_KEY]) || 0;
- }.bind(this));
-
- this.authFailedBanner_ =
- this.document_.querySelector('#drive-auth-failed-warning');
- var authFailedText = this.authFailedBanner_.querySelector('.drive-text');
- authFailedText.innerHTML = util.htmlUnescape(str('DRIVE_NOT_REACHED'));
- authFailedText.querySelector('a').addEventListener('click', function(e) {
- chrome.fileBrowserPrivate.logoutUserForReauthentication();
- e.preventDefault();
- });
- this.maybeShowAuthFailBanner_();
-}
-
-/**
- * FileListBannerController extends cr.EventTarget.
- */
-FileListBannerController.prototype.__proto__ = cr.EventTarget.prototype;
-
-/**
- * Key in localStorage to keep number of times the Drive Welcome
- * banner has shown.
- */
-var WELCOME_HEADER_COUNTER_KEY = 'driveWelcomeHeaderCounter';
-
-// If the warning was dismissed before, this key stores the quota value
-// (as of the moment of dismissal).
-// If the warning was never dismissed or was reset this key stores 0.
-var WARNING_DISMISSED_KEY = 'driveSpaceWarningDismissed';
-
-/**
- * Maximum times Drive Welcome banner could have shown.
- */
-var WELCOME_HEADER_COUNTER_LIMIT = 25;
-
-/**
- * Initializes the banner to promote DRIVE.
- * This method must be called before any of showing banner functions, and
- * also before registering them as callbacks.
- * @private
- */
-FileListBannerController.prototype.initializeWelcomeBanner_ = function() {
- this.usePromoWelcomeBanner_ = !util.boardIs('x86-mario') &&
- !util.boardIs('x86-zgb') &&
- !util.boardIs('x86-alex');
-};
-
-/**
- * @param {number} value How many times the Drive Welcome header banner
- * has shown.
- * @private
- */
-FileListBannerController.prototype.setWelcomeHeaderCounter_ = function(value) {
- var values = {};
- values[WELCOME_HEADER_COUNTER_KEY] = value;
- chrome.storage.local.set(values);
-};
-
-/**
- * @param {number} value How many times the low space warning has dismissed.
- * @private
- */
-FileListBannerController.prototype.setWarningDismissedCounter_ =
- function(value) {
- var values = {};
- values[WARNING_DISMISSED_KEY] = value;
- chrome.storage.local.set(values);
-};
-
-/**
- * chrome.storage.onChanged event handler.
- * @param {Object.<string, Object>} changes Changes values.
- * @param {string} areaName "local" or "sync".
- * @private
- */
-FileListBannerController.prototype.onStorageChange_ = function(changes,
- areaName) {
- if (areaName == 'local' && WELCOME_HEADER_COUNTER_KEY in changes) {
- this.welcomeHeaderCounter_ = changes[WELCOME_HEADER_COUNTER_KEY].newValue;
- }
- if (areaName == 'local' && WARNING_DISMISSED_KEY in changes) {
- this.warningDismissedCounter_ = changes[WARNING_DISMISSED_KEY].newValue;
- }
-};
-
-/**
- * Invoked when the drive connection status is change in the volume manager.
- * @private
- */
-FileListBannerController.prototype.onDriveConnectionChanged_ = function() {
- this.maybeShowAuthFailBanner_();
-};
-
-/**
- * @param {string} type 'none'|'page'|'header'.
- * @param {string} messageId Resource ID of the message.
- * @private
- */
-FileListBannerController.prototype.prepareAndShowWelcomeBanner_ =
- function(type, messageId) {
- this.showWelcomeBanner_(type);
-
- var container = this.document_.querySelector('.drive-welcome.' + type);
- if (container.firstElementChild)
- return; // Do not re-create.
-
- if (!this.document_.querySelector('link[drive-welcome-style]')) {
- var style = this.document_.createElement('link');
- style.rel = 'stylesheet';
- style.href = 'foreground/css/drive_welcome.css';
- style.setAttribute('drive-welcome-style', '');
- this.document_.head.appendChild(style);
- }
-
- var wrapper = util.createChild(container, 'drive-welcome-wrapper');
- util.createChild(wrapper, 'drive-welcome-icon');
-
- var close = util.createChild(wrapper, 'cr-dialog-close');
- close.addEventListener('click', this.closeWelcomeBanner_.bind(this));
-
- var message = util.createChild(wrapper, 'drive-welcome-message');
-
- var title = util.createChild(message, 'drive-welcome-title');
-
- var text = util.createChild(message, 'drive-welcome-text');
- text.innerHTML = str(messageId);
-
- var links = util.createChild(message, 'drive-welcome-links');
-
- var more;
- if (this.usePromoWelcomeBanner_) {
- var welcomeTitle = str('DRIVE_WELCOME_TITLE_ALTERNATIVE');
- if (util.boardIs('link'))
- welcomeTitle = str('DRIVE_WELCOME_TITLE_ALTERNATIVE_1TB');
- title.textContent = welcomeTitle;
- more = util.createChild(links,
- 'drive-welcome-button drive-welcome-start', 'a');
- more.textContent = str('DRIVE_WELCOME_CHECK_ELIGIBILITY');
- more.href = str('GOOGLE_DRIVE_REDEEM_URL');
- } else {
- title.textContent = str('DRIVE_WELCOME_TITLE');
- more = util.createChild(links, 'plain-link', 'a');
- more.textContent = str('DRIVE_LEARN_MORE');
- more.href = str('GOOGLE_DRIVE_OVERVIEW_URL');
- }
- more.tabIndex = '13'; // See: go/filesapp-tabindex.
- more.target = '_blank';
-
- var dismiss;
- if (this.usePromoWelcomeBanner_)
- dismiss = util.createChild(links, 'drive-welcome-button');
- else
- dismiss = util.createChild(links, 'plain-link');
-
- dismiss.classList.add('drive-welcome-dismiss');
- dismiss.textContent = str('DRIVE_WELCOME_DISMISS');
- dismiss.addEventListener('click', this.closeWelcomeBanner_.bind(this));
-
- this.previousDirWasOnDrive_ = false;
-};
-
-/**
- * Show or hide the "Low Google Drive space" warning.
- * @param {boolean} show True if the box need to be shown.
- * @param {Object} sizeStats Size statistics. Should be defined when showing the
- * warning.
- * @private
- */
-FileListBannerController.prototype.showLowDriveSpaceWarning_ =
- function(show, sizeStats) {
- var box = this.document_.querySelector('#volume-space-warning');
-
- // Avoid showing two banners.
- // TODO(kaznacheev): Unify the low space warning and the promo header.
- if (show)
- this.cleanupWelcomeBanner_();
-
- if (box.hidden == !show)
- return;
-
- if (this.warningDismissedCounter_) {
- if (this.warningDismissedCounter_ ==
- sizeStats.totalSize && // Quota had not changed
- sizeStats.remainingSize / sizeStats.totalSize < 0.15) {
- // Since the last dismissal decision the quota has not changed AND
- // the user did not free up significant space. Obey the dismissal.
- show = false;
- } else {
- // Forget the dismissal. Warning will be shown again.
- this.setWarningDismissedCounter_(0);
- }
- }
-
- box.textContent = '';
- if (show) {
- var icon = this.document_.createElement('div');
- icon.className = 'drive-icon';
- box.appendChild(icon);
-
- var text = this.document_.createElement('div');
- text.className = 'drive-text';
- text.textContent = strf('DRIVE_SPACE_AVAILABLE_LONG',
- util.bytesToString(sizeStats.remainingSize));
- box.appendChild(text);
-
- var link = this.document_.createElement('a');
- link.className = 'plain-link';
- link.textContent = str('DRIVE_BUY_MORE_SPACE_LINK');
- link.href = str('GOOGLE_DRIVE_BUY_STORAGE_URL');
- link.target = '_blank';
- box.appendChild(link);
-
- var close = this.document_.createElement('div');
- close.className = 'cr-dialog-close';
- box.appendChild(close);
- close.addEventListener('click', function(total) {
- window.localStorage[WARNING_DISMISSED_KEY] = total;
- box.hidden = true;
- this.requestRelayout_(100);
- }.bind(this, sizeStats.totalSize));
- }
-
- if (box.hidden != !show) {
- box.hidden = !show;
- this.requestRelayout_(100);
- }
-};
-/**
- * Closes the Drive Welcome banner.
- * @private
- */
-FileListBannerController.prototype.closeWelcomeBanner_ = function() {
- this.cleanupWelcomeBanner_();
- // Stop showing the welcome banner.
- this.setWelcomeHeaderCounter_(WELCOME_HEADER_COUNTER_LIMIT);
-};
-
-/**
- * Shows or hides the welcome banner for drive.
- * @private
- */
-FileListBannerController.prototype.checkSpaceAndMaybeShowWelcomeBanner_ =
- function() {
- if (!this.isOnCurrentProfileDrive()) {
- // We are not on the drive file system. Do not show (close) the welcome
- // banner.
- this.cleanupWelcomeBanner_();
- this.previousDirWasOnDrive_ = false;
- return;
- }
-
- var driveVolume = this.volumeManager_.getCurrentProfileVolumeInfo(
- util.VolumeType.DRIVE);
- if (this.welcomeHeaderCounter_ >= WELCOME_HEADER_COUNTER_LIMIT ||
- !driveVolume || driveVolume.error) {
- // The banner is already shown enough times or the drive FS is not mounted.
- // So, do nothing here.
- return;
- }
-
- if (!this.showOffers_) {
- // Because it is not necessary to show the offer, set
- // |usePromoWelcomeBanner_| false here. Note that it probably should be able
- // to do this in the constructor, but there remains non-trivial path,
- // which may be causes |usePromoWelcomeBanner_| == true's behavior even
- // if |showOffers_| is false.
- // TODO(hidehiko): Make sure if it is expected or not, and simplify
- // |showOffers_| if possible.
- this.usePromoWelcomeBanner_ = false;
- }
-
- // Perform asynchronous tasks in parallel.
- var group = new AsyncUtil.Group();
-
- // Choose the offer basing on the board name. The default one is 100 GB.
- var offerSize = 100; // In GB.
- var offerServiceId = 'drive.cros.echo.1';
-
- if (util.boardIs('link')) {
- offerSize = 1024; // 1 TB.
- offerServiceId = 'drive.cros.echo.2';
- }
-
- // If the offer has been checked, then do not show the promo anymore.
- group.add(function(onCompleted) {
- chrome.echoPrivate.getOfferInfo(offerServiceId, function(offerInfo) {
- // If the offer has not been checked, then an error is raised.
- if (!chrome.runtime.lastError)
- this.usePromoWelcomeBanner_ = false;
- onCompleted();
- }.bind(this));
- }.bind(this));
-
- if (this.usePromoWelcomeBanner_) {
- // getSizeStats for Drive file system accesses to the server, so we should
- // minimize the invocation.
- group.add(function(onCompleted) {
- chrome.fileBrowserPrivate.getSizeStats(
- util.makeFilesystemUrl(this.directoryModel_.getCurrentRootPath()),
- function(result) {
- if (result && result.totalSize >= offerSize * 1024 * 1024 * 1024)
- this.usePromoWelcomeBanner_ = false;
- onCompleted();
- }.bind(this));
- }.bind(this));
- }
-
- group.run(this.maybeShowWelcomeBanner_.bind(this));
-};
-
-/**
- * Decides which banner should be shown, and show it. This method is designed
- * to be called only from checkSpaceAndMaybeShowWelcomeBanner_.
- * @private
- */
-FileListBannerController.prototype.maybeShowWelcomeBanner_ = function() {
- if (this.directoryModel_.getFileList().length == 0 &&
- this.welcomeHeaderCounter_ == 0) {
- // Only show the full page banner if the header banner was never shown.
- // Do not increment the counter.
- // The timeout below is required because sometimes another
- // 'rescan-completed' event arrives shortly with non-empty file list.
- setTimeout(function() {
- if (this.isOnCurrentProfileDrive() && this.welcomeHeaderCounter_ == 0) {
- this.prepareAndShowWelcomeBanner_('page', 'DRIVE_WELCOME_TEXT_LONG');
- }
- }.bind(this), 2000);
- } else {
- // We do not want to increment the counter when the user navigates
- // between different directories on Drive, but we increment the counter
- // once anyway to prevent the full page banner from showing.
- if (!this.previousDirWasOnDrive_ || this.welcomeHeaderCounter_ == 0) {
- this.setWelcomeHeaderCounter_(this.welcomeHeaderCounter_ + 1);
- this.prepareAndShowWelcomeBanner_('header', 'DRIVE_WELCOME_TEXT_SHORT');
- }
- }
- this.previousDirWasOnDrive_ = true;
-};
-
-/**
- * @return {boolean} True if current directory is on Drive root of current
- * profile.
- */
-FileListBannerController.prototype.isOnCurrentProfileDrive = function() {
- var entry = this.directoryModel_.getCurrentDirEntry();
- if (!entry || util.isFakeEntry(entry))
- return false;
- var locationInfo = this.volumeManager_.getLocationInfo(entry);
- return locationInfo &&
- locationInfo.rootType === RootType.DRIVE &&
- locationInfo.volumeInfo.profile.isCurrentProfile;
-};
-
-/**
- * Shows the Drive Welcome banner.
- * @param {string} type 'page'|'head'|'none'.
- * @private
- */
-FileListBannerController.prototype.showWelcomeBanner_ = function(type) {
- var container = this.document_.querySelector('.dialog-container');
- if (container.getAttribute('drive-welcome') != type) {
- container.setAttribute('drive-welcome', type);
- this.requestRelayout_(200); // Resize only after the animation is done.
- }
-};
-
-/**
- * Update the UI when the current directory changes.
- *
- * @param {Event} event The directory-changed event.
- * @private
- */
-FileListBannerController.prototype.onDirectoryChanged_ = function(event) {
- var rootVolume = this.volumeManager_.getVolumeInfo(event.newDirEntry);
- var previousRootVolume = event.previousDirEntry ?
- this.volumeManager_.getVolumeInfo(event.previousDirEntry) : null;
-
- // Show (or hide) the low space warning.
- this.maybeShowLowSpaceWarning_(rootVolume);
-
- // Add or remove listener to show low space warning, if necessary.
- var isLowSpaceWarningTarget = this.isLowSpaceWarningTarget_(rootVolume);
- if (isLowSpaceWarningTarget !==
- this.isLowSpaceWarningTarget_(previousRootVolume)) {
- if (isLowSpaceWarningTarget) {
- chrome.fileBrowserPrivate.onDirectoryChanged.addListener(
- this.privateOnDirectoryChangedBound_);
- } else {
- chrome.fileBrowserPrivate.onDirectoryChanged.removeListener(
- this.privateOnDirectoryChangedBound_);
- }
- }
-
- if (!this.isOnCurrentProfileDrive()) {
- this.cleanupWelcomeBanner_();
- this.authFailedBanner_.hidden = true;
- }
-
- this.updateDriveUnmountedPanel_();
- if (this.isOnCurrentProfileDrive()) {
- this.unmountedPanel_.classList.remove('retry-enabled');
- this.maybeShowAuthFailBanner_();
- }
-};
-
-/**
- * @param {VolumeInfo} volumeInfo Volume info to be checked.
- * @return {boolean} true if the file system specified by |root| is a target
- * to show low space warning. Otherwise false.
- * @private
- */
-FileListBannerController.prototype.isLowSpaceWarningTarget_ =
- function(volumeInfo) {
- return volumeInfo &&
- volumeInfo.profile.isCurrentProfile &&
- (volumeInfo.volumeType === util.VolumeType.DOWNLOADS ||
- volumeInfo.volumeType === util.VolumeType.DRIVE);
-};
-
-/**
- * Callback which is invoked when the file system has been changed.
- * @param {Object} event chrome.fileBrowserPrivate.onDirectoryChanged event.
- * @private
- */
-FileListBannerController.prototype.privateOnDirectoryChanged_ = function(
- event) {
- if (!this.directoryModel_.getCurrentDirEntry())
- return;
-
- var currentDirEntry = this.directoryModel_.getCurrentDirEntry();
- var currentVolume = currentDirEntry &&
- this.volumeManager_.getVolumeInfo(currentDirEntry);
- var eventVolume = this.volumeManager_.getVolumeInfo(event.entry);
- if (currentVolume === eventVolume) {
- // The file system we are currently on is changed.
- // So, check the free space.
- this.maybeShowLowSpaceWarning_(currentVolume);
- }
-};
-
-/**
- * Shows or hides the low space warning.
- * @param {VolumeInfo} volume Type of volume, which we are interested in.
- * @private
- */
-FileListBannerController.prototype.maybeShowLowSpaceWarning_ = function(
- volume) {
- // TODO(kaznacheev): Unify the two low space warning.
- var threshold = 0;
- switch (volume.volumeType) {
- case util.VolumeType.DOWNLOADS:
- this.showLowDriveSpaceWarning_(false);
- threshold = 0.2;
- break;
- case util.VolumeType.DRIVE:
- this.showLowDownloadsSpaceWarning_(false);
- threshold = 0.1;
- break;
- default:
- // If the current file system is neither the DOWNLOAD nor the DRIVE,
- // just hide the warning.
- this.showLowDownloadsSpaceWarning_(false);
- this.showLowDriveSpaceWarning_(false);
- return;
- }
-
- chrome.fileBrowserPrivate.getSizeStats(
- volume.getDisplayRootDirectoryURL(),
- function(sizeStats) {
- var currentVolume = this.volumeManager_.getVolumeInfo(
- this.directoryModel_.getCurrentDirEntry());
- if (volume !== currentVolume) {
- // This happens when the current directory is moved during requesting
- // the file system size. Just ignore it.
- return;
- }
- // sizeStats is undefined, if some error occurs.
- if (!sizeStats || sizeStats.totalSize == 0)
- return;
-
- var remainingRatio = sizeStats.remainingSize / sizeStats.totalSize;
- var isLowDiskSpace = remainingRatio < threshold;
- if (volume.volumeType === util.VolumeType.DOWNLOADS)
- this.showLowDownloadsSpaceWarning_(isLowDiskSpace);
- else
- this.showLowDriveSpaceWarning_(isLowDiskSpace, sizeStats);
- }.bind(this));
-};
-
-/**
- * removes the Drive Welcome banner.
- * @private
- */
-FileListBannerController.prototype.cleanupWelcomeBanner_ = function() {
- this.showWelcomeBanner_('none');
-};
-
-/**
- * Notifies the file manager what layout must be recalculated.
- * @param {number} delay In milliseconds.
- * @private
- */
-FileListBannerController.prototype.requestRelayout_ = function(delay) {
- var self = this;
- setTimeout(function() {
- cr.dispatchSimpleEvent(self, 'relayout');
- }, delay);
-};
-
-/**
- * Show or hide the "Low disk space" warning.
- * @param {boolean} show True if the box need to be shown.
- * @private
- */
-FileListBannerController.prototype.showLowDownloadsSpaceWarning_ =
- function(show) {
- var box = this.document_.querySelector('.downloads-warning');
-
- if (box.hidden == !show) return;
-
- if (show) {
- var html = util.htmlUnescape(str('DOWNLOADS_DIRECTORY_WARNING'));
- box.innerHTML = html;
- var link = box.querySelector('a');
- link.href = str('DOWNLOADS_LOW_SPACE_WARNING_HELP_URL');
- link.target = '_blank';
- } else {
- box.innerHTML = '';
- }
-
- box.hidden = !show;
- this.requestRelayout_(100);
-};
-
-/**
- * Creates contents for the DRIVE unmounted panel.
- * @private
- */
-FileListBannerController.prototype.ensureDriveUnmountedPanelInitialized_ =
- function() {
- var panel = this.unmountedPanel_;
- if (panel.firstElementChild)
- return;
-
- var create = function(parent, tag, className, opt_textContent) {
- var div = panel.ownerDocument.createElement(tag);
- div.className = className;
- div.textContent = opt_textContent || '';
- parent.appendChild(div);
- return div;
- };
-
- var loading = create(panel, 'div', 'loading', str('DRIVE_LOADING'));
- var spinnerBox = create(loading, 'div', 'spinner-box');
- create(spinnerBox, 'div', 'spinner');
- create(panel, 'div', 'error', str('DRIVE_CANNOT_REACH'));
-
- var learnMore = create(panel, 'a', 'learn-more plain-link',
- str('DRIVE_LEARN_MORE'));
- learnMore.href = str('GOOGLE_DRIVE_ERROR_HELP_URL');
- learnMore.target = '_blank';
-};
-
-/**
- * Called when volume info list is updated.
- * @param {Event} event Splice event data on volume info list.
- * @private
- */
-FileListBannerController.prototype.onVolumeInfoListSplice_ = function(event) {
- var isDriveVolume = function(volumeInfo) {
- return volumeInfo.volumeType === util.VolumeType.DRIVE;
- };
- if (event.removed.some(isDriveVolume) || event.added.some(isDriveVolume))
- this.updateDriveUnmountedPanel_();
-};
-
-/**
- * Shows the panel when current directory is DRIVE and it's unmounted.
- * Hides it otherwise. The panel shows spinner if DRIVE is mounting or
- * an error message if it failed.
- * @private
- */
-FileListBannerController.prototype.updateDriveUnmountedPanel_ = function() {
- var node = this.document_.body;
- if (this.isOnCurrentProfileDrive()) {
- var driveVolume = this.volumeManager_.getCurrentProfileVolumeInfo(
- util.VolumeType.DRIVE);
- if (driveVolume && driveVolume.error) {
- this.ensureDriveUnmountedPanelInitialized_();
- this.unmountedPanel_.classList.add('retry-enabled');
- } else {
- this.unmountedPanel_.classList.remove('retry-enabled');
- }
- node.setAttribute('drive', status);
- } else {
- node.removeAttribute('drive');
- }
-};
-
-/**
- * Updates the visibility of Drive Connection Warning banner, retrieving the
- * current connection information.
- * @private
- */
-FileListBannerController.prototype.maybeShowAuthFailBanner_ = function() {
- var connection = this.volumeManager_.getDriveConnectionState();
- var showDriveNotReachedMessage =
- this.isOnCurrentProfileDrive() &&
- connection.type == util.DriveConnectionType.OFFLINE &&
- connection.reason == util.DriveConnectionReason.NOT_READY;
- this.authFailedBanner_.hidden = !showDriveNotReachedMessage;
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/error_counter.js b/chromium/chrome/browser/resources/file_manager/foreground/js/error_counter.js
deleted file mode 100644
index 8cec3bba03f..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/error_counter.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * This variable is checked in SelectFileDialogExtensionBrowserTest.
- * @type {number}
- */
-window.JSErrorCount = 0;
-
-/**
- * Count uncaught exceptions.
- */
-window.onerror = function() { window.JSErrorCount++; };
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/error_dialog.js b/chromium/chrome/browser/resources/file_manager/foreground/js/error_dialog.js
deleted file mode 100644
index 5dd3545d3c7..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/error_dialog.js
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * @param {HTMLElement} parentNode Node to be parent for this dialog.
- * @constructor
- */
-function ErrorDialog(parentNode) {
- cr.ui.dialogs.BaseDialog.call(this, parentNode);
-}
-
-ErrorDialog.prototype = {
- __proto__: cr.ui.dialogs.BaseDialog.prototype
-};
-
-/**
- * One-time initialization of DOM.
- * @private
- */
-ErrorDialog.prototype.initDom_ = function() {
- cr.ui.dialogs.BaseDialog.prototype.initDom_.call(this);
- this.frame_.classList.add('error-dialog-frame');
- var img = this.document_.createElement('div');
- img.className = 'error-dialog-img';
- this.frame_.insertBefore(img, this.text_);
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/file_grid.js b/chromium/chrome/browser/resources/file_manager/foreground/js/file_grid.js
deleted file mode 100644
index b275cd0e9f5..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/file_grid.js
+++ /dev/null
@@ -1,302 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * FileGrid constructor.
- *
- * Represents grid for the Grid Vew in the File Manager.
- * @constructor
- * @extends {cr.ui.Grid}
- */
-
-function FileGrid() {
- throw new Error('Use FileGrid.decorate');
-}
-
-/**
- * Thumbnail quality.
- * @enum {number}
- */
-FileGrid.ThumbnailQuality = {
- LOW: 0,
- HIGH: 1
-};
-
-/**
- * Inherits from cr.ui.Grid.
- */
-FileGrid.prototype.__proto__ = cr.ui.Grid.prototype;
-
-/**
- * Decorates an HTML element to be a FileGrid.
- * @param {HTMLElement} self The grid to decorate.
- * @param {MetadataCache} metadataCache Metadata cache to find entries
- * metadata.
- */
-FileGrid.decorate = function(self, metadataCache) {
- cr.ui.Grid.decorate(self);
- self.__proto__ = FileGrid.prototype;
- self.metadataCache_ = metadataCache;
-
- self.scrollBar_ = new MainPanelScrollBar();
- self.scrollBar_.initialize(self.parentNode, self);
- self.setBottomMarginForPanel(0);
-
- self.itemConstructor = function(entry) {
- var item = self.ownerDocument.createElement('LI');
- FileGrid.Item.decorate(item, entry, self);
- return item;
- };
-
- self.relayoutAggregation_ =
- new AsyncUtil.Aggregation(self.relayoutImmediately_.bind(self));
-};
-
-/**
- * Updates items to reflect metadata changes.
- * @param {string} type Type of metadata changed.
- * @param {Object.<string, Object>} props Map from entry URLs to metadata props.
- */
-FileGrid.prototype.updateListItemsMetadata = function(type, props) {
- var boxes = this.querySelectorAll('.img-container');
- for (var i = 0; i < boxes.length; i++) {
- var box = boxes[i];
- var entry = this.dataModel.item(this.getListItemAncestor(box));
- if (!entry || !(entry.toURL() in props))
- continue;
-
- FileGrid.decorateThumbnailBox(box,
- entry,
- this.metadataCache_,
- ThumbnailLoader.FillMode.FIT,
- FileGrid.ThumbnailQuality.HIGH);
- }
-};
-
-/**
- * Redraws the UI. Skips multiple consecutive calls.
- */
-FileGrid.prototype.relayout = function() {
- this.relayoutAggregation_.run();
-};
-
-/**
- * Redraws the UI immediately.
- * @private
- */
-FileGrid.prototype.relayoutImmediately_ = function() {
- this.startBatchUpdates();
- this.columns = 0;
- this.redraw();
- this.endBatchUpdates();
- cr.dispatchSimpleEvent(this, 'relayout');
-};
-
-/**
- * Decorates thumbnail.
- * @param {HTMLElement} li List item.
- * @param {Entry} entry Entry to render a thumbnail for.
- * @param {MetadataCache} metadataCache To retrieve metadata.
- */
-FileGrid.decorateThumbnail = function(li, entry, metadataCache) {
- li.className = 'thumbnail-item';
- if (entry)
- filelist.decorateListItem(li, entry, metadataCache);
-
- var frame = li.ownerDocument.createElement('div');
- frame.className = 'thumbnail-frame';
- li.appendChild(frame);
-
- var box = li.ownerDocument.createElement('div');
- if (entry) {
- FileGrid.decorateThumbnailBox(box,
- entry,
- metadataCache,
- ThumbnailLoader.FillMode.AUTO,
- FileGrid.ThumbnailQuality.HIGH);
- }
- frame.appendChild(box);
-
- var bottom = li.ownerDocument.createElement('div');
- bottom.className = 'thumbnail-bottom';
- bottom.appendChild(filelist.renderFileNameLabel(li.ownerDocument, entry));
- frame.appendChild(bottom);
-};
-
-/**
- * Decorates the box containing a centered thumbnail image.
- *
- * @param {HTMLDivElement} box Box to decorate.
- * @param {Entry} entry Entry which thumbnail is generating for.
- * @param {MetadataCache} metadataCache To retrieve metadata.
- * @param {ThumbnailLoader.FillMode} fillMode Fill mode.
- * @param {FileGrid.ThumbnailQuality} quality Thumbnail quality.
- * @param {function(HTMLElement)=} opt_imageLoadCallback Callback called when
- * the image has been loaded before inserting it into the DOM.
- */
-FileGrid.decorateThumbnailBox = function(
- box, entry, metadataCache, fillMode, quality, opt_imageLoadCallback) {
- box.className = 'img-container';
- if (entry.isDirectory) {
- box.setAttribute('generic-thumbnail', 'folder');
- if (opt_imageLoadCallback)
- setTimeout(opt_imageLoadCallback, 0, null /* callback parameter */);
- return;
- }
-
- var metadataTypes = 'thumbnail|filesystem';
-
- if (FileType.isOnDrive(entry)) {
- metadataTypes += '|drive';
- } else {
- // TODO(dgozman): If we ask for 'media' for a Drive file we fall into an
- // infinite loop.
- metadataTypes += '|media';
- }
-
- // Drive provides high quality thumbnails via USE_EMBEDDED, however local
- // images usually provide very tiny thumbnails, therefore USE_EMBEDDE can't
- // be used to obtain high quality output.
- var useEmbedded;
- switch (quality) {
- case FileGrid.ThumbnailQuality.LOW:
- useEmbedded = ThumbnailLoader.UseEmbedded.USE_EMBEDDED;
- break;
- case FileGrid.ThumbnailQuality.HIGH:
- useEmbedded = FileType.isOnDrive(entry) ?
- ThumbnailLoader.UseEmbedded.USE_EMBEDDED :
- ThumbnailLoader.UseEmbedded.NO_EMBEDDED;
- break;
- }
-
- metadataCache.get(entry, metadataTypes,
- function(metadata) {
- new ThumbnailLoader(entry.toURL(),
- ThumbnailLoader.LoaderType.IMAGE,
- metadata,
- undefined, // opt_mediaType
- useEmbedded).
- load(box,
- fillMode,
- ThumbnailLoader.OptimizationMode.DISCARD_DETACHED,
- opt_imageLoadCallback);
- });
-};
-
-/**
- * Item for the Grid View.
- * @constructor
- */
-FileGrid.Item = function() {
- throw new Error();
-};
-
-/**
- * Inherits from cr.ui.ListItem.
- */
-FileGrid.Item.prototype.__proto__ = cr.ui.ListItem.prototype;
-
-Object.defineProperty(FileGrid.Item.prototype, 'label', {
- /**
- * @this {FileGrid.Item}
- * @return {string} Label of the item.
- */
- get: function() {
- return this.querySelector('filename-label').textContent;
- }
-});
-
-/**
- * @param {Element} li List item element.
- * @param {Entry} entry File entry.
- * @param {FileGrid} grid Owner.
- */
-FileGrid.Item.decorate = function(li, entry, grid) {
- li.__proto__ = FileGrid.Item.prototype;
- FileGrid.decorateThumbnail(li, entry, grid.metadataCache_, true);
-
- // Override the default role 'listitem' to 'option' to match the parent's
- // role (listbox).
- li.setAttribute('role', 'option');
-};
-
-/**
- * Sets the margin height for the transparent preview panel at the bottom.
- * @param {number} margin Margin to be set in px.
- */
-FileGrid.prototype.setBottomMarginForPanel = function(margin) {
- // +20 bottom margin is needed to match the bottom margin size with the
- // margin between its items.
- this.style.paddingBottom = (margin + 20) + 'px';
- this.scrollBar_.setBottomMarginForPanel(margin);
-};
-
-/**
- * Obtains if the drag selection should be start or not by referring the mouse
- * event.
- * @param {MouseEvent} event Drag start event.
- * @return {boolean} True if the mouse is hit to the background of the list.
- */
-FileGrid.prototype.shouldStartDragSelection = function(event) {
- var pos = DragSelector.getScrolledPosition(this, event);
- return this.getHitElements(pos.x, pos.y).length == 0;
-};
-
-/**
- * Obtains the column/row index that the coordinate points.
- * @param {number} coordinate Vertical/horizontal coodinate value that points
- * column/row.
- * @param {number} step Length from a column/row to the next one.
- * @param {number} threshold Threshold that determinds whether 1 offset is added
- * to the return value or not. This is used in order to handle the margin of
- * column/row.
- * @return {number} Index of hit column/row.
- * @private
- */
-FileGrid.prototype.getHitIndex_ = function(coordinate, step, threshold) {
- var index = ~~(coordinate / step);
- return (coordinate % step >= threshold) ? index + 1 : index;
-};
-
-/**
- * Obtains the index list of elements that are hit by the point or the
- * rectangle.
- *
- * We should match its argument interface with FileList.getHitElements.
- *
- * @param {number} x X coordinate value.
- * @param {number} y Y coordinate value.
- * @param {=number} opt_width Width of the coordinate.
- * @param {=number} opt_height Height of the coordinate.
- * @return {Array.<number>} Index list of hit elements.
- */
-FileGrid.prototype.getHitElements = function(x, y, opt_width, opt_height) {
- var currentSelection = [];
- var right = x + (opt_width || 0);
- var bottom = y + (opt_height || 0);
- var itemMetrics = this.measureItem();
- var horizontalStartIndex = this.getHitIndex_(
- x, itemMetrics.width, itemMetrics.width - itemMetrics.marginRight);
- var horizontalEndIndex = Math.min(this.columns, this.getHitIndex_(
- right, itemMetrics.width, itemMetrics.marginLeft));
- var verticalStartIndex = this.getHitIndex_(
- y, itemMetrics.height, itemMetrics.height - itemMetrics.bottom);
- var verticalEndIndex = this.getHitIndex_(
- bottom, itemMetrics.height, itemMetrics.marginTop);
- for (var verticalIndex = verticalStartIndex;
- verticalIndex < verticalEndIndex;
- verticalIndex++) {
- var indexBase = this.getFirstItemInRow(verticalIndex);
- for (var horizontalIndex = horizontalStartIndex;
- horizontalIndex < horizontalEndIndex;
- horizontalIndex++) {
- var index = indexBase + horizontalIndex;
- if (0 <= index && index < this.dataModel.length)
- currentSelection.push(index);
- }
- }
- return currentSelection;
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/file_manager.js b/chromium/chrome/browser/resources/file_manager/foreground/js/file_manager.js
deleted file mode 100644
index 201a4f6ad2d..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/file_manager.js
+++ /dev/null
@@ -1,3688 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * FileManager constructor.
- *
- * FileManager objects encapsulate the functionality of the file selector
- * dialogs, as well as the full screen file manager application (though the
- * latter is not yet implemented).
- *
- * @constructor
- */
-function FileManager() {
- this.initializeQueue_ = new AsyncUtil.Group();
-
- /**
- * Current list type.
- * @type {ListType}
- * @private
- */
- this.listType_ = null;
-
- /**
- * Whether to suppress the focus moving or not.
- * This is used to filter out focusing by mouse.
- * @type {boolean}
- * @private
- */
- this.suppressFocus_ = false;
-
- /**
- * SelectionHandler.
- * @type {SelectionHandler}
- * @private
- */
- this.selectionHandler_ = null;
-}
-
-/**
- * Maximum delay in milliseconds for updating thumbnails in the bottom panel
- * to mitigate flickering. If images load faster then the delay they replace
- * old images smoothly. On the other hand we don't want to keep old images
- * too long.
- *
- * @type {number}
- * @const
- */
-FileManager.THUMBNAIL_SHOW_DELAY = 100;
-
-FileManager.prototype = {
- __proto__: cr.EventTarget.prototype,
- get directoryModel() {
- return this.directoryModel_;
- },
- get navigationList() {
- return this.navigationList_;
- },
- get document() {
- return this.document_;
- },
- get fileTransferController() {
- return this.fileTransferController_;
- },
- get backgroundPage() {
- return this.backgroundPage_;
- },
- get volumeManager() {
- return this.volumeManager_;
- }
-};
-
-/**
- * Unload the file manager.
- * Used by background.js (when running in the packaged mode).
- */
-function unload() {
- fileManager.onBeforeUnload_();
- fileManager.onUnload_();
-}
-
-/**
- * List of dialog types.
- *
- * Keep this in sync with FileManagerDialog::GetDialogTypeAsString, except
- * FULL_PAGE which is specific to this code.
- *
- * @enum {string}
- */
-var DialogType = {
- SELECT_FOLDER: 'folder',
- SELECT_UPLOAD_FOLDER: 'upload-folder',
- SELECT_SAVEAS_FILE: 'saveas-file',
- SELECT_OPEN_FILE: 'open-file',
- SELECT_OPEN_MULTI_FILE: 'open-multi-file',
- FULL_PAGE: 'full-page'
-};
-
-/**
- * @param {string} type Dialog type.
- * @return {boolean} Whether the type is modal.
- */
-DialogType.isModal = function(type) {
- return type == DialogType.SELECT_FOLDER ||
- type == DialogType.SELECT_UPLOAD_FOLDER ||
- type == DialogType.SELECT_SAVEAS_FILE ||
- type == DialogType.SELECT_OPEN_FILE ||
- type == DialogType.SELECT_OPEN_MULTI_FILE;
-};
-
-/**
- * @param {string} type Dialog type.
- * @return {boolean} Whether the type is open dialog.
- */
-DialogType.isOpenDialog = function(type) {
- return type == DialogType.SELECT_OPEN_FILE ||
- type == DialogType.SELECT_OPEN_MULTI_FILE;
-};
-
-/**
- * @param {string} type Dialog type.
- * @return {boolean} Whether the type is folder selection dialog.
- */
-DialogType.isFolderDialog = function(type) {
- return type == DialogType.SELECT_FOLDER ||
- type == DialogType.SELECT_UPLOAD_FOLDER;
-};
-
-/**
- * Bottom margin of the list and tree for transparent preview panel.
- * @const
- */
-var BOTTOM_MARGIN_FOR_PREVIEW_PANEL_PX = 52;
-
-// Anonymous "namespace".
-(function() {
-
- // Private variables and helper functions.
-
- /**
- * Number of milliseconds in a day.
- */
- var MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000;
-
- /**
- * Some UI elements react on a single click and standard double click handling
- * leads to confusing results. We ignore a second click if it comes soon
- * after the first.
- */
- var DOUBLE_CLICK_TIMEOUT = 200;
-
- /**
- * Update the element to display the information about remaining space for
- * the storage.
- * @param {!Element} spaceInnerBar Block element for a percentage bar
- * representing the remaining space.
- * @param {!Element} spaceInfoLabel Inline element to contain the message.
- * @param {!Element} spaceOuterBar Block element around the percentage bar.
- */
- var updateSpaceInfo = function(
- sizeStatsResult, spaceInnerBar, spaceInfoLabel, spaceOuterBar) {
- spaceInnerBar.removeAttribute('pending');
- if (sizeStatsResult) {
- var sizeStr = util.bytesToString(sizeStatsResult.remainingSize);
- spaceInfoLabel.textContent = strf('SPACE_AVAILABLE', sizeStr);
-
- var usedSpace =
- sizeStatsResult.totalSize - sizeStatsResult.remainingSize;
- spaceInnerBar.style.width =
- (100 * usedSpace / sizeStatsResult.totalSize) + '%';
-
- spaceOuterBar.hidden = false;
- } else {
- spaceOuterBar.hidden = true;
- spaceInfoLabel.textContent = str('FAILED_SPACE_INFO');
- }
- };
-
- // Public statics.
-
- FileManager.ListType = {
- DETAIL: 'detail',
- THUMBNAIL: 'thumb'
- };
-
- FileManager.prototype.initPreferences_ = function(callback) {
- var group = new AsyncUtil.Group();
-
- // DRIVE preferences should be initialized before creating DirectoryModel
- // to rebuild the roots list.
- group.add(this.getPreferences_.bind(this));
-
- // Get startup preferences.
- this.viewOptions_ = {};
- group.add(function(done) {
- util.platform.getPreference(this.startupPrefName_, function(value) {
- // Load the global default options.
- try {
- this.viewOptions_ = JSON.parse(value);
- } catch (ignore) {}
- // Override with window-specific options.
- if (window.appState && window.appState.viewOptions) {
- for (var key in window.appState.viewOptions) {
- if (window.appState.viewOptions.hasOwnProperty(key))
- this.viewOptions_[key] = window.appState.viewOptions[key];
- }
- }
- done();
- }.bind(this));
- }.bind(this));
-
- // Get the command line option.
- group.add(function(done) {
- chrome.commandLinePrivate.hasSwitch(
- 'file-manager-show-checkboxes', function(flag) {
- this.showCheckboxes_ = flag;
- done();
- }.bind(this));
- }.bind(this));
-
- // TODO(yoshiki): Remove the flag when the feature is launched.
- this.enableExperimentalWebstoreIntegration_ = true;
-
- group.run(callback);
- };
-
- /**
- * One time initialization for the file system and related things.
- *
- * @param {function()} callback Completion callback.
- * @private
- */
- FileManager.prototype.initFileSystemUI_ = function(callback) {
- this.table_.startBatchUpdates();
- this.grid_.startBatchUpdates();
-
- this.initFileList_();
- this.setupCurrentDirectory_();
-
- // PyAuto tests monitor this state by polling this variable
- this.__defineGetter__('workerInitialized_', function() {
- return this.metadataCache_.isInitialized();
- }.bind(this));
-
- this.initDateTimeFormatters_();
-
- var self = this;
-
- // Get the 'allowRedeemOffers' preference before launching
- // FileListBannerController.
- this.getPreferences_(function(pref) {
- /** @type {boolean} */
- var showOffers = pref['allowRedeemOffers'];
- self.bannersController_ = new FileListBannerController(
- self.directoryModel_, self.volumeManager_, self.document_,
- showOffers);
- self.bannersController_.addEventListener('relayout',
- self.onResize_.bind(self));
- });
-
- var dm = this.directoryModel_;
- dm.addEventListener('directory-changed',
- this.onDirectoryChanged_.bind(this));
- dm.addEventListener('begin-update-files', function() {
- self.currentList_.startBatchUpdates();
- });
- dm.addEventListener('end-update-files', function() {
- self.restoreItemBeingRenamed_();
- self.currentList_.endBatchUpdates();
- });
- dm.addEventListener('scan-started', this.onScanStarted_.bind(this));
- dm.addEventListener('scan-completed', this.onScanCompleted_.bind(this));
- dm.addEventListener('scan-failed', this.onScanCancelled_.bind(this));
- dm.addEventListener('scan-cancelled', this.onScanCancelled_.bind(this));
- dm.addEventListener('scan-updated', this.onScanUpdated_.bind(this));
- dm.addEventListener('rescan-completed',
- this.onRescanCompleted_.bind(this));
-
- this.directoryTree_.addEventListener('change', function() {
- this.ensureDirectoryTreeItemNotBehindPreviewPanel_();
- }.bind(this));
-
- var stateChangeHandler =
- this.onPreferencesChanged_.bind(this);
- chrome.fileBrowserPrivate.onPreferencesChanged.addListener(
- stateChangeHandler);
- stateChangeHandler();
-
- var driveConnectionChangedHandler =
- this.onDriveConnectionChanged_.bind(this);
- this.volumeManager_.addEventListener('drive-connection-changed',
- driveConnectionChangedHandler);
- driveConnectionChangedHandler();
-
- // Set the initial focus.
- this.refocus();
- // Set it as a fallback when there is no focus.
- this.document_.addEventListener('focusout', function(e) {
- setTimeout(function() {
- // When there is no focus, the active element is the <body>.
- if (this.document_.activeElement == this.document_.body)
- this.refocus();
- }.bind(this), 0);
- }.bind(this));
-
- this.initDataTransferOperations_();
-
- this.initContextMenus_();
- this.initCommands_();
-
- this.updateFileTypeFilter_();
-
- this.selectionHandler_.onFileSelectionChanged();
-
- this.table_.endBatchUpdates();
- this.grid_.endBatchUpdates();
-
- callback();
- };
-
- /**
- * If |item| in the directory tree is behind the preview panel, scrolls up the
- * parent view and make the item visible. This should be called when:
- * - the selected item is changed in the directory tree.
- * - the visibility of the the preview panel is changed.
- *
- * @private
- */
- FileManager.prototype.ensureDirectoryTreeItemNotBehindPreviewPanel_ =
- function() {
- var selectedSubTree = this.directoryTree_.selectedItem;
- if (!selectedSubTree)
- return;
- var item = selectedSubTree.rowElement;
- var parentView = this.directoryTree_;
-
- var itemRect = item.getBoundingClientRect();
- if (!itemRect)
- return;
-
- var listRect = parentView.getBoundingClientRect();
- if (!listRect)
- return;
-
- var previewPanel = this.dialogDom_.querySelector('.preview-panel');
- var previewPanelRect = previewPanel.getBoundingClientRect();
- var panelHeight = previewPanelRect ? previewPanelRect.height : 0;
-
- var itemBottom = itemRect.bottom;
- var listBottom = listRect.bottom - panelHeight;
-
- if (itemBottom > listBottom) {
- var scrollOffset = itemBottom - listBottom;
- parentView.scrollTop += scrollOffset;
- }
- };
-
- /**
- * @private
- */
- FileManager.prototype.initDateTimeFormatters_ = function() {
- var use12hourClock = !this.preferences_['use24hourClock'];
- this.table_.setDateTimeFormat(use12hourClock);
- };
-
- /**
- * @private
- */
- FileManager.prototype.initDataTransferOperations_ = function() {
- this.fileOperationManager_ = FileOperationManagerWrapper.getInstance(
- this.backgroundPage_);
-
- // CopyManager are required for 'Delete' operation in
- // Open and Save dialogs. But drag-n-drop and copy-paste are not needed.
- if (this.dialogType != DialogType.FULL_PAGE) return;
-
- // TODO(hidehiko): Extract FileOperationManager related code from
- // FileManager to simplify it.
- this.onCopyProgressBound_ = this.onCopyProgress_.bind(this);
- this.fileOperationManager_.addEventListener(
- 'copy-progress', this.onCopyProgressBound_);
-
- this.onEntryChangedBound_ = this.onEntryChanged_.bind(this);
- this.fileOperationManager_.addEventListener(
- 'entry-changed', this.onEntryChangedBound_);
-
- var controller = this.fileTransferController_ =
- new FileTransferController(this.document_,
- this.fileOperationManager_,
- this.metadataCache_,
- this.directoryModel_);
- controller.attachDragSource(this.table_.list);
- controller.attachFileListDropTarget(this.table_.list);
- controller.attachDragSource(this.grid_);
- controller.attachFileListDropTarget(this.grid_);
- controller.attachTreeDropTarget(this.directoryTree_);
- controller.attachNavigationListDropTarget(this.navigationList_, true);
- controller.attachCopyPasteHandlers();
- controller.addEventListener('selection-copied',
- this.blinkSelection.bind(this));
- controller.addEventListener('selection-cut',
- this.blinkSelection.bind(this));
- };
-
- /**
- * One-time initialization of context menus.
- * @private
- */
- FileManager.prototype.initContextMenus_ = function() {
- this.fileContextMenu_ = this.dialogDom_.querySelector('#file-context-menu');
- cr.ui.Menu.decorate(this.fileContextMenu_);
-
- cr.ui.contextMenuHandler.setContextMenu(this.grid_, this.fileContextMenu_);
- cr.ui.contextMenuHandler.setContextMenu(this.table_.querySelector('.list'),
- this.fileContextMenu_);
- cr.ui.contextMenuHandler.setContextMenu(
- this.document_.querySelector('.drive-welcome.page'),
- this.fileContextMenu_);
-
- this.rootsContextMenu_ =
- this.dialogDom_.querySelector('#roots-context-menu');
- cr.ui.Menu.decorate(this.rootsContextMenu_);
- this.navigationList_.setContextMenu(this.rootsContextMenu_);
-
- this.directoryTreeContextMenu_ =
- this.dialogDom_.querySelector('#directory-tree-context-menu');
- cr.ui.Menu.decorate(this.directoryTreeContextMenu_);
- this.directoryTree_.contextMenuForSubitems = this.directoryTreeContextMenu_;
-
- this.textContextMenu_ =
- this.dialogDom_.querySelector('#text-context-menu');
- cr.ui.Menu.decorate(this.textContextMenu_);
-
- this.gearButton_ = this.dialogDom_.querySelector('#gear-button');
- this.gearButton_.addEventListener('menushow',
- this.refreshRemainingSpace_.bind(this,
- false /* Without loading caption. */));
- this.dialogDom_.querySelector('#gear-menu').menuItemSelector =
- 'menuitem, hr';
- cr.ui.decorate(this.gearButton_, cr.ui.MenuButton);
-
- if (this.dialogType == DialogType.FULL_PAGE) {
- // This is to prevent the buttons from stealing focus on mouse down.
- var preventFocus = function(event) {
- event.preventDefault();
- };
-
- var maximizeButton = this.dialogDom_.querySelector('#maximize-button');
- maximizeButton.addEventListener('click', this.onMaximize.bind(this));
- maximizeButton.addEventListener('mousedown', preventFocus);
-
- var closeButton = this.dialogDom_.querySelector('#close-button');
- closeButton.addEventListener('click', this.onClose.bind(this));
- closeButton.addEventListener('mousedown', preventFocus);
- }
-
- this.syncButton.checkable = true;
- this.hostedButton.checkable = true;
- this.detailViewButton_.checkable = true;
- this.thumbnailViewButton_.checkable = true;
-
- if (util.platform.runningInBrowser()) {
- // Suppresses the default context menu.
- this.dialogDom_.addEventListener('contextmenu', function(e) {
- e.preventDefault();
- e.stopPropagation();
- });
- }
- };
-
- FileManager.prototype.onMaximize = function() {
- var appWindow = chrome.app.window.current();
- if (appWindow.isMaximized())
- appWindow.restore();
- else
- appWindow.maximize();
- };
-
- FileManager.prototype.onClose = function() {
- window.close();
- };
-
- /**
- * One-time initialization of commands.
- * @private
- */
- FileManager.prototype.initCommands_ = function() {
- this.commandHandler = new CommandHandler(this);
-
- // TODO(hirono): Move the following block to the UI part.
- var commandButtons = this.dialogDom_.querySelectorAll('button[command]');
- for (var j = 0; j < commandButtons.length; j++)
- CommandButton.decorate(commandButtons[j]);
-
- var inputs = this.dialogDom_.querySelectorAll(
- 'input[type=text], input[type=search], textarea');
- for (var i = 0; i < inputs.length; i++) {
- cr.ui.contextMenuHandler.setContextMenu(inputs[i], this.textContextMenu_);
- this.registerInputCommands_(inputs[i]);
- }
-
- cr.ui.contextMenuHandler.setContextMenu(this.renameInput_,
- this.textContextMenu_);
- this.registerInputCommands_(this.renameInput_);
- this.document_.addEventListener('command',
- this.setNoHover_.bind(this, true));
- };
-
- /**
- * Registers cut, copy, paste and delete commands on input element.
- *
- * @param {Node} node Text input element to register on.
- * @private
- */
- FileManager.prototype.registerInputCommands_ = function(node) {
- CommandUtil.forceDefaultHandler(node, 'cut');
- CommandUtil.forceDefaultHandler(node, 'copy');
- CommandUtil.forceDefaultHandler(node, 'paste');
- CommandUtil.forceDefaultHandler(node, 'delete');
- node.addEventListener('keydown', function(e) {
- var key = util.getKeyModifiers(e) + e.keyCode;
- if (key === '190' /* '/' */ || key === '191' /* '.' */) {
- // If this key event is propagated, this is handled search command,
- // which calls 'preventDefault' method.
- e.stopPropagation();
- }
- });
- };
-
- /**
- * Entry point of the initialization.
- * This method is called from main.js.
- */
- FileManager.prototype.initializeCore = function() {
- this.initializeQueue_.add(this.initGeneral_.bind(this), [], 'initGeneral');
- this.initializeQueue_.add(this.initBackgroundPage_.bind(this),
- [], 'initBackgroundPage');
- this.initializeQueue_.add(this.initPreferences_.bind(this),
- ['initGeneral'], 'initPreferences');
- this.initializeQueue_.add(this.initVolumeManager_.bind(this),
- ['initGeneral', 'initBackgroundPage'],
- 'initVolumeManager');
-
- this.initializeQueue_.run();
- };
-
- FileManager.prototype.initializeUI = function(dialogDom, callback) {
- this.dialogDom_ = dialogDom;
- this.document_ = this.dialogDom_.ownerDocument;
-
- this.initializeQueue_.add(
- this.initEssentialUI_.bind(this),
- ['initGeneral', 'initBackgroundPage'],
- 'initEssentialUI');
- this.initializeQueue_.add(this.initAdditionalUI_.bind(this),
- ['initEssentialUI'], 'initAdditionalUI');
- this.initializeQueue_.add(
- this.initFileSystemUI_.bind(this),
- ['initAdditionalUI', 'initPreferences'], 'initFileSystemUI');
-
- // Run again just in case if all pending closures have completed and the
- // queue has stopped and monitor the completion.
- this.initializeQueue_.run(callback);
- };
-
- /**
- * Initializes general purpose basic things, which are used by other
- * initializing methods.
- *
- * @param {function()} callback Completion callback.
- * @private
- */
- FileManager.prototype.initGeneral_ = function(callback) {
- // Initialize the application state.
- if (window.appState) {
- this.params_ = window.appState.params || {};
- this.defaultPath = window.appState.defaultPath;
- } else {
- this.params_ = location.search ?
- JSON.parse(decodeURIComponent(location.search.substr(1))) :
- {};
- this.defaultPath = this.params_.defaultPath;
- }
-
- // Initialize the member variables that depend this.params_.
- this.dialogType = this.params_.type || DialogType.FULL_PAGE;
- this.startupPrefName_ = 'file-manager-' + this.dialogType;
- this.fileTypes_ = this.params_.typeList || [];
-
- callback();
- };
-
- /**
- * Initialize the background page.
- * @param {function()} callback Completion callback.
- * @private
- */
- FileManager.prototype.initBackgroundPage_ = function(callback) {
- chrome.runtime.getBackgroundPage(function(backgroundPage) {
- this.backgroundPage_ = backgroundPage;
- this.backgroundPage_.background.ready(function() {
- loadTimeData.data = this.backgroundPage_.background.stringData;
- callback();
- }.bind(this));
- }.bind(this));
- };
-
- /**
- * Initializes the VolumeManager instance.
- * @param {function()} callback Completion callback.
- * @private
- */
- FileManager.prototype.initVolumeManager_ = function(callback) {
- // Auto resolving to local path does not work for folders (e.g., dialog for
- // loading unpacked extensions).
- var noLocalPathResolution = DialogType.isFolderDialog(this.params_.type);
-
- // If this condition is false, VolumeManagerWrapper hides all drive
- // related event and data, even if Drive is enabled on preference.
- // In other words, even if Drive is disabled on preference but Files.app
- // should show Drive when it is re-enabled, then the value should be set to
- // true.
- // Note that the Drive enabling preference change is listened by
- // DriveIntegrationService, so here we don't need to take care about it.
- var driveEnabled =
- !noLocalPathResolution || !this.params_.shouldReturnLocalPath;
- this.volumeManager_ = new VolumeManagerWrapper(
- driveEnabled, this.backgroundPage_);
- callback();
- };
-
- /**
- * One time initialization of the Files.app's essential UI elements. These
- * elements will be shown to the user. Only visible elements should be
- * initialized here. Any heavy operation should be avoided. Files.app's
- * window is shown at the end of this routine.
- *
- * @param {function()} callback Completion callback.
- * @private
- */
- FileManager.prototype.initEssentialUI_ = function(callback) {
- // Optional list of file types.
- metrics.recordEnum('Create', this.dialogType,
- [DialogType.SELECT_FOLDER,
- DialogType.SELECT_UPLOAD_FOLDER,
- DialogType.SELECT_SAVEAS_FILE,
- DialogType.SELECT_OPEN_FILE,
- DialogType.SELECT_OPEN_MULTI_FILE,
- DialogType.FULL_PAGE]);
-
- // Create the metadata cache.
- this.metadataCache_ = MetadataCache.createFull();
-
- // Create the root view of FileManager.
- this.ui_ = new FileManagerUI(this.dialogDom_, this.dialogType);
- this.fileTypeSelector_ = this.ui_.fileTypeSelector;
- this.okButton_ = this.ui_.okButton;
- this.cancelButton_ = this.ui_.cancelButton;
-
- // Show the window as soon as the UI pre-initialization is done.
- if (this.dialogType == DialogType.FULL_PAGE &&
- !util.platform.runningInBrowser()) {
- chrome.app.window.current().show();
- setTimeout(callback, 100); // Wait until the animation is finished.
- } else {
- callback();
- }
- };
-
- /**
- * One-time initialization of dialogs.
- * @private
- */
- FileManager.prototype.initDialogs_ = function() {
- // Initialize the dialog.
- this.ui_.initDialogs();
- FileManagerDialogBase.setFileManager(this);
-
- // Obtains the dialog instances from FileManagerUI.
- // TODO(hirono): Remove the properties from the FileManager class.
- this.error = this.ui_.errorDialog;
- this.alert = this.ui_.alertDialog;
- this.confirm = this.ui_.confirmDialog;
- this.prompt = this.ui_.promptDialog;
- this.shareDialog_ = this.ui_.shareDialog;
- this.defaultTaskPicker = this.ui_.defaultTaskPicker;
- this.suggestAppsDialog = this.ui_.suggestAppsDialog;
- };
-
- /**
- * One-time initialization of various DOM nodes. Loads the additional DOM
- * elements visible to the user. Initialize here elements, which are expensive
- * or hidden in the beginning.
- *
- * @param {function()} callback Completion callback.
- * @private
- */
- FileManager.prototype.initAdditionalUI_ = function(callback) {
- this.initDialogs_();
- this.ui_.initAdditionalUI();
-
- this.dialogDom_.addEventListener('drop', function(e) {
- // Prevent opening an URL by dropping it onto the page.
- e.preventDefault();
- });
-
- this.dialogDom_.addEventListener('click',
- this.onExternalLinkClick_.bind(this));
- // Cache nodes we'll be manipulating.
- var dom = this.dialogDom_;
-
- this.filenameInput_ = dom.querySelector('#filename-input-box input');
- this.taskItems_ = dom.querySelector('#tasks');
-
- this.table_ = dom.querySelector('.detail-table');
- this.grid_ = dom.querySelector('.thumbnail-grid');
- this.spinner_ = dom.querySelector('#list-container > .spinner-layer');
- this.showSpinner_(true);
-
- // Check the option to hide the selecting checkboxes.
- this.table_.showCheckboxes = this.showCheckboxes_;
-
- var fullPage = this.dialogType == DialogType.FULL_PAGE;
- FileTable.decorate(this.table_, this.metadataCache_, fullPage);
- FileGrid.decorate(this.grid_, this.metadataCache_);
-
- this.previewPanel_ = new PreviewPanel(
- dom.querySelector('.preview-panel'),
- DialogType.isOpenDialog(this.dialogType) ?
- PreviewPanel.VisibilityType.ALWAYS_VISIBLE :
- PreviewPanel.VisibilityType.AUTO,
- this.metadataCache_,
- this.volumeManager_);
- this.previewPanel_.addEventListener(
- PreviewPanel.Event.VISIBILITY_CHANGE,
- this.onPreviewPanelVisibilityChange_.bind(this));
- this.previewPanel_.initialize();
-
- this.previewPanel_.breadcrumbs.addEventListener(
- 'pathclick', this.onBreadcrumbClick_.bind(this));
-
- // Initialize progress center panel.
- this.progressCenterPanel_ = new ProgressCenterPanel(
- dom.querySelector('#progress-center'));
- this.backgroundPage_.background.progressCenter.addPanel(
- this.progressCenterPanel_);
-
- this.document_.addEventListener('keydown', this.onKeyDown_.bind(this));
-
- // This capturing event is only used to distinguish focusing using
- // keyboard from focusing using mouse.
- this.document_.addEventListener('mousedown', function() {
- this.suppressFocus_ = true;
- }.bind(this), true);
-
- this.renameInput_ = this.document_.createElement('input');
- this.renameInput_.className = 'rename';
-
- this.renameInput_.addEventListener(
- 'keydown', this.onRenameInputKeyDown_.bind(this));
- this.renameInput_.addEventListener(
- 'blur', this.onRenameInputBlur_.bind(this));
-
- // TODO(hirono): Rename the handler after creating the DialogFooter class.
- this.filenameInput_.addEventListener(
- 'input', this.onFilenameInputInput_.bind(this));
- this.filenameInput_.addEventListener(
- 'keydown', this.onFilenameInputKeyDown_.bind(this));
- this.filenameInput_.addEventListener(
- 'focus', this.onFilenameInputFocus_.bind(this));
-
- this.listContainer_ = this.dialogDom_.querySelector('#list-container');
- this.listContainer_.addEventListener(
- 'keydown', this.onListKeyDown_.bind(this));
- this.listContainer_.addEventListener(
- 'keypress', this.onListKeyPress_.bind(this));
- this.listContainer_.addEventListener(
- 'mousemove', this.onListMouseMove_.bind(this));
-
- this.okButton_.addEventListener('click', this.onOk_.bind(this));
- this.onCancelBound_ = this.onCancel_.bind(this);
- this.cancelButton_.addEventListener('click', this.onCancelBound_);
-
- this.decorateSplitter(
- this.dialogDom_.querySelector('#navigation-list-splitter'));
- this.decorateSplitter(
- this.dialogDom_.querySelector('#middlebar-splitter'));
-
- this.dialogContainer_ = this.dialogDom_.querySelector('.dialog-container');
-
- this.syncButton = this.dialogDom_.querySelector('#drive-sync-settings');
- this.syncButton.addEventListener('click', this.onDrivePrefClick_.bind(
- this, 'cellularDisabled', false /* not inverted */));
-
- this.hostedButton = this.dialogDom_.querySelector('#drive-hosted-settings');
- this.hostedButton.addEventListener('click', this.onDrivePrefClick_.bind(
- this, 'hostedFilesDisabled', true /* inverted */));
-
- this.detailViewButton_ =
- this.dialogDom_.querySelector('#detail-view');
- this.detailViewButton_.addEventListener('activate',
- this.onDetailViewButtonClick_.bind(this));
-
- this.thumbnailViewButton_ =
- this.dialogDom_.querySelector('#thumbnail-view');
- this.thumbnailViewButton_.addEventListener('activate',
- this.onThumbnailViewButtonClick_.bind(this));
-
- cr.ui.ComboButton.decorate(this.taskItems_);
- this.taskItems_.showMenu = function(shouldSetFocus) {
- // Prevent the empty menu from opening.
- if (!this.menu.length)
- return;
- cr.ui.ComboButton.prototype.showMenu.call(this, shouldSetFocus);
- };
- this.taskItems_.addEventListener('select',
- this.onTaskItemClicked_.bind(this));
-
- this.dialogDom_.ownerDocument.defaultView.addEventListener(
- 'resize', this.onResize_.bind(this));
-
- this.filePopup_ = null;
-
- this.searchBoxWrapper_ = this.ui_.searchBox.element;
- this.searchBox_ = this.ui_.searchBox.inputElement;
- this.searchBox_.addEventListener(
- 'input', this.onSearchBoxUpdate_.bind(this));
- this.ui_.searchBox.clearButton.addEventListener(
- 'click', this.onSearchClearButtonClick_.bind(this));
-
- this.lastSearchQuery_ = '';
-
- this.autocompleteList_ = this.ui_.searchBox.autocompleteList;
- this.autocompleteList_.requestSuggestions =
- this.requestAutocompleteSuggestions_.bind(this);
-
- // Instead, open the suggested item when Enter key is pressed or
- // mouse-clicked.
- this.autocompleteList_.handleEnterKeydown = function(event) {
- this.openAutocompleteSuggestion_();
- this.lastAutocompleteQuery_ = '';
- this.autocompleteList_.suggestions = [];
- }.bind(this);
- this.autocompleteList_.addEventListener('mousedown', function(event) {
- this.openAutocompleteSuggestion_();
- this.lastAutocompleteQuery_ = '';
- this.autocompleteList_.suggestions = [];
- }.bind(this));
-
- this.defaultActionMenuItem_ =
- this.dialogDom_.querySelector('#default-action');
-
- this.openWithCommand_ =
- this.dialogDom_.querySelector('#open-with');
-
- this.driveBuyMoreStorageCommand_ =
- this.dialogDom_.querySelector('#drive-buy-more-space');
-
- this.defaultActionMenuItem_.addEventListener('click',
- this.dispatchSelectionAction_.bind(this));
-
- this.initFileTypeFilter_();
-
- util.addIsFocusedMethod();
-
- // Populate the static localized strings.
- i18nTemplate.process(this.document_, loadTimeData);
-
- // Arrange the file list.
- this.table_.normalizeColumns();
- this.table_.redraw();
-
- callback();
- };
-
- /**
- * @private
- */
- FileManager.prototype.onBreadcrumbClick_ = function(event) {
- // TODO(hirono): Use directoryModel#changeDirectoryEntry after implementing
- // it.
- if (event.entry === RootType.DRIVE_SHARED_WITH_ME)
- this.directoryModel_.changeDirectory(RootDirectory.DRIVE_SHARED_WITH_ME);
- else
- this.directoryModel_.changeDirectory(event.entry.fullPath);
- };
-
- /**
- * Constructs table and grid (heavy operation).
- * @private
- **/
- FileManager.prototype.initFileList_ = function() {
- // Always sharing the data model between the detail/thumb views confuses
- // them. Instead we maintain this bogus data model, and hook it up to the
- // view that is not in use.
- this.emptyDataModel_ = new cr.ui.ArrayDataModel([]);
- this.emptySelectionModel_ = new cr.ui.ListSelectionModel();
-
- var singleSelection =
- this.dialogType == DialogType.SELECT_OPEN_FILE ||
- this.dialogType == DialogType.SELECT_FOLDER ||
- this.dialogType == DialogType.SELECT_UPLOAD_FOLDER ||
- this.dialogType == DialogType.SELECT_SAVEAS_FILE;
-
- this.fileFilter_ = new FileFilter(
- this.metadataCache_,
- false /* Don't show dot files by default. */);
-
- this.fileWatcher_ = new FileWatcher(this.metadataCache_);
- this.fileWatcher_.addEventListener(
- 'watcher-metadata-changed',
- this.onWatcherMetadataChanged_.bind(this));
-
- this.directoryModel_ = new DirectoryModel(
- singleSelection,
- this.fileFilter_,
- this.fileWatcher_,
- this.metadataCache_,
- this.volumeManager_);
-
- this.folderShortcutsModel_ = new FolderShortcutsDataModel();
-
- this.selectionHandler_ = new FileSelectionHandler(this);
-
- var dataModel = this.directoryModel_.getFileList();
-
- this.table_.setupCompareFunctions(dataModel);
-
- dataModel.addEventListener('permuted',
- this.updateStartupPrefs_.bind(this));
-
- this.directoryModel_.getFileListSelection().addEventListener('change',
- this.selectionHandler_.onFileSelectionChanged.bind(
- this.selectionHandler_));
-
- this.initList_(this.grid_);
- this.initList_(this.table_.list);
-
- var fileListFocusBound = this.onFileListFocus_.bind(this);
- var fileListBlurBound = this.onFileListBlur_.bind(this);
-
- this.table_.list.addEventListener('focus', fileListFocusBound);
- this.grid_.addEventListener('focus', fileListFocusBound);
-
- this.table_.list.addEventListener('blur', fileListBlurBound);
- this.grid_.addEventListener('blur', fileListBlurBound);
-
- var dragStartBound = this.onDragStart_.bind(this);
- this.table_.list.addEventListener('dragstart', dragStartBound);
- this.grid_.addEventListener('dragstart', dragStartBound);
-
- var dragEndBound = this.onDragEnd_.bind(this);
- this.table_.list.addEventListener('dragend', dragEndBound);
- this.grid_.addEventListener('dragend', dragEndBound);
- // This event is published by DragSelector because drag end event is not
- // published at the end of drag selection.
- this.table_.list.addEventListener('dragselectionend', dragEndBound);
- this.grid_.addEventListener('dragselectionend', dragEndBound);
-
- // TODO(mtomasz, yoshiki): Create navigation list earlier, and here just
- // attach the directory model.
- this.initNavigationList_();
-
- this.table_.addEventListener('column-resize-end',
- this.updateStartupPrefs_.bind(this));
-
- // Restore preferences.
- this.directoryModel_.sortFileList(
- this.viewOptions_.sortField || 'modificationTime',
- this.viewOptions_.sortDirection || 'desc');
- if (this.viewOptions_.columns) {
- var cm = this.table_.columnModel;
- for (var i = 0; i < cm.totalSize; i++) {
- if (this.viewOptions_.columns[i] > 0)
- cm.setWidth(i, this.viewOptions_.columns[i]);
- }
- }
- this.setListType(this.viewOptions_.listType || FileManager.ListType.DETAIL);
-
- this.textSearchState_ = {text: '', date: new Date()};
- this.closeOnUnmount_ = (this.params_.action == 'auto-open');
-
- if (this.closeOnUnmount_) {
- this.volumeManager_.addEventListener('externally-unmounted',
- this.onExternallyUnmounted_.bind(this));
- }
-
- // Update metadata to change 'Today' and 'Yesterday' dates.
- var today = new Date();
- today.setHours(0);
- today.setMinutes(0);
- today.setSeconds(0);
- today.setMilliseconds(0);
- setTimeout(this.dailyUpdateModificationTime_.bind(this),
- today.getTime() + MILLISECONDS_IN_DAY - Date.now() + 1000);
- };
-
- /**
- * @private
- */
- FileManager.prototype.initNavigationList_ = function() {
- this.directoryTree_ = this.dialogDom_.querySelector('#directory-tree');
- DirectoryTree.decorate(this.directoryTree_, this.directoryModel_);
-
- this.navigationList_ = this.dialogDom_.querySelector('#navigation-list');
- NavigationList.decorate(this.navigationList_,
- this.volumeManager_,
- this.directoryModel_);
- this.navigationList_.fileManager = this;
- this.navigationList_.dataModel = new NavigationListModel(
- this.volumeManager_, this.folderShortcutsModel_);
- };
-
- /**
- * @private
- */
- FileManager.prototype.updateMiddleBarVisibility_ = function() {
- var entry = this.directoryModel_.getCurrentDirEntry();
- if (!entry)
- return;
-
- var driveVolume = this.volumeManager_.getVolumeInfo(entry);
- var visible =
- DirectoryTreeUtil.isEligiblePathForDirectoryTree(entry.fullPath) &&
- driveVolume && !driveVolume.error;
- this.dialogDom_.
- querySelector('.dialog-middlebar-contents').hidden = !visible;
- this.dialogDom_.querySelector('#middlebar-splitter').hidden = !visible;
- this.onResize_();
- };
-
- /**
- * @private
- */
- FileManager.prototype.updateStartupPrefs_ = function() {
- var sortStatus = this.directoryModel_.getFileList().sortStatus;
- var prefs = {
- sortField: sortStatus.field,
- sortDirection: sortStatus.direction,
- columns: [],
- listType: this.listType_
- };
- var cm = this.table_.columnModel;
- for (var i = 0; i < cm.totalSize; i++) {
- prefs.columns.push(cm.getWidth(i));
- }
- // Save the global default.
- util.platform.setPreference(this.startupPrefName_, JSON.stringify(prefs));
-
- // Save the window-specific preference.
- if (window.appState) {
- window.appState.viewOptions = prefs;
- util.saveAppState();
- }
- };
-
- FileManager.prototype.refocus = function() {
- var targetElement;
- if (this.dialogType == DialogType.SELECT_SAVEAS_FILE)
- targetElement = this.filenameInput_;
- else
- targetElement = this.currentList_;
-
- // Hack: if the tabIndex is disabled, we can assume a modal dialog is
- // shown. Focus to a button on the dialog instead.
- if (!targetElement.hasAttribute('tabIndex') || targetElement.tabIndex == -1)
- targetElement = document.querySelector('button:not([tabIndex="-1"])');
-
- if (targetElement)
- targetElement.focus();
- };
-
- /**
- * File list focus handler. Used to select the top most element on the list
- * if nothing was selected.
- *
- * @private
- */
- FileManager.prototype.onFileListFocus_ = function() {
- // Do not select default item if focused using mouse.
- if (this.suppressFocus_)
- return;
-
- var selection = this.getSelection();
- if (!selection || selection.totalCount != 0)
- return;
-
- this.directoryModel_.selectIndex(0);
- };
-
- /**
- * File list blur handler.
- *
- * @private
- */
- FileManager.prototype.onFileListBlur_ = function() {
- this.suppressFocus_ = false;
- };
-
- /**
- * Index of selected item in the typeList of the dialog params.
- *
- * @return {number} 1-based index of selected type or 0 if no type selected.
- * @private
- */
- FileManager.prototype.getSelectedFilterIndex_ = function() {
- var index = Number(this.fileTypeSelector_.selectedIndex);
- if (index < 0) // Nothing selected.
- return 0;
- if (this.params_.includeAllFiles) // Already 1-based.
- return index;
- return index + 1; // Convert to 1-based;
- };
-
- FileManager.prototype.setListType = function(type) {
- if (type && type == this.listType_)
- return;
-
- this.table_.list.startBatchUpdates();
- this.grid_.startBatchUpdates();
-
- // TODO(dzvorygin): style.display and dataModel setting order shouldn't
- // cause any UI bugs. Currently, the only right way is first to set display
- // style and only then set dataModel.
-
- if (type == FileManager.ListType.DETAIL) {
- this.table_.dataModel = this.directoryModel_.getFileList();
- this.table_.selectionModel = this.directoryModel_.getFileListSelection();
- this.table_.hidden = false;
- this.grid_.hidden = true;
- this.grid_.selectionModel = this.emptySelectionModel_;
- this.grid_.dataModel = this.emptyDataModel_;
- this.table_.hidden = false;
- /** @type {cr.ui.List} */
- this.currentList_ = this.table_.list;
- this.detailViewButton_.setAttribute('checked', '');
- this.thumbnailViewButton_.removeAttribute('checked');
- this.detailViewButton_.setAttribute('disabled', '');
- this.thumbnailViewButton_.removeAttribute('disabled');
- } else if (type == FileManager.ListType.THUMBNAIL) {
- this.grid_.dataModel = this.directoryModel_.getFileList();
- this.grid_.selectionModel = this.directoryModel_.getFileListSelection();
- this.grid_.hidden = false;
- this.table_.hidden = true;
- this.table_.selectionModel = this.emptySelectionModel_;
- this.table_.dataModel = this.emptyDataModel_;
- this.grid_.hidden = false;
- /** @type {cr.ui.List} */
- this.currentList_ = this.grid_;
- this.thumbnailViewButton_.setAttribute('checked', '');
- this.detailViewButton_.removeAttribute('checked');
- this.thumbnailViewButton_.setAttribute('disabled', '');
- this.detailViewButton_.removeAttribute('disabled');
- } else {
- throw new Error('Unknown list type: ' + type);
- }
-
- this.listType_ = type;
- this.updateStartupPrefs_();
- this.onResize_();
-
- this.table_.list.endBatchUpdates();
- this.grid_.endBatchUpdates();
- };
-
- /**
- * Initialize the file list table or grid.
- *
- * @param {cr.ui.List} list The list.
- * @private
- */
- FileManager.prototype.initList_ = function(list) {
- // Overriding the default role 'list' to 'listbox' for better accessibility
- // on ChromeOS.
- list.setAttribute('role', 'listbox');
- list.addEventListener('click', this.onDetailClick_.bind(this));
- list.id = 'file-list';
- };
-
- /**
- * @private
- */
- FileManager.prototype.onCopyProgress_ = function(event) {
- if (event.reason == 'ERROR' &&
- event.error.code == util.FileOperationErrorType.FILESYSTEM_ERROR &&
- event.error.data.toDrive &&
- event.error.data.code == FileError.QUOTA_EXCEEDED_ERR) {
- this.alert.showHtml(
- strf('DRIVE_SERVER_OUT_OF_SPACE_HEADER'),
- strf('DRIVE_SERVER_OUT_OF_SPACE_MESSAGE',
- decodeURIComponent(
- event.error.data.sourceFileUrl.split('/').pop()),
- str('GOOGLE_DRIVE_BUY_STORAGE_URL')));
- }
- };
-
- /**
- * Handler of file manager operations. Called when an entry has been
- * changed.
- * This updates directory model to reflect operation result immediately (not
- * waiting for directory update event). Also, preloads thumbnails for the
- * images of new entries.
- * See also FileOperationManager.EventRouter.
- *
- * @param {Event} event An event for the entry change.
- * @private
- */
- FileManager.prototype.onEntryChanged_ = function(event) {
- var kind = event.kind;
- var entry = event.entry;
- this.directoryModel_.onEntryChanged(kind, entry);
- this.selectionHandler_.onFileSelectionChanged();
-
- if (kind == util.EntryChangedKind.CREATE && FileType.isImage(entry)) {
- // Preload a thumbnail if the new copied entry an image.
- var metadata = entry.getMetadata(function(metadata) {
- var url = entry.toURL();
- var thumbnailLoader_ = new ThumbnailLoader(
- url,
- ThumbnailLoader.LoaderType.CANVAS,
- metadata,
- undefined, // Media type.
- FileType.isOnDrive(url) ?
- ThumbnailLoader.UseEmbedded.USE_EMBEDDED :
- ThumbnailLoader.UseEmbedded.NO_EMBEDDED,
- 10); // Very low priority.
- thumbnailLoader_.loadDetachedImage(function(success) {});
- });
- }
- };
-
- /**
- * Fills the file type list or hides it.
- * @private
- */
- FileManager.prototype.initFileTypeFilter_ = function() {
- if (this.params_.includeAllFiles) {
- var option = this.document_.createElement('option');
- option.innerText = str('ALL_FILES_FILTER');
- this.fileTypeSelector_.appendChild(option);
- option.value = 0;
- }
-
- for (var i = 0; i < this.fileTypes_.length; i++) {
- var fileType = this.fileTypes_[i];
- var option = this.document_.createElement('option');
- var description = fileType.description;
- if (!description) {
- // See if all the extensions in the group have the same description.
- for (var j = 0; j != fileType.extensions.length; j++) {
- var currentDescription =
- FileType.getTypeString('.' + fileType.extensions[j]);
- if (!description) // Set the first time.
- description = currentDescription;
- else if (description != currentDescription) {
- // No single description, fall through to the extension list.
- description = null;
- break;
- }
- }
-
- if (!description)
- // Convert ['jpg', 'png'] to '*.jpg, *.png'.
- description = fileType.extensions.map(function(s) {
- return '*.' + s;
- }).join(', ');
- }
- option.innerText = description;
-
- option.value = i + 1;
-
- if (fileType.selected)
- option.selected = true;
-
- this.fileTypeSelector_.appendChild(option);
- }
-
- var options = this.fileTypeSelector_.querySelectorAll('option');
- if (options.length >= 2) {
- // There is in fact no choice, show the selector.
- this.fileTypeSelector_.hidden = false;
-
- this.fileTypeSelector_.addEventListener('change',
- this.updateFileTypeFilter_.bind(this));
- }
- };
-
- /**
- * Filters file according to the selected file type.
- * @private
- */
- FileManager.prototype.updateFileTypeFilter_ = function() {
- this.fileFilter_.removeFilter('fileType');
- var selectedIndex = this.getSelectedFilterIndex_();
- if (selectedIndex > 0) { // Specific filter selected.
- var regexp = new RegExp('.*(' +
- this.fileTypes_[selectedIndex - 1].extensions.join('|') + ')$', 'i');
- var filter = function(entry) {
- return entry.isDirectory || regexp.test(entry.name);
- };
- this.fileFilter_.addFilter('fileType', filter);
- }
- };
-
- /**
- * Resize details and thumb views to fit the new window size.
- * @private
- */
- FileManager.prototype.onResize_ = function() {
- if (this.listType_ == FileManager.ListType.THUMBNAIL)
- this.grid_.relayout();
- else
- this.table_.relayout();
-
- // May not be available during initialization.
- if (this.directoryTree_)
- this.directoryTree_.relayout();
-
- // TODO(mtomasz, yoshiki): Initialize navigation list earlier, before
- // file system is available.
- if (this.navigationList_)
- this.navigationList_.redraw();
-
- this.ui_.searchBox.updateSizeRelatedStyle();
-
- this.previewPanel_.breadcrumbs.truncate();
- };
-
- /**
- * Handles local metadata changes in the currect directory.
- * @param {Event} event Change event.
- * @private
- */
- FileManager.prototype.onWatcherMetadataChanged_ = function(event) {
- this.updateMetadataInUI_(
- event.metadataType, event.entries, event.properties);
- };
-
- /**
- * Resize details and thumb views to fit the new window size.
- * @private
- */
- FileManager.prototype.onPreviewPanelVisibilityChange_ = function() {
- // This method may be called on initialization. Some object may not be
- // initialized.
-
- var panelHeight = this.previewPanel_.visible ?
- this.previewPanel_.height : 0;
- if (this.grid_)
- this.grid_.setBottomMarginForPanel(panelHeight);
- if (this.table_)
- this.table_.setBottomMarginForPanel(panelHeight);
-
- if (this.directoryTree_) {
- this.directoryTree_.setBottomMarginForPanel(panelHeight);
- this.ensureDirectoryTreeItemNotBehindPreviewPanel_();
- }
- };
-
- /**
- * Invoked when the drag is started on the list or the grid.
- * @private
- */
- FileManager.prototype.onDragStart_ = function() {
- // On open file dialog, the preview panel is always shown.
- if (DialogType.isOpenDialog(this.dialogType))
- return;
- this.previewPanel_.visibilityType =
- PreviewPanel.VisibilityType.ALWAYS_HIDDEN;
- };
-
- /**
- * Invoked when the drag is ended on the list or the grid.
- * @private
- */
- FileManager.prototype.onDragEnd_ = function() {
- // On open file dialog, the preview panel is always shown.
- if (DialogType.isOpenDialog(this.dialogType))
- return;
- this.previewPanel_.visibilityType = PreviewPanel.VisibilityType.AUTO;
- };
-
- /**
- * Restores current directory and may be a selected item after page load (or
- * reload) or popping a state (after click on back/forward). defaultPath
- * primarily is used with save/open dialogs.
- * Default path may also contain a file name. Freshly opened file manager
- * window has neither.
- *
- * @private
- */
- FileManager.prototype.setupCurrentDirectory_ = function() {
- var tracker = this.directoryModel_.createDirectoryChangeTracker();
- var queue = new AsyncUtil.Queue();
-
- // Wait until the volume manager is initialized.
- queue.run(function(callback) {
- tracker.start();
- this.volumeManager_.ensureInitialized(callback);
- }.bind(this));
-
- // Resolve the default path.
- var defaultFullPath;
- var candidateFullPath;
- var candidateEntry;
- queue.run(function(callback) {
- // Cancel this sequence if the current directory has already changed.
- if (tracker.hasChanged) {
- callback();
- return;
- }
-
- // Resolve the absolute path in case only the file name or an empty string
- // is passed.
- if (!this.defaultPath) {
- defaultFullPath = PathUtil.DEFAULT_MOUNT_POINT;
- } else if (this.defaultPath.indexOf('/') === -1) {
- // Path is a file name.
- defaultFullPath = PathUtil.DEFAULT_MOUNT_POINT + '/' + this.defaultPath;
- } else {
- defaultFullPath = this.defaultPath;
- }
-
- // If Drive is disabled but the path points to Drive's entry, fallback to
- // DEFAULT_MOUNT_POINT.
- if (PathUtil.isDriveBasedPath(defaultFullPath) &&
- !this.volumeManager_.getVolumeInfo(RootDirectory.DRIVE)) {
- candidateFullPath = PathUtil.DEFAULT_MOUNT_POINT + '/' +
- PathUtil.basename(defaultFullPath);
- } else {
- candidateFullPath = defaultFullPath;
- }
-
- // If the path points a fake entry, use the entry directly.
- var fakeEntries = DirectoryModel.FAKE_DRIVE_SPECIAL_SEARCH_ENTRIES;
- for (var i = 0; i < fakeEntries.length; i++) {
- if (candidateFullPath === fakeEntries[i].fullPath) {
- candidateEntry = fakeEntries[i];
- callback();
- return;
- }
- }
-
- // Convert the path to the directory entry and an optional selection
- // entry.
- // TODO(hirono): There may be a race here. The path on Drive, may not
- // be available yet.
- this.volumeManager_.resolveAbsolutePath(candidateFullPath,
- function(inEntry) {
- candidateEntry = inEntry;
- callback();
- }, function() {
- callback();
- });
- }.bind(this));
-
- // Check the obtained entry.
- var nextCurrentDirEntry;
- var selectionEntry = null;
- var suggestedName = null;
- var error = null;
- queue.run(function(callback) {
- // Cancel this sequence if the current directory has already changed.
- if (tracker.hasChanged) {
- callback();
- return;
- }
-
- if (candidateEntry) {
- // The entry is directory. Use it.
- if (candidateEntry.isDirectory) {
- nextCurrentDirEntry = candidateEntry;
- callback();
- return;
- }
- // The entry exists, but it is not a directory. Therefore use a
- // parent.
- candidateEntry.getParent(function(parentEntry) {
- nextCurrentDirEntry = parentEntry;
- selectionEntry = candidateEntry;
- callback();
- }, function() {
- error = new Error('Unable to resolve parent for: ' +
- candidateEntry.fullPath);
- callback();
- });
- return;
- }
-
- // If the entry doesn't exist, most probably because the path contains a
- // suggested name. Therefore try to open its parent. However, the parent
- // may also not exist. In such situation, fallback.
- var pathNodes = candidateFullPath.split('/');
- var baseName = pathNodes.pop();
- var parentPath = pathNodes.join('/');
- this.volumeManager_.resolveAbsolutePath(
- parentPath,
- function(parentEntry) {
- nextCurrentDirEntry = parentEntry;
- suggestedName = baseName;
- callback();
- },
- callback); // In case of an error, continue.
- }.bind(this));
-
- // If the directory is not set at this stage, fallback to the default
- // mount point.
- queue.run(function(callback) {
- // Cancel this sequence if the current directory has already changed,
- // or the next current directory is already set.
- if (tracker.hasChanged || nextCurrentDirEntry) {
- callback();
- return;
- }
- this.volumeManager_.resolveAbsolutePath(
- PathUtil.DEFAULT_MOUNT_POINT,
- function(fallbackEntry) {
- nextCurrentDirEntry = fallbackEntry;
- callback();
- },
- function() {
- // Fallback directory not available? Throw an error.
- error = new Error('Unable to resolve the fallback directory: ' +
- PathUtil.DEFAULT_MOUNT_POINT);
- callback();
- });
- }.bind(this));
-
- queue.run(function(callback) {
- // Check error.
- if (error) {
- callback();
- throw error;
- }
- // Check directory change.
- tracker.stop();
- if (tracker.hasChanged) {
- callback();
- return;
- }
- // Finish setup current directory.
- this.finishSetupCurrentDirectory_(
- nextCurrentDirEntry, selectionEntry, suggestedName);
- callback();
- }.bind(this));
- };
-
- /**
- * @param {DirectoryEntry} directoryEntry Directory to be opened.
- * @param {Entry=} opt_selectionEntry Entry to be selected.
- * @param {string=} opt_suggestedName Suggested name for a non-existing\
- * selection.
- * @private
- */
- FileManager.prototype.finishSetupCurrentDirectory_ = function(
- directoryEntry, opt_selectionEntry, opt_suggestedName) {
- // Open the directory, and select the selection (if passed).
- if (util.isFakeEntry(directoryEntry)) {
- this.directoryModel_.specialSearch(directoryEntry.fullPath, '');
- } else {
- this.directoryModel_.changeDirectoryEntry(directoryEntry, function() {
- if (opt_selectionEntry)
- this.directoryModel_.selectEntry(opt_selectionEntry);
- }.bind(this));
- }
-
- if (this.dialogType == DialogType.FULL_PAGE) {
- // In the FULL_PAGE mode if the restored path points to a file we might
- // have to invoke a task after selecting it.
- if (this.params_.action == 'select')
- return;
-
- var task = null;
- if (opt_suggestedName) {
- // Non-existent file or a directory.
- if (this.params_.gallery) {
- // Reloading while the Gallery is open with empty or multiple
- // selection. Open the Gallery when the directory is scanned.
- task = function() {
- new FileTasks(this, this.params_).openGallery([]);
- }.bind(this);
- }
- } else if (opt_selectionEntry) {
- // There is a file to be selected. It means, that we are recovering
- // the Files app.
- // We call the appropriate methods of FileTasks directly as we do
- // not need any of the preparations that |execute| method does.
- // TODO(mtomasz): Change Entry.fullPath to Entry.
- var mediaType = FileType.getMediaType(opt_selectionEntry.fullPath);
- if (mediaType == 'image' || mediaType == 'video') {
- task = function() {
- // TODO(mtomasz): Replace the url with an entry.
- new FileTasks(this, this.params_).openGallery([opt_selectionEntry]);
- }.bind(this);
- } else if (mediaType == 'archive') {
- task = function() {
- new FileTasks(this, this.params_).mountArchives(
- [opt_selectionEntry]);
- }.bind(this);
- }
- }
-
- // If there is a task to be run, run it after the scan is completed.
- if (task) {
- var listener = function() {
- this.directoryModel_.removeEventListener(
- 'scan-completed', listener);
- task();
- }.bind(this);
- this.directoryModel_.addEventListener('scan-completed', listener);
- }
- } else if (this.dialogType == DialogType.SELECT_SAVEAS_FILE) {
- this.filenameInput_.value = opt_suggestedName || '';
- this.selectDefaultPathInFilenameInput_();
- }
- };
-
- /**
- * Unmounts device.
- * @param {string} path Path to a volume to unmount.
- */
- FileManager.prototype.unmountVolume = function(path) {
- var onError = function(error) {
- this.alert.showHtml('', str('UNMOUNT_FAILED'));
- };
- this.volumeManager_.unmount(path, function() {}, onError.bind(this));
- };
-
- /**
- * @private
- */
- FileManager.prototype.refreshCurrentDirectoryMetadata_ = function() {
- var entries = this.directoryModel_.getFileList().slice();
- var directoryEntry = this.directoryModel_.getCurrentDirEntry();
- if (!directoryEntry)
- return;
- // We don't pass callback here. When new metadata arrives, we have an
- // observer registered to update the UI.
-
- // TODO(dgozman): refresh content metadata only when modificationTime
- // changed.
- var isFakeEntry = util.isFakeEntry(directoryEntry);
- var getEntries = (isFakeEntry ? [] : [directoryEntry]).concat(entries);
- if (!isFakeEntry)
- this.metadataCache_.clearRecursively(directoryEntry, '*');
- this.metadataCache_.get(getEntries, 'filesystem', null);
-
- if (this.isOnDrive())
- this.metadataCache_.get(getEntries, 'drive', null);
-
- var visibleItems = this.currentList_.items;
- var visibleEntries = [];
- for (var i = 0; i < visibleItems.length; i++) {
- var index = this.currentList_.getIndexOfListItem(visibleItems[i]);
- var entry = this.directoryModel_.getFileList().item(index);
- // The following check is a workaround for the bug in list: sometimes item
- // does not have listIndex, and therefore is not found in the list.
- if (entry) visibleEntries.push(entry);
- }
- this.metadataCache_.get(visibleEntries, 'thumbnail', null);
- };
-
- /**
- * @private
- */
- FileManager.prototype.dailyUpdateModificationTime_ = function() {
- var fileList = this.directoryModel_.getFileList();
- var entries = [];
- for (var i = 0; i < fileList.length; i++) {
- entries.push(fileList.item(i));
- }
- this.metadataCache_.get(
- entries,
- 'filesystem',
- this.updateMetadataInUI_.bind(this, 'filesystem', entries));
-
- setTimeout(this.dailyUpdateModificationTime_.bind(this),
- MILLISECONDS_IN_DAY);
- };
-
- /**
- * @param {string} type Type of metadata changed.
- * @param {Array.<Entry>} entries Array of entries.
- * @param {Object.<string, Object>} props Map from entry URLs to metadata
- * props.
- * @private
- */
- FileManager.prototype.updateMetadataInUI_ = function(
- type, entries, properties) {
- if (this.listType_ == FileManager.ListType.DETAIL)
- this.table_.updateListItemsMetadata(type, properties);
- else
- this.grid_.updateListItemsMetadata(type, properties);
- // TODO: update bottom panel thumbnails.
- };
-
- /**
- * Restore the item which is being renamed while refreshing the file list. Do
- * nothing if no item is being renamed or such an item disappeared.
- *
- * While refreshing file list it gets repopulated with new file entries.
- * There is not a big difference whether DOM items stay the same or not.
- * Except for the item that the user is renaming.
- *
- * @private
- */
- FileManager.prototype.restoreItemBeingRenamed_ = function() {
- if (!this.isRenamingInProgress())
- return;
-
- var dm = this.directoryModel_;
- var leadIndex = dm.getFileListSelection().leadIndex;
- if (leadIndex < 0)
- return;
-
- var leadEntry = dm.getFileList().item(leadIndex);
- if (this.renameInput_.currentEntry.fullPath != leadEntry.fullPath)
- return;
-
- var leadListItem = this.findListItemForNode_(this.renameInput_);
- if (this.currentList_ == this.table_.list) {
- this.table_.updateFileMetadata(leadListItem, leadEntry);
- }
- this.currentList_.restoreLeadItem(leadListItem);
- };
-
- /**
- * @return {boolean} True if the current directory content is from Google
- * Drive.
- */
- FileManager.prototype.isOnDrive = function() {
- var rootType = this.directoryModel_.getCurrentRootType();
- return rootType === RootType.DRIVE ||
- rootType === RootType.DRIVE_SHARED_WITH_ME ||
- rootType === RootType.DRIVE_RECENT ||
- rootType === RootType.DRIVE_OFFLINE;
- };
-
- /**
- * Overrides default handling for clicks on hyperlinks.
- * In a packaged apps links with targer='_blank' open in a new tab by
- * default, other links do not open at all.
- *
- * @param {Event} event Click event.
- * @private
- */
- FileManager.prototype.onExternalLinkClick_ = function(event) {
- if (event.target.tagName != 'A' || !event.target.href)
- return;
-
- if (this.dialogType != DialogType.FULL_PAGE)
- this.onCancel_();
- };
-
- /**
- * Task combobox handler.
- *
- * @param {Object} event Event containing task which was clicked.
- * @private
- */
- FileManager.prototype.onTaskItemClicked_ = function(event) {
- var selection = this.getSelection();
- if (!selection.tasks) return;
-
- if (event.item.task) {
- // Task field doesn't exist on change-default dropdown item.
- selection.tasks.execute(event.item.task.taskId);
- } else {
- var extensions = [];
-
- for (var i = 0; i < selection.entries.length; i++) {
- var match = /\.(\w+)$/g.exec(selection.entries[i].toURL());
- if (match) {
- var ext = match[1].toUpperCase();
- if (extensions.indexOf(ext) == -1) {
- extensions.push(ext);
- }
- }
- }
-
- var format = '';
-
- if (extensions.length == 1) {
- format = extensions[0];
- }
-
- // Change default was clicked. We should open "change default" dialog.
- selection.tasks.showTaskPicker(this.defaultTaskPicker,
- loadTimeData.getString('CHANGE_DEFAULT_MENU_ITEM'),
- strf('CHANGE_DEFAULT_CAPTION', format),
- this.onDefaultTaskDone_.bind(this));
- }
- };
-
- /**
- * Sets the given task as default, when this task is applicable.
- *
- * @param {Object} task Task to set as default.
- * @private
- */
- FileManager.prototype.onDefaultTaskDone_ = function(task) {
- // TODO(dgozman): move this method closer to tasks.
- var selection = this.getSelection();
- chrome.fileBrowserPrivate.setDefaultTask(
- task.taskId,
- util.entriesToURLs(selection.entries),
- selection.mimeTypes);
- selection.tasks = new FileTasks(this);
- selection.tasks.init(selection.entries, selection.mimeTypes);
- selection.tasks.display(this.taskItems_);
- this.refreshCurrentDirectoryMetadata_();
- this.selectionHandler_.onFileSelectionChanged();
- };
-
- /**
- * @private
- */
- FileManager.prototype.onPreferencesChanged_ = function() {
- var self = this;
- this.getPreferences_(function(prefs) {
- self.initDateTimeFormatters_();
- self.refreshCurrentDirectoryMetadata_();
-
- if (prefs.cellularDisabled)
- self.syncButton.setAttribute('checked', '');
- else
- self.syncButton.removeAttribute('checked');
-
- if (self.hostedButton.hasAttribute('checked') !=
- prefs.hostedFilesDisabled && self.isOnDrive()) {
- self.directoryModel_.rescan();
- }
-
- if (!prefs.hostedFilesDisabled)
- self.hostedButton.setAttribute('checked', '');
- else
- self.hostedButton.removeAttribute('checked');
- },
- true /* refresh */);
- };
-
- FileManager.prototype.onDriveConnectionChanged_ = function() {
- var connection = this.volumeManager_.getDriveConnectionState();
- if (this.commandHandler)
- this.commandHandler.updateAvailability();
- if (this.dialogContainer_)
- this.dialogContainer_.setAttribute('connection', connection.type);
- this.shareDialog_.hideWithResult(ShareDialog.Result.NETWORK_ERROR);
- this.suggestAppsDialog.onDriveConnectionChanged(connection.type);
- };
-
- /**
- * Get the metered status of Drive connection.
- *
- * @return {boolean} Returns true if drive should limit the traffic because
- * the connection is metered and the 'disable-sync-on-metered' setting is
- * enabled. Otherwise, returns false.
- */
- FileManager.prototype.isDriveOnMeteredConnection = function() {
- var connection = this.volumeManager_.getDriveConnectionState();
- return connection.type == util.DriveConnectionType.METERED;
- };
-
- /**
- * Get the online/offline status of drive.
- *
- * @return {boolean} Returns true if the connection is offline. Otherwise,
- * returns false.
- */
- FileManager.prototype.isDriveOffline = function() {
- var connection = this.volumeManager_.getDriveConnectionState();
- return connection.type == util.DriveConnectionType.OFFLINE;
- };
-
- FileManager.prototype.isOnReadonlyDirectory = function() {
- return this.directoryModel_.isReadOnly();
- };
-
- /**
- * @param {Event} Unmount event.
- * @private
- */
- FileManager.prototype.onExternallyUnmounted_ = function(event) {
- if (event.mountPath == this.directoryModel_.getCurrentRootPath()) {
- if (this.closeOnUnmount_) {
- // If the file manager opened automatically when a usb drive inserted,
- // user have never changed current volume (that implies the current
- // directory is still on the device) then close this window.
- window.close();
- }
- }
- };
-
- /**
- * Show a modal-like file viewer/editor on top of the File Manager UI.
- *
- * @param {HTMLElement} popup Popup element.
- * @param {function()} closeCallback Function to call after the popup is
- * closed.
- */
- FileManager.prototype.openFilePopup = function(popup, closeCallback) {
- this.closeFilePopup();
- this.filePopup_ = popup;
- this.filePopupCloseCallback_ = closeCallback;
- this.dialogDom_.insertBefore(
- this.filePopup_, this.dialogDom_.querySelector('#iframe-drag-area'));
- this.filePopup_.focus();
- this.document_.body.setAttribute('overlay-visible', '');
- this.document_.querySelector('#iframe-drag-area').hidden = false;
- };
-
- /**
- * Closes the modal-like file viewer/editor popup.
- */
- FileManager.prototype.closeFilePopup = function() {
- if (this.filePopup_) {
- this.document_.body.removeAttribute('overlay-visible');
- this.document_.querySelector('#iframe-drag-area').hidden = true;
- // The window resize would not be processed properly while the relevant
- // divs had 'display:none', force resize after the layout fired.
- setTimeout(this.onResize_.bind(this), 0);
- if (this.filePopup_.contentWindow &&
- this.filePopup_.contentWindow.unload) {
- this.filePopup_.contentWindow.unload();
- }
-
- if (this.filePopupCloseCallback_) {
- this.filePopupCloseCallback_();
- this.filePopupCloseCallback_ = null;
- }
-
- // These operations have to be in the end, otherwise v8 crashes on an
- // assert. See: crbug.com/224174.
- this.dialogDom_.removeChild(this.filePopup_);
- this.filePopup_ = null;
- }
- };
-
- /**
- * Updates visibility of the draggable app region in the modal-like file
- * viewer/editor.
- *
- * @param {boolean} visible True for visible, false otherwise.
- */
- FileManager.prototype.onFilePopupAppRegionChanged = function(visible) {
- if (!this.filePopup_)
- return;
-
- this.document_.querySelector('#iframe-drag-area').hidden = !visible;
- };
-
- /**
- * @return {Array.<Entry>} List of all entries in the current directory.
- */
- FileManager.prototype.getAllEntriesInCurrentDirectory = function() {
- return this.directoryModel_.getFileList().slice();
- };
-
- FileManager.prototype.isRenamingInProgress = function() {
- return !!this.renameInput_.currentEntry;
- };
-
- /**
- * @private
- */
- FileManager.prototype.focusCurrentList_ = function() {
- if (this.listType_ == FileManager.ListType.DETAIL)
- this.table_.focus();
- else // this.listType_ == FileManager.ListType.THUMBNAIL)
- this.grid_.focus();
- };
-
- /**
- * Return full path of the current directory or null.
- * @return {?string} The full path of the current directory.
- */
- FileManager.prototype.getCurrentDirectory = function() {
- return this.directoryModel_ && this.directoryModel_.getCurrentDirPath();
- };
-
- /**
- * Return URL of the current directory or null.
- * @return {string} URL representing the current directory.
- */
- FileManager.prototype.getCurrentDirectoryURL = function() {
- return this.directoryModel_ &&
- this.directoryModel_.getCurrentDirectoryURL();
- };
-
- /**
- * Return DirectoryEntry of the current directory or null.
- * @return {DirectoryEntry} DirectoryEntry of the current directory. Returns
- * null if the directory model is not ready or the current directory is
- * not set.
- */
- FileManager.prototype.getCurrentDirectoryEntry = function() {
- return this.directoryModel_ && this.directoryModel_.getCurrentDirEntry();
- };
-
- /**
- * Deletes the selected file and directories recursively.
- */
- FileManager.prototype.deleteSelection = function() {
- // TODO(mtomasz): Remove this temporary dialog. crbug.com/167364
- var entries = this.getSelection().entries;
- var message = entries.length == 1 ?
- strf('GALLERY_CONFIRM_DELETE_ONE', entries[0].name) :
- strf('GALLERY_CONFIRM_DELETE_SOME', entries.length);
- this.confirm.show(message, function() {
- this.fileOperationManager_.deleteEntries(entries);
- }.bind(this));
- };
-
- /**
- * Shows the share dialog for the selected file or directory.
- */
- FileManager.prototype.shareSelection = function() {
- var entries = this.getSelection().entries;
- if (entries.length != 1) {
- console.warn('Unable to share multiple items at once.');
- return;
- }
- // Add the overlapped class to prevent the applicaiton window from
- // captureing mouse events.
- this.shareDialog_.show(entries[0], function(result) {
- if (result == ShareDialog.Result.NETWORK_ERROR)
- this.error.show(str('SHARE_ERROR'));
- }.bind(this));
- };
-
- /**
- * Creates a folder shortcut.
- * @param {string} path A shortcut which refers to |path| to be created.
- */
- FileManager.prototype.createFolderShortcut = function(path) {
- // Duplicate entry.
- if (this.folderShortcutExists(path))
- return;
-
- this.folderShortcutsModel_.add(path);
- };
-
- /**
- * Checkes if the shortcut which refers to the given folder exists or not.
- * @param {string} path Path of the folder to be checked.
- */
- FileManager.prototype.folderShortcutExists = function(path) {
- return this.folderShortcutsModel_.exists(path);
- };
-
- /**
- * Removes the folder shortcut.
- * @param {string} path The shortcut which refers to |path| is to be removed.
- */
- FileManager.prototype.removeFolderShortcut = function(path) {
- this.folderShortcutsModel_.remove(path);
- };
-
- /**
- * Blinks the selection. Used to give feedback when copying or cutting the
- * selection.
- */
- FileManager.prototype.blinkSelection = function() {
- var selection = this.getSelection();
- if (!selection || selection.totalCount == 0)
- return;
-
- for (var i = 0; i < selection.entries.length; i++) {
- var selectedIndex = selection.indexes[i];
- var listItem = this.currentList_.getListItemByIndex(selectedIndex);
- if (listItem)
- this.blinkListItem_(listItem);
- }
- };
-
- /**
- * @param {Element} listItem List item element.
- * @private
- */
- FileManager.prototype.blinkListItem_ = function(listItem) {
- listItem.classList.add('blink');
- setTimeout(function() {
- listItem.classList.remove('blink');
- }, 100);
- };
-
- /**
- * @private
- */
- FileManager.prototype.selectDefaultPathInFilenameInput_ = function() {
- var input = this.filenameInput_;
- input.focus();
- var selectionEnd = input.value.lastIndexOf('.');
- if (selectionEnd == -1) {
- input.select();
- } else {
- input.selectionStart = 0;
- input.selectionEnd = selectionEnd;
- }
- // Clear, so we never do this again.
- this.defaultPath = '';
- };
-
- /**
- * Handles mouse click or tap.
- *
- * @param {Event} event The click event.
- * @private
- */
- FileManager.prototype.onDetailClick_ = function(event) {
- if (this.isRenamingInProgress()) {
- // Don't pay attention to clicks during a rename.
- return;
- }
-
- var listItem = this.findListItemForEvent_(event);
- var selection = this.getSelection();
- if (!listItem || !listItem.selected || selection.totalCount != 1) {
- return;
- }
-
- // React on double click, but only if both clicks hit the same item.
- // TODO(mtomasz): Simplify it, and use a double click handler if possible.
- var clickNumber = (this.lastClickedItem_ == listItem) ? 2 : undefined;
- this.lastClickedItem_ = listItem;
-
- if (event.detail != clickNumber)
- return;
-
- var entry = selection.entries[0];
- if (entry.isDirectory) {
- this.onDirectoryAction_(entry);
- } else {
- this.dispatchSelectionAction_();
- }
- };
-
- /**
- * @private
- */
- FileManager.prototype.dispatchSelectionAction_ = function() {
- if (this.dialogType == DialogType.FULL_PAGE) {
- var selection = this.getSelection();
- var tasks = selection.tasks;
- var urls = selection.urls;
- var mimeTypes = selection.mimeTypes;
- if (tasks)
- tasks.executeDefault();
- return true;
- }
- if (!this.okButton_.disabled) {
- this.onOk_();
- return true;
- }
- return false;
- };
-
- /**
- * Opens the suggest file dialog.
- *
- * @param {Entry} entry Entry of the file.
- * @param {function()} onSuccess Success callback.
- * @param {function()} onCancelled User-cancelled callback.
- * @param {function()} onFailure Failure callback.
- * @private
- */
- FileManager.prototype.openSuggestAppsDialog =
- function(entry, onSuccess, onCancelled, onFailure) {
- if (!url) {
- onFailure();
- return;
- }
-
- this.metadataCache_.get([entry], 'drive', function(props) {
- if (!props || !props[0] || !props[0].contentMimeType) {
- onFailure();
- return;
- }
-
- var basename = entry.name;
- var splitted = PathUtil.splitExtension(basename);
- var filename = splitted[0];
- var extension = splitted[1];
- var mime = props[0].contentMimeType;
-
- // Returns with failure if the file has neither extension nor mime.
- if (!extension || !mime) {
- onFailure();
- return;
- }
-
- var onDialogClosed = function(result) {
- switch (result) {
- case SuggestAppsDialog.Result.INSTALL_SUCCESSFUL:
- onSuccess();
- break;
- case SuggestAppsDialog.Result.FAILED:
- onFailure();
- break;
- default:
- onCancelled();
- }
- };
-
- if (FileTasks.EXECUTABLE_EXTENSIONS.indexOf(extension) !== -1) {
- this.suggestAppsDialog.showByFilename(filename, onDialogClosed);
- } else {
- this.suggestAppsDialog.showByExtensionAndMime(
- extension, mime, onDialogClosed);
- }
- }.bind(this));
- };
-
- /**
- * Called when a dialog is shown or hidden.
- * @param {boolean} flag True if a dialog is shown, false if hidden. */
- FileManager.prototype.onDialogShownOrHidden = function(show) {
- // Set/unset a flag to disable dragging on the title area.
- this.dialogContainer_.classList.toggle('disable-header-drag', show);
- };
-
- /**
- * Executes directory action (i.e. changes directory).
- *
- * @param {DirectoryEntry} entry Directory entry to which directory should be
- * changed.
- * @private
- */
- FileManager.prototype.onDirectoryAction_ = function(entry) {
- return this.directoryModel_.changeDirectory(entry.fullPath);
- };
-
- /**
- * Update the window title.
- * @private
- */
- FileManager.prototype.updateTitle_ = function() {
- if (this.dialogType != DialogType.FULL_PAGE)
- return;
-
- var path = this.getCurrentDirectory();
- var rootPath = PathUtil.getRootPath(path);
- this.document_.title = PathUtil.getRootLabel(rootPath) +
- path.substring(rootPath.length);
- };
-
- /**
- * Update the gear menu.
- * @private
- */
- FileManager.prototype.updateGearMenu_ = function() {
- var hideItemsForDrive = !this.isOnDrive();
- this.syncButton.hidden = hideItemsForDrive;
- this.hostedButton.hidden = hideItemsForDrive;
- this.document_.getElementById('drive-separator').hidden =
- hideItemsForDrive;
-
- // If volume has changed, then fetch remaining space data.
- if (this.previousRootUrl_ != this.directoryModel_.getCurrentMountPointUrl())
- this.refreshRemainingSpace_(true); // Show loading caption.
-
- this.previousRootUrl_ = this.directoryModel_.getCurrentMountPointUrl();
- };
-
- /**
- * Refreshes space info of the current volume.
- * @param {boolean} showLoadingCaption Whether show loading caption or not.
- * @private
- */
- FileManager.prototype.refreshRemainingSpace_ = function(showLoadingCaption) {
- var volumeSpaceInfoLabel =
- this.dialogDom_.querySelector('#volume-space-info-label');
- var volumeSpaceInnerBar =
- this.dialogDom_.querySelector('#volume-space-info-bar');
- var volumeSpaceOuterBar =
- this.dialogDom_.querySelector('#volume-space-info-bar').parentNode;
-
- volumeSpaceInnerBar.setAttribute('pending', '');
-
- if (showLoadingCaption) {
- volumeSpaceInfoLabel.innerText = str('WAITING_FOR_SPACE_INFO');
- volumeSpaceInnerBar.style.width = '100%';
- }
-
- var currentMountPointUrl = this.directoryModel_.getCurrentMountPointUrl();
- chrome.fileBrowserPrivate.getSizeStats(
- currentMountPointUrl, function(result) {
- if (this.directoryModel_.getCurrentMountPointUrl() !=
- currentMountPointUrl)
- return;
- updateSpaceInfo(result,
- volumeSpaceInnerBar,
- volumeSpaceInfoLabel,
- volumeSpaceOuterBar);
- }.bind(this));
- };
-
- /**
- * Update the UI when the current directory changes.
- *
- * @param {Event} event The directory-changed event.
- * @private
- */
- FileManager.prototype.onDirectoryChanged_ = function(event) {
- this.selectionHandler_.onFileSelectionChanged();
- this.ui_.searchBox.clear();
- util.updateAppState(this.getCurrentDirectory());
-
- // If the current directory is moved from the device's volume, do not
- // automatically close the window on device removal.
- if (event.previousDirEntry &&
- PathUtil.getRootPath(event.previousDirEntry.fullPath) !=
- PathUtil.getRootPath(event.newDirEntry.fullPath))
- this.closeOnUnmount_ = false;
-
- if (this.commandHandler)
- this.commandHandler.updateAvailability();
- this.updateUnformattedVolumeStatus_();
- this.updateTitle_();
- this.updateGearMenu_();
- var currentEntry = this.getCurrentDirectoryEntry();
- this.previewPanel_.currentEntry = util.isFakeEntry(currentEntry) ?
- null : currentEntry;
- };
-
- FileManager.prototype.updateUnformattedVolumeStatus_ = function() {
- var volumeInfo = this.volumeManager_.getVolumeInfo(
- this.directoryModel_.getCurrentDirEntry());
-
- if (volumeInfo && volumeInfo.error) {
- this.dialogDom_.setAttribute('unformatted', '');
-
- var errorNode = this.dialogDom_.querySelector('#format-panel > .error');
- if (volumeInfo.error == util.VolumeError.UNSUPPORTED_FILESYSTEM) {
- errorNode.textContent = str('UNSUPPORTED_FILESYSTEM_WARNING');
- } else {
- errorNode.textContent = str('UNKNOWN_FILESYSTEM_WARNING');
- }
-
- // Update 'canExecute' for format command so the format button's disabled
- // property is properly set.
- if (this.commandHandler)
- this.commandHandler.updateAvailability();
- } else {
- this.dialogDom_.removeAttribute('unformatted');
- }
- };
-
- FileManager.prototype.findListItemForEvent_ = function(event) {
- return this.findListItemForNode_(event.touchedElement || event.srcElement);
- };
-
- FileManager.prototype.findListItemForNode_ = function(node) {
- var item = this.currentList_.getListItemAncestor(node);
- // TODO(serya): list should check that.
- return item && this.currentList_.isItem(item) ? item : null;
- };
-
- /**
- * Unload handler for the page. May be called manually for the file picker
- * dialog, because it closes by calling extension API functions that do not
- * return.
- *
- * TODO(hirono): This method is not called when Files.app is opend as a dialog
- * and is closed by the close button in the dialog frame. crbug.com/309967
- * @private
- */
- FileManager.prototype.onUnload_ = function() {
- if (this.directoryModel_)
- this.directoryModel_.dispose();
- if (this.volumeManager_)
- this.volumeManager_.dispose();
- if (this.filePopup_ &&
- this.filePopup_.contentWindow &&
- this.filePopup_.contentWindow.unload)
- this.filePopup_.contentWindow.unload(true /* exiting */);
- if (this.progressCenterPanel_)
- this.backgroundPage_.background.progressCenter.removePanel(
- this.progressCenterPanel_);
- if (this.fileOperationManager_) {
- if (this.onCopyProgressBound_) {
- this.fileOperationManager_.removeEventListener(
- 'copy-progress', this.onCopyProgressBound_);
- }
- if (this.onEntryChangedBound_) {
- this.fileOperationManager_.removeEventListener(
- 'entry-changed', this.onEntryChangedBound_);
- }
- }
- window.closing = true;
- if (this.backgroundPage_ && util.platform.runningInBrowser())
- this.backgroundPage_.background.tryClose();
- };
-
- FileManager.prototype.initiateRename = function() {
- var item = this.currentList_.ensureLeadItemExists();
- if (!item)
- return;
- var label = item.querySelector('.filename-label');
- var input = this.renameInput_;
-
- input.value = label.textContent;
- label.parentNode.setAttribute('renaming', '');
- label.parentNode.appendChild(input);
- input.focus();
- var selectionEnd = input.value.lastIndexOf('.');
- if (selectionEnd == -1) {
- input.select();
- } else {
- input.selectionStart = 0;
- input.selectionEnd = selectionEnd;
- }
-
- // This has to be set late in the process so we don't handle spurious
- // blur events.
- input.currentEntry = this.currentList_.dataModel.item(item.listIndex);
- };
-
- /**
- * @type {Event} Key event.
- * @private
- */
- FileManager.prototype.onRenameInputKeyDown_ = function(event) {
- if (!this.isRenamingInProgress())
- return;
-
- // Do not move selection or lead item in list during rename.
- if (event.keyIdentifier == 'Up' || event.keyIdentifier == 'Down') {
- event.stopPropagation();
- }
-
- switch (util.getKeyModifiers(event) + event.keyCode) {
- case '27': // Escape
- this.cancelRename_();
- event.preventDefault();
- break;
-
- case '13': // Enter
- this.commitRename_();
- event.preventDefault();
- break;
- }
- };
-
- /**
- * @type {Event} Blur event.
- * @private
- */
- FileManager.prototype.onRenameInputBlur_ = function(event) {
- if (this.isRenamingInProgress() && !this.renameInput_.validation_)
- this.commitRename_();
- };
-
- /**
- * @private
- */
- FileManager.prototype.commitRename_ = function() {
- var input = this.renameInput_;
- var entry = input.currentEntry;
- var newName = input.value;
-
- if (newName == entry.name) {
- this.cancelRename_();
- return;
- }
-
- var nameNode = this.findListItemForNode_(this.renameInput_).
- querySelector('.filename-label');
-
- input.validation_ = true;
- var validationDone = function(valid) {
- input.validation_ = false;
- // Alert dialog restores focus unless the item removed from DOM.
- if (this.document_.activeElement != input)
- this.cancelRename_();
- if (!valid)
- return;
-
- // Validation succeeded. Do renaming.
-
- this.cancelRename_();
- // Optimistically apply new name immediately to avoid flickering in
- // case of success.
- nameNode.textContent = newName;
-
- util.rename(
- entry, newName,
- function(newEntry) {
- this.directoryModel_.onRenameEntry(entry, newEntry);
- }.bind(this),
- function(error) {
- // Write back to the old name.
- nameNode.textContent = entry.name;
-
- // Show error dialog.
- var message;
- if (error.code == FileError.PATH_EXISTS_ERR ||
- error.code == FileError.TYPE_MISMATCH_ERR) {
- // Check the existing entry is file or not.
- // 1) If the entry is a file:
- // a) If we get PATH_EXISTS_ERR, a file exists.
- // b) If we get TYPE_MISMATCH_ERR, a directory exists.
- // 2) If the entry is a directory:
- // a) If we get PATH_EXISTS_ERR, a directory exists.
- // b) If we get TYPE_MISMATCH_ERR, a file exists.
- message = strf(
- (entry.isFile && error.code == FileError.PATH_EXISTS_ERR) ||
- (!entry.isFile && error.code == FileError.TYPE_MISMATCH_ERR) ?
- 'FILE_ALREADY_EXISTS' :
- 'DIRECTORY_ALREADY_EXISTS',
- newName);
- } else {
- message = strf('ERROR_RENAMING', entry.name,
- util.getFileErrorString(err.code));
- }
-
- this.alert.show(message);
- }.bind(this));
- };
-
- // TODO(haruki): this.getCurrentDirectoryURL() might not return the actual
- // parent if the directory content is a search result. Fix it to do proper
- // validation.
- this.validateFileName_(this.getCurrentDirectoryURL(),
- newName,
- validationDone.bind(this));
- };
-
- /**
- * @private
- */
- FileManager.prototype.cancelRename_ = function() {
- this.renameInput_.currentEntry = null;
-
- var parent = this.renameInput_.parentNode;
- if (parent) {
- parent.removeAttribute('renaming');
- parent.removeChild(this.renameInput_);
- }
- };
-
- /**
- * @param {Event} Key event.
- * @private
- */
- FileManager.prototype.onFilenameInputInput_ = function() {
- this.selectionHandler_.updateOkButton();
- };
-
- /**
- * @param {Event} Key event.
- * @private
- */
- FileManager.prototype.onFilenameInputKeyDown_ = function(event) {
- if ((util.getKeyModifiers(event) + event.keyCode) === '13' /* Enter */)
- this.okButton_.click();
- };
-
- /**
- * @param {Event} Focus event.
- * @private
- */
- FileManager.prototype.onFilenameInputFocus_ = function(event) {
- var input = this.filenameInput_;
-
- // On focus we want to select everything but the extension, but
- // Chrome will select-all after the focus event completes. We
- // schedule a timeout to alter the focus after that happens.
- setTimeout(function() {
- var selectionEnd = input.value.lastIndexOf('.');
- if (selectionEnd == -1) {
- input.select();
- } else {
- input.selectionStart = 0;
- input.selectionEnd = selectionEnd;
- }
- }, 0);
- };
-
- /**
- * @private
- */
- FileManager.prototype.onScanStarted_ = function() {
- if (this.scanInProgress_) {
- this.table_.list.endBatchUpdates();
- this.grid_.endBatchUpdates();
- }
-
- if (this.commandHandler)
- this.commandHandler.updateAvailability();
- this.table_.list.startBatchUpdates();
- this.grid_.startBatchUpdates();
- this.scanInProgress_ = true;
-
- this.scanUpdatedAtLeastOnceOrCompleted_ = false;
- if (this.scanCompletedTimer_) {
- clearTimeout(this.scanCompletedTimer_);
- this.scanCompletedTimer_ = null;
- }
-
- if (this.scanUpdatedTimer_) {
- clearTimeout(this.scanUpdatedTimer_);
- this.scanUpdatedTimer_ = null;
- }
-
- if (this.spinner_.hidden) {
- this.cancelSpinnerTimeout_();
- this.showSpinnerTimeout_ =
- setTimeout(this.showSpinner_.bind(this, true), 500);
- }
- };
-
- /**
- * @private
- */
- FileManager.prototype.onScanCompleted_ = function() {
- if (!this.scanInProgress_) {
- console.error('Scan-completed event recieved. But scan is not started.');
- return;
- }
-
- if (this.commandHandler)
- this.commandHandler.updateAvailability();
- this.hideSpinnerLater_();
-
- if (this.scanUpdatedTimer_) {
- clearTimeout(this.scanUpdatedTimer_);
- this.scanUpdatedTimer_ = null;
- }
-
- // To avoid flickering postpone updating the ui by a small amount of time.
- // There is a high chance, that metadata will be received within 50 ms.
- this.scanCompletedTimer_ = setTimeout(function() {
- // Check if batch updates are already finished by onScanUpdated_().
- if (!this.scanUpdatedAtLeastOnceOrCompleted_) {
- this.scanUpdatedAtLeastOnceOrCompleted_ = true;
- this.updateMiddleBarVisibility_();
- }
-
- this.scanInProgress_ = false;
- this.table_.list.endBatchUpdates();
- this.grid_.endBatchUpdates();
- this.scanCompletedTimer_ = null;
- }.bind(this), 50);
- };
-
- /**
- * @private
- */
- FileManager.prototype.onScanUpdated_ = function() {
- if (!this.scanInProgress_) {
- console.error('Scan-updated event recieved. But scan is not started.');
- return;
- }
-
- if (this.scanUpdatedTimer_ || this.scanCompletedTimer_)
- return;
-
- // Show contents incrementally by finishing batch updated, but only after
- // 200ms elapsed, to avoid flickering when it is not necessary.
- this.scanUpdatedTimer_ = setTimeout(function() {
- // We need to hide the spinner only once.
- if (!this.scanUpdatedAtLeastOnceOrCompleted_) {
- this.scanUpdatedAtLeastOnceOrCompleted_ = true;
- this.hideSpinnerLater_();
- this.updateMiddleBarVisibility_();
- }
-
- // Update the UI.
- if (this.scanInProgress_) {
- this.table_.list.endBatchUpdates();
- this.grid_.endBatchUpdates();
- this.table_.list.startBatchUpdates();
- this.grid_.startBatchUpdates();
- }
- this.scanUpdatedTimer_ = null;
- }.bind(this), 200);
- };
-
- /**
- * @private
- */
- FileManager.prototype.onScanCancelled_ = function() {
- if (!this.scanInProgress_) {
- console.error('Scan-cancelled event recieved. But scan is not started.');
- return;
- }
-
- if (this.commandHandler)
- this.commandHandler.updateAvailability();
- this.hideSpinnerLater_();
- if (this.scanCompletedTimer_) {
- clearTimeout(this.scanCompletedTimer_);
- this.scanCompletedTimer_ = null;
- }
- if (this.scanUpdatedTimer_) {
- clearTimeout(this.scanUpdatedTimer_);
- this.scanUpdatedTimer_ = null;
- }
- // Finish unfinished batch updates.
- if (!this.scanUpdatedAtLeastOnceOrCompleted_) {
- this.scanUpdatedAtLeastOnceOrCompleted_ = true;
- this.updateMiddleBarVisibility_();
- }
-
- this.scanInProgress_ = false;
- this.table_.list.endBatchUpdates();
- this.grid_.endBatchUpdates();
- };
-
- /**
- * Handle the 'rescan-completed' from the DirectoryModel.
- * @private
- */
- FileManager.prototype.onRescanCompleted_ = function() {
- this.selectionHandler_.onFileSelectionChanged();
- };
-
- /**
- * @private
- */
- FileManager.prototype.cancelSpinnerTimeout_ = function() {
- if (this.showSpinnerTimeout_) {
- clearTimeout(this.showSpinnerTimeout_);
- this.showSpinnerTimeout_ = null;
- }
- };
-
- /**
- * @private
- */
- FileManager.prototype.hideSpinnerLater_ = function() {
- this.cancelSpinnerTimeout_();
- this.showSpinner_(false);
- };
-
- /**
- * @param {boolean} on True to show, false to hide.
- * @private
- */
- FileManager.prototype.showSpinner_ = function(on) {
- if (on && this.directoryModel_ && this.directoryModel_.isScanning())
- this.spinner_.hidden = false;
-
- if (!on && (!this.directoryModel_ ||
- !this.directoryModel_.isScanning() ||
- this.directoryModel_.getFileList().length != 0)) {
- this.spinner_.hidden = true;
- }
- };
-
- FileManager.prototype.createNewFolder = function() {
- var defaultName = str('DEFAULT_NEW_FOLDER_NAME');
-
- // Find a name that doesn't exist in the data model.
- var files = this.directoryModel_.getFileList();
- var hash = {};
- for (var i = 0; i < files.length; i++) {
- var name = files.item(i).name;
- // Filtering names prevents from conflicts with prototype's names
- // and '__proto__'.
- if (name.substring(0, defaultName.length) == defaultName)
- hash[name] = 1;
- }
-
- var baseName = defaultName;
- var separator = '';
- var suffix = '';
- var index = '';
-
- var advance = function() {
- separator = ' (';
- suffix = ')';
- index++;
- };
-
- var current = function() {
- return baseName + separator + index + suffix;
- };
-
- // Accessing hasOwnProperty is safe since hash properties filtered.
- while (hash.hasOwnProperty(current())) {
- advance();
- }
-
- var self = this;
- var list = self.currentList_;
- var tryCreate = function() {
- self.directoryModel_.createDirectory(current(),
- onSuccess, onError);
- };
-
- var onSuccess = function(entry) {
- metrics.recordUserAction('CreateNewFolder');
- list.selectedItem = entry;
- self.initiateRename();
- };
-
- var onError = function(error) {
- self.alert.show(strf('ERROR_CREATING_FOLDER', current(),
- util.getFileErrorString(error.code)));
- };
-
- tryCreate();
- };
-
- /**
- * @param {Event} event Click event.
- * @private
- */
- FileManager.prototype.onDetailViewButtonClick_ = function(event) {
- // Stop propagate and hide the menu manually, in order to prevent the focus
- // from being back to the button. (cf. http://crbug.com/248479)
- event.stopPropagation();
- this.gearButton_.hideMenu();
-
- this.setListType(FileManager.ListType.DETAIL);
- this.currentList_.focus();
- };
-
- /**
- * @param {Event} event Click event.
- * @private
- */
- FileManager.prototype.onThumbnailViewButtonClick_ = function(event) {
- // Stop propagate and hide the menu manually, in order to prevent the focus
- // from being back to the button. (cf. http://crbug.com/248479)
- event.stopPropagation();
- this.gearButton_.hideMenu();
-
- this.setListType(FileManager.ListType.THUMBNAIL);
- this.currentList_.focus();
- };
-
- /**
- * KeyDown event handler for the document.
- * @param {Event} event Key event.
- * @private
- */
- FileManager.prototype.onKeyDown_ = function(event) {
- if (event.srcElement === this.renameInput_) {
- // Ignore keydown handler in the rename input box.
- return;
- }
-
- switch (util.getKeyModifiers(event) + event.keyCode) {
- case 'Ctrl-190': // Ctrl-. => Toggle filter files.
- this.fileFilter_.setFilterHidden(
- !this.fileFilter_.isFilterHiddenOn());
- event.preventDefault();
- return;
-
- case '27': // Escape => Cancel dialog.
- if (this.dialogType != DialogType.FULL_PAGE) {
- // If there is nothing else for ESC to do, then cancel the dialog.
- event.preventDefault();
- this.cancelButton_.click();
- }
- break;
- }
- };
-
- /**
- * KeyDown event handler for the div#list-container element.
- * @param {Event} event Key event.
- * @private
- */
- FileManager.prototype.onListKeyDown_ = function(event) {
- if (event.srcElement.tagName == 'INPUT') {
- // Ignore keydown handler in the rename input box.
- return;
- }
-
- switch (util.getKeyModifiers(event) + event.keyCode) {
- case '8': // Backspace => Up one directory.
- event.preventDefault();
- var path = this.getCurrentDirectory();
- if (path && !PathUtil.isRootPath(path)) {
- var path = path.replace(/\/[^\/]+$/, '');
- this.directoryModel_.changeDirectory(path);
- }
- break;
-
- case '13': // Enter => Change directory or perform default action.
- // TODO(dgozman): move directory action to dispatchSelectionAction.
- var selection = this.getSelection();
- if (selection.totalCount == 1 &&
- selection.entries[0].isDirectory &&
- !DialogType.isFolderDialog(this.dialogType)) {
- event.preventDefault();
- this.onDirectoryAction_(selection.entries[0]);
- } else if (this.dispatchSelectionAction_()) {
- event.preventDefault();
- }
- break;
- }
-
- switch (event.keyIdentifier) {
- case 'Home':
- case 'End':
- case 'Up':
- case 'Down':
- case 'Left':
- case 'Right':
- // When navigating with keyboard we hide the distracting mouse hover
- // highlighting until the user moves the mouse again.
- this.setNoHover_(true);
- break;
- }
- };
-
- /**
- * Suppress/restore hover highlighting in the list container.
- * @param {boolean} on True to temporarity hide hover state.
- * @private
- */
- FileManager.prototype.setNoHover_ = function(on) {
- if (on) {
- this.listContainer_.classList.add('nohover');
- } else {
- this.listContainer_.classList.remove('nohover');
- }
- };
-
- /**
- * KeyPress event handler for the div#list-container element.
- * @param {Event} event Key event.
- * @private
- */
- FileManager.prototype.onListKeyPress_ = function(event) {
- if (event.srcElement.tagName == 'INPUT') {
- // Ignore keypress handler in the rename input box.
- return;
- }
-
- if (event.ctrlKey || event.metaKey || event.altKey)
- return;
-
- var now = new Date();
- var char = String.fromCharCode(event.charCode).toLowerCase();
- var text = now - this.textSearchState_.date > 1000 ? '' :
- this.textSearchState_.text;
- this.textSearchState_ = {text: text + char, date: now};
-
- this.doTextSearch_();
- };
-
- /**
- * Mousemove event handler for the div#list-container element.
- * @param {Event} event Mouse event.
- * @private
- */
- FileManager.prototype.onListMouseMove_ = function(event) {
- // The user grabbed the mouse, restore the hover highlighting.
- this.setNoHover_(false);
- };
-
- /**
- * Performs a 'text search' - selects a first list entry with name
- * starting with entered text (case-insensitive).
- * @private
- */
- FileManager.prototype.doTextSearch_ = function() {
- var text = this.textSearchState_.text;
- if (!text)
- return;
-
- var dm = this.directoryModel_.getFileList();
- for (var index = 0; index < dm.length; ++index) {
- var name = dm.item(index).name;
- if (name.substring(0, text.length).toLowerCase() == text) {
- this.currentList_.selectionModel.selectedIndexes = [index];
- return;
- }
- }
-
- this.textSearchState_.text = '';
- };
-
- /**
- * Handle a click of the cancel button. Closes the window.
- * TODO(jamescook): Make unload handler work automatically, crbug.com/104811
- *
- * @param {Event} event The click event.
- * @private
- */
- FileManager.prototype.onCancel_ = function(event) {
- chrome.fileBrowserPrivate.cancelDialog();
- this.onUnload_();
- window.close();
- };
-
- /**
- * Resolves selected file urls returned from an Open dialog.
- *
- * For drive files this involves some special treatment.
- * Starts getting drive files if needed.
- *
- * @param {Array.<string>} fileUrls Drive URLs.
- * @param {function(Array.<string>)} callback To be called with fixed URLs.
- * @private
- */
- FileManager.prototype.resolveSelectResults_ = function(fileUrls, callback) {
- if (this.isOnDrive()) {
- chrome.fileBrowserPrivate.getDriveFiles(
- fileUrls,
- function(localPaths) {
- callback(fileUrls);
- });
- } else {
- callback(fileUrls);
- }
- };
-
- /**
- * Closes this modal dialog with some files selected.
- * TODO(jamescook): Make unload handler work automatically, crbug.com/104811
- * @param {Object} selection Contains urls, filterIndex and multiple fields.
- * @private
- */
- FileManager.prototype.callSelectFilesApiAndClose_ = function(selection) {
- var self = this;
- function callback() {
- self.onUnload_();
- window.close();
- }
- if (selection.multiple) {
- chrome.fileBrowserPrivate.selectFiles(
- selection.urls, this.params_.shouldReturnLocalPath, callback);
- } else {
- var forOpening = (this.dialogType != DialogType.SELECT_SAVEAS_FILE);
- chrome.fileBrowserPrivate.selectFile(
- selection.urls[0], selection.filterIndex, forOpening,
- this.params_.shouldReturnLocalPath, callback);
- }
- };
-
- /**
- * Tries to close this modal dialog with some files selected.
- * Performs preprocessing if needed (e.g. for Drive).
- * @param {Object} selection Contains urls, filterIndex and multiple fields.
- * @private
- */
- FileManager.prototype.selectFilesAndClose_ = function(selection) {
- if (!this.isOnDrive() ||
- this.dialogType == DialogType.SELECT_SAVEAS_FILE) {
- setTimeout(this.callSelectFilesApiAndClose_.bind(this, selection), 0);
- return;
- }
-
- var shade = this.document_.createElement('div');
- shade.className = 'shade';
- var footer = this.dialogDom_.querySelector('.button-panel');
- var progress = footer.querySelector('.progress-track');
- progress.style.width = '0%';
- var cancelled = false;
-
- var progressMap = {};
- var filesStarted = 0;
- var filesTotal = selection.urls.length;
- for (var index = 0; index < selection.urls.length; index++) {
- progressMap[selection.urls[index]] = -1;
- }
- var lastPercent = 0;
- var bytesTotal = 0;
- var bytesDone = 0;
-
- var onFileTransfersUpdated = function(statusList) {
- for (var index = 0; index < statusList.length; index++) {
- var status = statusList[index];
- var escaped = encodeURI(status.fileUrl);
- if (!(escaped in progressMap)) continue;
- if (status.total == -1) continue;
-
- var old = progressMap[escaped];
- if (old == -1) {
- // -1 means we don't know file size yet.
- bytesTotal += status.total;
- filesStarted++;
- old = 0;
- }
- bytesDone += status.processed - old;
- progressMap[escaped] = status.processed;
- }
-
- var percent = bytesTotal == 0 ? 0 : bytesDone / bytesTotal;
- // For files we don't have information about, assume the progress is zero.
- percent = percent * filesStarted / filesTotal * 100;
- // Do not decrease the progress. This may happen, if first downloaded
- // file is small, and the second one is large.
- lastPercent = Math.max(lastPercent, percent);
- progress.style.width = lastPercent + '%';
- }.bind(this);
-
- var setup = function() {
- this.document_.querySelector('.dialog-container').appendChild(shade);
- setTimeout(function() { shade.setAttribute('fadein', 'fadein') }, 100);
- footer.setAttribute('progress', 'progress');
- this.cancelButton_.removeEventListener('click', this.onCancelBound_);
- this.cancelButton_.addEventListener('click', onCancel);
- chrome.fileBrowserPrivate.onFileTransfersUpdated.addListener(
- onFileTransfersUpdated);
- }.bind(this);
-
- var cleanup = function() {
- shade.parentNode.removeChild(shade);
- footer.removeAttribute('progress');
- this.cancelButton_.removeEventListener('click', onCancel);
- this.cancelButton_.addEventListener('click', this.onCancelBound_);
- chrome.fileBrowserPrivate.onFileTransfersUpdated.removeListener(
- onFileTransfersUpdated);
- }.bind(this);
-
- var onCancel = function() {
- cancelled = true;
- // According to API cancel may fail, but there is no proper UI to reflect
- // this. So, we just silently assume that everything is cancelled.
- chrome.fileBrowserPrivate.cancelFileTransfers(
- selection.urls, function(response) {});
- cleanup();
- }.bind(this);
-
- var onResolved = function(resolvedUrls) {
- if (cancelled) return;
- cleanup();
- selection.urls = resolvedUrls;
- // Call next method on a timeout, as it's unsafe to
- // close a window from a callback.
- setTimeout(this.callSelectFilesApiAndClose_.bind(this, selection), 0);
- }.bind(this);
-
- var onProperties = function(properties) {
- for (var i = 0; i < properties.length; i++) {
- if (!properties[i] || properties[i].present) {
- // For files already in GCache, we don't get any transfer updates.
- filesTotal--;
- }
- }
- this.resolveSelectResults_(selection.urls, onResolved);
- }.bind(this);
-
- setup();
-
- // TODO(mtomasz): Use Entry instead of URLs, if possible.
- util.URLsToEntries(selection.urls, function(entries) {
- this.metadataCache_.get(entries, 'drive', onProperties);
- }.bind(this));
- };
-
- /**
- * Handle a click of the ok button.
- *
- * The ok button has different UI labels depending on the type of dialog, but
- * in code it's always referred to as 'ok'.
- *
- * @param {Event} event The click event.
- * @private
- */
- FileManager.prototype.onOk_ = function(event) {
- if (this.dialogType == DialogType.SELECT_SAVEAS_FILE) {
- // Save-as doesn't require a valid selection from the list, since
- // we're going to take the filename from the text input.
- var filename = this.filenameInput_.value;
- if (!filename)
- throw new Error('Missing filename!');
-
- var directory = this.getCurrentDirectoryEntry();
- var currentDirUrl = directory.toURL();
- if (currentDirUrl.charAt(currentDirUrl.length - 1) != '/')
- currentDirUrl += '/';
- this.validateFileName_(currentDirUrl, filename, function(isValid) {
- if (!isValid)
- return;
-
- if (util.isFakeEntry(directory)) {
- // Can't save a file into a fake directory.
- return;
- }
-
- var selectFileAndClose = function() {
- this.selectFilesAndClose_({
- urls: [currentDirUrl + encodeURIComponent(filename)],
- multiple: false,
- filterIndex: this.getSelectedFilterIndex_(filename)
- });
- }.bind(this);
-
- directory.getFile(
- filename, {create: false},
- function(entry) {
- // An existing file is found. Show confirmation dialog to
- // overwrite it. If the user select "OK" on the dialog, save it.
- this.confirm.show(strf('CONFIRM_OVERWRITE_FILE', filename),
- selectFileAndClose);
- }.bind(this),
- function(error) {
- if (error.code == FileError.NOT_FOUND_ERR) {
- // The file does not exist, so it should be ok to create a
- // new file.
- selectFileAndClose();
- return;
- }
- if (error.code == FileError.TYPE_MISMATCH_ERR) {
- // An directory is found.
- // Do not allow to overwrite directory.
- this.alert.show(strf('DIRECTORY_ALREADY_EXISTS', filename));
- return;
- }
-
- // Unexpected error.
- console.error('File save failed: ' + error.code);
- }.bind(this));
- }.bind(this));
- return;
- }
-
- var files = [];
- var selectedIndexes = this.currentList_.selectionModel.selectedIndexes;
-
- if (DialogType.isFolderDialog(this.dialogType) &&
- selectedIndexes.length == 0) {
- var url = this.getCurrentDirectoryURL();
- var singleSelection = {
- urls: [url],
- multiple: false,
- filterIndex: this.getSelectedFilterIndex_()
- };
- this.selectFilesAndClose_(singleSelection);
- return;
- }
-
- // All other dialog types require at least one selected list item.
- // The logic to control whether or not the ok button is enabled should
- // prevent us from ever getting here, but we sanity check to be sure.
- if (!selectedIndexes.length)
- throw new Error('Nothing selected!');
-
- var dm = this.directoryModel_.getFileList();
- for (var i = 0; i < selectedIndexes.length; i++) {
- var entry = dm.item(selectedIndexes[i]);
- if (!entry) {
- console.error('Error locating selected file at index: ' + i);
- continue;
- }
-
- files.push(entry.toURL());
- }
-
- // Multi-file selection has no other restrictions.
- if (this.dialogType == DialogType.SELECT_OPEN_MULTI_FILE) {
- var multipleSelection = {
- urls: files,
- multiple: true
- };
- this.selectFilesAndClose_(multipleSelection);
- return;
- }
-
- // Everything else must have exactly one.
- if (files.length > 1)
- throw new Error('Too many files selected!');
-
- var selectedEntry = dm.item(selectedIndexes[0]);
-
- if (DialogType.isFolderDialog(this.dialogType)) {
- if (!selectedEntry.isDirectory)
- throw new Error('Selected entry is not a folder!');
- } else if (this.dialogType == DialogType.SELECT_OPEN_FILE) {
- if (!selectedEntry.isFile)
- throw new Error('Selected entry is not a file!');
- }
-
- var singleSelection = {
- urls: [files[0]],
- multiple: false,
- filterIndex: this.getSelectedFilterIndex_()
- };
- this.selectFilesAndClose_(singleSelection);
- };
-
- /**
- * Verifies the user entered name for file or folder to be created or
- * renamed to. Name restrictions must correspond to File API restrictions
- * (see DOMFilePath::isValidPath). Curernt WebKit implementation is
- * out of date (spec is
- * http://dev.w3.org/2009/dap/file-system/file-dir-sys.html, 8.3) and going to
- * be fixed. Shows message box if the name is invalid.
- *
- * It also verifies if the name length is in the limit of the filesystem.
- *
- * @param {string} parentUrl The URL of the parent directory entry.
- * @param {string} name New file or folder name.
- * @param {function} onDone Function to invoke when user closes the
- * warning box or immediatelly if file name is correct. If the name was
- * valid it is passed true, and false otherwise.
- * @private
- */
- FileManager.prototype.validateFileName_ = function(parentUrl, name, onDone) {
- var msg;
- var testResult = /[\/\\\<\>\:\?\*\"\|]/.exec(name);
- if (testResult) {
- msg = strf('ERROR_INVALID_CHARACTER', testResult[0]);
- } else if (/^\s*$/i.test(name)) {
- msg = str('ERROR_WHITESPACE_NAME');
- } else if (/^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$/i.test(name)) {
- msg = str('ERROR_RESERVED_NAME');
- } else if (this.fileFilter_.isFilterHiddenOn() && name[0] == '.') {
- msg = str('ERROR_HIDDEN_NAME');
- }
-
- if (msg) {
- this.alert.show(msg, function() {
- onDone(false);
- });
- return;
- }
-
- var self = this;
- chrome.fileBrowserPrivate.validatePathNameLength(
- parentUrl, name, function(valid) {
- if (!valid) {
- self.alert.show(str('ERROR_LONG_NAME'),
- function() { onDone(false); });
- } else {
- onDone(true);
- }
- });
- };
-
- /**
- * Handler invoked on preference setting in drive context menu.
- *
- * @param {string} pref The preference to alter.
- * @param {boolean} inverted Invert the value if true.
- * @param {Event} event The click event.
- * @private
- */
- FileManager.prototype.onDrivePrefClick_ = function(pref, inverted, event) {
- var newValue = !event.target.hasAttribute('checked');
- if (newValue)
- event.target.setAttribute('checked', 'checked');
- else
- event.target.removeAttribute('checked');
-
- var changeInfo = {};
- changeInfo[pref] = inverted ? !newValue : newValue;
- chrome.fileBrowserPrivate.setPreferences(changeInfo);
- };
-
- /**
- * Invoked when the search box is changed.
- *
- * @param {Event} event The changed event.
- * @private
- */
- FileManager.prototype.onSearchBoxUpdate_ = function(event) {
- var searchString = this.searchBox_.value;
-
- if (this.isOnDrive()) {
- // When the search text is changed, finishes the search and showes back
- // the last directory by passing an empty string to
- // {@code DirectoryModel.search()}.
- if (this.directoryModel_.isSearching() &&
- this.lastSearchQuery_ != searchString) {
- this.doSearch('');
- }
-
- // On drive, incremental search is not invoked since we have an auto-
- // complete suggestion instead.
- return;
- }
-
- this.search_(searchString);
- };
-
- /**
- * Handle the search clear button click.
- * @private
- */
- FileManager.prototype.onSearchClearButtonClick_ = function() {
- this.ui_.searchBox.clear();
- this.onSearchBoxUpdate_();
- };
-
- /**
- * Search files and update the list with the search result.
- *
- * @param {string} searchString String to be searched with.
- * @private
- */
- FileManager.prototype.search_ = function(searchString) {
- var noResultsDiv = this.document_.getElementById('no-search-results');
-
- var reportEmptySearchResults = function() {
- if (this.directoryModel_.getFileList().length === 0) {
- // The string 'SEARCH_NO_MATCHING_FILES_HTML' may contain HTML tags,
- // hence we escapes |searchString| here.
- var html = strf('SEARCH_NO_MATCHING_FILES_HTML',
- util.htmlEscape(searchString));
- noResultsDiv.innerHTML = html;
- noResultsDiv.setAttribute('show', 'true');
- } else {
- noResultsDiv.removeAttribute('show');
- }
- };
-
- var hideNoResultsDiv = function() {
- noResultsDiv.removeAttribute('show');
- };
-
- this.doSearch(searchString,
- reportEmptySearchResults.bind(this),
- hideNoResultsDiv.bind(this));
- };
-
- /**
- * Performs search and displays results.
- *
- * @param {string} query Query that will be searched for.
- * @param {function()=} opt_onSearchRescan Function that will be called when
- * the search directory is rescanned (i.e. search results are displayed).
- * @param {function()=} opt_onClearSearch Function to be called when search
- * state gets cleared.
- */
- FileManager.prototype.doSearch = function(
- searchString, opt_onSearchRescan, opt_onClearSearch) {
- var onSearchRescan = opt_onSearchRescan || function() {};
- var onClearSearch = opt_onClearSearch || function() {};
-
- this.lastSearchQuery_ = searchString;
- this.directoryModel_.search(searchString, onSearchRescan, onClearSearch);
- };
-
- /**
- * Requests autocomplete suggestions for files on Drive.
- * Once the suggestions are returned, the autocomplete popup will show up.
- *
- * @param {string} query The text to autocomplete from.
- * @private
- */
- FileManager.prototype.requestAutocompleteSuggestions_ = function(query) {
- query = query.trimLeft();
-
- // Only Drive supports auto-compelete
- if (!this.isOnDrive())
- return;
-
- // Remember the most recent query. If there is an other request in progress,
- // then it's result will be discarded and it will call a new request for
- // this query.
- this.lastAutocompleteQuery_ = query;
- if (this.autocompleteSuggestionsBusy_)
- return;
-
- // The autocomplete list should be resized and repositioned here as the
- // search box is resized when it's focused.
- this.autocompleteList_.syncWidthAndPositionToInput();
-
- if (!query) {
- this.autocompleteList_.suggestions = [];
- return;
- }
-
- var headerItem = {isHeaderItem: true, searchQuery: query};
- if (!this.autocompleteList_.dataModel ||
- this.autocompleteList_.dataModel.length == 0)
- this.autocompleteList_.suggestions = [headerItem];
- else
- // Updates only the head item to prevent a flickering on typing.
- this.autocompleteList_.dataModel.splice(0, 1, headerItem);
-
- this.autocompleteSuggestionsBusy_ = true;
-
- var searchParams = {
- 'query': query,
- 'types': 'ALL',
- 'maxResults': 4
- };
- chrome.fileBrowserPrivate.searchDriveMetadata(
- searchParams,
- function(suggestions) {
- this.autocompleteSuggestionsBusy_ = false;
-
- // Discard results for previous requests and fire a new search
- // for the most recent query.
- if (query != this.lastAutocompleteQuery_) {
- this.requestAutocompleteSuggestions_(this.lastAutocompleteQuery_);
- return;
- }
-
- // Keeps the items in the suggestion list.
- this.autocompleteList_.suggestions = [headerItem].concat(suggestions);
- }.bind(this));
- };
-
- /**
- * Opens the currently selected suggestion item.
- * @private
- */
- FileManager.prototype.openAutocompleteSuggestion_ = function() {
- var selectedItem = this.autocompleteList_.selectedItem;
-
- // If the entry is the search item or no entry is selected, just change to
- // the search result.
- if (!selectedItem || selectedItem.isHeaderItem) {
- var query = selectedItem ?
- selectedItem.searchQuery : this.searchBox_.value;
- this.search_(query);
- return;
- }
-
- var entry = selectedItem.entry;
- // If the entry is a directory, just change the directory.
- if (entry.isDirectory) {
- this.onDirectoryAction_(entry);
- return;
- }
-
- var entries = [entry];
- var self = this;
-
- // To open a file, first get the mime type.
- this.metadataCache_.get(entries, 'drive', function(props) {
- var mimeType = props[0].contentMimeType || '';
- var mimeTypes = [mimeType];
- var openIt = function() {
- if (self.dialogType == DialogType.FULL_PAGE) {
- var tasks = new FileTasks(self);
- tasks.init(entries, mimeTypes);
- tasks.executeDefault();
- } else {
- self.onOk_();
- }
- };
-
- // Change the current directory to the directory that contains the
- // selected file. Note that this is necessary for an image or a video,
- // which should be opened in the gallery mode, as the gallery mode
- // requires the entry to be in the current directory model. For
- // consistency, the current directory is always changed regardless of
- // the file type.
- entry.getParent(function(parent) {
- var onDirectoryChanged = function(event) {
- self.directoryModel_.removeEventListener('scan-completed',
- onDirectoryChanged);
- self.directoryModel_.selectEntry(entry);
- openIt();
- };
- // changeDirectory() returns immediately. We should wait until the
- // directory scan is complete.
- self.directoryModel_.addEventListener('scan-completed',
- onDirectoryChanged);
- self.directoryModel_.changeDirectory(
- parent.fullPath,
- function() {
- // Remove the listner if the change directory failed.
- self.directoryModel_.removeEventListener('scan-completed',
- onDirectoryChanged);
- });
- });
- });
- };
-
- FileManager.prototype.decorateSplitter = function(splitterElement) {
- var self = this;
-
- var Splitter = cr.ui.Splitter;
-
- var customSplitter = cr.ui.define('div');
-
- customSplitter.prototype = {
- __proto__: Splitter.prototype,
-
- handleSplitterDragStart: function(e) {
- Splitter.prototype.handleSplitterDragStart.apply(this, arguments);
- this.ownerDocument.documentElement.classList.add('col-resize');
- },
-
- handleSplitterDragMove: function(deltaX) {
- Splitter.prototype.handleSplitterDragMove.apply(this, arguments);
- self.onResize_();
- },
-
- handleSplitterDragEnd: function(e) {
- Splitter.prototype.handleSplitterDragEnd.apply(this, arguments);
- this.ownerDocument.documentElement.classList.remove('col-resize');
- }
- };
-
- customSplitter.decorate(splitterElement);
- };
-
- /**
- * Updates default action menu item to match passed taskItem (icon,
- * label and action).
- *
- * @param {Object} defaultItem - taskItem to match.
- * @param {boolean} isMultiple - if multiple tasks available.
- */
- FileManager.prototype.updateContextMenuActionItems = function(defaultItem,
- isMultiple) {
- if (defaultItem) {
- if (defaultItem.iconType) {
- this.defaultActionMenuItem_.style.backgroundImage = '';
- this.defaultActionMenuItem_.setAttribute('file-type-icon',
- defaultItem.iconType);
- } else if (defaultItem.iconUrl) {
- this.defaultActionMenuItem_.style.backgroundImage =
- 'url(' + defaultItem.iconUrl + ')';
- } else {
- this.defaultActionMenuItem_.style.backgroundImage = '';
- }
-
- this.defaultActionMenuItem_.label = defaultItem.title;
- this.defaultActionMenuItem_.disabled = !!defaultItem.disabled;
- this.defaultActionMenuItem_.taskId = defaultItem.taskId;
- }
-
- var defaultActionSeparator =
- this.dialogDom_.querySelector('#default-action-separator');
-
- this.openWithCommand_.canExecuteChange();
- this.openWithCommand_.setHidden(!(defaultItem && isMultiple));
- this.openWithCommand_.disabled = defaultItem && !!defaultItem.disabled;
-
- this.defaultActionMenuItem_.hidden = !defaultItem;
- defaultActionSeparator.hidden = !defaultItem;
- };
-
- /**
- * Window beforeunload handler.
- * @return {string} Message to show. Ignored when running as a packaged app.
- * @private
- */
- FileManager.prototype.onBeforeUnload_ = function() {
- if (this.filePopup_ &&
- this.filePopup_.contentWindow &&
- this.filePopup_.contentWindow.beforeunload) {
- // The gallery might want to prevent the unload if it is busy.
- return this.filePopup_.contentWindow.beforeunload();
- }
- return null;
- };
-
- /**
- * @return {FileSelection} Selection object.
- */
- FileManager.prototype.getSelection = function() {
- return this.selectionHandler_.selection;
- };
-
- /**
- * @return {ArrayDataModel} File list.
- */
- FileManager.prototype.getFileList = function() {
- return this.directoryModel_.getFileList();
- };
-
- /**
- * @return {cr.ui.List} Current list object.
- */
- FileManager.prototype.getCurrentList = function() {
- return this.currentList_;
- };
-
- /**
- * Retrieve the preferences of the files.app. This method caches the result
- * and returns it unless opt_update is true.
- * @param {function(Object.<string, *>)} callback Callback to get the
- * preference.
- * @param {boolean=} opt_update If is's true, don't use the cache and
- * retrieve latest preference. Default is false.
- * @private
- */
- FileManager.prototype.getPreferences_ = function(callback, opt_update) {
- if (!opt_update && this.preferences_ !== undefined) {
- callback(this.preferences_);
- return;
- }
-
- chrome.fileBrowserPrivate.getPreferences(function(prefs) {
- this.preferences_ = prefs;
- callback(prefs);
- }.bind(this));
- };
-})();
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/file_manager_commands.js b/chromium/chrome/browser/resources/file_manager/foreground/js/file_manager_commands.js
deleted file mode 100644
index 52a26b92a64..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/file_manager_commands.js
+++ /dev/null
@@ -1,828 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * TODO(dzvorygin): Here we use this hack, since 'hidden' is standard
- * attribute and we can't use it's setter as usual.
- * @param {boolean} value New value of hidden property.
- */
-cr.ui.Command.prototype.setHidden = function(value) {
- this.__lookupSetter__('hidden').call(this, value);
-};
-
-/**
- * A command.
- * @interface
- */
-var Command = function() {};
-
-/**
- * Handles the execute event.
- * @param {Event} event Command event.
- * @param {FileManager} fileManager FileManager.
- */
-Command.prototype.execute = function(event, fileManager) {};
-
-/**
- * Handles the can execute event.
- * @param {Event} event Can execute event.
- * @param {FileManager} fileManager FileManager.
- */
-Command.prototype.canExecute = function(event, fileManager) {};
-
-/**
- * Utility for commands.
- */
-var CommandUtil = {};
-
-/**
- * Extracts entry on which command event was dispatched.
- *
- * @param {DirectoryTree|DirectoryItem|NavigationList|HTMLLIElement|cr.ui.List}
- * element Directory to extract a path from.
- * @return {Entry} Entry of the found node.
- */
-CommandUtil.getCommandEntry = function(element) {
- if (element instanceof NavigationList) {
- // element is a NavigationList.
-
- /** @type {NavigationModelItem} */
- var selectedItem = element.selectedItem;
- return selectedItem && selectedItem.getCachedEntry();
- } else if (element instanceof NavigationListItem) {
- // element is a subitem of NavigationList.
- /** @type {NavigationList} */
- var navigationList = element.parentElement;
- var index = navigationList.getIndexOfListItem(element);
- /** @type {NavigationModelItem} */
- var item = (index != -1) ? navigationList.dataModel.item(index) : null;
- return item && item.getCachedEntry();
- } else if (element instanceof DirectoryTree) {
- // element is a DirectoryTree.
- return element.selectedItem;
- } else if (element instanceof DirectoryItem) {
- // element is a sub item in DirectoryTree.
-
- // DirectoryItem.fullPath is set on initialization, but entry is lazily.
- // We may use fullPath just in case that the entry has not been set yet.
- return element.entry;
- } else if (element instanceof cr.ui.List) {
- // element is a normal List (eg. the file list on the right panel).
- var entry = element.selectedItem;
- // Check if it is Entry or not by referring the fullPath member variable.
- return entry && entry.fullPath ? entry : null;
- } else {
- console.warn('Unsupported element');
- return null;
- }
-};
-
-/**
- * @param {NavigationList} navigationList navigation list to extract root node.
- * @return {?RootType} Type of the found root.
- */
-CommandUtil.getCommandRootType = function(navigationList) {
- var root = CommandUtil.getCommandEntry(navigationList);
- return root &&
- PathUtil.isRootPath(root.fullPath) &&
- PathUtil.getRootType(root.fullPath);
-};
-
-/**
- * Checks if command can be executed on drive.
- * @param {Event} event Command event to mark.
- * @param {FileManager} fileManager FileManager to use.
- */
-CommandUtil.canExecuteEnabledOnDriveOnly = function(event, fileManager) {
- event.canExecute = fileManager.isOnDrive();
-};
-
-/**
- * Checks if command should be visible on drive.
- * @param {Event} event Command event to mark.
- * @param {FileManager} fileManager FileManager to use.
- */
-CommandUtil.canExecuteVisibleOnDriveOnly = function(event, fileManager) {
- event.canExecute = fileManager.isOnDrive();
- event.command.setHidden(!fileManager.isOnDrive());
-};
-
-/**
- * Sets as the command as always enabled.
- * @param {Event} event Command event to mark.
- */
-CommandUtil.canExecuteAlways = function(event) {
- event.canExecute = true;
-};
-
-/**
- * Returns a single selected/passed entry or null.
- * @param {Event} event Command event.
- * @param {FileManager} fileManager FileManager to use.
- * @return {FileEntry} The entry or null.
- */
-CommandUtil.getSingleEntry = function(event, fileManager) {
- if (event.target.entry) {
- return event.target.entry;
- }
- var selection = fileManager.getSelection();
- if (selection.totalCount == 1) {
- return selection.entries[0];
- }
- return null;
-};
-
-/**
- * Obtains target entries that can be pinned from the selection.
- * If directories are included in the selection, it just returns an empty
- * array to avoid confusing because pinning directory is not supported
- * currently.
- *
- * @return {Array.<Entry>} Target entries.
- */
-CommandUtil.getPinTargetEntries = function() {
- var hasDirectory = false;
- var results = fileManager.getSelection().entries.filter(function(entry) {
- hasDirectory = hasDirectory || entry.isDirectory;
- if (!entry || hasDirectory)
- return false;
- var metadata = fileManager.metadataCache_.getCached(entry, 'drive');
- if (!metadata || metadata.hosted)
- return false;
- entry.pinned = metadata.pinned;
- return true;
- });
- return hasDirectory ? [] : results;
-};
-
-/**
- * Sets the default handler for the commandId and prevents handling
- * the keydown events for this command. Not doing that breaks relationship
- * of original keyboard event and the command. WebKit would handle it
- * differently in some cases.
- * @param {Node} node to register command handler on.
- * @param {string} commandId Command id to respond to.
- */
-CommandUtil.forceDefaultHandler = function(node, commandId) {
- var doc = node.ownerDocument;
- var command = doc.querySelector('command[id="' + commandId + '"]');
- node.addEventListener('keydown', function(e) {
- if (command.matchesEvent(e)) {
- // Prevent cr.ui.CommandManager of handling it and leave it
- // for the default handler.
- e.stopPropagation();
- }
- });
- node.addEventListener('command', function(event) {
- if (event.command.id !== commandId)
- return;
- document.execCommand(event.command.id);
- event.cancelBubble = true;
- });
- node.addEventListener('canExecute', function(event) {
- if (event.command.id === commandId)
- event.canExecute = document.queryCommandEnabled(event.command.id);
- });
-};
-
-/**
- * Default command.
- * @type {Command}
- */
-CommandUtil.defaultCommand = {
- execute: function(event, fileManager) {
- fileManager.document.execCommand(event.command.id);
- },
- canExecute: function(event, fileManager) {
- event.canExecute = fileManager.document.queryCommandEnabled(
- event.command.id);
- }
-};
-
-/**
- * Creates the volume switch command with index.
- * @param {number} index Volume index from 1 to 9.
- * @return {Command} Volume switch command.
- */
-CommandUtil.createVolumeSwitchCommand = function(index) {
- return {
- execute: function(event, fileManager) {
- fileManager.navigationList.selectByIndex(index - 1);
- },
- canExecute: function(event, fileManager) {
- event.canExecute = index > 0 &&
- index <= fileManager.navigationList.dataModel.length;
- }
- };
-};
-
-/**
- * Handle of the command events.
- * @param {FileManager} fileManager FileManager.
- * @constructor
- */
-var CommandHandler = function(fileManager) {
- /**
- * FileManager.
- * @type {FileManager}
- * @private
- */
- this.fileManager_ = fileManager;
-
- /**
- * Command elements.
- * @type {Object.<string, cr.ui.Command>}
- * @private
- */
- this.commands_ = {};
-
- /**
- * Whether the ctrl key is pressed or not.
- * @type {boolean}
- * @private
- */
- this.ctrlKeyPressed_ = false;
-
- Object.seal(this);
-
- // Decorate command tags in the document.
- var commands = fileManager.document.querySelectorAll('command');
- for (var i = 0; i < commands.length; i++) {
- cr.ui.Command.decorate(commands[i]);
- this.commands_[commands[i].id] = commands[i];
- }
-
- // Register events.
- fileManager.document.addEventListener('command', this.onCommand_.bind(this));
- fileManager.document.addEventListener('canExecute',
- this.onCanExecute_.bind(this));
- fileManager.document.addEventListener('keydown', this.onKeyDown_.bind(this));
- fileManager.document.addEventListener('keyup', this.onKeyUp_.bind(this));
-};
-
-/**
- * Updates the availability of all commands.
- */
-CommandHandler.prototype.updateAvailability = function() {
- for (var id in this.commands_) {
- this.commands_[id].canExecuteChange();
- }
-};
-
-/**
- * Checks if the handler should ignore the current event, eg. since there is
- * a popup dialog currently opened.
- *
- * @return {boolean} True if the event should be ignored, false otherwise.
- * @private
- */
-CommandHandler.prototype.shouldIgnoreEvents_ = function() {
- // Do not handle commands, when a dialog is shown.
- if (this.fileManager_.document.querySelector('.cr-dialog-container.shown'))
- return true;
-
- return false; // Do not ignore.
-};
-
-/**
- * Handles command events.
- * @param {Event} event Command event.
- * @private
- */
-CommandHandler.prototype.onCommand_ = function(event) {
- if (this.shouldIgnoreEvents_())
- return;
- var handler = CommandHandler.COMMANDS_[event.command.id];
- handler.execute.call(this, event, this.fileManager_);
-};
-
-/**
- * Handles canExecute events.
- * @param {Event} event Can execute event.
- * @private
- */
-CommandHandler.prototype.onCanExecute_ = function(event) {
- if (this.shouldIgnoreEvents_())
- return;
- var handler = CommandHandler.COMMANDS_[event.command.id];
- handler.canExecute.call(this, event, this.fileManager_);
-};
-
-/**
- * Handle key down event.
- * @param {Event} event Key down event.
- * @private
- */
-CommandHandler.prototype.onKeyDown_ = function(event) {
- // 17 is the keycode of Ctrl key and it means the event is not for other keys
- // with Ctrl modifier but for ctrl key itself.
- if (util.getKeyModifiers(event) + event.keyCode == 'Ctrl-17') {
- this.ctrlKeyPressed_ = true;
- this.updateAvailability();
- }
-};
-
-/**
- * Handle key up event.
- * @param {Event} event Key up event.
- * @private
- */
-CommandHandler.prototype.onKeyUp_ = function(event) {
- // 17 is the keycode of Ctrl key and it means the event is not for other keys
- // with Ctrl modifier but for ctrl key itself.
- if (util.getKeyModifiers(event) + event.keyCode == '17') {
- this.ctrlKeyPressed_ = false;
- this.updateAvailability();
- }
-};
-
-/**
- * Commands.
- * @type {Object.<string, Command>}
- * @const
- * @private
- */
-CommandHandler.COMMANDS_ = {};
-
-/**
- * Unmounts external drive.
- * @type {Command}
- */
-CommandHandler.COMMANDS_['unmount'] = {
- /**
- * @param {Event} event Command event.
- * @param {FileManager} fileManager The file manager instance.
- */
- execute: function(event, fileManager) {
- var root = CommandUtil.getCommandEntry(event.target);
- if (root)
- fileManager.unmountVolume(PathUtil.getRootPath(root.fullPath));
- },
- /**
- * @param {Event} event Command event.
- */
- canExecute: function(event, fileManager) {
- var rootType = CommandUtil.getCommandRootType(event.target);
-
- event.canExecute = (rootType == RootType.ARCHIVE ||
- rootType == RootType.REMOVABLE);
- event.command.setHidden(!event.canExecute);
- event.command.label = rootType == RootType.ARCHIVE ?
- str('CLOSE_ARCHIVE_BUTTON_LABEL') :
- str('UNMOUNT_DEVICE_BUTTON_LABEL');
- }
-};
-
-/**
- * Formats external drive.
- * @type {Command}
- */
-CommandHandler.COMMANDS_['format'] = {
- /**
- * @param {Event} event Command event.
- * @param {FileManager} fileManager The file manager instance.
- */
- execute: function(event, fileManager) {
- var directoryModel = fileManager.directoryModel;
- var root = CommandUtil.getCommandEntry(event.target);
- // If an entry is not found from the event target, use the current
- // directory. This can happen for the format button for unsupported and
- // unrecognized volumes.
- if (!root)
- root = directoryModel.getCurrentDirEntry();
-
- // TODO(satorux): Stop assuming fullPath to be unique. crbug.com/320967
- var mountPath = root.fullPath;
- var volumeInfo = fileManager.volumeManager.getVolumeInfo(mountPath);
- if (volumeInfo) {
- fileManager.confirm.show(
- loadTimeData.getString('FORMATTING_WARNING'),
- chrome.fileBrowserPrivate.formatVolume.bind(null,
- volumeInfo.volumeId));
- }
- },
- /**
- * @param {Event} event Command event.
- * @param {FileManager} fileManager The file manager instance.
- */
- canExecute: function(event, fileManager) {
- var directoryModel = fileManager.directoryModel;
- var root = CommandUtil.getCommandEntry(event.target);
- // See the comment in execute() for why doing this.
- if (!root)
- root = directoryModel.getCurrentDirEntry();
- var removable = root &&
- PathUtil.getRootType(root.fullPath) == RootType.REMOVABLE;
- // Don't check if the volume is read-only. Unformatted volume is
- // considered read-only per directoryModel.isPathReadOnly(), but can be
- // formatted. An error will be raised if formatting failed anyway.
- event.canExecute = removable;
- event.command.setHidden(!removable);
- }
-};
-
-/**
- * Initiates new folder creation.
- * @type {Command}
- */
-CommandHandler.COMMANDS_['new-folder'] = {
- execute: function(event, fileManager) {
- fileManager.createNewFolder();
- },
- canExecute: function(event, fileManager) {
- var directoryModel = fileManager.directoryModel;
- event.canExecute = !fileManager.isOnReadonlyDirectory() &&
- !fileManager.isRenamingInProgress() &&
- !directoryModel.isSearching() &&
- !directoryModel.isScanning();
- }
-};
-
-/**
- * Initiates new window creation.
- * @type {Command}
- */
-CommandHandler.COMMANDS_['new-window'] = {
- execute: function(event, fileManager) {
- fileManager.backgroundPage.launchFileManager({
- defaultPath: fileManager.getCurrentDirectory()
- });
- },
- canExecute: function(event, fileManager) {
- event.canExecute =
- fileManager.getCurrentDirectoryEntry() &&
- (fileManager.dialogType === DialogType.FULL_PAGE);
- }
-};
-
-/**
- * Deletes selected files.
- * @type {Command}
- */
-CommandHandler.COMMANDS_['delete'] = {
- execute: function(event, fileManager) {
- fileManager.deleteSelection();
- },
- canExecute: function(event, fileManager) {
- var allowDeletingWhileOffline =
- fileManager.directoryModel.getCurrentRootType() === RootType.DRIVE;
- var selection = fileManager.getSelection();
- event.canExecute = (!fileManager.isOnReadonlyDirectory() ||
- allowDeletingWhileOffline) &&
- selection &&
- selection.totalCount > 0;
- }
-};
-
-/**
- * Pastes files from clipboard.
- * @type {Command}
- */
-CommandHandler.COMMANDS_['paste'] = {
- execute: function() {
- document.execCommand(event.command.id);
- },
- canExecute: function(event, fileManager) {
- var document = fileManager.document;
- var fileTransferController = fileManager.fileTransferController;
- event.canExecute = (fileTransferController &&
- fileTransferController.queryPasteCommandEnabled());
- }
-};
-
-CommandHandler.COMMANDS_['cut'] = CommandUtil.defaultCommand;
-CommandHandler.COMMANDS_['copy'] = CommandUtil.defaultCommand;
-
-/**
- * Initiates file renaming.
- * @type {Command}
- */
-CommandHandler.COMMANDS_['rename'] = {
- execute: function(event, fileManager) {
- fileManager.initiateRename();
- },
- canExecute: function(event, fileManager) {
- var allowRenamingWhileOffline =
- fileManager.directoryModel.getCurrentRootType() === RootType.DRIVE;
- var selection = fileManager.getSelection();
- event.canExecute =
- !fileManager.isRenamingInProgress() &&
- (!fileManager.isOnReadonlyDirectory() || allowRenamingWhileOffline) &&
- selection &&
- selection.totalCount == 1;
- }
-};
-
-/**
- * Opens drive help.
- * @type {Command}
- */
-CommandHandler.COMMANDS_['volume-help'] = {
- execute: function(event, fileManager) {
- if (fileManager.isOnDrive())
- util.visitURL(str('GOOGLE_DRIVE_HELP_URL'));
- else
- util.visitURL(str('FILES_APP_HELP_URL'));
- },
- canExecute: CommandUtil.canExecuteAlways
-};
-
-/**
- * Opens drive buy-more-space url.
- * @type {Command}
- */
-CommandHandler.COMMANDS_['drive-buy-more-space'] = {
- execute: function(event, fileManager) {
- util.visitURL(str('GOOGLE_DRIVE_BUY_STORAGE_URL'));
- },
- canExecute: CommandUtil.canExecuteVisibleOnDriveOnly
-};
-
-/**
- * Opens drive.google.com.
- * @type {Command}
- */
-CommandHandler.COMMANDS_['drive-go-to-drive'] = {
- execute: function(event, fileManager) {
- util.visitURL(str('GOOGLE_DRIVE_ROOT_URL'));
- },
- canExecute: CommandUtil.canExecuteVisibleOnDriveOnly
-};
-
-/**
- * Displays open with dialog for current selection.
- * @type {Command}
- */
-CommandHandler.COMMANDS_['open-with'] = {
- execute: function(event, fileManager) {
- var tasks = fileManager.getSelection().tasks;
- if (tasks) {
- tasks.showTaskPicker(fileManager.defaultTaskPicker,
- str('OPEN_WITH_BUTTON_LABEL'),
- null,
- function(task) {
- tasks.execute(task.taskId);
- });
- }
- },
- canExecute: function(event, fileManager) {
- var tasks = fileManager.getSelection().tasks;
- event.canExecute = tasks && tasks.size() > 1;
- }
-};
-
-/**
- * Focuses search input box.
- * @type {Command}
- */
-CommandHandler.COMMANDS_['search'] = {
- execute: function(event, fileManager) {
- var element = fileManager.document.querySelector('#search-box input');
- element.focus();
- element.select();
- },
- canExecute: function(event, fileManager) {
- event.canExecute = !fileManager.isRenamingInProgress();
- }
-};
-
-/**
- * Activates the n-th volume.
- * @type {Command}
- */
-CommandHandler.COMMANDS_['volume-switch-1'] =
- CommandUtil.createVolumeSwitchCommand(1);
-CommandHandler.COMMANDS_['volume-switch-2'] =
- CommandUtil.createVolumeSwitchCommand(2);
-CommandHandler.COMMANDS_['volume-switch-3'] =
- CommandUtil.createVolumeSwitchCommand(3);
-CommandHandler.COMMANDS_['volume-switch-4'] =
- CommandUtil.createVolumeSwitchCommand(4);
-CommandHandler.COMMANDS_['volume-switch-5'] =
- CommandUtil.createVolumeSwitchCommand(5);
-CommandHandler.COMMANDS_['volume-switch-6'] =
- CommandUtil.createVolumeSwitchCommand(6);
-CommandHandler.COMMANDS_['volume-switch-7'] =
- CommandUtil.createVolumeSwitchCommand(7);
-CommandHandler.COMMANDS_['volume-switch-8'] =
- CommandUtil.createVolumeSwitchCommand(8);
-CommandHandler.COMMANDS_['volume-switch-9'] =
- CommandUtil.createVolumeSwitchCommand(9);
-
-/**
- * Flips 'available offline' flag on the file.
- * @type {Command}
- */
-CommandHandler.COMMANDS_['toggle-pinned'] = {
- execute: function(event, fileManager) {
- var pin = !event.command.checked;
- event.command.checked = pin;
- var entries = CommandUtil.getPinTargetEntries();
- var currentEntry;
- var error = false;
- var steps = {
- // Pick an entry and pin it.
- start: function() {
- // Check if all the entries are pinned or not.
- if (entries.length == 0)
- return;
- currentEntry = entries.shift();
- chrome.fileBrowserPrivate.pinDriveFile(
- currentEntry.toURL(),
- pin,
- steps.entryPinned);
- },
-
- // Check the result of pinning
- entryPinned: function() {
- // Convert to boolean.
- error = !!chrome.runtime.lastError;
- if (error && pin) {
- fileManager.metadataCache_.get(
- currentEntry, 'filesystem', steps.showError);
- }
- fileManager.metadataCache_.clear(currentEntry, 'drive');
- fileManager.metadataCache_.get(
- currentEntry, 'drive', steps.updateUI.bind(this));
- },
-
- // Update the user interface accoding to the cache state.
- updateUI: function(drive) {
- fileManager.updateMetadataInUI_(
- 'drive', [currentEntry.toURL()], [drive]);
- if (!error)
- steps.start();
- },
-
- // Show the error
- showError: function(filesystem) {
- fileManager.alert.showHtml(str('DRIVE_OUT_OF_SPACE_HEADER'),
- strf('DRIVE_OUT_OF_SPACE_MESSAGE',
- unescape(currentEntry.name),
- util.bytesToString(filesystem.size)));
- }
- };
- steps.start();
- },
-
- canExecute: function(event, fileManager) {
- var entries = CommandUtil.getPinTargetEntries();
- var checked = true;
- for (var i = 0; i < entries.length; i++) {
- checked = checked && entries[i].pinned;
- }
- if (entries.length > 0) {
- event.canExecute = true;
- event.command.setHidden(false);
- event.command.checked = checked;
- } else {
- event.canExecute = false;
- event.command.setHidden(true);
- }
- }
-};
-
-/**
- * Creates zip file for current selection.
- * @type {Command}
- */
-CommandHandler.COMMANDS_['zip-selection'] = {
- execute: function(event, fileManager) {
- var dirEntry = fileManager.getCurrentDirectoryEntry();
- var selectionEntries = fileManager.getSelection().entries;
- fileManager.fileOperationManager_.zipSelection(dirEntry, selectionEntries);
- },
- canExecute: function(event, fileManager) {
- var dirEntry = fileManager.getCurrentDirectoryEntry();
- var selection = fileManager.getSelection();
- event.canExecute =
- dirEntry &&
- !fileManager.isOnReadonlyDirectory() &&
- !fileManager.isOnDrive() &&
- selection && selection.totalCount > 0;
- }
-};
-
-/**
- * Shows the share dialog for the current selection (single only).
- * @type {Command}
- */
-CommandHandler.COMMANDS_['share'] = {
- execute: function(event, fileManager) {
- fileManager.shareSelection();
- },
- canExecute: function(event, fileManager) {
- var selection = fileManager.getSelection();
- event.canExecute = fileManager.isOnDrive() &&
- !fileManager.isDriveOffline() &&
- selection && selection.totalCount == 1;
- event.command.setHidden(!fileManager.isOnDrive());
- }
-};
-
-/**
- * Creates a shortcut of the selected folder (single only).
- * @type {Command}
- */
-CommandHandler.COMMANDS_['create-folder-shortcut'] = {
- /**
- * @param {Event} event Command event.
- * @param {FileManager} fileManager The file manager instance.
- */
- execute: function(event, fileManager) {
- var entry = CommandUtil.getCommandEntry(event.target);
- if (entry)
- fileManager.createFolderShortcut(entry.fullPath);
- },
-
- /**
- * @param {Event} event Command event.
- * @param {FileManager} fileManager The file manager instance.
- */
- canExecute: function(event, fileManager) {
- var entry = CommandUtil.getCommandEntry(event.target);
- var folderShortcutExists = entry &&
- fileManager.folderShortcutExists(entry.fullPath);
-
- var onlyOneFolderSelected = true;
- // Only on list, user can select multiple files. The command is enabled only
- // when a single file is selected.
- if (event.target instanceof cr.ui.List &&
- !(event.target instanceof NavigationList)) {
- var items = event.target.selectedItems;
- onlyOneFolderSelected = (items.length == 1 && items[0].isDirectory);
- }
-
- var eligible = entry &&
- PathUtil.isEligibleForFolderShortcut(entry.fullPath);
- event.canExecute =
- eligible && onlyOneFolderSelected && !folderShortcutExists;
- event.command.setHidden(!eligible || !onlyOneFolderSelected);
- }
-};
-
-/**
- * Removes the folder shortcut.
- * @type {Command}
- */
-CommandHandler.COMMANDS_['remove-folder-shortcut'] = {
- /**
- * @param {Event} event Command event.
- * @param {FileManager} fileManager The file manager instance.
- */
- execute: function(event, fileManager) {
- var entry = CommandUtil.getCommandEntry(event.target);
- if (entry && entry.fullPath)
- fileManager.removeFolderShortcut(entry.fullPath);
- },
-
- /**
- * @param {Event} event Command event.
- * @param {FileManager} fileManager The file manager instance.
- */
- canExecute: function(event, fileManager) {
- var entry = CommandUtil.getCommandEntry(event.target);
- var path = entry && entry.fullPath;
-
- var eligible = path && PathUtil.isEligibleForFolderShortcut(path);
- var isShortcut = path && fileManager.folderShortcutExists(path);
- event.canExecute = isShortcut && eligible;
- event.command.setHidden(!event.canExecute);
- }
-};
-
-/**
- * Zoom in to the Files.app.
- * @type {Command}
- */
-CommandHandler.COMMANDS_['zoom-in'] = {
- execute: function(event, fileManager) {
- chrome.fileBrowserPrivate.zoom('in');
- },
- canExecute: CommandUtil.canExecuteAlways
-};
-
-/**
- * Zoom out from the Files.app.
- * @type {Command}
- */
-CommandHandler.COMMANDS_['zoom-out'] = {
- execute: function(event, fileManager) {
- chrome.fileBrowserPrivate.zoom('out');
- },
- canExecute: CommandUtil.canExecuteAlways
-};
-
-/**
- * Reset the zoom factor.
- * @type {Command}
- */
-CommandHandler.COMMANDS_['zoom-reset'] = {
- execute: function(event, fileManager) {
- chrome.fileBrowserPrivate.zoom('reset');
- },
- canExecute: CommandUtil.canExecuteAlways
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/file_operation_manager_wrapper.js b/chromium/chrome/browser/resources/file_manager/foreground/js/file_operation_manager_wrapper.js
deleted file mode 100644
index 583b9bf549e..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/file_operation_manager_wrapper.js
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * While FileOperationManager is run in the background page, this class is
- * used to communicate with it.
- * @param {DOMWindow} backgroundPage Window object of the background page.
- * @constructor
- */
-function FileOperationManagerWrapper(backgroundPage) {
- this.fileOperationManager_ =
- backgroundPage.FileOperationManager.getInstance();
-}
-
-/**
- * Create a new instance or get existing instance of FCMW.
- * @param {DOMWindow} backgroundPage Window object of the background page.
- * @return {FileOperationManagerWrapper} FileOperationManagerWrapper instance.
- */
-FileOperationManagerWrapper.getInstance = function(backgroundPage) {
- if (!FileOperationManagerWrapper.instance_)
- FileOperationManagerWrapper.instance_ =
- new FileOperationManagerWrapper(backgroundPage);
-
- return FileOperationManagerWrapper.instance_;
-};
-
-/**
- * @return {boolean} True if there is a running task.
- */
-FileOperationManagerWrapper.prototype.isRunning = function() {
- return this.fileOperationManager_.hasQueuedTasks();
-};
-
-/**
- * Decorates a FileOperationManager method, so it will be executed after
- * initializing the FileOperationManager instance in background page.
- * @param {string} method The method name.
- */
-FileOperationManagerWrapper.decorateAsyncMethod = function(method) {
- FileOperationManagerWrapper.prototype[method] = function() {
- this.fileOperationManager_[method].apply(
- this.fileOperationManager_, arguments);
- };
-};
-
-FileOperationManagerWrapper.decorateAsyncMethod('paste');
-FileOperationManagerWrapper.decorateAsyncMethod('deleteEntries');
-FileOperationManagerWrapper.decorateAsyncMethod('forceDeleteTask');
-FileOperationManagerWrapper.decorateAsyncMethod('cancelDeleteTask');
-FileOperationManagerWrapper.decorateAsyncMethod('zipSelection');
-FileOperationManagerWrapper.decorateAsyncMethod('addEventListener');
-FileOperationManagerWrapper.decorateAsyncMethod('removeEventListener');
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/file_selection.js b/chromium/chrome/browser/resources/file_manager/foreground/js/file_selection.js
deleted file mode 100644
index 945a48bfa0e..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/file_selection.js
+++ /dev/null
@@ -1,360 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * The current selection object.
- *
- * @param {FileManager} fileManager FileManager instance.
- * @param {Array.<number>} indexes Selected indexes.
- * @constructor
- */
-function FileSelection(fileManager, indexes) {
- this.fileManager_ = fileManager;
- this.computeBytesSequence_ = 0;
- this.indexes = indexes;
- this.entries = [];
- this.totalCount = 0;
- this.fileCount = 0;
- this.directoryCount = 0;
- this.bytes = 0;
- this.showBytes = false;
- this.allDriveFilesPresent = false,
- this.iconType = null;
- this.bytesKnown = false;
- this.mustBeHidden_ = false;
- this.mimeTypes = null;
-
- // Synchronously compute what we can.
- for (var i = 0; i < this.indexes.length; i++) {
- var entry = fileManager.getFileList().item(this.indexes[i]);
- if (!entry)
- continue;
-
- this.entries.push(entry);
-
- if (this.iconType == null) {
- this.iconType = FileType.getIcon(entry);
- } else if (this.iconType != 'unknown') {
- var iconType = FileType.getIcon(entry);
- if (this.iconType != iconType)
- this.iconType = 'unknown';
- }
-
- if (entry.isFile) {
- this.fileCount += 1;
- } else {
- this.directoryCount += 1;
- }
- this.totalCount++;
- }
-
- this.tasks = new FileTasks(this.fileManager_);
-
- Object.seal(this);
-}
-
-/**
- * Computes data required to get file tasks and requests the tasks.
- *
- * @param {function} callback The callback.
- */
-FileSelection.prototype.createTasks = function(callback) {
- if (!this.fileManager_.isOnDrive()) {
- this.tasks.init(this.entries);
- callback();
- return;
- }
-
- this.fileManager_.metadataCache_.get(this.entries, 'drive', function(props) {
- var present = props.filter(function(p) { return p && p.availableOffline });
- this.allDriveFilesPresent = present.length == props.length;
-
- // Collect all of the mime types and push that info into the selection.
- this.mimeTypes = props.map(function(value) {
- return (value && value.contentMimeType) || '';
- });
-
- this.tasks.init(this.entries, this.mimeTypes);
- callback();
- }.bind(this));
-};
-
-/**
- * Computes the total size of selected files.
- *
- * @param {function} callback Completion callback. Not called when cancelled,
- * or a new call has been invoked in the meantime.
- */
-FileSelection.prototype.computeBytes = function(callback) {
- if (this.entries.length == 0) {
- this.bytesKnown = true;
- this.showBytes = false;
- this.bytes = 0;
- return;
- }
-
- var computeBytesSequence = ++this.computeBytesSequence_;
- var pendingMetadataCount = 0;
-
- var maybeDone = function() {
- if (pendingMetadataCount == 0) {
- this.bytesKnown = true;
- callback();
- }
- }.bind(this);
-
- var onProps = function(properties) {
- // Ignore if the call got cancelled, or there is another new one fired.
- if (computeBytesSequence != this.computeBytesSequence_)
- return;
-
- // It may happen that the metadata is not available because a file has been
- // deleted in the meantime.
- if (properties)
- this.bytes += properties.size;
- pendingMetadataCount--;
- maybeDone();
- }.bind(this);
-
- for (var index = 0; index < this.entries.length; index++) {
- var entry = this.entries[index];
- if (entry.isFile) {
- this.showBytes |= !FileType.isHosted(entry);
- pendingMetadataCount++;
- this.fileManager_.metadataCache_.get(entry, 'filesystem', onProps);
- } else if (entry.isDirectory) {
- // Don't compute the directory size as it's expensive.
- // crbug.com/179073.
- this.showBytes = false;
- break;
- }
- }
- maybeDone();
-};
-
-/**
- * Cancels any async computation by increasing the sequence number. Results
- * of any previous call to computeBytes() will be discarded.
- *
- * @private
- */
-FileSelection.prototype.cancelComputing_ = function() {
- this.computeBytesSequence_++;
-};
-
-/**
- * This object encapsulates everything related to current selection.
- *
- * @param {FileManager} fileManager File manager instance.
- * @extends {cr.EventTarget}
- * @constructor
- */
-function FileSelectionHandler(fileManager) {
- this.fileManager_ = fileManager;
- // TODO(dgozman): create a shared object with most of UI elements.
- this.okButton_ = fileManager.okButton_;
- this.filenameInput_ = fileManager.filenameInput_;
- this.previewPanel_ = fileManager.previewPanel_;
- this.taskItems_ = fileManager.taskItems_;
-}
-
-/**
- * Create the temporary disabled action menu item.
- * @return {Object} Created disabled item.
- * @private
- */
-FileSelectionHandler.createTemporaryDisabledActionMenuItem_ = function() {
- if (!FileSelectionHandler.cachedDisabledActionMenuItem_) {
- FileSelectionHandler.cachedDisabledActionMenuItem_ = {
- label: str('ACTION_OPEN'),
- disabled: true
- };
- }
-
- return FileSelectionHandler.cachedDisabledActionMenuItem_;
-};
-
-/**
- * Cached the temporary disabled action menu item. Used inside
- * FileSelectionHandler.createTemporaryDisabledActionMenuItem_().
- * @private
- */
-FileSelectionHandler.cachedDisabledActionMenuItem_ = null;
-
-/**
- * FileSelectionHandler extends cr.EventTarget.
- */
-FileSelectionHandler.prototype.__proto__ = cr.EventTarget.prototype;
-
-/**
- * Maximum amount of thumbnails in the preview pane.
- *
- * @const
- * @type {number}
- */
-FileSelectionHandler.MAX_PREVIEW_THUMBNAIL_COUNT = 4;
-
-/**
- * Maximum width or height of an image what pops up when the mouse hovers
- * thumbnail in the bottom panel (in pixels).
- *
- * @const
- * @type {number}
- */
-FileSelectionHandler.IMAGE_HOVER_PREVIEW_SIZE = 200;
-
-/**
- * Update the UI when the selection model changes.
- *
- * @param {Event} event The change event.
- */
-FileSelectionHandler.prototype.onFileSelectionChanged = function(event) {
- var indexes =
- this.fileManager_.getCurrentList().selectionModel.selectedIndexes;
- if (this.selection) this.selection.cancelComputing_();
- var selection = new FileSelection(this.fileManager_, indexes);
- this.selection = selection;
-
- if (this.fileManager_.dialogType == DialogType.SELECT_SAVEAS_FILE) {
- // If this is a save-as dialog, copy the selected file into the filename
- // input text box.
- if (this.selection.totalCount == 1 &&
- this.selection.entries[0].isFile &&
- this.filenameInput_.value != this.selection.entries[0].name) {
- this.filenameInput_.value = this.selection.entries[0].name;
- }
- }
-
- this.updateOkButton();
-
- if (this.selectionUpdateTimer_) {
- clearTimeout(this.selectionUpdateTimer_);
- this.selectionUpdateTimer_ = null;
- }
-
- // The rest of the selection properties are computed via (sometimes lengthy)
- // asynchronous calls. We initiate these calls after a timeout. If the
- // selection is changing quickly we only do this once when it slows down.
-
- var updateDelay = 200;
- var now = Date.now();
- if (now > (this.lastFileSelectionTime_ || 0) + updateDelay) {
- // The previous selection change happened a while ago. Update the UI soon.
- updateDelay = 0;
- }
- this.lastFileSelectionTime_ = now;
-
- if (this.fileManager_.dialogType === DialogType.FULL_PAGE &&
- selection.directoryCount === 0 && selection.fileCount > 0) {
- // Show disabled items for position calculation of the menu. They will be
- // overridden in this.updateFileSelectionAsync().
- this.fileManager_.updateContextMenuActionItems(
- FileSelectionHandler.createTemporaryDisabledActionMenuItem_(), true);
- } else {
- // Update context menu.
- this.fileManager_.updateContextMenuActionItems(null, false);
- }
-
- this.selectionUpdateTimer_ = setTimeout(function() {
- this.selectionUpdateTimer_ = null;
- if (this.selection == selection)
- this.updateFileSelectionAsync(selection);
- }.bind(this), updateDelay);
-};
-
-/**
- * Updates the Ok button enabled state.
- *
- * @return {boolean} Whether button is enabled.
- */
-FileSelectionHandler.prototype.updateOkButton = function() {
- var selectable;
- var dialogType = this.fileManager_.dialogType;
-
- if (DialogType.isFolderDialog(dialogType)) {
- // In SELECT_FOLDER mode, we allow to select current directory
- // when nothing is selected.
- selectable = this.selection.directoryCount <= 1 &&
- this.selection.fileCount == 0;
- } else if (dialogType == DialogType.SELECT_OPEN_FILE) {
- selectable = (this.isFileSelectionAvailable() &&
- this.selection.directoryCount == 0 &&
- this.selection.fileCount == 1);
- } else if (dialogType == DialogType.SELECT_OPEN_MULTI_FILE) {
- selectable = (this.isFileSelectionAvailable() &&
- this.selection.directoryCount == 0 &&
- this.selection.fileCount >= 1);
- } else if (dialogType == DialogType.SELECT_SAVEAS_FILE) {
- if (this.fileManager_.isOnReadonlyDirectory()) {
- selectable = false;
- } else {
- selectable = !!this.filenameInput_.value;
- }
- } else if (dialogType == DialogType.FULL_PAGE) {
- // No "select" buttons on the full page UI.
- selectable = true;
- } else {
- throw new Error('Unknown dialog type');
- }
-
- this.okButton_.disabled = !selectable;
- return selectable;
-};
-
-/**
- * Check if all the files in the current selection are available. The only
- * case when files might be not available is when the selection contains
- * uncached Drive files and the browser is offline.
- *
- * @return {boolean} True if all files in the current selection are
- * available.
- */
-FileSelectionHandler.prototype.isFileSelectionAvailable = function() {
- return !this.fileManager_.isOnDrive() ||
- !this.fileManager_.isDriveOffline() ||
- this.selection.allDriveFilesPresent;
-};
-
-/**
- * Calculates async selection stats and updates secondary UI elements.
- *
- * @param {FileSelection} selection The selection object.
- */
-FileSelectionHandler.prototype.updateFileSelectionAsync = function(selection) {
- if (this.selection != selection) return;
-
- // Update the file tasks.
- if (this.fileManager_.dialogType === DialogType.FULL_PAGE &&
- selection.directoryCount === 0 && selection.fileCount > 0) {
- selection.createTasks(function() {
- if (this.selection != selection)
- return;
- selection.tasks.display(this.taskItems_);
- selection.tasks.updateMenuItem();
- }.bind(this));
- } else {
- this.taskItems_.hidden = true;
- }
-
- // Update preview panels.
- var wasVisible = this.previewPanel_.visible;
- this.previewPanel_.setSelection(selection);
-
- // Scroll to item
- if (!wasVisible && this.selection.totalCount == 1) {
- var list = this.fileManager_.getCurrentList();
- list.scrollIndexIntoView(list.selectionModel.selectedIndex);
- }
-
- // Sync the commands availability.
- if (this.fileManager_.commandHandler)
- this.fileManager_.commandHandler.updateAvailability();
-
- // Inform tests it's OK to click buttons now.
- if (selection.totalCount > 0) {
- chrome.test.sendMessage('selection-change-complete');
- }
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/file_table.js b/chromium/chrome/browser/resources/file_manager/foreground/js/file_table.js
deleted file mode 100644
index 3280de32953..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/file_table.js
+++ /dev/null
@@ -1,1036 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Namespace for utility functions.
- */
-var filelist = {};
-
-/**
- * Custom column model for advanced auto-resizing.
- *
- * @param {Array.<cr.ui.table.TableColumn>} tableColumns Table columns.
- * @extends {cr.ui.table.TableColumnModel}
- * @constructor
- */
-function FileTableColumnModel(tableColumns) {
- cr.ui.table.TableColumnModel.call(this, tableColumns);
-}
-
-/**
- * The columns whose index is less than the constant are resizable.
- * @const
- * @type {number}
- * @private
- */
-FileTableColumnModel.RESIZABLE_LENGTH_ = 4;
-
-/**
- * Inherits from cr.ui.TableColumnModel.
- */
-FileTableColumnModel.prototype.__proto__ =
- cr.ui.table.TableColumnModel.prototype;
-
-/**
- * Minimum width of column.
- * @const
- * @type {number}
- * @private
- */
-FileTableColumnModel.MIN_WIDTH_ = 10;
-
-/**
- * Sets column width so that the column dividers move to the specified position.
- * This function also check the width of each column and keep the width larger
- * than MIN_WIDTH_.
- *
- * @private
- * @param {Array.<number>} newPos Positions of each column dividers.
- */
-FileTableColumnModel.prototype.applyColumnPositions_ = function(newPos) {
- // Check the minimum width and adjust the positions.
- for (var i = 0; i < newPos.length - 2; i++) {
- if (newPos[i + 1] - newPos[i] < FileTableColumnModel.MIN_WIDTH_) {
- newPos[i + 1] = newPos[i] + FileTableColumnModel.MIN_WIDTH_;
- }
- }
- for (var i = newPos.length - 1; i >= 2; i--) {
- if (newPos[i] - newPos[i - 1] < FileTableColumnModel.MIN_WIDTH_) {
- newPos[i - 1] = newPos[i] - FileTableColumnModel.MIN_WIDTH_;
- }
- }
- // Set the new width of columns
- for (var i = 0; i < FileTableColumnModel.RESIZABLE_LENGTH_; i++) {
- this.columns_[i].width = newPos[i + 1] - newPos[i];
- }
-};
-
-/**
- * Normalizes widths to make their sum 100% if possible. Uses the proportional
- * approach with some additional constraints.
- *
- * @param {number} contentWidth Target width.
- * @override
- */
-FileTableColumnModel.prototype.normalizeWidths = function(contentWidth) {
- var totalWidth = 0;
- var fixedWidth = 0;
- // Some columns have fixed width.
- for (var i = 0; i < this.columns_.length; i++) {
- if (i < FileTableColumnModel.RESIZABLE_LENGTH_)
- totalWidth += this.columns_[i].width;
- else
- fixedWidth += this.columns_[i].width;
- }
- var newTotalWidth = Math.max(contentWidth - fixedWidth, 0);
- var positions = [0];
- var sum = 0;
- for (var i = 0; i < FileTableColumnModel.RESIZABLE_LENGTH_; i++) {
- var column = this.columns_[i];
- sum += column.width;
- // Faster alternative to Math.floor for non-negative numbers.
- positions[i + 1] = ~~(newTotalWidth * sum / totalWidth);
- }
- this.applyColumnPositions_(positions);
-};
-
-/**
- * Handles to the start of column resizing by splitters.
- */
-FileTableColumnModel.prototype.handleSplitterDragStart = function() {
- this.columnPos_ = [0];
- for (var i = 0; i < this.columns_.length; i++) {
- this.columnPos_[i + 1] = this.columns_[i].width + this.columnPos_[i];
- }
-};
-
-/**
- * Handles to the end of column resizing by splitters.
- */
-FileTableColumnModel.prototype.handleSplitterDragEnd = function() {
- this.columnPos_ = null;
-};
-
-/**
- * Sets the width of column with keeping the total width of table.
- * @param {number} columnIndex Index of column that is resized.
- * @param {number} columnWidth New width of the column.
- */
-FileTableColumnModel.prototype.setWidthAndKeepTotal = function(
- columnIndex, columnWidth) {
- // Skip to resize 'selection' column
- if (columnIndex < 0 ||
- columnIndex >= FileTableColumnModel.RESIZABLE_LENGTH_ ||
- !this.columnPos_) {
- return;
- }
-
- // Calculate new positions of column splitters.
- var newPosStart =
- this.columnPos_[columnIndex] + Math.max(columnWidth,
- FileTableColumnModel.MIN_WIDTH_);
- var newPos = [];
- var posEnd = this.columnPos_[FileTableColumnModel.RESIZABLE_LENGTH_];
- for (var i = 0; i < columnIndex + 1; i++) {
- newPos[i] = this.columnPos_[i];
- }
- for (var i = columnIndex + 1;
- i < FileTableColumnModel.RESIZABLE_LENGTH_;
- i++) {
- var posStart = this.columnPos_[columnIndex + 1];
- newPos[i] = (posEnd - newPosStart) *
- (this.columnPos_[i] - posStart) /
- (posEnd - posStart) +
- newPosStart;
- // Faster alternative to Math.floor for non-negative numbers.
- newPos[i] = ~~newPos[i];
- }
- newPos[columnIndex] = this.columnPos_[columnIndex];
- newPos[FileTableColumnModel.RESIZABLE_LENGTH_] = posEnd;
- this.applyColumnPositions_(newPos);
-
- // Notifiy about resizing
- cr.dispatchSimpleEvent(this, 'resize');
-};
-
-/**
- * Custom splitter that resizes column with retaining the sum of all the column
- * width.
- */
-var FileTableSplitter = cr.ui.define('div');
-
-/**
- * Inherits from cr.ui.TableSplitter.
- */
-FileTableSplitter.prototype.__proto__ = cr.ui.TableSplitter.prototype;
-
-/**
- * Handles the drag start event.
- */
-FileTableSplitter.prototype.handleSplitterDragStart = function() {
- cr.ui.TableSplitter.prototype.handleSplitterDragStart.call(this);
- this.table_.columnModel.handleSplitterDragStart();
-};
-
-/**
- * Handles the drag move event.
- * @param {number} deltaX Horizontal mouse move offset.
- */
-FileTableSplitter.prototype.handleSplitterDragMove = function(deltaX) {
- this.table_.columnModel.setWidthAndKeepTotal(this.columnIndex,
- this.columnWidth_ + deltaX,
- true);
-};
-
-/**
- * Handles the drag end event.
- */
-FileTableSplitter.prototype.handleSplitterDragEnd = function() {
- cr.ui.TableSplitter.prototype.handleSplitterDragEnd.call(this);
- this.table_.columnModel.handleSplitterDragEnd();
-};
-
-/**
- * File list Table View.
- * @constructor
- */
-function FileTable() {
- throw new Error('Designed to decorate elements');
-}
-
-/**
- * Inherits from cr.ui.Table.
- */
-FileTable.prototype.__proto__ = cr.ui.Table.prototype;
-
-/**
- * Decorates the element.
- * @param {HTMLElement} self Table to decorate.
- * @param {MetadataCache} metadataCache To retrieve metadata.
- * @param {boolean} fullPage True if it's full page File Manager,
- * False if a file open/save dialog.
- */
-FileTable.decorate = function(self, metadataCache, fullPage) {
- cr.ui.Table.decorate(self);
- self.__proto__ = FileTable.prototype;
- self.metadataCache_ = metadataCache;
- self.collator_ = Intl.Collator([], {numeric: true, sensitivity: 'base'});
-
- var columns = [
- new cr.ui.table.TableColumn('name', str('NAME_COLUMN_LABEL'),
- fullPage ? 386 : 324),
- new cr.ui.table.TableColumn('size', str('SIZE_COLUMN_LABEL'),
- 110, true),
- new cr.ui.table.TableColumn('type', str('TYPE_COLUMN_LABEL'),
- fullPage ? 110 : 110),
- new cr.ui.table.TableColumn('modificationTime',
- str('DATE_COLUMN_LABEL'),
- fullPage ? 150 : 210)
- ];
-
- columns[0].renderFunction = self.renderName_.bind(self);
- columns[1].renderFunction = self.renderSize_.bind(self);
- columns[1].defaultOrder = 'desc';
- columns[2].renderFunction = self.renderType_.bind(self);
- columns[3].renderFunction = self.renderDate_.bind(self);
- columns[3].defaultOrder = 'desc';
-
- var tableColumnModelClass;
- tableColumnModelClass = FileTableColumnModel;
- if (self.showCheckboxes) {
- columns.push(new cr.ui.table.TableColumn('selection',
- '',
- 50, true));
- columns[4].renderFunction = self.renderSelection_.bind(self);
- columns[4].headerRenderFunction =
- self.renderSelectionColumnHeader_.bind(self);
- columns[4].fixed = true;
- }
-
- var columnModel = Object.create(tableColumnModelClass.prototype, {
- /**
- * The number of columns.
- * @type {number}
- */
- size: {
- /**
- * @this {FileTableColumnModel}
- * @return {number} Number of columns.
- */
- get: function() {
- return this.totalSize;
- }
- },
-
- /**
- * The number of columns.
- * @type {number}
- */
- totalSize: {
- /**
- * @this {FileTableColumnModel}
- * @return {number} Number of columns.
- */
- get: function() {
- return columns.length;
- }
- },
-
- /**
- * Obtains a column by the specified horizontal position.
- */
- getHitColumn: {
- /**
- * @this {FileTableColumnModel}
- * @param {number} x Horizontal position.
- * @return {object} The object that contains column index, column width,
- * and hitPosition where the horizontal position is hit in the column.
- */
- value: function(x) {
- for (var i = 0; x >= this.columns_[i].width; i++) {
- x -= this.columns_[i].width;
- }
- if (i >= this.columns_.length)
- return null;
- return {index: i, hitPosition: x, width: this.columns_[i].width};
- }
- }
- });
-
- tableColumnModelClass.call(columnModel, columns);
- self.columnModel = columnModel;
- self.setDateTimeFormat(true);
- self.setRenderFunction(self.renderTableRow_.bind(self,
- self.getRenderFunction()));
-
- self.scrollBar_ = MainPanelScrollBar();
- self.scrollBar_.initialize(self, self.list);
- // Keep focus on the file list when clicking on the header.
- self.header.addEventListener('mousedown', function(e) {
- self.list.focus();
- e.preventDefault();
- });
-
- var handleSelectionChange = function() {
- var selectAll = self.querySelector('#select-all-checkbox');
- if (selectAll)
- self.updateSelectAllCheckboxState_(selectAll);
- };
-
- self.relayoutAggregation_ =
- new AsyncUtil.Aggregation(self.relayoutImmediately_.bind(self));
-
- Object.defineProperty(self.list_, 'selectionModel', {
- /**
- * @this {cr.ui.List}
- * @return {cr.ui.ListSelectionModel} The current selection model.
- */
- get: function() {
- return this.selectionModel_;
- },
- /**
- * @this {cr.ui.List}
- */
- set: function(value) {
- var sm = this.selectionModel;
- if (sm)
- sm.removeEventListener('change', handleSelectionChange);
-
- util.callInheritedSetter(this, 'selectionModel', value);
- sm = value;
-
- if (sm)
- sm.addEventListener('change', handleSelectionChange);
- handleSelectionChange();
- }
- });
-
- // Override header#redraw to use FileTableSplitter.
- self.header_.redraw = function() {
- this.__proto__.redraw.call(this);
- // Extend table splitters
- var splitters = this.querySelectorAll('.table-header-splitter');
- for (var i = 0; i < splitters.length; i++) {
- if (splitters[i] instanceof FileTableSplitter)
- continue;
- FileTableSplitter.decorate(splitters[i]);
- }
- };
-
- // Save the last selection. This is used by shouldStartDragSelection.
- self.list.addEventListener('mousedown', function(e) {
- this.lastSelection_ = this.selectionModel.selectedIndexes;
- }.bind(self), true);
- self.list.shouldStartDragSelection =
- self.shouldStartDragSelection_.bind(self);
-
- /**
- * Obtains the index list of elements that are hit by the point or the
- * rectangle.
- *
- * @param {number} x X coordinate value.
- * @param {number} y Y coordinate value.
- * @param {=number} opt_width Width of the coordinate.
- * @param {=number} opt_height Height of the coordinate.
- * @return {Array.<number>} Index list of hit elements.
- */
- self.list.getHitElements = function(x, y, opt_width, opt_height) {
- var currentSelection = [];
- var bottom = y + (opt_height || 0);
- for (var i = 0; i < this.selectionModel_.length; i++) {
- var itemMetrics = this.getHeightsForIndex_(i);
- if (itemMetrics.top < bottom && itemMetrics.top + itemMetrics.height >= y)
- currentSelection.push(i);
- }
- return currentSelection;
- };
-};
-
-/**
- * Sets date and time format.
- * @param {boolean} use12hourClock True if 12 hours clock, False if 24 hours.
- */
-FileTable.prototype.setDateTimeFormat = function(use12hourClock) {
- this.timeFormatter_ = Intl.DateTimeFormat(
- [] /* default locale */,
- {hour: 'numeric', minute: 'numeric',
- hour12: use12hourClock});
- this.dateFormatter_ = Intl.DateTimeFormat(
- [] /* default locale */,
- {year: 'numeric', month: 'short', day: 'numeric',
- hour: 'numeric', minute: 'numeric',
- hour12: use12hourClock});
-};
-
-/**
- * Obtains if the drag selection should be start or not by referring the mouse
- * event.
- * @param {MouseEvent} event Drag start event.
- * @return {boolean} True if the mouse is hit to the background of the list.
- * @private
- */
-FileTable.prototype.shouldStartDragSelection_ = function(event) {
- // If the shift key is pressed, it should starts drag selection.
- if (event.shiftKey)
- return true;
-
- // If the position values are negative, it points the out of list.
- // It should start the drag selection.
- var pos = DragSelector.getScrolledPosition(this.list, event);
- if (!pos)
- return false;
- if (pos.x < 0 || pos.y < 0)
- return true;
-
- // If the item index is out of range, it should start the drag selection.
- var itemHeight = this.list.measureItem().height;
- // Faster alternative to Math.floor for non-negative numbers.
- var itemIndex = ~~(pos.y / itemHeight);
- if (itemIndex >= this.list.dataModel.length)
- return true;
-
- // If the pointed item is already selected, it should not start the drag
- // selection.
- if (this.lastSelection_.indexOf(itemIndex) != -1)
- return false;
-
- // If the horizontal value is not hit to column, it should start the drag
- // selection.
- var hitColumn = this.columnModel.getHitColumn(pos.x);
- if (!hitColumn)
- return true;
-
- // Check if the point is on the column contents or not.
- var item = this.list.getListItemByIndex(itemIndex);
- switch (this.columnModel.columns_[hitColumn.index].id) {
- case 'name':
- var spanElement = item.querySelector('.filename-label span');
- var spanRect = spanElement.getBoundingClientRect();
- // The this.list.cachedBounds_ object is set by
- // DragSelector.getScrolledPosition.
- if (!this.list.cachedBounds)
- return true;
- var textRight =
- spanRect.left - this.list.cachedBounds.left + spanRect.width;
- return textRight <= hitColumn.hitPosition;
- default:
- return true;
- }
-};
-
-/**
- * Update check and disable states of the 'Select all' checkbox.
- * @param {HTMLInputElement} checkbox The checkbox. If not passed, using
- * the default one.
- * @private
- */
-FileTable.prototype.updateSelectAllCheckboxState_ = function(checkbox) {
- // TODO(serya): introduce this.selectionModel.selectedCount.
- checkbox.checked = this.dataModel.length > 0 &&
- this.dataModel.length == this.selectionModel.selectedIndexes.length;
- checkbox.disabled = this.dataModel.length == 0;
-};
-
-/**
- * Prepares the data model to be sorted by columns.
- * @param {cr.ui.ArrayDataModel} dataModel Data model to prepare.
- */
-FileTable.prototype.setupCompareFunctions = function(dataModel) {
- dataModel.setCompareFunction('name',
- this.compareName_.bind(this));
- dataModel.setCompareFunction('modificationTime',
- this.compareMtime_.bind(this));
- dataModel.setCompareFunction('size',
- this.compareSize_.bind(this));
- dataModel.setCompareFunction('type',
- this.compareType_.bind(this));
-};
-
-/**
- * Render the Name column of the detail table.
- *
- * Invoked by cr.ui.Table when a file needs to be rendered.
- *
- * @param {Entry} entry The Entry object to render.
- * @param {string} columnId The id of the column to be rendered.
- * @param {cr.ui.Table} table The table doing the rendering.
- * @return {HTMLDivElement} Created element.
- * @private
- */
-FileTable.prototype.renderName_ = function(entry, columnId, table) {
- var label = this.ownerDocument.createElement('div');
- label.appendChild(this.renderIconType_(entry, columnId, table));
- label.entry = entry;
- label.className = 'detail-name';
- label.appendChild(filelist.renderFileNameLabel(this.ownerDocument, entry));
- return label;
-};
-
-/**
- * Render the Selection column of the detail table.
- *
- * Invoked by cr.ui.Table when a file needs to be rendered.
- *
- * @param {Entry} entry The Entry object to render.
- * @param {string} columnId The id of the column to be rendered.
- * @param {cr.ui.Table} table The table doing the rendering.
- * @return {HTMLDivElement} Created element.
- * @private
- */
-FileTable.prototype.renderSelection_ = function(entry, columnId, table) {
- var label = this.ownerDocument.createElement('div');
- label.className = 'selection-label';
- if (this.selectionModel.multiple) {
- var checkBox = this.ownerDocument.createElement('input');
- filelist.decorateSelectionCheckbox(checkBox, entry, this.list);
- label.appendChild(checkBox);
- }
- return label;
-};
-
-/**
- * Render the Size column of the detail table.
- *
- * @param {Entry} entry The Entry object to render.
- * @param {string} columnId The id of the column to be rendered.
- * @param {cr.ui.Table} table The table doing the rendering.
- * @return {HTMLDivElement} Created element.
- * @private
- */
-FileTable.prototype.renderSize_ = function(entry, columnId, table) {
- var div = this.ownerDocument.createElement('div');
- div.className = 'size';
- this.updateSize_(
- div, entry, this.metadataCache_.getCached(entry, 'filesystem'));
-
- return div;
-};
-
-/**
- * Sets up or updates the size cell.
- *
- * @param {HTMLDivElement} div The table cell.
- * @param {Entry} entry The corresponding entry.
- * @param {Object} filesystemProps Metadata.
- * @private
- */
-FileTable.prototype.updateSize_ = function(div, entry, filesystemProps) {
- if (!filesystemProps) {
- div.textContent = '...';
- } else if (filesystemProps.size == -1) {
- div.textContent = '--';
- } else if (filesystemProps.size == 0 &&
- FileType.isHosted(entry)) {
- div.textContent = '--';
- } else {
- div.textContent = util.bytesToString(filesystemProps.size);
- }
-};
-
-/**
- * Render the Type column of the detail table.
- *
- * @param {Entry} entry The Entry object to render.
- * @param {string} columnId The id of the column to be rendered.
- * @param {cr.ui.Table} table The table doing the rendering.
- * @return {HTMLDivElement} Created element.
- * @private
- */
-FileTable.prototype.renderType_ = function(entry, columnId, table) {
- var div = this.ownerDocument.createElement('div');
- div.className = 'type';
- div.textContent = FileType.getTypeString(entry);
- return div;
-};
-
-/**
- * Render the Date column of the detail table.
- *
- * @param {Entry} entry The Entry object to render.
- * @param {string} columnId The id of the column to be rendered.
- * @param {cr.ui.Table} table The table doing the rendering.
- * @return {HTMLDivElement} Created element.
- * @private
- */
-FileTable.prototype.renderDate_ = function(entry, columnId, table) {
- var div = this.ownerDocument.createElement('div');
- div.className = 'date';
-
- this.updateDate_(div,
- this.metadataCache_.getCached(entry, 'filesystem'));
- return div;
-};
-
-/**
- * Sets up or updates the date cell.
- *
- * @param {HTMLDivElement} div The table cell.
- * @param {Object} filesystemProps Metadata.
- * @private
- */
-FileTable.prototype.updateDate_ = function(div, filesystemProps) {
- if (!filesystemProps) {
- div.textContent = '...';
- return;
- }
-
- var modTime = filesystemProps.modificationTime;
- var today = new Date();
- today.setHours(0);
- today.setMinutes(0);
- today.setSeconds(0);
- today.setMilliseconds(0);
-
- /**
- * Number of milliseconds in a day.
- */
- var MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000;
-
- if (modTime >= today &&
- modTime < today.getTime() + MILLISECONDS_IN_DAY) {
- div.textContent = strf('TIME_TODAY', this.timeFormatter_.format(modTime));
- } else if (modTime >= today - MILLISECONDS_IN_DAY && modTime < today) {
- div.textContent = strf('TIME_YESTERDAY',
- this.timeFormatter_.format(modTime));
- } else {
- div.textContent =
- this.dateFormatter_.format(filesystemProps.modificationTime);
- }
-};
-
-/**
- * Updates the file metadata in the table item.
- *
- * @param {Element} item Table item.
- * @param {Entry} entry File entry.
- */
-FileTable.prototype.updateFileMetadata = function(item, entry) {
- var props = this.metadataCache_.getCached(entry, 'filesystem');
- this.updateDate_(item.querySelector('.date'), props);
- this.updateSize_(item.querySelector('.size'), entry, props);
-};
-
-/**
- * Updates list items 'in place' on metadata change.
- * @param {string} type Type of metadata change.
- * @param {Object.<sting, Object>} propsMap Map from entry URLs to metadata
- * properties.
- */
-FileTable.prototype.updateListItemsMetadata = function(type, propsMap) {
- var forEachCell = function(selector, callback) {
- var cells = this.querySelectorAll(selector);
- for (var i = 0; i < cells.length; i++) {
- var cell = cells[i];
- var listItem = this.list_.getListItemAncestor(cell);
- var entry = this.dataModel.item(listItem.listIndex);
- if (entry) {
- var props = propsMap[entry.toURL()];
- if (props)
- callback.call(this, cell, entry, props, listItem);
- }
- }
- }.bind(this);
- if (type == 'filesystem') {
- forEachCell('.table-row-cell > .date', function(item, entry, props) {
- this.updateDate_(item, props);
- });
- forEachCell('.table-row-cell > .size', function(item, entry, props) {
- this.updateSize_(item, entry, props);
- });
- } else if (type == 'drive') {
- // The cell name does not matter as the entire list item is needed.
- forEachCell('.table-row-cell > .date',
- function(item, entry, props, listItem) {
- filelist.updateListItemDriveProps(listItem, props);
- });
- }
-};
-
-/**
- * Compare by mtime first, then by name.
- * @param {Entry} a First entry.
- * @param {Entry} b Second entry.
- * @return {number} Compare result.
- * @private
- */
-FileTable.prototype.compareName_ = function(a, b) {
- return this.collator_.compare(a.name, b.name);
-};
-
-/**
- * Compare by mtime first, then by name.
- * @param {Entry} a First entry.
- * @param {Entry} b Second entry.
- * @return {number} Compare result.
- * @private
- */
-FileTable.prototype.compareMtime_ = function(a, b) {
- var aCachedFilesystem = this.metadataCache_.getCached(a, 'filesystem');
- var aTime = aCachedFilesystem ? aCachedFilesystem.modificationTime : 0;
-
- var bCachedFilesystem = this.metadataCache_.getCached(b, 'filesystem');
- var bTime = bCachedFilesystem ? bCachedFilesystem.modificationTime : 0;
-
- if (aTime > bTime)
- return 1;
-
- if (aTime < bTime)
- return -1;
-
- return this.collator_.compare(a.name, b.name);
-};
-
-/**
- * Compare by size first, then by name.
- * @param {Entry} a First entry.
- * @param {Entry} b Second entry.
- * @return {number} Compare result.
- * @private
- */
-FileTable.prototype.compareSize_ = function(a, b) {
- var aCachedFilesystem = this.metadataCache_.getCached(a, 'filesystem');
- var aSize = aCachedFilesystem ? aCachedFilesystem.size : 0;
-
- var bCachedFilesystem = this.metadataCache_.getCached(b, 'filesystem');
- var bSize = bCachedFilesystem ? bCachedFilesystem.size : 0;
-
- if (aSize != bSize) return aSize - bSize;
- return this.collator_.compare(a.name, b.name);
-};
-
-/**
- * Compare by type first, then by subtype and then by name.
- * @param {Entry} a First entry.
- * @param {Entry} b Second entry.
- * @return {number} Compare result.
- * @private
- */
-FileTable.prototype.compareType_ = function(a, b) {
- // Directories precede files.
- if (a.isDirectory != b.isDirectory)
- return Number(b.isDirectory) - Number(a.isDirectory);
-
- var aType = FileType.getTypeString(a);
- var bType = FileType.getTypeString(b);
-
- var result = this.collator_.compare(aType, bType);
- if (result != 0)
- return result;
-
- return this.collator_.compare(a.name, b.name);
-};
-
-/**
- * Renders table row.
- * @param {function(Entry, cr.ui.Table)} baseRenderFunction Base renderer.
- * @param {Entry} entry Corresponding entry.
- * @return {HTMLLiElement} Created element.
- * @private
- */
-FileTable.prototype.renderTableRow_ = function(baseRenderFunction, entry) {
- var item = baseRenderFunction(entry, this);
- filelist.decorateListItem(item, entry, this.metadataCache_);
- return item;
-};
-
-/**
- * Renders the name column header.
- * @param {string} name Localized column name.
- * @return {HTMLLiElement} Created element.
- * @private
- */
-FileTable.prototype.renderNameColumnHeader_ = function(name) {
- if (!this.selectionModel.multiple)
- return this.ownerDocument.createTextNode(name);
-
- var input = this.ownerDocument.createElement('input');
- input.setAttribute('type', 'checkbox');
- input.setAttribute('tabindex', -1);
- input.id = 'select-all-checkbox';
- input.className = 'common';
-
- this.updateSelectAllCheckboxState_(input);
-
- input.addEventListener('click', function(event) {
- if (input.checked)
- this.selectionModel.selectAll();
- else
- this.selectionModel.unselectAll();
- event.stopPropagation();
- }.bind(this));
-
- var fragment = this.ownerDocument.createDocumentFragment();
- fragment.appendChild(input);
- fragment.appendChild(this.ownerDocument.createTextNode(name));
- return fragment;
-};
-
-/**
- * Renders the selection column header.
- * @param {string} name Localized column name.
- * @return {HTMLLiElement} Created element.
- * @private
- */
-FileTable.prototype.renderSelectionColumnHeader_ = function(name) {
- if (!this.selectionModel.multiple)
- return this.ownerDocument.createTextNode('');
-
- var input = this.ownerDocument.createElement('input');
- input.setAttribute('type', 'checkbox');
- input.setAttribute('tabindex', -1);
- input.id = 'select-all-checkbox';
- input.className = 'common';
-
- this.updateSelectAllCheckboxState_(input);
-
- input.addEventListener('click', function(event) {
- if (input.checked)
- this.selectionModel.selectAll();
- else
- this.selectionModel.unselectAll();
- event.stopPropagation();
- }.bind(this));
-
- var fragment = this.ownerDocument.createDocumentFragment();
- fragment.appendChild(input);
- return fragment;
-};
-
-/**
- * Render the type column of the detail table.
- *
- * Invoked by cr.ui.Table when a file needs to be rendered.
- *
- * @param {Entry} entry The Entry object to render.
- * @param {string} columnId The id of the column to be rendered.
- * @param {cr.ui.Table} table The table doing the rendering.
- * @return {HTMLDivElement} Created element.
- * @private
- */
-FileTable.prototype.renderIconType_ = function(entry, columnId, table) {
- var icon = this.ownerDocument.createElement('div');
- icon.className = 'detail-icon';
- icon.setAttribute('file-type-icon', FileType.getIcon(entry));
- return icon;
-};
-
-/**
- * Sets the margin height for the transparent preview panel at the bottom.
- * @param {number} margin Margin to be set in px.
- */
-FileTable.prototype.setBottomMarginForPanel = function(margin) {
- this.list_.style.paddingBottom = margin + 'px';
- this.scrollBar_.setBottomMarginForPanel(margin);
-};
-
-/**
- * Redraws the UI. Skips multiple consecutive calls.
- */
-FileTable.prototype.relayout = function() {
- this.relayoutAggregation_.run();
-};
-
-/**
- * Redraws the UI immediately.
- * @private
- */
-FileTable.prototype.relayoutImmediately_ = function() {
- if (this.clientWidth > 0)
- this.normalizeColumns();
- this.redraw();
- cr.dispatchSimpleEvent(this.list, 'relayout');
-};
-
-/**
- * Decorates (and wire up) a checkbox to be used in either a detail or a
- * thumbnail list item.
- * @param {HTMLInputElement} input Element to decorate.
- */
-filelist.decorateCheckbox = function(input) {
- var stopEventPropagation = function(event) {
- if (!event.shiftKey)
- event.stopPropagation();
- };
- input.setAttribute('type', 'checkbox');
- input.setAttribute('tabindex', -1);
- input.classList.add('common');
- input.addEventListener('mousedown', stopEventPropagation);
- input.addEventListener('mouseup', stopEventPropagation);
-
- input.addEventListener(
- 'click',
- /**
- * @this {HTMLInputElement}
- */
- function(event) {
- // Revert default action and swallow the event
- // if this is a multiple click or Shift is pressed.
- if (event.detail > 1 || event.shiftKey) {
- this.checked = !this.checked;
- stopEventPropagation(event);
- }
- });
-};
-
-/**
- * Decorates selection checkbox.
- * @param {HTMLInputElement} input Element to decorate.
- * @param {Entry} entry Corresponding entry.
- * @param {cr.ui.List} list Owner list.
- */
-filelist.decorateSelectionCheckbox = function(input, entry, list) {
- filelist.decorateCheckbox(input);
- input.classList.add('file-checkbox');
- input.addEventListener('click', function(e) {
- var sm = list.selectionModel;
- var listIndex = list.getListItemAncestor(this).listIndex;
- sm.setIndexSelected(listIndex, this.checked);
- sm.leadIndex = listIndex;
- if (sm.anchorIndex == -1)
- sm.anchorIndex = listIndex;
-
- });
- // Since we do not want to open the item when tap on checkbox, we need to
- // stop propagation of TAP event dispatched by checkbox ideally. But all
- // touch events from touch_handler are dispatched to the list control. So we
- // have to stop propagation of native touchstart event to prevent list
- // control from generating TAP event here. The synthetic click event will
- // select the touched checkbox/item.
- input.addEventListener('touchstart',
- function(e) { e.stopPropagation() });
-
- var index = list.dataModel.indexOf(entry);
- // Our DOM nodes get discarded as soon as we're scrolled out of view,
- // so we have to make sure the check state is correct when we're brought
- // back to life.
- input.checked = list.selectionModel.getIndexSelected(index);
-};
-
-/**
- * Common item decoration for table's and grid's items.
- * @param {ListItem} li List item.
- * @param {Entry} entry The entry.
- * @param {MetadataCache} metadataCache Cache to retrieve metadada.
- */
-filelist.decorateListItem = function(li, entry, metadataCache) {
- li.classList.add(entry.isDirectory ? 'directory' : 'file');
- if (FileType.isOnDrive(entry)) {
- // The metadata may not yet be ready. In that case, the list item will be
- // updated when the metadata is ready via updateListItemsMetadata.
- var driveProps = metadataCache.getCached(entry, 'drive');
- if (driveProps)
- filelist.updateListItemDriveProps(li, driveProps);
- }
-
- // Overriding the default role 'list' to 'listbox' for better
- // accessibility on ChromeOS.
- li.setAttribute('role', 'option');
-
- Object.defineProperty(li, 'selected', {
- /**
- * @this {ListItem}
- * @return {boolean} True if the list item is selected.
- */
- get: function() {
- return this.hasAttribute('selected');
- },
-
- /**
- * @this {ListItem}
- */
- set: function(v) {
- if (v)
- this.setAttribute('selected', '');
- else
- this.removeAttribute('selected');
- var checkBox = this.querySelector('input.file-checkbox');
- if (checkBox)
- checkBox.checked = !!v;
- }
- });
-};
-
-/**
- * Render filename label for grid and list view.
- * @param {HTMLDocument} doc Owner document.
- * @param {Entry} entry The Entry object to render.
- * @return {HTMLDivElement} The label.
- */
-filelist.renderFileNameLabel = function(doc, entry) {
- // Filename need to be in a '.filename-label' container for correct
- // work of inplace renaming.
- var box = doc.createElement('div');
- box.className = 'filename-label';
- var fileName = doc.createElement('span');
- fileName.textContent = entry.name;
- box.appendChild(fileName);
-
- return box;
-};
-
-/**
- * Updates grid item or table row for the driveProps.
- * @param {cr.ui.ListItem} li List item.
- * @param {Object} driveProps Metadata.
- */
-filelist.updateListItemDriveProps = function(li, driveProps) {
- if (li.classList.contains('file')) {
- if (driveProps.availableOffline)
- li.classList.remove('dim-offline');
- else
- li.classList.add('dim-offline');
- // TODO(mtomasz): Consider adding some vidual indication for files which
- // are not cached on LTE. Currently we show them as normal files.
- // crbug.com/246611.
- }
-
- if (driveProps.customIconUrl) {
- var iconDiv = li.querySelector('.detail-icon');
- if (!iconDiv)
- return;
- iconDiv.style.backgroundImage = 'url(' + driveProps.customIconUrl + ')';
- }
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/file_tasks.js b/chromium/chrome/browser/resources/file_manager/foreground/js/file_tasks.js
deleted file mode 100644
index 7bde88ca9c2..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/file_tasks.js
+++ /dev/null
@@ -1,834 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * This object encapsulates everything related to tasks execution.
- *
- * @param {FileManager} fileManager FileManager instance.
- * @param {Object=} opt_params File manager load parameters.
- * @constructor
- */
-function FileTasks(fileManager, opt_params) {
- this.fileManager_ = fileManager;
- this.params_ = opt_params;
- this.tasks_ = null;
- this.defaultTask_ = null;
- this.entries_ = null;
-
- /**
- * List of invocations to be called once tasks are available.
- *
- * @private
- * @type {Array.<Object>}
- */
- this.pendingInvocations_ = [];
-}
-
-/**
- * Location of the FAQ about the file actions.
- *
- * @const
- * @type {string}
- */
-FileTasks.NO_ACTION_FOR_FILE_URL = 'http://support.google.com/chromeos/bin/' +
- 'answer.py?answer=1700055&topic=29026&ctx=topic';
-
-/**
- * Location of the Chrome Web Store.
- *
- * @const
- * @type {string}
- */
-FileTasks.CHROME_WEB_STORE_URL = 'https://chrome.google.com/webstore';
-
-/**
- * Base URL of apps list in the Chrome Web Store. This constant is used in
- * FileTasks.createWebStoreLink().
- *
- * @const
- * @type {string}
- */
-FileTasks.WEB_STORE_HANDLER_BASE_URL =
- 'https://chrome.google.com/webstore/category/collection/file_handlers';
-
-/**
- * Returns URL of the Chrome Web Store which show apps supporting the given
- * file-extension and mime-type.
- *
- * @param {string} extension Extension of the file (with the first dot).
- * @param {string} mimeType Mime type of the file.
- * @return {string} URL
- */
-FileTasks.createWebStoreLink = function(extension, mimeType) {
- if (!extension)
- return FileTasks.CHROME_WEB_STORE_URL;
-
- if (extension[0] === '.')
- extension = extension.substr(1);
- else
- console.warn('Please pass an extension with a dot to createWebStoreLink.');
-
- var url = FileTasks.WEB_STORE_HANDLER_BASE_URL;
- url += '?_fe=' + extension.toLowerCase().replace(/[^\w]/g, '');
-
- // If a mime is given, add it into the URL.
- if (mimeType)
- url += '&_fmt=' + mimeType.replace(/[^-\w\/]/g, '');
- return url;
-};
-
-/**
- * Complete the initialization.
- *
- * @param {Array.<Entry>} entries List of file entries.
- * @param {Array.<string>=} opt_mimeTypes List of MIME types for each
- * of the files.
- */
-FileTasks.prototype.init = function(entries, opt_mimeTypes) {
- this.entries_ = entries;
- this.mimeTypes_ = opt_mimeTypes || [];
-
- // TODO(mtomasz): Move conversion from entry to url to custom bindings.
- var urls = util.entriesToURLs(entries);
- if (urls.length > 0) {
- chrome.fileBrowserPrivate.getFileTasks(urls, this.mimeTypes_,
- this.onTasks_.bind(this));
- }
-};
-
-/**
- * Returns amount of tasks.
- *
- * @return {number} amount of tasks.
- */
-FileTasks.prototype.size = function() {
- return (this.tasks_ && this.tasks_.length) || 0;
-};
-
-/**
- * Callback when tasks found.
- *
- * @param {Array.<Object>} tasks The tasks.
- * @private
- */
-FileTasks.prototype.onTasks_ = function(tasks) {
- this.processTasks_(tasks);
- for (var index = 0; index < this.pendingInvocations_.length; index++) {
- var name = this.pendingInvocations_[index][0];
- var args = this.pendingInvocations_[index][1];
- this[name].apply(this, args);
- }
- this.pendingInvocations_ = [];
-};
-
-/**
- * The list of known extensions to record UMA.
- * Note: Because the data is recorded by the index, so new item shouldn't be
- * inserted.
- *
- * @const
- * @type {Array.<string>}
- * @private
- */
-FileTasks.knownExtensions_ = [
- 'other', '.3ga', '.3gp', '.aac', '.alac', '.asf', '.avi', '.bmp', '.csv',
- '.doc', '.docx', '.flac', '.gif', '.ico', '.jpeg', '.jpg', '.log', '.m3u',
- '.m3u8', '.m4a', '.m4v', '.mid', '.mkv', '.mov', '.mp3', '.mp4', '.mpg',
- '.odf', '.odp', '.ods', '.odt', '.oga', '.ogg', '.ogv', '.pdf', '.png',
- '.ppt', '.pptx', '.ra', '.ram', '.rar', '.rm', '.rtf', '.wav', '.webm',
- '.webp', '.wma', '.wmv', '.xls', '.xlsx',
-];
-
-/**
- * The list of excutable file extensions.
- *
- * @const
- * @type {Array.<string>}
- */
-FileTasks.EXECUTABLE_EXTENSIONS = Object.freeze([
- '.exe', '.lnk', '.deb', '.dmg', '.jar', '.msi',
-]);
-
-/**
- * The list of extensions to skip the suggest app dialog.
- * @const
- * @type {Array.<string>}
- * @private
- */
-FileTasks.EXTENSIONS_TO_SKIP_SUGGEST_APPS_ = Object.freeze([
- '.crdownload', '.dsc', '.inf', '.crx',
-]);
-
-/**
- * Records trial of opening file grouped by extensions.
- *
- * @param {Array.<Entry>} entries The entries to be opened.
- * @private
- */
-FileTasks.recordViewingFileTypeUMA_ = function(entries) {
- for (var i = 0; i < entries.length; i++) {
- var entry = entries[i];
- var extension = FileType.getExtension(entry).toLowerCase();
- if (FileTasks.knownExtensions_.indexOf(extension) < 0) {
- extension = 'other';
- }
- metrics.recordEnum(
- 'ViewingFileType', extension, FileTasks.knownExtensions_);
- }
-};
-
-/**
- * Returns true if the taskId is for an internal task.
- *
- * @param {string} taskId Task identifier.
- * @return {boolean} True if the task ID is for an internal task.
- * @private
- */
-FileTasks.isInternalTask_ = function(taskId) {
- var taskParts = taskId.split('|');
- var appId = taskParts[0];
- var taskType = taskParts[1];
- var actionId = taskParts[2];
- // The action IDs here should match ones used in executeInternalTask_().
- return (appId === chrome.runtime.id &&
- taskType === 'file' &&
- (actionId === 'play' ||
- actionId === 'watch' ||
- actionId === 'mount-archive' ||
- actionId === 'gallery'));
-};
-
-/**
- * Processes internal tasks.
- *
- * @param {Array.<Object>} tasks The tasks.
- * @private
- */
-FileTasks.prototype.processTasks_ = function(tasks) {
- this.tasks_ = [];
- var id = chrome.runtime.id;
- var isOnDrive = false;
- for (var index = 0; index < this.entries_.length; ++index) {
- if (FileType.isOnDrive(this.entries_[index])) {
- isOnDrive = true;
- break;
- }
- }
-
- for (var i = 0; i < tasks.length; i++) {
- var task = tasks[i];
- var taskParts = task.taskId.split('|');
-
- // Skip internal Files.app's handlers.
- if (taskParts[0] === id && (taskParts[2] === 'auto-open' ||
- taskParts[2] === 'select' || taskParts[2] === 'open')) {
- continue;
- }
-
- // Tweak images, titles of internal tasks.
- if (taskParts[0] === id && taskParts[1] === 'file') {
- if (taskParts[2] === 'play') {
- // TODO(serya): This hack needed until task.iconUrl is working
- // (see GetFileTasksFileBrowserFunction::RunImpl).
- task.iconType = 'audio';
- task.title = loadTimeData.getString('ACTION_LISTEN');
- } else if (taskParts[2] === 'mount-archive') {
- task.iconType = 'archive';
- task.title = loadTimeData.getString('MOUNT_ARCHIVE');
- } else if (taskParts[2] === 'gallery') {
- task.iconType = 'image';
- task.title = loadTimeData.getString('ACTION_OPEN');
- } else if (taskParts[2] === 'watch') {
- task.iconType = 'video';
- task.title = loadTimeData.getString('ACTION_WATCH');
- } else if (taskParts[2] === 'open-hosted-generic') {
- if (this.entries_.length > 1)
- task.iconType = 'generic';
- else // Use specific icon.
- task.iconType = FileType.getIcon(this.entries_[0]);
- task.title = loadTimeData.getString('ACTION_OPEN');
- } else if (taskParts[2] === 'open-hosted-gdoc') {
- task.iconType = 'gdoc';
- task.title = loadTimeData.getString('ACTION_OPEN_GDOC');
- } else if (taskParts[2] === 'open-hosted-gsheet') {
- task.iconType = 'gsheet';
- task.title = loadTimeData.getString('ACTION_OPEN_GSHEET');
- } else if (taskParts[2] === 'open-hosted-gslides') {
- task.iconType = 'gslides';
- task.title = loadTimeData.getString('ACTION_OPEN_GSLIDES');
- } else if (taskParts[2] === 'view-swf') {
- // Do not render this task if disabled.
- if (!loadTimeData.getBoolean('SWF_VIEW_ENABLED'))
- continue;
- task.iconType = 'generic';
- task.title = loadTimeData.getString('ACTION_VIEW');
- } else if (taskParts[2] === 'view-pdf') {
- // Do not render this task if disabled.
- if (!loadTimeData.getBoolean('PDF_VIEW_ENABLED'))
- continue;
- task.iconType = 'pdf';
- task.title = loadTimeData.getString('ACTION_VIEW');
- } else if (taskParts[2] === 'view-in-browser') {
- task.iconType = 'generic';
- task.title = loadTimeData.getString('ACTION_VIEW');
- }
- }
-
- if (!task.iconType && taskParts[1] === 'web-intent') {
- task.iconType = 'generic';
- }
-
- this.tasks_.push(task);
- if (this.defaultTask_ === null && task.isDefault) {
- this.defaultTask_ = task;
- }
- }
- if (!this.defaultTask_ && this.tasks_.length > 0) {
- // If we haven't picked a default task yet, then just pick the first one.
- // This is not the preferred way we want to pick this, but better this than
- // no default at all if the C++ code didn't set one.
- this.defaultTask_ = this.tasks_[0];
- }
-};
-
-/**
- * Executes default task.
- *
- * @param {function(boolean, Array.<string>)=} opt_callback Called when the
- * default task is executed, or the error is occurred.
- * @private
- */
-FileTasks.prototype.executeDefault_ = function(opt_callback) {
- FileTasks.recordViewingFileTypeUMA_(this.entries_);
- this.executeDefaultInternal_(this.entries_, opt_callback);
-};
-
-/**
- * Executes default task.
- *
- * @param {Array.<Entry>} entries Entries to execute.
- * @param {function(boolean, Array.<Entry>)=} opt_callback Called when the
- * default task is executed, or the error is occurred.
- * @private
- */
-FileTasks.prototype.executeDefaultInternal_ = function(entries, opt_callback) {
- var callback = opt_callback || function(arg1, arg2) {};
-
- if (this.defaultTask_ !== null) {
- this.executeInternal_(this.defaultTask_.taskId, entries);
- callback(true, entries);
- return;
- }
-
- // We don't have tasks, so try to show a file in a browser tab.
- // We only do that for single selection to avoid confusion.
- if (entries.length !== 1 || !entries[0])
- return;
-
- var filename = entries[0].name;
- var extension = PathUtil.splitExtension(filename)[1];
- var mimeType = this.mimeTypes_[0];
-
- var showAlert = function() {
- var textMessageId;
- var titleMessageId;
- switch (extension) {
- case '.exe':
- textMessageId = 'NO_ACTION_FOR_EXECUTABLE';
- break;
- case '.crx':
- textMessageId = 'NO_ACTION_FOR_CRX';
- titleMessageId = 'NO_ACTION_FOR_CRX_TITLE';
- break;
- default:
- textMessageId = 'NO_ACTION_FOR_FILE';
- }
-
- var webStoreUrl = FileTasks.createWebStoreLink(extension, mimeType);
- var text = strf(textMessageId,
- webStoreUrl,
- FileTasks.NO_ACTION_FOR_FILE_URL);
- var title = titleMessageId ? str(titleMessageId) : filename;
- this.fileManager_.alert.showHtml(title, text, function() {});
- callback(false, urls);
- }.bind(this);
-
- var onViewFilesFailure = function() {
- var fm = this.fileManager_;
- if (fm.enableExperimentalWebStoreIntegration_) {
- showAlert();
- return;
- }
-
- if (!fm.isOnDrive() ||
- !entries[0] ||
- FileTasks.EXTENSIONS_TO_SKIP_SUGGEST_APPS_.indexOf(extension) !== -1) {
- showAlert();
- return;
- }
-
- fm.openSuggestAppsDialog(
- entries[0],
- function() {
- var newTasks = new FileTasks(fm);
- newTasks.init(entries, this.mimeTypes_);
- newTasks.executeDefault();
- callback(true, entries);
- }.bind(this),
- // Cancelled callback.
- function() {
- callback(false, entries);
- },
- showAlert);
- }.bind(this);
-
- var onViewFiles = function(success) {
- if (success)
- callback(success, entries);
- else
- onViewFilesFailure();
- }.bind(this);
-
- this.checkAvailability_(function() {
- // TODO(mtomasz): Pass entries instead.
- var urls = util.entriesToURLs(entries);
- util.viewFilesInBrowser(urls, onViewFiles);
- }.bind(this));
-};
-
-/**
- * Executes a single task.
- *
- * @param {string} taskId Task identifier.
- * @param {Array.<Entry>=} opt_entries Entries to xecute on instead of
- * this.entries_|.
- * @private
- */
-FileTasks.prototype.execute_ = function(taskId, opt_entries) {
- var entries = opt_entries || this.entries_;
- FileTasks.recordViewingFileTypeUMA_(entries);
- this.executeInternal_(taskId, entries);
-};
-
-/**
- * The core implementation to execute a single task.
- *
- * @param {string} taskId Task identifier.
- * @param {Array.<Entry>} entries Entries to execute.
- * @private
- */
-FileTasks.prototype.executeInternal_ = function(taskId, entries) {
- this.checkAvailability_(function() {
- if (FileTasks.isInternalTask_(taskId)) {
- var taskParts = taskId.split('|');
- this.executeInternalTask_(taskParts[2], entries);
- } else {
- // TODO(mtomasz): Pass entries instead.
- var urls = util.entriesToURLs(entries);
- chrome.fileBrowserPrivate.executeTask(taskId, urls);
- }
- }.bind(this));
-};
-
-/**
- * Checks whether the remote files are available right now.
- *
- * @param {function} callback The callback.
- * @private
- */
-FileTasks.prototype.checkAvailability_ = function(callback) {
- var areAll = function(props, name) {
- var isOne = function(e) {
- // If got no properties, we safely assume that item is unavailable.
- return e && e[name];
- };
- return props.filter(isOne).length === props.length;
- };
-
- var fm = this.fileManager_;
- var entries = this.entries_;
-
- if (fm.isOnDrive() && fm.isDriveOffline()) {
- fm.metadataCache_.get(entries, 'drive', function(props) {
- if (areAll(props, 'availableOffline')) {
- callback();
- return;
- }
-
- fm.alert.showHtml(
- loadTimeData.getString('OFFLINE_HEADER'),
- props[0].hosted ?
- loadTimeData.getStringF(
- entries.length === 1 ?
- 'HOSTED_OFFLINE_MESSAGE' :
- 'HOSTED_OFFLINE_MESSAGE_PLURAL') :
- loadTimeData.getStringF(
- entries.length === 1 ?
- 'OFFLINE_MESSAGE' :
- 'OFFLINE_MESSAGE_PLURAL',
- loadTimeData.getString('OFFLINE_COLUMN_LABEL')));
- });
- return;
- }
-
- if (fm.isOnDrive() && fm.isDriveOnMeteredConnection()) {
- fm.metadataCache_.get(entries, 'drive', function(driveProps) {
- if (areAll(driveProps, 'availableWhenMetered')) {
- callback();
- return;
- }
-
- fm.metadataCache_.get(entries, 'filesystem', function(fileProps) {
- var sizeToDownload = 0;
- for (var i = 0; i !== entries.length; i++) {
- if (!driveProps[i].availableWhenMetered)
- sizeToDownload += fileProps[i].size;
- }
- fm.confirm.show(
- loadTimeData.getStringF(
- entries.length === 1 ?
- 'CONFIRM_MOBILE_DATA_USE' :
- 'CONFIRM_MOBILE_DATA_USE_PLURAL',
- util.bytesToString(sizeToDownload)),
- callback);
- });
- });
- return;
- }
-
- callback();
-};
-
-/**
- * Executes an internal task.
- *
- * @param {string} id The short task id.
- * @param {Array.<Entry>} entries The entries to execute on.
- * @private
- */
-FileTasks.prototype.executeInternalTask_ = function(id, entries) {
- var fm = this.fileManager_;
-
- if (id === 'play') {
- var position = 0;
- if (entries.length === 1) {
- // If just a single audio file is selected pass along every audio file
- // in the directory.
- var selectedEntries = entries[0];
- entries = fm.getAllEntriesInCurrentDirectory().filter(FileType.isAudio);
- position = entries.indexOf(selectedEntries);
- }
- // TODO(mtomasz): Pass entries instead.
- var urls = util.entriesToURLs(entries);
- fm.backgroundPage.launchAudioPlayer({items: urls, position: position});
- return;
- }
-
- if (id === 'watch') {
- console.assert(entries.length === 1, 'Cannot open multiple videos');
- // TODO(mtomasz): Pass an entry instead.
- fm.backgroundPage.launchVideoPlayer(entries[0].toURL());
- return;
- }
-
- if (id === 'mount-archive') {
- this.mountArchivesInternal_(entries);
- return;
- }
-
- if (id === 'gallery') {
- this.openGalleryInternal_(entries);
- return;
- }
-
- console.error('Unexpected action ID: ' + id);
-};
-
-/**
- * Mounts archives.
- *
- * @param {Array.<Entry>} entries Mount file entries list.
- */
-FileTasks.prototype.mountArchives = function(entries) {
- FileTasks.recordViewingFileTypeUMA_(entries);
- this.mountArchivesInternal_(entries);
-};
-
-/**
- * The core implementation of mounts archives.
- *
- * @param {Array.<Entry>} entries Mount file entries list.
- * @private
- */
-FileTasks.prototype.mountArchivesInternal_ = function(entries) {
- var fm = this.fileManager_;
-
- var tracker = fm.directoryModel.createDirectoryChangeTracker();
- tracker.start();
-
- // TODO(mtomasz): Pass Entries instead of URLs.
- var urls = util.entriesToURLs(entries);
- fm.resolveSelectResults_(urls, function(resolvedURLs) {
- for (var index = 0; index < resolvedURLs.length; ++index) {
- // TODO(mtomasz): Pass Entry instead of URL.
- fm.volumeManager.mountArchive(resolvedURLs[index],
- function(mountPath) {
- tracker.stop();
- if (!tracker.hasChanged)
- fm.directoryModel.changeDirectory(mountPath);
- }, function(url, error) {
- tracker.stop();
- var path = util.extractFilePath(url);
- var namePos = path.lastIndexOf('/');
- fm.alert.show(strf('ARCHIVE_MOUNT_FAILED',
- path.substr(namePos + 1), error));
- }.bind(null, resolvedURLs[index]));
- }
- });
-};
-
-/**
- * Open the Gallery.
- *
- * @param {Array.<Entry>} entries List of selected entries.
- */
-FileTasks.prototype.openGallery = function(entries) {
- FileTasks.recordViewingFileTypeUMA_(entries);
- this.openGalleryInternal_(entries);
-};
-
-/**
- * The core implementation to open the Gallery.
- *
- * @param {Array.<Entry>} entries List of selected entries.
- * @private
- */
-FileTasks.prototype.openGalleryInternal_ = function(entries) {
- var fm = this.fileManager_;
-
- var allEntries =
- fm.getAllEntriesInCurrentDirectory().filter(FileType.isImageOrVideo);
-
- var galleryFrame = fm.document_.createElement('iframe');
- galleryFrame.className = 'overlay-pane';
- galleryFrame.scrolling = 'no';
- galleryFrame.setAttribute('webkitallowfullscreen', true);
-
- if (this.params_ && this.params_.gallery) {
- // Remove the Gallery state from the location, we do not need it any more.
- util.updateAppState(null /* keep path */, '' /* remove search. */);
- }
-
- var savedAppState = window.appState;
- var savedTitle = document.title;
-
- // Push a temporary state which will be replaced every time the selection
- // changes in the Gallery and popped when the Gallery is closed.
- util.updateAppState();
-
- var onBack = function(selectedEntries) {
- fm.directoryModel.selectEntries(selectedEntries);
- fm.closeFilePopup(); // Will call Gallery.unload.
- window.appState = savedAppState;
- util.saveAppState();
- document.title = savedTitle;
- };
-
- var onClose = function() {
- fm.onClose();
- };
-
- var onMaximize = function() {
- fm.onMaximize();
- };
-
- var onAppRegionChanged = function(visible) {
- fm.onFilePopupAppRegionChanged(visible);
- };
-
- galleryFrame.onload = function() {
- galleryFrame.contentWindow.ImageUtil.metrics = metrics;
-
- // TODO(haruki): isOnReadonlyDirectory() only checks the permission for the
- // root. We should check more granular permission to know whether the file
- // is writable or not.
- var readonly = fm.isOnReadonlyDirectory();
- var currentDir = fm.getCurrentDirectoryEntry();
- var downloadsVolume =
- fm.volumeManager.getCurrentProfileVolumeInfo(RootType.DOWNLOADS);
- var downloadsDir = downloadsVolume && downloadsVolume.root;
- var readonlyDirName = null;
- if (readonly && currentDir) {
- var rootPath = PathUtil.getRootPath(currentDir.fullPath);
- readonlyDirName = fm.isOnDrive() ?
- PathUtil.getRootLabel(rootPath) :
- PathUtil.basename(rootPath);
- }
-
- var context = {
- // We show the root label in readonly warning (e.g. archive name).
- readonlyDirName: readonlyDirName,
- curDirEntry: currentDir,
- saveDirEntry: readonly ? downloadsDir : null,
- searchResults: fm.directoryModel.isSearching(),
- metadataCache: fm.metadataCache_,
- pageState: this.params_,
- appWindow: chrome.app.window.current(),
- onBack: onBack,
- onClose: onClose,
- onMaximize: onMaximize,
- onAppRegionChanged: onAppRegionChanged,
- displayStringFunction: strf
- };
- galleryFrame.contentWindow.Gallery.open(
- context, fm.volumeManager, allEntries, entries);
- }.bind(this);
-
- galleryFrame.src = 'gallery.html';
- fm.openFilePopup(galleryFrame, fm.updateTitle_.bind(fm));
-};
-
-/**
- * Displays the list of tasks in a task picker combobutton.
- *
- * @param {cr.ui.ComboButton} combobutton The task picker element.
- * @private
- */
-FileTasks.prototype.display_ = function(combobutton) {
- if (this.tasks_.length === 0) {
- combobutton.hidden = true;
- return;
- }
-
- combobutton.clear();
- combobutton.hidden = false;
- combobutton.defaultItem = this.createCombobuttonItem_(this.defaultTask_);
-
- var items = this.createItems_();
-
- if (items.length > 1) {
- var defaultIdx = 0;
-
- for (var j = 0; j < items.length; j++) {
- combobutton.addDropDownItem(items[j]);
- if (items[j].task.taskId === this.defaultTask_.taskId)
- defaultIdx = j;
- }
-
- combobutton.addSeparator();
- var changeDefaultMenuItem = combobutton.addDropDownItem({
- label: loadTimeData.getString('CHANGE_DEFAULT_MENU_ITEM')
- });
- changeDefaultMenuItem.classList.add('change-default');
- }
-};
-
-/**
- * Creates sorted array of available task descriptions such as title and icon.
- *
- * @return {Array} created array can be used to feed combobox, menus and so on.
- * @private
- */
-FileTasks.prototype.createItems_ = function() {
- var items = [];
- var title = this.defaultTask_.title + ' ' +
- loadTimeData.getString('DEFAULT_ACTION_LABEL');
- items.push(this.createCombobuttonItem_(this.defaultTask_, title, true));
-
- for (var index = 0; index < this.tasks_.length; index++) {
- var task = this.tasks_[index];
- if (task !== this.defaultTask_)
- items.push(this.createCombobuttonItem_(task));
- }
-
- items.sort(function(a, b) {
- return a.label.localeCompare(b.label);
- });
-
- return items;
-};
-
-/**
- * Updates context menu with default item.
- * @private
- */
-
-FileTasks.prototype.updateMenuItem_ = function() {
- this.fileManager_.updateContextMenuActionItems(this.defaultTask_,
- this.tasks_.length > 1);
-};
-
-/**
- * Creates combobutton item based on task.
- *
- * @param {Object} task Task to convert.
- * @param {string=} opt_title Title.
- * @param {boolean=} opt_bold Make a menu item bold.
- * @return {Object} Item appendable to combobutton drop-down list.
- * @private
- */
-FileTasks.prototype.createCombobuttonItem_ = function(task, opt_title,
- opt_bold) {
- return {
- label: opt_title || task.title,
- iconUrl: task.iconUrl,
- iconType: task.iconType,
- task: task,
- bold: opt_bold || false
- };
-};
-
-
-/**
- * Decorates a FileTasks method, so it will be actually executed after the tasks
- * are available.
- * This decorator expects an implementation called |method + '_'|.
- *
- * @param {string} method The method name.
- */
-FileTasks.decorate = function(method) {
- var privateMethod = method + '_';
- FileTasks.prototype[method] = function() {
- if (this.tasks_) {
- this[privateMethod].apply(this, arguments);
- } else {
- this.pendingInvocations_.push([privateMethod, arguments]);
- }
- return this;
- };
-};
-
-/**
- * Shows modal action picker dialog with currently available list of tasks.
- *
- * @param {DefaultActionDialog} actionDialog Action dialog to show and update.
- * @param {string} title Title to use.
- * @param {string} message Message to use.
- * @param {function(Object)} onSuccess Callback to pass selected task.
- */
-FileTasks.prototype.showTaskPicker = function(actionDialog, title, message,
- onSuccess) {
- var items = this.createItems_();
-
- var defaultIdx = 0;
- for (var j = 0; j < items.length; j++) {
- if (items[j].task.taskId === this.defaultTask_.taskId)
- defaultIdx = j;
- }
-
- actionDialog.show(
- title,
- message,
- items, defaultIdx,
- function(item) {
- onSuccess(item.task);
- });
-};
-
-FileTasks.decorate('display');
-FileTasks.decorate('updateMenuItem');
-FileTasks.decorate('execute');
-FileTasks.decorate('executeDefault');
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/file_transfer_controller.js b/chromium/chrome/browser/resources/file_manager/foreground/js/file_transfer_controller.js
deleted file mode 100644
index 3f8900c88d1..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/file_transfer_controller.js
+++ /dev/null
@@ -1,860 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Global (placed in the window object) variable name to hold internal
- * file dragging information. Needed to show visual feedback while dragging
- * since DataTransfer object is in protected state. Reachable from other
- * file manager instances.
- */
-var DRAG_AND_DROP_GLOBAL_DATA = '__drag_and_drop_global_data';
-
-/**
- * @param {HTMLDocument} doc Owning document.
- * @param {FileOperationManager} fileOperationManager File operation manager
- * instance.
- * @param {MetadataCache} metadataCache Metadata cache service.
- * @param {DirectoryModel} directoryModel Directory model instance.
- * @constructor
- */
-function FileTransferController(doc,
- fileOperationManager,
- metadataCache,
- directoryModel) {
- this.document_ = doc;
- this.fileOperationManager_ = fileOperationManager;
- this.metadataCache_ = metadataCache;
- this.directoryModel_ = directoryModel;
-
- this.directoryModel_.getFileListSelection().addEventListener('change',
- this.onSelectionChanged_.bind(this));
-
- /**
- * DOM element to represent selected file in drag operation. Used if only
- * one element is selected.
- * @type {HTMLElement}
- * @private
- */
- this.preloadedThumbnailImageNode_ = null;
-
- /**
- * File objects for selected files.
- *
- * @type {Array.<File>}
- * @private
- */
- this.selectedFileObjects_ = [];
-
- /**
- * Drag selector.
- * @type {DragSelector}
- * @private
- */
- this.dragSelector_ = new DragSelector();
-
- /**
- * Whether a user is touching the device or not.
- * @type {boolean}
- * @private
- */
- this.touching_ = false;
-}
-
-FileTransferController.prototype = {
- __proto__: cr.EventTarget.prototype,
-
- /**
- * @this {FileTransferController}
- * @param {cr.ui.List} list Items in the list will be draggable.
- */
- attachDragSource: function(list) {
- list.style.webkitUserDrag = 'element';
- list.addEventListener('dragstart', this.onDragStart_.bind(this, list));
- list.addEventListener('dragend', this.onDragEnd_.bind(this, list));
- list.addEventListener('touchstart', this.onTouchStart_.bind(this));
- list.addEventListener('touchend', this.onTouchEnd_.bind(this));
- },
-
- /**
- * @this {FileTransferController}
- * @param {cr.ui.List} list List itself and its directory items will could
- * be drop target.
- * @param {boolean=} opt_onlyIntoDirectories If true only directory list
- * items could be drop targets. Otherwise any other place of the list
- * accetps files (putting it into the current directory).
- */
- attachFileListDropTarget: function(list, opt_onlyIntoDirectories) {
- list.addEventListener('dragover', this.onDragOver_.bind(this,
- !!opt_onlyIntoDirectories, list));
- list.addEventListener('dragenter',
- this.onDragEnterFileList_.bind(this, list));
- list.addEventListener('dragleave', this.onDragLeave_.bind(this, list));
- list.addEventListener('drop',
- this.onDrop_.bind(this, !!opt_onlyIntoDirectories));
- },
-
- /**
- * @this {FileTransferController}
- * @param {DirectoryTree} tree Its sub items will could be drop target.
- */
- attachTreeDropTarget: function(tree) {
- tree.addEventListener('dragover', this.onDragOver_.bind(this, true, tree));
- tree.addEventListener('dragenter', this.onDragEnterTree_.bind(this, tree));
- tree.addEventListener('dragleave', this.onDragLeave_.bind(this, tree));
- tree.addEventListener('drop', this.onDrop_.bind(this, true));
- },
-
- /**
- * @this {FileTransferController}
- * @param {NavigationList} tree Its sub items will could be drop target.
- */
- attachNavigationListDropTarget: function(list) {
- list.addEventListener('dragover',
- this.onDragOver_.bind(this, true /* onlyIntoDirectories */, list));
- list.addEventListener('dragenter',
- this.onDragEnterVolumesList_.bind(this, list));
- list.addEventListener('dragleave', this.onDragLeave_.bind(this, list));
- list.addEventListener('drop',
- this.onDrop_.bind(this, true /* onlyIntoDirectories */));
- },
-
- /**
- * Attach handlers of copy, cut and paste operations to the document.
- *
- * @this {FileTransferController}
- */
- attachCopyPasteHandlers: function() {
- this.document_.addEventListener('beforecopy',
- this.onBeforeCopy_.bind(this));
- this.document_.addEventListener('copy',
- this.onCopy_.bind(this));
- this.document_.addEventListener('beforecut',
- this.onBeforeCut_.bind(this));
- this.document_.addEventListener('cut',
- this.onCut_.bind(this));
- this.document_.addEventListener('beforepaste',
- this.onBeforePaste_.bind(this));
- this.document_.addEventListener('paste',
- this.onPaste_.bind(this));
- this.copyCommand_ = this.document_.querySelector('command#copy');
- },
-
- /**
- * Write the current selection to system clipboard.
- *
- * @this {FileTransferController}
- * @param {DataTransfer} dataTransfer DataTransfer from the event.
- * @param {string} effectAllowed Value must be valid for the
- * |dataTransfer.effectAllowed| property ('move', 'copy', 'copyMove').
- */
- cutOrCopy_: function(dataTransfer, effectAllowed) {
- // Tag to check it's filemanager data.
- dataTransfer.setData('fs/tag', 'filemanager-data');
- dataTransfer.setData('fs/sourceRoot',
- this.directoryModel_.getCurrentRootPath());
- var sourcePaths =
- this.selectedEntries_.map(function(e) { return e.fullPath; });
- dataTransfer.setData('fs/sources', sourcePaths.join('\n'));
- dataTransfer.effectAllowed = effectAllowed;
- dataTransfer.setData('fs/effectallowed', effectAllowed);
-
- for (var i = 0; i < this.selectedFileObjects_.length; i++) {
- dataTransfer.items.add(this.selectedFileObjects_[i]);
- }
- },
-
- /**
- * Extracts source root from the |dataTransfer| object.
- *
- * @this {FileTransferController}
- * @param {DataTransfer} dataTransfer DataTransfer object from the event.
- * @return {string} Path or empty string (if unknown).
- */
- getSourceRoot_: function(dataTransfer) {
- var sourceRoot = dataTransfer.getData('fs/sourceRoot');
- if (sourceRoot)
- return sourceRoot;
-
- // |dataTransfer| in protected mode.
- if (window[DRAG_AND_DROP_GLOBAL_DATA])
- return window[DRAG_AND_DROP_GLOBAL_DATA].sourceRoot;
-
- // Dragging from other tabs/windows.
- var views = chrome && chrome.extension ? chrome.extension.getViews() : [];
- for (var i = 0; i < views.length; i++) {
- if (views[i][DRAG_AND_DROP_GLOBAL_DATA])
- return views[i][DRAG_AND_DROP_GLOBAL_DATA].sourceRoot;
- }
-
- // Unknown source.
- return '';
- },
-
- /**
- * Queue up a file copy operation based on the current system clipboard.
- *
- * @this {FileTransferController}
- * @param {DataTransfer} dataTransfer System data transfer object.
- * @param {string=} opt_destinationPath Paste destination.
- * @param {string=} opt_effect Desired drop/paste effect. Could be
- * 'move'|'copy' (default is copy). Ignored if conflicts with
- * |dataTransfer.effectAllowed|.
- * @return {string} Either "copy" or "move".
- */
- paste: function(dataTransfer, opt_destinationPath, opt_effect) {
- var sourcePaths = (dataTransfer.getData('fs/sources') || '').split('\n');
- var destinationPath = opt_destinationPath ||
- this.currentDirectoryContentPath;
- // effectAllowed set in copy/paste handlers stay uninitialized. DnD handlers
- // work fine.
- var effectAllowed = dataTransfer.effectAllowed != 'uninitialized' ?
- dataTransfer.effectAllowed : dataTransfer.getData('fs/effectallowed');
- var toMove = effectAllowed == 'move' ||
- (effectAllowed == 'copyMove' && opt_effect == 'move');
-
- // Start the pasting operation.
- this.fileOperationManager_.paste(sourcePaths, destinationPath, toMove);
- return toMove ? 'move' : 'copy';
- },
-
- /**
- * Preloads an image thumbnail for the specified file entry.
- *
- * @this {FileTransferController}
- * @param {Entry} entry Entry to preload a thumbnail for.
- */
- preloadThumbnailImage_: function(entry) {
- var metadataTypes = 'thumbnail|filesystem';
- var thumbnailContainer = this.document_.createElement('div');
- this.preloadedThumbnailImageNode_ = thumbnailContainer;
- this.preloadedThumbnailImageNode_.className = 'img-container';
- this.metadataCache_.get(
- entry,
- metadataTypes,
- function(metadata) {
- new ThumbnailLoader(entry.toURL(),
- ThumbnailLoader.LoaderType.IMAGE,
- metadata).
- load(thumbnailContainer,
- ThumbnailLoader.FillMode.FILL);
- }.bind(this));
- },
-
- /**
- * Renders a drag-and-drop thumbnail.
- *
- * @this {FileTransferController}
- * @return {HTMLElement} Element containing the thumbnail.
- */
- renderThumbnail_: function() {
- var length = this.selectedEntries_.length;
-
- var container = this.document_.querySelector('#drag-container');
- var contents = this.document_.createElement('div');
- contents.className = 'drag-contents';
- container.appendChild(contents);
-
- var thumbnailImage;
- if (this.preloadedThumbnailImageNode_)
- thumbnailImage = this.preloadedThumbnailImageNode_.querySelector('img');
-
- // Option 1. Multiple selection, render only a label.
- if (length > 1) {
- var label = this.document_.createElement('div');
- label.className = 'label';
- label.textContent = strf('DRAGGING_MULTIPLE_ITEMS', length);
- contents.appendChild(label);
- return container;
- }
-
- // Option 2. Thumbnail image available, then render it without
- // a label.
- if (thumbnailImage) {
- thumbnailImage.classList.add('drag-thumbnail');
- contents.classList.add('for-image');
- contents.appendChild(this.preloadedThumbnailImageNode_);
- return container;
- }
-
- // Option 3. Thumbnail not available. Render an icon and a label.
- var entry = this.selectedEntries_[0];
- var icon = this.document_.createElement('div');
- icon.className = 'detail-icon';
- icon.setAttribute('file-type-icon', FileType.getIcon(entry));
- contents.appendChild(icon);
- var label = this.document_.createElement('div');
- label.className = 'label';
- label.textContent = entry.name;
- contents.appendChild(label);
- return container;
- },
-
- /**
- * @this {FileTransferController}
- * @param {cr.ui.List} list Drop target list
- * @param {Event} event A dragstart event of DOM.
- */
- onDragStart_: function(list, event) {
- // If a user is touching, Files.app does not receive drag operations.
- if (this.touching_) {
- event.preventDefault();
- return;
- }
-
- // Check if a drag selection should be initiated or not.
- if (list.shouldStartDragSelection(event)) {
- this.dragSelector_.startDragSelection(list, event);
- return;
- }
-
- // Nothing selected.
- if (!this.selectedEntries_.length) {
- event.preventDefault();
- return;
- }
-
- var dt = event.dataTransfer;
-
- if (this.canCopyOrDrag_(dt)) {
- if (this.canCutOrDrag_(dt))
- this.cutOrCopy_(dt, 'copyMove');
- else
- this.cutOrCopy_(dt, 'copy');
- } else {
- event.preventDefault();
- return;
- }
-
- var dragThumbnail = this.renderThumbnail_();
- dt.setDragImage(dragThumbnail, 1000, 1000);
-
- window[DRAG_AND_DROP_GLOBAL_DATA] = {
- sourceRoot: this.directoryModel_.getCurrentRootPath()
- };
- },
-
- /**
- * @this {FileTransferController}
- * @param {cr.ui.List} list Drop target list.
- * @param {Event} event A dragend event of DOM.
- */
- onDragEnd_: function(list, event) {
- var container = this.document_.querySelector('#drag-container');
- container.textContent = '';
- this.clearDropTarget_();
- delete window[DRAG_AND_DROP_GLOBAL_DATA];
- },
-
- /**
- * @this {FileTransferController}
- * @param {boolean} onlyIntoDirectories True if the drag is only into
- * directories.
- * @param {cr.ui.List} list Drop target list.
- * @param {Event} event A dragover event of DOM.
- */
- onDragOver_: function(onlyIntoDirectories, list, event) {
- event.preventDefault();
- var path = this.destinationPath_ ||
- (!onlyIntoDirectories && this.currentDirectoryContentPath);
- event.dataTransfer.dropEffect = this.selectDropEffect_(event, path);
- event.preventDefault();
- },
-
- /**
- * @this {FileTransferController}
- * @param {cr.ui.List} list Drop target list.
- * @param {Event} event A dragenter event of DOM.
- */
- onDragEnterFileList_: function(list, event) {
- event.preventDefault(); // Required to prevent the cursor flicker.
- this.lastEnteredTarget_ = event.target;
- var item = list.getListItemAncestor(event.target);
- item = item && list.isItem(item) ? item : null;
- if (item == this.dropTarget_)
- return;
-
- var entry = item && list.dataModel.item(item.listIndex);
- if (entry) {
- this.setDropTarget_(item, entry.isDirectory, event.dataTransfer,
- entry.fullPath);
- } else {
- this.clearDropTarget_();
- }
- },
-
- /**
- * @this {FileTransferController}
- * @param {DirectoryTree} tree Drop target tree.
- * @param {Event} event A dragenter event of DOM.
- */
- onDragEnterTree_: function(tree, event) {
- event.preventDefault(); // Required to prevent the cursor flicker.
- this.lastEnteredTarget_ = event.target;
- var item = event.target;
- while (item && !(item instanceof DirectoryItem)) {
- item = item.parentNode;
- }
-
- if (item == this.dropTarget_)
- return;
-
- var entry = item && item.entry;
- if (entry) {
- this.setDropTarget_(item, entry.isDirectory, event.dataTransfer,
- entry.fullPath);
- } else {
- this.clearDropTarget_();
- }
- },
-
- /**
- * @this {FileTransferController}
- * @param {NavigationList} list Drop target list.
- * @param {Event} event A dragenter event of DOM.
- */
- onDragEnterVolumesList_: function(list, event) {
- event.preventDefault(); // Required to prevent the cursor flicker.
- this.lastEnteredTarget_ = event.target;
- var item = list.getListItemAncestor(event.target);
- item = item && list.isItem(item) ? item : null;
- if (item == this.dropTarget_)
- return;
-
- var path = item && list.dataModel.item(item.listIndex).path;
- if (path)
- this.setDropTarget_(item, true /* directory */, event.dataTransfer, path);
- else
- this.clearDropTarget_();
- },
-
- /**
- * @this {FileTransferController}
- * @param {cr.ui.List} list Drop target list.
- * @param {Event} event A dragleave event of DOM.
- */
- onDragLeave_: function(list, event) {
- // If mouse moves from one element to another the 'dragenter'
- // event for the new element comes before the 'dragleave' event for
- // the old one. In this case event.target != this.lastEnteredTarget_
- // and handler of the 'dragenter' event has already caried of
- // drop target. So event.target == this.lastEnteredTarget_
- // could only be if mouse goes out of listened element.
- if (event.target == this.lastEnteredTarget_) {
- this.clearDropTarget_();
- this.lastEnteredTarget_ = null;
- }
- },
-
- /**
- * @this {FileTransferController}
- * @param {boolean} onlyIntoDirectories True if the drag is only into
- * directories.
- * @param {Event} event A dragleave event of DOM.
- */
- onDrop_: function(onlyIntoDirectories, event) {
- if (onlyIntoDirectories && !this.dropTarget_)
- return;
- var destinationPath = this.destinationPath_ ||
- this.currentDirectoryContentPath;
- if (!this.canPasteOrDrop_(event.dataTransfer, destinationPath))
- return;
- event.preventDefault();
- this.paste(event.dataTransfer, destinationPath,
- this.selectDropEffect_(event, destinationPath));
- this.clearDropTarget_();
- },
-
- /**
- * Sets the drop target.
- * @this {FileTransferController}
- * @param {Element} domElement Target of the drop.
- * @param {boolean} isDirectory If the target is a directory.
- * @param {DataTransfer} dataTransfer Data transfer object.
- * @param {string} destinationPath Destination path.
- */
- setDropTarget_: function(domElement, isDirectory, dataTransfer,
- destinationPath) {
- if (this.dropTarget_ == domElement)
- return;
-
- // Remove the old drop target.
- this.clearDropTarget_();
-
- // Set the new drop target.
- this.dropTarget_ = domElement;
-
- if (!domElement ||
- !isDirectory ||
- !this.canPasteOrDrop_(dataTransfer, destinationPath)) {
- return;
- }
-
- // Add accept class if the domElement can accept the drag.
- domElement.classList.add('accepts');
- this.destinationPath_ = destinationPath;
-
- // Start timer changing the directory.
- this.navigateTimer_ = setTimeout(function() {
- if (domElement instanceof DirectoryItem)
- // Do custom action.
- (/** @type {DirectoryItem} */ domElement).doDropTargetAction();
- this.directoryModel_.changeDirectory(destinationPath);
- }.bind(this), 2000);
- },
-
- /**
- * Handles touch start.
- */
- onTouchStart_: function() {
- this.touching_ = true;
- },
-
- /**
- * Handles touch end.
- */
- onTouchEnd_: function(event) {
- if (event.touches.length === 0)
- this.touching_ = false;
- },
-
- /**
- * Clears the drop target.
- * @this {FileTransferController}
- */
- clearDropTarget_: function() {
- if (this.dropTarget_ && this.dropTarget_.classList.contains('accepts'))
- this.dropTarget_.classList.remove('accepts');
- this.dropTarget_ = null;
- this.destinationPath_ = null;
- if (this.navigateTimer_ !== undefined) {
- clearTimeout(this.navigateTimer_);
- this.navigateTimer_ = undefined;
- }
- },
-
- /**
- * @this {FileTransferController}
- * @return {boolean} Returns false if {@code <input type="text">} element is
- * currently active. Otherwise, returns true.
- */
- isDocumentWideEvent_: function() {
- return this.document_.activeElement.nodeName.toLowerCase() != 'input' ||
- this.document_.activeElement.type.toLowerCase() != 'text';
- },
-
- /**
- * @this {FileTransferController}
- */
- onCopy_: function(event) {
- if (!this.isDocumentWideEvent_() ||
- !this.canCopyOrDrag_()) {
- return;
- }
- event.preventDefault();
- this.cutOrCopy_(event.clipboardData, 'copy');
- this.notify_('selection-copied');
- },
-
- /**
- * @this {FileTransferController}
- */
- onBeforeCopy_: function(event) {
- if (!this.isDocumentWideEvent_())
- return;
-
- // queryCommandEnabled returns true if event.defaultPrevented is true.
- if (this.canCopyOrDrag_())
- event.preventDefault();
- },
-
- /**
- * @this {FileTransferController}
- * @return {boolean} Returns true if some files are selected and all the file
- * on drive is available to be copied. Otherwise, returns false.
- */
- canCopyOrDrag_: function() {
- if (this.isOnDrive &&
- this.directoryModel_.isDriveOffline() &&
- !this.allDriveFilesAvailable)
- return false;
- return this.selectedEntries_.length > 0;
- },
-
- /**
- * @this {FileTransferController}
- */
- onCut_: function(event) {
- if (!this.isDocumentWideEvent_() ||
- !this.canCutOrDrag_()) {
- return;
- }
- event.preventDefault();
- this.cutOrCopy_(event.clipboardData, 'move');
- this.notify_('selection-cut');
- },
-
- /**
- * @this {FileTransferController}
- */
- onBeforeCut_: function(event) {
- if (!this.isDocumentWideEvent_())
- return;
- // queryCommandEnabled returns true if event.defaultPrevented is true.
- if (this.canCutOrDrag_())
- event.preventDefault();
- },
-
- /**
- * @this {FileTransferController}
- * @return {boolean} Returns true if some files are selected and all the file
- * on drive is available to be cut. Otherwise, returns false.
- */
- canCutOrDrag_: function() {
- return !this.readonly && this.canCopyOrDrag_();
- },
-
- /**
- * @this {FileTransferController}
- */
- onPaste_: function(event) {
- // Need to update here since 'beforepaste' doesn't fire.
- if (!this.isDocumentWideEvent_() ||
- !this.canPasteOrDrop_(event.clipboardData,
- this.currentDirectoryContentPath)) {
- return;
- }
- event.preventDefault();
- var effect = this.paste(event.clipboardData);
-
- // On cut, we clear the clipboard after the file is pasted/moved so we don't
- // try to move/delete the original file again.
- if (effect == 'move') {
- this.simulateCommand_('cut', function(event) {
- event.preventDefault();
- event.clipboardData.setData('fs/clear', '');
- });
- }
- },
-
- /**
- * @this {FileTransferController}
- */
- onBeforePaste_: function(event) {
- if (!this.isDocumentWideEvent_())
- return;
- // queryCommandEnabled returns true if event.defaultPrevented is true.
- if (this.canPasteOrDrop_(event.clipboardData,
- this.currentDirectoryContentPath)) {
- event.preventDefault();
- }
- },
-
- /**
- * @this {FileTransferController}
- * @param {DataTransfer} dataTransfer Data transfer object.
- * @param {string?} destinationPath Destination path.
- * @return {boolean} Returns true if items stored in {@code dataTransfer} can
- * be pasted to {@code destinationPath}. Otherwise, returns false.
- */
- canPasteOrDrop_: function(dataTransfer, destinationPath) {
- if (!destinationPath) {
- return false;
- }
- if (this.directoryModel_.isPathReadOnly(destinationPath)) {
- return false;
- }
- if (!dataTransfer.types || dataTransfer.types.indexOf('fs/tag') == -1) {
- return false; // Unsupported type of content.
- }
- if (dataTransfer.getData('fs/tag') == '') {
- // Data protected. Other checks are not possible but it makes sense to
- // let the user try.
- return true;
- }
-
- var directories = dataTransfer.getData('fs/directories').split('\n').
- filter(function(d) { return d != ''; });
-
- for (var i = 0; i < directories.length; i++) {
- if (destinationPath.substr(0, directories[i].length) == directories[i])
- return false; // recursive paste.
- }
-
- return true;
- },
-
- /**
- * Execute paste command.
- *
- * @this {FileTransferController}
- * @return {boolean} Returns true, the paste is success. Otherwise, returns
- * false.
- */
- queryPasteCommandEnabled: function() {
- if (!this.isDocumentWideEvent_()) {
- return false;
- }
-
- // HACK(serya): return this.document_.queryCommandEnabled('paste')
- // should be used.
- var result;
- this.simulateCommand_('paste', function(event) {
- result = this.canPasteOrDrop_(event.clipboardData,
- this.currentDirectoryContentPath);
- }.bind(this));
- return result;
- },
-
- /**
- * Allows to simulate commands to get access to clipboard.
- *
- * @this {FileTransferController}
- * @param {string} command 'copy', 'cut' or 'paste'.
- * @param {function} handler Event handler.
- */
- simulateCommand_: function(command, handler) {
- var iframe = this.document_.querySelector('#command-dispatcher');
- var doc = iframe.contentDocument;
- doc.addEventListener(command, handler);
- doc.execCommand(command);
- doc.removeEventListener(command, handler);
- },
-
- /**
- * @this {FileTransferController}
- */
- onSelectionChanged_: function(event) {
- var entries = this.selectedEntries_;
- var files = this.selectedFileObjects_ = [];
- this.preloadedThumbnailImageNode_ = null;
-
- var fileEntries = [];
- for (var i = 0; i < entries.length; i++) {
- if (entries[i].isFile)
- fileEntries.push(entries[i]);
- }
-
- if (entries.length == 1) {
- // For single selection, the dragged element is created in advance,
- // otherwise an image may not be loaded at the time the 'dragstart' event
- // comes.
- this.preloadThumbnailImage_(entries[0]);
- }
-
- // File object must be prepeared in advance for clipboard operations
- // (copy, paste and drag). DataTransfer object closes for write after
- // returning control from that handlers so they may not have
- // asynchronous operations.
- var prepareFileObjects = function() {
- for (var i = 0; i < fileEntries.length; i++) {
- fileEntries[i].file(function(file) { files.push(file); });
- }
- };
-
- if (this.isOnDrive) {
- this.allDriveFilesAvailable = false;
- this.metadataCache_.get(
- entries, 'drive', function(props) {
- // We consider directories not available offline for the purposes of
- // file transfer since we cannot afford to recursive traversal.
- this.allDriveFilesAvailable =
- entries.filter(function(e) {return e.isDirectory}).length == 0 &&
- props.filter(function(p) {return !p.availableOffline}).length == 0;
- // |Copy| is the only menu item affected by allDriveFilesAvailable.
- // It could be open right now, update its UI.
- this.copyCommand_.disabled = !this.canCopyOrDrag_();
-
- if (this.allDriveFilesAvailable)
- prepareFileObjects();
- }.bind(this));
- } else {
- prepareFileObjects();
- }
- },
-
- /**
- * Path of directory that is displaying now.
- * If search result is displaying now, this is null.
- * @this {FileTransferController}
- * @return {string} Path of directry that is displaying now.
- */
- get currentDirectoryContentPath() {
- return this.directoryModel_.isSearching() ?
- null : this.directoryModel_.getCurrentDirPath();
- },
-
- /**
- * @this {FileTransferController}
- * @return {boolean} True if the current directory is read only.
- */
- get readonly() {
- return this.directoryModel_.isReadOnly();
- },
-
- /**
- * @this {FileTransferController}
- * @return {boolean} True if the current directory is on Drive.
- */
- get isOnDrive() {
- return PathUtil.isDriveBasedPath(this.directoryModel_.getCurrentRootPath());
- },
-
- /**
- * @this {FileTransferController}
- */
- notify_: function(eventName) {
- var self = this;
- // Set timeout to avoid recursive events.
- setTimeout(function() {
- cr.dispatchSimpleEvent(self, eventName);
- }, 0);
- },
-
- /**
- * @this {FileTransferController}
- * @return {Array.<Entry>} Array of the selected entries.
- */
- get selectedEntries_() {
- var list = this.directoryModel_.getFileList();
- var selectedIndexes = this.directoryModel_.getFileListSelection().
- selectedIndexes;
- var entries = selectedIndexes.map(function(index) {
- return list.item(index);
- });
-
- // TODO(serya): Diagnostics for http://crbug/129642
- if (entries.indexOf(undefined) != -1) {
- var index = entries.indexOf(undefined);
- entries = entries.filter(function(e) { return !!e; });
- console.error('Invalid selection found: list items: ', list.length,
- 'wrong indexe value: ', selectedIndexes[index],
- 'Stack trace: ', new Error().stack);
- }
- return entries;
- },
-
- /**
- * @this {FileTransferController}
- * @return {string} Returns the appropriate drop query type ('none', 'move'
- * or copy') to the current modifiers status and the destination.
- */
- selectDropEffect_: function(event, destinationPath) {
- if (!destinationPath ||
- this.directoryModel_.isPathReadOnly(destinationPath))
- return 'none';
- if (event.dataTransfer.effectAllowed == 'copyMove' &&
- this.getSourceRoot_(event.dataTransfer) ==
- PathUtil.getRootPath(destinationPath) &&
- !event.ctrlKey) {
- return 'move';
- }
- if (event.dataTransfer.effectAllowed == 'copyMove' &&
- event.shiftKey) {
- return 'move';
- }
- return 'copy';
- },
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/file_type.js b/chromium/chrome/browser/resources/file_manager/foreground/js/file_type.js
deleted file mode 100644
index ea0ae9278ee..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/file_type.js
+++ /dev/null
@@ -1,294 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Namespace object for file type utility functions.
- */
-var FileType = {};
-
-/**
- * Description of known file types.
- * Pair type-subtype defines order when sorted by file type.
- */
-FileType.types = [
- // Images
- {type: 'image', name: 'IMAGE_FILE_TYPE', subtype: 'JPEG',
- pattern: /\.jpe?g$/i},
- {type: 'image', name: 'IMAGE_FILE_TYPE', subtype: 'BMP',
- pattern: /\.bmp$/i},
- {type: 'image', name: 'IMAGE_FILE_TYPE', subtype: 'GIF',
- pattern: /\.gif$/i},
- {type: 'image', name: 'IMAGE_FILE_TYPE', subtype: 'ICO',
- pattern: /\.ico$/i},
- {type: 'image', name: 'IMAGE_FILE_TYPE', subtype: 'PNG',
- pattern: /\.png$/i},
- {type: 'image', name: 'IMAGE_FILE_TYPE', subtype: 'WebP',
- pattern: /\.webp$/i},
- {type: 'image', name: 'IMAGE_FILE_TYPE', subtype: 'TIFF',
- pattern: /\.tiff?$/i},
-
- // Video
- {type: 'video', name: 'VIDEO_FILE_TYPE', subtype: '3GP',
- pattern: /\.3gp$/i},
- {type: 'video', name: 'VIDEO_FILE_TYPE', subtype: 'AVI',
- pattern: /\.avi$/i},
- {type: 'video', name: 'VIDEO_FILE_TYPE', subtype: 'QuickTime',
- pattern: /\.mov$/i},
- {type: 'video', name: 'VIDEO_FILE_TYPE', subtype: 'MKV',
- pattern: /\.mkv$/i},
- {type: 'video', name: 'VIDEO_FILE_TYPE', subtype: 'MPEG',
- pattern: /\.m(p4|4v|pg|peg|pg4|peg4)$/i},
- {type: 'video', name: 'VIDEO_FILE_TYPE', subtype: 'OGG',
- pattern: /\.og(m|v|x)$/i},
- {type: 'video', name: 'VIDEO_FILE_TYPE', subtype: 'WebM',
- pattern: /\.webm$/i},
-
- // Audio
- {type: 'audio', name: 'AUDIO_FILE_TYPE', subtype: 'AMR',
- pattern: /\.amr$/i},
- {type: 'audio', name: 'AUDIO_FILE_TYPE', subtype: 'FLAC',
- pattern: /\.flac$/i},
- {type: 'audio', name: 'AUDIO_FILE_TYPE', subtype: 'MP3',
- pattern: /\.mp3$/i},
- {type: 'audio', name: 'AUDIO_FILE_TYPE', subtype: 'MPEG',
- pattern: /\.m4a$/i},
- {type: 'audio', name: 'AUDIO_FILE_TYPE', subtype: 'OGG',
- pattern: /\.og(a|g)$/i},
- {type: 'audio', name: 'AUDIO_FILE_TYPE', subtype: 'WAV',
- pattern: /\.wav$/i},
-
- // Text
- {type: 'text', name: 'PLAIN_TEXT_FILE_TYPE', subtype: 'TXT',
- pattern: /\.txt$/i},
-
- // Archive
- {type: 'archive', name: 'ZIP_ARCHIVE_FILE_TYPE', subtype: 'ZIP',
- pattern: /\.zip$/i},
- {type: 'archive', name: 'RAR_ARCHIVE_FILE_TYPE', subtype: 'RAR',
- pattern: /\.rar$/i},
- {type: 'archive', name: 'TAR_ARCHIVE_FILE_TYPE', subtype: 'TAR',
- pattern: /\.tar$/i},
- {type: 'archive', name: 'TAR_BZIP2_ARCHIVE_FILE_TYPE', subtype: 'TBZ2',
- pattern: /\.(tar\.bz2|tbz|tbz2)$/i},
- {type: 'archive', name: 'TAR_GZIP_ARCHIVE_FILE_TYPE', subtype: 'TGZ',
- pattern: /\.(tar\.|t)gz$/i},
-
- // Hosted docs.
- {type: 'hosted', icon: 'gdoc', name: 'GDOC_DOCUMENT_FILE_TYPE',
- subtype: 'doc', pattern: /\.gdoc$/i},
- {type: 'hosted', icon: 'gsheet', name: 'GSHEET_DOCUMENT_FILE_TYPE',
- subtype: 'sheet', pattern: /\.gsheet$/i},
- {type: 'hosted', icon: 'gslides', name: 'GSLIDES_DOCUMENT_FILE_TYPE',
- subtype: 'slides', pattern: /\.gslides$/i},
- {type: 'hosted', icon: 'gdraw', name: 'GDRAW_DOCUMENT_FILE_TYPE',
- subtype: 'draw', pattern: /\.gdraw$/i},
- {type: 'hosted', icon: 'gtable', name: 'GTABLE_DOCUMENT_FILE_TYPE',
- subtype: 'table', pattern: /\.gtable$/i},
- {type: 'hosted', icon: 'glink', name: 'GLINK_DOCUMENT_FILE_TYPE',
- subtype: 'glink', pattern: /\.glink$/i},
- {type: 'hosted', icon: 'gform', name: 'GFORM_DOCUMENT_FILE_TYPE',
- subtype: 'form', pattern: /\.gform$/i},
-
- // Others
- {type: 'document', icon: 'pdf', name: 'PDF_DOCUMENT_FILE_TYPE',
- subtype: 'PDF', pattern: /\.pdf$/i},
- {type: 'document', name: 'HTML_DOCUMENT_FILE_TYPE',
- subtype: 'HTML', pattern: /\.(html?|mht|mhtml)$/i},
- {type: 'document', icon: 'word', name: 'WORD_DOCUMENT_FILE_TYPE',
- subtype: 'Word', pattern: /\.(doc|docx)$/i},
- {type: 'document', icon: 'ppt', name: 'POWERPOINT_PRESENTATION_FILE_TYPE',
- subtype: 'PPT', pattern: /\.(ppt|pptx)$/i},
- {type: 'document', icon: 'excel', name: 'EXCEL_FILE_TYPE',
- subtype: 'Excel', pattern: /\.(xls|xlsx)$/i}
-];
-
-/**
- * A special type for directory.
- */
-FileType.DIRECTORY = {name: 'FOLDER', type: '.folder', icon: 'folder'};
-
-/**
- * Returns the file path extension for a given file.
- *
- * @param {string|Entry} file Reference to the file.
- * Can be a name, a path, a url or a File API Entry.
- * @return {string} The extension including a leading '.', or empty string if
- * not found.
- */
-FileType.getExtension = function(file) {
- var fileName;
- if (typeof file == 'object') {
- if (file.isDirectory) {
- // No extension for a directory.
- return '';
- } else {
- fileName = file.name;
- }
- } else {
- fileName = file;
- }
-
- var extensionStartIndex = fileName.lastIndexOf('.');
- if (extensionStartIndex == -1 || extensionStartIndex == fileName.length - 1) {
- return '';
- }
- return fileName.substr(extensionStartIndex);
-};
-
-/**
- * Get the file type object for a given file.
- *
- * @param {string|Entry} file Reference to the file.
- * Can be a name, a path, a url or a File API Entry.
- * @return {Object} The matching file type object or an empty object.
- */
-FileType.getType = function(file) {
- if (typeof file == 'object') {
- if (file.isDirectory)
- return FileType.DIRECTORY;
- else
- file = file.name;
- }
- var types = FileType.types;
- for (var i = 0; i < types.length; i++) {
- if (types[i].pattern.test(file)) {
- return types[i];
- }
- }
-
- // Unknown file type.
- var extension = FileType.getExtension(file);
- if (extension == '') {
- return { name: 'NO_EXTENSION_FILE_TYPE', type: 'UNKNOWN', icon: '' };
- }
- // subtype is the extension excluding the first dot.
- return { name: 'GENERIC_FILE_TYPE', type: 'UNKNOWN',
- subtype: extension.substr(1).toUpperCase(), icon: '' };
-};
-
-/**
- * @param {string|Entry} file Reference to the file.
- * Can be a name, a path, a url or a File API Entry.
- * @return {string} Localized string representation of file type.
- */
-FileType.getTypeString = function(file) {
- var fileType = FileType.getType(file);
- if (fileType.subtype)
- return strf(fileType.name, fileType.subtype);
- else
- return str(fileType.name);
-};
-
-/**
- * Pattern for urls pointing to Google Drive files.
- */
-FileType.DRIVE_URL_PATTERN =
- new RegExp('^filesystem:[^/]*://[^/]*/[^/]*/drive/(.*)');
-
-/**
- * Pattern for file paths pointing to Google Drive files.
- */
-FileType.DRIVE_PATH_PATTERN =
- new RegExp('^/drive/');
-
-/**
- * @param {string|Entry} file The url string or entry.
- * @return {boolean} Whether this provider supports the url.
- */
-FileType.isOnDrive = function(file) {
- return typeof file == 'string' ?
- FileType.DRIVE_URL_PATTERN.test(file) :
- FileType.DRIVE_PATH_PATTERN.test(file.fullPath);
-};
-
-
-/**
- * Get the media type for a given file.
- *
- * @param {string|Entry} file Reference to the file.
- * @return {string} The value of 'type' property from one of the elements in
- * FileType.types or undefined.
- */
-FileType.getMediaType = function(file) {
- return FileType.getType(file).type;
-};
-
-/**
- * @param {string|Entry} file Reference to the file.
- * @return {boolean} True if audio file.
- */
-FileType.isAudio = function(file) {
- return FileType.getMediaType(file) == 'audio';
-};
-
-/**
- * @param {string|Entry} file Reference to the file.
- * @return {boolean} True if image file.
- */
-FileType.isImage = function(file) {
- return FileType.getMediaType(file) == 'image';
-};
-
-/**
- * @param {string|Entry} file Reference to the file.
- * @return {boolean} True if video file.
- */
-FileType.isVideo = function(file) {
- return FileType.getMediaType(file) == 'video';
-};
-
-
-/**
- * Files with more pixels won't have preview.
- * @param {string|Entry} file Reference to the file.
- * @return {boolean} True if image or video.
- */
-FileType.isImageOrVideo = function(file) {
- var type = FileType.getMediaType(file);
- return type == 'image' || type == 'video';
-};
-
-/**
- * @param {string|Entry} file Reference to the file.
- * @return {boolean} Returns true if the file is hosted.
- */
-FileType.isHosted = function(file) {
- return FileType.getType(file).type === 'hosted';
-};
-
-/**
- * @param {string|Entry} file Reference to the file.
- * @return {boolean} Returns true if the file is not hidden, and we should
- * display it.
- */
-FileType.isVisible = function(file) {
- if (typeof file == 'object') {
- file = file.name;
- }
-
- var path = util.extractFilePath(file);
- if (path) file = path;
-
- file = file.split('/').pop();
- return file.indexOf('.') != 0 && !(file in FileType.HIDDEN_NAMES);
-};
-
-/**
- * File/directory names that we know are usually hidden.
- */
-FileType.HIDDEN_NAMES = {
- 'RECYCLED': true
-};
-
-/**
- * @param {string|Entry} file Reference to the file.
- * @return {string} Returns string that represents the file icon.
- * It refers to a file 'images/filetype_' + icon + '.png'.
- */
-FileType.getIcon = function(file) {
- var fileType = FileType.getType(file);
- return fileType.icon || fileType.type || 'unknown';
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/file_watcher.js b/chromium/chrome/browser/resources/file_manager/foreground/js/file_watcher.js
deleted file mode 100644
index a6414e61f4a..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/file_watcher.js
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Watches for changes in the tracked directory, including local metadata
- * changes.
- *
- * @param {MetadataCache} metadataCache Instance of MetadataCache.
- * @extends {cr.EventTarget}
- * @constructor
- */
-function FileWatcher(metadataCache) {
- this.queue_ = new AsyncUtil.Queue();
- this.metadataCache_ = metadataCache;
- this.watchedDirectoryEntry_ = null;
-
- this.onDirectoryChangedBound_ = this.onDirectoryChanged_.bind(this);
- chrome.fileBrowserPrivate.onDirectoryChanged.addListener(
- this.onDirectoryChangedBound_);
-
- this.filesystemMetadataObserverId_ = null;
- this.thumbnailMetadataObserverId_ = null;
- this.driveMetadataObserverId_ = null;
-}
-
-/**
- * FileWatcher extends cr.EventTarget.
- */
-FileWatcher.prototype.__proto__ = cr.EventTarget.prototype;
-
-/**
- * Stops watching (must be called before page unload).
- */
-FileWatcher.prototype.dispose = function() {
- chrome.fileBrowserPrivate.onDirectoryChanged.removeListener(
- this.onDirectoryChangedBound_);
- if (this.watchedDirectoryEntry_)
- this.resetWatchedEntry_(function() {}, function() {});
-};
-
-/**
- * Called when a file in the watched directory is changed.
- * @param {Event} event Change event.
- * @private
- */
-FileWatcher.prototype.onDirectoryChanged_ = function(event) {
- if (this.watchedDirectoryEntry_ &&
- event.entry.toURL() === this.watchedDirectoryEntry_.toURL()) {
- var e = new Event('watcher-directory-changed');
- this.dispatchEvent(e);
- }
-};
-
-/**
- * Called when general metadata in the watched directory has been changed.
- *
- * @param {Array.<Entry>} entries Array of entries.
- * @param {Object.<string, Object>} properties Map from entry URLs to metadata
- * properties.
- * @private
- */
-FileWatcher.prototype.onFilesystemMetadataChanged_ = function(
- entries, properties) {
- this.dispatchMetadataEvent_('filesystem', entries, properties);
-};
-
-/**
- * Called when thumbnail metadata in the watched directory has been changed.
- *
- * @param {Array.<Entry>} entries Arrray of entries.
- * @param {Object.<string, Object>} properties Map from entry URLs to metadata
- * properties.
- * @private
- */
-FileWatcher.prototype.onThumbnailMetadataChanged_ = function(
- entries, properties) {
- this.dispatchMetadataEvent_('thumbnail', entries, properties);
-};
-
-/**
- * Called when drive metadata in the watched directory has been changed.
- *
- * @param {Array.<Entry>} entries Array of entries.
- * @param {Object.<string, Object>} properties Map from entry URLs to metadata
- * properties.
- * @private
- */
-FileWatcher.prototype.onDriveMetadataChanged_ = function(
- entries, properties) {
- this.dispatchMetadataEvent_('drive', entries, properties);
-};
-
-/**
- * Dispatches an event about detected change in metadata within the tracked
- * directory.
- *
- * @param {string} type Type of the metadata change.
- * @param {Array.<Entry>} entries Array of entries.
- * @param {Object.<string, Object>} properties Map from entry URLs to metadata
- * properties.
- * @private
- */
-FileWatcher.prototype.dispatchMetadataEvent_ = function(
- type, entries, properties) {
- var e = new Event('watcher-metadata-changed');
- e.metadataType = type;
- e.entries = entries;
- e.properties = properties;
- this.dispatchEvent(e);
-};
-
-/**
- * Changes the watched directory. In case of a fake entry, the watch is
- * just released, since there is no reason to track a fake directory.
- *
- * @param {!DirectoryEntry|!Object} entry Directory entry to be tracked, or the
- * fake entry.
- * @param {function()} callback Completion callback.
- */
-FileWatcher.prototype.changeWatchedDirectory = function(entry, callback) {
- if (entry && entry.toURL) {
- this.changeWatchedEntry_(
- entry,
- callback,
- function() {
- console.error(
- 'Unable to change the watched directory to: ' + entry.toURL());
- callback();
- });
- } else {
- this.resetWatchedEntry_(
- callback,
- function() {
- console.error('Unable to reset the watched directory.');
- callback();
- });
- }
-};
-
-/**
- * Resets the watched entry to the passed directory.
- *
- * @param {function()} onSuccess Success callback.
- * @param {function()} onError Error callback.
- * @private
- */
-FileWatcher.prototype.resetWatchedEntry_ = function(onSuccess, onError) {
- // Run the tasks in the queue to avoid races.
- this.queue_.run(function(callback) {
- // Release the watched directory.
- if (this.watchedDirectoryEntry_) {
- chrome.fileBrowserPrivate.removeFileWatch(
- this.watchedDirectoryEntry_.toURL(),
- function(result) {
- this.watchedDirectoryEntry_ = null;
- if (result)
- onSuccess();
- else
- onError();
- callback();
- }.bind(this));
- this.metadataCache_.removeObserver(this.filesystemMetadataObserverId_);
- this.metadataCache_.removeObserver(this.thumbnailMetadataObserverId_);
- this.metadataCache_.removeObserver(this.driveMetadataObserverId_);
- } else {
- onSuccess();
- callback();
- }
- }.bind(this));
-};
-
-/**
- * Sets the watched entry to the passed directory.
- *
- * @param {!DirectoryEntry} entry Directory to be watched.
- * @param {function()} onSuccess Success callback.
- * @param {function()} onError Error callback.
- * @private
- */
-FileWatcher.prototype.changeWatchedEntry_ = function(
- entry, onSuccess, onError) {
- var setEntryClosure = function() {
- // Run the tasks in the queue to avoid races.
- this.queue_.run(function(callback) {
- chrome.fileBrowserPrivate.addFileWatch(
- entry.toURL(),
- function(result) {
- if (!result) {
- this.watchedDirectoryEntry_ = null;
- onError();
- } else {
- this.watchedDirectoryEntry_ = entry;
- onSuccess();
- }
- callback();
- }.bind(this));
- this.filesystemMetadataObserverId_ = this.metadataCache_.addObserver(
- entry,
- MetadataCache.CHILDREN,
- 'filesystem',
- this.onFilesystemMetadataChanged_.bind(this));
- this.thumbnailMetadataObserverId_ = this.metadataCache_.addObserver(
- entry,
- MetadataCache.CHILDREN,
- 'thumbnail',
- this.onThumbnailMetadataChanged_.bind(this));
- this.driveMetadataObserverId_ = this.metadataCache_.addObserver(
- entry,
- MetadataCache.CHILDREN,
- 'drive',
- this.onDriveMetadataChanged_.bind(this));
- }.bind(this));
- }.bind(this);
-
- // Reset the watched directory first, then set the new watched directory.
- this.resetWatchedEntry_(setEntryClosure, onError);
-};
-
-/**
- * @return {DirectoryEntry} Current watched directory entry.
- */
-FileWatcher.prototype.getWatchedDirectoryEntry = function() {
- return this.watchedDirectoryEntry_;
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/folder_shortcuts_data_model.js b/chromium/chrome/browser/resources/file_manager/foreground/js/folder_shortcuts_data_model.js
deleted file mode 100644
index 9467f5eec07..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/folder_shortcuts_data_model.js
+++ /dev/null
@@ -1,293 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * Model for the folder shortcuts. This object is cr.ui.ArrayDataModel-like
- * object with additional methods for the folder shortcut feature.
- * This uses chrome.storage as backend. Items are always sorted by file path.
- *
- * @constructor
- * @extends {cr.EventTarget}
- */
-function FolderShortcutsDataModel() {
- this.array_ = [];
-
- /**
- * Eliminate unsupported folders from the list.
- *
- * @param {Array.<string>} array Folder array which may contain the
- * unsupported folders.
- * @return {Array.<string>} Folder list without unsupported folder.
- */
- var filter = function(array) {
- return array.filter(PathUtil.isEligibleForFolderShortcut);
- };
-
- // Loads the contents from the storage to initialize the array.
- chrome.storage.sync.get(FolderShortcutsDataModel.NAME, function(value) {
- if (!(FolderShortcutsDataModel.NAME in value))
- return;
-
- // Since the value comes from outer resource, we have to check it just in
- // case.
- var list = value[FolderShortcutsDataModel.NAME];
- if (list instanceof Array) {
- list = filter(list);
-
- // Record metrics.
- metrics.recordSmallCount('FolderShortcut.Count', list.length);
-
- var permutation = this.calculatePermutation_(this.array_, list);
- this.array_ = list;
- this.firePermutedEvent_(permutation);
- }
- }.bind(this));
-
- // Listening for changes in the storage.
- chrome.storage.onChanged.addListener(function(changes, namespace) {
- if (!(FolderShortcutsDataModel.NAME in changes) || namespace != 'sync')
- return;
-
- var list = changes[FolderShortcutsDataModel.NAME].newValue;
- // Since the value comes from outer resource, we have to check it just in
- // case.
- if (list instanceof Array) {
- list = filter(list);
-
- // If the list is not changed, do nothing and just return.
- if (this.array_.length == list.length) {
- var changed = false;
- for (var i = 0; i < this.array_.length; i++) {
- // Same item check: must be exact match.
- if (this.array_[i] != list[i]) {
- changed = true;
- break;
- }
- }
- if (!changed)
- return;
- }
-
- var permutation = this.calculatePermutation_(this.array_, list);
- this.array_ = list;
- this.firePermutedEvent_(permutation);
- }
- }.bind(this));
-}
-
-/**
- * Key name in chrome.storage. The array are stored with this name.
- * @type {string}
- * @const
- */
-FolderShortcutsDataModel.NAME = 'folder-shortcuts-list';
-
-FolderShortcutsDataModel.prototype = {
- __proto__: cr.EventTarget.prototype,
-
- /**
- * @return {number} Number of elements in the array.
- */
- get length() {
- return this.array_.length;
- },
-
- /**
- * Returns the paths in the given range as a new array instance. The
- * arguments and return value are compatible with Array.slice().
- *
- * @param {number} start Where to start the selection.
- * @param {number=} opt_end Where to end the selection.
- * @return {Array.<string>} Paths in the selected range.
- */
- slice: function(begin, opt_end) {
- return this.array_.slice(begin, opt_end);
- },
-
- /**
- * @param {number} index Index of the element to be retrieved.
- * @return {string} The value of the |index|-th element.
- */
- item: function(index) {
- return this.array_[index];
- },
-
- /**
- * @param {string} value Value of the element to be retrieved.
- * @return {number} Index of the element with the specified |value|.
- */
- getIndex: function(value) {
- for (var i = 0; i < this.length; i++) {
- // Same item check: must be exact match.
- if (this.array_[i] == value) {
- return i;
- }
- }
- return -1;
- },
-
- /**
- * Compares 2 strings and returns a number indicating one string comes before
- * or after or is the same as the other string in sort order.
- *
- * @param {string} a String1.
- * @param {string} b String2.
- * @return {boolean} Return -1, if String1 < String2. Return 0, if String1 ==
- * String2. Otherwise, return 1.
- */
- compare: function(a, b) {
- return a.localeCompare(b,
- undefined, // locale parameter, use default locale.
- {usage: 'sort', numeric: true});
- },
-
- /**
- * Adds the given item to the array. If there were already same item in the
- * list, return the index of the existing item without adding a duplicate
- * item.
- *
- * @param {string} value Value to be added into the array.
- * @return {number} Index in the list which the element added to.
- */
- add: function(value) {
- var oldArray = this.array_.slice(0); // Shallow copy.
- var addedIndex = -1;
- for (var i = 0; i < this.length; i++) {
- // Same item check: must be exact match.
- if (this.array_[i] == value)
- return i;
-
- // Since the array is sorted, new item will be added just before the first
- // larger item.
- if (this.compare(this.array_[i], value) >= 0) {
- this.array_.splice(i, 0, value);
- addedIndex = i;
- break;
- }
- }
- // If value is not added yet, add it at the last.
- if (addedIndex == -1) {
- this.array_.push(value);
- addedIndex = this.length;
- }
-
- this.firePermutedEvent_(
- this.calculatePermutation_(oldArray, this.array_));
- this.save_();
- metrics.recordUserAction('FolderShortcut.Add');
- return addedIndex;
- },
-
- /**
- * Removes the given item from the array.
- * @param {string} value Value to be removed from the array.
- * @return {number} Index in the list which the element removed from.
- */
- remove: function(value) {
- var removedIndex = -1;
- var oldArray = this.array_.slice(0); // Shallow copy.
- for (var i = 0; i < this.length; i++) {
- // Same item check: must be exact match.
- if (this.array_[i] == value) {
- this.array_.splice(i, 1);
- removedIndex = i;
- break;
- }
- }
-
- if (removedIndex != -1) {
- this.firePermutedEvent_(
- this.calculatePermutation_(oldArray, this.array_));
- this.save_();
- metrics.recordUserAction('FolderShortcut.Remove');
- return removedIndex;
- }
-
- // No item is removed.
- return -1;
- },
-
- /**
- * @param {string} path Path to be checked.
- * @return {boolean} True if the given |path| exists in the array. False
- * otherwise.
- */
- exists: function(path) {
- var index = this.getIndex(path);
- return (index >= 0);
- },
-
- /**
- * Saves the current array to chrome.storage.
- * @private
- */
- save_: function() {
- var obj = {};
- obj[FolderShortcutsDataModel.NAME] = this.array_;
- chrome.storage.sync.set(obj, function() {});
- },
-
- /**
- * Creates a permutation array for 'permuted' event, which is compatible with
- * a permutation array used in cr/ui/array_data_model.js.
- *
- * @param {array} oldArray Previous array before changing.
- * @param {array} newArray New array after changing.
- * @return {Array.<number>} Created permutation array.
- * @private
- */
- calculatePermutation_: function(oldArray, newArray) {
- var oldIndex = 0; // Index of oldArray.
- var newIndex = 0; // Index of newArray.
-
- // Note that both new and old arrays are sorted.
- var permutation = [];
- for (; oldIndex < oldArray.length; oldIndex++) {
- if (newIndex >= newArray.length) {
- // oldArray[oldIndex] is deleted, which is not in the new array.
- permutation[oldIndex] = -1;
- continue;
- }
-
- while (newIndex < newArray.length) {
- // Unchanged item, which exists in both new and old array. But the
- // index may be changed.
- if (oldArray[oldIndex] == newArray[newIndex]) {
- permutation[oldIndex] = newIndex;
- newIndex++;
- break;
- }
-
- // oldArray[oldIndex] is deleted, which is not in the new array.
- if (this.compare(oldArray[oldIndex], newArray[newIndex]) < 0) {
- permutation[oldIndex] = -1;
- break;
- }
-
- // In the case of this.compare(oldArray[oldIndex]) > 0:
- // newArray[newIndex] is added, which is not in the old array.
- newIndex++;
- }
- }
- return permutation;
- },
-
- /**
- * Fires a 'permuted' event, which is compatible with cr.ui.ArrayDataModel.
- * @param {Array.<number>} Permutation array.
- */
- firePermutedEvent_: function(permutation) {
- var permutedEvent = new Event('permuted');
- permutedEvent.newLength = this.length;
- permutedEvent.permutation = permutation;
- this.dispatchEvent(permutedEvent);
-
- // Note: This model only fires 'permuted' event, because:
- // 1) 'change' event is not necessary to fire since it is covered by
- // 'permuted' event.
- // 2) 'splice' and 'sorted' events are not implemented. These events are
- // not used in NavigationListModel. We have to implement them when
- // necessary.
- }
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/commands.js b/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/commands.js
deleted file mode 100644
index f05f0f227d6..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/commands.js
+++ /dev/null
@@ -1,455 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Command queue is the only way to modify images.
- * Supports undo/redo.
- * Command execution is asynchronous (callback-based).
- *
- * @param {Document} document Document to create canvases in.
- * @param {HTMLCanvasElement} canvas The canvas with the original image.
- * @param {function(callback)} saveFunction Function to save the image.
- * @constructor
- */
-function CommandQueue(document, canvas, saveFunction) {
- this.document_ = document;
- this.undo_ = [];
- this.redo_ = [];
- this.subscribers_ = [];
- this.currentImage_ = canvas;
-
- // Current image may be null or not-null but with width = height = 0.
- // Copying an image with zero dimensions causes js errors.
- if (this.currentImage_) {
- this.baselineImage_ = document.createElement('canvas');
- this.baselineImage_.width = this.currentImage_.width;
- this.baselineImage_.height = this.currentImage_.height;
- if (this.currentImage_.width > 0 && this.currentImage_.height > 0) {
- var context = this.baselineImage_.getContext('2d');
- context.drawImage(this.currentImage_, 0, 0);
- }
- } else {
- this.baselineImage_ = null;
- }
-
- this.previousImage_ = document.createElement('canvas');
- this.previousImageAvailable_ = false;
-
- this.saveFunction_ = saveFunction;
- this.busy_ = false;
- this.UIContext_ = {};
-}
-
-/**
- * Attach the UI elements to the command queue.
- * Once the UI is attached the results of image manipulations are displayed.
- *
- * @param {ImageView} imageView The ImageView object to display the results.
- * @param {ImageEditor.Prompt} prompt Prompt to use with this CommandQueue.
- * @param {function(boolean)} lock Function to enable/disable buttons etc.
- */
-CommandQueue.prototype.attachUI = function(imageView, prompt, lock) {
- this.UIContext_ = {
- imageView: imageView,
- prompt: prompt,
- lock: lock
- };
-};
-
-/**
- * Execute the action when the queue is not busy.
- * @param {function} callback Callback.
- */
-CommandQueue.prototype.executeWhenReady = function(callback) {
- if (this.isBusy())
- this.subscribers_.push(callback);
- else
- setTimeout(callback, 0);
-};
-
-/**
- * @return {boolean} True if the command queue is busy.
- */
-CommandQueue.prototype.isBusy = function() { return this.busy_ };
-
-/**
- * Set the queue state to busy. Lock the UI.
- * @private
- */
-CommandQueue.prototype.setBusy_ = function() {
- if (this.busy_)
- throw new Error('CommandQueue already busy');
-
- this.busy_ = true;
-
- if (this.UIContext_.lock)
- this.UIContext_.lock(true);
-
- ImageUtil.trace.resetTimer('command-busy');
-};
-
-/**
- * Set the queue state to not busy. Unlock the UI and execute pending actions.
- * @private
- */
-CommandQueue.prototype.clearBusy_ = function() {
- if (!this.busy_)
- throw new Error('Inconsistent CommandQueue already not busy');
-
- this.busy_ = false;
-
- // Execute the actions requested while the queue was busy.
- while (this.subscribers_.length)
- this.subscribers_.shift()();
-
- if (this.UIContext_.lock)
- this.UIContext_.lock(false);
-
- ImageUtil.trace.reportTimer('command-busy');
-};
-
-/**
- * Commit the image change: save and unlock the UI.
- * @param {number=} opt_delay Delay in ms (to avoid disrupting the animation).
- * @private
- */
-CommandQueue.prototype.commit_ = function(opt_delay) {
- setTimeout(this.saveFunction_.bind(null, this.clearBusy_.bind(this)),
- opt_delay || 0);
-};
-
-/**
- * Internal function to execute the command in a given context.
- *
- * @param {Command} command The command to execute.
- * @param {Object} uiContext The UI context.
- * @param {function} callback Completion callback.
- * @private
- */
-CommandQueue.prototype.doExecute_ = function(command, uiContext, callback) {
- if (!this.currentImage_)
- throw new Error('Cannot operate on null image');
-
- // Remember one previous image so that the first undo is as fast as possible.
- this.previousImage_.width = this.currentImage_.width;
- this.previousImage_.height = this.currentImage_.height;
- this.previousImageAvailable_ = true;
- var context = this.previousImage_.getContext('2d');
- context.drawImage(this.currentImage_, 0, 0);
-
- command.execute(
- this.document_,
- this.currentImage_,
- function(result, opt_delay) {
- this.currentImage_ = result;
- callback(opt_delay);
- }.bind(this),
- uiContext);
-};
-
-/**
- * Executes the command.
- *
- * @param {Command} command Command to execute.
- * @param {boolean=} opt_keep_redo True if redo stack should not be cleared.
- */
-CommandQueue.prototype.execute = function(command, opt_keep_redo) {
- this.setBusy_();
-
- if (!opt_keep_redo)
- this.redo_ = [];
-
- this.undo_.push(command);
-
- this.doExecute_(command, this.UIContext_, this.commit_.bind(this));
-};
-
-/**
- * @return {boolean} True if Undo is applicable.
- */
-CommandQueue.prototype.canUndo = function() {
- return this.undo_.length != 0;
-};
-
-/**
- * Undo the most recent command.
- */
-CommandQueue.prototype.undo = function() {
- if (!this.canUndo())
- throw new Error('Cannot undo');
-
- this.setBusy_();
-
- var command = this.undo_.pop();
- this.redo_.push(command);
-
- var self = this;
-
- function complete() {
- var delay = command.revertView(
- self.currentImage_, self.UIContext_.imageView);
- self.commit_(delay);
- }
-
- if (this.previousImageAvailable_) {
- // First undo after an execute call.
- this.currentImage_.width = this.previousImage_.width;
- this.currentImage_.height = this.previousImage_.height;
- var context = this.currentImage_.getContext('2d');
- context.drawImage(this.previousImage_, 0, 0);
-
- // Free memory.
- this.previousImage_.width = 0;
- this.previousImage_.height = 0;
- this.previousImageAvailable_ = false;
-
- complete();
- // TODO(kaznacheev) Consider recalculating previousImage_ right here
- // by replaying the commands in the background.
- } else {
- this.currentImage_.width = this.baselineImage_.width;
- this.currentImage_.height = this.baselineImage_.height;
- var context = this.currentImage_.getContext('2d');
- context.drawImage(this.baselineImage_, 0, 0);
-
- var replay = function(index) {
- if (index < self.undo_.length)
- self.doExecute_(self.undo_[index], {}, replay.bind(null, index + 1));
- else {
- complete();
- }
- };
-
- replay(0);
- }
-};
-
-/**
- * @return {boolean} True if Redo is applicable.
- */
-CommandQueue.prototype.canRedo = function() {
- return this.redo_.length != 0;
-};
-
-/**
- * Repeat the command that was recently un-done.
- */
-CommandQueue.prototype.redo = function() {
- if (!this.canRedo())
- throw new Error('Cannot redo');
-
- this.execute(this.redo_.pop(), true);
-};
-
-/**
- * Closes internal buffers. Call to ensure, that internal buffers are freed
- * as soon as possible.
- */
-CommandQueue.prototype.close = function() {
- // Free memory used by the undo buffer.
- this.previousImage_.width = 0;
- this.previousImage_.height = 0;
- this.previousImageAvailable_ = false;
-
- if (this.baselineImage_) {
- this.baselineImage_.width = 0;
- this.baselineImage_.height = 0;
- }
-};
-
-/**
- * Command object encapsulates an operation on an image and a way to visualize
- * its result.
- *
- * @param {string} name Command name.
- * @constructor
- */
-function Command(name) {
- this.name_ = name;
-}
-
-/**
- * @return {string} String representation of the command.
- */
-Command.prototype.toString = function() {
- return 'Command ' + this.name_;
-};
-
-/**
- * Execute the command and visualize its results.
- *
- * The two actions are combined into one method because sometimes it is nice
- * to be able to show partial results for slower operations.
- *
- * @param {Document} document Document on which to execute command.
- * @param {HTMLCanvasElement} srcCanvas Canvas to execute on.
- * @param {function(HTMLCanvasElement, number)} callback Callback to call on
- * completion.
- * @param {Object} uiContext Context to work in.
- */
-Command.prototype.execute = function(document, srcCanvas, callback, uiContext) {
- console.error('Command.prototype.execute not implemented');
-};
-
-/**
- * Visualize reversion of the operation.
- *
- * @param {HTMLCanvasElement} canvas Image data to use.
- * @param {ImageView} imageView ImageView to revert.
- * @return {number} Animation duration in ms.
- */
-Command.prototype.revertView = function(canvas, imageView) {
- imageView.replace(canvas);
- return 0;
-};
-
-/**
- * Creates canvas to render on.
- *
- * @param {Document} document Document to create canvas in.
- * @param {HTMLCanvasElement} srcCanvas to copy optional dimensions from.
- * @param {number=} opt_width new canvas width.
- * @param {number=} opt_height new canvas height.
- * @return {HTMLCanvasElement} Newly created canvas.
- * @private
- */
-Command.prototype.createCanvas_ = function(
- document, srcCanvas, opt_width, opt_height) {
- var result = document.createElement('canvas');
- result.width = opt_width || srcCanvas.width;
- result.height = opt_height || srcCanvas.height;
- return result;
-};
-
-
-/**
- * Rotate command
- * @param {number} rotate90 Rotation angle in 90 degree increments (signed).
- * @constructor
- * @extends {Command}
- */
-Command.Rotate = function(rotate90) {
- Command.call(this, 'rotate(' + rotate90 * 90 + 'deg)');
- this.rotate90_ = rotate90;
-};
-
-Command.Rotate.prototype = { __proto__: Command.prototype };
-
-/** @override */
-Command.Rotate.prototype.execute = function(
- document, srcCanvas, callback, uiContext) {
- var result = this.createCanvas_(
- document,
- srcCanvas,
- (this.rotate90_ & 1) ? srcCanvas.height : srcCanvas.width,
- (this.rotate90_ & 1) ? srcCanvas.width : srcCanvas.height);
- ImageUtil.drawImageTransformed(
- result, srcCanvas, 1, 1, this.rotate90_ * Math.PI / 2);
- var delay;
- if (uiContext.imageView) {
- delay = uiContext.imageView.replaceAndAnimate(result, null, this.rotate90_);
- }
- setTimeout(callback, 0, result, delay);
-};
-
-/** @override */
-Command.Rotate.prototype.revertView = function(canvas, imageView) {
- return imageView.replaceAndAnimate(canvas, null, -this.rotate90_);
-};
-
-
-/**
- * Crop command.
- *
- * @param {Rect} imageRect Crop rectangle in image coordinates.
- * @constructor
- * @extends {Command}
- */
-Command.Crop = function(imageRect) {
- Command.call(this, 'crop' + imageRect.toString());
- this.imageRect_ = imageRect;
-};
-
-Command.Crop.prototype = { __proto__: Command.prototype };
-
-/** @override */
-Command.Crop.prototype.execute = function(
- document, srcCanvas, callback, uiContext) {
- var result = this.createCanvas_(
- document, srcCanvas, this.imageRect_.width, this.imageRect_.height);
- Rect.drawImage(result.getContext('2d'), srcCanvas, null, this.imageRect_);
- var delay;
- if (uiContext.imageView) {
- delay = uiContext.imageView.replaceAndAnimate(result, this.imageRect_, 0);
- }
- setTimeout(callback, 0, result, delay);
-};
-
-/** @override */
-Command.Crop.prototype.revertView = function(canvas, imageView) {
- return imageView.animateAndReplace(canvas, this.imageRect_);
-};
-
-
-/**
- * Filter command.
- *
- * @param {string} name Command name.
- * @param {function(ImageData,ImageData,number,number)} filter Filter function.
- * @param {string} message Message to display when done.
- * @constructor
- * @extends {Command}
- */
-Command.Filter = function(name, filter, message) {
- Command.call(this, name);
- this.filter_ = filter;
- this.message_ = message;
-};
-
-Command.Filter.prototype = { __proto__: Command.prototype };
-
-/** @override */
-Command.Filter.prototype.execute = function(
- document, srcCanvas, callback, uiContext) {
- var result = this.createCanvas_(document, srcCanvas);
-
- var self = this;
-
- var previousRow = 0;
-
- function onProgressVisible(updatedRow, rowCount) {
- if (updatedRow == rowCount) {
- uiContext.imageView.replace(result);
- if (self.message_)
- uiContext.prompt.show(self.message_, 2000);
- callback(result);
- } else {
- var viewport = uiContext.imageView.viewport_;
-
- var imageStrip = new Rect(viewport.getImageBounds());
- imageStrip.top = previousRow;
- imageStrip.height = updatedRow - previousRow;
-
- var screenStrip = new Rect(viewport.getImageBoundsOnScreen());
- screenStrip.top = Math.round(viewport.imageToScreenY(previousRow));
- screenStrip.height =
- Math.round(viewport.imageToScreenY(updatedRow)) - screenStrip.top;
-
- uiContext.imageView.paintDeviceRect(
- viewport.screenToDeviceRect(screenStrip), result, imageStrip);
- previousRow = updatedRow;
- }
- }
-
- function onProgressInvisible(updatedRow, rowCount) {
- if (updatedRow == rowCount) {
- callback(result);
- }
- }
-
- filter.applyByStrips(result, srcCanvas, this.filter_,
- uiContext.imageView ? onProgressVisible : onProgressInvisible);
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/exif_encoder.js b/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/exif_encoder.js
deleted file mode 100644
index e81b8fba899..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/exif_encoder.js
+++ /dev/null
@@ -1,569 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-// TODO:(kaznacheev) Share the EXIF constants with exif_parser.js
-var EXIF_MARK_SOS = 0xffda; // Start of "stream" (the actual image data).
-var EXIF_MARK_SOI = 0xffd8; // Start of image data.
-var EXIF_MARK_EOI = 0xffd9; // End of image data.
-
-var EXIF_MARK_APP0 = 0xffe0; // APP0 block, most commonly JFIF data.
-var EXIF_MARK_EXIF = 0xffe1; // Start of exif block.
-
-var EXIF_ALIGN_LITTLE = 0x4949; // Indicates little endian exif data.
-var EXIF_ALIGN_BIG = 0x4d4d; // Indicates big endian exif data.
-
-var EXIF_TAG_TIFF = 0x002a; // First directory containing TIFF data.
-var EXIF_TAG_GPSDATA = 0x8825; // Pointer from TIFF to the GPS directory.
-var EXIF_TAG_EXIFDATA = 0x8769; // Pointer from TIFF to the EXIF IFD.
-
-var EXIF_TAG_JPG_THUMB_OFFSET = 0x0201; // Pointer from TIFF to thumbnail.
-var EXIF_TAG_JPG_THUMB_LENGTH = 0x0202; // Length of thumbnail data.
-
-var EXIF_TAG_IMAGE_WIDTH = 0x0100;
-var EXIF_TAG_IMAGE_HEIGHT = 0x0101;
-
-var EXIF_TAG_ORIENTATION = 0x0112;
-var EXIF_TAG_X_DIMENSION = 0xA002;
-var EXIF_TAG_Y_DIMENSION = 0xA003;
-
-/**
- * The Exif metadata encoder.
- * Uses the metadata format as defined by ExifParser.
- * @param {Object} original_metadata Metadata to encode.
- * @constructor
- * @extends {ImageEncoder.MetadataEncoder}
- */
-function ExifEncoder(original_metadata) {
- ImageEncoder.MetadataEncoder.apply(this, arguments);
-
- this.ifd_ = this.metadata_.ifd;
- if (!this.ifd_)
- this.ifd_ = this.metadata_.ifd = {};
-}
-
-ExifEncoder.prototype = {__proto__: ImageEncoder.MetadataEncoder.prototype};
-
-ImageEncoder.registerMetadataEncoder(ExifEncoder, 'image/jpeg');
-
-/**
- * @param {HTMLCanvasElement|Object} canvas Canvas or anything with
- * width and height properties.
- */
-ExifEncoder.prototype.setImageData = function(canvas) {
- var image = this.ifd_.image;
- if (!image)
- image = this.ifd_.image = {};
-
- // Only update width/height in this directory if they are present.
- if (image[EXIF_TAG_IMAGE_WIDTH] && image[EXIF_TAG_IMAGE_HEIGHT]) {
- image[EXIF_TAG_IMAGE_WIDTH].value = canvas.width;
- image[EXIF_TAG_IMAGE_HEIGHT].value = canvas.height;
- }
-
- var exif = this.ifd_.exif;
- if (!exif)
- exif = this.ifd_.exif = {};
- ExifEncoder.findOrCreateTag(image, EXIF_TAG_EXIFDATA);
- ExifEncoder.findOrCreateTag(exif, EXIF_TAG_X_DIMENSION).value = canvas.width;
- ExifEncoder.findOrCreateTag(exif, EXIF_TAG_Y_DIMENSION).value = canvas.height;
-
- this.metadata_.width = canvas.width;
- this.metadata_.height = canvas.height;
-
- // Always save in default orientation.
- delete this.metadata_.imageTransform;
- ExifEncoder.findOrCreateTag(image, EXIF_TAG_ORIENTATION).value = 1;
-};
-
-
-/**
- * @param {HTMLCanvasElement} canvas Thumbnail canvas.
- * @param {number} quality (0..1] Thumbnail encoding quality.
- */
-ExifEncoder.prototype.setThumbnailData = function(canvas, quality) {
- // Empirical formula with reasonable behavior:
- // 10K for 1Mpix, 30K for 5Mpix, 50K for 9Mpix and up.
- var pixelCount = this.metadata_.width * this.metadata_.height;
- var maxEncodedSize = 5000 * Math.min(10, 1 + pixelCount / 1000000);
-
- var DATA_URL_PREFIX = 'data:' + this.mimeType + ';base64,';
- var BASE64_BLOAT = 4 / 3;
- var maxDataURLLength =
- DATA_URL_PREFIX.length + Math.ceil(maxEncodedSize * BASE64_BLOAT);
-
- for (;; quality *= 0.8) {
- ImageEncoder.MetadataEncoder.prototype.setThumbnailData.call(
- this, canvas, quality);
- if (this.metadata_.thumbnailURL.length <= maxDataURLLength || quality < 0.2)
- break;
- }
-
- if (this.metadata_.thumbnailURL.length <= maxDataURLLength) {
- var thumbnail = this.ifd_.thumbnail;
- if (!thumbnail)
- thumbnail = this.ifd_.thumbnail = {};
-
- ExifEncoder.findOrCreateTag(thumbnail, EXIF_TAG_IMAGE_WIDTH).value =
- canvas.width;
-
- ExifEncoder.findOrCreateTag(thumbnail, EXIF_TAG_IMAGE_HEIGHT).value =
- canvas.height;
-
- // The values for these tags will be set in ExifWriter.encode.
- ExifEncoder.findOrCreateTag(thumbnail, EXIF_TAG_JPG_THUMB_OFFSET);
- ExifEncoder.findOrCreateTag(thumbnail, EXIF_TAG_JPG_THUMB_LENGTH);
-
- // Always save in default orientation.
- ExifEncoder.findOrCreateTag(thumbnail, EXIF_TAG_ORIENTATION).value = 1;
- } else {
- console.warn(
- 'Thumbnail URL too long: ' + this.metadata_.thumbnailURL.length);
- // Delete thumbnail ifd so that it is not written out to a file, but
- // keep thumbnailURL for display purposes.
- if (this.ifd_.thumbnail) {
- delete this.ifd_.thumbnail;
- }
- }
- delete this.metadata_.thumbnailTransform;
-};
-
-/**
- * Return a range where the metadata is (or should be) located.
- * @param {string} encodedImage Raw image data to look for metadata.
- * @return {Object} An object with from and to properties.
- */
-ExifEncoder.prototype.findInsertionRange = function(encodedImage) {
- function getWord(pos) {
- if (pos + 2 > encodedImage.length)
- throw 'Reading past the buffer end @' + pos;
- return encodedImage.charCodeAt(pos) << 8 | encodedImage.charCodeAt(pos + 1);
- }
-
- if (getWord(0) != EXIF_MARK_SOI)
- throw new Error('Jpeg data starts from 0x' + getWord(0).toString(16));
-
- var sectionStart = 2;
-
- // Default: an empty range right after SOI.
- // Will be returned in absence of APP0 or Exif sections.
- var range = {from: sectionStart, to: sectionStart};
-
- for (;;) {
- var tag = getWord(sectionStart);
-
- if (tag == EXIF_MARK_SOS)
- break;
-
- var nextSectionStart = sectionStart + 2 + getWord(sectionStart + 2);
- if (nextSectionStart <= sectionStart ||
- nextSectionStart > encodedImage.length)
- throw new Error('Invalid section size in jpeg data');
-
- if (tag == EXIF_MARK_APP0) {
- // Assert that we have not seen the Exif section yet.
- if (range.from != range.to)
- throw new Error('APP0 section found after EXIF section');
- // An empty range right after the APP0 segment.
- range.from = range.to = nextSectionStart;
- } else if (tag == EXIF_MARK_EXIF) {
- // A range containing the existing EXIF section.
- range.from = sectionStart;
- range.to = nextSectionStart;
- }
- sectionStart = nextSectionStart;
- }
-
- return range;
-};
-
-/**
- * @return {ArrayBuffer} serialized metadata ready to write to an image file.
- */
-ExifEncoder.prototype.encode = function() {
- var HEADER_SIZE = 10;
-
- // Allocate the largest theoretically possible size.
- var bytes = new Uint8Array(0x10000);
-
- // Serialize header
- var hw = new ByteWriter(bytes.buffer, 0, HEADER_SIZE);
- hw.writeScalar(EXIF_MARK_EXIF, 2);
- hw.forward('size', 2);
- hw.writeString('Exif\0\0'); // Magic string.
-
- // First serialize the content of the exif section.
- // Use a ByteWriter starting at HEADER_SIZE offset so that tell() positions
- // can be directly mapped to offsets as encoded in the dictionaries.
- var bw = new ByteWriter(bytes.buffer, HEADER_SIZE);
-
- if (this.metadata_.littleEndian) {
- bw.setByteOrder(ByteWriter.LITTLE_ENDIAN);
- bw.writeScalar(EXIF_ALIGN_LITTLE, 2);
- } else {
- bw.setByteOrder(ByteWriter.BIG_ENDIAN);
- bw.writeScalar(EXIF_ALIGN_BIG, 2);
- }
-
- bw.writeScalar(EXIF_TAG_TIFF, 2);
-
- bw.forward('image-dir', 4); // The pointer should point right after itself.
- bw.resolveOffset('image-dir');
-
- ExifEncoder.encodeDirectory(bw, this.ifd_.image,
- [EXIF_TAG_EXIFDATA, EXIF_TAG_GPSDATA], 'thumb-dir');
-
- if (this.ifd_.exif) {
- bw.resolveOffset(EXIF_TAG_EXIFDATA);
- ExifEncoder.encodeDirectory(bw, this.ifd_.exif);
- } else {
- if (EXIF_TAG_EXIFDATA in this.ifd_.image)
- throw new Error('Corrupt exif dictionary reference');
- }
-
- if (this.ifd_.gps) {
- bw.resolveOffset(EXIF_TAG_GPSDATA);
- ExifEncoder.encodeDirectory(bw, this.ifd_.gps);
- } else {
- if (EXIF_TAG_GPSDATA in this.ifd_.image)
- throw new Error('Missing gps dictionary reference');
- }
-
- if (this.ifd_.thumbnail) {
- bw.resolveOffset('thumb-dir');
- ExifEncoder.encodeDirectory(
- bw,
- this.ifd_.thumbnail,
- [EXIF_TAG_JPG_THUMB_OFFSET, EXIF_TAG_JPG_THUMB_LENGTH]);
-
- var thumbnailDecoded =
- ImageEncoder.decodeDataURL(this.metadata_.thumbnailURL);
- bw.resolveOffset(EXIF_TAG_JPG_THUMB_OFFSET);
- bw.resolve(EXIF_TAG_JPG_THUMB_LENGTH, thumbnailDecoded.length);
- bw.writeString(thumbnailDecoded);
- } else {
- bw.resolve('thumb-dir', 0);
- }
-
- bw.checkResolved();
-
- var totalSize = HEADER_SIZE + bw.tell();
- hw.resolve('size', totalSize - 2); // The marker is excluded.
- hw.checkResolved();
-
- var subarray = new Uint8Array(totalSize);
- for (var i = 0; i != totalSize; i++) {
- subarray[i] = bytes[i];
- }
- return subarray.buffer;
-};
-
-/*
- * Static methods.
- */
-
-/**
- * Write the contents of an IFD directory.
- * @param {ByteWriter} bw ByteWriter to use.
- * @param {Object} directory A directory map as created by ExifParser.
- * @param {Array} resolveLater An array of tag ids for which the values will be
- * resolved later.
- * @param {string} nextDirPointer A forward key for the pointer to the next
- * directory. If omitted the pointer is set to 0.
- */
-ExifEncoder.encodeDirectory = function(
- bw, directory, resolveLater, nextDirPointer) {
-
- var longValues = [];
-
- bw.forward('dir-count', 2);
- var count = 0;
-
- for (var key in directory) {
- var tag = directory[key];
- bw.writeScalar(tag.id, 2);
- bw.writeScalar(tag.format, 2);
- bw.writeScalar(tag.componentCount, 4);
-
- var width = ExifEncoder.getComponentWidth(tag) * tag.componentCount;
-
- if (resolveLater && (resolveLater.indexOf(tag.id) >= 0)) {
- // The actual value depends on further computations.
- if (tag.componentCount != 1 || width > 4)
- throw new Error('Cannot forward the pointer for ' + tag.id);
- bw.forward(tag.id, width);
- } else if (width <= 4) {
- // The value fits into 4 bytes, write it immediately.
- ExifEncoder.writeValue(bw, tag);
- } else {
- // The value does not fit, forward the 4 byte offset to the actual value.
- width = 4;
- bw.forward(tag.id, width);
- longValues.push(tag);
- }
- bw.skip(4 - width); // Align so that the value take up exactly 4 bytes.
- count++;
- }
-
- bw.resolve('dir-count', count);
-
- if (nextDirPointer) {
- bw.forward(nextDirPointer, 4);
- } else {
- bw.writeScalar(0, 4);
- }
-
- // Write out the long values and resolve pointers.
- for (var i = 0; i != longValues.length; i++) {
- var longValue = longValues[i];
- bw.resolveOffset(longValue.id);
- ExifEncoder.writeValue(bw, longValue);
- }
-};
-
-/**
- * @param {{format:number, id:number}} tag EXIF tag object.
- * @return {number} Width in bytes of the data unit associated with this tag.
- * TODO(kaznacheev): Share with ExifParser?
- */
-ExifEncoder.getComponentWidth = function(tag) {
- switch (tag.format) {
- case 1: // Byte
- case 2: // String
- case 7: // Undefined
- return 1;
-
- case 3: // Short
- return 2;
-
- case 4: // Long
- case 9: // Signed Long
- return 4;
-
- case 5: // Rational
- case 10: // Signed Rational
- return 8;
-
- default: // ???
- console.warn('Unknown tag format 0x' +
- Number(tag.id).toString(16) + ': ' + tag.format);
- return 4;
- }
-};
-
-/**
- * Writes out the tag value.
- * @param {ByteWriter} bw Writer to use.
- * @param {Object} tag Tag, which value to write.
- */
-ExifEncoder.writeValue = function(bw, tag) {
- if (tag.format == 2) { // String
- if (tag.componentCount != tag.value.length) {
- throw new Error(
- 'String size mismatch for 0x' + Number(tag.id).toString(16));
- }
- bw.writeString(tag.value);
- } else { // Scalar or rational
- var width = ExifEncoder.getComponentWidth(tag);
-
- var writeComponent = function(value, signed) {
- if (width == 8) {
- bw.writeScalar(value[0], 4, signed);
- bw.writeScalar(value[1], 4, signed);
- } else {
- bw.writeScalar(value, width, signed);
- }
- };
-
- var signed = (tag.format == 9 || tag.format == 10);
- if (tag.componentCount == 1) {
- writeComponent(tag.value, signed);
- } else {
- for (var i = 0; i != tag.componentCount; i++) {
- writeComponent(tag.value[i], signed);
- }
- }
- }
-};
-
-/**
- * @param {{Object.<number,Object>}} directory EXIF directory.
- * @param {number} id Tag id.
- * @param {number} format Tag format
- * (used in {@link ExifEncoder#getComponentWidth}).
- * @param {number} componentCount Number of components in this tag.
- * @return {{id:number, format:number, componentCount:number}}
- * Tag found or created.
- */
-ExifEncoder.findOrCreateTag = function(directory, id, format, componentCount) {
- if (!(id in directory)) {
- directory[id] = {
- id: id,
- format: format || 3, // Short
- componentCount: componentCount || 1
- };
- }
- return directory[id];
-};
-
-/**
- * ByteWriter class.
- * @param {ArrayBuffer} arrayBuffer Underlying buffer to use.
- * @param {number} offset Offset at which to start writing.
- * @param {number} length Maximum length to use.
- * @class
- * @constructor
- */
-function ByteWriter(arrayBuffer, offset, length) {
- length = length || (arrayBuffer.byteLength - offset);
- this.view_ = new DataView(arrayBuffer, offset, length);
- this.littleEndian_ = false;
- this.pos_ = 0;
- this.forwards_ = {};
-}
-
-/**
- * Little endian byte order.
- * @type {number}
- */
-ByteWriter.LITTLE_ENDIAN = 0;
-
-/**
- * Bug endian byte order.
- * @type {number}
- */
-ByteWriter.BIG_ENDIAN = 1;
-
-/**
- * Set the byte ordering for future writes.
- * @param {number} order ByteOrder to use {ByteWriter.LITTLE_ENDIAN}
- * or {ByteWriter.BIG_ENDIAN}.
- */
-ByteWriter.prototype.setByteOrder = function(order) {
- this.littleEndian_ = (order == ByteWriter.LITTLE_ENDIAN);
-};
-
-/**
- * @return {number} the current write position.
- */
-ByteWriter.prototype.tell = function() { return this.pos_ };
-
-/**
- * Skips desired amount of bytes in output stream.
- * @param {number} count Byte count to skip.
- */
-ByteWriter.prototype.skip = function(count) {
- this.validateWrite(count);
- this.pos_ += count;
-};
-
-/**
- * Check if the buffer has enough room to read 'width' bytes. Throws an error
- * if it has not.
- * @param {number} width Amount of bytes to check.
- */
-ByteWriter.prototype.validateWrite = function(width) {
- if (this.pos_ + width > this.view_.byteLength)
- throw new Error('Writing past the end of the buffer');
-};
-
-/**
- * Writes scalar value to output stream.
- * @param {number} value Value to write.
- * @param {number} width Desired width of written value.
- * @param {boolean=} opt_signed True if value represents signed number.
- */
-ByteWriter.prototype.writeScalar = function(value, width, opt_signed) {
- var method;
-// The below switch is so verbose for two reasons:
-// 1. V8 is faster on method names which are 'symbols'.
-// 2. Method names are discoverable by full text search.
- switch (width) {
- case 1:
- method = opt_signed ? 'setInt8' : 'setUint8';
- break;
-
- case 2:
- method = opt_signed ? 'setInt16' : 'setUint16';
- break;
-
- case 4:
- method = opt_signed ? 'setInt32' : 'setUint32';
- break;
-
- case 8:
- method = opt_signed ? 'setInt64' : 'setUint64';
- break;
-
- default:
- throw new Error('Invalid width: ' + width);
- break;
- }
-
- this.validateWrite(width);
- this.view_[method](this.pos_, value, this.littleEndian_);
- this.pos_ += width;
-};
-
-/**
- * Writes string.
- * @param {string} str String to write.
- */
-ByteWriter.prototype.writeString = function(str) {
- this.validateWrite(str.length);
- for (var i = 0; i != str.length; i++) {
- this.view_.setUint8(this.pos_++, str.charCodeAt(i));
- }
-};
-
-/**
- * Allocate the space for 'width' bytes for the value that will be set later.
- * To be followed by a 'resolve' call with the same key.
- * @param {string} key A key to identify the value.
- * @param {number} width Width of the value in bytes.
- */
-ByteWriter.prototype.forward = function(key, width) {
- if (key in this.forwards_)
- throw new Error('Duplicate forward key ' + key);
- this.validateWrite(width);
- this.forwards_[key] = {
- pos: this.pos_,
- width: width
- };
- this.pos_ += width;
-};
-
-/**
- * Set the value previously allocated with a 'forward' call.
- * @param {string} key A key to identify the value.
- * @param {number} value value to write in pre-allocated space.
- */
-ByteWriter.prototype.resolve = function(key, value) {
- if (!(key in this.forwards_))
- throw new Error('Undeclared forward key ' + key.toString(16));
- var forward = this.forwards_[key];
- var curPos = this.pos_;
- this.pos_ = forward.pos;
- this.writeScalar(value, forward.width);
- this.pos_ = curPos;
- delete this.forwards_[key];
-};
-
-/**
- * A shortcut to resolve the value to the current write position.
- * @param {string} key A key to identify pre-allocated position.
- */
-ByteWriter.prototype.resolveOffset = function(key) {
- this.resolve(key, this.tell());
-};
-
-/**
- * Check if every forward has been resolved, throw and error if not.
- */
-ByteWriter.prototype.checkResolved = function() {
- for (var key in this.forwards_) {
- throw new Error('Unresolved forward pointer ' + key.toString(16));
- }
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/filter.js b/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/filter.js
deleted file mode 100644
index e06d4ef2dd8..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/filter.js
+++ /dev/null
@@ -1,612 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * A namespace for image filter utilities.
- */
-var filter = {};
-
-/**
- * Create a filter from name and options.
- *
- * @param {string} name Maps to a filter method name.
- * @param {Object} options A map of filter-specific options.
- * @return {function(ImageData,ImageData,number,number)} created function.
- */
-filter.create = function(name, options) {
- var filterFunc = filter[name](options);
- return function() {
- var time = Date.now();
- filterFunc.apply(null, arguments);
- var dst = arguments[0];
- var mPixPerSec = dst.width * dst.height / 1000 / (Date.now() - time);
- ImageUtil.trace.report(name, Math.round(mPixPerSec * 10) / 10 + 'Mps');
- }
-};
-
-/**
- * Apply a filter to a image by splitting it into strips.
- *
- * To be used with large images to avoid freezing up the UI.
- *
- * @param {HTMLCanvasElement} dstCanvas Destination canvas.
- * @param {HTMLCanvasElement} srcCanvas Source canvas.
- * @param {function(ImageData,ImageData,number,number)} filterFunc Filter.
- * @param {function(number, number)} progressCallback Progress callback.
- * @param {number} maxPixelsPerStrip Pixel number to process at once.
- */
-filter.applyByStrips = function(
- dstCanvas, srcCanvas, filterFunc, progressCallback, maxPixelsPerStrip) {
- var dstContext = dstCanvas.getContext('2d');
- var srcContext = srcCanvas.getContext('2d');
- var source = srcContext.getImageData(0, 0, srcCanvas.width, srcCanvas.height);
-
- var stripCount = Math.ceil(srcCanvas.width * srcCanvas.height /
- (maxPixelsPerStrip || 1000000)); // 1 Mpix is a reasonable default.
-
- var strip = srcContext.getImageData(0, 0,
- srcCanvas.width, Math.ceil(srcCanvas.height / stripCount));
-
- var offset = 0;
-
- function filterStrip() {
- // If the strip overlaps the bottom of the source image we cannot shrink it
- // and we cannot fill it partially (since canvas.putImageData always draws
- // the entire buffer).
- // Instead we move the strip up several lines (converting those lines
- // twice is a small price to pay).
- if (offset > source.height - strip.height) {
- offset = source.height - strip.height;
- }
-
- filterFunc(strip, source, 0, offset);
- dstContext.putImageData(strip, 0, offset);
-
- offset += strip.height;
-
- if (offset < source.height) {
- setTimeout(filterStrip, 0);
- } else {
- ImageUtil.trace.reportTimer('filter-commit');
- }
-
- progressCallback(offset, source.height);
- }
-
- ImageUtil.trace.resetTimer('filter-commit');
- filterStrip();
-};
-
-/**
- * Return a color histogram for an image.
- *
- * @param {HTMLCanvasElement|ImageData} source Image data to analyze.
- * @return {{r: Array.<number>, g: Array.<number>, b: Array.<number>}}
- * histogram.
- */
-filter.getHistogram = function(source) {
- var imageData;
- if (source.constructor.name == 'HTMLCanvasElement') {
- imageData = source.getContext('2d').
- getImageData(0, 0, source.width, source.height);
- } else {
- imageData = source;
- }
-
- var r = [];
- var g = [];
- var b = [];
-
- for (var i = 0; i != 256; i++) {
- r.push(0);
- g.push(0);
- b.push(0);
- }
-
- var data = imageData.data;
- var maxIndex = 4 * imageData.width * imageData.height;
- for (var index = 0; index != maxIndex;) {
- r[data[index++]]++;
- g[data[index++]]++;
- b[data[index++]]++;
- index++;
- }
-
- return { r: r, g: g, b: b };
-};
-
-/**
- * Compute the function for every integer value from 0 up to maxArg.
- *
- * Rounds and clips the results to fit the [0..255] range.
- * Useful to speed up pixel manipulations.
- *
- * @param {number} maxArg Maximum argument value (inclusive).
- * @param {function(number): number} func Function to precompute.
- * @return {Uint8Array} Computed results.
- */
-filter.precompute = function(maxArg, func) {
- var results = new Uint8Array(maxArg + 1);
- for (var arg = 0; arg <= maxArg; arg++) {
- results[arg] = Math.max(0, Math.min(0xFF, Math.round(func(arg))));
- }
- return results;
-};
-
-/**
- * Convert pixels by applying conversion tables to each channel individually.
- *
- * @param {Array.<number>} rMap Red channel conversion table.
- * @param {Array.<number>} gMap Green channel conversion table.
- * @param {Array.<number>} bMap Blue channel conversion table.
- * @param {ImageData} dst Destination image data. Can be smaller than the
- * source, must completely fit inside the source.
- * @param {ImageData} src Source image data.
- * @param {number} offsetX Horizontal offset of dst relative to src.
- * @param {number} offsetY Vertical offset of dst relative to src.
- */
-filter.mapPixels = function(rMap, gMap, bMap, dst, src, offsetX, offsetY) {
- var dstData = dst.data;
- var dstWidth = dst.width;
- var dstHeight = dst.height;
-
- var srcData = src.data;
- var srcWidth = src.width;
- var srcHeight = src.height;
-
- if (offsetX < 0 || offsetX + dstWidth > srcWidth ||
- offsetY < 0 || offsetY + dstHeight > srcHeight)
- throw new Error('Invalid offset');
-
- var dstIndex = 0;
- for (var y = 0; y != dstHeight; y++) {
- var srcIndex = (offsetX + (offsetY + y) * srcWidth) * 4;
- for (var x = 0; x != dstWidth; x++) {
- dstData[dstIndex++] = rMap[srcData[srcIndex++]];
- dstData[dstIndex++] = gMap[srcData[srcIndex++]];
- dstData[dstIndex++] = bMap[srcData[srcIndex++]];
- dstIndex++;
- srcIndex++;
- }
- }
-};
-
-/**
- * Number of digits after period(in binary form) to preserve.
- * @type {number}
- */
-filter.FIXED_POINT_SHIFT = 16;
-
-/**
- * Maximum value that can be represented in fixed point without overflow.
- * @type {number}
- */
-filter.MAX_FLOAT_VALUE = 0x7FFFFFFF >> filter.FIXED_POINT_SHIFT;
-
-/**
- * Converts floating point to fixed.
- * @param {number} x Number to convert.
- * @return {number} Converted number.
- */
-filter.floatToFixedPoint = function(x) {
- // Math.round on negative arguments causes V8 to deoptimize the calling
- // function, so we are using >> 0 instead.
- return (x * (1 << filter.FIXED_POINT_SHIFT)) >> 0;
-};
-
-/**
- * Perform an image convolution with a symmetrical 5x5 matrix:
- *
- * 0 0 w3 0 0
- * 0 w2 w1 w2 0
- * w3 w1 w0 w1 w3
- * 0 w2 w1 w2 0
- * 0 0 w3 0 0
- *
- * @param {Array.<number>} weights See the picture above.
- * @param {ImageData} dst Destination image data. Can be smaller than the
- * source, must completely fit inside the source.
- * @param {ImageData} src Source image data.
- * @param {number} offsetX Horizontal offset of dst relative to src.
- * @param {number} offsetY Vertical offset of dst relative to src.
- */
-filter.convolve5x5 = function(weights, dst, src, offsetX, offsetY) {
- var w0 = filter.floatToFixedPoint(weights[0]);
- var w1 = filter.floatToFixedPoint(weights[1]);
- var w2 = filter.floatToFixedPoint(weights[2]);
- var w3 = filter.floatToFixedPoint(weights[3]);
-
- var dstData = dst.data;
- var dstWidth = dst.width;
- var dstHeight = dst.height;
- var dstStride = dstWidth * 4;
-
- var srcData = src.data;
- var srcWidth = src.width;
- var srcHeight = src.height;
- var srcStride = srcWidth * 4;
- var srcStride2 = srcStride * 2;
-
- if (offsetX < 0 || offsetX + dstWidth > srcWidth ||
- offsetY < 0 || offsetY + dstHeight > srcHeight)
- throw new Error('Invalid offset');
-
- // Javascript is not very good at inlining constants.
- // We inline manually and assert that the constant is equal to the variable.
- if (filter.FIXED_POINT_SHIFT != 16)
- throw new Error('Wrong fixed point shift');
-
- var margin = 2;
-
- var startX = Math.max(0, margin - offsetX);
- var endX = Math.min(dstWidth, srcWidth - margin - offsetX);
-
- var startY = Math.max(0, margin - offsetY);
- var endY = Math.min(dstHeight, srcHeight - margin - offsetY);
-
- for (var y = startY; y != endY; y++) {
- var dstIndex = y * dstStride + startX * 4;
- var srcIndex = (y + offsetY) * srcStride + (startX + offsetX) * 4;
-
- for (var x = startX; x != endX; x++) {
- for (var c = 0; c != 3; c++) {
- var sum = w0 * srcData[srcIndex] +
- w1 * (srcData[srcIndex - 4] +
- srcData[srcIndex + 4] +
- srcData[srcIndex - srcStride] +
- srcData[srcIndex + srcStride]) +
- w2 * (srcData[srcIndex - srcStride - 4] +
- srcData[srcIndex + srcStride - 4] +
- srcData[srcIndex - srcStride + 4] +
- srcData[srcIndex + srcStride + 4]) +
- w3 * (srcData[srcIndex - 8] +
- srcData[srcIndex + 8] +
- srcData[srcIndex - srcStride2] +
- srcData[srcIndex + srcStride2]);
- if (sum < 0)
- dstData[dstIndex++] = 0;
- else if (sum > 0xFF0000)
- dstData[dstIndex++] = 0xFF;
- else
- dstData[dstIndex++] = sum >> 16;
- srcIndex++;
- }
- srcIndex++;
- dstIndex++;
- }
- }
-};
-
-/**
- * Compute the average color for the image.
- *
- * @param {ImageData} imageData Image data to analyze.
- * @return {{r: number, g: number, b: number}} average color.
- */
-filter.getAverageColor = function(imageData) {
- var data = imageData.data;
- var width = imageData.width;
- var height = imageData.height;
-
- var total = 0;
- var r = 0;
- var g = 0;
- var b = 0;
-
- var maxIndex = 4 * width * height;
- for (var i = 0; i != maxIndex;) {
- total++;
- r += data[i++];
- g += data[i++];
- b += data[i++];
- i++;
- }
- if (total == 0) return { r: 0, g: 0, b: 0 };
- return { r: r / total, g: g / total, b: b / total };
-};
-
-/**
- * Compute the average color with more weight given to pixes at the center.
- *
- * @param {ImageData} imageData Image data to analyze.
- * @return {{r: number, g: number, b: number}} weighted average color.
- */
-filter.getWeightedAverageColor = function(imageData) {
- var data = imageData.data;
- var width = imageData.width;
- var height = imageData.height;
-
- var total = 0;
- var r = 0;
- var g = 0;
- var b = 0;
-
- var center = Math.floor(width / 2);
- var maxDist = center * Math.sqrt(2);
- maxDist *= 2; // Weaken the effect of distance
-
- var i = 0;
- for (var x = 0; x != width; x++) {
- for (var y = 0; y != height; y++) {
- var dist = Math.sqrt(
- (x - center) * (x - center) + (y - center) * (y - center));
- var weight = (maxDist - dist) / maxDist;
-
- total += weight;
- r += data[i++] * weight;
- g += data[i++] * weight;
- b += data[i++] * weight;
- i++;
- }
- }
- if (total == 0) return { r: 0, g: 0, b: 0 };
- return { r: r / total, g: g / total, b: b / total };
-};
-
-/**
- * Copy part of src image to dst, applying matrix color filter on-the-fly.
- *
- * The copied part of src should completely fit into dst (there is no clipping
- * on either side).
- *
- * @param {Array.<number>} matrix 3x3 color matrix.
- * @param {ImageData} dst Destination image data.
- * @param {ImageData} src Source image data.
- * @param {number} offsetX X offset in source to start processing.
- * @param {number} offsetY Y offset in source to start processing.
- */
-filter.colorMatrix3x3 = function(matrix, dst, src, offsetX, offsetY) {
- var c11 = filter.floatToFixedPoint(matrix[0]);
- var c12 = filter.floatToFixedPoint(matrix[1]);
- var c13 = filter.floatToFixedPoint(matrix[2]);
- var c21 = filter.floatToFixedPoint(matrix[3]);
- var c22 = filter.floatToFixedPoint(matrix[4]);
- var c23 = filter.floatToFixedPoint(matrix[5]);
- var c31 = filter.floatToFixedPoint(matrix[6]);
- var c32 = filter.floatToFixedPoint(matrix[7]);
- var c33 = filter.floatToFixedPoint(matrix[8]);
-
- var dstData = dst.data;
- var dstWidth = dst.width;
- var dstHeight = dst.height;
-
- var srcData = src.data;
- var srcWidth = src.width;
- var srcHeight = src.height;
-
- if (offsetX < 0 || offsetX + dstWidth > srcWidth ||
- offsetY < 0 || offsetY + dstHeight > srcHeight)
- throw new Error('Invalid offset');
-
- // Javascript is not very good at inlining constants.
- // We inline manually and assert that the constant is equal to the variable.
- if (filter.FIXED_POINT_SHIFT != 16)
- throw new Error('Wrong fixed point shift');
-
- var dstIndex = 0;
- for (var y = 0; y != dstHeight; y++) {
- var srcIndex = (offsetX + (offsetY + y) * srcWidth) * 4;
- for (var x = 0; x != dstWidth; x++) {
- var r = srcData[srcIndex++];
- var g = srcData[srcIndex++];
- var b = srcData[srcIndex++];
- srcIndex++;
-
- var rNew = r * c11 + g * c12 + b * c13;
- var gNew = r * c21 + g * c22 + b * c23;
- var bNew = r * c31 + g * c32 + b * c33;
-
- if (rNew < 0) {
- dstData[dstIndex++] = 0;
- } else if (rNew > 0xFF0000) {
- dstData[dstIndex++] = 0xFF;
- } else {
- dstData[dstIndex++] = rNew >> 16;
- }
-
- if (gNew < 0) {
- dstData[dstIndex++] = 0;
- } else if (gNew > 0xFF0000) {
- dstData[dstIndex++] = 0xFF;
- } else {
- dstData[dstIndex++] = gNew >> 16;
- }
-
- if (bNew < 0) {
- dstData[dstIndex++] = 0;
- } else if (bNew > 0xFF0000) {
- dstData[dstIndex++] = 0xFF;
- } else {
- dstData[dstIndex++] = bNew >> 16;
- }
-
- dstIndex++;
- }
- }
-};
-
-/**
- * Return a convolution filter function bound to specific weights.
- *
- * @param {Array.<number>} weights Weights for the convolution matrix
- * (not normalized).
- * @return {function(ImageData,ImageData,number,number)} Convolution filter.
- */
-filter.createConvolutionFilter = function(weights) {
- // Normalize the weights to sum to 1.
- var total = 0;
- for (var i = 0; i != weights.length; i++) {
- total += weights[i] * (i ? 4 : 1);
- }
-
- var normalized = [];
- for (i = 0; i != weights.length; i++) {
- normalized.push(weights[i] / total);
- }
- for (; i < 4; i++) {
- normalized.push(0);
- }
-
- var maxWeightedSum = 0xFF *
- Math.abs(normalized[0]) +
- Math.abs(normalized[1]) * 4 +
- Math.abs(normalized[2]) * 4 +
- Math.abs(normalized[3]) * 4;
- if (maxWeightedSum > filter.MAX_FLOAT_VALUE)
- throw new Error('convolve5x5 cannot convert the weights to fixed point');
-
- return filter.convolve5x5.bind(null, normalized);
-};
-
-/**
- * Creates matrix filter.
- * @param {Array.<number>} matrix Color transformation matrix.
- * @return {function(ImageData,ImageData,number,number)} Matrix filter.
- */
-filter.createColorMatrixFilter = function(matrix) {
- for (var r = 0; r != 3; r++) {
- var maxRowSum = 0;
- for (var c = 0; c != 3; c++) {
- maxRowSum += 0xFF * Math.abs(matrix[r * 3 + c]);
- }
- if (maxRowSum > filter.MAX_FLOAT_VALUE)
- throw new Error(
- 'colorMatrix3x3 cannot convert the matrix to fixed point');
- }
- return filter.colorMatrix3x3.bind(null, matrix);
-};
-
-/**
- * Return a blur filter.
- * @param {Object} options Blur options.
- * @return {function(ImageData,ImageData,number,number)} Blur filter.
- */
-filter.blur = function(options) {
- if (options.radius == 1)
- return filter.createConvolutionFilter(
- [1, options.strength]);
- else if (options.radius == 2)
- return filter.createConvolutionFilter(
- [1, options.strength, options.strength]);
- else
- return filter.createConvolutionFilter(
- [1, options.strength, options.strength, options.strength]);
-};
-
-/**
- * Return a sharpen filter.
- * @param {Object} options Sharpen options.
- * @return {function(ImageData,ImageData,number,number)} Sharpen filter.
- */
-filter.sharpen = function(options) {
- if (options.radius == 1)
- return filter.createConvolutionFilter(
- [5, -options.strength]);
- else if (options.radius == 2)
- return filter.createConvolutionFilter(
- [10, -options.strength, -options.strength]);
- else
- return filter.createConvolutionFilter(
- [15, -options.strength, -options.strength, -options.strength]);
-};
-
-/**
- * Return an exposure filter.
- * @param {Object} options exposure options.
- * @return {function(ImageData,ImageData,number,number)} Exposure filter.
- */
-filter.exposure = function(options) {
- var pixelMap = filter.precompute(
- 255,
- function(value) {
- if (options.brightness > 0) {
- value *= (1 + options.brightness);
- } else {
- value += (0xFF - value) * options.brightness;
- }
- return 0x80 +
- (value - 0x80) * Math.tan((options.contrast + 1) * Math.PI / 4);
- });
-
- return filter.mapPixels.bind(null, pixelMap, pixelMap, pixelMap);
-};
-
-/**
- * Return a color autofix filter.
- * @param {Object} options Histogram for autofix.
- * @return {function(ImageData,ImageData,number,number)} Autofix filter.
- */
-filter.autofix = function(options) {
- return filter.mapPixels.bind(null,
- filter.autofix.stretchColors(options.histogram.r),
- filter.autofix.stretchColors(options.histogram.g),
- filter.autofix.stretchColors(options.histogram.b));
-};
-
-/**
- * Return a conversion table that stretches the range of colors used
- * in the image to 0..255.
- * @param {Array.<number>} channelHistogram Histogram to calculate range.
- * @return {Uint8Array} Color mapping array.
- */
-filter.autofix.stretchColors = function(channelHistogram) {
- var range = filter.autofix.getRange(channelHistogram);
- return filter.precompute(
- 255,
- function(x) {
- return (x - range.first) / (range.last - range.first) * 255;
- }
- );
-};
-
-/**
- * Return a range that encloses non-zero elements values in a histogram array.
- * @param {Array.<number>} channelHistogram Histogram to analyze.
- * @return {{first: number, last: number}} Channel range in histogram.
- */
-filter.autofix.getRange = function(channelHistogram) {
- var first = 0;
- while (first < channelHistogram.length && channelHistogram[first] == 0)
- first++;
-
- var last = channelHistogram.length - 1;
- while (last >= 0 && channelHistogram[last] == 0)
- last--;
-
- if (first >= last) // Stretching does not make sense
- return {first: 0, last: channelHistogram.length - 1};
- else
- return {first: first, last: last};
-};
-
-/**
- * Minimum channel offset that makes visual difference. If autofix calculated
- * offset is less than SENSITIVITY, probably autofix is not needed.
- * Reasonable empirical value.
- * @type {number}
- */
-filter.autofix.SENSITIVITY = 8;
-
-/**
- * @param {Array.<number>} channelHistogram Histogram to analyze.
- * @return {boolean} True if stretching this range to 0..255 would make
- * a visible difference.
- */
-filter.autofix.needsStretching = function(channelHistogram) {
- var range = filter.autofix.getRange(channelHistogram);
- return (range.first >= filter.autofix.SENSITIVITY ||
- range.last <= 255 - filter.autofix.SENSITIVITY);
-};
-
-/**
- * @param {{r: Array.<number>, g: Array.<number>, b: Array.<number>}} histogram
- * @return {boolean} True if the autofix would make a visible difference.
- */
-filter.autofix.isApplicable = function(histogram) {
- return filter.autofix.needsStretching(histogram.r) ||
- filter.autofix.needsStretching(histogram.g) ||
- filter.autofix.needsStretching(histogram.b);
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_adjust.js b/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_adjust.js
deleted file mode 100644
index 2abb10ed2f5..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_adjust.js
+++ /dev/null
@@ -1,248 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * The base class for simple filters that only modify the image content
- * but do not modify the image dimensions.
- * @constructor
- * @extends ImageEditor.Mode
- */
-ImageEditor.Mode.Adjust = function() {
- ImageEditor.Mode.apply(this, arguments);
- this.implicitCommit = true;
- this.doneMessage_ = null;
- this.viewportGeneration_ = 0;
-};
-
-ImageEditor.Mode.Adjust.prototype = {__proto__: ImageEditor.Mode.prototype};
-
-/** @override */
-ImageEditor.Mode.Adjust.prototype.getCommand = function() {
- if (!this.filter_) return null;
-
- return new Command.Filter(this.name, this.filter_, this.doneMessage_);
-};
-
-/** @override */
-ImageEditor.Mode.Adjust.prototype.cleanUpUI = function() {
- ImageEditor.Mode.prototype.cleanUpUI.apply(this, arguments);
- this.hidePreview();
-};
-
-/**
- * TODO(JSDOC)
- */
-ImageEditor.Mode.Adjust.prototype.hidePreview = function() {
- if (this.canvas_) {
- this.canvas_.parentNode.removeChild(this.canvas_);
- this.canvas_ = null;
- }
-};
-
-/**
- * TODO(JSDOC)
- */
-ImageEditor.Mode.Adjust.prototype.cleanUpCaches = function() {
- this.filter_ = null;
- this.previewImageData_ = null;
-};
-
-/**
- * TODO(JSDOC)
- */
-ImageEditor.Mode.Adjust.prototype.reset = function() {
- ImageEditor.Mode.prototype.reset.call(this);
- this.hidePreview();
- this.cleanUpCaches();
-};
-
-/**
- * TODO(JSDOC)
- * @param {Object} options // TODO(JSDOC).
- */
-ImageEditor.Mode.Adjust.prototype.update = function(options) {
- ImageEditor.Mode.prototype.update.apply(this, arguments);
-
- // We assume filter names are used in the UI directly.
- // This will have to change with i18n.
- this.filter_ = this.createFilter(options);
- this.updatePreviewImage();
- ImageUtil.trace.resetTimer('preview');
- this.filter_(this.previewImageData_, this.originalImageData, 0, 0);
- ImageUtil.trace.reportTimer('preview');
- this.canvas_.getContext('2d').putImageData(
- this.previewImageData_, 0, 0);
-};
-
-/**
- * Copy the source image data for the preview.
- * Use the cached copy if the viewport has not changed.
- */
-ImageEditor.Mode.Adjust.prototype.updatePreviewImage = function() {
- if (!this.previewImageData_ ||
- this.viewportGeneration_ != this.getViewport().getCacheGeneration()) {
- this.viewportGeneration_ = this.getViewport().getCacheGeneration();
-
- if (!this.canvas_) {
- this.canvas_ = this.getImageView().createOverlayCanvas();
- }
-
- this.getImageView().setupDeviceBuffer(this.canvas_);
-
- this.originalImageData = this.getImageView().copyScreenImageData();
- this.previewImageData_ = this.getImageView().copyScreenImageData();
- }
-};
-
-/*
- * Own methods
- */
-
-/**
- * TODO(JSDOC)
- * @param {Object} options // TODO(JSDOC).
- * @return {function(ImageData,ImageData,number,number)} Created function.
- */
-ImageEditor.Mode.Adjust.prototype.createFilter = function(options) {
- return filter.create(this.name, options);
-};
-
-/**
- * A base class for color filters that are scale independent.
- * @constructor
- */
-ImageEditor.Mode.ColorFilter = function() {
- ImageEditor.Mode.Adjust.apply(this, arguments);
-};
-
-ImageEditor.Mode.ColorFilter.prototype =
- {__proto__: ImageEditor.Mode.Adjust.prototype};
-
-/**
- * TODO(JSDOC)
- * @return {{r: Array.<number>, g: Array.<number>, b: Array.<number>}}
- * histogram.
- */
-ImageEditor.Mode.ColorFilter.prototype.getHistogram = function() {
- return filter.getHistogram(this.getImageView().getThumbnail());
-};
-
-/**
- * Exposure/contrast filter.
- * @constructor
- */
-ImageEditor.Mode.Exposure = function() {
- ImageEditor.Mode.ColorFilter.call(this, 'exposure', 'GALLERY_EXPOSURE');
-};
-
-ImageEditor.Mode.Exposure.prototype =
- {__proto__: ImageEditor.Mode.ColorFilter.prototype};
-
-/**
- * TODO(JSDOC)
- * @param {ImageEditor.Toolbar} toolbar The toolbar to populate.
- */
-ImageEditor.Mode.Exposure.prototype.createTools = function(toolbar) {
- toolbar.addRange('brightness', 'GALLERY_BRIGHTNESS', -1, 0, 1, 100);
- toolbar.addRange('contrast', 'GALLERY_CONTRAST', -1, 0, 1, 100);
-};
-
-/**
- * Autofix.
- * @constructor
- */
-ImageEditor.Mode.Autofix = function() {
- ImageEditor.Mode.ColorFilter.call(this, 'autofix', 'GALLERY_AUTOFIX');
- this.doneMessage_ = 'GALLERY_FIXED';
-};
-
-ImageEditor.Mode.Autofix.prototype =
- {__proto__: ImageEditor.Mode.ColorFilter.prototype};
-
-/**
- * TODO(JSDOC)
- * @param {ImageEditor.Toolbar} toolbar The toolbar to populate.
- */
-ImageEditor.Mode.Autofix.prototype.createTools = function(toolbar) {
- var self = this;
- toolbar.addButton('Apply', this.apply.bind(this));
-};
-
-/**
- * TODO(JSDOC)
- * @return {boolean} // TODO(JSDOC).
- */
-ImageEditor.Mode.Autofix.prototype.isApplicable = function() {
- return this.getImageView().hasValidImage() &&
- filter.autofix.isApplicable(this.getHistogram());
-};
-
-/**
- * TODO(JSDOC)
- */
-ImageEditor.Mode.Autofix.prototype.apply = function() {
- this.update({histogram: this.getHistogram()});
-};
-
-/**
- * Instant Autofix.
- * @constructor
- */
-ImageEditor.Mode.InstantAutofix = function() {
- ImageEditor.Mode.Autofix.apply(this, arguments);
- this.instant = true;
-};
-
-ImageEditor.Mode.InstantAutofix.prototype =
- {__proto__: ImageEditor.Mode.Autofix.prototype};
-
-/**
- * TODO(JSDOC)
- */
-ImageEditor.Mode.InstantAutofix.prototype.setUp = function() {
- ImageEditor.Mode.Autofix.prototype.setUp.apply(this, arguments);
- this.apply();
-};
-
-/**
- * Blur filter.
- * @constructor
- */
-ImageEditor.Mode.Blur = function() {
- ImageEditor.Mode.Adjust.call(this, 'blur');
-};
-
-ImageEditor.Mode.Blur.prototype =
- {__proto__: ImageEditor.Mode.Adjust.prototype};
-
-/**
- * TODO(JSDOC)
- * @param {ImageEditor.Toolbar} toolbar The toolbar to populate.
- */
-ImageEditor.Mode.Blur.prototype.createTools = function(toolbar) {
- toolbar.addRange('strength', 'GALLERY_STRENGTH', 0, 0, 1, 100);
- toolbar.addRange('radius', 'GALLERY_RADIUS', 1, 1, 3);
-};
-
-/**
- * Sharpen filter.
- * @constructor
- */
-ImageEditor.Mode.Sharpen = function() {
- ImageEditor.Mode.Adjust.call(this, 'sharpen');
-};
-
-ImageEditor.Mode.Sharpen.prototype =
- {__proto__: ImageEditor.Mode.Adjust.prototype};
-
-/**
- * TODO(JSDOC)
- * @param {ImageEditor.Toolbar} toolbar The toolbar to populate.
- */
-ImageEditor.Mode.Sharpen.prototype.createTools = function(toolbar) {
- toolbar.addRange('strength', 'GALLERY_STRENGTH', 0, 0, 1, 100);
- toolbar.addRange('radius', 'GALLERY_RADIUS', 1, 1, 3);
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_buffer.js b/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_buffer.js
deleted file mode 100644
index 8e894a8a0f2..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_buffer.js
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * A stack of overlays that display itself and handle mouse events.
- * TODO(kaznacheev) Consider disbanding this class and moving
- * the functionality to individual objects that display anything or handle
- * mouse events.
- * @constructor
- */
-function ImageBuffer() {
- this.overlays_ = [];
-}
-
-/**
- * TODO(JSDOC).
- * @param {ImageBuffer.Overlay} overlay // TODO(JSDOC).
- */
-ImageBuffer.prototype.addOverlay = function(overlay) {
- var zIndex = overlay.getZIndex();
- // Store the overlays in the ascending Z-order.
- var i;
- for (i = 0; i != this.overlays_.length; i++) {
- if (zIndex < this.overlays_[i].getZIndex()) break;
- }
- this.overlays_.splice(i, 0, overlay);
-};
-
-/**
- * TODO(JSDOC).
- * @param {ImageBuffer.Overlay} overlay // TODO(JSDOC).
- */
-ImageBuffer.prototype.removeOverlay = function(overlay) {
- for (var i = 0; i != this.overlays_.length; i++) {
- if (this.overlays_[i] == overlay) {
- this.overlays_.splice(i, 1);
- return;
- }
- }
- throw new Error('Cannot remove overlay ' + overlay);
-};
-
-/**
- * Draws overlays in the ascending Z-order.
- */
-ImageBuffer.prototype.draw = function() {
- for (var i = 0; i != this.overlays_.length; i++) {
- this.overlays_[i].draw();
- }
-};
-
-/**
- * Searches for a cursor style in the descending Z-order.
- * @param {number} x X coordinate for cursor.
- * @param {number} y Y coordinate for cursor.
- * @param {boolean} mouseDown If mouse button is down.
- * @return {string} A value for style.cursor CSS property.
- */
-ImageBuffer.prototype.getCursorStyle = function(x, y, mouseDown) {
- for (var i = this.overlays_.length - 1; i >= 0; i--) {
- var style = this.overlays_[i].getCursorStyle(x, y, mouseDown);
- if (style) return style;
- }
- return 'default';
-};
-
-/**
- * Searches for a click handler in the descending Z-order.
- * @param {number} x X coordinate for click event.
- * @param {number} y Y coordinate for click event.
- * @return {boolean} True if handled.
- */
-ImageBuffer.prototype.onClick = function(x, y) {
- for (var i = this.overlays_.length - 1; i >= 0; i--) {
- if (this.overlays_[i].onClick(x, y)) return true;
- }
- return false;
-};
-
-/**
- * Searches for a drag handler in the descending Z-order.
- * @param {number} x Event X coordinate.
- * @param {number} y Event Y coordinate.
- * @param {boolean} touch True if it's a touch event, false if mouse.
- * @return {function(number,number)} A function to be called on mouse drag.
- */
-ImageBuffer.prototype.getDragHandler = function(x, y, touch) {
- for (var i = this.overlays_.length - 1; i >= 0; i--) {
- var handler = this.overlays_[i].getDragHandler(x, y, touch);
- if (handler)
- return handler;
- }
- return null;
-};
-
-/**
- * Searches for an action for the double tap enumerating
- * layers in the descending Z-order.
- * @param {number} x X coordinate of the event.
- * @param {number} y Y coordinate of the event.
- * @return {ImageBuffer.DoubleTapAction} Action to perform as result.
- */
-ImageBuffer.prototype.getDoubleTapAction = function(x, y) {
- for (var i = this.overlays_.length - 1; i >= 0; i--) {
- var action = this.overlays_[i].getDoubleTapAction(x, y);
- if (action != ImageBuffer.DoubleTapAction.NOTHING)
- return action;
- }
- return ImageBuffer.DoubleTapAction.NOTHING;
-};
-
-/**
- * Possible double tap actions.
- * @enum
- */
-ImageBuffer.DoubleTapAction = {
- NOTHING: 0,
- COMMIT: 1,
- CANCEL: 2
-};
-
-/**
- * ImageBuffer.Overlay is a pluggable extension that modifies the outlook
- * and the behavior of the ImageBuffer instance.
- * @class
- */
-ImageBuffer.Overlay = function() {};
-
-/**
- * TODO(JSDOC).
- * @return {number} // TODO(JSDOC).
- */
-ImageBuffer.Overlay.prototype.getZIndex = function() { return 0 };
-
-/**
- * TODO(JSDOC).
- */
-ImageBuffer.Overlay.prototype.draw = function() {};
-
-/**
- * TODO(JSDOC).
- * @param {number} x X coordinate for cursor.
- * @param {number} y Y coordinate for cursor.
- * @param {boolean} mouseDown If mouse button is down.
- * @return {?string} A value for style.cursor CSS property or null for
- * default.
- */
-ImageBuffer.Overlay.prototype.getCursorStyle = function(x, y, mouseDown) {
- return null;
-};
-
-/**
- * TODO(JSDOC).
- * @param {number} x // TODO(JSDOC).
- * @param {number} y // TODO(JSDOC).
- * @return {boolean} // TODO(JSDOC).
- */
-ImageBuffer.Overlay.prototype.onClick = function(x, y) {
- return false;
-};
-
-/**
- * TODO(JSDOC).
- * @param {number} x Event X coordinate.
- * @param {number} y Event Y coordinate.
- * @param {boolean} touch True if it's a touch event, false if mouse.
- * @return {function(number,number)} A function to be called on mouse drag.
- */
-ImageBuffer.Overlay.prototype.getDragHandler = function(x, y, touch) {
- return null;
-};
-
-/**
- * TODO(JSDOC).
- * @param {number} x // TODO(JSDOC).
- * @param {number} y // TODO(JSDOC).
- * @return {ImageBuffer.DoubleTapAction} // TODO(JSDOC).
- */
-ImageBuffer.Overlay.prototype.getDoubleTapAction = function(x, y) {
- return ImageBuffer.DoubleTapAction.NOTHING;
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_editor.js b/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_editor.js
deleted file mode 100644
index 090155494bd..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_editor.js
+++ /dev/null
@@ -1,1177 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * ImageEditor is the top level object that holds together and connects
- * everything needed for image editing.
- *
- * @param {Viewport} viewport The viewport.
- * @param {ImageView} imageView The ImageView containing the images to edit.
- * @param {ImageEditor.Prompt} prompt Prompt instance.
- * @param {Object} DOMContainers Various DOM containers required for the editor.
- * @param {Array.<ImageEditor.Mode>} modes Available editor modes.
- * @param {function} displayStringFunction String formatting function.
- * @param {function()} onToolsVisibilityChanged Callback to be called, when
- * some of the UI elements have been dimmed or revealed.
- * @constructor
- */
-function ImageEditor(
- viewport, imageView, prompt, DOMContainers, modes, displayStringFunction,
- onToolsVisibilityChanged) {
- this.rootContainer_ = DOMContainers.root;
- this.container_ = DOMContainers.image;
- this.modes_ = modes;
- this.displayStringFunction_ = displayStringFunction;
- this.onToolsVisibilityChanged_ = onToolsVisibilityChanged;
-
- ImageUtil.removeChildren(this.container_);
-
- var document = this.container_.ownerDocument;
-
- this.viewport_ = viewport;
- this.viewport_.sizeByFrame(this.container_);
-
- this.buffer_ = new ImageBuffer();
- this.viewport_.addRepaintCallback(this.buffer_.draw.bind(this.buffer_));
-
- this.imageView_ = imageView;
- this.imageView_.addContentCallback(this.onContentUpdate_.bind(this));
- this.buffer_.addOverlay(this.imageView_);
-
- this.panControl_ = new ImageEditor.MouseControl(
- this.rootContainer_, this.container_, this.getBuffer());
-
- this.panControl_.setDoubleTapCallback(this.onDoubleTap_.bind(this));
-
- this.mainToolbar_ = new ImageEditor.Toolbar(
- DOMContainers.toolbar, displayStringFunction);
-
- this.modeToolbar_ = new ImageEditor.Toolbar(
- DOMContainers.mode, displayStringFunction,
- this.onOptionsChange.bind(this));
-
- this.prompt_ = prompt;
-
- this.createToolButtons();
-
- this.commandQueue_ = null;
-}
-
-/**
- * @return {boolean} True if no user commands are to be accepted.
- */
-ImageEditor.prototype.isLocked = function() {
- return !this.commandQueue_ || this.commandQueue_.isBusy();
-};
-
-/**
- * @return {boolean} True if the command queue is busy.
- */
-ImageEditor.prototype.isBusy = function() {
- return this.commandQueue_ && this.commandQueue_.isBusy();
-};
-
-/**
- * Reflect the locked state of the editor in the UI.
- * @param {boolean} on True if locked.
- */
-ImageEditor.prototype.lockUI = function(on) {
- ImageUtil.setAttribute(this.rootContainer_, 'locked', on);
-};
-
-/**
- * Report the tool use to the metrics subsystem.
- * @param {string} name Action name.
- */
-ImageEditor.prototype.recordToolUse = function(name) {
- ImageUtil.metrics.recordEnum(
- ImageUtil.getMetricName('Tool'), name, this.actionNames_);
-};
-
-/**
- * Content update handler.
- * @private
- */
-ImageEditor.prototype.onContentUpdate_ = function() {
- for (var i = 0; i != this.modes_.length; i++) {
- var mode = this.modes_[i];
- ImageUtil.setAttribute(mode.button_, 'disabled', !mode.isApplicable());
- }
-};
-
-/**
- * Open the editing session for a new image.
- *
- * @param {string} url Image url.
- * @param {Object} metadata Metadata.
- * @param {Object} effect Transition effect object.
- * @param {function(function)} saveFunction Image save function.
- * @param {function} displayCallback Display callback.
- * @param {function} loadCallback Load callback.
- */
-ImageEditor.prototype.openSession = function(
- url, metadata, effect, saveFunction, displayCallback, loadCallback) {
- if (this.commandQueue_)
- throw new Error('Session not closed');
-
- this.lockUI(true);
-
- var self = this;
- this.imageView_.load(
- url, metadata, effect, displayCallback, function(loadType, delay, error) {
- self.lockUI(false);
- self.commandQueue_ = new CommandQueue(
- self.container_.ownerDocument,
- self.imageView_.getCanvas(),
- saveFunction);
- self.commandQueue_.attachUI(
- self.getImageView(), self.getPrompt(), self.lockUI.bind(self));
- self.updateUndoRedo();
- loadCallback(loadType, delay, error);
- });
-};
-
-/**
- * Close the current image editing session.
- * @param {function} callback Callback.
- */
-ImageEditor.prototype.closeSession = function(callback) {
- this.getPrompt().hide();
- if (this.imageView_.isLoading()) {
- if (this.commandQueue_) {
- console.warn('Inconsistent image editor state');
- this.commandQueue_ = null;
- }
- this.imageView_.cancelLoad();
- this.lockUI(false);
- callback();
- return;
- }
- if (!this.commandQueue_) {
- // Session is already closed.
- callback();
- return;
- }
-
- this.executeWhenReady(callback);
- this.commandQueue_.close();
- this.commandQueue_ = null;
-};
-
-/**
- * Commit the current operation and execute the action.
- *
- * @param {function} callback Callback.
- */
-ImageEditor.prototype.executeWhenReady = function(callback) {
- if (this.commandQueue_) {
- this.leaveModeGently();
- this.commandQueue_.executeWhenReady(callback);
- } else {
- if (!this.imageView_.isLoading())
- console.warn('Inconsistent image editor state');
- callback();
- }
-};
-
-/**
- * @return {boolean} True if undo queue is not empty.
- */
-ImageEditor.prototype.canUndo = function() {
- return this.commandQueue_ && this.commandQueue_.canUndo();
-};
-
-/**
- * Undo the recently executed command.
- */
-ImageEditor.prototype.undo = function() {
- if (this.isLocked()) return;
- this.recordToolUse('undo');
-
- // First undo click should dismiss the uncommitted modifications.
- if (this.currentMode_ && this.currentMode_.isUpdated()) {
- this.currentMode_.reset();
- return;
- }
-
- this.getPrompt().hide();
- this.leaveMode(false);
- this.commandQueue_.undo();
- this.updateUndoRedo();
-};
-
-/**
- * Redo the recently un-done command.
- */
-ImageEditor.prototype.redo = function() {
- if (this.isLocked()) return;
- this.recordToolUse('redo');
- this.getPrompt().hide();
- this.leaveMode(false);
- this.commandQueue_.redo();
- this.updateUndoRedo();
-};
-
-/**
- * Update Undo/Redo buttons state.
- */
-ImageEditor.prototype.updateUndoRedo = function() {
- var canUndo = this.commandQueue_ && this.commandQueue_.canUndo();
- var canRedo = this.commandQueue_ && this.commandQueue_.canRedo();
- ImageUtil.setAttribute(this.undoButton_, 'disabled', !canUndo);
- this.redoButton_.hidden = !canRedo;
-};
-
-/**
- * @return {HTMLCanvasElement} The current image canvas.
- */
-ImageEditor.prototype.getCanvas = function() {
- return this.getImageView().getCanvas();
-};
-
-/**
- * @return {ImageBuffer} ImageBuffer instance.
- */
-ImageEditor.prototype.getBuffer = function() { return this.buffer_ };
-
-/**
- * @return {ImageView} ImageView instance.
- */
-ImageEditor.prototype.getImageView = function() { return this.imageView_ };
-
-/**
- * @return {Viewport} Viewport instance.
- */
-ImageEditor.prototype.getViewport = function() { return this.viewport_ };
-
-/**
- * @return {ImageEditor.Prompt} Prompt instance.
- */
-ImageEditor.prototype.getPrompt = function() { return this.prompt_ };
-
-/**
- * Handle the toolbar controls update.
- * @param {Object} options A map of options.
- */
-ImageEditor.prototype.onOptionsChange = function(options) {
- ImageUtil.trace.resetTimer('update');
- if (this.currentMode_) {
- this.currentMode_.update(options);
- }
- ImageUtil.trace.reportTimer('update');
-};
-
-/**
- * ImageEditor.Mode represents a modal state dedicated to a specific operation.
- * Inherits from ImageBuffer. Overlay to simplify the drawing of mode-specific
- * tools.
- *
- * @param {string} name The mode name.
- * @param {string} title The mode title.
- * @constructor
- */
-
-ImageEditor.Mode = function(name, title) {
- this.name = name;
- this.title = title;
- this.message_ = 'GALLERY_ENTER_WHEN_DONE';
-};
-
-ImageEditor.Mode.prototype = {__proto__: ImageBuffer.Overlay.prototype };
-
-/**
- * @return {Viewport} Viewport instance.
- */
-ImageEditor.Mode.prototype.getViewport = function() { return this.viewport_ };
-
-/**
- * @return {ImageView} ImageView instance.
- */
-ImageEditor.Mode.prototype.getImageView = function() { return this.imageView_ };
-
-/**
- * @return {string} The mode-specific message to be displayed when entering.
- */
-ImageEditor.Mode.prototype.getMessage = function() { return this.message_ };
-
-/**
- * @return {boolean} True if the mode is applicable in the current context.
- */
-ImageEditor.Mode.prototype.isApplicable = function() { return true };
-
-/**
- * Called once after creating the mode button.
- *
- * @param {ImageEditor} editor The editor instance.
- * @param {HTMLElement} button The mode button.
- */
-
-ImageEditor.Mode.prototype.bind = function(editor, button) {
- this.editor_ = editor;
- this.editor_.registerAction_(this.name);
- this.button_ = button;
- this.viewport_ = editor.getViewport();
- this.imageView_ = editor.getImageView();
-};
-
-/**
- * Called before entering the mode.
- */
-ImageEditor.Mode.prototype.setUp = function() {
- this.editor_.getBuffer().addOverlay(this);
- this.updated_ = false;
-};
-
-/**
- * Create mode-specific controls here.
- * @param {ImageEditor.Toolbar} toolbar The toolbar to populate.
- */
-ImageEditor.Mode.prototype.createTools = function(toolbar) {};
-
-/**
- * Called before exiting the mode.
- */
-ImageEditor.Mode.prototype.cleanUpUI = function() {
- this.editor_.getBuffer().removeOverlay(this);
-};
-
-/**
- * Called after exiting the mode.
- */
-ImageEditor.Mode.prototype.cleanUpCaches = function() {};
-
-/**
- * Called when any of the controls changed its value.
- * @param {Object} options A map of options.
- */
-ImageEditor.Mode.prototype.update = function(options) {
- this.markUpdated();
-};
-
-/**
- * Mark the editor mode as updated.
- */
-ImageEditor.Mode.prototype.markUpdated = function() {
- this.updated_ = true;
-};
-
-/**
- * @return {boolean} True if the mode controls changed.
- */
-ImageEditor.Mode.prototype.isUpdated = function() { return this.updated_ };
-
-/**
- * Resets the mode to a clean state.
- */
-ImageEditor.Mode.prototype.reset = function() {
- this.editor_.modeToolbar_.reset();
- this.updated_ = false;
-};
-
-/**
- * One-click editor tool, requires no interaction, just executes the command.
- *
- * @param {string} name The mode name.
- * @param {string} title The mode title.
- * @param {Command} command The command to execute on click.
- * @constructor
- */
-ImageEditor.Mode.OneClick = function(name, title, command) {
- ImageEditor.Mode.call(this, name, title);
- this.instant = true;
- this.command_ = command;
-};
-
-ImageEditor.Mode.OneClick.prototype = {__proto__: ImageEditor.Mode.prototype};
-
-/**
- * @return {Command} command.
- */
-ImageEditor.Mode.OneClick.prototype.getCommand = function() {
- return this.command_;
-};
-
-/**
- * Register the action name. Required for metrics reporting.
- * @param {string} name Button name.
- * @private
- */
-ImageEditor.prototype.registerAction_ = function(name) {
- this.actionNames_.push(name);
-};
-
-/**
- * Populate the toolbar.
- */
-ImageEditor.prototype.createToolButtons = function() {
- this.mainToolbar_.clear();
- this.actionNames_ = [];
-
- var self = this;
- function createButton(name, title, handler) {
- return self.mainToolbar_.addButton(name,
- title,
- handler,
- name /* opt_className */);
- }
-
- for (var i = 0; i != this.modes_.length; i++) {
- var mode = this.modes_[i];
- mode.bind(this, createButton(mode.name,
- mode.title,
- this.enterMode.bind(this, mode)));
- }
-
- this.undoButton_ = createButton('undo',
- 'GALLERY_UNDO',
- this.undo.bind(this));
- this.registerAction_('undo');
-
- this.redoButton_ = createButton('redo',
- 'GALLERY_REDO',
- this.redo.bind(this));
- this.registerAction_('redo');
-};
-
-/**
- * @return {ImageEditor.Mode} The current mode.
- */
-ImageEditor.prototype.getMode = function() { return this.currentMode_ };
-
-/**
- * The user clicked on the mode button.
- *
- * @param {ImageEditor.Mode} mode The new mode.
- */
-ImageEditor.prototype.enterMode = function(mode) {
- if (this.isLocked()) return;
-
- if (this.currentMode_ == mode) {
- // Currently active editor tool clicked, commit if modified.
- this.leaveMode(this.currentMode_.updated_);
- return;
- }
-
- this.recordToolUse(mode.name);
-
- this.leaveModeGently();
- // The above call could have caused a commit which might have initiated
- // an asynchronous command execution. Wait for it to complete, then proceed
- // with the mode set up.
- this.commandQueue_.executeWhenReady(this.setUpMode_.bind(this, mode));
-};
-
-/**
- * Set up the new editing mode.
- *
- * @param {ImageEditor.Mode} mode The mode.
- * @private
- */
-ImageEditor.prototype.setUpMode_ = function(mode) {
- this.currentTool_ = mode.button_;
-
- ImageUtil.setAttribute(this.currentTool_, 'pressed', true);
-
- this.currentMode_ = mode;
- this.currentMode_.setUp();
-
- if (this.currentMode_.instant) { // Instant tool.
- this.leaveMode(true);
- return;
- }
-
- this.getPrompt().show(this.currentMode_.getMessage());
-
- this.modeToolbar_.clear();
- this.currentMode_.createTools(this.modeToolbar_);
- this.modeToolbar_.show(true);
-};
-
-/**
- * The user clicked on 'OK' or 'Cancel' or on a different mode button.
- * @param {boolean} commit True if commit is required.
- */
-ImageEditor.prototype.leaveMode = function(commit) {
- if (!this.currentMode_) return;
-
- if (!this.currentMode_.instant) {
- this.getPrompt().hide();
- }
-
- this.modeToolbar_.show(false);
-
- this.currentMode_.cleanUpUI();
- if (commit) {
- var self = this;
- var command = this.currentMode_.getCommand();
- if (command) { // Could be null if the user did not do anything.
- this.commandQueue_.execute(command);
- this.updateUndoRedo();
- }
- }
- this.currentMode_.cleanUpCaches();
- this.currentMode_ = null;
-
- ImageUtil.setAttribute(this.currentTool_, 'pressed', false);
- this.currentTool_ = null;
-};
-
-/**
- * Leave the mode, commit only if required by the current mode.
- */
-ImageEditor.prototype.leaveModeGently = function() {
- this.leaveMode(this.currentMode_ &&
- this.currentMode_.updated_ &&
- this.currentMode_.implicitCommit);
-};
-
-/**
- * Enter the editor mode with the given name.
- *
- * @param {string} name Mode name.
- * @private
- */
-ImageEditor.prototype.enterModeByName_ = function(name) {
- for (var i = 0; i != this.modes_.length; i++) {
- var mode = this.modes_[i];
- if (mode.name == name) {
- if (!mode.button_.hasAttribute('disabled'))
- this.enterMode(mode);
- return;
- }
- }
- console.error('Mode "' + name + '" not found.');
-};
-
-/**
- * Key down handler.
- * @param {Event} event The keydown event.
- * @return {boolean} True if handled.
- */
-ImageEditor.prototype.onKeyDown = function(event) {
- switch (util.getKeyModifiers(event) + event.keyIdentifier) {
- case 'U+001B': // Escape
- case 'Enter':
- if (this.getMode()) {
- this.leaveMode(event.keyIdentifier == 'Enter');
- return true;
- }
- break;
-
- case 'Ctrl-U+005A': // Ctrl+Z
- if (this.commandQueue_.canUndo()) {
- this.undo();
- return true;
- }
- break;
-
- case 'Ctrl-U+0059': // Ctrl+Y
- if (this.commandQueue_.canRedo()) {
- this.redo();
- return true;
- }
- break;
-
- case 'U+0041': // 'a'
- this.enterModeByName_('autofix');
- return true;
-
- case 'U+0042': // 'b'
- this.enterModeByName_('exposure');
- return true;
-
- case 'U+0043': // 'c'
- this.enterModeByName_('crop');
- return true;
-
- case 'U+004C': // 'l'
- this.enterModeByName_('rotate_left');
- return true;
-
- case 'U+0052': // 'r'
- this.enterModeByName_('rotate_right');
- return true;
- }
- return false;
-};
-
-/**
- * Double tap handler.
- * @param {number} x X coordinate of the event.
- * @param {number} y Y coordinate of the event.
- * @private
- */
-ImageEditor.prototype.onDoubleTap_ = function(x, y) {
- if (this.getMode()) {
- var action = this.buffer_.getDoubleTapAction(x, y);
- if (action == ImageBuffer.DoubleTapAction.COMMIT)
- this.leaveMode(true);
- else if (action == ImageBuffer.DoubleTapAction.CANCEL)
- this.leaveMode(false);
- }
-};
-
-/**
- * Hide the tools that overlap the given rectangular frame.
- *
- * @param {Rect} frame Hide the tool that overlaps this rect.
- * @param {Rect} transparent But do not hide the tool that is completely inside
- * this rect.
- */
-ImageEditor.prototype.hideOverlappingTools = function(frame, transparent) {
- var tools = this.rootContainer_.ownerDocument.querySelectorAll('.dimmable');
- var changed = false;
- for (var i = 0; i != tools.length; i++) {
- var tool = tools[i];
- var toolRect = tool.getBoundingClientRect();
- var overlapping =
- (frame && frame.intersects(toolRect)) &&
- !(transparent && transparent.contains(toolRect));
- if (overlapping && !tool.hasAttribute('dimmed') ||
- !overlapping && tool.hasAttribute('dimmed')) {
- ImageUtil.setAttribute(tool, 'dimmed', overlapping);
- changed = true;
- }
- }
- if (changed)
- this.onToolsVisibilityChanged_();
-};
-
-/**
- * A helper object for panning the ImageBuffer.
- *
- * @param {HTMLElement} rootContainer The top-level container.
- * @param {HTMLElement} container The container for mouse events.
- * @param {ImageBuffer} buffer Image buffer.
- * @constructor
- */
-ImageEditor.MouseControl = function(rootContainer, container, buffer) {
- this.rootContainer_ = rootContainer;
- this.container_ = container;
- this.buffer_ = buffer;
-
- var handlers = {
- 'touchstart': this.onTouchStart,
- 'touchend': this.onTouchEnd,
- 'touchcancel': this.onTouchCancel,
- 'touchmove': this.onTouchMove,
- 'mousedown': this.onMouseDown,
- 'mouseup': this.onMouseUp
- };
-
- for (var eventName in handlers) {
- container.addEventListener(
- eventName, handlers[eventName].bind(this), false);
- }
-
- // Mouse move handler has to be attached to the window to receive events
- // from outside of the window. See: http://crbug.com/155705
- window.addEventListener('mousemove', this.onMouseMove.bind(this), false);
-};
-
-/**
- * Maximum movement for touch to be detected as a tap (in pixels).
- * @private
- */
-ImageEditor.MouseControl.MAX_MOVEMENT_FOR_TAP_ = 8;
-
-/**
- * Maximum time for touch to be detected as a tap (in milliseconds).
- * @private
- */
-ImageEditor.MouseControl.MAX_TAP_DURATION_ = 500;
-
-/**
- * Maximum distance from the first tap to the second tap to be considered
- * as a double tap.
- * @private
- */
-ImageEditor.MouseControl.MAX_DISTANCE_FOR_DOUBLE_TAP_ = 32;
-
-/**
- * Maximum time for touch to be detected as a double tap (in milliseconds).
- * @private
- */
-ImageEditor.MouseControl.MAX_DOUBLE_TAP_DURATION_ = 1000;
-
-/**
- * Returns an event's position.
- *
- * @param {MouseEvent|Touch} e Pointer position.
- * @return {Object} A pair of x,y in page coordinates.
- * @private
- */
-ImageEditor.MouseControl.getPosition_ = function(e) {
- return {
- x: e.pageX,
- y: e.pageY
- };
-};
-
-/**
- * Returns touch position or null if there is more than one touch position.
- *
- * @param {TouchEvent} e Event.
- * @return {object?} A pair of x,y in page coordinates.
- * @private
- */
-ImageEditor.MouseControl.prototype.getTouchPosition_ = function(e) {
- if (e.targetTouches.length == 1)
- return ImageEditor.MouseControl.getPosition_(e.targetTouches[0]);
- else
- return null;
-};
-
-/**
- * Touch start handler.
- * @param {TouchEvent} e Event.
- */
-ImageEditor.MouseControl.prototype.onTouchStart = function(e) {
- var position = this.getTouchPosition_(e);
- if (position) {
- this.touchStartInfo_ = {
- x: position.x,
- y: position.y,
- time: Date.now()
- };
- this.dragHandler_ = this.buffer_.getDragHandler(position.x, position.y,
- true /* touch */);
- this.dragHappened_ = false;
- }
-};
-
-/**
- * Touch end handler.
- * @param {TouchEvent} e Event.
- */
-ImageEditor.MouseControl.prototype.onTouchEnd = function(e) {
- if (!this.dragHappened_ && Date.now() - this.touchStartInfo_.time <=
- ImageEditor.MouseControl.MAX_TAP_DURATION_) {
- this.buffer_.onClick(this.touchStartInfo_.x, this.touchStartInfo_.y);
- if (this.previousTouchStartInfo_ &&
- Date.now() - this.previousTouchStartInfo_.time <
- ImageEditor.MouseControl.MAX_DOUBLE_TAP_DURATION_) {
- var prevTouchCircle = new Circle(
- this.previousTouchStartInfo_.x,
- this.previousTouchStartInfo_.y,
- ImageEditor.MouseControl.MAX_DISTANCE_FOR_DOUBLE_TAP_);
- if (prevTouchCircle.inside(this.touchStartInfo_.x,
- this.touchStartInfo_.y)) {
- this.doubleTapCallback_(this.touchStartInfo_.x, this.touchStartInfo_.y);
- }
- }
- this.previousTouchStartInfo_ = this.touchStartInfo_;
- } else {
- this.previousTouchStartInfo_ = null;
- }
- this.onTouchCancel(e);
-};
-
-/**
- * Default double tap handler.
- * @param {number} x X coordinate of the event.
- * @param {number} y Y coordinate of the event.
- * @private
- */
-ImageEditor.MouseControl.prototype.doubleTapCallback_ = function(x, y) {};
-
-/**
- * Sets callback to be called when double tap detected.
- * @param {function(number, number)} callback New double tap callback.
- */
-ImageEditor.MouseControl.prototype.setDoubleTapCallback = function(callback) {
- this.doubleTapCallback_ = callback;
-};
-
-/**
- * Touch chancel handler.
- */
-ImageEditor.MouseControl.prototype.onTouchCancel = function() {
- this.dragHandler_ = null;
- this.dragHappened_ = false;
- this.touchStartInfo_ = null;
- this.lockMouse_(false);
-};
-
-/**
- * Touch move handler.
- * @param {TouchEvent} e Event.
- */
-ImageEditor.MouseControl.prototype.onTouchMove = function(e) {
- var position = this.getTouchPosition_(e);
- if (!position)
- return;
-
- if (this.touchStartInfo_ && !this.dragHappened_) {
- var tapCircle = new Circle(this.touchStartInfo_.x, this.touchStartInfo_.y,
- ImageEditor.MouseControl.MAX_MOVEMENT_FOR_TAP_);
- this.dragHappened_ = !tapCircle.inside(position.x, position.y);
- }
- if (this.dragHandler_ && this.dragHappened_) {
- this.dragHandler_(position.x, position.y);
- this.lockMouse_(true);
- }
-};
-
-/**
- * Mouse down handler.
- * @param {MouseEvent} e Event.
- */
-ImageEditor.MouseControl.prototype.onMouseDown = function(e) {
- var position = ImageEditor.MouseControl.getPosition_(e);
-
- this.dragHandler_ = this.buffer_.getDragHandler(position.x, position.y,
- false /* mouse */);
- this.dragHappened_ = false;
- this.updateCursor_(position);
-};
-
-/**
- * Mouse up handler.
- * @param {MouseEvent} e Event.
- */
-ImageEditor.MouseControl.prototype.onMouseUp = function(e) {
- var position = ImageEditor.MouseControl.getPosition_(e);
-
- if (!this.dragHappened_) {
- this.buffer_.onClick(position.x, position.y);
- }
- this.dragHandler_ = null;
- this.dragHappened_ = false;
- this.lockMouse_(false);
-};
-
-/**
- * Mouse move handler.
- * @param {MouseEvent} e Event.
- */
-ImageEditor.MouseControl.prototype.onMouseMove = function(e) {
- var position = ImageEditor.MouseControl.getPosition_(e);
-
- if (this.dragHandler_ && !e.which) {
- // mouseup must have happened while the mouse was outside our window.
- this.dragHandler_ = null;
- this.lockMouse_(false);
- }
-
- this.updateCursor_(position);
- if (this.dragHandler_) {
- this.dragHandler_(position.x, position.y);
- this.dragHappened_ = true;
- this.lockMouse_(true);
- }
-};
-
-/**
- * Update the UI to reflect mouse drag state.
- * @param {boolean} on True if dragging.
- * @private
- */
-ImageEditor.MouseControl.prototype.lockMouse_ = function(on) {
- ImageUtil.setAttribute(this.rootContainer_, 'mousedrag', on);
-};
-
-/**
- * Update the cursor.
- *
- * @param {Object} position An object holding x and y properties.
- * @private
- */
-ImageEditor.MouseControl.prototype.updateCursor_ = function(position) {
- var oldCursor = this.container_.getAttribute('cursor');
- var newCursor = this.buffer_.getCursorStyle(
- position.x, position.y, !!this.dragHandler_);
- if (newCursor != oldCursor) // Avoid flicker.
- this.container_.setAttribute('cursor', newCursor);
-};
-
-/**
- * A toolbar for the ImageEditor.
- * @param {HTMLElement} parent The parent element.
- * @param {function} displayStringFunction A string formatting function.
- * @param {function} updateCallback The callback called when controls change.
- * @constructor
- */
-ImageEditor.Toolbar = function(parent, displayStringFunction, updateCallback) {
- this.wrapper_ = parent;
- this.displayStringFunction_ = displayStringFunction;
- this.updateCallback_ = updateCallback;
-};
-
-/**
- * Clear the toolbar.
- */
-ImageEditor.Toolbar.prototype.clear = function() {
- ImageUtil.removeChildren(this.wrapper_);
-};
-
-/**
- * Create a control.
- * @param {string} tagName The element tag name.
- * @return {HTMLElement} The created control element.
- * @private
- */
-ImageEditor.Toolbar.prototype.create_ = function(tagName) {
- return this.wrapper_.ownerDocument.createElement(tagName);
-};
-
-/**
- * Add a control.
- * @param {HTMLElement} element The control to add.
- * @return {HTMLElement} The added element.
- */
-ImageEditor.Toolbar.prototype.add = function(element) {
- this.wrapper_.appendChild(element);
- return element;
-};
-
-/**
- * Add a text label.
- * @param {string} name Label name.
- * @return {HTMLElement} The added label.
- */
-ImageEditor.Toolbar.prototype.addLabel = function(name) {
- var label = this.create_('span');
- label.textContent = this.displayStringFunction_(name);
- return this.add(label);
-};
-
-/**
- * Add a button.
- *
- * @param {string} name Button name.
- * @param {string} title Button title.
- * @param {function} handler onClick handler.
- * @param {string=} opt_class Extra class name.
- * @return {HTMLElement} The added button.
- */
-ImageEditor.Toolbar.prototype.addButton = function(
- name, title, handler, opt_class) {
- var button = this.create_('button');
- if (opt_class) button.classList.add(opt_class);
- var label = this.create_('span');
- label.textContent = this.displayStringFunction_(title);
- button.appendChild(label);
- button.label = this.displayStringFunction_(title);
- button.addEventListener('click', handler, false);
- return this.add(button);
-};
-
-/**
- * Add a range control (scalar value picker).
- *
- * @param {string} name An option name.
- * @param {string} title An option title.
- * @param {number} min Min value of the option.
- * @param {number} value Default value of the option.
- * @param {number} max Max value of the options.
- * @param {number} scale A number to multiply by when setting
- * min/value/max in DOM.
- * @param {boolean=} opt_showNumeric True if numeric value should be displayed.
- * @return {HTMLElement} Range element.
- */
-ImageEditor.Toolbar.prototype.addRange = function(
- name, title, min, value, max, scale, opt_showNumeric) {
- var self = this;
-
- scale = scale || 1;
-
- var range = this.create_('input');
-
- range.className = 'range';
- range.type = 'range';
- range.name = name;
- range.min = Math.ceil(min * scale);
- range.max = Math.floor(max * scale);
-
- var numeric = this.create_('div');
- numeric.className = 'numeric';
- function mirror() {
- numeric.textContent = Math.round(range.getValue() * scale) / scale;
- }
-
- range.setValue = function(newValue) {
- range.value = Math.round(newValue * scale);
- mirror();
- };
-
- range.getValue = function() {
- return Number(range.value) / scale;
- };
-
- range.reset = function() {
- range.setValue(value);
- };
-
- range.addEventListener('change',
- function() {
- mirror();
- self.updateCallback_(self.getOptions());
- },
- false);
-
- range.setValue(value);
-
- var label = this.create_('div');
- label.textContent = this.displayStringFunction_(title);
- label.className = 'label ' + name;
- this.add(label);
- this.add(range);
-
- if (opt_showNumeric)
- this.add(numeric);
-
- // Swallow the left and right keys, so they are not handled by other
- // listeners.
- range.addEventListener('keydown', function(e) {
- if (e.keyIdentifier === 'Left' || e.keyIdentifier === 'Right')
- e.stopPropagation();
- });
-
- return range;
-};
-
-/**
- * @return {Object} options A map of options.
- */
-ImageEditor.Toolbar.prototype.getOptions = function() {
- var values = {};
- for (var child = this.wrapper_.firstChild; child; child = child.nextSibling) {
- if (child.name)
- values[child.name] = child.getValue();
- }
- return values;
-};
-
-/**
- * Reset the toolbar.
- */
-ImageEditor.Toolbar.prototype.reset = function() {
- for (var child = this.wrapper_.firstChild; child; child = child.nextSibling) {
- if (child.reset) child.reset();
- }
-};
-
-/**
- * Show/hide the toolbar.
- * @param {boolean} on True if show.
- */
-ImageEditor.Toolbar.prototype.show = function(on) {
- if (!this.wrapper_.firstChild)
- return; // Do not show empty toolbar;
-
- this.wrapper_.hidden = !on;
-};
-
-/** A prompt panel for the editor.
- *
- * @param {HTMLElement} container Container element.
- * @param {function} displayStringFunction A formatting function.
- * @constructor
- */
-ImageEditor.Prompt = function(container, displayStringFunction) {
- this.container_ = container;
- this.displayStringFunction_ = displayStringFunction;
-};
-
-/**
- * Reset the prompt.
- */
-ImageEditor.Prompt.prototype.reset = function() {
- this.cancelTimer();
- if (this.wrapper_) {
- this.container_.removeChild(this.wrapper_);
- this.wrapper_ = null;
- this.prompt_ = null;
- }
-};
-
-/**
- * Cancel the delayed action.
- */
-ImageEditor.Prompt.prototype.cancelTimer = function() {
- if (this.timer_) {
- clearTimeout(this.timer_);
- this.timer_ = null;
- }
-};
-
-/**
- * Schedule the delayed action.
- * @param {function} callback Callback.
- * @param {number} timeout Timeout.
- */
-ImageEditor.Prompt.prototype.setTimer = function(callback, timeout) {
- this.cancelTimer();
- var self = this;
- this.timer_ = setTimeout(function() {
- self.timer_ = null;
- callback();
- }, timeout);
-};
-
-/**
- * Show the prompt.
- *
- * @param {string} text The prompt text.
- * @param {number} timeout Timeout in ms.
- * @param {Object} formatArgs varArgs for the formatting fuction.
- */
-ImageEditor.Prompt.prototype.show = function(text, timeout, formatArgs) {
- this.showAt.apply(this,
- ['center'].concat(Array.prototype.slice.call(arguments)));
-};
-
-/**
- *
- * @param {string} pos The 'pos' attribute value.
- * @param {string} text The prompt text.
- * @param {number} timeout Timeout in ms.
- * @param {Object} formatArgs varArgs for the formatting function.
- */
-ImageEditor.Prompt.prototype.showAt = function(pos, text, timeout, formatArgs) {
- this.reset();
- if (!text) return;
-
- var document = this.container_.ownerDocument;
- this.wrapper_ = document.createElement('div');
- this.wrapper_.className = 'prompt-wrapper';
- this.wrapper_.setAttribute('pos', pos);
- this.container_.appendChild(this.wrapper_);
-
- this.prompt_ = document.createElement('div');
- this.prompt_.className = 'prompt';
-
- // Create an extra wrapper which opacity can be manipulated separately.
- var tool = document.createElement('div');
- tool.className = 'dimmable';
- this.wrapper_.appendChild(tool);
- tool.appendChild(this.prompt_);
-
- var args = [text].concat(Array.prototype.slice.call(arguments, 3));
- this.prompt_.textContent = this.displayStringFunction_.apply(null, args);
-
- var close = document.createElement('div');
- close.className = 'close';
- close.addEventListener('click', this.hide.bind(this));
- this.prompt_.appendChild(close);
-
- setTimeout(
- this.prompt_.setAttribute.bind(this.prompt_, 'state', 'fadein'), 0);
-
- if (timeout)
- this.setTimer(this.hide.bind(this), timeout);
-};
-
-/**
- * Hide the prompt.
- */
-ImageEditor.Prompt.prototype.hide = function() {
- if (!this.prompt_) return;
- this.prompt_.setAttribute('state', 'fadeout');
- // Allow some time for the animation to play out.
- this.setTimer(this.reset.bind(this), 500);
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_encoder.js b/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_encoder.js
deleted file mode 100644
index 1c96b1fe326..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_encoder.js
+++ /dev/null
@@ -1,228 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * A namespace class for image encoding functions. All methods are static.
- */
-function ImageEncoder() {}
-
-/**
- * @type {Array.<Object>}
- */
-ImageEncoder.metadataEncoders = {};
-
-/**
- * @param {function(new:ImageEncoder.MetadataEncoder)} constructor
- * // TODO(JSDOC).
- * @param {string} mimeType // TODO(JSDOC).
- */
-ImageEncoder.registerMetadataEncoder = function(constructor, mimeType) {
- ImageEncoder.metadataEncoders[mimeType] = constructor;
-};
-
-/**
- * Create a metadata encoder.
- *
- * The encoder will own and modify a copy of the original metadata.
- *
- * @param {Object} metadata Original metadata.
- * @return {ImageEncoder.MetadataEncoder} Created metadata encoder.
- */
-ImageEncoder.createMetadataEncoder = function(metadata) {
- var constructor = ImageEncoder.metadataEncoders[metadata.mimeType] ||
- ImageEncoder.MetadataEncoder;
- return new constructor(metadata);
-};
-
-
-/**
- * Create a metadata encoder object holding a copy of metadata
- * modified according to the properties of the supplied image.
- *
- * @param {Object} metadata Original metadata.
- * @param {HTMLCanvasElement} canvas Canvas to use for metadata.
- * @param {number} quality Encoding quality (defaults to 1).
- * @return {ImageEncoder.MetadataEncoder} Encoder with encoded metadata.
- */
-ImageEncoder.encodeMetadata = function(metadata, canvas, quality) {
- var encoder = ImageEncoder.createMetadataEncoder(metadata);
- encoder.setImageData(canvas);
- encoder.setThumbnailData(ImageEncoder.createThumbnail(canvas), quality || 1);
- return encoder;
-};
-
-
-/**
- * Return a blob with the encoded image with metadata inserted.
- * @param {HTMLCanvasElement} canvas The canvas with the image to be encoded.
- * @param {ImageEncoder.MetadataEncoder} metadataEncoder Encoder to use.
- * @param {number} quality (0..1], Encoding quality, defaults to 0.9.
- * @return {Blob} encoded data.
- */
-ImageEncoder.getBlob = function(canvas, metadataEncoder, quality) {
- // Contrary to what one might think 1.0 is not a good default. Opening and
- // saving an typical photo taken with consumer camera increases its file size
- // by 50-100%.
- // Experiments show that 0.9 is much better. It shrinks some photos a bit,
- // keeps others about the same size, but does not visibly lower the quality.
- quality = quality || 0.9;
-
- ImageUtil.trace.resetTimer('dataurl');
- // WebKit does not support canvas.toBlob yet so canvas.toDataURL is
- // the only way to use the Chrome built-in image encoder.
- var dataURL =
- canvas.toDataURL(metadataEncoder.getMetadata().mimeType, quality);
- ImageUtil.trace.reportTimer('dataurl');
-
- var encodedImage = ImageEncoder.decodeDataURL(dataURL);
-
- var encodedMetadata = metadataEncoder.encode();
-
- var slices = [];
-
- // TODO(kaznacheev): refactor |stringToArrayBuffer| and |encode| to return
- // arrays instead of array buffers.
- function appendSlice(arrayBuffer) {
- slices.push(new DataView(arrayBuffer));
- }
-
- ImageUtil.trace.resetTimer('blob');
- if (encodedMetadata.byteLength != 0) {
- var metadataRange = metadataEncoder.findInsertionRange(encodedImage);
- appendSlice(ImageEncoder.stringToArrayBuffer(
- encodedImage, 0, metadataRange.from));
-
- appendSlice(metadataEncoder.encode());
-
- appendSlice(ImageEncoder.stringToArrayBuffer(
- encodedImage, metadataRange.to, encodedImage.length));
- } else {
- appendSlice(ImageEncoder.stringToArrayBuffer(
- encodedImage, 0, encodedImage.length));
- }
- var blob = new Blob(slices, {type: metadataEncoder.getMetadata().mimeType});
- ImageUtil.trace.reportTimer('blob');
- return blob;
-};
-
-/**
- * Decode a dataURL into a binary string containing the encoded image.
- *
- * Why return a string? Calling atob and having the rest of the code deal
- * with a string is several times faster than decoding base64 in Javascript.
- *
- * @param {string} dataURL Data URL to decode.
- * @return {string} A binary string (char codes are the actual byte values).
- */
-ImageEncoder.decodeDataURL = function(dataURL) {
- // Skip the prefix ('data:image/<type>;base64,')
- var base64string = dataURL.substring(dataURL.indexOf(',') + 1);
- return atob(base64string);
-};
-
-/**
- * Return a thumbnail for an image.
- * @param {HTMLCanvasElement} canvas Original image.
- * @param {number=} opt_shrinkage Thumbnail should be at least this much smaller
- * than the original image (in each dimension).
- * @return {HTMLCanvasElement} Thumbnail canvas.
- */
-ImageEncoder.createThumbnail = function(canvas, opt_shrinkage) {
- var MAX_THUMBNAIL_DIMENSION = 320;
-
- opt_shrinkage = Math.max(opt_shrinkage || 4,
- canvas.width / MAX_THUMBNAIL_DIMENSION,
- canvas.height / MAX_THUMBNAIL_DIMENSION);
-
- var thumbnailCanvas = canvas.ownerDocument.createElement('canvas');
- thumbnailCanvas.width = Math.round(canvas.width / opt_shrinkage);
- thumbnailCanvas.height = Math.round(canvas.height / opt_shrinkage);
-
- var context = thumbnailCanvas.getContext('2d');
- context.drawImage(canvas,
- 0, 0, canvas.width, canvas.height,
- 0, 0, thumbnailCanvas.width, thumbnailCanvas.height);
-
- return thumbnailCanvas;
-};
-
-/**
- * TODO(JSDOC)
- * @param {string} string // TODO(JSDOC).
- * @param {number} from // TODO(JSDOC).
- * @param {number} to // TODO(JSDOC).
- * @return {ArrayBuffer} // TODO(JSDOC).
- */
-ImageEncoder.stringToArrayBuffer = function(string, from, to) {
- var size = to - from;
- var array = new Uint8Array(size);
- for (var i = 0; i != size; i++) {
- array[i] = string.charCodeAt(from + i);
- }
- return array.buffer;
-};
-
-/**
- * A base class for a metadata encoder.
- *
- * Serves as a default metadata encoder for images that none of the metadata
- * parsers recognized.
- *
- * @param {Object} original_metadata Starting metadata.
- * @constructor
- */
-ImageEncoder.MetadataEncoder = function(original_metadata) {
- this.metadata_ = MetadataCache.cloneMetadata(original_metadata) || {};
- if (this.metadata_.mimeType != 'image/jpeg') {
- // Chrome can only encode JPEG and PNG. Force PNG mime type so that we
- // can save to file and generate a thumbnail.
- this.metadata_.mimeType = 'image/png';
- }
-};
-
-/**
- * TODO(JSDOC)
- * @return {Object} // TODO(JSDOC).
- */
-ImageEncoder.MetadataEncoder.prototype.getMetadata = function() {
- return this.metadata_;
-};
-
-/**
- * @param {HTMLCanvasElement|Object} canvas Canvas or or anything with
- * width and height properties.
- */
-ImageEncoder.MetadataEncoder.prototype.setImageData = function(canvas) {
- this.metadata_.width = canvas.width;
- this.metadata_.height = canvas.height;
-};
-
-/**
- * @param {HTMLCanvasElement} canvas Canvas to use as thumbnail.
- * @param {number} quality Thumbnail quality.
- */
-ImageEncoder.MetadataEncoder.prototype.setThumbnailData =
- function(canvas, quality) {
- this.metadata_.thumbnailURL =
- canvas.toDataURL(this.metadata_.mimeType, quality);
-};
-
-/**
- * Return a range where the metadata is (or should be) located.
- * @param {string} encodedImage // TODO(JSDOC).
- * @return {Object} An object with from and to properties.
- */
-ImageEncoder.MetadataEncoder.prototype.
- findInsertionRange = function(encodedImage) { return {from: 0, to: 0} };
-
-/**
- * Return serialized metadata ready to write to an image file.
- * The return type is optimized for passing to Blob.append.
- * @return {ArrayBuffer} // TODO(JSDOC).
- */
-ImageEncoder.MetadataEncoder.prototype.encode = function() {
- return new Uint8Array(0).buffer;
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_transform.js b/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_transform.js
deleted file mode 100644
index 6b194baf0fc..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_transform.js
+++ /dev/null
@@ -1,493 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Crop mode.
- * @constructor
- */
-ImageEditor.Mode.Crop = function() {
- ImageEditor.Mode.call(this, 'crop', 'GALLERY_CROP');
-};
-
-ImageEditor.Mode.Crop.prototype = {__proto__: ImageEditor.Mode.prototype};
-
-/**
- * TODO(JSDOC).
- */
-ImageEditor.Mode.Crop.prototype.setUp = function() {
- ImageEditor.Mode.prototype.setUp.apply(this, arguments);
-
- var container = this.getImageView().container_;
- var doc = container.ownerDocument;
-
- this.domOverlay_ = doc.createElement('div');
- this.domOverlay_.className = 'crop-overlay';
- container.appendChild(this.domOverlay_);
-
- this.shadowTop_ = doc.createElement('div');
- this.shadowTop_.className = 'shadow';
- this.domOverlay_.appendChild(this.shadowTop_);
-
- this.middleBox_ = doc.createElement('div');
- this.middleBox_.className = 'middle-box';
- this.domOverlay_.appendChild(this.middleBox_);
-
- this.shadowLeft_ = doc.createElement('div');
- this.shadowLeft_.className = 'shadow';
- this.middleBox_.appendChild(this.shadowLeft_);
-
- this.cropFrame_ = doc.createElement('div');
- this.cropFrame_.className = 'crop-frame';
- this.middleBox_.appendChild(this.cropFrame_);
-
- this.shadowRight_ = doc.createElement('div');
- this.shadowRight_.className = 'shadow';
- this.middleBox_.appendChild(this.shadowRight_);
-
- this.shadowBottom_ = doc.createElement('div');
- this.shadowBottom_.className = 'shadow';
- this.domOverlay_.appendChild(this.shadowBottom_);
-
- var cropFrame = this.cropFrame_;
- function addCropFrame(className) {
- var div = doc.createElement('div');
- div.className = className;
- cropFrame.appendChild(div);
- }
-
- addCropFrame('left top corner');
- addCropFrame('top horizontal');
- addCropFrame('right top corner');
- addCropFrame('left vertical');
- addCropFrame('right vertical');
- addCropFrame('left bottom corner');
- addCropFrame('bottom horizontal');
- addCropFrame('right bottom corner');
-
- this.onResizedBound_ = this.onResized_.bind(this);
- window.addEventListener('resize', this.onResizedBound_);
-
- this.createDefaultCrop();
-};
-
-/**
- * Handles resizing of the window and updates the crop rectangle.
- * @private
- */
-ImageEditor.Mode.Crop.prototype.onResized_ = function() {
- this.positionDOM();
-};
-
-/**
- * TODO(JSDOC).
- */
-ImageEditor.Mode.Crop.prototype.reset = function() {
- ImageEditor.Mode.prototype.reset.call(this);
- this.createDefaultCrop();
-};
-
-/**
- * TODO(JSDOC).
- */
-ImageEditor.Mode.Crop.prototype.positionDOM = function() {
- var screenClipped = this.viewport_.getScreenClipped();
-
- var screenCrop = this.viewport_.imageToScreenRect(this.cropRect_.getRect());
- var delta = ImageEditor.Mode.Crop.MOUSE_GRAB_RADIUS;
- this.editor_.hideOverlappingTools(
- screenCrop.inflate(delta, delta),
- screenCrop.inflate(-delta, -delta));
-
- this.domOverlay_.style.left = screenClipped.left + 'px';
- this.domOverlay_.style.top = screenClipped.top + 'px';
- this.domOverlay_.style.width = screenClipped.width + 'px';
- this.domOverlay_.style.height = screenClipped.height + 'px';
-
- this.shadowLeft_.style.width = screenCrop.left - screenClipped.left + 'px';
-
- this.shadowTop_.style.height = screenCrop.top - screenClipped.top + 'px';
-
- this.shadowRight_.style.width = screenClipped.left + screenClipped.width -
- (screenCrop.left + screenCrop.width) + 'px';
-
- this.shadowBottom_.style.height = screenClipped.top + screenClipped.height -
- (screenCrop.top + screenCrop.height) + 'px';
-};
-
-/**
- * TODO(JSDOC).
- */
-ImageEditor.Mode.Crop.prototype.cleanUpUI = function() {
- ImageEditor.Mode.prototype.cleanUpUI.apply(this, arguments);
- this.domOverlay_.parentNode.removeChild(this.domOverlay_);
- this.domOverlay_ = null;
- this.editor_.hideOverlappingTools();
- window.removeEventListener(this.onResizedBound_);
- this.onResizedBound_ = null;
-};
-
-/**
- * @const
- * @type {number}
- */
-ImageEditor.Mode.Crop.MOUSE_GRAB_RADIUS = 6;
-/**
- * @const
- * @type {number}
- */
-ImageEditor.Mode.Crop.TOUCH_GRAB_RADIUS = 20;
-
-/**
- * TODO(JSDOC).
- * @return {Command.Crop} // TODO(JSDOC).
- */
-ImageEditor.Mode.Crop.prototype.getCommand = function() {
- var cropImageRect = this.cropRect_.getRect();
- return new Command.Crop(cropImageRect);
-};
-
-/**
- * TODO(JSDOC).
- */
-ImageEditor.Mode.Crop.prototype.createDefaultCrop = function() {
- var rect = new Rect(this.getViewport().getImageClipped());
- rect = rect.inflate(
- -Math.round(rect.width / 6), -Math.round(rect.height / 6));
- this.cropRect_ = new DraggableRect(rect, this.getViewport());
- this.positionDOM();
-};
-
-/**
- * TODO(JSDOC).
- * @param {number} x X coordinate for cursor.
- * @param {number} y Y coordinate for cursor.
- * @param {boolean} mouseDown If mouse button is down.
- * @return {string} A value for style.cursor CSS property.
- */
-ImageEditor.Mode.Crop.prototype.getCursorStyle = function(x, y, mouseDown) {
- return this.cropRect_.getCursorStyle(x, y, mouseDown);
-};
-
-/**
- * TODO(JSDOC).
- * @param {number} x Event X coordinate.
- * @param {number} y Event Y coordinate.
- * @param {boolean} touch True if it's a touch event, false if mouse.
- * @return {function(number,number)} A function to be called on mouse drag.
- */
-ImageEditor.Mode.Crop.prototype.getDragHandler = function(x, y, touch) {
- var cropDragHandler = this.cropRect_.getDragHandler(x, y, touch);
- if (!cropDragHandler) return null;
-
- var self = this;
- return function(x, y) {
- cropDragHandler(x, y);
- self.markUpdated();
- self.positionDOM();
- };
-};
-
-/**
- * TODO(JSDOC).
- * @param {number} x X coordinate of the event.
- * @param {number} y Y coordinate of the event.
- * @return {ImageBuffer.DoubleTapAction} Action to perform as result.
- */
-ImageEditor.Mode.Crop.prototype.getDoubleTapAction = function(x, y) {
- return this.cropRect_.getDoubleTapAction(x, y);
-};
-
-/*
- * A draggable rectangle over the image.
- * @param {Rect} rect // TODO(JSDOC).
- * @param {Viewport} viewport // TODO(JSDOC).
- * @constructor
- */
-function DraggableRect(rect, viewport) {
- // The bounds are not held in a regular rectangle (with width/height).
- // left/top/right/bottom held instead for convenience.
- this.bounds_ = {};
- this.bounds_[DraggableRect.LEFT] = rect.left;
- this.bounds_[DraggableRect.RIGHT] = rect.left + rect.width;
- this.bounds_[DraggableRect.TOP] = rect.top;
- this.bounds_[DraggableRect.BOTTOM] = rect.top + rect.height;
-
- this.viewport_ = viewport;
-
- this.oppositeSide_ = {};
- this.oppositeSide_[DraggableRect.LEFT] = DraggableRect.RIGHT;
- this.oppositeSide_[DraggableRect.RIGHT] = DraggableRect.LEFT;
- this.oppositeSide_[DraggableRect.TOP] = DraggableRect.BOTTOM;
- this.oppositeSide_[DraggableRect.BOTTOM] = DraggableRect.TOP;
-
- // Translation table to form CSS-compatible cursor style.
- this.cssSide_ = {};
- this.cssSide_[DraggableRect.LEFT] = 'w';
- this.cssSide_[DraggableRect.TOP] = 'n';
- this.cssSide_[DraggableRect.RIGHT] = 'e';
- this.cssSide_[DraggableRect.BOTTOM] = 's';
- this.cssSide_[DraggableRect.NONE] = '';
-}
-
-// Static members to simplify reflective access to the bounds.
-/**
- * @const
- * @type {string}
- */
-DraggableRect.LEFT = 'left';
-/**
- * @const
- * @type {string}
- */
-DraggableRect.RIGHT = 'right';
-/**
- * @const
- * @type {string}
- */
-DraggableRect.TOP = 'top';
-/**
- * @const
- * @type {string}
- */
-DraggableRect.BOTTOM = 'bottom';
-/**
- * @const
- * @type {string}
- */
-DraggableRect.NONE = 'none';
-
-/**
- * TODO(JSDOC)
- * @return {number} // TODO(JSDOC).
- */
-DraggableRect.prototype.getLeft = function() {
- return this.bounds_[DraggableRect.LEFT];
-};
-
-/**
- * TODO(JSDOC)
- * @return {number} // TODO(JSDOC).
- */
-DraggableRect.prototype.getRight = function() {
- return this.bounds_[DraggableRect.RIGHT];
-};
-
-/**
- * TODO(JSDOC)
- * @return {number} // TODO(JSDOC).
- */
-DraggableRect.prototype.getTop = function() {
- return this.bounds_[DraggableRect.TOP];
-};
-
-/**
- * TODO(JSDOC)
- * @return {number} // TODO(JSDOC).
- */
-DraggableRect.prototype.getBottom = function() {
- return this.bounds_[DraggableRect.BOTTOM];
-};
-
-/**
- * TODO(JSDOC)
- * @return {Rect} // TODO(JSDOC).
- */
-DraggableRect.prototype.getRect = function() {
- return new Rect(this.bounds_);
-};
-
-/**
- * TODO(JSDOC)
- * @param {number} x X coordinate for cursor.
- * @param {number} y Y coordinate for cursor.
- * @param {boolean} touch // TODO(JSDOC).
- * @return {Object} // TODO(JSDOC).
- */
-DraggableRect.prototype.getDragMode = function(x, y, touch) {
- var result = {
- xSide: DraggableRect.NONE,
- ySide: DraggableRect.NONE
- };
-
- var bounds = this.bounds_;
- var R = this.viewport_.screenToImageSize(
- touch ? ImageEditor.Mode.Crop.TOUCH_GRAB_RADIUS :
- ImageEditor.Mode.Crop.MOUSE_GRAB_RADIUS);
-
- var circle = new Circle(x, y, R);
-
- var xBetween = ImageUtil.between(bounds.left, x, bounds.right);
- var yBetween = ImageUtil.between(bounds.top, y, bounds.bottom);
-
- if (circle.inside(bounds.left, bounds.top)) {
- result.xSide = DraggableRect.LEFT;
- result.ySide = DraggableRect.TOP;
- } else if (circle.inside(bounds.left, bounds.bottom)) {
- result.xSide = DraggableRect.LEFT;
- result.ySide = DraggableRect.BOTTOM;
- } else if (circle.inside(bounds.right, bounds.top)) {
- result.xSide = DraggableRect.RIGHT;
- result.ySide = DraggableRect.TOP;
- } else if (circle.inside(bounds.right, bounds.bottom)) {
- result.xSide = DraggableRect.RIGHT;
- result.ySide = DraggableRect.BOTTOM;
- } else if (yBetween && Math.abs(x - bounds.left) <= R) {
- result.xSide = DraggableRect.LEFT;
- } else if (yBetween && Math.abs(x - bounds.right) <= R) {
- result.xSide = DraggableRect.RIGHT;
- } else if (xBetween && Math.abs(y - bounds.top) <= R) {
- result.ySide = DraggableRect.TOP;
- } else if (xBetween && Math.abs(y - bounds.bottom) <= R) {
- result.ySide = DraggableRect.BOTTOM;
- } else if (xBetween && yBetween) {
- result.whole = true;
- } else {
- result.newcrop = true;
- result.xSide = DraggableRect.RIGHT;
- result.ySide = DraggableRect.BOTTOM;
- }
-
- return result;
-};
-
-/**
- * TODO(JSDOC)
- * @param {number} x X coordinate for cursor.
- * @param {number} y Y coordinate for cursor.
- * @param {boolean} mouseDown If mouse button is down.
- * @return {string} // TODO(JSDOC).
- */
-DraggableRect.prototype.getCursorStyle = function(x, y, mouseDown) {
- var mode;
- if (mouseDown) {
- mode = this.dragMode_;
- } else {
- mode = this.getDragMode(
- this.viewport_.screenToImageX(x), this.viewport_.screenToImageY(y));
- }
- if (mode.whole) return 'move';
- if (mode.newcrop) return 'crop';
- return this.cssSide_[mode.ySide] + this.cssSide_[mode.xSide] + '-resize';
-};
-
-/**
- * TODO(JSDOC)
- * @param {number} x X coordinate for cursor.
- * @param {number} y Y coordinate for cursor.
- * @param {boolean} touch // TODO(JSDOC).
- * @return {function(number,number)} // TODO(JSDOC).
- */
-DraggableRect.prototype.getDragHandler = function(x, y, touch) {
- x = this.viewport_.screenToImageX(x);
- y = this.viewport_.screenToImageY(y);
-
- var clipRect = this.viewport_.getImageClipped();
- if (!clipRect.inside(x, y)) return null;
-
- this.dragMode_ = this.getDragMode(x, y, touch);
-
- var self = this;
-
- var mouseBiasX;
- var mouseBiasY;
-
- var fixedWidth = 0;
- var fixedHeight = 0;
-
- var resizeFuncX;
- var resizeFuncY;
-
- if (this.dragMode_.whole) {
- mouseBiasX = this.bounds_.left - x;
- fixedWidth = this.bounds_.right - this.bounds_.left;
- resizeFuncX = function(x) {
- self.bounds_.left = x;
- self.bounds_.right = self.bounds_.left + fixedWidth;
- };
- mouseBiasY = this.bounds_.top - y;
- fixedHeight = this.bounds_.bottom - this.bounds_.top;
- resizeFuncY = function(y) {
- self.bounds_.top = y;
- self.bounds_.bottom = self.bounds_.top + fixedHeight;
- };
- } else {
- var checkNewCrop = function() {
- if (self.dragMode_.newcrop) {
- self.dragMode_.newcrop = false;
- self.bounds_.left = self.bounds_.right = x;
- self.bounds_.top = self.bounds_.bottom = y;
- mouseBiasX = 0;
- mouseBiasY = 0;
- }
- };
-
- var flipSide = function(side) {
- var opposite = self.oppositeSide_[side];
- var temp = self.bounds_[side];
- self.bounds_[side] = self.bounds_[opposite];
- self.bounds_[opposite] = temp;
- return opposite;
- };
-
- if (this.dragMode_.xSide != DraggableRect.NONE) {
- mouseBiasX = self.bounds_[this.dragMode_.xSide] - x;
- resizeFuncX = function(x) {
- checkNewCrop();
- self.bounds_[self.dragMode_.xSide] = x;
- if (self.bounds_.left > self.bounds_.right) {
- self.dragMode_.xSide = flipSide(self.dragMode_.xSide);
- }
- };
- }
- if (this.dragMode_.ySide != DraggableRect.NONE) {
- mouseBiasY = self.bounds_[this.dragMode_.ySide] - y;
- resizeFuncY = function(y) {
- checkNewCrop();
- self.bounds_[self.dragMode_.ySide] = y;
- if (self.bounds_.top > self.bounds_.bottom) {
- self.dragMode_.ySide = flipSide(self.dragMode_.ySide);
- }
- };
- }
- }
-
- function convertX(x) {
- return ImageUtil.clamp(
- clipRect.left,
- self.viewport_.screenToImageX(x) + mouseBiasX,
- clipRect.left + clipRect.width - fixedWidth);
- }
-
- function convertY(y) {
- return ImageUtil.clamp(
- clipRect.top,
- self.viewport_.screenToImageY(y) + mouseBiasY,
- clipRect.top + clipRect.height - fixedHeight);
- }
-
- return function(x, y) {
- if (resizeFuncX) resizeFuncX(convertX(x));
- if (resizeFuncY) resizeFuncY(convertY(y));
- };
-};
-
-/**
- * TODO(JSDOC)
- * @param {number} x X coordinate for cursor.
- * @param {number} y Y coordinate for cursor.
- * @param {boolean} touch // TODO(JSDOC).
- * @return {ImageBuffer.DoubleTapAction} // TODO(JSDOC).
- */
-DraggableRect.prototype.getDoubleTapAction = function(x, y, touch) {
- x = this.viewport_.screenToImageX(x);
- y = this.viewport_.screenToImageY(y);
-
- var clipRect = this.viewport_.getImageClipped();
- if (clipRect.inside(x, y))
- return ImageBuffer.DoubleTapAction.COMMIT;
- else
- return ImageBuffer.DoubleTapAction.NOTHING;
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_util.js b/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_util.js
deleted file mode 100644
index f088f7c6c83..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_util.js
+++ /dev/null
@@ -1,701 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-
-// Namespace object for the utilities.
-function ImageUtil() {}
-
-/**
- * Performance trace.
- */
-ImageUtil.trace = (function() {
- function PerformanceTrace() {
- this.lines_ = {};
- this.timers_ = {};
- this.container_ = null;
- }
-
- PerformanceTrace.prototype.bindToDOM = function(container) {
- this.container_ = container;
- };
-
- PerformanceTrace.prototype.report = function(key, value) {
- if (!(key in this.lines_)) {
- if (this.container_) {
- var div = this.lines_[key] = document.createElement('div');
- this.container_.appendChild(div);
- } else {
- this.lines_[key] = {};
- }
- }
- this.lines_[key].textContent = key + ': ' + value;
- if (ImageUtil.trace.log) this.dumpLine(key);
- };
-
- PerformanceTrace.prototype.resetTimer = function(key) {
- this.timers_[key] = Date.now();
- };
-
- PerformanceTrace.prototype.reportTimer = function(key) {
- this.report(key, (Date.now() - this.timers_[key]) + 'ms');
- };
-
- PerformanceTrace.prototype.dump = function() {
- for (var key in this.lines_)
- this.dumpLine(key);
- };
-
- PerformanceTrace.prototype.dumpLine = function(key) {
- console.log('trace.' + this.lines_[key].textContent);
- };
-
- return new PerformanceTrace();
-})();
-
-/**
- * @param {number} min Minimum value.
- * @param {number} value Value to adjust.
- * @param {number} max Maximum value.
- * @return {number} The closest to the |value| number in span [min, max].
- */
-ImageUtil.clamp = function(min, value, max) {
- return Math.max(min, Math.min(max, value));
-};
-
-/**
- * @param {number} min Minimum value.
- * @param {number} value Value to check.
- * @param {number} max Maximum value.
- * @return {boolean} True if value is between.
- */
-ImageUtil.between = function(min, value, max) {
- return (value - min) * (value - max) <= 0;
-};
-
-/**
- * Rectangle class.
- */
-
-/**
- * Rectangle constructor takes 0, 1, 2 or 4 arguments.
- * Supports following variants:
- * new Rect(left, top, width, height)
- * new Rect(width, height)
- * new Rect(rect) // anything with left, top, width, height properties
- * new Rect(bounds) // anything with left, top, right, bottom properties
- * new Rect(canvas|image) // anything with width and height properties.
- * new Rect() // empty rectangle.
- * @constructor
- */
-function Rect() {
- switch (arguments.length) {
- case 4:
- this.left = arguments[0];
- this.top = arguments[1];
- this.width = arguments[2];
- this.height = arguments[3];
- return;
-
- case 2:
- this.left = 0;
- this.top = 0;
- this.width = arguments[0];
- this.height = arguments[1];
- return;
-
- case 1: {
- var source = arguments[0];
- if ('left' in source && 'top' in source) {
- this.left = source.left;
- this.top = source.top;
- if ('right' in source && 'bottom' in source) {
- this.width = source.right - source.left;
- this.height = source.bottom - source.top;
- return;
- }
- } else {
- this.left = 0;
- this.top = 0;
- }
- if ('width' in source && 'height' in source) {
- this.width = source.width;
- this.height = source.height;
- return;
- }
- break; // Fall through to the error message.
- }
-
- case 0:
- this.left = 0;
- this.top = 0;
- this.width = 0;
- this.height = 0;
- return;
- }
- console.error('Invalid Rect constructor arguments:',
- Array.apply(null, arguments));
-}
-
-/**
- * @param {number} factor Factor to scale.
- * @return {Rect} A rectangle with every dimension scaled.
- */
-Rect.prototype.scale = function(factor) {
- return new Rect(
- this.left * factor,
- this.top * factor,
- this.width * factor,
- this.height * factor);
-};
-
-/**
- * @param {number} dx Difference in X.
- * @param {number} dy Difference in Y.
- * @return {Rect} A rectangle shifted by (dx,dy), same size.
- */
-Rect.prototype.shift = function(dx, dy) {
- return new Rect(this.left + dx, this.top + dy, this.width, this.height);
-};
-
-/**
- * @param {number} x Coordinate of the left top corner.
- * @param {number} y Coordinate of the left top corner.
- * @return {Rect} A rectangle with left==x and top==y, same size.
- */
-Rect.prototype.moveTo = function(x, y) {
- return new Rect(x, y, this.width, this.height);
-};
-
-/**
- * @param {number} dx Difference in X.
- * @param {number} dy Difference in Y.
- * @return {Rect} A rectangle inflated by (dx, dy), same center.
- */
-Rect.prototype.inflate = function(dx, dy) {
- return new Rect(
- this.left - dx, this.top - dy, this.width + 2 * dx, this.height + 2 * dy);
-};
-
-/**
- * @param {number} x Coordinate of the point.
- * @param {number} y Coordinate of the point.
- * @return {boolean} True if the point lies inside the rectangle.
- */
-Rect.prototype.inside = function(x, y) {
- return this.left <= x && x < this.left + this.width &&
- this.top <= y && y < this.top + this.height;
-};
-
-/**
- * @param {Rect} rect Rectangle to check.
- * @return {boolean} True if this rectangle intersects with the |rect|.
- */
-Rect.prototype.intersects = function(rect) {
- return (this.left + this.width) > rect.left &&
- (rect.left + rect.width) > this.left &&
- (this.top + this.height) > rect.top &&
- (rect.top + rect.height) > this.top;
-};
-
-/**
- * @param {Rect} rect Rectangle to check.
- * @return {boolean} True if this rectangle containing the |rect|.
- */
-Rect.prototype.contains = function(rect) {
- return (this.left <= rect.left) &&
- (rect.left + rect.width) <= (this.left + this.width) &&
- (this.top <= rect.top) &&
- (rect.top + rect.height) <= (this.top + this.height);
-};
-
-/**
- * @return {boolean} True if rectangle is empty.
- */
-Rect.prototype.isEmpty = function() {
- return this.width === 0 || this.height === 0;
-};
-
-/**
- * Clamp the rectangle to the bounds by moving it.
- * Decrease the size only if necessary.
- * @param {Rect} bounds Bounds.
- * @return {Rect} Calculated rectangle.
- */
-Rect.prototype.clamp = function(bounds) {
- var rect = new Rect(this);
-
- if (rect.width > bounds.width) {
- rect.left = bounds.left;
- rect.width = bounds.width;
- } else if (rect.left < bounds.left) {
- rect.left = bounds.left;
- } else if (rect.left + rect.width >
- bounds.left + bounds.width) {
- rect.left = bounds.left + bounds.width - rect.width;
- }
-
- if (rect.height > bounds.height) {
- rect.top = bounds.top;
- rect.height = bounds.height;
- } else if (rect.top < bounds.top) {
- rect.top = bounds.top;
- } else if (rect.top + rect.height >
- bounds.top + bounds.height) {
- rect.top = bounds.top + bounds.height - rect.height;
- }
-
- return rect;
-};
-
-/**
- * @return {string} String representation.
- */
-Rect.prototype.toString = function() {
- return '(' + this.left + ',' + this.top + '):' +
- '(' + (this.left + this.width) + ',' + (this.top + this.height) + ')';
-};
-/*
- * Useful shortcuts for drawing (static functions).
- */
-
-/**
- * Draw the image in context with appropriate scaling.
- * @param {CanvasRenderingContext2D} context Context to draw.
- * @param {Image} image Image to draw.
- * @param {Rect=} opt_dstRect Rectangle in the canvas (whole canvas by default).
- * @param {Rect=} opt_srcRect Rectangle in the image (whole image by default).
- */
-Rect.drawImage = function(context, image, opt_dstRect, opt_srcRect) {
- opt_dstRect = opt_dstRect || new Rect(context.canvas);
- opt_srcRect = opt_srcRect || new Rect(image);
- if (opt_dstRect.isEmpty() || opt_srcRect.isEmpty())
- return;
- context.drawImage(image,
- opt_srcRect.left, opt_srcRect.top, opt_srcRect.width, opt_srcRect.height,
- opt_dstRect.left, opt_dstRect.top, opt_dstRect.width, opt_dstRect.height);
-};
-
-/**
- * Draw a box around the rectangle.
- * @param {CanvasRenderingContext2D} context Context to draw.
- * @param {Rect} rect Rectangle.
- */
-Rect.outline = function(context, rect) {
- context.strokeRect(
- rect.left - 0.5, rect.top - 0.5, rect.width + 1, rect.height + 1);
-};
-
-/**
- * Fill the rectangle.
- * @param {CanvasRenderingContext2D} context Context to draw.
- * @param {Rect} rect Rectangle.
- */
-Rect.fill = function(context, rect) {
- context.fillRect(rect.left, rect.top, rect.width, rect.height);
-};
-
-/**
- * Fills the space between the two rectangles.
- * @param {CanvasRenderingContext2D} context Context to draw.
- * @param {Rect} inner Inner rectangle.
- * @param {Rect} outer Outer rectangle.
- */
-Rect.fillBetween = function(context, inner, outer) {
- var innerRight = inner.left + inner.width;
- var innerBottom = inner.top + inner.height;
- var outerRight = outer.left + outer.width;
- var outerBottom = outer.top + outer.height;
- if (inner.top > outer.top) {
- context.fillRect(
- outer.left, outer.top, outer.width, inner.top - outer.top);
- }
- if (inner.left > outer.left) {
- context.fillRect(
- outer.left, inner.top, inner.left - outer.left, inner.height);
- }
- if (inner.width < outerRight) {
- context.fillRect(
- innerRight, inner.top, outerRight - innerRight, inner.height);
- }
- if (inner.height < outerBottom) {
- context.fillRect(
- outer.left, innerBottom, outer.width, outerBottom - innerBottom);
- }
-};
-
-/**
- * Circle class.
- * @param {number} x X coordinate of circle center.
- * @param {number} y Y coordinate of circle center.
- * @param {number} r Radius.
- * @constructor
- */
-function Circle(x, y, r) {
- this.x = x;
- this.y = y;
- this.squaredR = r * r;
-}
-
-/**
- * Check if the point is inside the circle.
- * @param {number} x X coordinate of the point.
- * @param {number} y Y coordinate of the point.
- * @return {boolean} True if the point is inside.
- */
-Circle.prototype.inside = function(x, y) {
- x -= this.x;
- y -= this.y;
- return x * x + y * y <= this.squaredR;
-};
-
-/**
- * Copy an image applying scaling and rotation.
- *
- * @param {HTMLCanvasElement} dst Destination.
- * @param {HTMLCanvasElement|HTMLImageElement} src Source.
- * @param {number} scaleX Y scale transformation.
- * @param {number} scaleY X scale transformation.
- * @param {number} angle (in radians).
- */
-ImageUtil.drawImageTransformed = function(dst, src, scaleX, scaleY, angle) {
- var context = dst.getContext('2d');
- context.save();
- context.translate(context.canvas.width / 2, context.canvas.height / 2);
- context.rotate(angle);
- context.scale(scaleX, scaleY);
- context.drawImage(src, -src.width / 2, -src.height / 2);
- context.restore();
-};
-
-/**
- * Adds or removes an attribute to/from an HTML element.
- * @param {HTMLElement} element To be applied to.
- * @param {string} attribute Name of attribute.
- * @param {boolean} on True if add, false if remove.
- */
-ImageUtil.setAttribute = function(element, attribute, on) {
- if (on)
- element.setAttribute(attribute, '');
- else
- element.removeAttribute(attribute);
-};
-
-/**
- * Adds or removes CSS class to/from an HTML element.
- * @param {HTMLElement} element To be applied to.
- * @param {string} className Name of CSS class.
- * @param {boolean} on True if add, false if remove.
- */
-ImageUtil.setClass = function(element, className, on) {
- var cl = element.classList;
- if (on)
- cl.add(className);
- else
- cl.remove(className);
-};
-
-/**
- * ImageLoader loads an image from a given Entry into a canvas in two steps:
- * 1. Loads the image into an HTMLImageElement.
- * 2. Copies pixels from HTMLImageElement to HTMLCanvasElement. This is done
- * stripe-by-stripe to avoid freezing up the UI. The transform is taken into
- * account.
- *
- * @param {HTMLDocument} document Owner document.
- * @param {MetadataCache=} opt_metadataCache Metadata cache. Required for
- * caching. If not passed, caching will be disabled.
- * @constructor
- */
-ImageUtil.ImageLoader = function(document, opt_metadataCache) {
- this.document_ = document;
- this.metadataCache_ = opt_metadataCache || null;
- this.image_ = new Image();
- this.generation_ = 0;
-};
-
-/**
- * Max size of image to be displayed (in pixels)
- */
-ImageUtil.ImageLoader.IMAGE_SIZE_LIMIT = 25 * 1000 * 1000;
-
-/**
- * @param {number} width Width of the image.
- * @param {number} height Height of the image.
- * @return {boolean} True if the image is too large to be loaded.
- */
-ImageUtil.ImageLoader.isTooLarge = function(width, height) {
- return width * height > ImageUtil.ImageLoader.IMAGE_SIZE_LIMIT;
-};
-
-/**
- * Loads an image.
- * TODO(mtomasz): Simplify, or even get rid of this class and merge with the
- * ThumbnaiLoader class.
- *
- * @param {FileEntry} entry Image entry to be loaded.
- * @param {function(function(object))} transformFetcher function to get
- * the image transform (which we need for the image orientation).
- * @param {function(HTMLCanvasElement, string=)} callback Callback to be
- * called when loaded. The second optional argument is an error identifier.
- * @param {number=} opt_delay Load delay in milliseconds, useful to let the
- * animations play out before the computation heavy image loading starts.
- */
-ImageUtil.ImageLoader.prototype.load = function(
- entry, transformFetcher, callback, opt_delay) {
- this.cancel();
-
- this.entry_ = entry;
- this.callback_ = callback;
-
- // The transform fetcher is not cancellable so we need a generation counter.
- var generation = ++this.generation_;
- var onTransform = function(image, transform) {
- if (generation === this.generation_) {
- this.convertImage_(
- image, transform || { scaleX: 1, scaleY: 1, rotate90: 0});
- }
- };
-
- var onError = function(opt_error) {
- this.image_.onerror = null;
- this.image_.onload = null;
- var tmpCallback = this.callback_;
- this.callback_ = null;
- var emptyCanvas = this.document_.createElement('canvas');
- emptyCanvas.width = 0;
- emptyCanvas.height = 0;
- tmpCallback(emptyCanvas, opt_error);
- }.bind(this);
-
- var loadImage = function(opt_metadata) {
- ImageUtil.metrics.startInterval(ImageUtil.getMetricName('LoadTime'));
- this.timeout_ = null;
-
- this.image_.onload = function(e) {
- this.image_.onerror = null;
- this.image_.onload = null;
- if (ImageUtil.ImageLoader.isTooLarge(this.image_.width,
- this.image_.height)) {
- onError('GALLERY_IMAGE_TOO_BIG_ERROR');
- return;
- }
- transformFetcher(entry, onTransform.bind(this, e.target));
- }.bind(this);
-
- // The error callback has an optional error argument, which in case of a
- // general error should not be specified
- this.image_.onerror = onError.bind(this, 'GALLERY_IMAGE_ERROR');
-
- // Extract the last modification date to determine if the cached image
- // is outdated.
- var modificationTime = opt_metadata &&
- opt_metadata.modificationTime &&
- opt_metadata.modificationTime.getTime();
-
- // Load the image directly.
- this.image_.src = entry.toURL();
- }.bind(this);
-
- // Loads the image. If already loaded, then forces a reload.
- var startLoad = this.resetImage_.bind(this, function() {
- // Fetch metadata to detect last modification time for the caching purpose.
- if (this.metadataCache_)
- this.metadataCache_.get(entry, 'filesystem', loadImage);
- else
- loadImage();
- }.bind(this), onError);
-
- if (opt_delay) {
- this.timeout_ = setTimeout(startLoad, opt_delay);
- } else {
- startLoad();
- }
-};
-
-/**
- * Resets the image by forcing the garbage collection and clearing the src
- * attribute.
- *
- * @param {function()} onSuccess Success callback.
- * @param {function(opt_string)} onError Failure callback with an optional
- * error identifier.
- * @private
- */
-ImageUtil.ImageLoader.prototype.resetImage_ = function(onSuccess, onError) {
- var clearSrc = function() {
- this.image_.onload = onSuccess;
- this.image_.onerror = onSuccess;
- this.image_.src = '';
- }.bind(this);
-
- var emptyImage = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAA' +
- 'AAABAAEAAAICTAEAOw==';
-
- if (this.image_.src !== emptyImage) {
- // Load an empty image, then clear src.
- this.image_.onload = clearSrc;
- this.image_.onerror = onError.bind(this, 'GALLERY_IMAGE_ERROR');
- this.image_.src = emptyImage;
- } else {
- // Empty image already loaded, so clear src immediately.
- clearSrc();
- }
-};
-
-/**
- * @return {boolean} True if an image is loading.
- */
-ImageUtil.ImageLoader.prototype.isBusy = function() {
- return !!this.callback_;
-};
-
-/**
- * @param {Entry} entry Image entry.
- * @return {boolean} True if loader loads this image.
- */
-ImageUtil.ImageLoader.prototype.isLoading = function(entry) {
- return this.isBusy() && util.isSameEntry(this.entry_, entry);
-};
-
-/**
- * @param {function} callback To be called when the image loaded.
- */
-ImageUtil.ImageLoader.prototype.setCallback = function(callback) {
- this.callback_ = callback;
-};
-
-/**
- * Stops loading image.
- */
-ImageUtil.ImageLoader.prototype.cancel = function() {
- if (!this.callback_) return;
- this.callback_ = null;
- if (this.timeout_) {
- clearTimeout(this.timeout_);
- this.timeout_ = null;
- }
- if (this.image_) {
- this.image_.onload = function() {};
- this.image_.onerror = function() {};
- this.image_.src = '';
- }
- this.generation_++; // Silence the transform fetcher if it is in progress.
-};
-
-/**
- * @param {HTMLImageElement} image Image to be transformed.
- * @param {Object} transform transformation description to apply to the image.
- * @private
- */
-ImageUtil.ImageLoader.prototype.convertImage_ = function(image, transform) {
- var canvas = this.document_.createElement('canvas');
-
- if (transform.rotate90 & 1) { // Rotated +/-90deg, swap the dimensions.
- canvas.width = image.height;
- canvas.height = image.width;
- } else {
- canvas.width = image.width;
- canvas.height = image.height;
- }
-
- var context = canvas.getContext('2d');
- context.save();
- context.translate(canvas.width / 2, canvas.height / 2);
- context.rotate(transform.rotate90 * Math.PI / 2);
- context.scale(transform.scaleX, transform.scaleY);
-
- var stripCount = Math.ceil(image.width * image.height / (1 << 21));
- var step = Math.max(16, Math.ceil(image.height / stripCount)) & 0xFFFFF0;
-
- this.copyStrip_(context, image, 0, step);
-};
-
-/**
- * @param {CanvasRenderingContext2D} context Context to draw.
- * @param {HTMLImageElement} image Image to draw.
- * @param {number} firstRow Number of the first pixel row to draw.
- * @param {number} rowCount Count of pixel rows to draw.
- * @private
- */
-ImageUtil.ImageLoader.prototype.copyStrip_ = function(
- context, image, firstRow, rowCount) {
- var lastRow = Math.min(firstRow + rowCount, image.height);
-
- context.drawImage(
- image, 0, firstRow, image.width, lastRow - firstRow,
- -image.width / 2, firstRow - image.height / 2,
- image.width, lastRow - firstRow);
-
- if (lastRow === image.height) {
- context.restore();
- if (this.entry_.toURL().substr(0, 5) !== 'data:') { // Ignore data urls.
- ImageUtil.metrics.recordInterval(ImageUtil.getMetricName('LoadTime'));
- }
- try {
- setTimeout(this.callback_, 0, context.canvas);
- } catch (e) {
- console.error(e);
- }
- this.callback_ = null;
- } else {
- var self = this;
- this.timeout_ = setTimeout(
- function() {
- self.timeout_ = null;
- self.copyStrip_(context, image, lastRow, rowCount);
- }, 0);
- }
-};
-
-/**
- * @param {HTMLElement} element To remove children from.
- */
-ImageUtil.removeChildren = function(element) {
- element.textContent = '';
-};
-
-/**
- * @param {string} name File name (with extension).
- * @return {string} File name without extension.
- */
-ImageUtil.getDisplayNameFromName = function(name) {
- var index = name.lastIndexOf('.');
- if (index !== -1)
- return name.substr(0, index);
- else
- return name;
-};
-
-/**
- * @param {string} name File name.
- * @return {string} File extension.
- */
-ImageUtil.getExtensionFromFullName = function(name) {
- var index = name.lastIndexOf('.');
- if (index !== -1)
- return name.substring(index);
- else
- return '';
-};
-
-/**
- * Metrics (from metrics.js) itnitialized by the File Manager from owner frame.
- * @type {Object?}
- */
-ImageUtil.metrics = null;
-
-/**
- * @param {string} name Local name.
- * @return {string} Full name.
- */
-ImageUtil.getMetricName = function(name) {
- return 'PhotoEditor.' + name;
-};
-
-/**
- * Used for metrics reporting, keep in sync with the histogram description.
- */
-ImageUtil.FILE_TYPES = ['jpg', 'png', 'gif', 'bmp', 'webp'];
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_view.js b/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_view.js
deleted file mode 100644
index 24d70045798..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/image_view.js
+++ /dev/null
@@ -1,1065 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * The overlay displaying the image.
- *
- * @param {HTMLElement} container The container element.
- * @param {Viewport} viewport The viewport.
- * @param {MetadataCache} metadataCache The metadataCache.
- * @constructor
- */
-function ImageView(container, viewport, metadataCache) {
- this.container_ = container;
- this.viewport_ = viewport;
- this.document_ = container.ownerDocument;
- this.contentGeneration_ = 0;
- this.displayedContentGeneration_ = 0;
- this.displayedViewportGeneration_ = 0;
-
- this.imageLoader_ = new ImageUtil.ImageLoader(this.document_, metadataCache);
- // We have a separate image loader for prefetch which does not get cancelled
- // when the selection changes.
- this.prefetchLoader_ = new ImageUtil.ImageLoader(
- this.document_, metadataCache);
-
- // The content cache is used for prefetching the next image when going
- // through the images sequentially. The real life photos can be large
- // (18Mpix = 72Mb pixel array) so we want only the minimum amount of caching.
- this.contentCache_ = new ImageView.Cache(2);
-
- // We reuse previously generated screen-scale images so that going back to
- // a recently loaded image looks instant even if the image is not in
- // the content cache any more. Screen-scale images are small (~1Mpix)
- // so we can afford to cache more of them.
- this.screenCache_ = new ImageView.Cache(5);
- this.contentCallbacks_ = [];
-
- /**
- * The element displaying the current content.
- *
- * @type {HTMLCanvasElement|HTMLVideoElement}
- * @private
- */
- this.screenImage_ = null;
-
- this.localImageTransformFetcher_ = function(entry, callback) {
- metadataCache.get(entry, 'fetchedMedia', function(fetchedMedia) {
- callback(fetchedMedia.imageTransform);
- });
- };
-}
-
-/**
- * Duration of transition between modes in ms.
- */
-ImageView.MODE_TRANSITION_DURATION = 350;
-
-/**
- * If the user flips though images faster than this interval we do not apply
- * the slide-in/slide-out transition.
- */
-ImageView.FAST_SCROLL_INTERVAL = 300;
-
-/**
- * Image load type: full resolution image loaded from cache.
- */
-ImageView.LOAD_TYPE_CACHED_FULL = 0;
-
-/**
- * Image load type: screen resolution preview loaded from cache.
- */
-ImageView.LOAD_TYPE_CACHED_SCREEN = 1;
-
-/**
- * Image load type: image read from file.
- */
-ImageView.LOAD_TYPE_IMAGE_FILE = 2;
-
-/**
- * Image load type: video loaded.
- */
-ImageView.LOAD_TYPE_VIDEO_FILE = 3;
-
-/**
- * Image load type: error occurred.
- */
-ImageView.LOAD_TYPE_ERROR = 4;
-
-/**
- * Image load type: the file contents is not available offline.
- */
-ImageView.LOAD_TYPE_OFFLINE = 5;
-
-/**
- * The total number of load types.
- */
-ImageView.LOAD_TYPE_TOTAL = 6;
-
-ImageView.prototype = {__proto__: ImageBuffer.Overlay.prototype};
-
-/**
- * Draws below overlays with the default zIndex.
- * @return {number} Z-index.
- */
-ImageView.prototype.getZIndex = function() { return -1 };
-
-/**
- * Draws the image on screen.
- */
-ImageView.prototype.draw = function() {
- if (!this.contentCanvas_) // Do nothing if the image content is not set.
- return;
-
- var forceRepaint = false;
-
- if (this.displayedViewportGeneration_ !==
- this.viewport_.getCacheGeneration()) {
- this.displayedViewportGeneration_ = this.viewport_.getCacheGeneration();
-
- this.setupDeviceBuffer(this.screenImage_);
-
- forceRepaint = true;
- }
-
- if (forceRepaint ||
- this.displayedContentGeneration_ !== this.contentGeneration_) {
- this.displayedContentGeneration_ = this.contentGeneration_;
-
- ImageUtil.trace.resetTimer('paint');
- this.paintDeviceRect(this.viewport_.getDeviceClipped(),
- this.contentCanvas_, this.viewport_.getImageClipped());
- ImageUtil.trace.reportTimer('paint');
- }
-};
-
-/**
- * @param {number} x X pointer position.
- * @param {number} y Y pointer position.
- * @param {boolean} mouseDown True if mouse is down.
- * @return {string} CSS cursor style.
- */
-ImageView.prototype.getCursorStyle = function(x, y, mouseDown) {
- // Indicate that the image is draggable.
- if (this.viewport_.isClipped() &&
- this.viewport_.getScreenClipped().inside(x, y))
- return 'move';
-
- return null;
-};
-
-/**
- * @param {number} x X pointer position.
- * @param {number} y Y pointer position.
- * @return {function} The closure to call on drag.
- */
-ImageView.prototype.getDragHandler = function(x, y) {
- var cursor = this.getCursorStyle(x, y);
- if (cursor === 'move') {
- // Return the handler that drags the entire image.
- return this.viewport_.createOffsetSetter(x, y);
- }
-
- return null;
-};
-
-/**
- * @return {number} The cache generation.
- */
-ImageView.prototype.getCacheGeneration = function() {
- return this.contentGeneration_;
-};
-
-/**
- * Invalidates the caches to force redrawing the screen canvas.
- */
-ImageView.prototype.invalidateCaches = function() {
- this.contentGeneration_++;
-};
-
-/**
- * @return {HTMLCanvasElement} The content canvas element.
- */
-ImageView.prototype.getCanvas = function() { return this.contentCanvas_ };
-
-/**
- * @return {boolean} True if the a valid image is currently loaded.
- */
-ImageView.prototype.hasValidImage = function() {
- return !this.preview_ && this.contentCanvas_ && this.contentCanvas_.width;
-};
-
-/**
- * @return {HTMLVideoElement} The video element.
- */
-ImageView.prototype.getVideo = function() { return this.videoElement_ };
-
-/**
- * @return {HTMLCanvasElement} The cached thumbnail image.
- */
-ImageView.prototype.getThumbnail = function() { return this.thumbnailCanvas_ };
-
-/**
- * @return {number} The content revision number.
- */
-ImageView.prototype.getContentRevision = function() {
- return this.contentRevision_;
-};
-
-/**
- * Copies an image fragment from a full resolution canvas to a device resolution
- * canvas.
- *
- * @param {Rect} deviceRect Rectangle in the device coordinates.
- * @param {HTMLCanvasElement} canvas Full resolution canvas.
- * @param {Rect} imageRect Rectangle in the full resolution canvas.
- */
-ImageView.prototype.paintDeviceRect = function(deviceRect, canvas, imageRect) {
- // Map screen canvas (0,0) to (deviceBounds.left, deviceBounds.top)
- var deviceBounds = this.viewport_.getDeviceClipped();
- deviceRect = deviceRect.shift(-deviceBounds.left, -deviceBounds.top);
-
- // The source canvas may have different physical size than the image size
- // set at the viewport. Adjust imageRect accordingly.
- var bounds = this.viewport_.getImageBounds();
- var scaleX = canvas.width / bounds.width;
- var scaleY = canvas.height / bounds.height;
- imageRect = new Rect(imageRect.left * scaleX, imageRect.top * scaleY,
- imageRect.width * scaleX, imageRect.height * scaleY);
- Rect.drawImage(
- this.screenImage_.getContext('2d'), canvas, deviceRect, imageRect);
-};
-
-/**
- * Creates an overlay canvas with properties similar to the screen canvas.
- * Useful for showing quick feedback when editing.
- *
- * @return {HTMLCanvasElement} Overlay canvas.
- */
-ImageView.prototype.createOverlayCanvas = function() {
- var canvas = this.document_.createElement('canvas');
- canvas.className = 'image';
- this.container_.appendChild(canvas);
- return canvas;
-};
-
-/**
- * Sets up the canvas as a buffer in the device resolution.
- *
- * @param {HTMLCanvasElement} canvas The buffer canvas.
- */
-ImageView.prototype.setupDeviceBuffer = function(canvas) {
- var deviceRect = this.viewport_.getDeviceClipped();
-
- // Set the canvas position and size in device pixels.
- if (canvas.width !== deviceRect.width)
- canvas.width = deviceRect.width;
-
- if (canvas.height !== deviceRect.height)
- canvas.height = deviceRect.height;
-
- canvas.style.left = deviceRect.left + 'px';
- canvas.style.top = deviceRect.top + 'px';
-
- // Scale the canvas down to screen pixels.
- this.setTransform(canvas);
-};
-
-/**
- * @return {ImageData} A new ImageData object with a copy of the content.
- */
-ImageView.prototype.copyScreenImageData = function() {
- return this.screenImage_.getContext('2d').getImageData(
- 0, 0, this.screenImage_.width, this.screenImage_.height);
-};
-
-/**
- * @return {boolean} True if the image is currently being loaded.
- */
-ImageView.prototype.isLoading = function() {
- return this.imageLoader_.isBusy();
-};
-
-/**
- * Cancels the current image loading operation. The callbacks will be ignored.
- */
-ImageView.prototype.cancelLoad = function() {
- this.imageLoader_.cancel();
-};
-
-/**
- * Loads and display a new image.
- *
- * Loads the thumbnail first, then replaces it with the main image.
- * Takes into account the image orientation encoded in the metadata.
- *
- * @param {FileEntry} entry Image entry.
- * @param {Object} metadata Metadata.
- * @param {Object} effect Transition effect object.
- * @param {function(number} displayCallback Called when the image is displayed
- * (possibly as a prevew).
- * @param {function(number} loadCallback Called when the image is fully loaded.
- * The parameter is the load type.
- */
-ImageView.prototype.load = function(entry, metadata, effect,
- displayCallback, loadCallback) {
- if (effect) {
- // Skip effects when reloading repeatedly very quickly.
- var time = Date.now();
- if (this.lastLoadTime_ &&
- (time - this.lastLoadTime_) < ImageView.FAST_SCROLL_INTERVAL) {
- effect = null;
- }
- this.lastLoadTime_ = time;
- }
-
- metadata = metadata || {};
-
- ImageUtil.metrics.startInterval(ImageUtil.getMetricName('DisplayTime'));
-
- var self = this;
-
- this.contentEntry_ = entry;
- this.contentRevision_ = -1;
-
- var loadingVideo = FileType.getMediaType(entry) === 'video';
- if (loadingVideo) {
- var video = this.document_.createElement('video');
- var videoPreview = !!(metadata.thumbnail && metadata.thumbnail.url);
- if (videoPreview) {
- var thumbnailLoader = new ThumbnailLoader(
- metadata.thumbnail.url,
- ThumbnailLoader.LoaderType.CANVAS,
- metadata);
- thumbnailLoader.loadDetachedImage(function(success) {
- if (success) {
- var canvas = thumbnailLoader.getImage();
- video.setAttribute('poster', canvas.toDataURL('image/jpeg'));
- this.replace(video, effect); // Show the poster immediately.
- if (displayCallback) displayCallback();
- }
- }.bind(this));
- }
-
- var onVideoLoad = function(error) {
- video.removeEventListener('loadedmetadata', onVideoLoadSuccess);
- video.removeEventListener('error', onVideoLoadError);
- displayMainImage(ImageView.LOAD_TYPE_VIDEO_FILE, videoPreview, video,
- error);
- };
- var onVideoLoadError = onVideoLoad.bind(this, 'GALLERY_VIDEO_ERROR');
- var onVideoLoadSuccess = onVideoLoad.bind(this, null);
-
- video.addEventListener('loadedmetadata', onVideoLoadSuccess);
- video.addEventListener('error', onVideoLoadError);
-
- video.src = entry.toURL();
- video.load();
- return;
- }
-
- // Cache has to be evicted in advance, so the returned cached image is not
- // evicted later by the prefetched image.
- this.contentCache_.evictLRU();
-
- var cached = this.contentCache_.getItem(this.contentEntry_);
- if (cached) {
- displayMainImage(ImageView.LOAD_TYPE_CACHED_FULL,
- false /* no preview */, cached);
- } else {
- var cachedScreen = this.screenCache_.getItem(this.contentEntry_);
- var imageWidth = metadata.media && metadata.media.width ||
- metadata.drive && metadata.drive.imageWidth;
- var imageHeight = metadata.media && metadata.media.height ||
- metadata.drive && metadata.drive.imageHeight;
- if (cachedScreen) {
- // We have a cached screen-scale canvas, use it instead of a thumbnail.
- displayThumbnail(ImageView.LOAD_TYPE_CACHED_SCREEN, cachedScreen);
- // As far as the user can tell the image is loaded. We still need to load
- // the full res image to make editing possible, but we can report now.
- ImageUtil.metrics.recordInterval(ImageUtil.getMetricName('DisplayTime'));
- } else if ((!effect || (effect.constructor.name === 'Slide')) &&
- metadata.thumbnail && metadata.thumbnail.url &&
- !(imageWidth && imageHeight &&
- ImageUtil.ImageLoader.isTooLarge(imageWidth, imageHeight))) {
- // Only show thumbnails if there is no effect or the effect is Slide.
- // Also no thumbnail if the image is too large to be loaded.
- var thumbnailLoader = new ThumbnailLoader(
- metadata.thumbnail.url,
- ThumbnailLoader.LoaderType.CANVAS,
- metadata);
- thumbnailLoader.loadDetachedImage(function(success) {
- displayThumbnail(ImageView.LOAD_TYPE_IMAGE_FILE,
- success ? thumbnailLoader.getImage() : null);
- });
- } else {
- loadMainImage(ImageView.LOAD_TYPE_IMAGE_FILE, entry,
- false /* no preview*/, 0 /* delay */);
- }
- }
-
- function displayThumbnail(loadType, canvas) {
- if (canvas) {
- self.replace(
- canvas,
- effect,
- metadata.media.width || metadata.drive.imageWidth,
- metadata.media.height || metadata.drive.imageHeight,
- true /* preview */);
- if (displayCallback) displayCallback();
- }
- loadMainImage(loadType, entry, !!canvas,
- (effect && canvas) ? effect.getSafeInterval() : 0);
- }
-
- function loadMainImage(loadType, contentEntry, previewShown, delay) {
- if (self.prefetchLoader_.isLoading(contentEntry)) {
- // The image we need is already being prefetched. Initiating another load
- // would be a waste. Hijack the load instead by overriding the callback.
- self.prefetchLoader_.setCallback(
- displayMainImage.bind(null, loadType, previewShown));
-
- // Swap the loaders so that the self.isLoading works correctly.
- var temp = self.prefetchLoader_;
- self.prefetchLoader_ = self.imageLoader_;
- self.imageLoader_ = temp;
- return;
- }
- self.prefetchLoader_.cancel(); // The prefetch was doing something useless.
-
- self.imageLoader_.load(
- contentEntry,
- self.localImageTransformFetcher_,
- displayMainImage.bind(null, loadType, previewShown),
- delay);
- }
-
- function displayMainImage(loadType, previewShown, content, opt_error) {
- if (opt_error)
- loadType = ImageView.LOAD_TYPE_ERROR;
-
- // If we already displayed the preview we should not replace the content if:
- // 1. The full content failed to load.
- // or
- // 2. We are loading a video (because the full video is displayed in the
- // same HTML element as the preview).
- var animationDuration = 0;
- if (!(previewShown &&
- (loadType === ImageView.LOAD_TYPE_ERROR ||
- loadType === ImageView.LOAD_TYPE_VIDEO_FILE))) {
- var replaceEffect = previewShown ? null : effect;
- animationDuration = replaceEffect ? replaceEffect.getSafeInterval() : 0;
- self.replace(content, replaceEffect);
- if (!previewShown && displayCallback) displayCallback();
- }
-
- if (loadType !== ImageView.LOAD_TYPE_ERROR &&
- loadType !== ImageView.LOAD_TYPE_CACHED_SCREEN) {
- ImageUtil.metrics.recordInterval(ImageUtil.getMetricName('DisplayTime'));
- }
- ImageUtil.metrics.recordEnum(ImageUtil.getMetricName('LoadMode'),
- loadType, ImageView.LOAD_TYPE_TOTAL);
-
- if (loadType === ImageView.LOAD_TYPE_ERROR &&
- !navigator.onLine && metadata.streaming) {
- // |streaming| is set only when the file is not locally cached.
- loadType = ImageView.LOAD_TYPE_OFFLINE;
- }
- if (loadCallback) loadCallback(loadType, animationDuration, opt_error);
- }
-};
-
-/**
- * Prefetches an image.
- * @param {FileEntry} entry The image entry.
- * @param {number} delay Image load delay in ms.
- */
-ImageView.prototype.prefetch = function(entry, delay) {
- var self = this;
- function prefetchDone(canvas) {
- if (canvas.width)
- self.contentCache_.putItem(entry, canvas);
- }
-
- var cached = this.contentCache_.getItem(entry);
- if (cached) {
- prefetchDone(cached);
- } else if (FileType.getMediaType(entry) === 'image') {
- // Evict the LRU item before we allocate the new canvas to avoid unneeded
- // strain on memory.
- this.contentCache_.evictLRU();
-
- this.prefetchLoader_.load(
- entry,
- this.localImageTransformFetcher_,
- prefetchDone,
- delay);
- }
-};
-
-/**
- * Renames the current image.
- * @param {FileEntry} newEntry The new image Entry.
- */
-ImageView.prototype.changeEntry = function(newEntry) {
- this.contentCache_.renameItem(this.contentEntry_, newEntry);
- this.screenCache_.renameItem(this.contentEntry_, newEntry);
- this.contentEntry_ = newEntry;
-};
-
-/**
- * Unloads content.
- * @param {Rect} zoomToRect Target rectangle for zoom-out-effect.
- */
-ImageView.prototype.unload = function(zoomToRect) {
- if (this.unloadTimer_) {
- clearTimeout(this.unloadTimer_);
- this.unloadTimer_ = null;
- }
- if (zoomToRect && this.screenImage_) {
- var effect = this.createZoomEffect(zoomToRect);
- this.setTransform(this.screenImage_, effect);
- this.screenImage_.setAttribute('fade', true);
- this.unloadTimer_ = setTimeout(function() {
- this.unloadTimer_ = null;
- this.unload(null /* force unload */);
- }.bind(this),
- effect.getSafeInterval());
- return;
- }
- this.container_.textContent = '';
- this.contentCanvas_ = null;
- this.screenImage_ = null;
- this.videoElement_ = null;
-};
-
-/**
- * @param {HTMLCanvasElement|HTMLVideoElement} content The image element.
- * @param {number=} opt_width Image width.
- * @param {number=} opt_height Image height.
- * @param {boolean=} opt_preview True if the image is a preview (not full res).
- * @private
- */
-ImageView.prototype.replaceContent_ = function(
- content, opt_width, opt_height, opt_preview) {
-
- if (this.contentCanvas_ && this.contentCanvas_.parentNode === this.container_)
- this.container_.removeChild(this.contentCanvas_);
-
- if (content.constructor.name === 'HTMLVideoElement') {
- this.contentCanvas_ = null;
- this.videoElement_ = content;
- this.screenImage_ = content;
- this.screenImage_.className = 'image';
- this.container_.appendChild(this.screenImage_);
- this.videoElement_.play();
- return;
- }
-
- this.screenImage_ = this.document_.createElement('canvas');
- this.screenImage_.className = 'image';
-
- this.videoElement_ = null;
- this.contentCanvas_ = content;
- this.invalidateCaches();
- this.viewport_.setImageSize(
- opt_width || this.contentCanvas_.width,
- opt_height || this.contentCanvas_.height);
- this.viewport_.fitImage();
- this.viewport_.update();
- this.draw();
-
- this.container_.appendChild(this.screenImage_);
-
- this.preview_ = opt_preview;
- // If this is not a thumbnail, cache the content and the screen-scale image.
- if (this.hasValidImage()) {
- // Insert the full resolution canvas into DOM so that it can be printed.
- this.container_.appendChild(this.contentCanvas_);
- this.contentCanvas_.classList.add('fullres');
-
- this.contentCache_.putItem(this.contentEntry_, this.contentCanvas_, true);
- this.screenCache_.putItem(this.contentEntry_, this.screenImage_);
-
- // TODO(kaznacheev): It is better to pass screenImage_ as it is usually
- // much smaller than contentCanvas_ and still contains the entire image.
- // Once we implement zoom/pan we should pass contentCanvas_ instead.
- this.updateThumbnail_(this.screenImage_);
-
- this.contentRevision_++;
- for (var i = 0; i !== this.contentCallbacks_.length; i++) {
- try {
- this.contentCallbacks_[i]();
- } catch (e) {
- console.error(e);
- }
- }
- }
-};
-
-/**
- * Adds a listener for content changes.
- * @param {function} callback Callback.
- */
-ImageView.prototype.addContentCallback = function(callback) {
- this.contentCallbacks_.push(callback);
-};
-
-/**
- * Updates the cached thumbnail image.
- *
- * @param {HTMLCanvasElement} canvas The source canvas.
- * @private
- */
-ImageView.prototype.updateThumbnail_ = function(canvas) {
- ImageUtil.trace.resetTimer('thumb');
- var pixelCount = 10000;
- var downScale =
- Math.max(1, Math.sqrt(canvas.width * canvas.height / pixelCount));
-
- this.thumbnailCanvas_ = canvas.ownerDocument.createElement('canvas');
- this.thumbnailCanvas_.width = Math.round(canvas.width / downScale);
- this.thumbnailCanvas_.height = Math.round(canvas.height / downScale);
- Rect.drawImage(this.thumbnailCanvas_.getContext('2d'), canvas);
- ImageUtil.trace.reportTimer('thumb');
-};
-
-/**
- * Replaces the displayed image, possibly with slide-in animation.
- *
- * @param {HTMLCanvasElement|HTMLVideoElement} content The image element.
- * @param {Object=} opt_effect Transition effect object.
- * @param {number=} opt_width Image width.
- * @param {number=} opt_height Image height.
- * @param {boolean=} opt_preview True if the image is a preview (not full res).
- */
-ImageView.prototype.replace = function(
- content, opt_effect, opt_width, opt_height, opt_preview) {
- var oldScreenImage = this.screenImage_;
-
- this.replaceContent_(content, opt_width, opt_height, opt_preview);
- if (!opt_effect) {
- if (oldScreenImage)
- oldScreenImage.parentNode.removeChild(oldScreenImage);
- return;
- }
-
- var newScreenImage = this.screenImage_;
-
- if (oldScreenImage)
- ImageUtil.setAttribute(newScreenImage, 'fade', true);
- this.setTransform(newScreenImage, opt_effect, 0 /* instant */);
-
- setTimeout(function() {
- this.setTransform(newScreenImage, null,
- opt_effect && opt_effect.getDuration());
- if (oldScreenImage) {
- ImageUtil.setAttribute(newScreenImage, 'fade', false);
- ImageUtil.setAttribute(oldScreenImage, 'fade', true);
- console.assert(opt_effect.getReverse, 'Cannot revert an effect.');
- var reverse = opt_effect.getReverse();
- this.setTransform(oldScreenImage, reverse);
- setTimeout(function() {
- if (oldScreenImage.parentNode)
- oldScreenImage.parentNode.removeChild(oldScreenImage);
- }, reverse.getSafeInterval());
- }
- }.bind(this), 0);
-};
-
-/**
- * @param {HTMLCanvasElement|HTMLVideoElement} element The element to transform.
- * @param {ImageView.Effect=} opt_effect The effect to apply.
- * @param {number=} opt_duration Transition duration.
- */
-ImageView.prototype.setTransform = function(element, opt_effect, opt_duration) {
- if (!opt_effect)
- opt_effect = new ImageView.Effect.None();
- if (typeof opt_duration !== 'number')
- opt_duration = opt_effect.getDuration();
- element.style.webkitTransitionDuration = opt_duration + 'ms';
- element.style.webkitTransitionTimingFunction = opt_effect.getTiming();
- element.style.webkitTransform = opt_effect.transform(element, this.viewport_);
-};
-
-/**
- * @param {Rect} screenRect Target rectangle in screen coordinates.
- * @return {ImageView.Effect.Zoom} Zoom effect object.
- */
-ImageView.prototype.createZoomEffect = function(screenRect) {
- return new ImageView.Effect.Zoom(
- this.viewport_.screenToDeviceRect(screenRect),
- null /* use viewport */,
- ImageView.MODE_TRANSITION_DURATION);
-};
-
-/**
- * Visualizes crop or rotate operation. Hide the old image instantly, animate
- * the new image to visualize the operation.
- *
- * @param {HTMLCanvasElement} canvas New content canvas.
- * @param {Rect} imageCropRect The crop rectangle in image coordinates.
- * Null for rotation operations.
- * @param {number} rotate90 Rotation angle in 90 degree increments.
- * @return {number} Animation duration.
- */
-ImageView.prototype.replaceAndAnimate = function(
- canvas, imageCropRect, rotate90) {
- var oldScale = this.viewport_.getScale();
- var deviceCropRect = imageCropRect && this.viewport_.screenToDeviceRect(
- this.viewport_.imageToScreenRect(imageCropRect));
-
- var oldScreenImage = this.screenImage_;
- this.replaceContent_(canvas);
- var newScreenImage = this.screenImage_;
-
- // Display the new canvas, initially transformed.
- var deviceFullRect = this.viewport_.getDeviceClipped();
-
- var effect = rotate90 ?
- new ImageView.Effect.Rotate(
- oldScale / this.viewport_.getScale(), -rotate90) :
- new ImageView.Effect.Zoom(deviceCropRect, deviceFullRect);
-
- this.setTransform(newScreenImage, effect, 0 /* instant */);
-
- oldScreenImage.parentNode.appendChild(newScreenImage);
- oldScreenImage.parentNode.removeChild(oldScreenImage);
-
- // Let the layout fire, then animate back to non-transformed state.
- setTimeout(
- this.setTransform.bind(
- this, newScreenImage, null, effect.getDuration()),
- 0);
-
- return effect.getSafeInterval();
-};
-
-/**
- * Visualizes "undo crop". Shrink the current image to the given crop rectangle
- * while fading in the new image.
- *
- * @param {HTMLCanvasElement} canvas New content canvas.
- * @param {Rect} imageCropRect The crop rectangle in image coordinates.
- * @return {number} Animation duration.
- */
-ImageView.prototype.animateAndReplace = function(canvas, imageCropRect) {
- var deviceFullRect = this.viewport_.getDeviceClipped();
- var oldScale = this.viewport_.getScale();
-
- var oldScreenImage = this.screenImage_;
- this.replaceContent_(canvas);
- var newScreenImage = this.screenImage_;
-
- var deviceCropRect = this.viewport_.screenToDeviceRect(
- this.viewport_.imageToScreenRect(imageCropRect));
-
- var setFade = ImageUtil.setAttribute.bind(null, newScreenImage, 'fade');
- setFade(true);
- oldScreenImage.parentNode.insertBefore(newScreenImage, oldScreenImage);
-
- var effect = new ImageView.Effect.Zoom(deviceCropRect, deviceFullRect);
- // Animate to the transformed state.
- this.setTransform(oldScreenImage, effect);
-
- setTimeout(setFade.bind(null, false), 0);
-
- setTimeout(function() {
- if (oldScreenImage.parentNode)
- oldScreenImage.parentNode.removeChild(oldScreenImage);
- }, effect.getSafeInterval());
-
- return effect.getSafeInterval();
-};
-
-
-/**
- * Generic cache with a limited capacity and LRU eviction.
- * @param {number} capacity Maximum number of cached item.
- * @constructor
- */
-ImageView.Cache = function(capacity) {
- this.capacity_ = capacity;
- this.map_ = {};
- this.order_ = [];
-};
-
-/**
- * Fetches the item from the cache.
- * @param {FileEntry} entry The entry.
- * @return {Object} The cached item.
- */
-ImageView.Cache.prototype.getItem = function(entry) {
- return this.map_[entry.toURL()];
-};
-
-/**
- * Puts the item into the cache.
- *
- * @param {FileEntry} entry The entry.
- * @param {Object} item The item object.
- * @param {boolean=} opt_keepLRU True if the LRU order should not be modified.
- */
-ImageView.Cache.prototype.putItem = function(entry, item, opt_keepLRU) {
- var pos = this.order_.indexOf(entry.toURL());
-
- if ((pos >= 0) !== (entry.toURL() in this.map_))
- throw new Error('Inconsistent cache state');
-
- if (entry.toURL() in this.map_) {
- if (!opt_keepLRU) {
- // Move to the end (most recently used).
- this.order_.splice(pos, 1);
- this.order_.push(entry.toURL());
- }
- } else {
- this.evictLRU();
- this.order_.push(entry.toURL());
- }
-
- if ((pos >= 0) && (item !== this.map_[entry.toURL()]))
- this.deleteItem_(this.map_[entry.toURL()]);
- this.map_[entry.toURL()] = item;
-
- if (this.order_.length > this.capacity_)
- throw new Error('Exceeded cache capacity');
-};
-
-/**
- * Evicts the least recently used items.
- */
-ImageView.Cache.prototype.evictLRU = function() {
- if (this.order_.length === this.capacity_) {
- var url = this.order_.shift();
- this.deleteItem_(this.map_[url]);
- delete this.map_[url];
- }
-};
-
-/**
- * Changes the Entry.
- * @param {FileEntry} oldEntry The old Entry.
- * @param {FileEntry} newEntry The new Entry.
- */
-ImageView.Cache.prototype.renameItem = function(oldEntry, newEntry) {
- if (util.isSameEntry(oldEntry, newEntry))
- return; // No need to rename.
-
- var pos = this.order_.indexOf(oldEntry.toURL());
- if (pos < 0)
- return; // Not cached.
-
- this.order_[pos] = newEntry.toURL();
- this.map_[newEntry.toURL()] = this.map_[oldEntry.toURL()];
- delete this.map_[oldEntry.toURL()];
-};
-
-/**
- * Disposes an object.
- *
- * @param {Object} item The item object.
- * @private
- */
-ImageView.Cache.prototype.deleteItem_ = function(item) {
- // Trick to reduce memory usage without waiting for gc.
- if (item instanceof HTMLCanvasElement) {
- // If the canvas is being used somewhere else (eg. displayed on the screen),
- // it will be cleared.
- item.width = 0;
- item.height = 0;
- }
-};
-
-/* Transition effects */
-
-/**
- * Base class for effects.
- *
- * @param {number} duration Duration in ms.
- * @param {string=} opt_timing CSS transition timing function name.
- * @constructor
- */
-ImageView.Effect = function(duration, opt_timing) {
- this.duration_ = duration;
- this.timing_ = opt_timing || 'linear';
-};
-
-/**
- *
- */
-ImageView.Effect.DEFAULT_DURATION = 180;
-
-/**
- *
- */
-ImageView.Effect.MARGIN = 100;
-
-/**
- * @return {number} Effect duration in ms.
- */
-ImageView.Effect.prototype.getDuration = function() { return this.duration_ };
-
-/**
- * @return {number} Delay in ms since the beginning of the animation after which
- * it is safe to perform CPU-heavy operations without disrupting the animation.
- */
-ImageView.Effect.prototype.getSafeInterval = function() {
- return this.getDuration() + ImageView.Effect.MARGIN;
-};
-
-/**
- * @return {string} CSS transition timing function name.
- */
-ImageView.Effect.prototype.getTiming = function() { return this.timing_ };
-
-/**
- * @param {HTMLCanvasElement|HTMLVideoElement} element Element.
- * @return {number} Preferred pixel ration to use with this element.
- * @private
- */
-ImageView.Effect.getPixelRatio_ = function(element) {
- if (element.constructor.name === 'HTMLCanvasElement')
- return Viewport.getDevicePixelRatio();
- else
- return 1;
-};
-
-/**
- * Default effect. It is not a no-op as it needs to adjust a canvas scale
- * for devicePixelRatio.
- *
- * @constructor
- */
-ImageView.Effect.None = function() {
- ImageView.Effect.call(this, 0);
-};
-
-/**
- * Inherits from ImageView.Effect.
- */
-ImageView.Effect.None.prototype = { __proto__: ImageView.Effect.prototype };
-
-/**
- * @param {HTMLCanvasElement|HTMLVideoElement} element Element.
- * @return {string} Transform string.
- */
-ImageView.Effect.None.prototype.transform = function(element) {
- var ratio = ImageView.Effect.getPixelRatio_(element);
- return 'scale(' + (1 / ratio) + ')';
-};
-
-/**
- * Slide effect.
- *
- * @param {number} direction -1 for left, 1 for right.
- * @param {boolean=} opt_slow True if slow (as in slideshow).
- * @constructor
- */
-ImageView.Effect.Slide = function Slide(direction, opt_slow) {
- ImageView.Effect.call(this,
- opt_slow ? 800 : ImageView.Effect.DEFAULT_DURATION, 'ease-in-out');
- this.direction_ = direction;
- this.slow_ = opt_slow;
- this.shift_ = opt_slow ? 100 : 40;
- if (this.direction_ < 0) this.shift_ = -this.shift_;
-};
-
-/**
- * Inherits from ImageView.Effect.
- */
-ImageView.Effect.Slide.prototype = { __proto__: ImageView.Effect.prototype };
-
-/**
- * @return {ImageView.Effect.Slide} Reverse Slide effect.
- */
-ImageView.Effect.Slide.prototype.getReverse = function() {
- return new ImageView.Effect.Slide(-this.direction_, this.slow_);
-};
-
-/**
- * @param {HTMLCanvasElement|HTMLVideoElement} element Element.
- * @return {string} Transform string.
- */
-ImageView.Effect.Slide.prototype.transform = function(element) {
- var ratio = ImageView.Effect.getPixelRatio_(element);
- return 'scale(' + (1 / ratio) + ') translate(' + this.shift_ + 'px, 0px)';
-};
-
-/**
- * Zoom effect.
- *
- * Animates the original rectangle to the target rectangle. Both parameters
- * should be given in device coordinates (accounting for devicePixelRatio).
- *
- * @param {Rect} deviceTargetRect Target rectangle.
- * @param {Rect=} opt_deviceOriginalRect Original rectangle. If omitted,
- * the full viewport will be used at the time of |transform| call.
- * @param {number=} opt_duration Duration in ms.
- * @constructor
- */
-ImageView.Effect.Zoom = function(
- deviceTargetRect, opt_deviceOriginalRect, opt_duration) {
- ImageView.Effect.call(this,
- opt_duration || ImageView.Effect.DEFAULT_DURATION);
- this.target_ = deviceTargetRect;
- this.original_ = opt_deviceOriginalRect;
-};
-
-/**
- * Inherits from ImageView.Effect.
- */
-ImageView.Effect.Zoom.prototype = { __proto__: ImageView.Effect.prototype };
-
-/**
- * @param {HTMLCanvasElement|HTMLVideoElement} element Element.
- * @param {Viewport} viewport Viewport.
- * @return {string} Transform string.
- */
-ImageView.Effect.Zoom.prototype.transform = function(element, viewport) {
- if (!this.original_)
- this.original_ = viewport.getDeviceClipped();
-
- var ratio = ImageView.Effect.getPixelRatio_(element);
-
- var dx = (this.target_.left + this.target_.width / 2) -
- (this.original_.left + this.original_.width / 2);
- var dy = (this.target_.top + this.target_.height / 2) -
- (this.original_.top + this.original_.height / 2);
-
- var scaleX = this.target_.width / this.original_.width;
- var scaleY = this.target_.height / this.original_.height;
-
- return 'translate(' + (dx / ratio) + 'px,' + (dy / ratio) + 'px) ' +
- 'scaleX(' + (scaleX / ratio) + ') scaleY(' + (scaleY / ratio) + ')';
-};
-
-/**
- * Rotate effect.
- *
- * @param {number} scale Scale.
- * @param {number} rotate90 Rotation in 90 degrees increments.
- * @constructor
- */
-ImageView.Effect.Rotate = function(scale, rotate90) {
- ImageView.Effect.call(this, ImageView.Effect.DEFAULT_DURATION);
- this.scale_ = scale;
- this.rotate90_ = rotate90;
-};
-
-/**
- * Inherits from ImageView.Effect.
- */
-ImageView.Effect.Rotate.prototype = { __proto__: ImageView.Effect.prototype };
-
-/**
- * @param {HTMLCanvasElement|HTMLVideoElement} element Element.
- * @return {string} Transform string.
- */
-ImageView.Effect.Rotate.prototype.transform = function(element) {
- var ratio = ImageView.Effect.getPixelRatio_(element);
- return 'rotate(' + (this.rotate90_ * 90) + 'deg) ' +
- 'scale(' + (this.scale_ / ratio) + ')';
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/viewport.js b/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/viewport.js
deleted file mode 100644
index 4d6b8ea0874..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/image_editor/viewport.js
+++ /dev/null
@@ -1,430 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Viewport class controls the way the image is displayed (scale, offset etc).
- * @constructor
- */
-function Viewport() {
- this.imageBounds_ = new Rect();
- this.screenBounds_ = new Rect();
-
- this.scale_ = 1;
- this.offsetX_ = 0;
- this.offsetY_ = 0;
-
- this.generation_ = 0;
-
- this.scaleControl_ = null;
- this.repaintCallbacks_ = [];
- this.update();
-}
-
-/*
- * Viewport modification.
- */
-
-/**
- * @param {Object} scaleControl The UI object responsible for scaling.
- */
-Viewport.prototype.setScaleControl = function(scaleControl) {
- this.scaleControl_ = scaleControl;
-};
-
-/**
- * @param {number} width Image width.
- * @param {number} height Image height.
- */
-Viewport.prototype.setImageSize = function(width, height) {
- this.imageBounds_ = new Rect(width, height);
- if (this.scaleControl_) this.scaleControl_.displayImageSize(width, height);
- this.invalidateCaches();
-};
-
-/**
- * @param {number} width Screen width.
- * @param {number} height Screen height.
- */
-Viewport.prototype.setScreenSize = function(width, height) {
- this.screenBounds_ = new Rect(width, height);
- if (this.scaleControl_)
- this.scaleControl_.setMinScale(this.getFittingScale());
- this.invalidateCaches();
-};
-
-/**
- * Set the size by an HTML element.
- *
- * @param {HTMLElement} frame The element acting as the "screen".
- */
-Viewport.prototype.sizeByFrame = function(frame) {
- this.setScreenSize(frame.clientWidth, frame.clientHeight);
-};
-
-/**
- * Set the size and scale to fit an HTML element.
- *
- * @param {HTMLElement} frame The element acting as the "screen".
- */
-Viewport.prototype.sizeByFrameAndFit = function(frame) {
- var wasFitting = this.getScale() == this.getFittingScale();
- this.sizeByFrame(frame);
- var minScale = this.getFittingScale();
- if (wasFitting || (this.getScale() < minScale)) {
- this.setScale(minScale, true);
- }
-};
-
-/**
- * @return {number} Scale.
- */
-Viewport.prototype.getScale = function() { return this.scale_ };
-
-/**
- * @param {number} scale The new scale.
- * @param {boolean} notify True if the change should be reflected in the UI.
- */
-Viewport.prototype.setScale = function(scale, notify) {
- if (this.scale_ == scale) return;
- this.scale_ = scale;
- if (notify && this.scaleControl_) this.scaleControl_.displayScale(scale);
- this.invalidateCaches();
-};
-
-/**
- * @return {number} Best scale to fit the current image into the current screen.
- */
-Viewport.prototype.getFittingScale = function() {
- var scaleX = this.screenBounds_.width / this.imageBounds_.width;
- var scaleY = this.screenBounds_.height / this.imageBounds_.height;
- // Scales > (1 / this.getDevicePixelRatio()) do not look good. Also they are
- // not really useful as we do not have any pixel-level operations.
- return Math.min(1 / Viewport.getDevicePixelRatio(), scaleX, scaleY);
-};
-
-/**
- * Set the scale to fit the image into the screen.
- */
-Viewport.prototype.fitImage = function() {
- var scale = this.getFittingScale();
- if (this.scaleControl_) this.scaleControl_.setMinScale(scale);
- this.setScale(scale, true);
-};
-
-/**
- * @return {number} X-offset of the viewport.
- */
-Viewport.prototype.getOffsetX = function() { return this.offsetX_ };
-
-/**
- * @return {number} Y-offset of the viewport.
- */
-Viewport.prototype.getOffsetY = function() { return this.offsetY_ };
-
-/**
- * Set the image offset in the viewport.
- * @param {number} x X-offset.
- * @param {number} y Y-offset.
- * @param {boolean} ignoreClipping True if no clipping should be applied.
- */
-Viewport.prototype.setOffset = function(x, y, ignoreClipping) {
- if (!ignoreClipping) {
- x = this.clampOffsetX_(x);
- y = this.clampOffsetY_(y);
- }
- if (this.offsetX_ == x && this.offsetY_ == y) return;
- this.offsetX_ = x;
- this.offsetY_ = y;
- this.invalidateCaches();
-};
-
-/**
- * Return a closure that can be called to pan the image.
- * Useful for implementing non-trivial variants of panning (overview etc).
- * @param {number} originalX The x coordinate on the screen canvas that
- * corresponds to zero change to offsetX.
- * @param {number} originalY The y coordinate on the screen canvas that
- * corresponds to zero change to offsetY.
- * @param {function():number} scaleFunc returns the image to screen scale.
- * @param {function(number,number):boolean} hitFunc returns true if (x,y) is
- * in the valid region.
- * @return {function} The closure to pan the image.
- */
-Viewport.prototype.createOffsetSetter = function(
- originalX, originalY, scaleFunc, hitFunc) {
- var originalOffsetX = this.offsetX_;
- var originalOffsetY = this.offsetY_;
- if (!hitFunc) hitFunc = function() { return true };
- if (!scaleFunc) scaleFunc = this.getScale.bind(this);
-
- var self = this;
- return function(x, y) {
- if (hitFunc(x, y)) {
- var scale = scaleFunc();
- self.setOffset(
- originalOffsetX + (x - originalX) / scale,
- originalOffsetY + (y - originalY) / scale);
- self.repaint();
- }
- };
-};
-
-/*
- * Access to the current viewport state.
- */
-
-/**
- * @return {Rect} The image bounds in image coordinates.
- */
-Viewport.prototype.getImageBounds = function() { return this.imageBounds_ };
-
-/**
-* @return {Rect} The screen bounds in screen coordinates.
-*/
-Viewport.prototype.getScreenBounds = function() { return this.screenBounds_ };
-
-/**
- * @return {Rect} The visible part of the image, in image coordinates.
- */
-Viewport.prototype.getImageClipped = function() { return this.imageClipped_ };
-
-/**
- * @return {Rect} The visible part of the image, in screen coordinates.
- */
-Viewport.prototype.getScreenClipped = function() { return this.screenClipped_ };
-
-/**
- * A counter that is incremented with each viewport state change.
- * Clients that cache anything that depends on the viewport state should keep
- * track of this counter.
- * @return {number} counter.
- */
-Viewport.prototype.getCacheGeneration = function() { return this.generation_ };
-
-/**
- * Called on event view port state change (even if repaint has not been called).
- */
-Viewport.prototype.invalidateCaches = function() { this.generation_++ };
-
-/**
- * @return {Rect} The image bounds in screen coordinates.
- */
-Viewport.prototype.getImageBoundsOnScreen = function() {
- return this.imageOnScreen_;
-};
-
-/*
- * Conversion between the screen and image coordinate spaces.
- */
-
-/**
- * @param {number} size Size in screen coordinates.
- * @return {number} Size in image coordinates.
- */
-Viewport.prototype.screenToImageSize = function(size) {
- return size / this.getScale();
-};
-
-/**
- * @param {number} x X in screen coordinates.
- * @return {number} X in image coordinates.
- */
-Viewport.prototype.screenToImageX = function(x) {
- return Math.round((x - this.imageOnScreen_.left) / this.getScale());
-};
-
-/**
- * @param {number} y Y in screen coordinates.
- * @return {number} Y in image coordinates.
- */
-Viewport.prototype.screenToImageY = function(y) {
- return Math.round((y - this.imageOnScreen_.top) / this.getScale());
-};
-
-/**
- * @param {Rect} rect Rectangle in screen coordinates.
- * @return {Rect} Rectangle in image coordinates.
- */
-Viewport.prototype.screenToImageRect = function(rect) {
- return new Rect(
- this.screenToImageX(rect.left),
- this.screenToImageY(rect.top),
- this.screenToImageSize(rect.width),
- this.screenToImageSize(rect.height));
-};
-
-/**
- * @param {number} size Size in image coordinates.
- * @return {number} Size in screen coordinates.
- */
-Viewport.prototype.imageToScreenSize = function(size) {
- return size * this.getScale();
-};
-
-/**
- * @param {number} x X in image coordinates.
- * @return {number} X in screen coordinates.
- */
-Viewport.prototype.imageToScreenX = function(x) {
- return Math.round(this.imageOnScreen_.left + x * this.getScale());
-};
-
-/**
- * @param {number} y Y in image coordinates.
- * @return {number} Y in screen coordinates.
- */
-Viewport.prototype.imageToScreenY = function(y) {
- return Math.round(this.imageOnScreen_.top + y * this.getScale());
-};
-
-/**
- * @param {Rect} rect Rectangle in image coordinates.
- * @return {Rect} Rectangle in screen coordinates.
- */
-Viewport.prototype.imageToScreenRect = function(rect) {
- return new Rect(
- this.imageToScreenX(rect.left),
- this.imageToScreenY(rect.top),
- Math.round(this.imageToScreenSize(rect.width)),
- Math.round(this.imageToScreenSize(rect.height)));
-};
-
-/**
- * @return {number} The number of physical pixels in one CSS pixel.
- */
-Viewport.getDevicePixelRatio = function() { return window.devicePixelRatio };
-
-/**
- * Convert a rectangle from screen coordinates to 'device' coordinates.
- *
- * This conversion enlarges the original rectangle devicePixelRatio times
- * with the screen center as a fixed point.
- *
- * @param {Rect} rect Rectangle in screen coordinates.
- * @return {Rect} Rectangle in device coordinates.
- */
-Viewport.prototype.screenToDeviceRect = function(rect) {
- var ratio = Viewport.getDevicePixelRatio();
- var screenCenterX = Math.round(
- this.screenBounds_.left + this.screenBounds_.width / 2);
- var screenCenterY = Math.round(
- this.screenBounds_.top + this.screenBounds_.height / 2);
- return new Rect(screenCenterX + (rect.left - screenCenterX) * ratio,
- screenCenterY + (rect.top - screenCenterY) * ratio,
- rect.width * ratio,
- rect.height * ratio);
-};
-
-/**
- * @return {Rect} The visible part of the image, in device coordinates.
- */
-Viewport.prototype.getDeviceClipped = function() {
- return this.screenToDeviceRect(this.getScreenClipped());
-};
-
-/**
- * @return {boolean} True if some part of the image is clipped by the screen.
- */
-Viewport.prototype.isClipped = function() {
- return this.getMarginX_() < 0 || this.getMarginY_() < 0;
-};
-
-/**
- * @return {number} Horizontal margin.
- * Negative if the image is clipped horizontally.
- * @private
- */
-Viewport.prototype.getMarginX_ = function() {
- return Math.round(
- (this.screenBounds_.width - this.imageBounds_.width * this.scale_) / 2);
-};
-
-/**
- * @return {number} Vertical margin.
- * Negative if the image is clipped vertically.
- * @private
- */
-Viewport.prototype.getMarginY_ = function() {
- return Math.round(
- (this.screenBounds_.height - this.imageBounds_.height * this.scale_) / 2);
-};
-
-/**
- * @param {number} x X-offset.
- * @return {number} X-offset clamped to the valid range.
- * @private
- */
-Viewport.prototype.clampOffsetX_ = function(x) {
- var limit = Math.round(Math.max(0, -this.getMarginX_() / this.getScale()));
- return ImageUtil.clamp(-limit, x, limit);
-};
-
-/**
- * @param {number} y Y-offset.
- * @return {number} Y-offset clamped to the valid range.
- * @private
- */
-Viewport.prototype.clampOffsetY_ = function(y) {
- var limit = Math.round(Math.max(0, -this.getMarginY_() / this.getScale()));
- return ImageUtil.clamp(-limit, y, limit);
-};
-
-/**
- * Recalculate the viewport parameters.
- */
-Viewport.prototype.update = function() {
- var scale = this.getScale();
-
- // Image bounds in screen coordinates.
- this.imageOnScreen_ = new Rect(
- this.getMarginX_(),
- this.getMarginY_(),
- Math.round(this.imageBounds_.width * scale),
- Math.round(this.imageBounds_.height * scale));
-
- // A visible part of the image in image coordinates.
- this.imageClipped_ = new Rect(this.imageBounds_);
-
- // A visible part of the image in screen coordinates.
- this.screenClipped_ = new Rect(this.screenBounds_);
-
- // Adjust for the offset.
- if (this.imageOnScreen_.left < 0) {
- this.imageOnScreen_.left +=
- Math.round(this.clampOffsetX_(this.offsetX_) * scale);
- this.imageClipped_.left = Math.round(-this.imageOnScreen_.left / scale);
- this.imageClipped_.width = Math.round(this.screenBounds_.width / scale);
- } else {
- this.screenClipped_.left = this.imageOnScreen_.left;
- this.screenClipped_.width = this.imageOnScreen_.width;
- }
-
- if (this.imageOnScreen_.top < 0) {
- this.imageOnScreen_.top +=
- Math.round(this.clampOffsetY_(this.offsetY_) * scale);
- this.imageClipped_.top = Math.round(-this.imageOnScreen_.top / scale);
- this.imageClipped_.height = Math.round(this.screenBounds_.height / scale);
- } else {
- this.screenClipped_.top = this.imageOnScreen_.top;
- this.screenClipped_.height = this.imageOnScreen_.height;
- }
-};
-
-/**
- * @param {function} callback Repaint callback.
- */
-Viewport.prototype.addRepaintCallback = function(callback) {
- this.repaintCallbacks_.push(callback);
-};
-
-/**
- * Repaint all clients.
- */
-Viewport.prototype.repaint = function() {
- this.update();
- for (var i = 0; i != this.repaintCallbacks_.length; i++)
- this.repaintCallbacks_[i]();
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/main.js b/chromium/chrome/browser/resources/file_manager/foreground/js/main.js
deleted file mode 100644
index f32c0a1ef47..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/main.js
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * @type {FileManager}
- */
-var fileManager;
-
-/**
- * Indicates if the DOM and scripts have been already loaded.
- * @type {boolean}
- */
-var pageLoaded = false;
-
-/**
- * Kick off the file manager dialog.
- * Called by main.html after the DOM has been parsed.
- */
-function init() {
- // Initializes UI and starts the File Manager dialog.
- fileManager.initializeUI(document.body, function() {
- chrome.test.sendMessage('ready');
- metrics.recordInterval('Load.Total');
- });
-}
-
-// Create the File Manager object. Note, that the DOM, nor any external
-// scripts may not be ready yet.
-fileManager = new FileManager();
-
-// Initialize the core stuff, which doesn't require access to DOM nor to
-// additional scripts.
-fileManager.initializeCore();
-
-// Final initialization is performed after all scripts and Dom is loaded.
-util.addPageLoadHandler(init);
-
-metrics.recordInterval('Load.Script'); // Must be the last line.
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/main_scripts.js b/chromium/chrome/browser/resources/file_manager/foreground/js/main_scripts.js
deleted file mode 100644
index 768d35ce8fd..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/main_scripts.js
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// The include directives are put into Javascript-style comments to prevent
-// parsing errors in non-flattened mode. The flattener still sees them.
-// Note that this makes the flattener to comment out the first line of the
-// included file but that's all right since any javascript file should start
-// with a copyright comment anyway.
-
-// If you add a new dependency, you should update build files by rerunning
-// gyp. Otherwise, you'll be bitten by a dependency issue like:
-//
-// 1) You add a new dependency to "whatever.js"
-// 2) You make changes in "whatever.js"
-// 3) Rebuild "resources.pak" and open Files.app
-// 4) You don't see the changes in "whatever.js". Why is that?
-//
-// Because the dependencies are computed at gyp time, the existing build
-// files don't know that "resources.pak" now has a dependency to
-// "whatever.js". You should rerun gyp to let the build files know.
-//
-// //metrics.js initiates load performance tracking
-// //so we want to parse it as early as possible.
-//<include src="metrics.js"/>
-//
-//<include src="../../../image_loader/image_loader_client.js"/>
-//
-//<include src="../../../../../../ui/webui/resources/js/load_time_data.js"/>
-//<include src="../../../../../../ui/webui/resources/js/cr.js"/>
-//<include src="../../../../../../ui/webui/resources/js/util.js"/>
-//<include src="../../../../../../ui/webui/resources/js/i18n_template_no_process.js"/>
-//
-//<include src="../../../../../../ui/webui/resources/js/event_tracker.js"/>
-//<include src="../../../../../../ui/webui/resources/js/cr/ui.js"/>
-//<include src="../../../../../../ui/webui/resources/js/cr/event_target.js"/>
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/touch_handler.js"/>
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/array_data_model.js"/>
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/dialogs.js"/>
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/list_item.js"/>
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/list_selection_model.js"/>
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/list_single_selection_model.js"/>
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/list_selection_controller.js"/>
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/list.js"/>
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/tree.js"/>
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/autocomplete_list.js"/>
-//
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/splitter.js"/>
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/table/table_splitter.js"/>
-//
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/table/table_column.js"/>
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/table/table_column_model.js"/>
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/table/table_header.js"/>
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/table/table_list.js"/>
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/table.js"/>
-//
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/grid.js"/>
-//
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/command.js"/>
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/position_util.js"/>
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/menu_item.js"/>
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/menu.js"/>
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/menu_button.js"/>
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/context_menu_handler.js"/>
-
-(function() {
-// 'strict mode' is invoked for this scope.
-
-// // This script must be loaded before all other Files.app's scripts.
-//<include src="error_counter.js"/>
-//
-//<include src="../../common/js/async_util.js"/>
-//<include src="../../common/js/path_util.js"/>
-//<include src="../../common/js/util.js"/>
-//<include src="../../common/js/progress_center_common.js">
-//
-//<include src="combobutton.js"/>
-//<include src="commandbutton.js"/>
-//<include src="ui/file_manager_dialog_base.js"/>
-//
-//<include src="app_installer.js"/>
-//<include src="cws_container_client.js"/>
-//<include src="directory_contents.js"/>
-//<include src="directory_model.js"/>
-//<include src="directory_tree.js"/>
-//<include src="drag_selector.js"/>
-//<include src="drive_banners.js" />
-//<include src="error_dialog.js"/>
-//<include src="file_operation_manager_wrapper.js"/>
-//<include src="file_grid.js"/>
-//<include src="file_manager.js"/>
-//<include src="file_selection.js"/>
-//<include src="file_table.js"/>
-//<include src="file_tasks.js"/>
-//<include src="file_transfer_controller.js"/>
-//<include src="file_type.js"/>
-//<include src="file_watcher.js"/>
-//<include src="folder_shortcuts_data_model.js"/>
-//<include src="navigation_list_model.js"/>
-//<include src="scrollbar.js"/>
-//<include src="share_client.js"/>
-//<include src="share_dialog.js"/>
-//<include src="suggest_apps_dialog.js"/>
-//<include src="text_measure.js"/>
-//<include src="tree.css.js"/>
-//<include src="ui/breadcrumbs_controller.js"/>
-//<include src="ui/conflict_dialog.js"/>
-//<include src="ui/file_manager_ui.js"/>
-//<include src="ui/navigation_list.js"/>
-//<include src="ui/preview_panel.js"/>
-//<include src="ui/progress_center_panel.js"/>
-//<include src="ui/search_box.js"/>
-//<include src="volume_manager_wrapper.js"/>
-//<include src="media/media_util.js"/>
-//<include src="metadata/metadata_cache.js"/>
-//<include src="default_action_dialog.js"/>
-//<include src="file_manager_commands.js"/>
-
-// // For accurate load performance tracking place main.js should be
-// // the last include to include.
-//<include src="main.js"/>
-
-// Global fileManager reference useful for poking at from the console.
-window.fileManager = fileManager;
-
-// Exports
-window.util = util;
-window.FileOperationManagerWrapper = FileOperationManagerWrapper;
-
-window.unload = unload;
-
-})();
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/media/audio_player.js b/chromium/chrome/browser/resources/file_manager/foreground/js/media/audio_player.js
deleted file mode 100644
index 4791c31f92b..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/media/audio_player.js
+++ /dev/null
@@ -1,628 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * TODO(mtomasz): Rewrite the entire audio player.
- *
- * @param {HTMLElement} container Container element.
- * @constructor
- */
-function AudioPlayer(container) {
- this.container_ = container;
- this.metadataCache_ = MetadataCache.createFull();
- this.currentTrack_ = -1;
- this.playlistGeneration_ = 0;
- this.selectedEntry_ = null;
- this.volumeManager_ = new VolumeManagerWrapper(
- VolumeManagerWrapper.DriveEnabledStatus.DRIVE_ENABLED);
-
- this.container_.classList.add('collapsed');
-
- function createChild(opt_className, opt_tag) {
- var child = container.ownerDocument.createElement(opt_tag || 'div');
- if (opt_className)
- child.className = opt_className;
- container.appendChild(child);
- return child;
- }
-
- // We create two separate containers (for expanded and compact view) and keep
- // two sets of TrackInfo instances. We could fiddle with a single set instead
- // but it would make keeping the list scroll position very tricky.
- this.trackList_ = createChild('track-list');
- this.trackStack_ = createChild('track-stack');
-
- createChild('title-button collapse').addEventListener(
- 'click', this.onExpandCollapse_.bind(this));
-
- this.audioControls_ = new FullWindowAudioControls(
- createChild(), this.advance_.bind(this), this.onError_.bind(this));
-
- this.audioControls_.attachMedia(createChild('', 'audio'));
-
- chrome.fileBrowserPrivate.getStrings(function(strings) {
- container.ownerDocument.title = strings['AUDIO_PLAYER_TITLE'];
- this.errorString_ = strings['AUDIO_ERROR'];
- this.offlineString_ = strings['AUDIO_OFFLINE'];
- AudioPlayer.TrackInfo.DEFAULT_ARTIST =
- strings['AUDIO_PLAYER_DEFAULT_ARTIST'];
- }.bind(this));
-
- this.volumeManager_.addEventListener('externally-unmounted',
- this.onExternallyUnmounted_.bind(this));
-
- window.addEventListener('resize', this.onResize_.bind(this));
-
- // Show the window after DOM is processed.
- var currentWindow = chrome.app.window.current();
- setTimeout(currentWindow.show.bind(currentWindow), 0);
-}
-
-/**
- * Initial load method (static).
- */
-AudioPlayer.load = function() {
- document.ondragstart = function(e) { e.preventDefault() };
-
- // TODO(mtomasz): Consider providing an exact size icon, instead of relying
- // on downsampling by ash.
- chrome.app.window.current().setIcon(
- 'foreground/images/media/2x/audio_player.png');
-
- AudioPlayer.instance =
- new AudioPlayer(document.querySelector('.audio-player'));
- reload();
-};
-
-util.addPageLoadHandler(AudioPlayer.load);
-
-/**
- * Unload the player.
- */
-function unload() {
- if (AudioPlayer.instance)
- AudioPlayer.instance.onUnload();
-}
-
-/**
- * Reload the player.
- */
-function reload() {
- if (window.appState) {
- util.saveAppState();
- AudioPlayer.instance.load(window.appState);
- return;
- }
-}
-
-/**
- * Load a new playlist.
- * @param {Playlist} playlist Playlist object passed via mediaPlayerPrivate.
- */
-AudioPlayer.prototype.load = function(playlist) {
- this.playlistGeneration_++;
- this.audioControls_.pause();
- this.currentTrack_ = -1;
-
- // Save the app state, in case of restart.
- window.appState = playlist;
- util.saveAppState();
-
- util.URLsToEntries(playlist.items, function(entries) {
- this.entries_ = entries;
- this.invalidTracks_ = {};
- this.cancelAutoAdvance_();
-
- if (this.entries_.length <= 1)
- this.container_.classList.add('single-track');
- else
- this.container_.classList.remove('single-track');
-
- this.syncHeight_();
-
- this.trackList_.textContent = '';
- this.trackStack_.textContent = '';
-
- this.trackListItems_ = [];
- this.trackStackItems_ = [];
-
- if (this.entries_.length == 0)
- return;
-
- for (var i = 0; i != this.entries_.length; i++) {
- var entry = this.entries_[i];
- var onClick = this.select_.bind(this, i, false /* no restore */);
- this.trackListItems_.push(
- new AudioPlayer.TrackInfo(this.trackList_, entry, onClick));
- this.trackStackItems_.push(
- new AudioPlayer.TrackInfo(this.trackStack_, entry, onClick));
- }
-
- this.select_(playlist.position, !!playlist.time);
-
- // This class will be removed if at least one track has art.
- this.container_.classList.add('noart');
-
- // Load the selected track metadata first, then load the rest.
- this.loadMetadata_(playlist.position);
- for (i = 0; i != this.entries_.length; i++) {
- if (i != playlist.position)
- this.loadMetadata_(i);
- }
- }.bind(this));
-};
-
-/**
- * Load metadata for a track.
- * @param {number} track Track number.
- * @private
- */
-AudioPlayer.prototype.loadMetadata_ = function(track) {
- this.fetchMetadata_(
- this.entries_[track], this.displayMetadata_.bind(this, track));
-};
-
-/**
- * Display track's metadata.
- * @param {number} track Track number.
- * @param {Object} metadata Metadata object.
- * @param {string=} opt_error Error message.
- * @private
- */
-AudioPlayer.prototype.displayMetadata_ = function(track, metadata, opt_error) {
- this.trackListItems_[track].
- setMetadata(metadata, this.container_, opt_error);
- this.trackStackItems_[track].
- setMetadata(metadata, this.container_, opt_error);
-};
-
-/**
- * Closes audio player when a volume containing the selected item is unmounted.
- * @param {Event} event The unmount event.
- * @private
- */
-AudioPlayer.prototype.onExternallyUnmounted_ = function(event) {
- if (!this.selectedEntry_)
- return;
-
- if (this.volumeManager_.getVolumeInfo(this.selectedEntry_) ===
- event.volumeInfo) {
- window.close();
- }
-};
-
-/**
- * Called on window is being unloaded.
- */
-AudioPlayer.prototype.onUnload = function() {
- this.audioControls_.cleanup();
- this.volumeManager_.dispose();
-};
-
-/**
- * Select a new track to play.
- * @param {number} newTrack New track number.
- * @param {boolean=} opt_restoreState True if restoring the play state from URL.
- * @private
- */
-AudioPlayer.prototype.select_ = function(newTrack, opt_restoreState) {
- if (this.currentTrack_ == newTrack) return;
-
- this.changeSelectionInList_(this.currentTrack_, newTrack);
- this.changeSelectionInStack_(this.currentTrack_, newTrack);
-
- this.currentTrack_ = newTrack;
-
- if (window.appState) {
- window.appState.position = this.currentTrack_;
- window.appState.time = 0;
- util.saveAppState();
- } else {
- util.platform.setPreference(AudioPlayer.TRACK_KEY, this.currentTrack_);
- }
-
- this.scrollToCurrent_(false);
-
- var currentTrack = this.currentTrack_;
- var entry = this.entries_[currentTrack];
- this.fetchMetadata_(entry, function(metadata) {
- if (this.currentTrack_ != currentTrack)
- return;
- this.audioControls_.load(entry, opt_restoreState);
-
- // Resolve real filesystem path of the current audio file.
- this.selectedEntry_ = entry;
- }.bind(this));
-};
-
-/**
- * @param {Entry} entry Track file entry.
- * @param {function(object)} callback Callback.
- * @private
- */
-AudioPlayer.prototype.fetchMetadata_ = function(entry, callback) {
- this.metadataCache_.get(entry, 'thumbnail|media|streaming',
- function(generation, metadata) {
- // Do nothing if another load happened since the metadata request.
- if (this.playlistGeneration_ == generation)
- callback(metadata);
- }.bind(this, this.playlistGeneration_));
-};
-
-/**
- * @param {number} oldTrack Old track number.
- * @param {number} newTrack New track number.
- * @private
- */
-AudioPlayer.prototype.changeSelectionInList_ = function(oldTrack, newTrack) {
- this.trackListItems_[newTrack].getBox().classList.add('selected');
-
- if (oldTrack >= 0) {
- this.trackListItems_[oldTrack].getBox().classList.remove('selected');
- }
-};
-
-/**
- * @param {number} oldTrack Old track number.
- * @param {number} newTrack New track number.
- * @private
- */
-AudioPlayer.prototype.changeSelectionInStack_ = function(oldTrack, newTrack) {
- var newBox = this.trackStackItems_[newTrack].getBox();
- newBox.classList.add('selected'); // Put on top immediately.
- newBox.classList.add('visible'); // Start fading in.
-
- if (oldTrack >= 0) {
- var oldBox = this.trackStackItems_[oldTrack].getBox();
- oldBox.classList.remove('selected'); // Put under immediately.
- setTimeout(function() {
- if (!oldBox.classList.contains('selected')) {
- // This will start fading out which is not really necessary because
- // oldBox is already completely obscured by newBox.
- oldBox.classList.remove('visible');
- }
- }, 300);
- }
-};
-
-/**
- * Scrolls the current track into the viewport.
- *
- * @param {boolean} keepAtBottom If true, make the selected track the last
- * of the visible (if possible). If false, perform minimal scrolling.
- * @private
- */
-AudioPlayer.prototype.scrollToCurrent_ = function(keepAtBottom) {
- var box = this.trackListItems_[this.currentTrack_].getBox();
- this.trackList_.scrollTop = Math.max(
- keepAtBottom ? 0 : Math.min(box.offsetTop, this.trackList_.scrollTop),
- box.offsetTop + box.offsetHeight - this.trackList_.clientHeight);
-};
-
-/**
- * @return {boolean} True if the player is be displayed in compact mode.
- * @private
- */
-AudioPlayer.prototype.isCompact_ = function() {
- return this.container_.classList.contains('collapsed') ||
- this.container_.classList.contains('single-track');
-};
-
-/**
- * Go to the previous or the next track.
- * @param {boolean} forward True if next, false if previous.
- * @param {boolean=} opt_onlyIfValid True if invalid tracks should be selected.
- * @private
- */
-AudioPlayer.prototype.advance_ = function(forward, opt_onlyIfValid) {
- this.cancelAutoAdvance_();
-
- var newTrack = this.currentTrack_ + (forward ? 1 : -1);
- if (newTrack < 0) newTrack = this.entries_.length - 1;
- if (newTrack == this.entries_.length) newTrack = 0;
- if (opt_onlyIfValid && this.invalidTracks_[newTrack])
- return;
- this.select_(newTrack);
-};
-
-/**
- * Media error handler.
- * @private
- */
-AudioPlayer.prototype.onError_ = function() {
- var track = this.currentTrack_;
-
- this.invalidTracks_[track] = true;
-
- this.fetchMetadata_(
- this.entries_[track],
- function(metadata) {
- var error = (!navigator.onLine && metadata.streaming) ?
- this.offlineString_ : this.errorString_;
- this.displayMetadata_(track, metadata, error);
- this.scheduleAutoAdvance_();
- }.bind(this));
-};
-
-/**
- * Schedule automatic advance to the next track after a timeout.
- * @private
- */
-AudioPlayer.prototype.scheduleAutoAdvance_ = function() {
- this.cancelAutoAdvance_();
- this.autoAdvanceTimer_ = setTimeout(
- function() {
- this.autoAdvanceTimer_ = null;
- // We are advancing only if the next track is not known to be invalid.
- // This prevents an endless auto-advancing in the case when all tracks
- // are invalid (we will only visit each track once).
- this.advance_(true /* forward */, true /* only if valid */);
- }.bind(this),
- 3000);
-};
-
-/**
- * Cancel the scheduled auto advance.
- * @private
- */
-AudioPlayer.prototype.cancelAutoAdvance_ = function() {
- if (this.autoAdvanceTimer_) {
- clearTimeout(this.autoAdvanceTimer_);
- this.autoAdvanceTimer_ = null;
- }
-};
-
-/**
- * Expand/collapse button click handler. Toggles the mode and updates the
- * height of the window.
- *
- * @private
- */
-AudioPlayer.prototype.onExpandCollapse_ = function() {
- if (!this.isCompact_()) {
- this.setExpanded_(false);
- this.lastExpandedHeight_ = window.innerHeight;
- } else {
- this.setExpanded_(true);
- }
- this.syncHeight_();
-};
-
-/**
- * Toggles the current expand mode.
- *
- * @param {boolean} on True if on, false otherwise.
- * @private
- */
-AudioPlayer.prototype.setExpanded_ = function(on) {
- if (on) {
- this.container_.classList.remove('collapsed');
- this.scrollToCurrent_(true);
- } else {
- this.container_.classList.add('collapsed');
- }
-};
-
-/**
- * Toggles the expanded mode when resizing.
- *
- * @param {Event} event Resize event.
- * @private
- */
-AudioPlayer.prototype.onResize_ = function(event) {
- if (this.isCompact_() &&
- window.innerHeight >= AudioPlayer.EXPANDED_MODE_MIN_HEIGHT) {
- this.setExpanded_(true);
- } else if (!this.isCompact_() &&
- window.innerHeight < AudioPlayer.EXPANDED_MODE_MIN_HEIGHT) {
- this.setExpanded_(false);
- }
-};
-
-/* Keep the below constants in sync with the CSS. */
-
-/**
- * Window header size in pixels.
- * @type {number}
- * @const
- */
-AudioPlayer.HEADER_HEIGHT = 28;
-
-/**
- * Track height in pixels.
- * @type {number}
- * @const
- */
-AudioPlayer.TRACK_HEIGHT = 58;
-
-/**
- * Controls bar height in pixels.
- * @type {number}
- * @const
- */
-AudioPlayer.CONTROLS_HEIGHT = 35;
-
-/**
- * Default number of items in the expanded mode.
- * @type {number}
- * @const
- */
-AudioPlayer.DEFAULT_EXPANDED_ITEMS = 5;
-
-/**
- * Minimum size of the window in the expanded mode in pixels.
- * @type {number}
- * @const
- */
-AudioPlayer.EXPANDED_MODE_MIN_HEIGHT = AudioPlayer.CONTROLS_HEIGHT +
- AudioPlayer.TRACK_HEIGHT * 2;
-
-/**
- * Set the correct player window height.
- * @private
- */
-AudioPlayer.prototype.syncHeight_ = function() {
- var targetHeight;
-
- if (!this.isCompact_()) {
- // Expanded.
- if (this.lastExpandedHeight_) {
- targetHeight = this.lastExpandedHeight_;
- } else {
- var expandedListHeight =
- Math.min(this.entries_.length, AudioPlayer.DEFAULT_EXPANDED_ITEMS) *
- AudioPlayer.TRACK_HEIGHT;
- targetHeight = AudioPlayer.CONTROLS_HEIGHT + expandedListHeight;
- }
- } else {
- // Not expaned.
- targetHeight = AudioPlayer.CONTROLS_HEIGHT + AudioPlayer.TRACK_HEIGHT;
- }
-
- window.resizeTo(window.innerWidth, targetHeight + AudioPlayer.HEADER_HEIGHT);
-};
-
-/**
- * Create a TrackInfo object encapsulating the information about one track.
- *
- * @param {HTMLElement} container Container element.
- * @param {Entry} entry Track entry.
- * @param {function} onClick Click handler.
- * @constructor
- */
-AudioPlayer.TrackInfo = function(container, entry, onClick) {
- this.entry_ = entry;
-
- var doc = container.ownerDocument;
-
- this.box_ = doc.createElement('div');
- this.box_.className = 'track';
- this.box_.addEventListener('click', onClick);
- container.appendChild(this.box_);
-
- this.art_ = doc.createElement('div');
- this.art_.className = 'art blank';
- this.box_.appendChild(this.art_);
-
- this.img_ = doc.createElement('img');
- this.art_.appendChild(this.img_);
-
- this.data_ = doc.createElement('div');
- this.data_.className = 'data';
- this.box_.appendChild(this.data_);
-
- this.title_ = doc.createElement('div');
- this.title_.className = 'data-title';
- this.data_.appendChild(this.title_);
-
- this.artist_ = doc.createElement('div');
- this.artist_.className = 'data-artist';
- this.data_.appendChild(this.artist_);
-};
-
-/**
- * @return {HTMLDivElement} The wrapper element for the track.
- */
-AudioPlayer.TrackInfo.prototype.getBox = function() { return this.box_ };
-
-/**
- * @return {string} Default track title (file name extracted from the entry).
- */
-AudioPlayer.TrackInfo.prototype.getDefaultTitle = function() {
- // TODO(mtomasz): Reuse ImageUtil.getDisplayNameFromName().
- var name = this.entry_.name;
- var dotIndex = name.lastIndexOf('.');
- var title = dotIndex >= 0 ? name.substr(0, dotIndex) : name;
- return title;
-};
-
-/**
- * TODO(kaznacheev): Localize.
- */
-AudioPlayer.TrackInfo.DEFAULT_ARTIST = 'Unknown Artist';
-
-/**
- * @return {string} 'Unknown artist' string.
- */
-AudioPlayer.TrackInfo.prototype.getDefaultArtist = function() {
- return AudioPlayer.TrackInfo.DEFAULT_ARTIST;
-};
-
-/**
- * @param {Object} metadata The metadata object.
- * @param {HTMLElement} container The container for the tracks.
- * @param {string} error Error string.
- */
-AudioPlayer.TrackInfo.prototype.setMetadata = function(
- metadata, container, error) {
- if (error) {
- this.art_.classList.add('blank');
- this.art_.classList.add('error');
- container.classList.remove('noart');
- } else if (metadata.thumbnail && metadata.thumbnail.url) {
- this.img_.onload = function() {
- // Only display the image if the thumbnail loaded successfully.
- this.art_.classList.remove('blank');
- container.classList.remove('noart');
- }.bind(this);
- this.img_.src = metadata.thumbnail.url;
- }
- this.title_.textContent = (metadata.media && metadata.media.title) ||
- this.getDefaultTitle();
- this.artist_.textContent = error ||
- (metadata.media && metadata.media.artist) || this.getDefaultArtist();
-};
-
-/**
- * Audio controls specific for the Audio Player.
- *
- * @param {HTMLElement} container Parent container.
- * @param {function(boolean)} advanceTrack Parameter: true=forward.
- * @param {function} onError Error handler.
- * @constructor
- */
-function FullWindowAudioControls(container, advanceTrack, onError) {
- AudioControls.apply(this, arguments);
-
- document.addEventListener('keydown', function(e) {
- if (e.keyIdentifier == 'U+0020') {
- this.togglePlayState();
- e.preventDefault();
- }
- }.bind(this));
-}
-
-FullWindowAudioControls.prototype = { __proto__: AudioControls.prototype };
-
-/**
- * Enable play state restore from the location hash.
- * @param {FileEntry} entry Source Entry.
- * @param {boolean} restore True if need to restore the play state.
- */
-FullWindowAudioControls.prototype.load = function(entry, restore) {
- this.media_.src = entry.toURL();
- this.media_.load();
- this.restoreWhenLoaded_ = restore;
-};
-
-/**
- * Save the current state so that it survives page/app reload.
- */
-FullWindowAudioControls.prototype.onPlayStateChanged = function() {
- this.encodeState();
-};
-
-/**
- * Restore the state after page/app reload.
- */
-FullWindowAudioControls.prototype.restorePlayState = function() {
- if (this.restoreWhenLoaded_) {
- this.restoreWhenLoaded_ = false; // This should only work once.
- if (this.decodeState())
- return;
- }
- this.play();
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/media/media_controls.js b/chromium/chrome/browser/resources/file_manager/foreground/js/media/media_controls.js
deleted file mode 100644
index a335bdc4c52..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/media/media_controls.js
+++ /dev/null
@@ -1,1245 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * @fileoverview MediaControls class implements media playback controls
- * that exist outside of the audio/video HTML element.
- */
-
-/**
- * @param {HTMLElement} containerElement The container for the controls.
- * @param {function} onMediaError Function to display an error message.
- * @constructor
- */
-function MediaControls(containerElement, onMediaError) {
- this.container_ = containerElement;
- this.document_ = this.container_.ownerDocument;
- this.media_ = null;
-
- this.onMediaPlayBound_ = this.onMediaPlay_.bind(this, true);
- this.onMediaPauseBound_ = this.onMediaPlay_.bind(this, false);
- this.onMediaDurationBound_ = this.onMediaDuration_.bind(this);
- this.onMediaProgressBound_ = this.onMediaProgress_.bind(this);
- this.onMediaError_ = onMediaError || function() {};
-}
-
-/**
- * Button's state types. Values are used as CSS class names.
- * @enum {string}
- */
-MediaControls.ButtonStateType = {
- DEFAULT: 'default',
- PLAYING: 'playing',
- ENDED: 'ended'
-};
-
-/**
- * @return {HTMLAudioElement|HTMLVideoElement} The media element.
- */
-MediaControls.prototype.getMedia = function() { return this.media_ };
-
-/**
- * Format the time in hh:mm:ss format (omitting redundant leading zeros).
- *
- * @param {number} timeInSec Time in seconds.
- * @return {string} Formatted time string.
- * @private
- */
-MediaControls.formatTime_ = function(timeInSec) {
- var seconds = Math.floor(timeInSec % 60);
- var minutes = Math.floor((timeInSec / 60) % 60);
- var hours = Math.floor(timeInSec / 60 / 60);
- var result = '';
- if (hours) result += hours + ':';
- if (hours && (minutes < 10)) result += '0';
- result += minutes + ':';
- if (seconds < 10) result += '0';
- result += seconds;
- return result;
-};
-
-/**
- * Create a custom control.
- *
- * @param {string} className Class name.
- * @param {HTMLElement=} opt_parent Parent element or container if undefined.
- * @return {HTMLElement} The new control element.
- */
-MediaControls.prototype.createControl = function(className, opt_parent) {
- var parent = opt_parent || this.container_;
- var control = this.document_.createElement('div');
- control.className = className;
- parent.appendChild(control);
- return control;
-};
-
-/**
- * Create a custom button.
- *
- * @param {string} className Class name.
- * @param {function(Event)} handler Click handler.
- * @param {HTMLElement=} opt_parent Parent element or container if undefined.
- * @param {number=} opt_numStates Number of states, default: 1.
- * @return {HTMLElement} The new button element.
- */
-MediaControls.prototype.createButton = function(
- className, handler, opt_parent, opt_numStates) {
- opt_numStates = opt_numStates || 1;
-
- var button = this.createControl(className, opt_parent);
- button.classList.add('media-button');
- button.addEventListener('click', handler);
-
- var stateTypes = Object.keys(MediaControls.ButtonStateType);
- for (var state = 0; state != opt_numStates; state++) {
- var stateClass = MediaControls.ButtonStateType[stateTypes[state]];
- this.createControl('normal ' + stateClass, button);
- this.createControl('hover ' + stateClass, button);
- this.createControl('active ' + stateClass, button);
- }
- this.createControl('disabled', button);
-
- button.setAttribute('state', MediaControls.ButtonStateType.DEFAULT);
- button.addEventListener('click', handler);
- return button;
-};
-
-/**
- * Enable/disable controls matching a given selector.
- *
- * @param {string} selector CSS selector.
- * @param {boolean} on True if enable, false if disable.
- * @private
- */
-MediaControls.prototype.enableControls_ = function(selector, on) {
- var controls = this.container_.querySelectorAll(selector);
- for (var i = 0; i != controls.length; i++) {
- var classList = controls[i].classList;
- if (on)
- classList.remove('disabled');
- else
- classList.add('disabled');
- }
-};
-
-/*
- * Playback control.
- */
-
-/**
- * Play the media.
- */
-MediaControls.prototype.play = function() {
- this.media_.play();
-};
-
-/**
- * Pause the media.
- */
-MediaControls.prototype.pause = function() {
- this.media_.pause();
-};
-
-/**
- * @return {boolean} True if the media is currently playing.
- */
-MediaControls.prototype.isPlaying = function() {
- return !this.media_.paused && !this.media_.ended;
-};
-
-/**
- * Toggle play/pause.
- */
-MediaControls.prototype.togglePlayState = function() {
- if (this.isPlaying())
- this.pause();
- else
- this.play();
-};
-
-/**
- * Toggle play/pause state on a mouse click on the play/pause button. Can be
- * called externally. TODO(mtomasz): Remove it. http://www.crbug.com/254318.
- *
- * @param {Event=} opt_event Mouse click event.
- */
-MediaControls.prototype.onPlayButtonClicked = function(opt_event) {
- this.togglePlayState();
-};
-
-/**
- * @param {HTMLElement=} opt_parent Parent container.
- */
-MediaControls.prototype.initPlayButton = function(opt_parent) {
- this.playButton_ = this.createButton('play media-control',
- this.onPlayButtonClicked.bind(this), opt_parent, 3 /* States. */);
-};
-
-/*
- * Time controls
- */
-
-/**
- * The default range of 100 is too coarse for the media progress slider.
- */
-MediaControls.PROGRESS_RANGE = 5000;
-
-/**
- * @param {boolean=} opt_seekMark True if the progress slider should have
- * a seek mark.
- * @param {HTMLElement=} opt_parent Parent container.
- */
-MediaControls.prototype.initTimeControls = function(opt_seekMark, opt_parent) {
- var timeControls = this.createControl('time-controls', opt_parent);
-
- var sliderConstructor =
- opt_seekMark ? MediaControls.PreciseSlider : MediaControls.Slider;
-
- this.progressSlider_ = new sliderConstructor(
- this.createControl('progress media-control', timeControls),
- 0, /* value */
- MediaControls.PROGRESS_RANGE,
- this.onProgressChange_.bind(this),
- this.onProgressDrag_.bind(this));
-
- var timeBox = this.createControl('time media-control', timeControls);
-
- this.duration_ = this.createControl('duration', timeBox);
- // Set the initial width to the minimum to reduce the flicker.
- this.duration_.textContent = MediaControls.formatTime_(0);
-
- this.currentTime_ = this.createControl('current', timeBox);
-};
-
-/**
- * @param {number} current Current time is seconds.
- * @param {number} duration Duration in seconds.
- * @private
- */
-MediaControls.prototype.displayProgress_ = function(current, duration) {
- var ratio = current / duration;
- this.progressSlider_.setValue(ratio);
- this.currentTime_.textContent = MediaControls.formatTime_(current);
-};
-
-/**
- * @param {number} value Progress [0..1].
- * @private
- */
-MediaControls.prototype.onProgressChange_ = function(value) {
- if (!this.media_.seekable || !this.media_.duration) {
- console.error('Inconsistent media state');
- return;
- }
-
- var current = this.media_.duration * value;
- this.media_.currentTime = current;
- this.currentTime_.textContent = MediaControls.formatTime_(current);
-};
-
-/**
- * @param {boolean} on True if dragging.
- * @private
- */
-MediaControls.prototype.onProgressDrag_ = function(on) {
- if (on) {
- this.resumeAfterDrag_ = this.isPlaying();
- this.media_.pause();
- } else {
- if (this.resumeAfterDrag_) {
- if (this.media_.ended)
- this.onMediaPlay_(false);
- else
- this.media_.play();
- }
- this.updatePlayButtonState_(this.isPlaying());
- }
-};
-
-/*
- * Volume controls
- */
-
-/**
- * @param {HTMLElement=} opt_parent Parent element for the controls.
- */
-MediaControls.prototype.initVolumeControls = function(opt_parent) {
- var volumeControls = this.createControl('volume-controls', opt_parent);
-
- this.soundButton_ = this.createButton('sound media-control',
- this.onSoundButtonClick_.bind(this), volumeControls);
- this.soundButton_.setAttribute('level', 3); // max level.
-
- this.volume_ = new MediaControls.AnimatedSlider(
- this.createControl('volume media-control', volumeControls),
- 1, /* value */
- 100 /* range */,
- this.onVolumeChange_.bind(this),
- this.onVolumeDrag_.bind(this));
-};
-
-/**
- * Click handler for the sound level button.
- * @private
- */
-MediaControls.prototype.onSoundButtonClick_ = function() {
- if (this.media_.volume == 0) {
- this.volume_.setValue(this.savedVolume_ || 1);
- } else {
- this.savedVolume_ = this.media_.volume;
- this.volume_.setValue(0);
- }
- this.onVolumeChange_(this.volume_.getValue());
-};
-
-/**
- * @param {number} value Volume [0..1].
- * @return {number} The rough level [0..3] used to pick an icon.
- * @private
- */
-MediaControls.getVolumeLevel_ = function(value) {
- if (value == 0) return 0;
- if (value <= 1 / 3) return 1;
- if (value <= 2 / 3) return 2;
- return 3;
-};
-
-/**
- * @param {number} value Volume [0..1].
- * @private
- */
-MediaControls.prototype.onVolumeChange_ = function(value) {
- this.media_.volume = value;
- this.soundButton_.setAttribute('level', MediaControls.getVolumeLevel_(value));
-};
-
-/**
- * @param {boolean} on True if dragging is in progress.
- * @private
- */
-MediaControls.prototype.onVolumeDrag_ = function(on) {
- if (on && (this.media_.volume != 0)) {
- this.savedVolume_ = this.media_.volume;
- }
-};
-
-/*
- * Media event handlers.
- */
-
-/**
- * Attach a media element.
- *
- * @param {HTMLMediaElement} mediaElement The media element to control.
- */
-MediaControls.prototype.attachMedia = function(mediaElement) {
- this.media_ = mediaElement;
-
- this.media_.addEventListener('play', this.onMediaPlayBound_);
- this.media_.addEventListener('pause', this.onMediaPauseBound_);
- this.media_.addEventListener('durationchange', this.onMediaDurationBound_);
- this.media_.addEventListener('timeupdate', this.onMediaProgressBound_);
- this.media_.addEventListener('error', this.onMediaError_);
-
- // Reflect the media state in the UI.
- this.onMediaDuration_();
- this.onMediaPlay_(this.isPlaying());
- this.onMediaProgress_();
- if (this.volume_) {
- /* Copy the user selected volume to the new media element. */
- this.media_.volume = this.volume_.getValue();
- }
-};
-
-/**
- * Detach media event handlers.
- */
-MediaControls.prototype.detachMedia = function() {
- if (!this.media_)
- return;
-
- this.media_.removeEventListener('play', this.onMediaPlayBound_);
- this.media_.removeEventListener('pause', this.onMediaPauseBound_);
- this.media_.removeEventListener('durationchange', this.onMediaDurationBound_);
- this.media_.removeEventListener('timeupdate', this.onMediaProgressBound_);
- this.media_.removeEventListener('error', this.onMediaError_);
-
- this.media_ = null;
-};
-
-/**
- * Force-empty the media pipeline. This is a workaround for crbug.com/149957.
- * The document is not going to be GC-ed until the last Files app window closes,
- * but we want the media pipeline to deinitialize ASAP to minimize leakage.
- */
-MediaControls.prototype.cleanup = function() {
- this.media_.src = '';
- this.media_.load();
- this.detachMedia();
-};
-
-/**
- * 'play' and 'pause' event handler.
- * @param {boolean} playing True if playing.
- * @private
- */
-MediaControls.prototype.onMediaPlay_ = function(playing) {
- if (this.progressSlider_.isDragging())
- return;
-
- this.updatePlayButtonState_(playing);
- this.onPlayStateChanged();
-};
-
-/**
- * 'durationchange' event handler.
- * @private
- */
-MediaControls.prototype.onMediaDuration_ = function() {
- if (!this.media_.duration) {
- this.enableControls_('.media-control', false);
- return;
- }
-
- this.enableControls_('.media-control', true);
-
- var sliderContainer = this.progressSlider_.getContainer();
- if (this.media_.seekable)
- sliderContainer.classList.remove('readonly');
- else
- sliderContainer.classList.add('readonly');
-
- var valueToString = function(value) {
- return MediaControls.formatTime_(this.media_.duration * value);
- }.bind(this);
-
- this.duration_.textContent = valueToString(1);
-
- if (this.progressSlider_.setValueToStringFunction)
- this.progressSlider_.setValueToStringFunction(valueToString);
-
- if (this.media_.seekable)
- this.restorePlayState();
-};
-
-/**
- * 'timeupdate' event handler.
- * @private
- */
-MediaControls.prototype.onMediaProgress_ = function() {
- if (!this.media_.duration) {
- this.displayProgress_(0, 1);
- return;
- }
-
- var current = this.media_.currentTime;
- var duration = this.media_.duration;
-
- if (this.progressSlider_.isDragging())
- return;
-
- this.displayProgress_(current, duration);
-
- if (current == duration) {
- this.onMediaComplete();
- }
- this.onPlayStateChanged();
-};
-
-/**
- * Called when the media playback is complete.
- */
-MediaControls.prototype.onMediaComplete = function() {};
-
-/**
- * Called when play/pause state is changed or on playback progress.
- * This is the right moment to save the play state.
- */
-MediaControls.prototype.onPlayStateChanged = function() {};
-
-/**
- * Updates the play button state.
- * @param {boolean} playing If the video is playing.
- * @private
- */
-MediaControls.prototype.updatePlayButtonState_ = function(playing) {
- if (playing) {
- this.playButton_.setAttribute('state',
- MediaControls.ButtonStateType.PLAYING);
- } else if (!this.media_.ended) {
- this.playButton_.setAttribute('state',
- MediaControls.ButtonStateType.DEFAULT);
- } else {
- this.playButton_.setAttribute('state',
- MediaControls.ButtonStateType.ENDED);
- }
-};
-
-/**
- * Restore play state. Base implementation is empty.
- */
-MediaControls.prototype.restorePlayState = function() {};
-
-/**
- * Encode current state into the page URL or the app state.
- */
-MediaControls.prototype.encodeState = function() {
- if (!this.media_.duration)
- return;
-
- if (window.appState) {
- window.appState.time = this.media_.currentTime;
- util.saveAppState();
- return;
- }
-
- var playState = JSON.stringify({
- play: this.isPlaying(),
- time: this.media_.currentTime
- });
-
- var newLocation = document.location.origin + document.location.pathname +
- document.location.search + '#' + playState;
-
- document.location.href = newLocation;
-};
-
-/**
- * Decode current state from the page URL or the app state.
- * @return {boolean} True if decode succeeded.
- */
-MediaControls.prototype.decodeState = function() {
- if (window.appState) {
- if (!('time' in window.appState))
- return false;
- // There is no page reload for apps v2, only app restart.
- // Always restart in paused state.
- this.media_.currentTime = appState.time;
- this.pause();
- return true;
- }
-
- var hash = document.location.hash.substring(1);
- if (hash) {
- try {
- var playState = JSON.parse(hash);
- if (!('time' in playState))
- return false;
-
- this.media_.currentTime = playState.time;
-
- if (playState.play)
- this.play();
- else
- this.pause();
-
- return true;
- } catch (e) {
- console.warn('Cannot decode play state');
- }
- }
- return false;
-};
-
-/**
- * Remove current state from the page URL or the app state.
- */
-MediaControls.prototype.clearState = function() {
- if (window.appState) {
- if ('time' in window.appState)
- delete window.appState.time;
- util.saveAppState();
- return;
- }
-
- var newLocation = document.location.origin + document.location.pathname +
- document.location.search + '#';
-
- document.location.href = newLocation;
-};
-
-/**
- * Create a customized slider control.
- *
- * @param {HTMLElement} container The containing div element.
- * @param {number} value Initial value [0..1].
- * @param {number} range Number of distinct slider positions to be supported.
- * @param {function(number)} onChange Value change handler.
- * @param {function(boolean)} onDrag Drag begin/end handler.
- * @constructor
- */
-
-MediaControls.Slider = function(container, value, range, onChange, onDrag) {
- this.container_ = container;
- this.onChange_ = onChange;
- this.onDrag_ = onDrag;
-
- var document = this.container_.ownerDocument;
-
- this.container_.classList.add('custom-slider');
-
- this.input_ = document.createElement('input');
- this.input_.type = 'range';
- this.input_.min = 0;
- this.input_.max = range;
- this.input_.value = value * range;
- this.container_.appendChild(this.input_);
-
- this.input_.addEventListener(
- 'change', this.onInputChange_.bind(this));
- this.input_.addEventListener(
- 'mousedown', this.onInputDrag_.bind(this, true));
- this.input_.addEventListener(
- 'mouseup', this.onInputDrag_.bind(this, false));
-
- this.bar_ = document.createElement('div');
- this.bar_.className = 'bar';
- this.container_.appendChild(this.bar_);
-
- this.filled_ = document.createElement('div');
- this.filled_.className = 'filled';
- this.bar_.appendChild(this.filled_);
-
- var leftCap = document.createElement('div');
- leftCap.className = 'cap left';
- this.bar_.appendChild(leftCap);
-
- var rightCap = document.createElement('div');
- rightCap.className = 'cap right';
- this.bar_.appendChild(rightCap);
-
- this.value_ = value;
- this.setFilled_(value);
-};
-
-/**
- * @return {HTMLElement} The container element.
- */
-MediaControls.Slider.prototype.getContainer = function() {
- return this.container_;
-};
-
-/**
- * @return {HTMLElement} The standard input element.
- * @private
- */
-MediaControls.Slider.prototype.getInput_ = function() {
- return this.input_;
-};
-
-/**
- * @return {HTMLElement} The slider bar element.
- */
-MediaControls.Slider.prototype.getBar = function() {
- return this.bar_;
-};
-
-/**
- * @return {number} [0..1] The current value.
- */
-MediaControls.Slider.prototype.getValue = function() {
- return this.value_;
-};
-
-/**
- * @param {number} value [0..1].
- */
-MediaControls.Slider.prototype.setValue = function(value) {
- this.value_ = value;
- this.setValueToUI_(value);
-};
-
-/**
- * Fill the given proportion the slider bar (from the left).
- *
- * @param {number} proportion [0..1].
- * @private
- */
-MediaControls.Slider.prototype.setFilled_ = function(proportion) {
- this.filled_.style.width = proportion * 100 + '%';
-};
-
-/**
- * Get the value from the input element.
- *
- * @return {number} Value [0..1].
- * @private
- */
-MediaControls.Slider.prototype.getValueFromUI_ = function() {
- return this.input_.value / this.input_.max;
-};
-
-/**
- * Update the UI with the current value.
- *
- * @param {number} value [0..1].
- * @private
- */
-MediaControls.Slider.prototype.setValueToUI_ = function(value) {
- this.input_.value = value * this.input_.max;
- this.setFilled_(value);
-};
-
-/**
- * Compute the proportion in which the given position divides the slider bar.
- *
- * @param {number} position in pixels.
- * @return {number} [0..1] proportion.
- */
-MediaControls.Slider.prototype.getProportion = function(position) {
- var rect = this.bar_.getBoundingClientRect();
- return Math.max(0, Math.min(1, (position - rect.left) / rect.width));
-};
-
-/**
- * 'change' event handler.
- * @private
- */
-MediaControls.Slider.prototype.onInputChange_ = function() {
- this.value_ = this.getValueFromUI_();
- this.setFilled_(this.value_);
- this.onChange_(this.value_);
-};
-
-/**
- * @return {boolean} True if dragging is in progress.
- */
-MediaControls.Slider.prototype.isDragging = function() {
- return this.isDragging_;
-};
-
-/**
- * Mousedown/mouseup handler.
- * @param {boolean} on True if the mouse is down.
- * @private
- */
-MediaControls.Slider.prototype.onInputDrag_ = function(on) {
- this.isDragging_ = on;
- this.onDrag_(on);
-};
-
-/**
- * Create a customized slider with animated thumb movement.
- *
- * @param {HTMLElement} container The containing div element.
- * @param {number} value Initial value [0..1].
- * @param {number} range Number of distinct slider positions to be supported.
- * @param {function(number)} onChange Value change handler.
- * @param {function(boolean)} onDrag Drag begin/end handler.
- * @param {function(number):string} formatFunction Value formatting function.
- * @constructor
- */
-MediaControls.AnimatedSlider = function(
- container, value, range, onChange, onDrag, formatFunction) {
- MediaControls.Slider.apply(this, arguments);
-};
-
-MediaControls.AnimatedSlider.prototype = {
- __proto__: MediaControls.Slider.prototype
-};
-
-/**
- * Number of animation steps.
- */
-MediaControls.AnimatedSlider.STEPS = 10;
-
-/**
- * Animation duration.
- */
-MediaControls.AnimatedSlider.DURATION = 100;
-
-/**
- * @param {number} value [0..1].
- * @private
- */
-MediaControls.AnimatedSlider.prototype.setValueToUI_ = function(value) {
- if (this.animationInterval_) {
- clearInterval(this.animationInterval_);
- }
- var oldValue = this.getValueFromUI_();
- var step = 0;
- this.animationInterval_ = setInterval(function() {
- step++;
- var currentValue = oldValue +
- (value - oldValue) * (step / MediaControls.AnimatedSlider.STEPS);
- MediaControls.Slider.prototype.setValueToUI_.call(this, currentValue);
- if (step == MediaControls.AnimatedSlider.STEPS) {
- clearInterval(this.animationInterval_);
- }
- }.bind(this),
- MediaControls.AnimatedSlider.DURATION / MediaControls.AnimatedSlider.STEPS);
-};
-
-/**
- * Create a customized slider with a precise time feedback.
- *
- * The time value is shown above the slider bar at the mouse position.
- *
- * @param {HTMLElement} container The containing div element.
- * @param {number} value Initial value [0..1].
- * @param {number} range Number of distinct slider positions to be supported.
- * @param {function(number)} onChange Value change handler.
- * @param {function(boolean)} onDrag Drag begin/end handler.
- * @param {function(number):string} formatFunction Value formatting function.
- * @constructor
- */
-MediaControls.PreciseSlider = function(
- container, value, range, onChange, onDrag, formatFunction) {
- MediaControls.Slider.apply(this, arguments);
-
- var doc = this.container_.ownerDocument;
-
- /**
- * @type {function(number):string}
- * @private
- */
- this.valueToString_ = null;
-
- this.seekMark_ = doc.createElement('div');
- this.seekMark_.className = 'seek-mark';
- this.getBar().appendChild(this.seekMark_);
-
- this.seekLabel_ = doc.createElement('div');
- this.seekLabel_.className = 'seek-label';
- this.seekMark_.appendChild(this.seekLabel_);
-
- this.getContainer().addEventListener(
- 'mousemove', this.onMouseMove_.bind(this));
- this.getContainer().addEventListener(
- 'mouseout', this.onMouseOut_.bind(this));
-};
-
-MediaControls.PreciseSlider.prototype = {
- __proto__: MediaControls.Slider.prototype
-};
-
-/**
- * Show the seek mark after a delay.
- */
-MediaControls.PreciseSlider.SHOW_DELAY = 200;
-
-/**
- * Hide the seek mark for this long after changing the position with a click.
- */
-MediaControls.PreciseSlider.HIDE_AFTER_MOVE_DELAY = 2500;
-
-/**
- * Hide the seek mark for this long after changing the position with a drag.
- */
-MediaControls.PreciseSlider.HIDE_AFTER_DRAG_DELAY = 750;
-
-/**
- * Default hide timeout (no hiding).
- */
-MediaControls.PreciseSlider.NO_AUTO_HIDE = 0;
-
-/**
- * @param {function(number):string} func Value formatting function.
- */
-MediaControls.PreciseSlider.prototype.setValueToStringFunction =
- function(func) {
- this.valueToString_ = func;
-
- /* It is not completely accurate to assume that the max value corresponds
- to the longest string, but generous CSS padding will compensate for that. */
- var labelWidth = this.valueToString_(1).length / 2 + 1;
- this.seekLabel_.style.width = labelWidth + 'em';
- this.seekLabel_.style.marginLeft = -labelWidth / 2 + 'em';
-};
-
-/**
- * Show the time above the slider.
- *
- * @param {number} ratio [0..1] The proportion of the duration.
- * @param {number} timeout Timeout in ms after which the label should be hidden.
- * MediaControls.PreciseSlider.NO_AUTO_HIDE means show until the next call.
- * @private
- */
-MediaControls.PreciseSlider.prototype.showSeekMark_ =
- function(ratio, timeout) {
- // Do not update the seek mark for the first 500ms after the drag is finished.
- if (this.latestMouseUpTime_ && (this.latestMouseUpTime_ + 500 > Date.now()))
- return;
-
- this.seekMark_.style.left = ratio * 100 + '%';
-
- if (ratio < this.getValue()) {
- this.seekMark_.classList.remove('inverted');
- } else {
- this.seekMark_.classList.add('inverted');
- }
- this.seekLabel_.textContent = this.valueToString_(ratio);
-
- this.seekMark_.classList.add('visible');
-
- if (this.seekMarkTimer_) {
- clearTimeout(this.seekMarkTimer_);
- this.seekMarkTimer_ = null;
- }
- if (timeout != MediaControls.PreciseSlider.NO_AUTO_HIDE) {
- this.seekMarkTimer_ = setTimeout(this.hideSeekMark_.bind(this), timeout);
- }
-};
-
-/**
- * @private
- */
-MediaControls.PreciseSlider.prototype.hideSeekMark_ = function() {
- this.seekMarkTimer_ = null;
- this.seekMark_.classList.remove('visible');
-};
-
-/**
- * 'mouseout' event handler.
- * @param {Event} e Event.
- * @private
- */
-MediaControls.PreciseSlider.prototype.onMouseMove_ = function(e) {
- this.latestSeekRatio_ = this.getProportion(e.clientX);
-
- var self = this;
- function showMark() {
- if (!self.isDragging()) {
- self.showSeekMark_(self.latestSeekRatio_,
- MediaControls.PreciseSlider.HIDE_AFTER_MOVE_DELAY);
- }
- }
-
- if (this.seekMark_.classList.contains('visible')) {
- showMark();
- } else if (!this.seekMarkTimer_) {
- this.seekMarkTimer_ =
- setTimeout(showMark, MediaControls.PreciseSlider.SHOW_DELAY);
- }
-};
-
-/**
- * 'mouseout' event handler.
- * @param {Event} e Event.
- * @private
- */
-MediaControls.PreciseSlider.prototype.onMouseOut_ = function(e) {
- for (var element = e.relatedTarget; element; element = element.parentNode) {
- if (element == this.getContainer())
- return;
- }
- if (this.seekMarkTimer_) {
- clearTimeout(this.seekMarkTimer_);
- this.seekMarkTimer_ = null;
- }
- this.hideSeekMark_();
-};
-
-/**
- * 'change' event handler.
- * @private
- */
-MediaControls.PreciseSlider.prototype.onInputChange_ = function() {
- MediaControls.Slider.prototype.onInputChange_.apply(this, arguments);
- if (this.isDragging()) {
- this.showSeekMark_(
- this.getValue(), MediaControls.PreciseSlider.NO_AUTO_HIDE);
- }
-};
-
-/**
- * Mousedown/mouseup handler.
- * @param {boolean} on True if the mouse is down.
- * @private
- */
-MediaControls.PreciseSlider.prototype.onInputDrag_ = function(on) {
- MediaControls.Slider.prototype.onInputDrag_.apply(this, arguments);
-
- if (on) {
- // Dragging started, align the seek mark with the thumb position.
- this.showSeekMark_(
- this.getValue(), MediaControls.PreciseSlider.NO_AUTO_HIDE);
- } else {
- // Just finished dragging.
- // Show the label for the last time with a shorter timeout.
- this.showSeekMark_(
- this.getValue(), MediaControls.PreciseSlider.HIDE_AFTER_DRAG_DELAY);
- this.latestMouseUpTime_ = Date.now();
- }
-};
-
-/**
- * Create video controls.
- *
- * @param {HTMLElement} containerElement The container for the controls.
- * @param {function} onMediaError Function to display an error message.
- * @param {function(string):string} stringFunction Function providing localized
- * strings.
- * @param {function=} opt_fullScreenToggle Function to toggle fullscreen mode.
- * @param {HTMLElement=} opt_stateIconParent The parent for the icon that
- * gives visual feedback when the playback state changes.
- * @constructor
- */
-function VideoControls(containerElement, onMediaError, stringFunction,
- opt_fullScreenToggle, opt_stateIconParent) {
- MediaControls.call(this, containerElement, onMediaError);
- this.stringFunction_ = stringFunction;
-
- this.container_.classList.add('video-controls');
- this.initPlayButton();
- this.initTimeControls(true /* show seek mark */);
- this.initVolumeControls();
-
- if (opt_fullScreenToggle) {
- this.fullscreenButton_ =
- this.createButton('fullscreen', opt_fullScreenToggle);
- }
-
- if (opt_stateIconParent) {
- this.stateIcon_ = this.createControl(
- 'playback-state-icon', opt_stateIconParent);
- this.textBanner_ = this.createControl('text-banner', opt_stateIconParent);
- }
-
- var videoControls = this;
- chrome.mediaPlayerPrivate.onTogglePlayState.addListener(
- function() { videoControls.togglePlayStateWithFeedback(); });
-}
-
-/**
- * No resume if we are within this margin from the start or the end.
- */
-VideoControls.RESUME_MARGIN = 0.03;
-
-/**
- * No resume for videos shorter than this.
- */
-VideoControls.RESUME_THRESHOLD = 5 * 60; // 5 min.
-
-/**
- * When resuming rewind back this much.
- */
-VideoControls.RESUME_REWIND = 5; // seconds.
-
-VideoControls.prototype = { __proto__: MediaControls.prototype };
-
-/**
- * Shows icon feedback for the current state of the video player.
- * @private
- */
-VideoControls.prototype.showIconFeedback_ = function() {
- this.stateIcon_.removeAttribute('state');
- setTimeout(function() {
- this.stateIcon_.setAttribute('state', this.isPlaying() ? 'play' : 'pause');
- }.bind(this), 0);
-};
-
-/**
- * Shows a text banner.
- *
- * @param {string} identifier String identifier.
- * @private
- */
-VideoControls.prototype.showTextBanner_ = function(identifier) {
- this.textBanner_.removeAttribute('visible');
- this.textBanner_.textContent = this.stringFunction_(identifier);
- setTimeout(function() {
- this.textBanner_.setAttribute('visible', 'true');
- }.bind(this), 0);
-};
-
-/**
- * Toggle play/pause state on a mouse click on the play/pause button. Can be
- * called externally.
- *
- * @param {Event} event Mouse click event.
- */
-VideoControls.prototype.onPlayButtonClicked = function(event) {
- if (event.ctrlKey) {
- this.toggleLoopedModeWithFeedback(true);
- if (!this.isPlaying())
- this.togglePlayState();
- } else {
- this.togglePlayState();
- }
-};
-
-/**
- * Media completion handler.
- */
-VideoControls.prototype.onMediaComplete = function() {
- this.onMediaPlay_(false); // Just update the UI.
- this.savePosition(); // This will effectively forget the position.
-};
-
-/**
- * Toggles the looped mode with feedback.
- * @param {boolean} on Whether enabled or not.
- */
-VideoControls.prototype.toggleLoopedModeWithFeedback = function(on) {
- if (!this.getMedia().duration)
- return;
- this.toggleLoopedMode(on);
- if (on) {
- // TODO(mtomasz): Simplify, crbug.com/254318.
- this.showTextBanner_('GALLERY_VIDEO_LOOPED_MODE');
- }
-};
-
-/**
- * Toggles the looped mode.
- * @param {boolean} on Whether enabled or not.
- */
-VideoControls.prototype.toggleLoopedMode = function(on) {
- this.getMedia().loop = on;
-};
-
-/**
- * Toggles play/pause state and flash an icon over the video.
- */
-VideoControls.prototype.togglePlayStateWithFeedback = function() {
- if (!this.getMedia().duration)
- return;
-
- this.togglePlayState();
- this.showIconFeedback_();
-};
-
-/**
- * Toggles play/pause state.
- */
-VideoControls.prototype.togglePlayState = function() {
- if (this.isPlaying()) {
- // User gave the Pause command. Save the state and reset the loop mode.
- this.toggleLoopedMode(false);
- this.savePosition();
- }
- MediaControls.prototype.togglePlayState.apply(this, arguments);
-};
-
-/**
- * Saves the playback position to the persistent storage.
- * @param {boolean=} opt_sync True if the position must be saved synchronously
- * (required when closing app windows).
- */
-VideoControls.prototype.savePosition = function(opt_sync) {
- if (!this.media_.duration ||
- this.media_.duration < VideoControls.RESUME_THRESHOLD) {
- return;
- }
-
- var ratio = this.media_.currentTime / this.media_.duration;
- var position;
- if (ratio < VideoControls.RESUME_MARGIN ||
- ratio > (1 - VideoControls.RESUME_MARGIN)) {
- // We are too close to the beginning or the end.
- // Remove the resume position so that next time we start from the beginning.
- position = null;
- } else {
- position = Math.floor(
- Math.max(0, this.media_.currentTime - VideoControls.RESUME_REWIND));
- }
-
- if (opt_sync) {
- // Packaged apps cannot save synchronously.
- // Pass the data to the background page.
- if (!window.saveOnExit)
- window.saveOnExit = [];
- window.saveOnExit.push({ key: this.media_.src, value: position });
- } else {
- util.AppCache.update(this.media_.src, position);
- }
-};
-
-/**
- * Resumes the playback position saved in the persistent storage.
- */
-VideoControls.prototype.restorePlayState = function() {
- if (this.media_.duration >= VideoControls.RESUME_THRESHOLD) {
- util.AppCache.getValue(this.media_.src, function(position) {
- if (position)
- this.media_.currentTime = position;
- }.bind(this));
- }
-};
-
-/**
- * Updates style to best fit the size of the container.
- */
-VideoControls.prototype.updateStyle = function() {
- // We assume that the video controls element fills the parent container.
- // This is easier than adding margins to this.container_.clientWidth.
- var width = this.container_.parentNode.clientWidth;
-
- // Set the margin to 5px for width >= 400, 0px for width < 160,
- // interpolate linearly in between.
- this.container_.style.margin =
- Math.ceil((Math.max(160, Math.min(width, 400)) - 160) / 48) + 'px';
-
- var hideBelow = function(selector, limit) {
- this.container_.querySelector(selector).style.display =
- width < limit ? 'none' : '-webkit-box';
- }.bind(this);
-
- hideBelow('.time', 350);
- hideBelow('.volume', 275);
- hideBelow('.volume-controls', 210);
- hideBelow('.fullscreen', 150);
-};
-
-/**
- * Creates audio controls.
- *
- * @param {HTMLElement} container Parent container.
- * @param {function(boolean)} advanceTrack Parameter: true=forward.
- * @param {function} onError Error handler.
- * @constructor
- */
-function AudioControls(container, advanceTrack, onError) {
- MediaControls.call(this, container, onError);
-
- this.container_.classList.add('audio-controls');
-
- this.advanceTrack_ = advanceTrack;
-
- this.initPlayButton();
- this.initTimeControls(false /* no seek mark */);
- /* No volume controls */
- this.createButton('previous', this.onAdvanceClick_.bind(this, false));
- this.createButton('next', this.onAdvanceClick_.bind(this, true));
-
- var audioControls = this;
- chrome.mediaPlayerPrivate.onNextTrack.addListener(
- function() { audioControls.onAdvanceClick_(true); });
- chrome.mediaPlayerPrivate.onPrevTrack.addListener(
- function() { audioControls.onAdvanceClick_(false); });
- chrome.mediaPlayerPrivate.onTogglePlayState.addListener(
- function() { audioControls.togglePlayState(); });
-}
-
-AudioControls.prototype = { __proto__: MediaControls.prototype };
-
-/**
- * Media completion handler. Advances to the next track.
- */
-AudioControls.prototype.onMediaComplete = function() {
- this.advanceTrack_(true);
-};
-
-/**
- * The track position after which "previous" button acts as "restart".
- */
-AudioControls.TRACK_RESTART_THRESHOLD = 5; // seconds.
-
-/**
- * @param {boolean} forward True if advancing forward.
- * @private
- */
-AudioControls.prototype.onAdvanceClick_ = function(forward) {
- if (!forward &&
- (this.getMedia().currentTime > AudioControls.TRACK_RESTART_THRESHOLD)) {
- // We are far enough from the beginning of the current track.
- // Restart it instead of than skipping to the previous one.
- this.getMedia().currentTime = 0;
- } else {
- this.advanceTrack_(forward);
- }
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/media/media_util.js b/chromium/chrome/browser/resources/file_manager/foreground/js/media/media_util.js
deleted file mode 100644
index a4c28348048..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/media/media_util.js
+++ /dev/null
@@ -1,421 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Loads a thumbnail using provided url. In CANVAS mode, loaded images
- * are attached as <canvas> element, while in IMAGE mode as <img>.
- * <canvas> renders faster than <img>, however has bigger memory overhead.
- *
- * @param {string} url File URL.
- * @param {ThumbnailLoader.LoaderType=} opt_loaderType Canvas or Image loader,
- * default: IMAGE.
- * @param {Object=} opt_metadata Metadata object.
- * @param {string=} opt_mediaType Media type.
- * @param {ThumbnailLoader.UseEmbedded=} opt_useEmbedded If to use embedded
- * jpeg thumbnail if available. Default: USE_EMBEDDED.
- * @param {number=} opt_priority Priority, the highest is 0. default: 2.
- * @constructor
- */
-function ThumbnailLoader(url, opt_loaderType, opt_metadata, opt_mediaType,
- opt_useEmbedded, opt_priority) {
- opt_useEmbedded = opt_useEmbedded || ThumbnailLoader.UseEmbedded.USE_EMBEDDED;
-
- this.mediaType_ = opt_mediaType || FileType.getMediaType(url);
- this.loaderType_ = opt_loaderType || ThumbnailLoader.LoaderType.IMAGE;
- this.metadata_ = opt_metadata;
- this.priority_ = (opt_priority !== undefined) ? opt_priority : 2;
- this.transform_ = null;
-
- if (!opt_metadata) {
- this.thumbnailUrl_ = url; // Use the URL directly.
- return;
- }
-
- this.fallbackUrl_ = null;
- this.thumbnailUrl_ = null;
- if (opt_metadata.drive && opt_metadata.drive.customIconUrl)
- this.fallbackUrl_ = opt_metadata.drive.customIconUrl;
-
- // Fetch the rotation from the Drive metadata (if available).
- var driveTransform;
- if (opt_metadata.drive && opt_metadata.drive.imageRotation !== undefined) {
- driveTransform = {
- scaleX: 1,
- scaleY: 1,
- rotate90: opt_metadata.drive.imageRotation / 90
- };
- }
-
- if (opt_metadata.thumbnail && opt_metadata.thumbnail.url &&
- opt_useEmbedded == ThumbnailLoader.UseEmbedded.USE_EMBEDDED) {
- this.thumbnailUrl_ = opt_metadata.thumbnail.url;
- this.transform_ = driveTransform !== undefined ? driveTransform :
- opt_metadata.thumbnail.transform;
- } else if (FileType.isImage(url)) {
- this.thumbnailUrl_ = url;
- this.transform_ = driveTransform !== undefined ? driveTransform :
- opt_metadata.media && opt_metadata.media.imageTransform;
- } else if (this.fallbackUrl_) {
- // Use fallback as the primary thumbnail.
- this.thumbnailUrl_ = this.fallbackUrl_;
- this.fallbackUrl_ = null;
- } // else the generic thumbnail based on the media type will be used.
-}
-
-/**
- * In percents (0.0 - 1.0), how much area can be cropped to fill an image
- * in a container, when loading a thumbnail in FillMode.AUTO mode.
- * The specified 30% value allows to fill 16:9, 3:2 pictures in 4:3 element.
- * @type {number}
- */
-ThumbnailLoader.AUTO_FILL_THRESHOLD = 0.3;
-
-/**
- * Type of displaying a thumbnail within a box.
- * @enum {number}
- */
-ThumbnailLoader.FillMode = {
- FILL: 0, // Fill whole box. Image may be cropped.
- FIT: 1, // Keep aspect ratio, do not crop.
- OVER_FILL: 2, // Fill whole box with possible stretching.
- AUTO: 3 // Try to fill, but if incompatible aspect ratio, then fit.
-};
-
-/**
- * Optimization mode for downloading thumbnails.
- * @enum {number}
- */
-ThumbnailLoader.OptimizationMode = {
- NEVER_DISCARD: 0, // Never discards downloading. No optimization.
- DISCARD_DETACHED: 1 // Canceled if the container is not attached anymore.
-};
-
-/**
- * Type of element to store the image.
- * @enum {number}
- */
-ThumbnailLoader.LoaderType = {
- IMAGE: 0,
- CANVAS: 1
-};
-
-/**
- * Whether to use the embedded thumbnail, or not. The embedded thumbnail may
- * be small.
- * @enum {number}
- */
-ThumbnailLoader.UseEmbedded = {
- USE_EMBEDDED: 0,
- NO_EMBEDDED: 1
-};
-
-/**
- * Maximum thumbnail's width when generating from the full resolution image.
- * @const
- * @type {number}
- */
-ThumbnailLoader.THUMBNAIL_MAX_WIDTH = 500;
-
-/**
- * Maximum thumbnail's height when generating from the full resolution image.
- * @const
- * @type {number}
- */
-ThumbnailLoader.THUMBNAIL_MAX_HEIGHT = 500;
-
-/**
- * Loads and attaches an image.
- *
- * @param {HTMLElement} box Container element.
- * @param {ThumbnailLoader.FillMode} fillMode Fill mode.
- * @param {ThumbnailLoader.OptimizationMode=} opt_optimizationMode Optimization
- * for downloading thumbnails. By default optimizations are disabled.
- * @param {function(Image, Object)} opt_onSuccess Success callback,
- * accepts the image and the transform.
- * @param {function} opt_onError Error callback.
- * @param {function} opt_onGeneric Callback for generic image used.
- */
-ThumbnailLoader.prototype.load = function(box, fillMode, opt_optimizationMode,
- opt_onSuccess, opt_onError, opt_onGeneric) {
- opt_optimizationMode = opt_optimizationMode ||
- ThumbnailLoader.OptimizationMode.NEVER_DISCARD;
-
- if (!this.thumbnailUrl_) {
- // Relevant CSS rules are in file_types.css.
- box.setAttribute('generic-thumbnail', this.mediaType_);
- if (opt_onGeneric) opt_onGeneric();
- return;
- }
-
- this.cancel();
- this.canvasUpToDate_ = false;
- this.image_ = new Image();
- this.image_.onload = function() {
- this.attachImage(box, fillMode);
- if (opt_onSuccess)
- opt_onSuccess(this.image_, this.transform_);
- }.bind(this);
- this.image_.onerror = function() {
- if (opt_onError)
- opt_onError();
- if (this.fallbackUrl_) {
- new ThumbnailLoader(this.fallbackUrl_,
- this.loaderType_,
- null, // No metadata.
- this.mediaType_,
- undefined, // Default value for use-embedded.
- this.priority_).
- load(box, fillMode, opt_optimizationMode, opt_onSuccess);
- } else {
- box.setAttribute('generic-thumbnail', this.mediaType_);
- }
- }.bind(this);
-
- if (this.image_.src) {
- console.warn('Thumbnail already loaded: ' + this.thumbnailUrl_);
- return;
- }
-
- // TODO(mtomasz): Smarter calculation of the requested size.
- var wasAttached = box.ownerDocument.contains(box);
- var modificationTime = this.metadata_ &&
- this.metadata_.filesystem &&
- this.metadata_.filesystem.modificationTime &&
- this.metadata_.filesystem.modificationTime.getTime();
- this.taskId_ = util.loadImage(
- this.image_,
- this.thumbnailUrl_,
- { maxWidth: ThumbnailLoader.THUMBNAIL_MAX_WIDTH,
- maxHeight: ThumbnailLoader.THUMBNAIL_MAX_HEIGHT,
- cache: true,
- priority: this.priority_,
- timestamp: modificationTime },
- function() {
- if (opt_optimizationMode ==
- ThumbnailLoader.OptimizationMode.DISCARD_DETACHED &&
- !box.ownerDocument.contains(box)) {
- // If the container is not attached, then invalidate the download.
- return false;
- }
- return true;
- });
-};
-
-/**
- * Cancels loading the current image.
- */
-ThumbnailLoader.prototype.cancel = function() {
- if (this.taskId_) {
- this.image_.onload = function() {};
- this.image_.onerror = function() {};
- util.cancelLoadImage(this.taskId_);
- this.taskId_ = null;
- }
-};
-
-/**
- * @return {boolean} True if a valid image is loaded.
- */
-ThumbnailLoader.prototype.hasValidImage = function() {
- return !!(this.image_ && this.image_.width && this.image_.height);
-};
-
-/**
- * @return {boolean} True if the image is rotated 90 degrees left or right.
- * @private
- */
-ThumbnailLoader.prototype.isRotated_ = function() {
- return this.transform_ && (this.transform_.rotate90 % 2 == 1);
-};
-
-/**
- * @return {number} Image width (corrected for rotation).
- */
-ThumbnailLoader.prototype.getWidth = function() {
- return this.isRotated_() ? this.image_.height : this.image_.width;
-};
-
-/**
- * @return {number} Image height (corrected for rotation).
- */
-ThumbnailLoader.prototype.getHeight = function() {
- return this.isRotated_() ? this.image_.width : this.image_.height;
-};
-
-/**
- * Load an image but do not attach it.
- *
- * @param {function(boolean)} callback Callback, parameter is true if the image
- * has loaded successfully or a stock icon has been used.
- */
-ThumbnailLoader.prototype.loadDetachedImage = function(callback) {
- if (!this.thumbnailUrl_) {
- callback(true);
- return;
- }
-
- this.cancel();
- this.canvasUpToDate_ = false;
- this.image_ = new Image();
- this.image_.onload = callback.bind(null, true);
- this.image_.onerror = callback.bind(null, false);
-
- // TODO(mtomasz): Smarter calculation of the requested size.
- var modificationTime = this.metadata_ &&
- this.metadata_.filesystem &&
- this.metadata_.filesystem.modificationTime &&
- this.metadata_.filesystem.modificationTime.getTime();
- this.taskId_ = util.loadImage(
- this.image_,
- this.thumbnailUrl_,
- { maxWidth: ThumbnailLoader.THUMBNAIL_MAX_WIDTH,
- maxHeight: ThumbnailLoader.THUMBNAIL_MAX_HEIGHT,
- cache: true,
- priority: this.priority_,
- timestamp: modificationTime });
-};
-
-/**
- * Renders the thumbnail into either canvas or an image element.
- * @private
- */
-ThumbnailLoader.prototype.renderMedia_ = function() {
- if (this.loaderType_ != ThumbnailLoader.LoaderType.CANVAS)
- return;
-
- if (!this.canvas_)
- this.canvas_ = document.createElement('canvas');
-
- // Copy the image to a canvas if the canvas is outdated.
- if (!this.canvasUpToDate_) {
- this.canvas_.width = this.image_.width;
- this.canvas_.height = this.image_.height;
- var context = this.canvas_.getContext('2d');
- context.drawImage(this.image_, 0, 0);
- this.canvasUpToDate_ = true;
- }
-};
-
-/**
- * Attach the image to a given element.
- * @param {Element} container Parent element.
- * @param {ThumbnailLoader.FillMode} fillMode Fill mode.
- */
-ThumbnailLoader.prototype.attachImage = function(container, fillMode) {
- if (!this.hasValidImage()) {
- container.setAttribute('generic-thumbnail', this.mediaType_);
- return;
- }
-
- this.renderMedia_();
- util.applyTransform(container, this.transform_);
- var attachableMedia = this.loaderType_ == ThumbnailLoader.LoaderType.CANVAS ?
- this.canvas_ : this.image_;
-
- ThumbnailLoader.centerImage_(
- container, attachableMedia, fillMode, this.isRotated_());
-
- if (attachableMedia.parentNode != container) {
- container.textContent = '';
- container.appendChild(attachableMedia);
- }
-
- if (!this.taskId_)
- attachableMedia.classList.add('cached');
-};
-
-/**
- * Gets the loaded image.
- * TODO(mtomasz): Apply transformations.
- *
- * @return {Image|HTMLCanvasElement} Either image or a canvas object.
- */
-ThumbnailLoader.prototype.getImage = function() {
- this.renderMedia_();
- return this.loaderType_ == ThumbnailLoader.LoaderType.CANVAS ? this.canvas_ :
- this.image_;
-};
-
-/**
- * Update the image style to fit/fill the container.
- *
- * Using webkit center packing does not align the image properly, so we need
- * to wait until the image loads and its dimensions are known, then manually
- * position it at the center.
- *
- * @param {HTMLElement} box Containing element.
- * @param {Image|HTMLCanvasElement} img Element containing an image.
- * @param {ThumbnailLoader.FillMode} fillMode Fill mode.
- * @param {boolean} rotate True if the image should be rotated 90 degrees.
- * @private
- */
-ThumbnailLoader.centerImage_ = function(box, img, fillMode, rotate) {
- var imageWidth = img.width;
- var imageHeight = img.height;
-
- var fractionX;
- var fractionY;
-
- var boxWidth = box.clientWidth;
- var boxHeight = box.clientHeight;
-
- var fill;
- switch (fillMode) {
- case ThumbnailLoader.FillMode.FILL:
- case ThumbnailLoader.FillMode.OVER_FILL:
- fill = true;
- break;
- case ThumbnailLoader.FillMode.FIT:
- fill = false;
- break;
- case ThumbnailLoader.FillMode.AUTO:
- var imageRatio = imageWidth / imageHeight;
- var boxRatio = 1.0;
- if (boxWidth && boxHeight)
- boxRatio = boxWidth / boxHeight;
- // Cropped area in percents.
- var ratioFactor = boxRatio / imageRatio;
- fill = (ratioFactor >= 1.0 - ThumbnailLoader.AUTO_FILL_THRESHOLD) &&
- (ratioFactor <= 1.0 + ThumbnailLoader.AUTO_FILL_THRESHOLD);
- break;
- }
-
- if (boxWidth && boxHeight) {
- // When we know the box size we can position the image correctly even
- // in a non-square box.
- var fitScaleX = (rotate ? boxHeight : boxWidth) / imageWidth;
- var fitScaleY = (rotate ? boxWidth : boxHeight) / imageHeight;
-
- var scale = fill ?
- Math.max(fitScaleX, fitScaleY) :
- Math.min(fitScaleX, fitScaleY);
-
- if (fillMode != ThumbnailLoader.FillMode.OVER_FILL)
- scale = Math.min(scale, 1); // Never overscale.
-
- fractionX = imageWidth * scale / boxWidth;
- fractionY = imageHeight * scale / boxHeight;
- } else {
- // We do not know the box size so we assume it is square.
- // Compute the image position based only on the image dimensions.
- // First try vertical fit or horizontal fill.
- fractionX = imageWidth / imageHeight;
- fractionY = 1;
- if ((fractionX < 1) == !!fill) { // Vertical fill or horizontal fit.
- fractionY = 1 / fractionX;
- fractionX = 1;
- }
- }
-
- function percent(fraction) {
- return (fraction * 100).toFixed(2) + '%';
- }
-
- img.style.width = percent(fractionX);
- img.style.height = percent(fractionY);
- img.style.left = percent((1 - fractionX) / 2);
- img.style.top = percent((1 - fractionY) / 2);
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/media/mediaplayer_scripts.js b/chromium/chrome/browser/resources/file_manager/foreground/js/media/mediaplayer_scripts.js
deleted file mode 100644
index 496a8d09d98..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/media/mediaplayer_scripts.js
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// The include directives are put into Javascript-style comments to prevent
-// parsing errors in non-flattened mode. The flattener still sees them.
-// Note that this makes the flattener to comment out the first line of the
-// included file but that's all right since any javascript file should start
-// with a copyright comment anyway.
-
-
-//<include src="../../../../../../../ui/webui/resources/js/cr.js"/>
-//<include src="../../../../../../../ui/webui/resources/js/cr/event_target.js"/>
-//<include src="../../../../../../../ui/webui/resources/js/cr/ui/array_data_model.js"/>
-
-(function() {
-// 'strict mode' is invoked for this scope.
-
-//<include src="../../../common/js/async_util.js"/>
-//<include src="../../../common/js/util.js"/>
-//<include src="../../../common/js/path_util.js"/>
-//<include src="../file_type.js"/>
-//<include src="../volume_manager_wrapper.js">
-//<include src="../metadata/metadata_cache.js"/>
-
-//<include src="media_controls.js"/>
-//<include src="audio_player.js"/>
-//<include src="player_testapi.js"/>
-
-window.reload = reload;
-window.unload = unload;
-
-})();
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/media/player_testapi.js b/chromium/chrome/browser/resources/file_manager/foreground/js/media/player_testapi.js
deleted file mode 100644
index 75f0b302502..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/media/player_testapi.js
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Test API for Chrome OS Video Player and Audio Player.
- *
- * To test the Video Player open a tab with the URL:
- * chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/video_player.html
- *
- * To test the Audio Player open a tab with the URL:
- * chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/mediaplayer.html
- *
- */
-var playerTestAPI = {
-
- /* Methods common for audio and video players */
-
- /**
- * Respond with the path to the current media source.
- */
- getSrc: function() {
- playerTestAPI.respond_(util.extractFilePath(playerTestAPI.getMedia_().src));
- },
-
- /**
- * Respond with a boolean value, true if the media is playing.
- */
- isPlaying: function() {
- playerTestAPI.respond_(playerTestAPI.getControls_().isPlaying());
- },
-
- /**
- * Play the media.
- */
- play: function() {
- playerTestAPI.getControls_().play();
- },
-
- /**
- * Pause the playback.
- */
- pause: function() {
- playerTestAPI.getControls_().pause();
- },
-
- /**
- * Respond with a number, duration of the media in seconds.
- */
- getDuration: function() {
- playerTestAPI.respond_(playerTestAPI.getMedia_().duration);
- },
-
- /**
- * Respond with a number, current media position in seconds.
- */
- getCurrentTime: function() {
- playerTestAPI.respond_(playerTestAPI.getMedia_().currentTime);
- },
-
- /**
- * Change media position.
- * @param {number} time Media positions.
- */
- seekTo: function(time) {
- playerTestAPI.getMedia_().currentTime = time;
- },
-
- /* Video player-specific methods.
- *
- * To test the video player open a tab with the url:
- * chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/mediaplayer.html
- *
- */
-
- /**
- * Load the specified file in the video player,
- * Starts playing immediately.
- * @param {string} filePath File path.
- */
- loadVideo: function(filePath) {
- var url = util.makeFilesystemUrl(filePath);
- location.href = location.origin + location.pathname + '?' + url;
- reload();
- },
-
- /**
- * Respond with a number, current volume [0..100].
- */
- getVolume: function() {
- playerTestAPI.respond_(playerTestAPI.getMedia_().volume * 100);
- },
-
- /**
- * Change volume.
- * @param {number} volume Volume [0..100].
- */
- setVolume: function(volume) {
- playerTestAPI.respond_(
- playerTestAPI.getControls_().onVolumeChange_(volume / 100));
- },
-
- /**
- * Respond with a boolean, true if the volume is muted.
- */
- isMuted: function() {
- playerTestAPI.respond_(playerTestAPI.getMedia_().volume == 0);
- },
-
- /**
- * Mute the volume. No-op if already muted.
- */
- mute: function() {
- if (playerTestAPI.getMedia_().volume != 0)
- playerTestAPI.getControls_().onSoundButtonClick_();
- },
-
- /**
- * Unmute the volume. No-op if not muted.
- */
- unmute: function() {
- if (playerTestAPI.getMedia_().volume == 0)
- playerTestAPI.getControls_().onSoundButtonClick_();
- },
-
- /* Audio player-specific methods. */
-
- /**
- * Load a group of tracks into the audio player.
- * Starts playing one of the tracks immediately.
- * @param {Array.<string>} filePaths Array of file paths.
- * @param {number} firstTrack Number of the file to play first (0-based).
- */
- loadAudio: function(filePaths, firstTrack) {
- AudioPlayer.instance.load({
- items: filePaths.map(util.makeFilesystemUrl),
- position: firstTrack
- });
- },
-
- /**
- * Respond with a current track number,
- */
- getTrackNumber: function() {
- playerTestAPI.respond_(AudioPlayer.instance.currentTrack_);
- },
-
- /**
- * Play the next track.
- */
- forward: function() {
- playerTestAPI.getControls_().onAdvanceClick_(true /* forward */);
- },
-
- /**
- * Go back. Will restart the current track if the current position is > 5 sec
- * or play the previous track otherwise.
- */
- back: function() {
- playerTestAPI.getControls_().onAdvanceClick_(false /* back */);
- },
-
- /* Utility methods */
-
- /**
- * @return {AudioControls|VideoControls} Media controls.
- * @private
- */
- getControls_: function() {
- return window.controls || window.AudioPlayer.instance.audioControls_;
- },
-
- /**
- * @return {HTMLVideoElement|HTMLAudioElement} Media element.
- * @private
- */
- getMedia_: function() {
- return playerTestAPI.getControls_().getMedia();
- },
-
- /**
- * @param {string|boolean|number} value Value to send back.
- * @private
- */
- respond_: function(value) {
- if (window.domAutomationController)
- window.domAutomationController.send(value);
- else
- console.log('playerTestAPI response: ' + value);
- }
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/media/util.js b/chromium/chrome/browser/resources/file_manager/foreground/js/media/util.js
deleted file mode 100644
index 4d3c953dd55..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/media/util.js
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * A controller class detects mouse inactivity and hides "tool" elements.
- *
- * @param {Element} container The main DOM container.
- * @param {number=} opt_timeout Hide timeout in ms.
- * @param {function():boolean=} opt_toolsActive Function that returns |true|
- * if the tools are active and should not be hidden.
- * @constructor
- */
-function MouseInactivityWatcher(container, opt_timeout, opt_toolsActive) {
- this.container_ = container;
- this.timeout_ = opt_timeout || MouseInactivityWatcher.DEFAULT_TIMEOUT;
- this.toolsActive_ = opt_toolsActive || function() { return false };
-
- this.onTimeoutBound_ = this.onTimeout_.bind(this);
- this.timeoutID_ = null;
- this.mouseOverTool_ = false;
-
- this.clientX_ = 0;
- this.clientY_ = 0;
-
- /**
- * Indicates if the inactivity watcher is enabled or disabled. Use getters
- * and setters.
- * @type {boolean}
- * @private
- **/
- this.disabled_ = false;
- this.__defineSetter__('disabled', function(value) {
- this.disabled_ = value;
- if (value)
- this.kick();
- else
- this.check();
- });
- this.__defineGetter__('disabled', function() {
- return this.disabled_;
- });
-
- this.container_.addEventListener('mousemove', this.onMouseMove_.bind(this));
- var tools = this.container_.querySelector('.tool');
- for (var i = 0; i < tools.length; i++) {
- tools[i].addEventListener('mouseover', this.onToolMouseOver_.bind(this));
- tools[i].addEventListener('mouseout', this.onToolMouseOut_.bind(this));
- }
-
- // Show tools when the user touches the screen.
- this.container_.addEventListener(
- 'touchstart', this.activityStarted_.bind(this));
- var initiateFading = this.activityStopped_.bind(this, this.timeout_);
- this.container_.addEventListener('touchend', initiateFading);
- this.container_.addEventListener('touchcancel', initiateFading);
-}
-
-/**
- * Default inactivity timeout.
- */
-MouseInactivityWatcher.DEFAULT_TIMEOUT = 3000;
-
-/**
- * @param {boolean} on True if show, false if hide.
- */
-MouseInactivityWatcher.prototype.showTools = function(on) {
- if (on)
- this.container_.setAttribute('tools', 'true');
- else
- this.container_.removeAttribute('tools');
-};
-
-/**
- * To be called when the user started activity. Shows the tools
- * and cancels the countdown.
- * @private
- */
-MouseInactivityWatcher.prototype.activityStarted_ = function() {
- this.showTools(true);
-
- if (this.timeoutID_) {
- clearTimeout(this.timeoutID_);
- this.timeoutID_ = null;
- }
-};
-
-/**
- * Called when user activity has stopped. Re-starts the countdown.
- * @param {number=} opt_timeout Timeout.
- * @private
- */
-MouseInactivityWatcher.prototype.activityStopped_ = function(opt_timeout) {
- if (this.disabled_ || this.mouseOverTool_ || this.toolsActive_())
- return;
-
- if (this.timeoutID_)
- clearTimeout(this.timeoutID_);
-
- this.timeoutID_ = setTimeout(
- this.onTimeoutBound_, opt_timeout || this.timeout_);
-};
-
-/**
- * Called when a user performed a short action (such as a click or a key press)
- * that should show the tools if they are not visible.
- * @param {number=} opt_timeout Timeout.
- */
-MouseInactivityWatcher.prototype.kick = function(opt_timeout) {
- this.activityStarted_();
- this.activityStopped_(opt_timeout);
-};
-
-/**
- * Check if the tools are active and update the tools visibility accordingly.
- */
-MouseInactivityWatcher.prototype.check = function() {
- if (this.toolsActive_())
- this.activityStarted_();
- else
- this.activityStopped_();
-};
-
-/**
- * Mouse move handler.
- *
- * @param {Event} e Event.
- * @private
- */
-MouseInactivityWatcher.prototype.onMouseMove_ = function(e) {
- if (this.clientX_ == e.clientX && this.clientY_ == e.clientY) {
- // The mouse has not moved, must be the cursor change triggered by
- // some of the attributes on the root container. Ignore the event.
- return;
- }
- this.clientX_ = e.clientX;
- this.clientY_ = e.clientY;
-
- if (this.disabled_)
- return;
-
- this.kick();
-};
-
-/**
- * Mouse over handler on a tool element.
- *
- * @param {Event} e Event.
- * @private
- */
-MouseInactivityWatcher.prototype.onToolMouseOver_ = function(e) {
- this.mouseOverTool_ = true;
- if (!this.disabled_)
- this.kick();
-};
-
-/**
- * Mouse out handler on a tool element.
- *
- * @param {Event} e Event.
- * @private
- */
-MouseInactivityWatcher.prototype.onToolMouseOut_ = function(e) {
- this.mouseOverTool_ = false;
- if (!this.disabled_)
- this.kick();
-};
-
-/**
- * Timeout handler.
- * @private
- */
-MouseInactivityWatcher.prototype.onTimeout_ = function() {
- this.timeoutID_ = null;
- if (!this.disabled_ && !this.toolsActive_())
- this.showTools(false);
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/media/video_player.js b/chromium/chrome/browser/resources/file_manager/foreground/js/media/video_player.js
deleted file mode 100644
index 9b4b663fdc1..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/media/video_player.js
+++ /dev/null
@@ -1,289 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Display error message.
- * @param {string} message Message id.
- */
-function showErrorMessage(message) {
- var errorBanner = document.querySelector('#error');
- errorBanner.textContent =
- loadTimeData.getString(message);
- errorBanner.setAttribute('visible', 'true');
-
- // The window is hidden if the video has not loaded yet.
- chrome.app.window.current().show();
-}
-
-/**
- * Handles playback (decoder) errors.
- */
-function onPlaybackError() {
- showErrorMessage('GALLERY_VIDEO_DECODING_ERROR');
- decodeErrorOccured = true;
-
- // Disable inactivity watcher, and disable the ui, by hiding tools manually.
- controls.inactivityWatcher.disabled = true;
- document.querySelector('#video-player').setAttribute('disabled', 'true');
-
- // Detach the video element, since it may be unreliable and reset stored
- // current playback time.
- controls.cleanup();
- controls.clearState();
-
- // Avoid reusing a video element.
- video.parentNode.removeChild(video);
- video = null;
-}
-
-/**
- * @param {Element} playerContainer Main container.
- * @param {Element} videoContainer Container for the video element.
- * @param {Element} controlsContainer Container for video controls.
- * @constructor
- */
-function FullWindowVideoControls(
- playerContainer, videoContainer, controlsContainer) {
- VideoControls.call(this,
- controlsContainer,
- onPlaybackError,
- loadTimeData.getString.bind(loadTimeData),
- this.toggleFullScreen_.bind(this),
- videoContainer);
-
- this.playerContainer_ = playerContainer;
-
- this.updateStyle();
- window.addEventListener('resize', this.updateStyle.bind(this));
-
- document.addEventListener('keydown', function(e) {
- if (e.keyIdentifier == 'U+0020') { // Space
- this.togglePlayStateWithFeedback();
- e.preventDefault();
- }
- if (e.keyIdentifier == 'U+001B') { // Escape
- util.toggleFullScreen(
- chrome.app.window.current(),
- false); // Leave the full screen mode.
- e.preventDefault();
- }
- }.bind(this));
-
- // TODO(mtomasz): Simplify. crbug.com/254318.
- videoContainer.addEventListener('click', function(e) {
- if (e.ctrlKey) {
- this.toggleLoopedModeWithFeedback(true);
- if (!this.isPlaying())
- this.togglePlayStateWithFeedback();
- } else {
- this.togglePlayStateWithFeedback();
- }
- }.bind(this));
-
- this.inactivityWatcher_ = new MouseInactivityWatcher(playerContainer);
- this.__defineGetter__('inactivityWatcher', function() {
- return this.inactivityWatcher_;
- });
-
- this.inactivityWatcher_.check();
-}
-
-FullWindowVideoControls.prototype = { __proto__: VideoControls.prototype };
-
-/**
- * Save the current state so that it survives page/app reload.
- */
-FullWindowVideoControls.prototype.onPlayStateChanged = function() {
- this.encodeState();
-};
-
-/**
- * Restore the state after the video is loaded.
- */
-FullWindowVideoControls.prototype.restorePlayState = function() {
- if (!this.decodeState()) {
- VideoControls.prototype.restorePlayState.apply(this, arguments);
- this.play();
- }
-};
-
-/**
- * Toggles the full screen mode.
- * @private
- */
-FullWindowVideoControls.prototype.toggleFullScreen_ = function() {
- var appWindow = chrome.app.window.current();
- util.toggleFullScreen(appWindow, !util.isFullScreen(appWindow));
-};
-
-// TODO(mtomasz): Convert it to class members: crbug.com/171191.
-var decodeErrorOccured;
-var video;
-var controls;
-var metadataCache;
-var volumeManager;
-var selectedEntry;
-
-/**
- * Initialize the video player window.
- */
-function loadVideoPlayer() {
- document.ondragstart = function(e) { e.preventDefault() };
-
- chrome.fileBrowserPrivate.getStrings(function(strings) {
- loadTimeData.data = strings;
-
- controls = new FullWindowVideoControls(
- document.querySelector('#video-player'),
- document.querySelector('#video-container'),
- document.querySelector('#controls'));
-
- metadataCache = MetadataCache.createFull();
- volumeManager = new VolumeManagerWrapper(
- VolumeManagerWrapper.DriveEnabledStatus.DRIVE_ENABLED);
- volumeManager.addEventListener('externally-unmounted',
- onExternallyUnmounted);
-
- // If the video player is starting before the first instance of the File
- // Manager then it does not have access to filesystem URLs.
- // Request it now.
- volumeManager.ensureInitialized(reload);
- var reloadVideo = function(e) {
- if (decodeErrorOccured &&
- // Ignore shortcut keys
- !e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey) {
- reload();
- e.preventDefault();
- }
- };
-
- document.addEventListener('keydown', reloadVideo, true);
- document.addEventListener('click', reloadVideo, true);
- });
-}
-
-/**
- * Closes video player when a volume containing the played item is unmounted.
- * @param {Event} event The unmount event.
- */
-function onExternallyUnmounted(event) {
- if (!selectedEntry)
- return;
-
- if (volumeManager.getVolumeInfo(selectedEntry) === event.volumeInfo)
- window.close();
-}
-
-/**
- * Unload the player.
- */
-function unload() {
- if (volumeManager)
- volumeManager.dispose();
-
- if (!controls.getMedia())
- return;
-
- controls.savePosition(true /* exiting */);
- controls.cleanup();
-}
-
-/**
- * Reload the player.
- */
-function reload() {
- // Re-enable ui and hide error message if already displayed.
- document.querySelector('#video-player').removeAttribute('disabled');
- document.querySelector('#error').removeAttribute('visible');
- controls.inactivityWatcher.disabled = false;
- decodeErrorOccured = false;
-
- var url;
- if (window.appState) {
- util.saveAppState();
- url = window.appState.url;
- } else {
- url = document.location.search.substr(1);
- }
-
- document.title = decodeURIComponent(url.split('/').pop());
- var queue = new AsyncUtil.Queue();
-
- queue.run(function(callback) {
- webkitResolveLocalFileSystemURL(url,
- function(entry) {
- selectedEntry = entry;
- callback();
- }, function() {
- console.warn('Failed to resolve entry for: ' + url);
- callback();
- });
- });
-
-
- queue.run(function(callback) {
- if (!selectedEntry) {
- showErrorMessage('GALLERY_VIDEO_ERROR');
- return;
- }
- metadataCache.get(selectedEntry, 'streaming', function(streaming) {
- if (streaming && !navigator.onLine) {
- showErrorMessage('GALLERY_VIDEO_OFFLINE');
- return;
- }
-
- // Detach the previous video element, if exists.
- if (video)
- video.parentNode.removeChild(video);
-
- video = document.createElement('video');
- document.querySelector('#video-container').appendChild(video);
- controls.attachMedia(video);
-
- video.src = selectedEntry.toURL();
- video.load();
- video.addEventListener('loadedmetadata', function() {
- // TODO: chrome.app.window soon will be able to resize the content area.
- // Until then use approximate title bar height.
- var TITLE_HEIGHT = 28;
-
- var aspect = video.videoWidth / video.videoHeight;
- var newWidth = video.videoWidth;
- var newHeight = video.videoHeight + TITLE_HEIGHT;
-
- var shrinkX = newWidth / window.screen.availWidth;
- var shrinkY = newHeight / window.screen.availHeight;
- if (shrinkX > 1 || shrinkY > 1) {
- if (shrinkY > shrinkX) {
- newHeight = newHeight / shrinkY;
- newWidth = (newHeight - TITLE_HEIGHT) * aspect;
- } else {
- newWidth = newWidth / shrinkX;
- newHeight = newWidth / aspect + TITLE_HEIGHT;
- }
- }
-
- var oldLeft = window.screenX;
- var oldTop = window.screenY;
- var oldWidth = window.outerWidth;
- var oldHeight = window.outerHeight;
-
- if (!oldWidth && !oldHeight) {
- oldLeft = window.screen.availWidth / 2;
- oldTop = window.screen.availHeight / 2;
- }
-
- var appWindow = chrome.app.window.current();
- appWindow.resizeTo(newWidth, newHeight);
- appWindow.moveTo(oldLeft - (newWidth - oldWidth) / 2,
- oldTop - (newHeight - oldHeight) / 2);
- appWindow.show();
- });
- });
- });
-}
-
-util.addPageLoadHandler(loadVideoPlayer);
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/media/video_player_scripts.js b/chromium/chrome/browser/resources/file_manager/foreground/js/media/video_player_scripts.js
deleted file mode 100644
index 54ea178f2fe..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/media/video_player_scripts.js
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// The include directives are put into Javascript-style comments to prevent
-// parsing errors in non-flattened mode. The flattener still sees them.
-// Note that this makes the flattener to comment out the first line of the
-// included file but that's all right since any javascript file should start
-// with a copyright comment anyway.
-
-//<include src="../../../../../../../ui/webui/resources/js/cr.js"/>
-//<include src="../../../../../../../ui/webui/resources/js/cr/event_target.js"/>
-//<include src="../../../../../../../ui/webui/resources/js/cr/ui/array_data_model.js"/>
-//<include src="../../../../../../../ui/webui/resources/js/load_time_data.js"/>
-
-(function() {
-// 'strict mode' is invoked for this scope.
-
-//<include src="../../../common/js/async_util.js"/>
-//<include src="../../../common/js/util.js"/>
-//<include src="../../../common/js/path_util.js"/>
-//<include src="../file_type.js"/>
-//<include src="../volume_manager_wrapper.js">
-//<include src="../metadata/metadata_cache.js"/>
-
-//<include src="media_controls.js"/>
-//<include src="util.js"/>
-//<include src="video_player.js"/>
-//<include src="player_testapi.js"/>
-
-window.reload = reload;
-window.unload = unload;
-
-})();
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/byte_reader.js b/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/byte_reader.js
deleted file mode 100644
index 09cf306b53c..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/byte_reader.js
+++ /dev/null
@@ -1,535 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * @constructor
- * @param {ArrayBuffer} arrayBuffer // TODO(JSDOC).
- * @param {number=} opt_offset // TODO(JSDOC).
- * @param {number=} opt_length // TODO(JSDOC).
- */
-function ByteReader(arrayBuffer, opt_offset, opt_length) {
- opt_offset = opt_offset || 0;
- opt_length = opt_length || (arrayBuffer.byteLength - opt_offset);
- this.view_ = new DataView(arrayBuffer, opt_offset, opt_length);
- this.pos_ = 0;
- this.seekStack_ = [];
- this.setByteOrder(ByteReader.BIG_ENDIAN);
-}
-
-// Static constants and methods.
-
-/**
- * Intel, 0x1234 is [0x34, 0x12]
- * @const
- * @type {number}
- */
-ByteReader.LITTLE_ENDIAN = 0;
-/**
- * Motorola, 0x1234 is [0x12, 0x34]
- * @const
- * @type {number}
- */
-ByteReader.BIG_ENDIAN = 1;
-
-/**
- * Seek relative to the beginning of the buffer.
- * @const
- * @type {number}
- */
-ByteReader.SEEK_BEG = 0;
-/**
- * Seek relative to the current position.
- * @const
- * @type {number}
- */
-ByteReader.SEEK_CUR = 1;
-/**
- * Seek relative to the end of the buffer.
- * @const
- * @type {number}
- */
-ByteReader.SEEK_END = 2;
-
-/**
- * Throw an error if (0 > pos >= end) or if (pos + size > end).
- *
- * Static utility function.
- *
- * @param {number} pos // TODO(JSDOC).
- * @param {number} size // TODO(JSDOC).
- * @param {number} end // TODO(JSDOC).
- */
-ByteReader.validateRead = function(pos, size, end) {
- if (pos < 0 || pos >= end)
- throw new Error('Invalid read position');
-
- if (pos + size > end)
- throw new Error('Read past end of buffer');
-};
-
-/**
- * Read as a sequence of characters, returning them as a single string.
- *
- * This is a static utility function. There is a member function with the
- * same name which side-effects the current read position.
- *
- * @param {DataView} dataView // TODO(JSDOC).
- * @param {number} pos // TODO(JSDOC).
- * @param {number} size // TODO(JSDOC).
- * @param {number=} opt_end // TODO(JSDOC).
- * @return {string} // TODO(JSDOC).
- */
-ByteReader.readString = function(dataView, pos, size, opt_end) {
- ByteReader.validateRead(pos, size, opt_end || dataView.byteLength);
-
- var codes = [];
-
- for (var i = 0; i < size; ++i)
- codes.push(dataView.getUint8(pos + i));
-
- return String.fromCharCode.apply(null, codes);
-};
-
-/**
- * Read as a sequence of characters, returning them as a single string.
- *
- * This is a static utility function. There is a member function with the
- * same name which side-effects the current read position.
- *
- * @param {DataView} dataView // TODO(JSDOC).
- * @param {number} pos // TODO(JSDOC).
- * @param {number} size // TODO(JSDOC).
- * @param {number=} opt_end // TODO(JSDOC).
- * @return {string} // TODO(JSDOC).
- */
-ByteReader.readNullTerminatedString = function(dataView, pos, size, opt_end) {
- ByteReader.validateRead(pos, size, opt_end || dataView.byteLength);
-
- var codes = [];
-
- for (var i = 0; i < size; ++i) {
- var code = dataView.getUint8(pos + i);
- if (code == 0) break;
- codes.push(code);
- }
-
- return String.fromCharCode.apply(null, codes);
-};
-
-/**
- * Read as a sequence of UTF16 characters, returning them as a single string.
- *
- * This is a static utility function. There is a member function with the
- * same name which side-effects the current read position.
- *
- * @param {DataView} dataView // TODO(JSDOC).
- * @param {number} pos // TODO(JSDOC).
- * @param {boolean} bom // TODO(JSDOC).
- * @param {number} size // TODO(JSDOC).
- * @param {number=} opt_end // TODO(JSDOC).
- * @return {string} // TODO(JSDOC).
- */
-ByteReader.readNullTerminatedStringUTF16 = function(
- dataView, pos, bom, size, opt_end) {
- ByteReader.validateRead(pos, size, opt_end || dataView.byteLength);
-
- var littleEndian = false;
- var start = 0;
-
- if (bom) {
- littleEndian = (dataView.getUint8(pos) == 0xFF);
- start = 2;
- }
-
- var codes = [];
-
- for (var i = start; i < size; i += 2) {
- var code = dataView.getUint16(pos + i, littleEndian);
- if (code == 0) break;
- codes.push(code);
- }
-
- return String.fromCharCode.apply(null, codes);
-};
-
-/**
- * @const
- * @type {Array.<string>}
- * @private
- */
-ByteReader.base64Alphabet_ =
- ('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/').
- split('');
-
-/**
- * Read as a sequence of bytes, returning them as a single base64 encoded
- * string.
- *
- * This is a static utility function. There is a member function with the
- * same name which side-effects the current read position.
- *
- * @param {DataView} dataView // TODO(JSDOC).
- * @param {number} pos // TODO(JSDOC).
- * @param {number} size // TODO(JSDOC).
- * @param {number=} opt_end // TODO(JSDOC).
- * @return {string} // TODO(JSDOC).
- */
-ByteReader.readBase64 = function(dataView, pos, size, opt_end) {
- ByteReader.validateRead(pos, size, opt_end || dataView.byteLength);
-
- var rv = [];
- var chars = [];
- var padding = 0;
-
- for (var i = 0; i < size; /* incremented inside */) {
- var bits = dataView.getUint8(pos + (i++)) << 16;
-
- if (i < size) {
- bits |= dataView.getUint8(pos + (i++)) << 8;
-
- if (i < size) {
- bits |= dataView.getUint8(pos + (i++));
- } else {
- padding = 1;
- }
- } else {
- padding = 2;
- }
-
- chars[3] = ByteReader.base64Alphabet_[bits & 63];
- chars[2] = ByteReader.base64Alphabet_[(bits >> 6) & 63];
- chars[1] = ByteReader.base64Alphabet_[(bits >> 12) & 63];
- chars[0] = ByteReader.base64Alphabet_[(bits >> 18) & 63];
-
- rv.push.apply(rv, chars);
- }
-
- if (padding > 0)
- rv[rv.length - 1] = '=';
- if (padding > 1)
- rv[rv.length - 2] = '=';
-
- return rv.join('');
-};
-
-/**
- * Read as an image encoded in a data url.
- *
- * This is a static utility function. There is a member function with the
- * same name which side-effects the current read position.
- *
- * @param {DataView} dataView // TODO(JSDOC).
- * @param {number} pos // TODO(JSDOC).
- * @param {number} size // TODO(JSDOC).
- * @param {number=} opt_end // TODO(JSDOC).
- * @return {string} // TODO(JSDOC).
- */
-ByteReader.readImage = function(dataView, pos, size, opt_end) {
- opt_end = opt_end || dataView.byteLength;
- ByteReader.validateRead(pos, size, opt_end);
-
- // Two bytes is enough to identify the mime type.
- var prefixToMime = {
- '\x89P' : 'png',
- '\xFF\xD8' : 'jpeg',
- 'BM' : 'bmp',
- 'GI' : 'gif'
- };
-
- var prefix = ByteReader.readString(dataView, pos, 2, opt_end);
- var mime = prefixToMime[prefix] ||
- dataView.getUint16(pos, false).toString(16); // For debugging.
-
- var b64 = ByteReader.readBase64(dataView, pos, size, opt_end);
- return 'data:image/' + mime + ';base64,' + b64;
-};
-
-// Instance methods.
-
-/**
- * Return true if the requested number of bytes can be read from the buffer.
- *
- * @param {number} size // TODO(JSDOC).
- * @return {boolean} // TODO(JSDOC).
- */
-ByteReader.prototype.canRead = function(size) {
- return this.pos_ + size <= this.view_.byteLength;
-};
-
-/**
- * Return true if the current position is past the end of the buffer.
- * @return {boolean} // TODO(JSDOC).
- */
-ByteReader.prototype.eof = function() {
- return this.pos_ >= this.view_.byteLength;
-};
-
-/**
- * Return true if the current position is before the beginning of the buffer.
- * @return {boolean} // TODO(JSDOC).
- */
-ByteReader.prototype.bof = function() {
- return this.pos_ < 0;
-};
-
-/**
- * Return true if the current position is outside the buffer.
- * @return {boolean} // TODO(JSDOC).
- */
-ByteReader.prototype.beof = function() {
- return this.pos_ >= this.view_.byteLength || this.pos_ < 0;
-};
-
-/**
- * Set the expected byte ordering for future reads.
- * @param {number} order // TODO(JSDOC).
- */
-ByteReader.prototype.setByteOrder = function(order) {
- this.littleEndian_ = order == ByteReader.LITTLE_ENDIAN;
-};
-
-/**
- * Throw an error if the reader is at an invalid position, or if a read a read
- * of |size| would put it in one.
- *
- * You may optionally pass opt_end to override what is considered to be the
- * end of the buffer.
- *
- * @param {number} size // TODO(JSDOC).
- * @param {number=} opt_end // TODO(JSDOC).
- */
-ByteReader.prototype.validateRead = function(size, opt_end) {
- if (typeof opt_end == 'undefined')
- opt_end = this.view_.byteLength;
-
- ByteReader.validateRead(this.view_, this.pos_, size, opt_end);
-};
-
-/**
- * @param {number} width // TODO(JSDOC).
- * @param {boolean=} opt_signed // TODO(JSDOC).
- * @param {number=} opt_end // TODO(JSDOC).
- * @return {string} // TODO(JSDOC).
- */
-ByteReader.prototype.readScalar = function(width, opt_signed, opt_end) {
- var method = opt_signed ? 'getInt' : 'getUint';
-
- switch (width) {
- case 1:
- method += '8';
- break;
-
- case 2:
- method += '16';
- break;
-
- case 4:
- method += '32';
- break;
-
- case 8:
- method += '64';
- break;
-
- default:
- throw new Error('Invalid width: ' + width);
- break;
- }
-
- this.validateRead(width, opt_end);
- var rv = this.view_[method](this.pos_, this.littleEndian_);
- this.pos_ += width;
- return rv;
-};
-
-/**
- * Read as a sequence of characters, returning them as a single string.
- *
- * Adjusts the current position on success. Throws an exception if the
- * read would go past the end of the buffer.
- *
- * @param {number} size // TODO(JSDOC).
- * @param {number=} opt_end // TODO(JSDOC).
- * @return {string} // TODO(JSDOC).
- */
-ByteReader.prototype.readString = function(size, opt_end) {
- var rv = ByteReader.readString(this.view_, this.pos_, size, opt_end);
- this.pos_ += size;
- return rv;
-};
-
-
-/**
- * Read as a sequence of characters, returning them as a single string.
- *
- * Adjusts the current position on success. Throws an exception if the
- * read would go past the end of the buffer.
- *
- * @param {number} size // TODO(JSDOC).
- * @param {number=} opt_end // TODO(JSDOC).
- * @return {string} // TODO(JSDOC).
- */
-ByteReader.prototype.readNullTerminatedString = function(size, opt_end) {
- var rv = ByteReader.readNullTerminatedString(this.view_,
- this.pos_,
- size,
- opt_end);
- this.pos_ += rv.length;
-
- if (rv.length < size) {
- // If we've stopped reading because we found '0' but didn't hit size limit
- // then we should skip additional '0' character
- this.pos_++;
- }
-
- return rv;
-};
-
-
-/**
- * Read as a sequence of UTF16 characters, returning them as a single string.
- *
- * Adjusts the current position on success. Throws an exception if the
- * read would go past the end of the buffer.
- *
- * @param {boolean} bom // TODO(JSDOC).
- * @param {number} size // TODO(JSDOC).
- * @param {number=} opt_end // TODO(JSDOC).
- * @return {string} // TODO(JSDOC).
- */
-ByteReader.prototype.readNullTerminatedStringUTF16 =
- function(bom, size, opt_end) {
- var rv = ByteReader.readNullTerminatedStringUTF16(
- this.view_, this.pos_, bom, size, opt_end);
-
- if (bom) {
- // If the BOM word was present advance the position.
- this.pos_ += 2;
- }
-
- this.pos_ += rv.length;
-
- if (rv.length < size) {
- // If we've stopped reading because we found '0' but didn't hit size limit
- // then we should skip additional '0' character
- this.pos_ += 2;
- }
-
- return rv;
-};
-
-
-/**
- * Read as an array of numbers.
- *
- * Adjusts the current position on success. Throws an exception if the
- * read would go past the end of the buffer.
- *
- * @param {number} size // TODO(JSDOC).
- * @param {number=} opt_end // TODO(JSDOC).
- * @param {function(new:Array.<*>)=} opt_arrayConstructor // TODO(JSDOC).
- * @return {Array.<*>} // TODO(JSDOC).
- */
-ByteReader.prototype.readSlice = function(size, opt_end,
- opt_arrayConstructor) {
- this.validateRead(size, opt_end);
-
- var arrayConstructor = opt_arrayConstructor || Uint8Array;
- var slice = new arrayConstructor(
- this.view_.buffer, this.view_.byteOffset + this.pos, size);
- this.pos_ += size;
-
- return slice;
-};
-
-/**
- * Read as a sequence of bytes, returning them as a single base64 encoded
- * string.
- *
- * Adjusts the current position on success. Throws an exception if the
- * read would go past the end of the buffer.
- *
- * @param {number} size // TODO(JSDOC).
- * @param {number=} opt_end // TODO(JSDOC).
- * @return {string} // TODO(JSDOC).
- */
-ByteReader.prototype.readBase64 = function(size, opt_end) {
- var rv = ByteReader.readBase64(this.view_, this.pos_, size, opt_end);
- this.pos_ += size;
- return rv;
-};
-
-/**
- * Read an image returning it as a data url.
- *
- * Adjusts the current position on success. Throws an exception if the
- * read would go past the end of the buffer.
- *
- * @param {number} size // TODO(JSDOC).
- * @param {number=} opt_end // TODO(JSDOC).
- * @return {string} // TODO(JSDOC).
- */
-ByteReader.prototype.readImage = function(size, opt_end) {
- var rv = ByteReader.readImage(this.view_, this.pos_, size, opt_end);
- this.pos_ += size;
- return rv;
-};
-
-/**
- * Seek to a give position relative to opt_seekStart.
- *
- * @param {number} pos // TODO(JSDOC).
- * @param {number=} opt_seekStart // TODO(JSDOC).
- * @param {number=} opt_end // TODO(JSDOC).
- */
-ByteReader.prototype.seek = function(pos, opt_seekStart, opt_end) {
- opt_end = opt_end || this.view_.byteLength;
-
- var newPos;
- if (opt_seekStart == ByteReader.SEEK_CUR) {
- newPos = this.pos_ + pos;
- } else if (opt_seekStart == ByteReader.SEEK_END) {
- newPos = opt_end + pos;
- } else {
- newPos = pos;
- }
-
- if (newPos < 0 || newPos > this.view_.byteLength)
- throw new Error('Seek outside of buffer: ' + (newPos - opt_end));
-
- this.pos_ = newPos;
-};
-
-/**
- * Seek to a given position relative to opt_seekStart, saving the current
- * position.
- *
- * Recover the current position with a call to seekPop.
- *
- * @param {number} pos // TODO(JSDOC).
- * @param {number=} opt_seekStart // TODO(JSDOC).
- */
-ByteReader.prototype.pushSeek = function(pos, opt_seekStart) {
- var oldPos = this.pos_;
- this.seek(pos, opt_seekStart);
- // Alter the seekStack_ after the call to seek(), in case it throws.
- this.seekStack_.push(oldPos);
-};
-
-/**
- * Undo a previous seekPush.
- */
-ByteReader.prototype.popSeek = function() {
- this.seek(this.seekStack_.pop());
-};
-
-/**
- * Return the current read position.
- * @return {number} // TODO(JSDOC).
- */
-ByteReader.prototype.tell = function() {
- return this.pos_;
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/exif_parser.js b/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/exif_parser.js
deleted file mode 100644
index f81e5cc0b9f..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/exif_parser.js
+++ /dev/null
@@ -1,439 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-var EXIF_MARK_SOI = 0xffd8; // Start of image data.
-var EXIF_MARK_SOS = 0xffda; // Start of "stream" (the actual image data).
-var EXIF_MARK_SOF = 0xffc0; // Start of "frame"
-var EXIF_MARK_EXIF = 0xffe1; // Start of exif block.
-
-var EXIF_ALIGN_LITTLE = 0x4949; // Indicates little endian exif data.
-var EXIF_ALIGN_BIG = 0x4d4d; // Indicates big endian exif data.
-
-var EXIF_TAG_TIFF = 0x002a; // First directory containing TIFF data.
-var EXIF_TAG_GPSDATA = 0x8825; // Pointer from TIFF to the GPS directory.
-var EXIF_TAG_EXIFDATA = 0x8769; // Pointer from TIFF to the EXIF IFD.
-var EXIF_TAG_SUBIFD = 0x014a; // Pointer from TIFF to "Extra" IFDs.
-
-var EXIF_TAG_JPG_THUMB_OFFSET = 0x0201; // Pointer from TIFF to thumbnail.
-var EXIF_TAG_JPG_THUMB_LENGTH = 0x0202; // Length of thumbnail data.
-
-var EXIF_TAG_ORIENTATION = 0x0112;
-var EXIF_TAG_X_DIMENSION = 0xA002;
-var EXIF_TAG_Y_DIMENSION = 0xA003;
-
-function ExifParser(parent) {
- ImageParser.call(this, parent, 'jpeg', /\.jpe?g$/i);
-}
-
-ExifParser.prototype = {__proto__: ImageParser.prototype};
-
-/**
- * @param {File} file // TODO(JSDOC).
- * @param {Object} metadata // TODO(JSDOC).
- * @param {function} callback // TODO(JSDOC).
- * @param {function} errorCallback // TODO(JSDOC).
- */
-ExifParser.prototype.parse = function(file, metadata, callback, errorCallback) {
- this.requestSlice(file, callback, errorCallback, metadata, 0);
-};
-
-/**
- * @param {File} file // TODO(JSDOC).
- * @param {function} callback // TODO(JSDOC).
- * @param {function} errorCallback // TODO(JSDOC).
- * @param {Object} metadata // TODO(JSDOC).
- * @param {number} filePos // TODO(JSDOC).
- * @param {number=} opt_length // TODO(JSDOC).
- */
-ExifParser.prototype.requestSlice = function(
- file, callback, errorCallback, metadata, filePos, opt_length) {
- // Read at least 1Kb so that we do not issue too many read requests.
- opt_length = Math.max(1024, opt_length || 0);
-
- var self = this;
- var reader = new FileReader();
- reader.onerror = errorCallback;
- reader.onload = function() { self.parseSlice(
- file, callback, errorCallback, metadata, filePos, reader.result);
- };
- reader.readAsArrayBuffer(file.slice(filePos, filePos + opt_length));
-};
-
-/**
- * @param {File} file // TODO(JSDOC).
- * @param {function} callback // TODO(JSDOC).
- * @param {function} errorCallback // TODO(JSDOC).
- * @param {Object} metadata // TODO(JSDOC).
- * @param {number} filePos // TODO(JSDOC).
- * @param {ArrayBuffer} buf // TODO(JSDOC).
- */
-ExifParser.prototype.parseSlice = function(
- file, callback, errorCallback, metadata, filePos, buf) {
- try {
- var br = new ByteReader(buf);
-
- if (!br.canRead(4)) {
- // We never ask for less than 4 bytes. This can only mean we reached EOF.
- throw new Error('Unexpected EOF @' + (filePos + buf.byteLength));
- }
-
- if (filePos == 0) {
- // First slice, check for the SOI mark.
- var firstMark = this.readMark(br);
- if (firstMark != EXIF_MARK_SOI)
- throw new Error('Invalid file header: ' + firstMark.toString(16));
- }
-
- var self = this;
- var reread = function(opt_offset, opt_bytes) {
- self.requestSlice(file, callback, errorCallback, metadata,
- filePos + br.tell() + (opt_offset || 0), opt_bytes);
- };
-
- while (true) {
- if (!br.canRead(4)) {
- // Cannot read the mark and the length, request a minimum-size slice.
- reread();
- return;
- }
-
- var mark = this.readMark(br);
- if (mark == EXIF_MARK_SOS)
- throw new Error('SOS marker found before SOF');
-
- var markLength = this.readMarkLength(br);
-
- var nextSectionStart = br.tell() + markLength;
- if (!br.canRead(markLength)) {
- // Get the entire section.
- if (filePos + br.tell() + markLength > file.size) {
- throw new Error(
- 'Invalid section length @' + (filePos + br.tell() - 2));
- }
- reread(-4, markLength + 4);
- return;
- }
-
- if (mark == EXIF_MARK_EXIF) {
- this.parseExifSection(metadata, buf, br);
- } else if (ExifParser.isSOF_(mark)) {
- // The most reliable size information is encoded in the SOF section.
- br.seek(1, ByteReader.SEEK_CUR); // Skip the precision byte.
- var height = br.readScalar(2);
- var width = br.readScalar(2);
- ExifParser.setImageSize(metadata, width, height);
- callback(metadata); // We are done!
- return;
- }
-
- br.seek(nextSectionStart, ByteReader.SEEK_BEG);
- }
- } catch (e) {
- errorCallback(e.toString());
- }
-};
-
-/**
- * @private
- * @param {number} mark // TODO(JSDOC).
- * @return {boolean} // TODO(JSDOC).
- */
-ExifParser.isSOF_ = function(mark) {
- // There are 13 variants of SOF fragment format distinguished by the last
- // hex digit of the mark, but the part we want is always the same.
- if ((mark & ~0xF) != EXIF_MARK_SOF) return false;
-
- // If the last digit is 4, 8 or 12 it is not really a SOF.
- var type = mark & 0xF;
- return (type != 4 && type != 8 && type != 12);
-};
-
-/**
- * @param {Object} metadata // TODO(JSDOC).
- * @param {ArrayBuffer} buf // TODO(JSDOC).
- * @param {ByteReader} br // TODO(JSDOC).
- */
-ExifParser.prototype.parseExifSection = function(metadata, buf, br) {
- var magic = br.readString(6);
- if (magic != 'Exif\0\0') {
- // Some JPEG files may have sections marked with EXIF_MARK_EXIF
- // but containing something else (e.g. XML text). Ignore such sections.
- this.vlog('Invalid EXIF magic: ' + magic + br.readString(100));
- return;
- }
-
- // Offsets inside the EXIF block are based after the magic string.
- // Create a new ByteReader based on the current position to make offset
- // calculations simpler.
- br = new ByteReader(buf, br.tell());
-
- var order = br.readScalar(2);
- if (order == EXIF_ALIGN_LITTLE) {
- br.setByteOrder(ByteReader.LITTLE_ENDIAN);
- } else if (order != EXIF_ALIGN_BIG) {
- this.log('Invalid alignment value: ' + order.toString(16));
- return;
- }
-
- var tag = br.readScalar(2);
- if (tag != EXIF_TAG_TIFF) {
- this.log('Invalid TIFF tag: ' + tag.toString(16));
- return;
- }
-
- metadata.littleEndian = (order == EXIF_ALIGN_LITTLE);
- metadata.ifd = {
- image: {},
- thumbnail: {}
- };
- var directoryOffset = br.readScalar(4);
-
- // Image directory.
- this.vlog('Read image directory.');
- br.seek(directoryOffset);
- directoryOffset = this.readDirectory(br, metadata.ifd.image);
- metadata.imageTransform = this.parseOrientation(metadata.ifd.image);
-
- // Thumbnail Directory chained from the end of the image directory.
- if (directoryOffset) {
- this.vlog('Read thumbnail directory.');
- br.seek(directoryOffset);
- this.readDirectory(br, metadata.ifd.thumbnail);
- // If no thumbnail orientation is encoded, assume same orientation as
- // the primary image.
- metadata.thumbnailTransform =
- this.parseOrientation(metadata.ifd.thumbnail) ||
- metadata.imageTransform;
- }
-
- // EXIF Directory may be specified as a tag in the image directory.
- if (EXIF_TAG_EXIFDATA in metadata.ifd.image) {
- this.vlog('Read EXIF directory.');
- directoryOffset = metadata.ifd.image[EXIF_TAG_EXIFDATA].value;
- br.seek(directoryOffset);
- metadata.ifd.exif = {};
- this.readDirectory(br, metadata.ifd.exif);
- }
-
- // GPS Directory may also be linked from the image directory.
- if (EXIF_TAG_GPSDATA in metadata.ifd.image) {
- this.vlog('Read GPS directory.');
- directoryOffset = metadata.ifd.image[EXIF_TAG_GPSDATA].value;
- br.seek(directoryOffset);
- metadata.ifd.gps = {};
- this.readDirectory(br, metadata.ifd.gps);
- }
-
- // Thumbnail may be linked from the image directory.
- if (EXIF_TAG_JPG_THUMB_OFFSET in metadata.ifd.thumbnail &&
- EXIF_TAG_JPG_THUMB_LENGTH in metadata.ifd.thumbnail) {
- this.vlog('Read thumbnail image.');
- br.seek(metadata.ifd.thumbnail[EXIF_TAG_JPG_THUMB_OFFSET].value);
- metadata.thumbnailURL = br.readImage(
- metadata.ifd.thumbnail[EXIF_TAG_JPG_THUMB_LENGTH].value);
- } else {
- this.vlog('Image has EXIF data, but no JPG thumbnail.');
- }
-};
-
-/**
- * @param {Object} metadata // TODO(JSDOC).
- * @param {number} width // TODO(JSDOC).
- * @param {number} height // TODO(JSDOC).
- */
-ExifParser.setImageSize = function(metadata, width, height) {
- if (metadata.imageTransform && metadata.imageTransform.rotate90) {
- metadata.width = height;
- metadata.height = width;
- } else {
- metadata.width = width;
- metadata.height = height;
- }
-};
-
-/**
- * @param {ByteReader} br // TODO(JSDOC).
- * @return {number} // TODO(JSDOC).
- */
-ExifParser.prototype.readMark = function(br) {
- return br.readScalar(2);
-};
-
-/**
- * @param {ByteReader} br // TODO(JSDOC).
- * @return {number} // TODO(JSDOC).
- */
-ExifParser.prototype.readMarkLength = function(br) {
- // Length includes the 2 bytes used to store the length.
- return br.readScalar(2) - 2;
-};
-
-/**
- * @param {ByteReader} br // TODO(JSDOC).
- * @param {Array.<Object>} tags // TODO(JSDOC).
- * @return {number} // TODO(JSDOC).
- */
-ExifParser.prototype.readDirectory = function(br, tags) {
- var entryCount = br.readScalar(2);
- for (var i = 0; i < entryCount; i++) {
- var tagId = br.readScalar(2);
- var tag = tags[tagId] = {id: tagId};
- tag.format = br.readScalar(2);
- tag.componentCount = br.readScalar(4);
- this.readTagValue(br, tag);
- }
-
- return br.readScalar(4);
-};
-
-/**
- * @param {ByteReader} br // TODO(JSDOC).
- * @param {Object} tag // TODO(JSDOC).
- */
-ExifParser.prototype.readTagValue = function(br, tag) {
- var self = this;
-
- function safeRead(size, readFunction, signed) {
- try {
- unsafeRead(size, readFunction, signed);
- } catch (ex) {
- self.log('error reading tag 0x' + tag.id.toString(16) + '/' +
- tag.format + ', size ' + tag.componentCount + '*' + size + ' ' +
- (ex.stack || '<no stack>') + ': ' + ex);
- tag.value = null;
- }
- }
-
- function unsafeRead(size, readFunction, signed) {
- if (!readFunction)
- readFunction = function(size) { return br.readScalar(size, signed) };
-
- var totalSize = tag.componentCount * size;
- if (totalSize < 1) {
- // This is probably invalid exif data, skip it.
- tag.componentCount = 1;
- tag.value = br.readScalar(4);
- return;
- }
-
- if (totalSize > 4) {
- // If the total size is > 4, the next 4 bytes will be a pointer to the
- // actual data.
- br.pushSeek(br.readScalar(4));
- }
-
- if (tag.componentCount == 1) {
- tag.value = readFunction(size);
- } else {
- // Read multiple components into an array.
- tag.value = [];
- for (var i = 0; i < tag.componentCount; i++)
- tag.value[i] = readFunction(size);
- }
-
- if (totalSize > 4) {
- // Go back to the previous position if we had to jump to the data.
- br.popSeek();
- } else if (totalSize < 4) {
- // Otherwise, if the value wasn't exactly 4 bytes, skip over the
- // unread data.
- br.seek(4 - totalSize, ByteReader.SEEK_CUR);
- }
- }
-
- switch (tag.format) {
- case 1: // Byte
- case 7: // Undefined
- safeRead(1);
- break;
-
- case 2: // String
- safeRead(1);
- if (tag.componentCount == 0) {
- tag.value = '';
- } else if (tag.componentCount == 1) {
- tag.value = String.fromCharCode(tag.value);
- } else {
- tag.value = String.fromCharCode.apply(null, tag.value);
- }
- break;
-
- case 3: // Short
- safeRead(2);
- break;
-
- case 4: // Long
- safeRead(4);
- break;
-
- case 9: // Signed Long
- safeRead(4, null, true);
- break;
-
- case 5: // Rational
- safeRead(8, function() {
- return [br.readScalar(4), br.readScalar(4)];
- });
- break;
-
- case 10: // Signed Rational
- safeRead(8, function() {
- return [br.readScalar(4, true), br.readScalar(4, true)];
- });
- break;
-
- default: // ???
- this.vlog('Unknown tag format 0x' + Number(tag.id).toString(16) +
- ': ' + tag.format);
- safeRead(4);
- break;
- }
-
- this.vlog('Read tag: 0x' + tag.id.toString(16) + '/' + tag.format + ': ' +
- tag.value);
-};
-
-/**
- * TODO(JSDOC)
- * @const
- * @type {Array.<number>}
- */
-ExifParser.SCALEX = [1, -1, -1, 1, 1, 1, -1, -1];
-
-/**
- * TODO(JSDOC)
- * @const
- * @type {Array.<number>}
- */
-ExifParser.SCALEY = [1, 1, -1, -1, -1, 1, 1, -1];
-
-/**
- * TODO(JSDOC)
- * @const
- * @type {Array.<number>}
- */
-ExifParser.ROTATE90 = [0, 0, 0, 0, 1, 1, 1, 1];
-
-/**
- * Transform exif-encoded orientation into a set of parameters compatible with
- * CSS and canvas transforms (scaleX, scaleY, rotation).
- *
- * @param {Object} ifd exif property dictionary (image or thumbnail).
- * @return {Object} // TODO(JSDOC).
- */
-ExifParser.prototype.parseOrientation = function(ifd) {
- if (ifd[EXIF_TAG_ORIENTATION]) {
- var index = (ifd[EXIF_TAG_ORIENTATION].value || 1) - 1;
- return {
- scaleX: ExifParser.SCALEX[index],
- scaleY: ExifParser.SCALEY[index],
- rotate90: ExifParser.ROTATE90[index]
- };
- }
- return null;
-};
-
-MetadataDispatcher.registerParserClass(ExifParser);
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/function_parallel.js b/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/function_parallel.js
deleted file mode 100644
index 1691a89a1fa..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/function_parallel.js
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * @class FunctionSequence to invoke steps in sequence
- *
- * @param {string} name // TODO(JSDOC).
- * @param {Array.<function>} steps Array of functions to invoke in parallel.
- * @param {Object} logger // TODO(JSDOC).
- * @param {function()} callback Callback to invoke on success.
- * @param {function(string)} failureCallback Callback to invoke on failure.
- * @constructor
- */
-function FunctionParallel(name, steps, logger, callback, failureCallback) {
- // Private variables hidden in closure
- this.currentStepIdx_ = -1;
- this.failed_ = false;
- this.steps_ = steps;
- this.callback_ = callback;
- this.failureCallback_ = failureCallback;
- this.logger = logger;
- this.name = name;
-
- this.remaining = this.steps_.length;
-
- this.nextStep = this.nextStep_.bind(this);
- this.onError = this.onError_.bind(this);
- this.apply = this.start.bind(this);
-}
-
-
-/**
- * Error handling function, which fires error callback.
- *
- * @param {string} err Error message.
- * @private
- */
-FunctionParallel.prototype.onError_ = function(err) {
- if (!this.failed_) {
- this.failed_ = true;
- this.failureCallback_(err);
- }
-};
-
-/**
- * Advances to next step. This method should not be used externally. In external
- * cases should be used nextStep function, which is defined in closure and thus
- * has access to internal variables of functionsequence.
- *
- * @private
- */
-FunctionParallel.prototype.nextStep_ = function() {
- if (--this.remaining == 0 && !this.failed_) {
- this.callback_();
- }
-};
-
-/**
- * This function should be called only once on start, so start all the children
- * at once
- * @param {...} var_args // TODO(JSDOC).
- */
-FunctionParallel.prototype.start = function(var_args) {
- this.logger.vlog('Starting [' + this.steps_.length + '] parallel tasks ' +
- 'with ' + arguments.length + ' argument(s)');
- if (this.logger.verbose) {
- for (var j = 0; j < arguments.length; j++) {
- this.logger.vlog(arguments[j]);
- }
- }
- for (var i = 0; i < this.steps_.length; i++) {
- this.logger.vlog('Attempting to start step [' + this.steps_[i].name + ']');
- try {
- this.steps_[i].apply(this, arguments);
- } catch (e) {
- this.onError(e.toString());
- }
- }
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/function_sequence.js b/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/function_sequence.js
deleted file mode 100644
index a2372f9f146..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/function_sequence.js
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * @class FunctionSequence to invoke steps in sequence
- *
- * @param {string} name // TODO(JSDOC).
- * @param {Array} steps array of functions to invoke in sequence.
- * @param {Object} logger logger.
- * @param {function} callback callback to invoke on success.
- * @param {function} failureCallback callback to invoke on failure.
- * @constructor
- */
-function FunctionSequence(name, steps, logger, callback, failureCallback) {
- // Private variables hidden in closure
- this.currentStepIdx_ = -1;
- this.failed_ = false;
- this.steps_ = steps;
- this.callback_ = callback;
- this.failureCallback_ = failureCallback;
- this.logger = logger;
- this.name = name;
-
- this.onError = this.onError_.bind(this);
- this.finish = this.finish_.bind(this);
- this.nextStep = this.nextStep_.bind(this);
- this.apply = this.apply_.bind(this);
-}
-
-/**
- * Sets new callback
- *
- * @param {function} callback new callback to call on succeed.
- */
-FunctionSequence.prototype.setCallback = function(callback) {
- this.callback_ = callback;
-};
-
-/**
- * Sets new error callback
- *
- * @param {function} failureCallback new callback to call on failure.
- */
-FunctionSequence.prototype.setFailureCallback = function(failureCallback) {
- this.failureCallback_ = failureCallback;
-};
-
-
-/**
- * Error handling function, which traces current error step, stops sequence
- * advancing and fires error callback.
- *
- * @param {string} err Error message.
- * @private
- */
-FunctionSequence.prototype.onError_ = function(err) {
- this.logger.vlog('Failed step: ' + this.steps_[this.currentStepIdx_].name +
- ': ' + err);
- if (!this.failed_) {
- this.failed_ = true;
- this.failureCallback_(err);
- }
-};
-
-/**
- * Finishes sequence processing and jumps to the last step.
- * This method should not be used externally. In external
- * cases should be used finish function, which is defined in closure and thus
- * has access to internal variables of functionsequence.
- * @private
- */
-FunctionSequence.prototype.finish_ = function() {
- if (!this.failed_ && this.currentStepIdx_ < this.steps_.length) {
- this.currentStepIdx_ = this.steps_.length;
- this.callback_();
- }
-};
-
-/**
- * Advances to next step.
- * This method should not be used externally. In external
- * cases should be used nextStep function, which is defined in closure and thus
- * has access to internal variables of functionsequence.
- * @private
- * @param {...} var_args // TODO(JSDOC).
- */
-FunctionSequence.prototype.nextStep_ = function(var_args) {
- if (this.failed_) {
- return;
- }
-
- if (++this.currentStepIdx_ >= this.steps_.length) {
- this.logger.vlog('Sequence ended');
- this.callback_.apply(this, arguments);
- } else {
- this.logger.vlog('Attempting to start step [' +
- this.steps_[this.currentStepIdx_].name +
- ']');
- try {
- this.steps_[this.currentStepIdx_].apply(this, arguments);
- } catch (e) {
- this.onError(e.toString());
- }
- }
-};
-
-/**
- * This function should be called only once on start, so start sequence pipeline
- * @param {...} var_args // TODO(JSDOC).
- */
-FunctionSequence.prototype.start = function(var_args) {
- if (this.started) {
- throw new Error('"Start" method of FunctionSequence was called twice');
- }
-
- this.logger.log('Starting sequence with ' + arguments.length + ' arguments');
-
- this.started = true;
- this.nextStep.apply(this, arguments);
-};
-
-/**
- * Add Function object mimics to FunctionSequence
- * @private
- * @param {*} obj // TODO(JSDOC).
- * @param {Array.*} args // TODO(JSDOC).
- */
-FunctionSequence.prototype.apply_ = function(obj, args) {
- this.start.apply(this, args);
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/id3_parser.js b/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/id3_parser.js
deleted file mode 100644
index 4037d02e43e..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/id3_parser.js
+++ /dev/null
@@ -1,708 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-importScripts('function_sequence.js');
-importScripts('function_parallel.js');
-
-function Id3Parser(parent) {
- MetadataParser.call(this, parent, 'id3', /\.(mp3)$/i);
-}
-
-Id3Parser.prototype = {__proto__: MetadataParser.prototype};
-
-/**
- * Reads synchsafe integer.
- * 'SynchSafe' term is taken from id3 documentation.
- *
- * @param {ByteReader} reader - reader to use.
- * @param {number} length - bytes to read.
- * @return {number} // TODO(JSDOC).
- * @private
- */
-Id3Parser.readSynchSafe_ = function(reader, length) {
- var rv = 0;
-
- switch (length) {
- case 4:
- rv = reader.readScalar(1, false) << 21;
- case 3:
- rv |= reader.readScalar(1, false) << 14;
- case 2:
- rv |= reader.readScalar(1, false) << 7;
- case 1:
- rv |= reader.readScalar(1, false);
- }
-
- return rv;
-};
-
-/**
- * Reads 3bytes integer.
- *
- * @param {ByteReader} reader - reader to use.
- * @return {number} // TODO(JSDOC).
- * @private
- */
-Id3Parser.readUInt24_ = function(reader) {
- return reader.readScalar(2, false) << 16 | reader.readScalar(1, false);
-};
-
-/**
- * Reads string from reader with specified encoding
- *
- * @param {ByteReader} reader reader to use.
- * @param {number} encoding string encoding.
- * @param {number} size maximum string size. Actual result may be shorter.
- * @return {string} // TODO(JSDOC).
- * @private
- */
-Id3Parser.prototype.readString_ = function(reader, encoding, size) {
- switch (encoding) {
- case Id3Parser.v2.ENCODING.ISO_8859_1:
- return reader.readNullTerminatedString(size);
-
- case Id3Parser.v2.ENCODING.UTF_16:
- return reader.readNullTerminatedStringUTF16(true, size);
-
- case Id3Parser.v2.ENCODING.UTF_16BE:
- return reader.readNullTerminatedStringUTF16(false, size);
-
- case Id3Parser.v2.ENCODING.UTF_8:
- // TODO: implement UTF_8.
- this.log('UTF8 encoding not supported, used ISO_8859_1 instead');
- return reader.readNullTerminatedString(size);
-
- default: {
- this.log('Unsupported encoding in ID3 tag: ' + encoding);
- return '';
- }
- }
-};
-
-/**
- * Reads text frame from reader.
- *
- * @param {ByteReader} reader reader to use.
- * @param {number} majorVersion major id3 version to use.
- * @param {Object} frame frame so store data at.
- * @param {number} end frame end position in reader.
- * @private
- */
-Id3Parser.prototype.readTextFrame_ = function(reader,
- majorVersion,
- frame,
- end) {
- frame.encoding = reader.readScalar(1, false, end);
- frame.value = this.readString_(reader, frame.encoding, end - reader.tell());
-};
-
-/**
- * Reads user defined text frame from reader.
- *
- * @param {ByteReader} reader reader to use.
- * @param {number} majorVersion major id3 version to use.
- * @param {Object} frame frame so store data at.
- * @param {number} end frame end position in reader.
- * @private
- */
-Id3Parser.prototype.readUserDefinedTextFrame_ = function(reader,
- majorVersion,
- frame,
- end) {
- frame.encoding = reader.readScalar(1, false, end);
-
- frame.description = this.readString_(
- reader,
- frame.encoding,
- end - reader.tell());
-
- frame.value = this.readString_(
- reader,
- frame.encoding,
- end - reader.tell());
-};
-
-/**
- * @param {ByteReader} reader Reader to use.
- * @param {number} majorVersion Major id3 version to use.
- * @param {Object} frame Frame so store data at.
- * @param {number} end Frame end position in reader.
- * @private
- */
-Id3Parser.prototype.readPIC_ = function(reader, majorVersion, frame, end) {
- frame.encoding = reader.readScalar(1, false, end);
- frame.format = reader.readNullTerminatedString(3, end - reader.tell());
- frame.pictureType = reader.readScalar(1, false, end);
- frame.description = this.readString_(reader,
- frame.encoding,
- end - reader.tell());
-
-
- if (frame.format == '-->') {
- frame.imageUrl = reader.readNullTerminatedString(end - reader.tell());
- } else {
- frame.imageUrl = reader.readImage(end - reader.tell());
- }
-};
-
-/**
- * @param {ByteReader} reader Reader to use.
- * @param {number} majorVersion Major id3 version to use.
- * @param {Object} frame Frame so store data at.
- * @param {number} end Frame end position in reader.
- * @private
- */
-Id3Parser.prototype.readAPIC_ = function(reader, majorVersion, frame, end) {
- this.vlog('Extracting picture');
- frame.encoding = reader.readScalar(1, false, end);
- frame.mime = reader.readNullTerminatedString(end - reader.tell());
- frame.pictureType = reader.readScalar(1, false, end);
- frame.description = this.readString_(
- reader,
- frame.encoding,
- end - reader.tell());
-
- if (frame.mime == '-->') {
- frame.imageUrl = reader.readNullTerminatedString(end - reader.tell());
- } else {
- frame.imageUrl = reader.readImage(end - reader.tell());
- }
-};
-
-/**
- * Reads string from reader with specified encoding
- *
- * @param {ByteReader} reader reader to use.
- * @param {number} majorVersion // TODO(JSDOC).
- * @return {Object} frame read.
- * @private
- */
-Id3Parser.prototype.readFrame_ = function(reader, majorVersion) {
- if (reader.eof())
- return null;
-
- var frame = {};
-
- reader.pushSeek(reader.tell(), ByteReader.SEEK_BEG);
-
- var position = reader.tell();
-
- frame.name = (majorVersion == 2) ? reader.readNullTerminatedString(3) :
- reader.readNullTerminatedString(4);
-
- if (frame.name == '')
- return null;
-
- this.vlog('Found frame ' + (frame.name) + ' at position ' + position);
-
- switch (majorVersion) {
- case 2:
- frame.size = Id3Parser.readUInt24_(reader);
- frame.headerSize = 6;
- break;
- case 3:
- frame.size = reader.readScalar(4, false);
- frame.headerSize = 10;
- frame.flags = reader.readScalar(2, false);
- break;
- case 4:
- frame.size = Id3Parser.readSynchSafe_(reader, 4);
- frame.headerSize = 10;
- frame.flags = reader.readScalar(2, false);
- break;
- }
-
- this.vlog('Found frame [' + frame.name + '] with size [' + frame.size + ']');
-
- if (Id3Parser.v2.HANDLERS[frame.name]) {
- Id3Parser.v2.HANDLERS[frame.name].call(
- this,
- reader,
- majorVersion,
- frame,
- reader.tell() + frame.size);
- } else if (frame.name.charAt(0) == 'T' || frame.name.charAt(0) == 'W') {
- this.readTextFrame_(
- reader,
- majorVersion,
- frame,
- reader.tell() + frame.size);
- }
-
- reader.popSeek();
-
- reader.seek(frame.size + frame.headerSize, ByteReader.SEEK_CUR);
-
- return frame;
-};
-
-/**
- * @param {File} file // TODO(JSDOC).
- * @param {Object} metadata // TODO(JSDOC).
- * @param {function(Object)} callback // TODO(JSDOC).
- * @param {function(etring)} onError // TODO(JSDOC).
- */
-Id3Parser.prototype.parse = function(file, metadata, callback, onError) {
- var self = this;
-
- this.log('Starting id3 parser for ' + file.name);
-
- var id3v1Parser = new FunctionSequence(
- 'id3v1parser',
- [
- /**
- * Reads last 128 bytes of file in bytebuffer,
- * which passes further.
- * In last 128 bytes should be placed ID3v1 tag if available.
- * @param {File} file File which bytes to read.
- */
- function readTail(file) {
- util.readFileBytes(file, file.size - 128, file.size,
- this.nextStep, this.onError, this);
- },
-
- /**
- * Attempts to extract ID3v1 tag from 128 bytes long ByteBuffer
- * @param {File} file File which tags are being extracted. Could be used
- * for logging purposes.
- * @param {ByteReader} reader ByteReader of 128 bytes.
- */
- function extractId3v1(file, reader) {
- if (reader.readString(3) == 'TAG') {
- this.logger.vlog('id3v1 found');
- var id3v1 = metadata.id3v1 = {};
-
- var title = reader.readNullTerminatedString(30).trim();
-
- if (title.length > 0) {
- metadata.title = title;
- }
-
- reader.seek(3 + 30, ByteReader.SEEK_BEG);
-
- var artist = reader.readNullTerminatedString(30).trim();
- if (artist.length > 0) {
- metadata.artist = artist;
- }
-
- reader.seek(3 + 30 + 30, ByteReader.SEEK_BEG);
-
- var album = reader.readNullTerminatedString(30).trim();
- if (album.length > 0) {
- metadata.album = album;
- }
- }
- this.nextStep();
- }
- ],
- this
- );
-
- var id3v2Parser = new FunctionSequence(
- 'id3v2parser',
- [
- function readHead(file) {
- util.readFileBytes(file, 0, 10, this.nextStep, this.onError,
- this);
- },
-
- /**
- * Check if passed array of 10 bytes contains ID3 header.
- * @param {File} file File to check and continue reading if ID3
- * metadata found.
- * @param {ByteReader} reader Reader to fill with stream bytes.
- */
- function checkId3v2(file, reader) {
- if (reader.readString(3) == 'ID3') {
- this.logger.vlog('id3v2 found');
- var id3v2 = metadata.id3v2 = {};
- id3v2.major = reader.readScalar(1, false);
- id3v2.minor = reader.readScalar(1, false);
- id3v2.flags = reader.readScalar(1, false);
- id3v2.size = Id3Parser.readSynchSafe_(reader, 4);
-
- util.readFileBytes(file, 10, 10 + id3v2.size, this.nextStep,
- this.onError, this);
- } else {
- this.finish();
- }
- },
-
- /**
- * Extracts all ID3v2 frames from given bytebuffer.
- * @param {File} file File being parsed.
- * @param {ByteReader} reader Reader to use for metadata extraction.
- */
- function extractFrames(file, reader) {
- var id3v2 = metadata.id3v2;
-
- if ((id3v2.major > 2) &&
- (id3v2.flags & Id3Parser.v2.FLAG_EXTENDED_HEADER != 0)) {
- // Skip extended header if found
- if (id3v2.major == 3) {
- reader.seek(reader.readScalar(4, false) - 4);
- } else if (id3v2.major == 4) {
- reader.seek(Id3Parser.readSynchSafe_(reader, 4) - 4);
- }
- }
-
- var frame;
-
- while (frame = self.readFrame_(reader, id3v2.major)) {
- metadata.id3v2[frame.name] = frame;
- }
-
- this.nextStep();
- },
-
- /**
- * Adds 'description' object to metadata.
- * 'description' used to unify different parsers and make
- * metadata parser-aware.
- * Description is array if value-type pairs. Type should be used
- * to properly format value before displaying to user.
- */
- function prepareDescription() {
- var id3v2 = metadata.id3v2;
-
- if (id3v2['APIC'])
- metadata.thumbnailURL = id3v2['APIC'].imageUrl;
- else if (id3v2['PIC'])
- metadata.thumbnailURL = id3v2['PIC'].imageUrl;
-
- metadata.description = [];
-
- for (var key in id3v2) {
- if (typeof(Id3Parser.v2.MAPPERS[key]) != 'undefined' &&
- id3v2[key].value.trim().length > 0) {
- metadata.description.push({
- key: Id3Parser.v2.MAPPERS[key],
- value: id3v2[key].value.trim()
- });
- }
- }
-
- function extract(propName, tags) {
- for (var i = 1; i != arguments.length; i++) {
- var tag = id3v2[arguments[i]];
- if (tag && tag.value) {
- metadata[propName] = tag.value;
- break;
- }
- }
- }
-
- extract('album', 'TALB', 'TAL');
- extract('title', 'TIT2', 'TT2');
- extract('artist', 'TPE1', 'TP1');
-
- metadata.description.sort(function(a, b) {
- return Id3Parser.METADATA_ORDER.indexOf(a.key) -
- Id3Parser.METADATA_ORDER.indexOf(b.key);
- });
- this.nextStep();
- }
- ],
- this
- );
-
- var metadataParser = new FunctionParallel(
- 'mp3metadataParser',
- [id3v1Parser, id3v2Parser],
- this,
- function() {
- callback.call(null, metadata);
- },
- onError
- );
-
- id3v1Parser.setCallback(metadataParser.nextStep);
- id3v2Parser.setCallback(metadataParser.nextStep);
-
- id3v1Parser.setFailureCallback(metadataParser.onError);
- id3v2Parser.setFailureCallback(metadataParser.onError);
-
- this.vlog('Passed argument : ' + file);
-
- metadataParser.start(file);
-};
-
-
-/**
- * Metadata order to use for metadata generation
- */
-Id3Parser.METADATA_ORDER = [
- 'ID3_TITLE',
- 'ID3_LEAD_PERFORMER',
- 'ID3_YEAR',
- 'ID3_ALBUM',
- 'ID3_TRACK_NUMBER',
- 'ID3_BPM',
- 'ID3_COMPOSER',
- 'ID3_DATE',
- 'ID3_PLAYLIST_DELAY',
- 'ID3_LYRICIST',
- 'ID3_FILE_TYPE',
- 'ID3_TIME',
- 'ID3_LENGTH',
- 'ID3_FILE_OWNER',
- 'ID3_BAND',
- 'ID3_COPYRIGHT',
- 'ID3_OFFICIAL_AUDIO_FILE_WEBPAGE',
- 'ID3_OFFICIAL_ARTIST',
- 'ID3_OFFICIAL_AUDIO_SOURCE_WEBPAGE',
- 'ID3_PUBLISHERS_OFFICIAL_WEBPAGE'
-];
-
-
-/**
- * id3v1 constants
- */
-Id3Parser.v1 = {
- /**
- * Genres list as described in id3 documentation. We aren't going to
- * localize this list, because at least in Russian (and I think most
- * other languages), translation exists at least for 10% and most time
- * translation would degrade to transliteration.
- */
- GENRES: [
- 'Blues',
- 'Classic Rock',
- 'Country',
- 'Dance',
- 'Disco',
- 'Funk',
- 'Grunge',
- 'Hip-Hop',
- 'Jazz',
- 'Metal',
- 'New Age',
- 'Oldies',
- 'Other',
- 'Pop',
- 'R&B',
- 'Rap',
- 'Reggae',
- 'Rock',
- 'Techno',
- 'Industrial',
- 'Alternative',
- 'Ska',
- 'Death Metal',
- 'Pranks',
- 'Soundtrack',
- 'Euro-Techno',
- 'Ambient',
- 'Trip-Hop',
- 'Vocal',
- 'Jazz+Funk',
- 'Fusion',
- 'Trance',
- 'Classical',
- 'Instrumental',
- 'Acid',
- 'House',
- 'Game',
- 'Sound Clip',
- 'Gospel',
- 'Noise',
- 'AlternRock',
- 'Bass',
- 'Soul',
- 'Punk',
- 'Space',
- 'Meditative',
- 'Instrumental Pop',
- 'Instrumental Rock',
- 'Ethnic',
- 'Gothic',
- 'Darkwave',
- 'Techno-Industrial',
- 'Electronic',
- 'Pop-Folk',
- 'Eurodance',
- 'Dream',
- 'Southern Rock',
- 'Comedy',
- 'Cult',
- 'Gangsta',
- 'Top 40',
- 'Christian Rap',
- 'Pop/Funk',
- 'Jungle',
- 'Native American',
- 'Cabaret',
- 'New Wave',
- 'Psychadelic',
- 'Rave',
- 'Showtunes',
- 'Trailer',
- 'Lo-Fi',
- 'Tribal',
- 'Acid Punk',
- 'Acid Jazz',
- 'Polka',
- 'Retro',
- 'Musical',
- 'Rock & Roll',
- 'Hard Rock',
- 'Folk',
- 'Folk-Rock',
- 'National Folk',
- 'Swing',
- 'Fast Fusion',
- 'Bebob',
- 'Latin',
- 'Revival',
- 'Celtic',
- 'Bluegrass',
- 'Avantgarde',
- 'Gothic Rock',
- 'Progressive Rock',
- 'Psychedelic Rock',
- 'Symphonic Rock',
- 'Slow Rock',
- 'Big Band',
- 'Chorus',
- 'Easy Listening',
- 'Acoustic',
- 'Humour',
- 'Speech',
- 'Chanson',
- 'Opera',
- 'Chamber Music',
- 'Sonata',
- 'Symphony',
- 'Booty Bass',
- 'Primus',
- 'Porn Groove',
- 'Satire',
- 'Slow Jam',
- 'Club',
- 'Tango',
- 'Samba',
- 'Folklore',
- 'Ballad',
- 'Power Ballad',
- 'Rhythmic Soul',
- 'Freestyle',
- 'Duet',
- 'Punk Rock',
- 'Drum Solo',
- 'A capella',
- 'Euro-House',
- 'Dance Hall',
- 'Goa',
- 'Drum & Bass',
- 'Club-House',
- 'Hardcore',
- 'Terror',
- 'Indie',
- 'BritPop',
- 'Negerpunk',
- 'Polsk Punk',
- 'Beat',
- 'Christian Gangsta Rap',
- 'Heavy Metal',
- 'Black Metal',
- 'Crossover',
- 'Contemporary Christian',
- 'Christian Rock',
- 'Merengue',
- 'Salsa',
- 'Thrash Metal',
- 'Anime',
- 'Jpop',
- 'Synthpop'
- ]
-};
-
-/**
- * id3v2 constants
- */
-Id3Parser.v2 = {
- FLAG_EXTENDED_HEADER: 1 << 5,
-
- ENCODING: {
- /**
- * ISO-8859-1 [ISO-8859-1]. Terminated with $00.
- *
- * @const
- * @type {number}
- */
- ISO_8859_1: 0,
-
-
- /**
- * [UTF-16] encoded Unicode [UNICODE] with BOM. All
- * strings in the same frame SHALL have the same byteorder.
- * Terminated with $00 00.
- *
- * @const
- * @type {number}
- */
- UTF_16: 1,
-
- /**
- * UTF-16BE [UTF-16] encoded Unicode [UNICODE] without BOM.
- * Terminated with $00 00.
- *
- * @const
- * @type {number}
- */
- UTF_16BE: 2,
-
- /**
- * UTF-8 [UTF-8] encoded Unicode [UNICODE]. Terminated with $00.
- *
- * @const
- * @type {number}
- */
- UTF_8: 3
- },
- HANDLERS: {
- //User defined text information frame
- TXX: Id3Parser.prototype.readUserDefinedTextFrame_,
- //User defined URL link frame
- WXX: Id3Parser.prototype.readUserDefinedTextFrame_,
-
- //User defined text information frame
- TXXX: Id3Parser.prototype.readUserDefinedTextFrame_,
-
- //User defined URL link frame
- WXXX: Id3Parser.prototype.readUserDefinedTextFrame_,
-
- //User attached image
- PIC: Id3Parser.prototype.readPIC_,
-
- //User attached image
- APIC: Id3Parser.prototype.readAPIC_
- },
- MAPPERS: {
- TALB: 'ID3_ALBUM',
- TBPM: 'ID3_BPM',
- TCOM: 'ID3_COMPOSER',
- TDAT: 'ID3_DATE',
- TDLY: 'ID3_PLAYLIST_DELAY',
- TEXT: 'ID3_LYRICIST',
- TFLT: 'ID3_FILE_TYPE',
- TIME: 'ID3_TIME',
- TIT2: 'ID3_TITLE',
- TLEN: 'ID3_LENGTH',
- TOWN: 'ID3_FILE_OWNER',
- TPE1: 'ID3_LEAD_PERFORMER',
- TPE2: 'ID3_BAND',
- TRCK: 'ID3_TRACK_NUMBER',
- TYER: 'ID3_YEAR',
- WCOP: 'ID3_COPYRIGHT',
- WOAF: 'ID3_OFFICIAL_AUDIO_FILE_WEBPAGE',
- WOAR: 'ID3_OFFICIAL_ARTIST',
- WOAS: 'ID3_OFFICIAL_AUDIO_SOURCE_WEBPAGE',
- WPUB: 'ID3_PUBLISHERS_OFFICIAL_WEBPAGE'
- }
-};
-
-MetadataDispatcher.registerParserClass(Id3Parser);
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/image_parsers.js b/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/image_parsers.js
deleted file mode 100644
index 52c4fc4e8a8..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/image_parsers.js
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/* Base class for image metadata parsers that only need to look at a short
- fragment at the start of the file */
-function SimpleImageParser(parent, type, urlFilter, headerSize) {
- ImageParser.call(this, parent, type, urlFilter);
- this.headerSize = headerSize;
-}
-
-SimpleImageParser.prototype = {__proto__: ImageParser.prototype};
-
-/**
- * @param {File} file // TODO(JSDOC).
- * @param {Object} metadata // TODO(JSDOC).
- * @param {function(Object)} callback // TODO(JSDOC).
- * @param {function(string)} errorCallback // TODO(JSDOC).
- */
-SimpleImageParser.prototype.parse = function(
- file, metadata, callback, errorCallback) {
- var self = this;
- util.readFileBytes(file, 0, this.headerSize,
- function(file, br) {
- try {
- self.parseHeader(metadata, br);
- callback(metadata);
- } catch (e) {
- errorCallback(e.toString());
- }
- },
- errorCallback);
-};
-
-
-function PngParser(parent) {
- SimpleImageParser.call(this, parent, 'png', /\.png$/i, 24);
-}
-
-PngParser.prototype = {__proto__: SimpleImageParser.prototype};
-
-/**
- * @param {Object} metadata // TODO(JSDOC).
- * @param {ByteReader} br // TODO(JSDOC).
- */
-PngParser.prototype.parseHeader = function(metadata, br) {
- br.setByteOrder(ByteReader.BIG_ENDIAN);
-
- var signature = br.readString(8);
- if (signature != '\x89PNG\x0D\x0A\x1A\x0A')
- throw new Error('Invalid PNG signature: ' + signature);
-
- br.seek(12);
- var ihdr = br.readString(4);
- if (ihdr != 'IHDR')
- throw new Error('Missing IHDR chunk');
-
- metadata.width = br.readScalar(4);
- metadata.height = br.readScalar(4);
-};
-
-MetadataDispatcher.registerParserClass(PngParser);
-
-
-function BmpParser(parent) {
- SimpleImageParser.call(this, parent, 'bmp', /\.bmp$/i, 28);
-}
-
-BmpParser.prototype = {__proto__: SimpleImageParser.prototype};
-
-/**
- * @param {Object} metadata // TODO(JSDOC).
- * @param {ByteReader} br // TODO(JSDOC).
- */
-BmpParser.prototype.parseHeader = function(metadata, br) {
- br.setByteOrder(ByteReader.LITTLE_ENDIAN);
-
- var signature = br.readString(2);
- if (signature != 'BM')
- throw new Error('Invalid BMP signature: ' + signature);
-
- br.seek(18);
- metadata.width = br.readScalar(4);
- metadata.height = br.readScalar(4);
-};
-
-MetadataDispatcher.registerParserClass(BmpParser);
-
-
-function GifParser(parent) {
- SimpleImageParser.call(this, parent, 'gif', /\.Gif$/i, 10);
-}
-
-GifParser.prototype = {__proto__: SimpleImageParser.prototype};
-
-/**
- * @param {Object} metadata // TODO(JSDOC).
- * @param {ByteReader} br // TODO(JSDOC).
- */
-GifParser.prototype.parseHeader = function(metadata, br) {
- br.setByteOrder(ByteReader.LITTLE_ENDIAN);
-
- var signature = br.readString(6);
- if (!signature.match(/GIF8(7|9)a/))
- throw new Error('Invalid GIF signature: ' + signature);
-
- metadata.width = br.readScalar(2);
- metadata.height = br.readScalar(2);
-};
-
-MetadataDispatcher.registerParserClass(GifParser);
-
-
-function WebpParser(parent) {
- SimpleImageParser.call(this, parent, 'webp', /\.webp$/i, 30);
-}
-
-WebpParser.prototype = {__proto__: SimpleImageParser.prototype};
-
-/**
- * @param {Object} metadata // TODO(JSDOC).
- * @param {ByteReader} br // TODO(JSDOC).
- */
-WebpParser.prototype.parseHeader = function(metadata, br) {
- br.setByteOrder(ByteReader.LITTLE_ENDIAN);
-
- var riffSignature = br.readString(4);
- if (riffSignature != 'RIFF')
- throw new Error('Invalid RIFF signature: ' + riffSignature);
-
- br.seek(8);
- var webpSignature = br.readString(4);
- if (webpSignature != 'WEBP')
- throw new Error('Invalid WEBP signature: ' + webpSignature);
-
- var chunkFormat = br.readString(4);
- if (chunkFormat != 'VP8 ' && chunkFormat != 'VP8L')
- throw new Error('Invalid chunk format: ' + chunkFormat);
-
- if (chunkFormat == 'VP8 ') {
- // VP8 lossy bitstream format.
- br.seek(23);
- var lossySignature = br.readScalar(2) | (br.readScalar(1) << 16);
- if (lossySignature != 0x2a019d)
- throw new Error('Invalid VP8 lossy bitstream signature: ' +
- lossySignature);
-
- var dimensionBits = br.readScalar(4);
- metadata.width = dimensionBits & 0x3fff;
- metadata.height = (dimensionBits >> 16) & 0x3fff;
- } else {
- // VP8 lossless bitstream format.
- br.seek(20);
- var losslessSignature = br.readScalar(1);
- if (losslessSignature != 0x2f)
- throw new Error('Invalid VP8 lossless bitstream signature: ' +
- losslessSignature);
-
- var dimensionBits = br.readScalar(4);
- metadata.width = (dimensionBits & 0x3fff) + 1;
- metadata.height = ((dimensionBits >> 14) & 0x3fff) + 1;
- }
-};
-
-MetadataDispatcher.registerParserClass(WebpParser);
-
-/**
- * Parser for the header of .ico icon files.
- * @param {MetadataDispatcher} parent Parent metadata dispatcher object.
- * @constructor
- * @extends SimpleImageParser
- */
-function IcoParser(parent) {
- SimpleImageParser.call(this, parent, 'ico', /\.ico$/i, 8);
-}
-
-IcoParser.prototype = {__proto__: SimpleImageParser.prototype};
-
-/**
- * Parse the binary data as a ico header and stores to metadata.
- * @param {Object} metadata Dictionary to store the parser metadata.
- * @param {ByteReader} byteReader Reader for header binary data.
- */
-IcoParser.prototype.parseHeader = function(metadata, byteReader) {
- byteReader.setByteOrder(ByteReader.LITTLE_ENDIAN);
-
- var signature = byteReader.readString(4);
- if (signature !== '\x00\x00\x00\x01')
- throw new Error('Invalid ICO signature: ' + signature);
-
- byteReader.seek(2);
- metadata.width = byteReader.readScalar(1);
- metadata.height = byteReader.readScalar(1);
-};
-
-MetadataDispatcher.registerParserClass(IcoParser);
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/metadata_cache.js b/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/metadata_cache.js
deleted file mode 100644
index 4bbbe182958..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/metadata_cache.js
+++ /dev/null
@@ -1,1042 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * MetadataCache is a map from Entry to an object containing properties.
- * Properties are divided by types, and all properties of one type are accessed
- * at once.
- * Some of the properties:
- * {
- * filesystem: size, modificationTime
- * internal: presence
- * drive: pinned, present, hosted, availableOffline
- * streaming: (no property)
- *
- * Following are not fetched for non-present drive files.
- * media: artist, album, title, width, height, imageTransform, etc.
- * thumbnail: url, transform
- *
- * Following are always fetched from content, and so force the downloading
- * of remote drive files. One should use this for required content metadata,
- * i.e. image orientation.
- * fetchedMedia: width, height, etc.
- * }
- *
- * Typical usages:
- * {
- * cache.get([entry1, entry2], 'drive|filesystem', function(metadata) {
- * if (metadata[0].drive.pinned && metadata[1].filesystem.size == 0)
- * alert("Pinned and empty!");
- * });
- *
- * cache.set(entry, 'internal', {presence: 'deleted'});
- *
- * cache.clear([fileEntry1, fileEntry2], 'filesystem');
- *
- * // Getting fresh value.
- * cache.clear(entry, 'thumbnail');
- * cache.get(entry, 'thumbnail', function(thumbnail) {
- * img.src = thumbnail.url;
- * });
- *
- * var cached = cache.getCached(entry, 'filesystem');
- * var size = (cached && cached.size) || UNKNOWN_SIZE;
- * }
- *
- * @constructor
- */
-function MetadataCache() {
- /**
- * Map from Entry (using Entry.toURL) to metadata. Metadata contains
- * |properties| - an hierarchical object of values, and an object for each
- * metadata provider: <prodiver-id>: {time, callbacks}
- * @private
- */
- this.cache_ = {};
-
- /**
- * List of metadata providers.
- * @private
- */
- this.providers_ = [];
-
- /**
- * List of observers added. Each one is an object with fields:
- * re - regexp of urls;
- * type - metadata type;
- * callback - the callback.
- * @private
- */
- this.observers_ = [];
- this.observerId_ = 0;
-
- this.batchCount_ = 0;
- this.totalCount_ = 0;
-
- this.currentCacheSize_ = 0;
-
- /**
- * Time of first get query of the current batch. Items updated later than this
- * will not be evicted.
- * @private
- */
- this.lastBatchStart_ = new Date();
-}
-
-/**
- * Observer type: it will be notified if the changed Entry is exactly the same
- * as the observed Entry.
- */
-MetadataCache.EXACT = 0;
-
-/**
- * Observer type: it will be notified if the changed Entry is an immediate child
- * of the observed Entry.
- */
-MetadataCache.CHILDREN = 1;
-
-/**
- * Observer type: it will be notified if the changed Entry is a descendant of
- * of the observer Entry.
- */
-MetadataCache.DESCENDANTS = 2;
-
-/**
- * Margin of the cache size. This amount of caches may be kept in addition.
- */
-MetadataCache.EVICTION_THRESHOLD_MARGIN = 500;
-
-/**
- * @return {MetadataCache!} The cache with all providers.
- */
-MetadataCache.createFull = function() {
- var cache = new MetadataCache();
- cache.providers_.push(new FilesystemProvider());
- cache.providers_.push(new DriveProvider());
- cache.providers_.push(new ContentProvider());
- return cache;
-};
-
-/**
- * Clones metadata entry. Metadata entries may contain scalars, arrays,
- * hash arrays and Date object. Other objects are not supported.
- * @param {Object} metadata Metadata object.
- * @return {Object} Cloned entry.
- */
-MetadataCache.cloneMetadata = function(metadata) {
- if (metadata instanceof Array) {
- var result = [];
- for (var index = 0; index < metadata.length; index++) {
- result[index] = MetadataCache.cloneMetadata(metadata[index]);
- }
- return result;
- } else if (metadata instanceof Date) {
- var result = new Date();
- result.setTime(metadata.getTime());
- return result;
- } else if (metadata instanceof Object) { // Hash array only.
- var result = {};
- for (var property in metadata) {
- if (metadata.hasOwnProperty(property))
- result[property] = MetadataCache.cloneMetadata(metadata[property]);
- }
- return result;
- } else {
- return metadata;
- }
-};
-
-/**
- * @return {boolean} Whether all providers are ready.
- */
-MetadataCache.prototype.isInitialized = function() {
- for (var index = 0; index < this.providers_.length; index++) {
- if (!this.providers_[index].isInitialized()) return false;
- }
- return true;
-};
-
-/**
- * Sets the size of cache. The actual cache size may be larger than the given
- * value.
- * @param {number} size The cache size to be set.
- */
-MetadataCache.prototype.setCacheSize = function(size) {
- this.currentCacheSize_ = size;
-
- if (this.totalCount_ > this.currentEvictionThreshold_())
- this.evict_();
-};
-
-/**
- * Returns the current threshold to evict caches. When the number of caches
- * exceeds this, the cache should be evicted.
- * @return {number} Threshold to evict caches.
- * @private
- */
-MetadataCache.prototype.currentEvictionThreshold_ = function() {
- return this.currentCacheSize_ * 2 + MetadataCache.EVICTION_THRESHOLD_MARGIN;
-};
-
-/**
- * Fetches the metadata, puts it in the cache, and passes to callback.
- * If required metadata is already in the cache, does not fetch it again.
- * @param {Entry|Array.<Entry>} entries The list of entries. May be just a
- * single item.
- * @param {string} type The metadata type.
- * @param {function(Object)} callback The metadata is passed to callback.
- */
-MetadataCache.prototype.get = function(entries, type, callback) {
- if (!(entries instanceof Array)) {
- this.getOne(entries, type, callback);
- return;
- }
-
- if (entries.length == 0) {
- if (callback) callback([]);
- return;
- }
-
- var result = [];
- var remaining = entries.length;
- this.startBatchUpdates();
-
- var onOneItem = function(index, value) {
- result[index] = value;
- remaining--;
- if (remaining == 0) {
- this.endBatchUpdates();
- if (callback) setTimeout(callback, 0, result);
- }
- };
-
- for (var index = 0; index < entries.length; index++) {
- result.push(null);
- this.getOne(entries[index], type, onOneItem.bind(this, index));
- }
-};
-
-/**
- * Fetches the metadata for one Entry. See comments to |get|.
- * @param {Entry} entry The entry.
- * @param {string} type Metadata type.
- * @param {function(Object)} callback The callback.
- */
-MetadataCache.prototype.getOne = function(entry, type, callback) {
- if (type.indexOf('|') != -1) {
- var types = type.split('|');
- var result = {};
- var typesLeft = types.length;
-
- var onOneType = function(requestedType, metadata) {
- result[requestedType] = metadata;
- typesLeft--;
- if (typesLeft == 0) callback(result);
- };
-
- for (var index = 0; index < types.length; index++) {
- this.getOne(entry, types[index], onOneType.bind(null, types[index]));
- }
- return;
- }
-
- callback = callback || function() {};
-
- var entryURL = entry.toURL();
- if (!(entryURL in this.cache_)) {
- this.cache_[entryURL] = this.createEmptyItem_();
- this.totalCount_++;
- }
-
- var item = this.cache_[entryURL];
-
- if (type in item.properties) {
- callback(item.properties[type]);
- return;
- }
-
- this.startBatchUpdates();
- var providers = this.providers_.slice();
- var currentProvider;
- var self = this;
-
- var onFetched = function() {
- if (type in item.properties) {
- self.endBatchUpdates();
- // Got properties from provider.
- callback(item.properties[type]);
- } else {
- tryNextProvider();
- }
- };
-
- var onProviderProperties = function(properties) {
- var id = currentProvider.getId();
- var fetchedCallbacks = item[id].callbacks;
- delete item[id].callbacks;
- item.time = new Date();
- self.mergeProperties_(entry, properties);
-
- for (var index = 0; index < fetchedCallbacks.length; index++) {
- fetchedCallbacks[index]();
- }
- };
-
- var queryProvider = function() {
- var id = currentProvider.getId();
- if ('callbacks' in item[id]) {
- // We are querying this provider now.
- item[id].callbacks.push(onFetched);
- } else {
- item[id].callbacks = [onFetched];
- currentProvider.fetch(entry, type, onProviderProperties);
- }
- };
-
- var tryNextProvider = function() {
- if (providers.length == 0) {
- self.endBatchUpdates();
- callback(item.properties[type] || null);
- return;
- }
-
- currentProvider = providers.shift();
- if (currentProvider.supportsEntry(entry) &&
- currentProvider.providesType(type)) {
- queryProvider();
- } else {
- tryNextProvider();
- }
- };
-
- tryNextProvider();
-};
-
-/**
- * Returns the cached metadata value, or |null| if not present.
- * @param {Entry|Array.<Entry>} entries The list of entries. May be just a
- * single entry.
- * @param {string} type The metadata type.
- * @return {Object} The metadata or null.
- */
-MetadataCache.prototype.getCached = function(entries, type) {
- var single = false;
- if (!(entries instanceof Array)) {
- single = true;
- entries = [entries];
- }
-
- var result = [];
- for (var index = 0; index < entries.length; index++) {
- var entryURL = entries[index].toURL();
- result.push(entryURL in this.cache_ ?
- (this.cache_[entryURL].properties[type] || null) : null);
- }
-
- return single ? result[0] : result;
-};
-
-/**
- * Puts the metadata into cache
- * @param {Entry|Array.<Entry>} entries The list of entries. May be just a
- * single entry.
- * @param {string} type The metadata type.
- * @param {Array.<Object>} values List of corresponding metadata values.
- */
-MetadataCache.prototype.set = function(entries, type, values) {
- if (!(entries instanceof Array)) {
- entries = [entries];
- values = [values];
- }
-
- this.startBatchUpdates();
- for (var index = 0; index < entries.length; index++) {
- var entryURL = entries[index].toURL();
- if (!(entryURL in this.cache_)) {
- this.cache_[entryURL] = this.createEmptyItem_();
- this.totalCount_++;
- }
- this.cache_[entryURL].properties[type] = values[index];
- this.notifyObservers_(entries[index], type);
- }
- this.endBatchUpdates();
-};
-
-/**
- * Clears the cached metadata values.
- * @param {Entry|Array.<Entry>} entries The list of entries. May be just a
- * single entry.
- * @param {string} type The metadata types or * for any type.
- */
-MetadataCache.prototype.clear = function(entries, type) {
- if (!(entries instanceof Array))
- entries = [entries];
-
- var types = type.split('|');
-
- for (var index = 0; index < entries.length; index++) {
- var entry = entries[index];
- var entryURL = entry.toURL();
- if (entryURL in this.cache_) {
- if (type === '*') {
- this.cache_[entryURL].properties = {};
- } else {
- for (var j = 0; j < types.length; j++) {
- var type = types[j];
- delete this.cache_[entryURL].properties[type];
- }
- }
- }
- }
-};
-
-/**
- * Clears the cached metadata values recursively.
- * @param {Entry} entry An entry to be cleared recursively from cache.
- * @param {string} type The metadata types or * for any type.
- */
-MetadataCache.prototype.clearRecursively = function(entry, type) {
- var types = type.split('|');
- var keys = Object.keys(this.cache_);
- var entryURL = entry.toURL();
-
- for (var index = 0; index < keys.length; index++) {
- var cachedEntryURL = keys[index];
- if (cachedEntryURL.substring(0, entryURL.length) === entryURL) {
- if (type === '*') {
- this.cache_[cachedEntryURL].properties = {};
- } else {
- for (var j = 0; j < types.length; j++) {
- var type = types[j];
- delete this.cache_[cachedEntryURL].properties[type];
- }
- }
- }
- }
-};
-
-/**
- * Adds an observer, which will be notified when metadata changes.
- * @param {Entry} entry The root entry to look at.
- * @param {number} relation This defines, which items will trigger the observer.
- * See comments to |MetadataCache.EXACT| and others.
- * @param {string} type The metadata type.
- * @param {function(Array.<Entry>, Array.<Object>)} observer List of entries
- * and corresponding metadata values are passed to this callback.
- * @return {number} The observer id, which can be used to remove it.
- */
-MetadataCache.prototype.addObserver = function(
- entry, relation, type, observer) {
- var entryURL = entry.toURL();
- var re;
- if (relation == MetadataCache.CHILDREN)
- re = entryURL + '(/[^/]*)?';
- else if (relation == MetadataCache.DESCENDANTS)
- re = entryURL + '(/.*)?';
- else
- re = entryURL;
-
- var id = ++this.observerId_;
- this.observers_.push({
- re: new RegExp('^' + re + '$'),
- type: type,
- callback: observer,
- id: id,
- pending: {}
- });
-
- return id;
-};
-
-/**
- * Removes the observer.
- * @param {number} id Observer id.
- * @return {boolean} Whether observer was removed or not.
- */
-MetadataCache.prototype.removeObserver = function(id) {
- for (var index = 0; index < this.observers_.length; index++) {
- if (this.observers_[index].id == id) {
- this.observers_.splice(index, 1);
- return true;
- }
- }
- return false;
-};
-
-/**
- * Start batch updates.
- */
-MetadataCache.prototype.startBatchUpdates = function() {
- this.batchCount_++;
- if (this.batchCount_ == 1)
- this.lastBatchStart_ = new Date();
-};
-
-/**
- * End batch updates. Notifies observers if all nested updates are finished.
- */
-MetadataCache.prototype.endBatchUpdates = function() {
- this.batchCount_--;
- if (this.batchCount_ != 0) return;
- if (this.totalCount_ > this.currentEvictionThreshold_())
- this.evict_();
- for (var index = 0; index < this.observers_.length; index++) {
- var observer = this.observers_[index];
- var entries = [];
- var properties = [];
- for (var entryURL in observer.pending) {
- if (observer.pending.hasOwnProperty(entryURL) &&
- entryURL in this.cache_) {
- var entry = observer.pending[entryURL];
- entries.push(entry);
- properties.push(
- this.cache_[entryURL].properties[observer.type] || null);
- }
- }
- observer.pending = {};
- if (entries.length > 0) {
- observer.callback(entries, properties);
- }
- }
-};
-
-/**
- * Notifies observers or puts the data to pending list.
- * @param {Entry} entry Changed entry.
- * @param {string} type Metadata type.
- * @private
- */
-MetadataCache.prototype.notifyObservers_ = function(entry, type) {
- var entryURL = entry.toURL();
- for (var index = 0; index < this.observers_.length; index++) {
- var observer = this.observers_[index];
- if (observer.type == type && observer.re.test(entryURL)) {
- if (this.batchCount_ == 0) {
- // Observer expects array of urls and array of properties.
- observer.callback(
- [entry], [this.cache_[entryURL].properties[type] || null]);
- } else {
- observer.pending[entryURL] = entry;
- }
- }
- }
-};
-
-/**
- * Removes the oldest items from the cache.
- * This method never removes the items from last batch.
- * @private
- */
-MetadataCache.prototype.evict_ = function() {
- var toRemove = [];
-
- // We leave only a half of items, so we will not call evict_ soon again.
- var desiredCount = this.currentEvictionThreshold_();
- var removeCount = this.totalCount_ - desiredCount;
- for (var url in this.cache_) {
- if (this.cache_.hasOwnProperty(url) &&
- this.cache_[url].time < this.lastBatchStart_) {
- toRemove.push(url);
- }
- }
-
- toRemove.sort(function(a, b) {
- var aTime = this.cache_[a].time;
- var bTime = this.cache_[b].time;
- return aTime < bTime ? -1 : aTime > bTime ? 1 : 0;
- }.bind(this));
-
- removeCount = Math.min(removeCount, toRemove.length);
- this.totalCount_ -= removeCount;
- for (var index = 0; index < removeCount; index++) {
- delete this.cache_[toRemove[index]];
- }
-};
-
-/**
- * @return {Object} Empty cache item.
- * @private
- */
-MetadataCache.prototype.createEmptyItem_ = function() {
- var item = {properties: {}};
- for (var index = 0; index < this.providers_.length; index++) {
- item[this.providers_[index].getId()] = {};
- }
- return item;
-};
-
-/**
- * Caches all the properties from data to cache entry for the entry.
- * @param {Entry} entry The file entry.
- * @param {Object} data The properties.
- * @private
- */
-MetadataCache.prototype.mergeProperties_ = function(entry, data) {
- if (data == null) return;
- var properties = this.cache_[entry.toURL()].properties;
- for (var type in data) {
- if (data.hasOwnProperty(type) && !properties.hasOwnProperty(type)) {
- properties[type] = data[type];
- this.notifyObservers_(entry, type);
- }
- }
-};
-
-/**
- * Base class for metadata providers.
- * @constructor
- */
-function MetadataProvider() {
-}
-
-/**
- * @param {Entry} entry The entry.
- * @return {boolean} Whether this provider supports the entry.
- */
-MetadataProvider.prototype.supportsEntry = function(entry) { return false; };
-
-/**
- * @param {string} type The metadata type.
- * @return {boolean} Whether this provider provides this metadata.
- */
-MetadataProvider.prototype.providesType = function(type) { return false; };
-
-/**
- * @return {string} Unique provider id.
- */
-MetadataProvider.prototype.getId = function() { return ''; };
-
-/**
- * @return {boolean} Whether provider is ready.
- */
-MetadataProvider.prototype.isInitialized = function() { return true; };
-
-/**
- * Fetches the metadata. It's suggested to return all the metadata this provider
- * can fetch at once.
- * @param {Entry} entry File entry.
- * @param {string} type Requested metadata type.
- * @param {function(Object)} callback Callback expects a map from metadata type
- * to metadata value.
- */
-MetadataProvider.prototype.fetch = function(entry, type, callback) {
- throw new Error('Default metadata provider cannot fetch.');
-};
-
-
-/**
- * Provider of filesystem metadata.
- * This provider returns the following objects:
- * filesystem: { size, modificationTime }
- * @constructor
- */
-function FilesystemProvider() {
- MetadataProvider.call(this);
-}
-
-FilesystemProvider.prototype = {
- __proto__: MetadataProvider.prototype
-};
-
-/**
- * @param {Entry} entry The entry.
- * @return {boolean} Whether this provider supports the entry.
- */
-FilesystemProvider.prototype.supportsEntry = function(entry) {
- return true;
-};
-
-/**
- * @param {string} type The metadata type.
- * @return {boolean} Whether this provider provides this metadata.
- */
-FilesystemProvider.prototype.providesType = function(type) {
- return type == 'filesystem';
-};
-
-/**
- * @return {string} Unique provider id.
- */
-FilesystemProvider.prototype.getId = function() { return 'filesystem'; };
-
-/**
- * Fetches the metadata.
- * @param {Entry} entry File entry.
- * @param {string} type Requested metadata type.
- * @param {function(Object)} callback Callback expects a map from metadata type
- * to metadata value.
- */
-FilesystemProvider.prototype.fetch = function(
- entry, type, callback) {
- function onError(error) {
- callback(null);
- }
-
- function onMetadata(entry, metadata) {
- callback({
- filesystem: {
- size: entry.isFile ? (metadata.size || 0) : -1,
- modificationTime: metadata.modificationTime
- }
- });
- }
-
- entry.getMetadata(onMetadata.bind(null, entry), onError);
-};
-
-/**
- * Provider of drive metadata.
- * This provider returns the following objects:
- * drive: { pinned, hosted, present, customIconUrl, etc. }
- * thumbnail: { url, transform }
- * streaming: { }
- * @constructor
- */
-function DriveProvider() {
- MetadataProvider.call(this);
-
- // We batch metadata fetches into single API call.
- this.entries_ = [];
- this.callbacks_ = [];
- this.scheduled_ = false;
-
- this.callApiBound_ = this.callApi_.bind(this);
-}
-
-DriveProvider.prototype = {
- __proto__: MetadataProvider.prototype
-};
-
-/**
- * @param {Entry} entry The entry.
- * @return {boolean} Whether this provider supports the entry.
- */
-DriveProvider.prototype.supportsEntry = function(entry) {
- return FileType.isOnDrive(entry);
-};
-
-/**
- * @param {string} type The metadata type.
- * @return {boolean} Whether this provider provides this metadata.
- */
-DriveProvider.prototype.providesType = function(type) {
- return type == 'drive' || type == 'thumbnail' ||
- type == 'streaming' || type == 'media';
-};
-
-/**
- * @return {string} Unique provider id.
- */
-DriveProvider.prototype.getId = function() { return 'drive'; };
-
-/**
- * Fetches the metadata.
- * @param {Entry} entry File entry.
- * @param {string} type Requested metadata type.
- * @param {function(Object)} callback Callback expects a map from metadata type
- * to metadata value.
- */
-DriveProvider.prototype.fetch = function(entry, type, callback) {
- this.entries_.push(entry);
- this.callbacks_.push(callback);
- if (!this.scheduled_) {
- this.scheduled_ = true;
- setTimeout(this.callApiBound_, 0);
- }
-};
-
-/**
- * Schedules the API call.
- * @private
- */
-DriveProvider.prototype.callApi_ = function() {
- this.scheduled_ = false;
-
- var entries = this.entries_;
- var callbacks = this.callbacks_;
- this.entries_ = [];
- this.callbacks_ = [];
- var self = this;
-
- var task = function(entry, callback) {
- // TODO(mtomasz): Make getDriveEntryProperties accept Entry instead of URL.
- var entryURL = entry.toURL();
- chrome.fileBrowserPrivate.getDriveEntryProperties(entryURL,
- function(properties) {
- callback(self.convert_(properties, entry));
- });
- };
-
- for (var i = 0; i < entries.length; i++)
- task(entries[i], callbacks[i]);
-};
-
-/**
- * @param {DriveEntryProperties} data Drive entry properties.
- * @param {Entry} entry File entry.
- * @return {boolean} True if the file is available offline.
- */
-DriveProvider.isAvailableOffline = function(data, entry) {
- if (data.isPresent)
- return true;
-
- if (!data.isHosted)
- return false;
-
- // What's available offline? See the 'Web' column at:
- // http://support.google.com/drive/bin/answer.py?hl=en&answer=1628467
- var subtype = FileType.getType(entry).subtype;
- return (subtype == 'doc' ||
- subtype == 'draw' ||
- subtype == 'sheet' ||
- subtype == 'slides');
-};
-
-/**
- * @param {DriveEntryProperties} data Drive entry properties.
- * @return {boolean} True if opening the file does not require downloading it
- * via a metered connection.
- */
-DriveProvider.isAvailableWhenMetered = function(data) {
- return data.isPresent || data.isHosted;
-};
-
-/**
- * Converts API metadata to internal format.
- * @param {Object} data Metadata from API call.
- * @param {Entry} entry File entry.
- * @return {Object} Metadata in internal format.
- * @private
- */
-DriveProvider.prototype.convert_ = function(data, entry) {
- var result = {};
- result.drive = {
- present: data.isPresent,
- pinned: data.isPinned,
- hosted: data.isHosted,
- imageWidth: data.imageWidth,
- imageHeight: data.imageHeight,
- imageRotation: data.imageRotation,
- availableOffline: DriveProvider.isAvailableOffline(data, entry),
- availableWhenMetered: DriveProvider.isAvailableWhenMetered(data),
- customIconUrl: data.customIconUrl || '',
- contentMimeType: data.contentMimeType || '',
- sharedWithMe: data.sharedWithMe,
- shared: data.shared
- };
-
- if (!data.isPresent) {
- // Block the local fetch for drive files, which require downloading.
- result.thumbnail = {url: '', transform: null};
- result.media = {};
- }
-
- if ('thumbnailUrl' in data) {
- result.thumbnail = {
- url: data.thumbnailUrl,
- transform: null
- };
- }
- if (!data.isPresent) {
- // Indicate that the data is not available in local cache.
- // It used to have a field 'url' for streaming play, but it is
- // derprecated. See crbug.com/174560.
- result.streaming = {};
- }
- return result;
-};
-
-
-/**
- * Provider of content metadata.
- * This provider returns the following objects:
- * thumbnail: { url, transform }
- * media: { artist, album, title, width, height, imageTransform, etc. }
- * fetchedMedia: { same fields here }
- * @constructor
- */
-function ContentProvider() {
- MetadataProvider.call(this);
-
- // Pass all URLs to the metadata reader until we have a correct filter.
- this.urlFilter_ = /.*/;
-
- var path = document.location.pathname;
- var workerPath = document.location.origin +
- path.substring(0, path.lastIndexOf('/') + 1) +
- 'foreground/js/metadata/metadata_dispatcher.js';
-
- this.dispatcher_ = new SharedWorker(workerPath).port;
- this.dispatcher_.start();
-
- this.dispatcher_.onmessage = this.onMessage_.bind(this);
- this.dispatcher_.postMessage({verb: 'init'});
-
- // Initialization is not complete until the Worker sends back the
- // 'initialized' message. See below.
- this.initialized_ = false;
-
- // Map from Entry.toURL() to callback.
- // Note that simultaneous requests for same url are handled in MetadataCache.
- this.callbacks_ = {};
-}
-
-ContentProvider.prototype = {
- __proto__: MetadataProvider.prototype
-};
-
-/**
- * @param {Entry} entry The entry.
- * @return {boolean} Whether this provider supports the entry.
- */
-ContentProvider.prototype.supportsEntry = function(entry) {
- return entry.toURL().match(this.urlFilter_);
-};
-
-/**
- * @param {string} type The metadata type.
- * @return {boolean} Whether this provider provides this metadata.
- */
-ContentProvider.prototype.providesType = function(type) {
- return type == 'thumbnail' || type == 'fetchedMedia' || type == 'media';
-};
-
-/**
- * @return {string} Unique provider id.
- */
-ContentProvider.prototype.getId = function() { return 'content'; };
-
-/**
- * Fetches the metadata.
- * @param {Entry} entry File entry.
- * @param {string} type Requested metadata type.
- * @param {function(Object)} callback Callback expects a map from metadata type
- * to metadata value.
- */
-ContentProvider.prototype.fetch = function(entry, type, callback) {
- if (entry.isDirectory) {
- callback({});
- return;
- }
- var entryURL = entry.toURL();
- this.callbacks_[entryURL] = callback;
- this.dispatcher_.postMessage({verb: 'request', arguments: [entryURL]});
-};
-
-/**
- * Dispatch a message from a metadata reader to the appropriate on* method.
- * @param {Object} event The event.
- * @private
- */
-ContentProvider.prototype.onMessage_ = function(event) {
- var data = event.data;
-
- var methodName =
- 'on' + data.verb.substr(0, 1).toUpperCase() + data.verb.substr(1) + '_';
-
- if (!(methodName in this)) {
- console.error('Unknown message from metadata reader: ' + data.verb, data);
- return;
- }
-
- this[methodName].apply(this, data.arguments);
-};
-
-/**
- * @return {boolean} Whether provider is ready.
- */
-ContentProvider.prototype.isInitialized = function() {
- return this.initialized_;
-};
-
-/**
- * Handles the 'initialized' message from the metadata reader Worker.
- * @param {Object} regexp Regexp of supported urls.
- * @private
- */
-ContentProvider.prototype.onInitialized_ = function(regexp) {
- this.urlFilter_ = regexp;
-
- // Tests can monitor for this state with
- // ExtensionTestMessageListener listener("worker-initialized");
- // ASSERT_TRUE(listener.WaitUntilSatisfied());
- // Automated tests need to wait for this, otherwise we crash in
- // browser_test cleanup because the worker process still has
- // URL requests in-flight.
- var test = chrome.test || window.top.chrome.test;
- test.sendMessage('worker-initialized');
- this.initialized_ = true;
-};
-
-/**
- * Converts content metadata from parsers to the internal format.
- * @param {Object} metadata The content metadata.
- * @param {Object=} opt_result The internal metadata object ot put result in.
- * @return {Object!} Converted metadata.
- */
-ContentProvider.ConvertContentMetadata = function(metadata, opt_result) {
- var result = opt_result || {};
-
- if ('thumbnailURL' in metadata) {
- metadata.thumbnailTransform = metadata.thumbnailTransform || null;
- result.thumbnail = {
- url: metadata.thumbnailURL,
- transform: metadata.thumbnailTransform
- };
- }
-
- for (var key in metadata) {
- if (metadata.hasOwnProperty(key)) {
- if (!('media' in result)) result.media = {};
- result.media[key] = metadata[key];
- }
- }
-
- if ('media' in result) {
- result.fetchedMedia = result.media;
- }
-
- return result;
-};
-
-/**
- * Handles the 'result' message from the worker.
- * @param {string} url File url.
- * @param {Object} metadata The metadata.
- * @private
- */
-ContentProvider.prototype.onResult_ = function(url, metadata) {
- var callback = this.callbacks_[url];
- delete this.callbacks_[url];
- callback(ContentProvider.ConvertContentMetadata(metadata));
-};
-
-/**
- * Handles the 'error' message from the worker.
- * @param {string} url File entry.
- * @param {string} step Step failed.
- * @param {string} error Error description.
- * @param {Object?} metadata The metadata, if available.
- * @private
- */
-ContentProvider.prototype.onError_ = function(url, step, error, metadata) {
- if (MetadataCache.log) // Avoid log spam by default.
- console.warn('metadata: ' + url + ': ' + step + ': ' + error);
- metadata = metadata || {};
- // Prevent asking for thumbnail again.
- metadata.thumbnailURL = '';
- this.onResult_(url, metadata);
-};
-
-/**
- * Handles the 'log' message from the worker.
- * @param {Array.<*>} arglist Log arguments.
- * @private
- */
-ContentProvider.prototype.onLog_ = function(arglist) {
- if (MetadataCache.log) // Avoid log spam by default.
- console.log.apply(console, ['metadata:'].concat(arglist));
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/metadata_dispatcher.js b/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/metadata_dispatcher.js
deleted file mode 100644
index b711d7559b7..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/metadata_dispatcher.js
+++ /dev/null
@@ -1,226 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-// All of these scripts could be imported with a single call to importScripts,
-// but then load and compile time errors would all be reported from the same
-// line.
-importScripts('metadata_parser.js');
-importScripts('byte_reader.js');
-importScripts('../../../common/js/util.js');
-
-/**
- * Dispatches metadata requests to the correct parser.
- *
- * @param {Object} port Worker port.
- * @constructor
- */
-function MetadataDispatcher(port) {
- this.port_ = port;
- this.port_.onmessage = this.onMessage.bind(this);
-
- // Make sure to update component_extension_resources.grd
- // when adding new parsers.
- importScripts('exif_parser.js');
- importScripts('image_parsers.js');
- importScripts('mpeg_parser.js');
- importScripts('id3_parser.js');
-
- var patterns = [];
-
- this.parserInstances_ = [];
- for (var i = 0; i < MetadataDispatcher.parserClasses_.length; i++) {
- var parserClass = MetadataDispatcher.parserClasses_[i];
- var parser = new parserClass(this);
- this.parserInstances_.push(parser);
- patterns.push(parser.urlFilter.source);
- }
-
- this.parserRegexp_ = new RegExp('(' + patterns.join('|') + ')', 'i');
-
- this.messageHandlers_ = {
- init: this.init_.bind(this),
- request: this.request_.bind(this)
- };
-}
-
-/**
- * List of registered parser classes.
- * @private
- */
-MetadataDispatcher.parserClasses_ = [];
-
-/**
- * @param {function} parserClass Parser constructor function.
- */
-MetadataDispatcher.registerParserClass = function(parserClass) {
- MetadataDispatcher.parserClasses_.push(parserClass);
-};
-
-/**
- * Verbose logging for the dispatcher.
- *
- * Individual parsers also take this as their default verbosity setting.
- */
-MetadataDispatcher.prototype.verbose = false;
-
-/**
- * |init| message handler.
- * @private
- */
-MetadataDispatcher.prototype.init_ = function() {
- // Inform our owner that we're done initializing.
- // If we need to pass more data back, we can add it to the param array.
- this.postMessage('initialized', [this.parserRegexp_]);
- this.log('initialized with URL filter ' + this.parserRegexp_);
-};
-
-/**
- * |request| message handler.
- * @param {string} fileURL File URL.
- * @private
- */
-MetadataDispatcher.prototype.request_ = function(fileURL) {
- try {
- this.processOneFile(fileURL, function callback(metadata) {
- this.postMessage('result', [fileURL, metadata]);
- }.bind(this));
- } catch (ex) {
- this.error(fileURL, ex);
- }
-};
-
-/**
- * Indicate to the caller that an operation has failed.
- *
- * No other messages relating to the failed operation should be sent.
- * @param {...Object} var_args Arguments.
- */
-MetadataDispatcher.prototype.error = function(var_args) {
- var ary = Array.apply(null, arguments);
- this.postMessage('error', ary);
-};
-
-/**
- * Send a log message to the caller.
- *
- * Callers must not parse log messages for control flow.
- * @param {...Object} var_args Arguments.
- */
-MetadataDispatcher.prototype.log = function(var_args) {
- var ary = Array.apply(null, arguments);
- this.postMessage('log', ary);
-};
-
-/**
- * Send a log message to the caller only if this.verbose is true.
- * @param {...Object} var_args Arguments.
- */
-MetadataDispatcher.prototype.vlog = function(var_args) {
- if (this.verbose)
- this.log.apply(this, arguments);
-};
-
-/**
- * Post a properly formatted message to the caller.
- * @param {string} verb Message type descriptor.
- * @param {Array.<Object>} args Arguments array.
- */
-MetadataDispatcher.prototype.postMessage = function(verb, args) {
- this.port_.postMessage({verb: verb, arguments: args});
-};
-
-/**
- * Message handler.
- * @param {Event} event Event object.
- */
-MetadataDispatcher.prototype.onMessage = function(event) {
- var data = event.data;
-
- if (this.messageHandlers_.hasOwnProperty(data.verb)) {
- this.messageHandlers_[data.verb].apply(this, data.arguments);
- } else {
- this.log('Unknown message from client: ' + data.verb, data);
- }
-};
-
-/**
- * @param {string} fileURL File URL.
- * @param {function(Object)} callback Completion callback.
- */
-MetadataDispatcher.prototype.processOneFile = function(fileURL, callback) {
- var self = this;
- var currentStep = -1;
-
- function nextStep(var_args) {
- self.vlog('nextStep: ' + steps[currentStep + 1].name);
- steps[++currentStep].apply(self, arguments);
- }
-
- var metadata;
-
- function onError(err, stepName) {
- self.error(fileURL, stepName || steps[currentStep].name, err.toString(),
- metadata);
- }
-
- var steps =
- [ // Step one, find the parser matching the url.
- function detectFormat() {
- for (var i = 0; i != self.parserInstances_.length; i++) {
- var parser = self.parserInstances_[i];
- if (fileURL.match(parser.urlFilter)) {
- // Create the metadata object as early as possible so that we can
- // pass it with the error message.
- metadata = parser.createDefaultMetadata();
- nextStep(parser);
- return;
- }
- }
- onError('unsupported format');
- },
-
- // Step two, turn the url into an entry.
- function getEntry(parser) {
- webkitResolveLocalFileSystemURL(
- fileURL,
- function(entry) { nextStep(entry, parser) },
- onError);
- },
-
- // Step three, turn the entry into a file.
- function getFile(entry, parser) {
- entry.file(function(file) { nextStep(file, parser) }, onError);
- },
-
- // Step four, parse the file content.
- function parseContent(file, parser) {
- metadata.fileSize = file.size;
- try {
- parser.parse(file, metadata, callback, onError);
- } catch (e) {
- onError(e.stack);
- }
- }
- ];
-
- nextStep();
-};
-
-// Webworker spec says that the worker global object is called self. That's
-// a terrible name since we use it all over the chrome codebase to capture
-// the 'this' keyword in lambdas.
-var global = self;
-
-if (global.constructor.name == 'SharedWorkerGlobalScope') {
- global.addEventListener('connect', function(e) {
- var port = e.ports[0];
- new MetadataDispatcher(port);
- port.start();
- });
-} else {
- // Non-shared worker.
- new MetadataDispatcher(global);
-}
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/metadata_parser.js b/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/metadata_parser.js
deleted file mode 100644
index 087eb42a9aa..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/metadata_parser.js
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * @param {MetadataDispatcher} parent Parent object.
- * @param {string} type Parser type.
- * @param {RegExp} urlFilter RegExp to match URLs.
- * @constructor
- */
-function MetadataParser(parent, type, urlFilter) {
- this.parent_ = parent;
- this.type = type;
- this.urlFilter = urlFilter;
- this.verbose = parent.verbose;
- this.mimeType = 'unknown';
-}
-
-/**
- * Output an error message.
- * @param {...Object} var_args Arguments.
- */
-MetadataParser.prototype.error = function(var_args) {
- this.parent_.error.apply(this.parent_, arguments);
-};
-
-/**
- * Output a log message.
- * @param {...Object} var_args Arguments.
- */
-MetadataParser.prototype.log = function(var_args) {
- this.parent_.log.apply(this.parent_, arguments);
-};
-
-/**
- * Output a log message if |verbose| flag is on.
- * @param {...Object} var_args Arguments.
- */
-MetadataParser.prototype.vlog = function(var_args) {
- if (this.verbose)
- this.parent_.log.apply(this.parent_, arguments);
-};
-
-/**
- * @return {Object} Metadata object with the minimal set of properties.
- */
-MetadataParser.prototype.createDefaultMetadata = function() {
- return {
- type: this.type,
- mimeType: this.mimeType
- };
-};
-
-/* Base class for image metadata parsers */
-function ImageParser(parent, type, urlFilter) {
- MetadataParser.apply(this, arguments);
- this.mimeType = 'image/' + this.type;
-}
-
-ImageParser.prototype = {__proto__: MetadataParser.prototype};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/mpeg_parser.js b/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/mpeg_parser.js
deleted file mode 100644
index 03637cff6ad..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/metadata/mpeg_parser.js
+++ /dev/null
@@ -1,317 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * @param {MetadataDispatcher} parent Parent object.
- * @constructor
- */
-function MpegParser(parent) {
- MetadataParser.call(this, parent, 'mpeg', /\.(mp4|m4v|m4a|mpe?g4?)$/i);
- this.mimeType = 'video/mpeg';
-}
-
-MpegParser.prototype = {__proto__: MetadataParser.prototype};
-
-/**
- * Size of the atom header.
- */
-MpegParser.HEADER_SIZE = 8;
-
-/**
- * @param {ByteReader} br ByteReader instance.
- * @param {number=} opt_end End of atom position.
- * @return {number} Atom size.
- */
-MpegParser.readAtomSize = function(br, opt_end) {
- var pos = br.tell();
-
- if (opt_end) {
- // Assert that opt_end <= buffer end.
- // When supplied, opt_end is the end of the enclosing atom and is used to
- // check the correct nesting.
- br.validateRead(opt_end - pos);
- }
-
- var size = br.readScalar(4, false, opt_end);
-
- if (size < MpegParser.HEADER_SIZE)
- throw 'atom too short (' + size + ') @' + pos;
-
- if (opt_end && pos + size > opt_end)
- throw 'atom too long (' + size + '>' + (opt_end - pos) + ') @' + pos;
-
- return size;
-};
-
-/**
- * @param {ByteReader} br ByteReader instance.
- * @param {number=} opt_end End of atom position.
- * @return {string} Atom name.
- */
-MpegParser.readAtomName = function(br, opt_end) {
- return br.readString(4, opt_end).toLowerCase();
-};
-
-/**
- * @param {Object} metadata Metadata object.
- * @return {Object} Root of the parser tree.
- */
-MpegParser.createRootParser = function(metadata) {
- function findParentAtom(atom, name) {
- for (;;) {
- atom = atom.parent;
- if (!atom) return null;
- if (atom.name == name) return atom;
- }
- }
-
- function parseFtyp(br, atom) {
- metadata.brand = br.readString(4, atom.end);
- }
-
- function parseMvhd(br, atom) {
- var version = br.readScalar(4, false, atom.end);
- var offset = (version == 0) ? 8 : 16;
- br.seek(offset, ByteReader.SEEK_CUR);
- var timescale = br.readScalar(4, false, atom.end);
- var duration = br.readScalar(4, false, atom.end);
- metadata.duration = duration / timescale;
- }
-
- function parseHdlr(br, atom) {
- br.seek(8, ByteReader.SEEK_CUR);
- findParentAtom(atom, 'trak').trackType = br.readString(4, atom.end);
- }
-
- function parseStsd(br, atom) {
- var track = findParentAtom(atom, 'trak');
- if (track && track.trackType == 'vide') {
- br.seek(40, ByteReader.SEEK_CUR);
- metadata.width = br.readScalar(2, false, atom.end);
- metadata.height = br.readScalar(2, false, atom.end);
- }
- }
-
- function parseDataString(name, br, atom) {
- br.seek(8, ByteReader.SEEK_CUR);
- metadata[name] = br.readString(atom.end - br.tell(), atom.end);
- }
-
- function parseCovr(br, atom) {
- br.seek(8, ByteReader.SEEK_CUR);
- metadata.thumbnailURL = br.readImage(atom.end - br.tell(), atom.end);
- }
-
- // 'meta' atom can occur at one of the several places in the file structure.
- var parseMeta = {
- ilst: {
- '©nam': { data: parseDataString.bind(null, 'title') },
- '©alb': { data: parseDataString.bind(null, 'album') },
- '©art': { data: parseDataString.bind(null, 'artist') },
- 'covr': { data: parseCovr }
- },
- versioned: true
- };
-
- // main parser for the entire file structure.
- return {
- ftyp: parseFtyp,
- moov: {
- mvhd: parseMvhd,
- trak: {
- mdia: {
- hdlr: parseHdlr,
- minf: {
- stbl: {
- stsd: parseStsd
- }
- }
- },
- meta: parseMeta
- },
- udta: {
- meta: parseMeta
- },
- meta: parseMeta
- },
- meta: parseMeta
- };
-};
-
-/**
- *
- * @param {File} file File.
- * @param {Object} metadata Metadata.
- * @param {function(Object)} callback Success callback.
- * @param {function} onError Error callback.
- */
-MpegParser.prototype.parse = function(file, metadata, callback, onError) {
- this.rootParser_ = MpegParser.createRootParser(metadata);
-
- // Kick off the processing by reading the first atom's header.
- this.requestRead(file, 0, MpegParser.HEADER_SIZE, null,
- onError, callback.bind(null, metadata));
-};
-
-/**
- * @param {function(ByteReader, Object)|Object} parser Parser tree node.
- * @param {ByteReader} br ByteReader instance.
- * @param {Object} atom Atom descriptor.
- * @param {number} filePos File position of the atom start.
- */
-MpegParser.prototype.applyParser = function(parser, br, atom, filePos) {
- if (this.verbose) {
- var path = atom.name;
- for (var p = atom.parent; p && p.name; p = p.parent) {
- path = p.name + '.' + path;
- }
-
- var action;
- if (!parser) {
- action = 'skipping ';
- } else if (parser instanceof Function) {
- action = 'parsing ';
- } else {
- action = 'recursing';
- }
-
- var start = atom.start - MpegParser.HEADER_SIZE;
- this.vlog(path + ': ' +
- '@' + (filePos + start) + ':' + (atom.end - start),
- action);
- }
-
- if (parser) {
- if (parser instanceof Function) {
- br.pushSeek(atom.start);
- parser(br, atom);
- br.popSeek();
- } else {
- if (parser.versioned) {
- atom.start += 4;
- }
- this.parseMpegAtomsInRange(parser, br, atom, filePos);
- }
- }
-};
-
-/**
- * @param {function(ByteReader, Object)|Object} parser Parser tree node.
- * @param {ByteReader} br ByteReader instance.
- * @param {Object} parentAtom Parent atom descriptor.
- * @param {number} filePos File position of the atom start.
- */
-MpegParser.prototype.parseMpegAtomsInRange = function(
- parser, br, parentAtom, filePos) {
- var count = 0;
- for (var offset = parentAtom.start; offset != parentAtom.end;) {
- if (count++ > 100) // Most likely we are looping through a corrupt file.
- throw 'too many child atoms in ' + parentAtom.name + ' @' + offset;
-
- br.seek(offset);
- var size = MpegParser.readAtomSize(br, parentAtom.end);
- var name = MpegParser.readAtomName(br, parentAtom.end);
-
- this.applyParser(
- parser[name],
- br,
- { start: offset + MpegParser.HEADER_SIZE,
- end: offset + size,
- name: name,
- parent: parentAtom
- },
- filePos
- );
-
- offset += size;
- }
-};
-
-/**
- * @param {File} file File.
- * @param {number} filePos Start position in the file.
- * @param {number} size Atom size.
- * @param {string} name Atom name.
- * @param {function} onError Error callback.
- * @param {function} onSuccess Success callback.
- */
-MpegParser.prototype.requestRead = function(
- file, filePos, size, name, onError, onSuccess) {
- var self = this;
- var reader = new FileReader();
- reader.onerror = onError;
- reader.onload = function(event) {
- self.processTopLevelAtom(
- reader.result, file, filePos, size, name, onError, onSuccess);
- };
- this.vlog('reading @' + filePos + ':' + size);
- reader.readAsArrayBuffer(file.slice(filePos, filePos + size));
-};
-
-/**
- * @param {ArrayBuffer} buf Data buffer.
- * @param {File} file File.
- * @param {number} filePos Start position in the file.
- * @param {number} size Atom size.
- * @param {string} name Atom name.
- * @param {function} onError Error callback.
- * @param {function} onSuccess Success callback.
- */
-MpegParser.prototype.processTopLevelAtom = function(
- buf, file, filePos, size, name, onError, onSuccess) {
- try {
- var br = new ByteReader(buf);
-
- // the header has already been read.
- var atomEnd = size - MpegParser.HEADER_SIZE;
-
- var bufLength = buf.byteLength;
-
- // Check the available data size. It should be either exactly
- // what we requested or HEADER_SIZE bytes less (for the last atom).
- if (bufLength != atomEnd && bufLength != size) {
- throw 'Read failure @' + filePos + ', ' +
- 'requested ' + size + ', read ' + bufLength;
- }
-
- // Process the top level atom.
- if (name) { // name is null only the first time.
- this.applyParser(
- this.rootParser_[name],
- br,
- {start: 0, end: atomEnd, name: name},
- filePos
- );
- }
-
- filePos += bufLength;
- if (bufLength == size) {
- // The previous read returned everything we asked for, including
- // the next atom header at the end of the buffer.
- // Parse this header and schedule the next read.
- br.seek(-MpegParser.HEADER_SIZE, ByteReader.SEEK_END);
- var nextSize = MpegParser.readAtomSize(br);
- var nextName = MpegParser.readAtomName(br);
-
- // If we do not have a parser for the next atom, skip the content and
- // read only the header (the one after the next).
- if (!this.rootParser_[nextName]) {
- filePos += nextSize - MpegParser.HEADER_SIZE;
- nextSize = MpegParser.HEADER_SIZE;
- }
-
- this.requestRead(file, filePos, nextSize, nextName, onError, onSuccess);
- } else {
- // The previous read did not return the next atom header, EOF reached.
- this.vlog('EOF @' + filePos);
- onSuccess();
- }
- } catch (e) {
- onError(e.toString());
- }
-};
-
-MetadataDispatcher.registerParserClass(MpegParser);
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/metrics.js b/chromium/chrome/browser/resources/file_manager/foreground/js/metrics.js
deleted file mode 100644
index 3f34e51a299..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/metrics.js
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Utility methods for accessing chrome.metricsPrivate API.
- *
- * To be included as a first script in main.html
- */
-
-var metrics = {};
-
-/**
- * A map from interval name to interval start timestamp.
- */
-metrics.intervals = {};
-
-/**
- * Start the named time interval.
- * Should be followed by a call to recordInterval with the same name.
- *
- * @param {string} name Unique interval name.
- */
-metrics.startInterval = function(name) {
- metrics.intervals[name] = Date.now();
-};
-
-metrics.startInterval('Load.Total');
-metrics.startInterval('Load.Script');
-
-/**
- * Convert a short metric name to the full format.
- *
- * @param {string} name Short metric name.
- * @return {string} Full metric name.
- * @private
- */
-metrics.convertName_ = function(name) {
- return 'FileBrowser.' + name;
-};
-
-/**
- * Wrapper method for calling chrome.fileBrowserPrivate safely.
- * @param {string} name Method name.
- * @param {Array.<Object>} args Arguments.
- * @private
- */
-metrics.call_ = function(name, args) {
- try {
- chrome.metricsPrivate[name].apply(chrome.metricsPrivate, args);
- } catch (e) {
- console.error(e.stack);
- }
-};
-
-/**
- * Create a decorator function that calls a chrome.metricsPrivate function
- * with the same name and correct parameters.
- *
- * @param {string} name Method name.
- */
-metrics.decorate = function(name) {
- metrics[name] = function() {
- var args = Array.apply(null, arguments);
- args[0] = metrics.convertName_(args[0]);
- metrics.call_(name, args);
- if (metrics.log) {
- console.log('chrome.metricsPrivate.' + name, args);
- }
- };
-};
-
-metrics.decorate('recordMediumCount');
-metrics.decorate('recordSmallCount');
-metrics.decorate('recordTime');
-metrics.decorate('recordUserAction');
-
-/**
- * Complete the time interval recording.
- *
- * Should be preceded by a call to startInterval with the same name. *
- *
- * @param {string} name Unique interval name.
- */
-metrics.recordInterval = function(name) {
- if (name in metrics.intervals) {
- metrics.recordTime(name, Date.now() - metrics.intervals[name]);
- } else {
- console.error('Unknown interval: ' + name);
- }
-};
-
-/**
- * Record an enum value.
- *
- * @param {string} name Metric name.
- * @param {Object} value Enum value.
- * @param {Array.<Object>|number} validValues Array of valid values
- * or a boundary number value.
- */
-metrics.recordEnum = function(name, value, validValues) {
- var boundaryValue;
- var index;
- if (validValues.constructor.name == 'Array') {
- index = validValues.indexOf(value);
- boundaryValue = validValues.length;
- } else {
- index = value;
- boundaryValue = validValues;
- }
- // Collect invalid values in the overflow bucket at the end.
- if (index < 0 || index > boundaryValue)
- index = boundaryValue;
-
- // Setting min to 1 looks strange but this is exactly the recommended way
- // of using histograms for enum-like types. Bucket #0 works as a regular
- // bucket AND the underflow bucket.
- // (Source: UMA_HISTOGRAM_ENUMERATION definition in base/metrics/histogram.h)
- var metricDescr = {
- 'metricName': metrics.convertName_(name),
- 'type': 'histogram-linear',
- 'min': 1,
- 'max': boundaryValue,
- 'buckets': boundaryValue + 1
- };
- metrics.call_('recordValue', [metricDescr, index]);
- if (metrics.log) {
- console.log('chrome.metricsPrivate.recordValue',
- [metricDescr.metricName, index, value]);
- }
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/navigation_list_model.js b/chromium/chrome/browser/resources/file_manager/foreground/js/navigation_list_model.js
deleted file mode 100644
index f1d31e6966d..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/navigation_list_model.js
+++ /dev/null
@@ -1,350 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Entry of NavigationListModel. This constructor should be called only from
- * the helper methods (NavigationModelItem.create).
- *
- * @param {string} path Path.
- * @param {DirectoryEntry} entry Entry. Can be null.
- * @param {string} label Label.
- * @constructor
- */
-function NavigationModelItem(path, entry, label) {
- this.path_ = path;
- this.entry_ = entry;
- this.label_ = label;
- this.resolvingQueue_ = new AsyncUtil.Queue();
-
- Object.seal(this);
-}
-
-NavigationModelItem.prototype = {
- get path() { return this.path_; },
- get label() { return this.label_; }
-};
-
-/**
- * Returns the cached entry of the item. This may return NULL if the target is
- * not available on the filesystem, is not resolved or is under resolving the
- * entry.
- *
- * @return {Entry} Cached entry.
- */
-NavigationModelItem.prototype.getCachedEntry = function() {
- return this.entry_;
-};
-
-/**
- * TODO(mtomasz): Use Entry instead of path.
- * @param {VolumeManagerWrapper} volumeManager VolumeManagerWrapper instance.
- * @param {string} path Path.
- * @param {DirectoryEntry} entry Entry. Can be null.
- * @param {string} label Label.
- * @param {function(FileError)} errorCallback Called when the resolving is
- * failed with the error.
- * @return {NavigationModelItem} Created NavigationModelItem.
- */
-NavigationModelItem.create = function(
- volumeManager, path, entry, label, errorCallback) {
- var item = new NavigationModelItem(path, entry, label);
-
- // If the given entry is null, try to resolve path to get an entry.
- if (!entry) {
- item.resolvingQueue_.run(function(continueCallback) {
- volumeManager.resolveAbsolutePath(
- path,
- function(entry) {
- if (entry.isDirectory)
- item.entry_ = entry;
- else
- errorCallback(util.createFileError(FileError.TYPE_MISMATCH_ERR));
- continueCallback();
- },
- function(error) {
- errorCallback(error);
- continueCallback();
- });
- });
- }
- return item;
-};
-
-/**
- * Retrieves the entry. If the entry is being retrieved, waits until it
- * finishes.
- * @param {function(Entry)} callback Called with the resolved entry. The entry
- * may be NULL if resolving is failed.
- */
-NavigationModelItem.prototype.getEntryAsync = function(callback) {
- // If resolving the entry is running, wait until it finishes.
- this.resolvingQueue_.run(function(continueCallback) {
- callback(this.entry_);
- continueCallback();
- }.bind(this));
-};
-
-/**
- * Returns if this item is a shortcut or a volume root.
- * @return {boolean} True if a shortcut, false if a volume root.
- */
-NavigationModelItem.prototype.isShortcut = function() {
- return !PathUtil.isRootPath(this.path_);
-};
-
-/**
- * A navigation list model. This model combines the 2 lists.
- * @param {VolumeManagerWrapper} volumeManager VolumeManagerWrapper instance.
- * @param {cr.ui.ArrayDataModel} shortcutListModel The list of folder shortcut.
- * @constructor
- * @extends {cr.EventTarget}
- */
-function NavigationListModel(volumeManager, shortcutListModel) {
- cr.EventTarget.call(this);
-
- this.volumeManager_ = volumeManager;
- this.shortcutListModel_ = shortcutListModel;
-
- var volumeInfoToModelItem = function(volumeInfo) {
- if (volumeInfo.volumeType == util.VolumeType.DRIVE) {
- // For drive volume, we assign the path to "My Drive".
- return NavigationModelItem.create(
- this.volumeManager_,
- volumeInfo.mountPath + '/root',
- null,
- volumeInfo.getLabel(),
- function() {});
- } else {
- return NavigationModelItem.create(
- this.volumeManager_,
- volumeInfo.mountPath,
- volumeInfo.root,
- volumeInfo.getLabel(),
- function() {});
- }
- }.bind(this);
-
- var pathToModelItem = function(path) {
- var item = NavigationModelItem.create(
- this.volumeManager_,
- path,
- null, // Entry will be resolved.
- PathUtil.getFolderLabel(path),
- function(error) {
- if (error.code == FileError.NOT_FOUND_ERR)
- this.onItemNotFoundError(item);
- }.bind(this));
- return item;
- }.bind(this);
-
- /**
- * Type of updated list.
- * @enum {number}
- * @const
- */
- var ListType = {
- VOLUME_LIST: 1,
- SHORTCUT_LIST: 2
- };
- Object.freeze(ListType);
-
- // Generates this.volumeList_ and this.shortcutList_ from the models.
- this.volumeList_ =
- this.volumeManager_.volumeInfoList.slice().map(volumeInfoToModelItem);
-
- this.shortcutList_ = [];
- for (var i = 0; i < this.shortcutListModel_.length; i++) {
- var shortcutPath = this.shortcutListModel_.item(i);
- var volumeInfo = this.volumeManager_.getVolumeInfo(shortcutPath);
- var isMounted = volumeInfo && !volumeInfo.error;
- if (isMounted)
- this.shortcutList_.push(pathToModelItem(shortcutPath));
- }
-
- // Generates a combined 'permuted' event from an event of either list.
- var permutedHandler = function(listType, event) {
- var permutation;
-
- // Build the volumeList.
- if (listType == ListType.VOLUME_LIST) {
- // The volume is mounted or unmounted.
- var newList = [];
-
- // Use the old instances if they just move.
- for (var i = 0; i < event.permutation.length; i++) {
- if (event.permutation[i] >= 0)
- newList[event.permutation[i]] = this.volumeList_[i];
- }
-
- // Create missing instances.
- for (var i = 0; i < event.newLength; i++) {
- if (!newList[i]) {
- newList[i] = volumeInfoToModelItem(
- this.volumeManager_.volumeInfoList.item(i));
- }
- }
- this.volumeList_ = newList;
-
- permutation = event.permutation.slice();
- } else {
- // volumeList part has not been changed, so the permutation should be
- // idenetity mapping.
- permutation = [];
- for (var i = 0; i < this.volumeList_.length; i++)
- permutation[i] = i;
- }
-
- // Build the shortcutList. Even if the event is for the volumeInfoList
- // update, the short cut path may be unmounted or newly mounted. So, here
- // shortcutList will always be re-built.
- // Currently this code may be redundant, as shortcut folder is supported
- // only on Drive File System and we can assume single-profile, but
- // multi-profile will be supported later.
- // The shortcut list is sorted in case-insensitive lexicographical order.
- // So we just can traverse the two list linearly.
- var modelIndex = 0;
- var oldListIndex = 0;
- var newList = [];
- while (modelIndex < this.shortcutListModel_.length &&
- oldListIndex < this.shortcutList_.length) {
- var shortcutPath = this.shortcutListModel_.item(modelIndex);
- var cmp = this.shortcutListModel_.compare(
- shortcutPath, this.shortcutList_[oldListIndex].path);
- if (cmp > 0) {
- // The shortcut at shortcutList_[oldListIndex] is removed.
- permutation.push(-1);
- oldListIndex++;
- continue;
- }
-
- // Check if the volume where the shortcutPath is is mounted or not.
- var volumeInfo = this.volumeManager_.getVolumeInfo(shortcutPath);
- var isMounted = volumeInfo && !volumeInfo.error;
- if (cmp == 0) {
- // There exists an old NavigationModelItem instance.
- if (isMounted) {
- // Reuse the old instance.
- permutation.push(newList.length + this.volumeList_.length);
- newList.push(this.shortcutList_[oldListIndex]);
- } else {
- permutation.push(-1);
- }
- oldListIndex++;
- } else {
- // We needs to create a new instance for the shortcut path.
- if (isMounted)
- newList.push(pathToModelItem(shortcutPath));
- }
- modelIndex++;
- }
-
- // Add remaining (new) shortcuts if necessary.
- for (; modelIndex < this.shortcutListModel_.length; modelIndex++) {
- var shortcutPath = this.shortcutListModel_.item(modelIndex);
- var volumeInfo = this.volumeManager_.getVolumeInfo(shortcutPath);
- var isMounted = volumeInfo && !volumeInfo.error;
- if (isMounted)
- newList.push(pathToModelItem(shortcutPath));
- }
-
- // Fill remaining permutation if necessary.
- for (; oldListIndex < this.shortcutList_.length; oldListIndex++)
- permutation.push(-1);
-
- this.shortcutList_ = newList;
-
- // Dispatch permuted event.
- var permutedEvent = new Event('permuted');
- permutedEvent.newLength =
- this.volumeList_.length + this.shortcutList_.length;
- permutedEvent.permutation = permutation;
- this.dispatchEvent(permutedEvent);
- };
-
- this.volumeManager_.volumeInfoList.addEventListener(
- 'permuted', permutedHandler.bind(this, ListType.VOLUME_LIST));
- this.shortcutListModel_.addEventListener(
- 'permuted', permutedHandler.bind(this, ListType.SHORTCUT_LIST));
-
- // 'change' event is just ignored, because it is not fired neither in
- // the folder shortcut list nor in the volume info list.
- // 'splice' and 'sorted' events are not implemented, since they are not used
- // in list.js.
-}
-
-/**
- * NavigationList inherits cr.EventTarget.
- */
-NavigationListModel.prototype = {
- __proto__: cr.EventTarget.prototype,
- get length() { return this.length_(); },
- get folderShortcutList() { return this.shortcutList_; }
-};
-
-/**
- * Returns the item at the given index.
- * @param {number} index The index of the entry to get.
- * @return {?string} The path at the given index.
- */
-NavigationListModel.prototype.item = function(index) {
- var offset = this.volumeList_.length;
- if (index < offset)
- return this.volumeList_[index];
- return this.shortcutList_[index - offset];
-};
-
-/**
- * Returns the number of items in the model.
- * @return {number} The length of the model.
- * @private
- */
-NavigationListModel.prototype.length_ = function() {
- return this.volumeList_.length + this.shortcutList_.length;
-};
-
-/**
- * Returns the first matching item.
- * @param {NavigationModelItem} modelItem The entry to find.
- * @param {number=} opt_fromIndex If provided, then the searching start at
- * the {@code opt_fromIndex}.
- * @return {number} The index of the first found element or -1 if not found.
- */
-NavigationListModel.prototype.indexOf = function(modelItem, opt_fromIndex) {
- for (var i = opt_fromIndex || 0; i < this.length; i++) {
- if (modelItem === this.item(i))
- return i;
- }
- return -1;
-};
-
-/**
- * Called when one od the items is not found on the filesystem.
- * @param {NavigationModelItem} modelItem The entry which is not found.
- */
-NavigationListModel.prototype.onItemNotFoundError = function(modelItem) {
- var index = this.indexOf(modelItem);
- if (index === -1) {
- // Invalid modelItem.
- } else if (index < this.volumeList_.length) {
- // The item is in the volume list.
- // Not implemented.
- // TODO(yoshiki): Implement it when necessary.
- } else {
- // The item is in the folder shortcut list.
- if (this.isDriveMounted())
- this.shortcutListModel_.remove(modelItem.path);
- }
-};
-
-/**
- * Returns if the drive is mounted or not.
- * @return {boolean} True if the drive is mounted, false otherwise.
- */
-NavigationListModel.prototype.isDriveMounted = function() {
- var volumeInfo =
- this.volumeManager_.getCurrentProfileVolumeInfo(RootType.DRIVE);
- return !!volumeInfo && volumeInfo.root;
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/photo/gallery.js b/chromium/chrome/browser/resources/file_manager/foreground/js/photo/gallery.js
deleted file mode 100644
index 91171b6d3f1..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/photo/gallery.js
+++ /dev/null
@@ -1,867 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Called from the main frame when unloading.
- * @return {string?} User-visible message on null if it is OK to close.
- */
-function beforeunload() { return Gallery.instance.onBeforeUnload() }
-
-/**
- * Called from the main frame when unloading.
- * @param {boolean=} opt_exiting True if the app is exiting.
- */
-function unload(opt_exiting) { Gallery.instance.onUnload(opt_exiting) }
-
-/**
- * Gallery for viewing and editing image files.
- *
- * @param {Object} context Object containing the following:
- * {function(string)} onNameChange Called every time a selected
- * item name changes (on rename and on selection change).
- * {AppWindow} appWindow
- * {function(string)} onBack
- * {function()} onClose
- * {function()} onMaximize
- * {function(boolean)} onAppRegionChanged
- * {MetadataCache} metadataCache
- * {Array.<Object>} shareActions
- * {string} readonlyDirName Directory name for readonly warning or null.
- * {DirEntry} saveDirEntry Directory to save to.
- * {function(string)} displayStringFunction.
- * @param {VolumeManagerWrapper} volumeManager The VolumeManager instance of
- * the system.
- * @class
- * @constructor
- */
-function Gallery(context, volumeManager) {
- this.container_ = document.querySelector('.gallery');
- this.document_ = document;
- this.context_ = context;
- this.metadataCache_ = context.metadataCache;
- this.volumeManager_ = volumeManager;
- this.selectedEntry_ = null;
-
- this.dataModel_ = new cr.ui.ArrayDataModel([]);
- this.selectionModel_ = new cr.ui.ListSelectionModel();
- this.displayStringFunction_ = context.displayStringFunction;
-
- this.initDom_();
- this.initListeners_();
-}
-
-/**
- * Gallery extends cr.EventTarget.
- */
-Gallery.prototype.__proto__ = cr.EventTarget.prototype;
-
-/**
- * Creates and initializes a Gallery object based on a context.
- *
- * @param {Object} context Gallery context.
- * @param {VolumeManagerWrapper} volumeManager VolumeManager of the system.
- * @param {Array.<Entry>} entries Array of entries.
- * @param {Array.<Entry>} selectedEntries Array of selected entries.
- */
-Gallery.open = function(context, volumeManager, entries, selectedEntries) {
- Gallery.instance = new Gallery(context, volumeManager);
- Gallery.instance.load(entries, selectedEntries);
-};
-
-/**
- * Tools fade-out timeout im milliseconds.
- * @const
- * @type {number}
- */
-Gallery.FADE_TIMEOUT = 3000;
-
-/**
- * First time tools fade-out timeout im milliseconds.
- * @const
- * @type {number}
- */
-Gallery.FIRST_FADE_TIMEOUT = 1000;
-
-/**
- * Time until mosaic is initialized in the background. Used to make gallery
- * in the slide mode load faster. In miiliseconds.
- * @const
- * @type {number}
- */
-Gallery.MOSAIC_BACKGROUND_INIT_DELAY = 1000;
-
-/**
- * Types of metadata Gallery uses (to query the metadata cache).
- * @const
- * @type {string}
- */
-Gallery.METADATA_TYPE = 'thumbnail|filesystem|media|streaming|drive';
-
-/**
- * Initializes listeners.
- * @private
- */
-Gallery.prototype.initListeners_ = function() {
- this.document_.oncontextmenu = function(e) { e.preventDefault(); };
- this.keyDownBound_ = this.onKeyDown_.bind(this);
- this.document_.body.addEventListener('keydown', this.keyDownBound_);
-
- this.inactivityWatcher_ = new MouseInactivityWatcher(
- this.container_, Gallery.FADE_TIMEOUT, this.hasActiveTool.bind(this));
-
- // Search results may contain files from different subdirectories so
- // the observer is not going to work.
- if (!this.context_.searchResults && this.context_.curDirEntry) {
- this.thumbnailObserverId_ = this.metadataCache_.addObserver(
- this.context_.curDirEntry,
- MetadataCache.CHILDREN,
- 'thumbnail',
- this.updateThumbnails_.bind(this));
- }
-
- this.volumeManager_.addEventListener('externally-unmounted',
- this.onExternallyUnmounted_.bind(this));
-};
-
-/**
- * Closes gallery when a volume containing the selected item is unmounted.
- * @param {Event} event The unmount event.
- * @private
- */
-Gallery.prototype.onExternallyUnmounted_ = function(event) {
- if (!this.selectedEntry_)
- return;
-
- if (this.volumeManager_.getVolumeInfo(this.selectedEntry_) ===
- event.volumeInfo) {
- this.onBack_();
- }
-};
-
-/**
- * Beforeunload handler.
- * @return {string?} User-visible message on null if it is OK to close.
- */
-Gallery.prototype.onBeforeUnload = function() {
- return this.slideMode_.onBeforeUnload();
-};
-
-/**
- * Unloads the Gallery.
- * @param {boolean} exiting True if the app is exiting.
- */
-Gallery.prototype.onUnload = function(exiting) {
- if (!this.context_.searchResults) {
- this.metadataCache_.removeObserver(this.thumbnailObserverId_);
- }
- this.slideMode_.onUnload(exiting);
-};
-
-/**
- * Initializes DOM UI
- * @private
- */
-Gallery.prototype.initDom_ = function() {
- var content = util.createChild(this.container_, 'content');
- content.addEventListener('click', this.onContentClick_.bind(this));
-
- this.header_ = util.createChild(this.container_, 'header tool dimmable');
- this.toolbar_ = util.createChild(this.container_, 'toolbar tool dimmable');
-
- var backButton = util.createChild(this.container_,
- 'back-button tool dimmable');
- util.createChild(backButton);
- backButton.addEventListener('click', this.onBack_.bind(this));
-
- var preventDefault = function(event) { event.preventDefault(); };
-
- var maximizeButton = util.createChild(this.header_,
- 'maximize-button tool dimmable',
- 'button');
- maximizeButton.tabIndex = -1;
- maximizeButton.addEventListener('click', this.onMaximize_.bind(this));
- maximizeButton.addEventListener('mousedown', preventDefault);
-
- var closeButton = util.createChild(this.header_,
- 'close-button tool dimmable',
- 'button');
- closeButton.tabIndex = -1;
- closeButton.addEventListener('click', this.onClose_.bind(this));
- closeButton.addEventListener('mousedown', preventDefault);
-
- this.filenameSpacer_ = util.createChild(this.toolbar_, 'filename-spacer');
- this.filenameEdit_ = util.createChild(this.filenameSpacer_,
- 'namebox', 'input');
-
- this.filenameEdit_.setAttribute('type', 'text');
- this.filenameEdit_.addEventListener('blur',
- this.onFilenameEditBlur_.bind(this));
-
- this.filenameEdit_.addEventListener('focus',
- this.onFilenameFocus_.bind(this));
-
- this.filenameEdit_.addEventListener('keydown',
- this.onFilenameEditKeydown_.bind(this));
-
- util.createChild(this.toolbar_, 'button-spacer');
-
- this.prompt_ = new ImageEditor.Prompt(
- this.container_, this.displayStringFunction_);
-
- this.modeButton_ = util.createChild(this.toolbar_, 'button mode', 'button');
- this.modeButton_.addEventListener('click',
- this.toggleMode_.bind(this, null));
-
- this.mosaicMode_ = new MosaicMode(content,
- this.dataModel_,
- this.selectionModel_,
- this.metadataCache_,
- this.toggleMode_.bind(this, null));
-
- this.slideMode_ = new SlideMode(this.container_,
- content,
- this.toolbar_,
- this.prompt_,
- this.dataModel_,
- this.selectionModel_,
- this.context_,
- this.toggleMode_.bind(this),
- this.displayStringFunction_);
-
- this.slideMode_.addEventListener('image-displayed', function() {
- cr.dispatchSimpleEvent(this, 'image-displayed');
- }.bind(this));
- this.slideMode_.addEventListener('image-saved', function() {
- cr.dispatchSimpleEvent(this, 'image-saved');
- }.bind(this));
-
- var deleteButton = this.createToolbarButton_('delete', 'GALLERY_DELETE');
- deleteButton.addEventListener('click', this.delete_.bind(this));
-
- this.shareButton_ = this.createToolbarButton_('share', 'GALLERY_SHARE');
- this.shareButton_.setAttribute('disabled', '');
- this.shareButton_.addEventListener('click', this.toggleShare_.bind(this));
-
- this.shareMenu_ = util.createChild(this.container_, 'share-menu');
- this.shareMenu_.hidden = true;
- util.createChild(this.shareMenu_, 'bubble-point');
-
- this.dataModel_.addEventListener('splice', this.onSplice_.bind(this));
- this.dataModel_.addEventListener('content', this.onContentChange_.bind(this));
-
- this.selectionModel_.addEventListener('change', this.onSelection_.bind(this));
- this.slideMode_.addEventListener('useraction', this.onUserAction_.bind(this));
-};
-
-/**
- * Creates toolbar button.
- *
- * @param {string} className Class to add.
- * @param {string} title Button title.
- * @return {HTMLElement} Newly created button.
- * @private
- */
-Gallery.prototype.createToolbarButton_ = function(className, title) {
- var button = util.createChild(this.toolbar_, className, 'button');
- button.title = this.displayStringFunction_(title);
- return button;
-};
-
-/**
- * Loads the content.
- *
- * @param {Array.<Entry>} entries Array of entries.
- * @param {Array.<Entry>} selectedEntries Array of selected entries. Must be a
- * subset of {@code entries}.
- */
-Gallery.prototype.load = function(entries, selectedEntries) {
- var items = [];
- for (var index = 0; index < entries.length; ++index) {
- items.push(new Gallery.Item(entries[index]));
- }
- this.dataModel_.push.apply(this.dataModel_, items);
-
- this.selectionModel_.adjustLength(this.dataModel_.length);
-
- for (var i = 0; i !== selectedEntries.length; i++) {
- var selectedIndex = entries.indexOf(selectedEntries[i]);
- if (selectedIndex >= 0)
- this.selectionModel_.setIndexSelected(selectedIndex, true);
- else
- console.error('Cannot select ' + selectedEntries[i]);
- }
-
- if (this.selectionModel_.selectedIndexes.length === 0)
- this.onSelection_();
-
- var mosaic = this.mosaicMode_ && this.mosaicMode_.getMosaic();
-
- // Mosaic view should show up if most of the selected files are images.
- var imagesCount = 0;
- for (var i = 0; i !== selectedEntries.length; i++) {
- if (FileType.getMediaType(selectedEntries[i]) === 'image')
- imagesCount++;
- }
- var mostlyImages = imagesCount > (selectedEntries.length / 2.0);
-
- var forcedMosaic = (this.context_.pageState &&
- this.context_.pageState.gallery === 'mosaic');
-
- var showMosaic = (mostlyImages && selectedEntries.length > 1) || forcedMosaic;
- if (mosaic && showMosaic) {
- this.setCurrentMode_(this.mosaicMode_);
- mosaic.init();
- mosaic.show();
- this.inactivityWatcher_.check(); // Show the toolbar.
- cr.dispatchSimpleEvent(this, 'loaded');
- } else {
- this.setCurrentMode_(this.slideMode_);
- var maybeLoadMosaic = function() {
- if (mosaic)
- mosaic.init();
- cr.dispatchSimpleEvent(this, 'loaded');
- }.bind(this);
- /* TODO: consider nice blow-up animation for the first image */
- this.slideMode_.enter(null, function() {
- // Flash the toolbar briefly to show it is there.
- this.inactivityWatcher_.kick(Gallery.FIRST_FADE_TIMEOUT);
- }.bind(this),
- maybeLoadMosaic);
- }
-};
-
-/**
- * Closes the Gallery and go to Files.app.
- * @private
- */
-Gallery.prototype.back_ = function() {
- if (util.isFullScreen(this.context_.appWindow)) {
- util.toggleFullScreen(this.context_.appWindow,
- false); // Leave the full screen mode.
- }
- this.context_.onBack(this.getSelectedEntries());
-};
-
-/**
- * Handles user's 'Back' action (Escape or a click on the X icon).
- * @private
- */
-Gallery.prototype.onBack_ = function() {
- this.executeWhenReady(this.back_.bind(this));
-};
-
-/**
- * Handles user's 'Close' action.
- * @private
- */
-Gallery.prototype.onClose_ = function() {
- this.executeWhenReady(this.context_.onClose);
-};
-
-/**
- * Handles user's 'Maximize' action (Escape or a click on the X icon).
- * @private
- */
-Gallery.prototype.onMaximize_ = function() {
- this.executeWhenReady(this.context_.onMaximize);
-};
-
-/**
- * Executes a function when the editor is done with the modifications.
- * @param {function} callback Function to execute.
- */
-Gallery.prototype.executeWhenReady = function(callback) {
- this.currentMode_.executeWhenReady(callback);
-};
-
-/**
- * @return {Object} File browser private API.
- */
-Gallery.getFileBrowserPrivate = function() {
- return chrome.fileBrowserPrivate || window.top.chrome.fileBrowserPrivate;
-};
-
-/**
- * @return {boolean} True if some tool is currently active.
- */
-Gallery.prototype.hasActiveTool = function() {
- return this.currentMode_.hasActiveTool() ||
- this.isSharing_() || this.isRenaming_();
-};
-
-/**
-* External user action event handler.
-* @private
-*/
-Gallery.prototype.onUserAction_ = function() {
- this.closeShareMenu_();
- // Show the toolbar and hide it after the default timeout.
- this.inactivityWatcher_.kick();
-};
-
-/**
- * Sets the current mode, update the UI.
- * @param {Object} mode Current mode.
- * @private
- */
-Gallery.prototype.setCurrentMode_ = function(mode) {
- if (mode !== this.slideMode_ && mode !== this.mosaicMode_)
- console.error('Invalid Gallery mode');
-
- this.currentMode_ = mode;
- this.container_.setAttribute('mode', this.currentMode_.getName());
- this.updateSelectionAndState_();
- this.updateButtons_();
-};
-
-/**
- * Mode toggle event handler.
- * @param {function=} opt_callback Callback.
- * @param {Event=} opt_event Event that caused this call.
- * @private
- */
-Gallery.prototype.toggleMode_ = function(opt_callback, opt_event) {
- if (!this.modeButton_)
- return;
-
- if (this.changingMode_) // Do not re-enter while changing the mode.
- return;
-
- if (opt_event)
- this.onUserAction_();
-
- this.changingMode_ = true;
-
- var onModeChanged = function() {
- this.changingMode_ = false;
- if (opt_callback) opt_callback();
- }.bind(this);
-
- var tileIndex = Math.max(0, this.selectionModel_.selectedIndex);
-
- var mosaic = this.mosaicMode_.getMosaic();
- var tileRect = mosaic.getTileRect(tileIndex);
-
- if (this.currentMode_ === this.slideMode_) {
- this.setCurrentMode_(this.mosaicMode_);
- mosaic.transform(
- tileRect, this.slideMode_.getSelectedImageRect(), true /* instant */);
- this.slideMode_.leave(tileRect,
- function() {
- // Animate back to normal position.
- mosaic.transform();
- mosaic.show();
- onModeChanged();
- }.bind(this));
- } else {
- this.setCurrentMode_(this.slideMode_);
- this.slideMode_.enter(tileRect,
- function() {
- // Animate to zoomed position.
- mosaic.transform(tileRect, this.slideMode_.getSelectedImageRect());
- mosaic.hide();
- }.bind(this),
- onModeChanged);
- }
-};
-
-/**
- * Deletes the selected items.
- * @private
- */
-Gallery.prototype.delete_ = function() {
- this.onUserAction_();
-
- // Clone the sorted selected indexes array.
- var indexesToRemove = this.selectionModel_.selectedIndexes.slice();
- if (!indexesToRemove.length)
- return;
-
- /* TODO(dgozman): Implement Undo delete, Remove the confirmation dialog. */
-
- var itemsToRemove = this.getSelectedItems();
- var plural = itemsToRemove.length > 1;
- var param = plural ? itemsToRemove.length : itemsToRemove[0].getFileName();
-
- function deleteNext() {
- if (!itemsToRemove.length)
- return; // All deleted.
-
- // TODO(hirono): Use fileOperationManager.
- var entry = itemsToRemove.pop().getEntry();
- entry.remove(deleteNext, function() {
- util.flog('Error deleting: ' + entry.fullPath, deleteNext);
- });
- }
-
- // Prevent the Gallery from handling Esc and Enter.
- this.document_.body.removeEventListener('keydown', this.keyDownBound_);
- var restoreListener = function() {
- this.document_.body.addEventListener('keydown', this.keyDownBound_);
- }.bind(this);
-
- cr.ui.dialogs.BaseDialog.OK_LABEL = this.displayStringFunction_(
- 'GALLERY_OK_LABEL');
- cr.ui.dialogs.BaseDialog.CANCEL_LABEL =
- this.displayStringFunction_('GALLERY_CANCEL_LABEL');
- var confirm = new cr.ui.dialogs.ConfirmDialog(this.container_);
- confirm.show(
- this.displayStringFunction_(plural ? 'GALLERY_CONFIRM_DELETE_SOME' :
- 'GALLERY_CONFIRM_DELETE_ONE', param),
- function() {
- restoreListener();
- this.selectionModel_.unselectAll();
- this.selectionModel_.leadIndex = -1;
- // Remove items from the data model, starting from the highest index.
- while (indexesToRemove.length)
- this.dataModel_.splice(indexesToRemove.pop(), 1);
- // Delete actual files.
- deleteNext();
- }.bind(this),
- function() {
- // Restore the listener after a timeout so that ESC is processed.
- setTimeout(restoreListener, 0);
- });
-};
-
-/**
- * @return {Array.<Gallery.Item>} Current selection.
- */
-Gallery.prototype.getSelectedItems = function() {
- return this.selectionModel_.selectedIndexes.map(
- this.dataModel_.item.bind(this.dataModel_));
-};
-
-/**
- * @return {Array.<Entry>} Array of currently selected entries.
- */
-Gallery.prototype.getSelectedEntries = function() {
- return this.selectionModel_.selectedIndexes.map(function(index) {
- return this.dataModel_.item(index).getEntry();
- }.bind(this));
-};
-
-/**
- * @return {Gallery.Item} Current single selection.
- */
-Gallery.prototype.getSingleSelectedItem = function() {
- var items = this.getSelectedItems();
- if (items.length > 1)
- throw new Error('Unexpected multiple selection');
- return items[0];
-};
-
-/**
- * Selection change event handler.
- * @private
- */
-Gallery.prototype.onSelection_ = function() {
- this.updateSelectionAndState_();
- this.updateShareMenu_();
-};
-
-/**
- * Data model splice event handler.
- * @private
- */
-Gallery.prototype.onSplice_ = function() {
- this.selectionModel_.adjustLength(this.dataModel_.length);
-};
-
-/**
- * Content change event handler.
- * @param {Event} event Event.
- * @private
-*/
-Gallery.prototype.onContentChange_ = function(event) {
- var index = this.dataModel_.indexOf(event.item);
- if (index !== this.selectionModel_.selectedIndex)
- console.error('Content changed for unselected item');
- this.updateSelectionAndState_();
-};
-
-/**
- * Keydown handler.
- *
- * @param {Event} event Event.
- * @private
- */
-Gallery.prototype.onKeyDown_ = function(event) {
- var wasSharing = this.isSharing_();
- this.closeShareMenu_();
-
- if (this.currentMode_.onKeyDown(event))
- return;
-
- switch (util.getKeyModifiers(event) + event.keyIdentifier) {
- case 'U+0008': // Backspace.
- // The default handler would call history.back and close the Gallery.
- event.preventDefault();
- break;
-
- case 'U+001B': // Escape
- // Swallow Esc if it closed the Share menu, otherwise close the Gallery.
- if (!wasSharing)
- this.onBack_();
- break;
-
- case 'U+004D': // 'm' switches between Slide and Mosaic mode.
- this.toggleMode_(null, event);
- break;
-
- case 'U+0056': // 'v'
- this.slideMode_.startSlideshow(SlideMode.SLIDESHOW_INTERVAL_FIRST, event);
- break;
-
- case 'U+007F': // Delete
- case 'Shift-U+0033': // Shift+'3' (Delete key might be missing).
- this.delete_();
- break;
- }
-};
-
-// Name box and rename support.
-
-/**
- * Updates the UI related to the selected item and the persistent state.
- *
- * @private
- */
-Gallery.prototype.updateSelectionAndState_ = function() {
- var path;
- var displayName = '';
-
- var selectedItems = this.getSelectedItems();
- if (selectedItems.length === 1) {
- var item = selectedItems[0];
- var entry = item.getEntry();
- window.top.document.title = entry.name;
- displayName = ImageUtil.getDisplayNameFromName(entry.name);
- } else if (selectedItems.length > 1 && this.context_.curDirEntry) {
- // If the Gallery was opened on search results the search query will not be
- // recorded in the app state and the relaunch will just open the gallery
- // in the curDirEntry directory.
- path = this.context_.curDirEntry.fullPath;
- window.top.document.title = this.context_.curDirEntry.name;
- displayName =
- this.displayStringFunction_('GALLERY_ITEMS_SELECTED',
- selectedItems.length);
- }
-
- window.top.util.updateAppState(path,
- {gallery: (this.currentMode_ === this.mosaicMode_ ? 'mosaic' : 'slide')});
-
- // We can't rename files in readonly directory.
- // We can only rename a single file.
- this.filenameEdit_.disabled = selectedItems.length !== 1 ||
- this.context_.readonlyDirName;
-
- this.filenameEdit_.value = displayName;
-
- // Resolve real filesystem path of the current file.
- if (this.selectionModel_.selectedIndexes.length) {
- var selectedIndex = this.selectionModel_.selectedIndex;
- var selectedItem =
- this.dataModel_.item(this.selectionModel_.selectedIndex);
- this.selectedEntry_ = selectedItem.getEntry();
- }
-};
-
-/**
- * Click event handler on filename edit box
- * @private
- */
-Gallery.prototype.onFilenameFocus_ = function() {
- ImageUtil.setAttribute(this.filenameSpacer_, 'renaming', true);
- this.filenameEdit_.originalValue = this.filenameEdit_.value;
- setTimeout(this.filenameEdit_.select.bind(this.filenameEdit_), 0);
- this.onUserAction_();
-};
-
-/**
- * Blur event handler on filename edit box.
- *
- * @param {Event} event Blur event.
- * @return {boolean} if default action should be prevented.
- * @private
- */
-Gallery.prototype.onFilenameEditBlur_ = function(event) {
- if (this.filenameEdit_.value && this.filenameEdit_.value[0] === '.') {
- this.prompt_.show('GALLERY_FILE_HIDDEN_NAME', 5000);
- this.filenameEdit_.focus();
- event.stopPropagation();
- event.preventDefault();
- return false;
- }
-
- var item = this.getSingleSelectedItem();
- var oldEntry = item.getEntry();
-
- var onFileExists = function() {
- this.prompt_.show('GALLERY_FILE_EXISTS', 3000);
- this.filenameEdit_.value = name;
- this.filenameEdit_.focus();
- }.bind(this);
-
- var onSuccess = function() {
- var event = new Event('content');
- event.item = item;
- event.oldEntry = oldEntry;
- event.metadata = null; // Metadata unchanged.
- this.dataModel_.dispatchEvent(event);
- }.bind(this);
-
- if (this.filenameEdit_.value) {
- this.getSingleSelectedItem().rename(
- this.filenameEdit_.value, onSuccess, onFileExists);
- }
-
- ImageUtil.setAttribute(this.filenameSpacer_, 'renaming', false);
- this.onUserAction_();
-};
-
-/**
- * Keydown event handler on filename edit box
- * @private
- */
-Gallery.prototype.onFilenameEditKeydown_ = function() {
- switch (event.keyCode) {
- case 27: // Escape
- this.filenameEdit_.value = this.filenameEdit_.originalValue;
- this.filenameEdit_.blur();
- break;
-
- case 13: // Enter
- this.filenameEdit_.blur();
- break;
- }
- event.stopPropagation();
-};
-
-/**
- * @return {boolean} True if file renaming is currently in progress.
- * @private
- */
-Gallery.prototype.isRenaming_ = function() {
- return this.filenameSpacer_.hasAttribute('renaming');
-};
-
-/**
- * Content area click handler.
- * @private
- */
-Gallery.prototype.onContentClick_ = function() {
- this.closeShareMenu_();
- this.filenameEdit_.blur();
-};
-
-// Share button support.
-
-/**
- * @return {boolean} True if the Share menu is active.
- * @private
- */
-Gallery.prototype.isSharing_ = function() {
- return !this.shareMenu_.hidden;
-};
-
-/**
- * Close Share menu if it is open.
- * @private
- */
-Gallery.prototype.closeShareMenu_ = function() {
- if (this.isSharing_())
- this.toggleShare_();
-};
-
-/**
- * Share button handler.
- * @private
- */
-Gallery.prototype.toggleShare_ = function() {
- if (!this.shareButton_.hasAttribute('disabled'))
- this.shareMenu_.hidden = !this.shareMenu_.hidden;
- this.inactivityWatcher_.check();
-};
-
-/**
- * Updates available actions list based on the currently selected urls.
- * @private.
- */
-Gallery.prototype.updateShareMenu_ = function() {
- var entries = this.getSelectedEntries();
-
- function isShareAction(task) {
- var taskParts = task.taskId.split('|');
- return taskParts[0] !== chrome.runtime.id;
- }
-
- var api = Gallery.getFileBrowserPrivate();
- var mimeTypes = []; // TODO(kaznacheev) Collect mime types properly.
-
- var createShareMenu = function(tasks) {
- var wasHidden = this.shareMenu_.hidden;
- this.shareMenu_.hidden = true;
- var items = this.shareMenu_.querySelectorAll('.item');
- for (var i = 0; i !== items.length; i++) {
- items[i].parentNode.removeChild(items[i]);
- }
-
- for (var t = 0; t !== tasks.length; t++) {
- var task = tasks[t];
- if (!isShareAction(task)) continue;
-
- var item = util.createChild(this.shareMenu_, 'item');
- item.textContent = task.title;
- item.style.backgroundImage = 'url(' + task.iconUrl + ')';
- item.addEventListener('click', function(taskId) {
- this.toggleShare_(); // Hide the menu.
- this.executeWhenReady(api.executeTask.bind(api, taskId, entries));
- }.bind(this, task.taskId));
- }
-
- var empty = this.shareMenu_.querySelector('.item') === null;
- ImageUtil.setAttribute(this.shareButton_, 'disabled', empty);
- this.shareMenu_.hidden = wasHidden || empty;
- }.bind(this);
-
- // Create or update the share menu with a list of sharing tasks and show
- // or hide the share button.
- // TODO(mtomasz): Pass Entries directly, instead of URLs.
- if (!entries.length)
- createShareMenu([]); // Empty list of tasks, since there is no selection.
- else
- api.getFileTasks(util.entriesToURLs(entries), mimeTypes, createShareMenu);
-};
-
-/**
- * Updates thumbnails.
- * @private
- */
-Gallery.prototype.updateThumbnails_ = function() {
- if (this.currentMode_ === this.slideMode_)
- this.slideMode_.updateThumbnails();
-
- if (this.mosaicMode_) {
- var mosaic = this.mosaicMode_.getMosaic();
- if (mosaic.isInitialized())
- mosaic.reload();
- }
-};
-
-/**
- * Updates buttons.
- * @private
- */
-Gallery.prototype.updateButtons_ = function() {
- if (this.modeButton_) {
- var oppositeMode =
- this.currentMode_ === this.slideMode_ ? this.mosaicMode_ :
- this.slideMode_;
- this.modeButton_.title =
- this.displayStringFunction_(oppositeMode.getTitle());
- }
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/photo/gallery_item.js b/chromium/chrome/browser/resources/file_manager/foreground/js/photo/gallery_item.js
deleted file mode 100644
index 2ae80c92dd7..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/photo/gallery_item.js
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Object representing an image item (a photo or a video).
- *
- * @param {FileEntry} entry Image entry.
- * @constructor
- */
-Gallery.Item = function(entry) {
- this.entry_ = entry;
- this.original_ = true;
-};
-
-/**
- * @return {FileEntry} Image entry.
- */
-Gallery.Item.prototype.getEntry = function() { return this.entry_ };
-
-/**
- * @return {string} File name.
- */
-Gallery.Item.prototype.getFileName = function() {
- return this.entry_.name;
-};
-
-/**
- * @return {boolean} True if this image has not been created in this session.
- */
-Gallery.Item.prototype.isOriginal = function() { return this.original_ };
-
-// TODO: Localize?
-/**
- * @type {string} Suffix for a edited copy file name.
- */
-Gallery.Item.COPY_SIGNATURE = ' - Edited';
-
-/**
- * Regular expression to match '... - Edited'.
- * @type {RegExp}
- */
-Gallery.Item.REGEXP_COPY_0 =
- new RegExp('^(.+)' + Gallery.Item.COPY_SIGNATURE + '$');
-
-/**
- * Regular expression to match '... - Edited (N)'.
- * @type {RegExp}
- */
-Gallery.Item.REGEXP_COPY_N =
- new RegExp('^(.+)' + Gallery.Item.COPY_SIGNATURE + ' \\((\\d+)\\)$');
-
-/**
- * Creates a name for an edited copy of the file.
- *
- * @param {Entry} dirEntry Entry.
- * @param {function} callback Callback.
- * @private
- */
-Gallery.Item.prototype.createCopyName_ = function(dirEntry, callback) {
- var name = this.getFileName();
-
- // If the item represents a file created during the current Gallery session
- // we reuse it for subsequent saves instead of creating multiple copies.
- if (!this.original_) {
- callback(name);
- return;
- }
-
- var ext = '';
- var index = name.lastIndexOf('.');
- if (index != -1) {
- ext = name.substr(index);
- name = name.substr(0, index);
- }
-
- if (!ext.match(/jpe?g/i)) {
- // Chrome can natively encode only two formats: JPEG and PNG.
- // All non-JPEG images are saved in PNG, hence forcing the file extension.
- ext = '.png';
- }
-
- function tryNext(tries) {
- // All the names are used. Let's overwrite the last one.
- if (tries == 0) {
- setTimeout(callback, 0, name + ext);
- return;
- }
-
- // If the file name contains the copy signature add/advance the sequential
- // number.
- var matchN = Gallery.Item.REGEXP_COPY_N.exec(name);
- var match0 = Gallery.Item.REGEXP_COPY_0.exec(name);
- if (matchN && matchN[1] && matchN[2]) {
- var copyNumber = parseInt(matchN[2], 10) + 1;
- name = matchN[1] + Gallery.Item.COPY_SIGNATURE + ' (' + copyNumber + ')';
- } else if (match0 && match0[1]) {
- name = match0[1] + Gallery.Item.COPY_SIGNATURE + ' (1)';
- } else {
- name += Gallery.Item.COPY_SIGNATURE;
- }
-
- dirEntry.getFile(name + ext, {create: false, exclusive: false},
- tryNext.bind(null, tries - 1),
- callback.bind(null, name + ext));
- }
-
- tryNext(10);
-};
-
-/**
- * Writes the new item content to the file.
- *
- * @param {Entry} overrideDir Directory to save to. If null, save to the same
- * directory as the original.
- * @param {boolean} overwrite True if overwrite, false if copy.
- * @param {HTMLCanvasElement} canvas Source canvas.
- * @param {ImageEncoder.MetadataEncoder} metadataEncoder MetadataEncoder.
- * @param {function(boolean)=} opt_callback Callback accepting true for success.
- */
-Gallery.Item.prototype.saveToFile = function(
- overrideDir, overwrite, canvas, metadataEncoder, opt_callback) {
- ImageUtil.metrics.startInterval(ImageUtil.getMetricName('SaveTime'));
-
- var name = this.getFileName();
-
- var onSuccess = function(entry) {
- ImageUtil.metrics.recordEnum(ImageUtil.getMetricName('SaveResult'), 1, 2);
- ImageUtil.metrics.recordInterval(ImageUtil.getMetricName('SaveTime'));
- this.entry_ = entry;
- if (opt_callback) opt_callback(true);
- }.bind(this);
-
- function onError(error) {
- console.error('Error saving from gallery', name, error);
- ImageUtil.metrics.recordEnum(ImageUtil.getMetricName('SaveResult'), 0, 2);
- if (opt_callback) opt_callback(false);
- }
-
- function doSave(newFile, fileEntry) {
- fileEntry.createWriter(function(fileWriter) {
- function writeContent() {
- fileWriter.onwriteend = onSuccess.bind(null, fileEntry);
- fileWriter.write(ImageEncoder.getBlob(canvas, metadataEncoder));
- }
- fileWriter.onerror = function(error) {
- onError(error);
- // Disable all callbacks on the first error.
- fileWriter.onerror = null;
- fileWriter.onwriteend = null;
- };
- if (newFile) {
- writeContent();
- } else {
- fileWriter.onwriteend = writeContent;
- fileWriter.truncate(0);
- }
- }, onError);
- }
-
- function getFile(dir, newFile) {
- dir.getFile(name, {create: newFile, exclusive: newFile},
- doSave.bind(null, newFile), onError);
- }
-
- function checkExistence(dir) {
- dir.getFile(name, {create: false, exclusive: false},
- getFile.bind(null, dir, false /* existing file */),
- getFile.bind(null, dir, true /* create new file */));
- }
-
- var saveToDir = function(dir) {
- if (overwrite) {
- checkExistence(dir);
- } else {
- this.createCopyName_(dir, function(copyName) {
- this.original_ = false;
- name = copyName;
- checkExistence(dir);
- }.bind(this));
- }
- }.bind(this);
-
- if (overrideDir) {
- saveToDir(overrideDir);
- } else {
- this.entry_.getParent(saveToDir, onError);
- }
-};
-
-/**
- * Renames the file.
- *
- * @param {string} displayName New display name (without the extension).
- * @param {function()} onSuccess Success callback.
- * @param {function()} onExists Called if the file with the new name exists.
- */
-Gallery.Item.prototype.rename = function(displayName, onSuccess, onExists) {
- var fileName = this.entry_.name.replace(
- ImageUtil.getDisplayNameFromName(this.entry_.name), displayName);
-
- if (name === this.entry_.name)
- return;
-
- var onRenamed = function(entry) {
- this.entry_ = entry;
- onSuccess();
- }.bind(this);
-
- var onError = function() {
- console.error('Rename error: "' + oldName + '" to "' + newName + '"');
- };
-
- var moveIfDoesNotExist = function(parentDir) {
- parentDir.getFile(
- fileName,
- {create: false, exclusive: false},
- onExists,
- function() {
- this.entry_.moveTo(parentDir, fileName, onRenamed, onError);
- }.bind(this));
- }.bind(this);
-
- this.entry_.getParent(moveIfDoesNotExist, onError);
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/photo/gallery_scripts.js b/chromium/chrome/browser/resources/file_manager/foreground/js/photo/gallery_scripts.js
deleted file mode 100644
index 336fa207938..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/photo/gallery_scripts.js
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// The include directives are put into Javascript-style comments to prevent
-// parsing errors in non-flattened mode. The flattener still sees them.
-// Note that this makes the flattener to comment out the first line of the
-// included file but that's all right since any javascript file should start
-// with a copyright comment anyway.
-
-//<include src="../metrics.js">
-
-//<include src="../../../../image_loader/image_loader_client.js"/>
-
-//<include src="../../../../../../../ui/webui/resources/js/cr.js">
-//<include src="../../../../../../../ui/webui/resources/js/event_tracker.js">
-//<include src="../../../../../../../ui/webui/resources/js/load_time_data.js">
-
-//<include src="../../../../../../../ui/webui/resources/js/cr/ui.js">
-//<include src="../../../../../../../ui/webui/resources/js/cr/event_target.js">
-//<include src="../../../../../../../ui/webui/resources/js/cr/ui/touch_handler.js">
-//<include src="../../../../../../../ui/webui/resources/js/cr/ui/array_data_model.js">
-//<include src="../../../../../../../ui/webui/resources/js/cr/ui/dialogs.js">
-//<include src="../../../../../../../ui/webui/resources/js/cr/ui/list_item.js">
-//<include src="../../../../../../../ui/webui/resources/js/cr/ui/list_selection_model.js">
-//<include src="../../../../../../../ui/webui/resources/js/cr/ui/list_single_selection_model.js">
-//<include src="../../../../../../../ui/webui/resources/js/cr/ui/list_selection_controller.js">
-//<include src="../../../../../../../ui/webui/resources/js/cr/ui/list.js">
-//<include src="../../../../../../../ui/webui/resources/js/cr/ui/grid.js">
-
-(function() {
-// 'strict mode' is invoked for this scope.
-
-//<include src="../../../common/js/async_util.js">
-//<include src="../../../common/js/util.js">
-//<include src="../../../common/js/path_util.js">
-//<include src="../file_type.js">
-//<include src="../volume_manager_wrapper.js">
-
-//<include src="../image_editor/image_util.js"/>
-//<include src="../image_editor/viewport.js"/>
-//<include src="../image_editor/image_buffer.js"/>
-//<include src="../image_editor/image_view.js"/>
-//<include src="../image_editor/commands.js"/>
-//<include src="../image_editor/image_editor.js"/>
-//<include src="../image_editor/image_transform.js"/>
-//<include src="../image_editor/image_adjust.js"/>
-//<include src="../image_editor/filter.js"/>
-//<include src="../image_editor/image_encoder.js"/>
-//<include src="../image_editor/exif_encoder.js"/>
-
-//<include src="../media/media_controls.js"/>
-//<include src="../media/media_util.js"/>
-//<include src="../media/util.js"/>
-
-//<include src="../metadata/metadata_cache.js"/>
-
-//<include src="gallery.js">
-//<include src="gallery_item.js">
-//<include src="mosaic_mode.js">
-//<include src="slide_mode.js">
-//<include src="ribbon.js">
-
-// Exports
-window.ImageUtil = ImageUtil;
-window.Gallery = Gallery;
-window.beforeunload = beforeunload;
-window.unload = unload;
-
-})();
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/photo/mosaic_mode.js b/chromium/chrome/browser/resources/file_manager/foreground/js/photo/mosaic_mode.js
deleted file mode 100644
index 6231864bbd8..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/photo/mosaic_mode.js
+++ /dev/null
@@ -1,2012 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * @param {Element} container Content container.
- * @param {cr.ui.ArrayDataModel} dataModel Data model.
- * @param {cr.ui.ListSelectionModel} selectionModel Selection model.
- * @param {MetadataCache} metadataCache Metadata cache.
- * @param {function} toggleMode Function to switch to the Slide mode.
- * @constructor
- */
-function MosaicMode(
- container, dataModel, selectionModel, metadataCache, toggleMode) {
- this.mosaic_ = new Mosaic(
- container.ownerDocument, dataModel, selectionModel, metadataCache);
- container.appendChild(this.mosaic_);
-
- this.toggleMode_ = toggleMode;
- this.mosaic_.addEventListener('dblclick', this.toggleMode_);
- this.showingTimeoutID_ = null;
-}
-
-/**
- * @return {Mosaic} The mosaic control.
- */
-MosaicMode.prototype.getMosaic = function() { return this.mosaic_ };
-
-/**
- * @return {string} Mode name.
- */
-MosaicMode.prototype.getName = function() { return 'mosaic' };
-
-/**
- * @return {string} Mode title.
- */
-MosaicMode.prototype.getTitle = function() { return 'GALLERY_MOSAIC' };
-
-/**
- * Execute an action (this mode has no busy state).
- * @param {function} action Action to execute.
- */
-MosaicMode.prototype.executeWhenReady = function(action) { action() };
-
-/**
- * @return {boolean} Always true (no toolbar fading in this mode).
- */
-MosaicMode.prototype.hasActiveTool = function() { return true };
-
-/**
- * Keydown handler.
- *
- * @param {Event} event Event.
- * @return {boolean} True if processed.
- */
-MosaicMode.prototype.onKeyDown = function(event) {
- switch (util.getKeyModifiers(event) + event.keyIdentifier) {
- case 'Enter':
- this.toggleMode_();
- return true;
- }
- return this.mosaic_.onKeyDown(event);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-/**
- * Mosaic control.
- *
- * @param {Document} document Document.
- * @param {cr.ui.ArrayDataModel} dataModel Data model.
- * @param {cr.ui.ListSelectionModel} selectionModel Selection model.
- * @param {MetadataCache} metadataCache Metadata cache.
- * @return {Element} Mosaic element.
- * @constructor
- */
-function Mosaic(document, dataModel, selectionModel, metadataCache) {
- var self = document.createElement('div');
- Mosaic.decorate(self, dataModel, selectionModel, metadataCache);
- return self;
-}
-
-/**
- * Inherit from HTMLDivElement.
- */
-Mosaic.prototype.__proto__ = HTMLDivElement.prototype;
-
-/**
- * Default layout delay in ms.
- * @const
- * @type {number}
- */
-Mosaic.LAYOUT_DELAY = 200;
-
-/**
- * Smooth scroll animation duration when scrolling using keyboard or
- * clicking on a partly visible tile. In ms.
- * @const
- * @type {number}
- */
-Mosaic.ANIMATED_SCROLL_DURATION = 500;
-
-/**
- * Decorate a Mosaic instance.
- *
- * @param {Mosaic} self Self pointer.
- * @param {cr.ui.ArrayDataModel} dataModel Data model.
- * @param {cr.ui.ListSelectionModel} selectionModel Selection model.
- * @param {MetadataCache} metadataCache Metadata cache.
- */
-Mosaic.decorate = function(self, dataModel, selectionModel, metadataCache) {
- self.__proto__ = Mosaic.prototype;
- self.className = 'mosaic';
-
- self.dataModel_ = dataModel;
- self.selectionModel_ = selectionModel;
- self.metadataCache_ = metadataCache;
-
- // Initialization is completed lazily on the first call to |init|.
-};
-
-/**
- * Initialize the mosaic element.
- */
-Mosaic.prototype.init = function() {
- if (this.tiles_)
- return; // Already initialized, nothing to do.
-
- this.layoutModel_ = new Mosaic.Layout();
- this.onResize_();
-
- this.selectionController_ =
- new Mosaic.SelectionController(this.selectionModel_, this.layoutModel_);
-
- this.tiles_ = [];
- for (var i = 0; i != this.dataModel_.length; i++)
- this.tiles_.push(new Mosaic.Tile(this, this.dataModel_.item(i)));
-
- this.selectionModel_.selectedIndexes.forEach(function(index) {
- this.tiles_[index].select(true);
- }.bind(this));
-
- this.initTiles_(this.tiles_);
-
- // The listeners might be called while some tiles are still loading.
- this.initListeners_();
-};
-
-/**
- * @return {boolean} Whether mosaic is initialized.
- */
-Mosaic.prototype.isInitialized = function() {
- return !!this.tiles_;
-};
-
-/**
- * Start listening to events.
- *
- * We keep listening to events even when the mosaic is hidden in order to
- * keep the layout up to date.
- *
- * @private
- */
-Mosaic.prototype.initListeners_ = function() {
- this.ownerDocument.defaultView.addEventListener(
- 'resize', this.onResize_.bind(this));
-
- var mouseEventBound = this.onMouseEvent_.bind(this);
- this.addEventListener('mousemove', mouseEventBound);
- this.addEventListener('mousedown', mouseEventBound);
- this.addEventListener('mouseup', mouseEventBound);
- this.addEventListener('scroll', this.onScroll_.bind(this));
-
- this.selectionModel_.addEventListener('change', this.onSelection_.bind(this));
- this.selectionModel_.addEventListener('leadIndexChange',
- this.onLeadChange_.bind(this));
-
- this.dataModel_.addEventListener('splice', this.onSplice_.bind(this));
- this.dataModel_.addEventListener('content', this.onContentChange_.bind(this));
-};
-
-/**
- * Smoothly scrolls the container to the specified position using
- * f(x) = sqrt(x) speed function normalized to animation duration.
- * @param {number} targetPosition Horizontal scroll position in pixels.
- */
-Mosaic.prototype.animatedScrollTo = function(targetPosition) {
- if (this.scrollAnimation_) {
- webkitCancelAnimationFrame(this.scrollAnimation_);
- this.scrollAnimation_ = null;
- }
-
- // Mouse move events are fired without touching the mouse because of scrolling
- // the container. Therefore, these events have to be suppressed.
- this.suppressHovering_ = true;
-
- // Calculates integral area from t1 to t2 of f(x) = sqrt(x) dx.
- var integral = function(t1, t2) {
- return 2.0 / 3.0 * Math.pow(t2, 3.0 / 2.0) -
- 2.0 / 3.0 * Math.pow(t1, 3.0 / 2.0);
- };
-
- var delta = targetPosition - this.scrollLeft;
- var factor = delta / integral(0, Mosaic.ANIMATED_SCROLL_DURATION);
- var startTime = Date.now();
- var lastPosition = 0;
- var scrollOffset = this.scrollLeft;
-
- var animationFrame = function() {
- var position = Date.now() - startTime;
- var step = factor *
- integral(Math.max(0, Mosaic.ANIMATED_SCROLL_DURATION - position),
- Math.max(0, Mosaic.ANIMATED_SCROLL_DURATION - lastPosition));
- scrollOffset += step;
-
- var oldScrollLeft = this.scrollLeft;
- var newScrollLeft = Math.round(scrollOffset);
-
- if (oldScrollLeft != newScrollLeft)
- this.scrollLeft = newScrollLeft;
-
- if (step == 0 || this.scrollLeft != newScrollLeft) {
- this.scrollAnimation_ = null;
- // Release the hovering lock after a safe delay to avoid hovering
- // a tile because of altering |this.scrollLeft|.
- setTimeout(function() {
- if (!this.scrollAnimation_)
- this.suppressHovering_ = false;
- }.bind(this), 100);
- } else {
- // Continue the animation.
- this.scrollAnimation_ = requestAnimationFrame(animationFrame);
- }
-
- lastPosition = position;
- }.bind(this);
-
- // Start the animation.
- this.scrollAnimation_ = requestAnimationFrame(animationFrame);
-};
-
-/**
- * @return {Mosaic.Tile} Selected tile or undefined if no selection.
- */
-Mosaic.prototype.getSelectedTile = function() {
- return this.tiles_ && this.tiles_[this.selectionModel_.selectedIndex];
-};
-
-/**
- * @param {number} index Tile index.
- * @return {Rect} Tile's image rectangle.
- */
-Mosaic.prototype.getTileRect = function(index) {
- var tile = this.tiles_[index];
- return tile && tile.getImageRect();
-};
-
-/**
- * @param {number} index Tile index.
- * Scroll the given tile into the viewport.
- */
-Mosaic.prototype.scrollIntoView = function(index) {
- var tile = this.tiles_[index];
- if (tile) tile.scrollIntoView();
-};
-
-/**
- * Initializes multiple tiles.
- *
- * @param {Array.<Mosaic.Tile>} tiles Array of tiles.
- * @param {function()=} opt_callback Completion callback.
- * @private
- */
-Mosaic.prototype.initTiles_ = function(tiles, opt_callback) {
- // We do not want to use tile indices in asynchronous operations because they
- // do not survive data model splices. Copy tile references instead.
- tiles = tiles.slice();
-
- // Throttle the metadata access so that we do not overwhelm the file system.
- var MAX_CHUNK_SIZE = 10;
-
- var loadChunk = function() {
- if (!tiles.length) {
- if (opt_callback) opt_callback();
- return;
- }
- var chunkSize = Math.min(tiles.length, MAX_CHUNK_SIZE);
- var loaded = 0;
- for (var i = 0; i != chunkSize; i++) {
- this.initTile_(tiles.shift(), function() {
- if (++loaded == chunkSize) {
- this.layout();
- loadChunk();
- }
- }.bind(this));
- }
- }.bind(this);
-
- loadChunk();
-};
-
-/**
- * Initializes a single tile.
- *
- * @param {Mosaic.Tile} tile Tile.
- * @param {function()} callback Completion callback.
- * @private
- */
-Mosaic.prototype.initTile_ = function(tile, callback) {
- var onImageMeasured = callback;
- this.metadataCache_.get(tile.getItem().getEntry(), Gallery.METADATA_TYPE,
- function(metadata) {
- tile.init(metadata, onImageMeasured);
- });
-};
-
-/**
- * Reload all tiles.
- */
-Mosaic.prototype.reload = function() {
- this.layoutModel_.reset_();
- this.tiles_.forEach(function(t) { t.markUnloaded() });
- this.initTiles_(this.tiles_);
-};
-
-/**
- * Layout the tiles in the order of their indices.
- *
- * Starts where it last stopped (at #0 the first time).
- * Stops when all tiles are processed or when the next tile is still loading.
- */
-Mosaic.prototype.layout = function() {
- if (this.layoutTimer_) {
- clearTimeout(this.layoutTimer_);
- this.layoutTimer_ = null;
- }
- while (true) {
- var index = this.layoutModel_.getTileCount();
- if (index == this.tiles_.length)
- break; // All tiles done.
- var tile = this.tiles_[index];
- if (!tile.isInitialized())
- break; // Next layout will try to restart from here.
- this.layoutModel_.add(tile, index + 1 == this.tiles_.length);
- }
- this.loadVisibleTiles_();
-};
-
-/**
- * Schedule the layout.
- *
- * @param {number=} opt_delay Delay in ms.
- */
-Mosaic.prototype.scheduleLayout = function(opt_delay) {
- if (!this.layoutTimer_) {
- this.layoutTimer_ = setTimeout(function() {
- this.layoutTimer_ = null;
- this.layout();
- }.bind(this), opt_delay || 0);
- }
-};
-
-/**
- * Resize handler.
- *
- * @private
- */
-Mosaic.prototype.onResize_ = function() {
- this.layoutModel_.setViewportSize(this.clientWidth, this.clientHeight -
- (Mosaic.Layout.PADDING_TOP + Mosaic.Layout.PADDING_BOTTOM));
- this.scheduleLayout();
-};
-
-/**
- * Mouse event handler.
- *
- * @param {Event} event Event.
- * @private
- */
-Mosaic.prototype.onMouseEvent_ = function(event) {
- // Navigating with mouse, enable hover state.
- if (!this.suppressHovering_)
- this.classList.add('hover-visible');
-
- if (event.type == 'mousemove')
- return;
-
- var index = -1;
- for (var target = event.target;
- target && (target != this);
- target = target.parentNode) {
- if (target.classList.contains('mosaic-tile')) {
- index = this.dataModel_.indexOf(target.getItem());
- break;
- }
- }
- this.selectionController_.handlePointerDownUp(event, index);
-};
-
-/**
- * Scroll handler.
- * @private
- */
-Mosaic.prototype.onScroll_ = function() {
- requestAnimationFrame(function() {
- this.loadVisibleTiles_();
- }.bind(this));
-};
-
-/**
- * Selection change handler.
- *
- * @param {Event} event Event.
- * @private
- */
-Mosaic.prototype.onSelection_ = function(event) {
- for (var i = 0; i != event.changes.length; i++) {
- var change = event.changes[i];
- var tile = this.tiles_[change.index];
- if (tile) tile.select(change.selected);
- }
-};
-
-/**
- * Lead item change handler.
- *
- * @param {Event} event Event.
- * @private
- */
-Mosaic.prototype.onLeadChange_ = function(event) {
- var index = event.newValue;
- if (index >= 0) {
- var tile = this.tiles_[index];
- if (tile) tile.scrollIntoView();
- }
-};
-
-/**
- * Splice event handler.
- *
- * @param {Event} event Event.
- * @private
- */
-Mosaic.prototype.onSplice_ = function(event) {
- var index = event.index;
- this.layoutModel_.invalidateFromTile_(index);
-
- if (event.removed.length) {
- for (var t = 0; t != event.removed.length; t++)
- this.removeChild(this.tiles_[index + t]);
-
- this.tiles_.splice(index, event.removed.length);
- this.scheduleLayout(Mosaic.LAYOUT_DELAY);
- }
-
- if (event.added.length) {
- var newTiles = [];
- for (var t = 0; t != event.added.length; t++)
- newTiles.push(new Mosaic.Tile(this, this.dataModel_.item(index + t)));
-
- this.tiles_.splice.apply(this.tiles_, [index, 0].concat(newTiles));
- this.initTiles_(newTiles);
- }
-
- if (this.tiles_.length != this.dataModel_.length)
- console.error('Mosaic is out of sync');
-};
-
-/**
- * Content change handler.
- *
- * @param {Event} event Event.
- * @private
- */
-Mosaic.prototype.onContentChange_ = function(event) {
- if (!this.tiles_)
- return;
-
- if (!event.metadata)
- return; // Thumbnail unchanged, nothing to do.
-
- var index = this.dataModel_.indexOf(event.item);
- if (index != this.selectionModel_.selectedIndex)
- console.error('Content changed for unselected item');
-
- this.layoutModel_.invalidateFromTile_(index);
- this.tiles_[index].init(event.metadata, function() {
- this.tiles_[index].unload();
- this.tiles_[index].load(
- Mosaic.Tile.LoadMode.HIGH_DPI,
- this.scheduleLayout.bind(this, Mosaic.LAYOUT_DELAY));
- }.bind(this));
-};
-
-/**
- * Keydown event handler.
- *
- * @param {Event} event Event.
- * @return {boolean} True if the event has been consumed.
- */
-Mosaic.prototype.onKeyDown = function(event) {
- this.selectionController_.handleKeyDown(event);
- if (event.defaultPrevented) // Navigating with keyboard, hide hover state.
- this.classList.remove('hover-visible');
- return event.defaultPrevented;
-};
-
-/**
- * @return {boolean} True if the mosaic zoom effect can be applied. It is
- * too slow if there are to many images.
- * TODO(kaznacheev): Consider unloading the images that are out of the viewport.
- */
-Mosaic.prototype.canZoom = function() {
- return this.tiles_.length < 100;
-};
-
-/**
- * Show the mosaic.
- */
-Mosaic.prototype.show = function() {
- var duration = ImageView.MODE_TRANSITION_DURATION;
- if (this.canZoom()) {
- // Fade in in parallel with the zoom effect.
- this.setAttribute('visible', 'zooming');
- } else {
- // Mosaic is not animating but the large image is. Fade in the mosaic
- // shortly before the large image animation is done.
- duration -= 100;
- }
- this.showingTimeoutID_ = setTimeout(function() {
- this.showingTimeoutID_ = null;
- // Make the selection visible.
- // If the mosaic is not animated it will start fading in now.
- this.setAttribute('visible', 'normal');
- this.loadVisibleTiles_();
- }.bind(this), duration);
-};
-
-/**
- * Hide the mosaic.
- */
-Mosaic.prototype.hide = function() {
- if (this.showingTimeoutID_ != null) {
- clearTimeout(this.showingTimeoutID_);
- this.showingTimeoutID_ = null;
- }
- this.removeAttribute('visible');
-};
-
-/**
- * Checks if the mosaic view is visible.
- * @return {boolean} True if visible, false otherwise.
- * @private
- */
-Mosaic.prototype.isVisible_ = function() {
- return this.hasAttribute('visible');
-};
-
-/**
- * Loads visible tiles. Ignores consecutive calls. Does not reload already
- * loaded images.
- * @private
- */
-Mosaic.prototype.loadVisibleTiles_ = function() {
- if (this.loadVisibleTilesSuppressed_) {
- this.loadVisibleTilesScheduled_ = true;
- return;
- }
-
- this.loadVisibleTilesSuppressed_ = true;
- this.loadVisibleTilesScheduled_ = false;
- setTimeout(function() {
- this.loadVisibleTilesSuppressed_ = false;
- if (this.loadVisibleTilesScheduled_)
- this.loadVisibleTiles_();
- }.bind(this), 100);
-
- // Tiles only in the viewport (visible).
- var visibleRect = new Rect(0,
- 0,
- this.clientWidth,
- this.clientHeight);
-
- // Tiles in the viewport and also some distance on the left and right.
- var renderableRect = new Rect(-this.clientWidth,
- 0,
- 3 * this.clientWidth,
- this.clientHeight);
-
- // Unload tiles out of scope.
- for (var index = 0; index < this.tiles_.length; index++) {
- var tile = this.tiles_[index];
- var imageRect = tile.getImageRect();
- // Unload a thumbnail.
- if (imageRect && !imageRect.intersects(renderableRect))
- tile.unload();
- }
-
- // Load the visible tiles first.
- var allVisibleLoaded = true;
- // Show high-dpi only when the mosaic view is visible.
- var loadMode = this.isVisible_() ? Mosaic.Tile.LoadMode.HIGH_DPI :
- Mosaic.Tile.LoadMode.LOW_DPI;
- for (var index = 0; index < this.tiles_.length; index++) {
- var tile = this.tiles_[index];
- var imageRect = tile.getImageRect();
- // Load a thumbnail.
- if (!tile.isLoading(loadMode) && !tile.isLoaded(loadMode) && imageRect &&
- imageRect.intersects(visibleRect)) {
- tile.load(loadMode, function() {});
- allVisibleLoaded = false;
- }
- }
-
- // Load also another, nearby, if the visible has been already loaded.
- if (allVisibleLoaded) {
- for (var index = 0; index < this.tiles_.length; index++) {
- var tile = this.tiles_[index];
- var imageRect = tile.getImageRect();
- // Load a thumbnail.
- if (!tile.isLoading() && !tile.isLoaded() && imageRect &&
- imageRect.intersects(renderableRect)) {
- tile.load(Mosaic.Tile.LoadMode.LOW_DPI, function() {});
- }
- }
- }
-};
-
-/**
- * Apply or reset the zoom transform.
- *
- * @param {Rect} tileRect Tile rectangle. Reset the transform if null.
- * @param {Rect} imageRect Large image rectangle. Reset the transform if null.
- * @param {boolean=} opt_instant True of the transition should be instant.
- */
-Mosaic.prototype.transform = function(tileRect, imageRect, opt_instant) {
- if (opt_instant) {
- this.style.webkitTransitionDuration = '0';
- } else {
- this.style.webkitTransitionDuration =
- ImageView.MODE_TRANSITION_DURATION + 'ms';
- }
-
- if (this.canZoom() && tileRect && imageRect) {
- var scaleX = imageRect.width / tileRect.width;
- var scaleY = imageRect.height / tileRect.height;
- var shiftX = (imageRect.left + imageRect.width / 2) -
- (tileRect.left + tileRect.width / 2);
- var shiftY = (imageRect.top + imageRect.height / 2) -
- (tileRect.top + tileRect.height / 2);
- this.style.webkitTransform =
- 'translate(' + shiftX * scaleX + 'px, ' + shiftY * scaleY + 'px)' +
- 'scaleX(' + scaleX + ') scaleY(' + scaleY + ')';
- } else {
- this.style.webkitTransform = '';
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-/**
- * Creates a selection controller that is to be used with grid.
- * @param {cr.ui.ListSelectionModel} selectionModel The selection model to
- * interact with.
- * @param {Mosaic.Layout} layoutModel The layout model to use.
- * @constructor
- * @extends {!cr.ui.ListSelectionController}
- */
-Mosaic.SelectionController = function(selectionModel, layoutModel) {
- cr.ui.ListSelectionController.call(this, selectionModel);
- this.layoutModel_ = layoutModel;
-};
-
-/**
- * Extends cr.ui.ListSelectionController.
- */
-Mosaic.SelectionController.prototype.__proto__ =
- cr.ui.ListSelectionController.prototype;
-
-/** @override */
-Mosaic.SelectionController.prototype.getLastIndex = function() {
- return this.layoutModel_.getLaidOutTileCount() - 1;
-};
-
-/** @override */
-Mosaic.SelectionController.prototype.getIndexBefore = function(index) {
- return this.layoutModel_.getHorizontalAdjacentIndex(index, -1);
-};
-
-/** @override */
-Mosaic.SelectionController.prototype.getIndexAfter = function(index) {
- return this.layoutModel_.getHorizontalAdjacentIndex(index, 1);
-};
-
-/** @override */
-Mosaic.SelectionController.prototype.getIndexAbove = function(index) {
- return this.layoutModel_.getVerticalAdjacentIndex(index, -1);
-};
-
-/** @override */
-Mosaic.SelectionController.prototype.getIndexBelow = function(index) {
- return this.layoutModel_.getVerticalAdjacentIndex(index, 1);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-/**
- * Mosaic layout.
- *
- * @param {string=} opt_mode Layout mode.
- * @param {Mosaic.Density=} opt_maxDensity Layout density.
- * @constructor
- */
-Mosaic.Layout = function(opt_mode, opt_maxDensity) {
- this.mode_ = opt_mode || Mosaic.Layout.MODE_TENTATIVE;
- this.maxDensity_ = opt_maxDensity || Mosaic.Density.createHighest();
- this.reset_();
-};
-
-/**
- * Blank space at the top of the mosaic element. We do not do that in CSS
- * to make transition effects easier.
- */
-Mosaic.Layout.PADDING_TOP = 50;
-
-/**
- * Blank space at the bottom of the mosaic element.
- */
-Mosaic.Layout.PADDING_BOTTOM = 50;
-
-/**
- * Horizontal and vertical spacing between images. Should be kept in sync
- * with the style of .mosaic-item in gallery.css (= 2 * ( 4 + 1))
- */
-Mosaic.Layout.SPACING = 10;
-
-/**
- * Margin for scrolling using keyboard. Distance between a selected tile
- * and window border.
- */
-Mosaic.Layout.SCROLL_MARGIN = 30;
-
-/**
- * Layout mode: commit to DOM immediately.
- */
-Mosaic.Layout.MODE_FINAL = 'final';
-
-/**
- * Layout mode: do not commit layout to DOM until it is complete or the viewport
- * overflows.
- */
-Mosaic.Layout.MODE_TENTATIVE = 'tentative';
-
-/**
- * Layout mode: never commit layout to DOM.
- */
-Mosaic.Layout.MODE_DRY_RUN = 'dry_run';
-
-/**
- * Reset the layout.
- *
- * @private
- */
-Mosaic.Layout.prototype.reset_ = function() {
- this.columns_ = [];
- this.newColumn_ = null;
- this.density_ = Mosaic.Density.createLowest();
- if (this.mode_ != Mosaic.Layout.MODE_DRY_RUN) // DRY_RUN is sticky.
- this.mode_ = Mosaic.Layout.MODE_TENTATIVE;
-};
-
-/**
- * @param {number} width Viewport width.
- * @param {number} height Viewport height.
- */
-Mosaic.Layout.prototype.setViewportSize = function(width, height) {
- this.viewportWidth_ = width;
- this.viewportHeight_ = height;
- this.reset_();
-};
-
-/**
- * @return {number} Total width of the layout.
- */
-Mosaic.Layout.prototype.getWidth = function() {
- var lastColumn = this.getLastColumn_();
- return lastColumn ? lastColumn.getRight() : 0;
-};
-
-/**
- * @return {number} Total height of the layout.
- */
-Mosaic.Layout.prototype.getHeight = function() {
- var firstColumn = this.columns_[0];
- return firstColumn ? firstColumn.getHeight() : 0;
-};
-
-/**
- * @return {Array.<Mosaic.Tile>} All tiles in the layout.
- */
-Mosaic.Layout.prototype.getTiles = function() {
- return Array.prototype.concat.apply([],
- this.columns_.map(function(c) { return c.getTiles() }));
-};
-
-/**
- * @return {number} Total number of tiles added to the layout.
- */
-Mosaic.Layout.prototype.getTileCount = function() {
- return this.getLaidOutTileCount() +
- (this.newColumn_ ? this.newColumn_.getTileCount() : 0);
-};
-
-/**
- * @return {Mosaic.Column} The last column or null for empty layout.
- * @private
- */
-Mosaic.Layout.prototype.getLastColumn_ = function() {
- return this.columns_.length ? this.columns_[this.columns_.length - 1] : null;
-};
-
-/**
- * @return {number} Total number of tiles in completed columns.
- */
-Mosaic.Layout.prototype.getLaidOutTileCount = function() {
- var lastColumn = this.getLastColumn_();
- return lastColumn ? lastColumn.getNextTileIndex() : 0;
-};
-
-/**
- * Add a tile to the layout.
- *
- * @param {Mosaic.Tile} tile The tile to be added.
- * @param {boolean} isLast True if this tile is the last.
- */
-Mosaic.Layout.prototype.add = function(tile, isLast) {
- var layoutQueue = [tile];
-
- // There are two levels of backtracking in the layout algorithm.
- // |Mosaic.Layout.density_| tracks the state of the 'global' backtracking
- // which aims to use as much of the viewport space as possible.
- // It starts with the lowest density and increases it until the layout
- // fits into the viewport. If it does not fit even at the highest density,
- // the layout continues with the highest density.
- //
- // |Mosaic.Column.density_| tracks the state of the 'local' backtracking
- // which aims to avoid producing unnaturally looking columns.
- // It starts with the current global density and decreases it until the column
- // looks nice.
-
- while (layoutQueue.length) {
- if (!this.newColumn_) {
- var lastColumn = this.getLastColumn_();
- this.newColumn_ = new Mosaic.Column(
- this.columns_.length,
- lastColumn ? lastColumn.getNextRowIndex() : 0,
- lastColumn ? lastColumn.getNextTileIndex() : 0,
- lastColumn ? lastColumn.getRight() : 0,
- this.viewportHeight_,
- this.density_.clone());
- }
-
- this.newColumn_.add(layoutQueue.shift());
-
- var isFinalColumn = isLast && !layoutQueue.length;
-
- if (!this.newColumn_.prepareLayout(isFinalColumn))
- continue; // Column is incomplete.
-
- if (this.newColumn_.isSuboptimal()) {
- layoutQueue = this.newColumn_.getTiles().concat(layoutQueue);
- this.newColumn_.retryWithLowerDensity();
- continue;
- }
-
- this.columns_.push(this.newColumn_);
- this.newColumn_ = null;
-
- if (this.mode_ == Mosaic.Layout.MODE_FINAL) {
- this.getLastColumn_().layout();
- continue;
- }
-
- if (this.getWidth() > this.viewportWidth_) {
- // Viewport completely filled.
- if (this.density_.equals(this.maxDensity_)) {
- // Max density reached, commit if tentative, just continue if dry run.
- if (this.mode_ == Mosaic.Layout.MODE_TENTATIVE)
- this.commit_();
- continue;
- }
-
- // Rollback the entire layout, retry with higher density.
- layoutQueue = this.getTiles().concat(layoutQueue);
- this.columns_ = [];
- this.density_.increase();
- continue;
- }
-
- if (isFinalColumn && this.mode_ == Mosaic.Layout.MODE_TENTATIVE) {
- // The complete tentative layout fits into the viewport.
- var stretched = this.findHorizontalLayout_();
- if (stretched)
- this.columns_ = stretched.columns_;
- // Center the layout in the viewport and commit.
- this.commit_((this.viewportWidth_ - this.getWidth()) / 2,
- (this.viewportHeight_ - this.getHeight()) / 2);
- }
- }
-};
-
-/**
- * Commit the tentative layout.
- *
- * @param {number=} opt_offsetX Horizontal offset.
- * @param {number=} opt_offsetY Vertical offset.
- * @private
- */
-Mosaic.Layout.prototype.commit_ = function(opt_offsetX, opt_offsetY) {
- console.assert(this.mode_ != Mosaic.Layout.MODE_FINAL,
- 'Did not expect final layout');
- for (var i = 0; i != this.columns_.length; i++) {
- this.columns_[i].layout(opt_offsetX, opt_offsetY);
- }
- this.mode_ = Mosaic.Layout.MODE_FINAL;
-};
-
-/**
- * Find the most horizontally stretched layout built from the same tiles.
- *
- * The main layout algorithm fills the entire available viewport height.
- * If there is too few tiles this results in a layout that is unnaturally
- * stretched in the vertical direction.
- *
- * This method tries a number of smaller heights and returns the most
- * horizontally stretched layout that still fits into the viewport.
- *
- * @return {Mosaic.Layout} A horizontally stretched layout.
- * @private
- */
-Mosaic.Layout.prototype.findHorizontalLayout_ = function() {
- // If the layout aspect ratio is not dramatically different from
- // the viewport aspect ratio then there is no need to optimize.
- if (this.getWidth() / this.getHeight() >
- this.viewportWidth_ / this.viewportHeight_ * 0.9)
- return null;
-
- var tiles = this.getTiles();
- if (tiles.length == 1)
- return null; // Single tile layout is always the same.
-
- var tileHeights = tiles.map(function(t) { return t.getMaxContentHeight() });
- var minTileHeight = Math.min.apply(null, tileHeights);
-
- for (var h = minTileHeight; h < this.viewportHeight_; h += minTileHeight) {
- var layout = new Mosaic.Layout(
- Mosaic.Layout.MODE_DRY_RUN, this.density_.clone());
- layout.setViewportSize(this.viewportWidth_, h);
- for (var t = 0; t != tiles.length; t++)
- layout.add(tiles[t], t + 1 == tiles.length);
-
- if (layout.getWidth() <= this.viewportWidth_)
- return layout;
- }
-
- return null;
-};
-
-/**
- * Invalidate the layout after the given tile was modified (added, deleted or
- * changed dimensions).
- *
- * @param {number} index Tile index.
- * @private
- */
-Mosaic.Layout.prototype.invalidateFromTile_ = function(index) {
- var columnIndex = this.getColumnIndexByTile_(index);
- if (columnIndex < 0)
- return; // Index not in the layout, probably already invalidated.
-
- if (this.columns_[columnIndex].getLeft() >= this.viewportWidth_) {
- // The columns to the right cover the entire viewport width, so there is no
- // chance that the modified layout would fit into the viewport.
- // No point in restarting the entire layout, keep the columns to the right.
- console.assert(this.mode_ == Mosaic.Layout.MODE_FINAL,
- 'Expected FINAL layout mode');
- this.columns_ = this.columns_.slice(0, columnIndex);
- this.newColumn_ = null;
- } else {
- // There is a chance that the modified layout would fit into the viewport.
- this.reset_();
- this.mode_ = Mosaic.Layout.MODE_TENTATIVE;
- }
-};
-
-/**
- * Get the index of the tile to the left or to the right from the given tile.
- *
- * @param {number} index Tile index.
- * @param {number} direction -1 for left, 1 for right.
- * @return {number} Adjacent tile index.
- */
-Mosaic.Layout.prototype.getHorizontalAdjacentIndex = function(
- index, direction) {
- var column = this.getColumnIndexByTile_(index);
- if (column < 0) {
- console.error('Cannot find column for tile #' + index);
- return -1;
- }
-
- var row = this.columns_[column].getRowByTileIndex(index);
- if (!row) {
- console.error('Cannot find row for tile #' + index);
- return -1;
- }
-
- var sameRowNeighbourIndex = index + direction;
- if (row.hasTile(sameRowNeighbourIndex))
- return sameRowNeighbourIndex;
-
- var adjacentColumn = column + direction;
- if (adjacentColumn < 0 || adjacentColumn == this.columns_.length)
- return -1;
-
- return this.columns_[adjacentColumn].
- getEdgeTileIndex_(row.getCenterY(), -direction);
-};
-
-/**
- * Get the index of the tile to the top or to the bottom from the given tile.
- *
- * @param {number} index Tile index.
- * @param {number} direction -1 for above, 1 for below.
- * @return {number} Adjacent tile index.
- */
-Mosaic.Layout.prototype.getVerticalAdjacentIndex = function(
- index, direction) {
- var column = this.getColumnIndexByTile_(index);
- if (column < 0) {
- console.error('Cannot find column for tile #' + index);
- return -1;
- }
-
- var row = this.columns_[column].getRowByTileIndex(index);
- if (!row) {
- console.error('Cannot find row for tile #' + index);
- return -1;
- }
-
- // Find the first item in the next row, or the last item in the previous row.
- var adjacentRowNeighbourIndex =
- row.getEdgeTileIndex_(direction) + direction;
-
- if (adjacentRowNeighbourIndex < 0 ||
- adjacentRowNeighbourIndex > this.getTileCount() - 1)
- return -1;
-
- if (!this.columns_[column].hasTile(adjacentRowNeighbourIndex)) {
- // It is not in the current column, so return it.
- return adjacentRowNeighbourIndex;
- } else {
- // It is in the current column, so we have to find optically the closest
- // tile in the adjacent row.
- var adjacentRow = this.columns_[column].getRowByTileIndex(
- adjacentRowNeighbourIndex);
- var previousTileCenterX = row.getTileByIndex(index).getCenterX();
-
- // Find the closest one.
- var closestIndex = -1;
- var closestDistance;
- var adjacentRowTiles = adjacentRow.getTiles();
- for (var t = 0; t != adjacentRowTiles.length; t++) {
- var distance =
- Math.abs(adjacentRowTiles[t].getCenterX() - previousTileCenterX);
- if (closestIndex == -1 || distance < closestDistance) {
- closestIndex = adjacentRow.getEdgeTileIndex_(-1) + t;
- closestDistance = distance;
- }
- }
- return closestIndex;
- }
-};
-
-/**
- * @param {number} index Tile index.
- * @return {number} Index of the column containing the given tile.
- * @private
- */
-Mosaic.Layout.prototype.getColumnIndexByTile_ = function(index) {
- for (var c = 0; c != this.columns_.length; c++) {
- if (this.columns_[c].hasTile(index))
- return c;
- }
- return -1;
-};
-
-/**
- * Scale the given array of size values to satisfy 3 conditions:
- * 1. The new sizes must be integer.
- * 2. The new sizes must sum up to the given |total| value.
- * 3. The relative proportions of the sizes should be as close to the original
- * as possible.
- *
- * @param {Array.<number>} sizes Array of sizes.
- * @param {number} newTotal New total size.
- */
-Mosaic.Layout.rescaleSizesToNewTotal = function(sizes, newTotal) {
- var total = 0;
-
- var partialTotals = [0];
- for (var i = 0; i != sizes.length; i++) {
- total += sizes[i];
- partialTotals.push(total);
- }
-
- var scale = newTotal / total;
-
- for (i = 0; i != sizes.length; i++) {
- sizes[i] = Math.round(partialTotals[i + 1] * scale) -
- Math.round(partialTotals[i] * scale);
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-/**
- * Representation of the layout density.
- *
- * @param {number} horizontal Horizontal density, number tiles per row.
- * @param {number} vertical Vertical density, frequency of rows forced to
- * contain a single tile.
- * @constructor
- */
-Mosaic.Density = function(horizontal, vertical) {
- this.horizontal = horizontal;
- this.vertical = vertical;
-};
-
-/**
- * Minimal horizontal density (tiles per row).
- */
-Mosaic.Density.MIN_HORIZONTAL = 1;
-
-/**
- * Minimal horizontal density (tiles per row).
- */
-Mosaic.Density.MAX_HORIZONTAL = 3;
-
-/**
- * Minimal vertical density: force 1 out of 2 rows to containt a single tile.
- */
-Mosaic.Density.MIN_VERTICAL = 2;
-
-/**
- * Maximal vertical density: force 1 out of 3 rows to containt a single tile.
- */
-Mosaic.Density.MAX_VERTICAL = 3;
-
-/**
- * @return {Mosaic.Density} Lowest density.
- */
-Mosaic.Density.createLowest = function() {
- return new Mosaic.Density(
- Mosaic.Density.MIN_HORIZONTAL,
- Mosaic.Density.MIN_VERTICAL /* ignored when horizontal is at min */);
-};
-
-/**
- * @return {Mosaic.Density} Highest density.
- */
-Mosaic.Density.createHighest = function() {
- return new Mosaic.Density(
- Mosaic.Density.MAX_HORIZONTAL,
- Mosaic.Density.MAX_VERTICAL);
-};
-
-/**
- * @return {Mosaic.Density} A clone of this density object.
- */
-Mosaic.Density.prototype.clone = function() {
- return new Mosaic.Density(this.horizontal, this.vertical);
-};
-
-/**
- * @param {Mosaic.Density} that The other object.
- * @return {boolean} True if equal.
- */
-Mosaic.Density.prototype.equals = function(that) {
- return this.horizontal == that.horizontal &&
- this.vertical == that.vertical;
-};
-
-/**
- * Increase the density to the next level.
- */
-Mosaic.Density.prototype.increase = function() {
- if (this.horizontal == Mosaic.Density.MIN_HORIZONTAL ||
- this.vertical == Mosaic.Density.MAX_VERTICAL) {
- console.assert(this.horizontal < Mosaic.Density.MAX_HORIZONTAL);
- this.horizontal++;
- this.vertical = Mosaic.Density.MIN_VERTICAL;
- } else {
- this.vertical++;
- }
-};
-
-/**
- * Decrease horizontal density.
- */
-Mosaic.Density.prototype.decreaseHorizontal = function() {
- console.assert(this.horizontal > Mosaic.Density.MIN_HORIZONTAL);
- this.horizontal--;
-};
-
-/**
- * @param {number} tileCount Number of tiles in the row.
- * @param {number} rowIndex Global row index.
- * @return {boolean} True if the row is complete.
- */
-Mosaic.Density.prototype.isRowComplete = function(tileCount, rowIndex) {
- return (tileCount == this.horizontal) || (rowIndex % this.vertical) == 0;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-/**
- * A column in a mosaic layout. Contains rows.
- *
- * @param {number} index Column index.
- * @param {number} firstRowIndex Global row index.
- * @param {number} firstTileIndex Index of the first tile in the column.
- * @param {number} left Left edge coordinate.
- * @param {number} maxHeight Maximum height.
- * @param {Mosaic.Density} density Layout density.
- * @constructor
- */
-Mosaic.Column = function(index, firstRowIndex, firstTileIndex, left, maxHeight,
- density) {
- this.index_ = index;
- this.firstRowIndex_ = firstRowIndex;
- this.firstTileIndex_ = firstTileIndex;
- this.left_ = left;
- this.maxHeight_ = maxHeight;
- this.density_ = density;
-
- this.reset_();
-};
-
-/**
- * Reset the layout.
- * @private
- */
-Mosaic.Column.prototype.reset_ = function() {
- this.tiles_ = [];
- this.rows_ = [];
- this.newRow_ = null;
-};
-
-/**
- * @return {number} Number of tiles in the column.
- */
-Mosaic.Column.prototype.getTileCount = function() { return this.tiles_.length };
-
-/**
- * @return {number} Index of the last tile + 1.
- */
-Mosaic.Column.prototype.getNextTileIndex = function() {
- return this.firstTileIndex_ + this.getTileCount();
-};
-
-/**
- * @return {number} Global index of the last row + 1.
- */
-Mosaic.Column.prototype.getNextRowIndex = function() {
- return this.firstRowIndex_ + this.rows_.length;
-};
-
-/**
- * @return {Array.<Mosaic.Tile>} Array of tiles in the column.
- */
-Mosaic.Column.prototype.getTiles = function() { return this.tiles_ };
-
-/**
- * @param {number} index Tile index.
- * @return {boolean} True if this column contains the tile with the given index.
- */
-Mosaic.Column.prototype.hasTile = function(index) {
- return this.firstTileIndex_ <= index &&
- index < (this.firstTileIndex_ + this.getTileCount());
-};
-
-/**
- * @param {number} y Y coordinate.
- * @param {number} direction -1 for left, 1 for right.
- * @return {number} Index of the tile lying on the edge of the column at the
- * given y coordinate.
- * @private
- */
-Mosaic.Column.prototype.getEdgeTileIndex_ = function(y, direction) {
- for (var r = 0; r < this.rows_.length; r++) {
- if (this.rows_[r].coversY(y))
- return this.rows_[r].getEdgeTileIndex_(direction);
- }
- return -1;
-};
-
-/**
- * @param {number} index Tile index.
- * @return {Mosaic.Row} The row containing the tile with a given index.
- */
-Mosaic.Column.prototype.getRowByTileIndex = function(index) {
- for (var r = 0; r != this.rows_.length; r++)
- if (this.rows_[r].hasTile(index))
- return this.rows_[r];
-
- return null;
-};
-
-/**
- * Add a tile to the column.
- *
- * @param {Mosaic.Tile} tile The tile to add.
- */
-Mosaic.Column.prototype.add = function(tile) {
- var rowIndex = this.getNextRowIndex();
-
- if (!this.newRow_)
- this.newRow_ = new Mosaic.Row(this.getNextTileIndex());
-
- this.tiles_.push(tile);
- this.newRow_.add(tile);
-
- if (this.density_.isRowComplete(this.newRow_.getTileCount(), rowIndex)) {
- this.rows_.push(this.newRow_);
- this.newRow_ = null;
- }
-};
-
-/**
- * Prepare the column layout.
- *
- * @param {boolean=} opt_force True if the layout must be performed even for an
- * incomplete column.
- * @return {boolean} True if the layout was performed.
- */
-Mosaic.Column.prototype.prepareLayout = function(opt_force) {
- if (opt_force && this.newRow_) {
- this.rows_.push(this.newRow_);
- this.newRow_ = null;
- }
-
- if (this.rows_.length == 0)
- return false;
-
- this.width_ = Math.min.apply(
- null, this.rows_.map(function(row) { return row.getMaxWidth() }));
-
- this.height_ = 0;
-
- this.rowHeights_ = [];
- for (var r = 0; r != this.rows_.length; r++) {
- var rowHeight = this.rows_[r].getHeightForWidth(this.width_);
- this.height_ += rowHeight;
- this.rowHeights_.push(rowHeight);
- }
-
- var overflow = this.height_ / this.maxHeight_;
- if (!opt_force && (overflow < 1))
- return false;
-
- if (overflow > 1) {
- // Scale down the column width and height.
- this.width_ = Math.round(this.width_ / overflow);
- this.height_ = this.maxHeight_;
- Mosaic.Layout.rescaleSizesToNewTotal(this.rowHeights_, this.maxHeight_);
- }
-
- return true;
-};
-
-/**
- * Retry the column layout with less tiles per row.
- */
-Mosaic.Column.prototype.retryWithLowerDensity = function() {
- this.density_.decreaseHorizontal();
- this.reset_();
-};
-
-/**
- * @return {number} Column left edge coordinate.
- */
-Mosaic.Column.prototype.getLeft = function() { return this.left_ };
-
-/**
- * @return {number} Column right edge coordinate after the layout.
- */
-Mosaic.Column.prototype.getRight = function() {
- return this.left_ + this.width_;
-};
-
-/**
- * @return {number} Column height after the layout.
- */
-Mosaic.Column.prototype.getHeight = function() { return this.height_ };
-
-/**
- * Perform the column layout.
- * @param {number=} opt_offsetX Horizontal offset.
- * @param {number=} opt_offsetY Vertical offset.
- */
-Mosaic.Column.prototype.layout = function(opt_offsetX, opt_offsetY) {
- opt_offsetX = opt_offsetX || 0;
- opt_offsetY = opt_offsetY || 0;
- var rowTop = Mosaic.Layout.PADDING_TOP;
- for (var r = 0; r != this.rows_.length; r++) {
- this.rows_[r].layout(
- opt_offsetX + this.left_,
- opt_offsetY + rowTop,
- this.width_,
- this.rowHeights_[r]);
- rowTop += this.rowHeights_[r];
- }
-};
-
-/**
- * Check if the column layout is too ugly to be displayed.
- *
- * @return {boolean} True if the layout is suboptimal.
- */
-Mosaic.Column.prototype.isSuboptimal = function() {
- var tileCounts =
- this.rows_.map(function(row) { return row.getTileCount() });
-
- var maxTileCount = Math.max.apply(null, tileCounts);
- if (maxTileCount == 1)
- return false; // Every row has exactly 1 tile, as optimal as it gets.
-
- var sizes =
- this.tiles_.map(function(tile) { return tile.getMaxContentHeight() });
-
- // Ugly layout #1: all images are small and some are one the same row.
- var allSmall = Math.max.apply(null, sizes) <= Mosaic.Tile.SMALL_IMAGE_SIZE;
- if (allSmall)
- return true;
-
- // Ugly layout #2: all images are large and none occupies an entire row.
- var allLarge = Math.min.apply(null, sizes) > Mosaic.Tile.SMALL_IMAGE_SIZE;
- var allCombined = Math.min.apply(null, tileCounts) != 1;
- if (allLarge && allCombined)
- return true;
-
- // Ugly layout #3: some rows have too many tiles for the resulting width.
- if (this.width_ / maxTileCount < 100)
- return true;
-
- return false;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-/**
- * A row in a mosaic layout. Contains tiles.
- *
- * @param {number} firstTileIndex Index of the first tile in the row.
- * @constructor
- */
-Mosaic.Row = function(firstTileIndex) {
- this.firstTileIndex_ = firstTileIndex;
- this.tiles_ = [];
-};
-
-/**
- * @param {Mosaic.Tile} tile The tile to add.
- */
-Mosaic.Row.prototype.add = function(tile) {
- console.assert(this.getTileCount() < Mosaic.Density.MAX_HORIZONTAL);
- this.tiles_.push(tile);
-};
-
-/**
- * @return {Array.<Mosaic.Tile>} Array of tiles in the row.
- */
-Mosaic.Row.prototype.getTiles = function() { return this.tiles_ };
-
-/**
- * Get a tile by index.
- * @param {number} index Tile index.
- * @return {Mosaic.Tile} Requested tile or null if not found.
- */
-Mosaic.Row.prototype.getTileByIndex = function(index) {
- if (!this.hasTile(index))
- return null;
- return this.tiles_[index - this.firstTileIndex_];
-};
-
-/**
- *
- * @return {number} Number of tiles in the row.
- */
-Mosaic.Row.prototype.getTileCount = function() { return this.tiles_.length };
-
-/**
- * @param {number} index Tile index.
- * @return {boolean} True if this row contains the tile with the given index.
- */
-Mosaic.Row.prototype.hasTile = function(index) {
- return this.firstTileIndex_ <= index &&
- index < (this.firstTileIndex_ + this.tiles_.length);
-};
-
-/**
- * @param {number} y Y coordinate.
- * @return {boolean} True if this row covers the given Y coordinate.
- */
-Mosaic.Row.prototype.coversY = function(y) {
- return this.top_ <= y && y < (this.top_ + this.height_);
-};
-
-/**
- * @return {number} Y coordinate of the tile center.
- */
-Mosaic.Row.prototype.getCenterY = function() {
- return this.top_ + Math.round(this.height_ / 2);
-};
-
-/**
- * Get the first or the last tile.
- *
- * @param {number} direction -1 for the first tile, 1 for the last tile.
- * @return {number} Tile index.
- * @private
- */
-Mosaic.Row.prototype.getEdgeTileIndex_ = function(direction) {
- if (direction < 0)
- return this.firstTileIndex_;
- else
- return this.firstTileIndex_ + this.getTileCount() - 1;
-};
-
-/**
- * @return {number} Aspect ration of the combined content box of this row.
- * @private
- */
-Mosaic.Row.prototype.getTotalContentAspectRatio_ = function() {
- var sum = 0;
- for (var t = 0; t != this.tiles_.length; t++)
- sum += this.tiles_[t].getAspectRatio();
- return sum;
-};
-
-/**
- * @return {number} Total horizontal spacing in this row. This includes
- * the spacing between the tiles and both left and right margins.
- *
- * @private
- */
-Mosaic.Row.prototype.getTotalHorizontalSpacing_ = function() {
- return Mosaic.Layout.SPACING * this.getTileCount();
-};
-
-/**
- * @return {number} Maximum width that this row may have without overscaling
- * any of the tiles.
- */
-Mosaic.Row.prototype.getMaxWidth = function() {
- var contentHeight = Math.min.apply(null,
- this.tiles_.map(function(tile) { return tile.getMaxContentHeight() }));
-
- var contentWidth =
- Math.round(contentHeight * this.getTotalContentAspectRatio_());
- return contentWidth + this.getTotalHorizontalSpacing_();
-};
-
-/**
- * Compute the height that best fits the supplied row width given
- * aspect ratios of the tiles in this row.
- *
- * @param {number} width Row width.
- * @return {number} Height.
- */
-Mosaic.Row.prototype.getHeightForWidth = function(width) {
- var contentWidth = width - this.getTotalHorizontalSpacing_();
- var contentHeight =
- Math.round(contentWidth / this.getTotalContentAspectRatio_());
- return contentHeight + Mosaic.Layout.SPACING;
-};
-
-/**
- * Position the row in the mosaic.
- *
- * @param {number} left Left position.
- * @param {number} top Top position.
- * @param {number} width Width.
- * @param {number} height Height.
- */
-Mosaic.Row.prototype.layout = function(left, top, width, height) {
- this.top_ = top;
- this.height_ = height;
-
- var contentWidth = width - this.getTotalHorizontalSpacing_();
- var contentHeight = height - Mosaic.Layout.SPACING;
-
- var tileContentWidth = this.tiles_.map(
- function(tile) { return tile.getAspectRatio() });
-
- Mosaic.Layout.rescaleSizesToNewTotal(tileContentWidth, contentWidth);
-
- var tileLeft = left;
- for (var t = 0; t != this.tiles_.length; t++) {
- var tileWidth = tileContentWidth[t] + Mosaic.Layout.SPACING;
- this.tiles_[t].layout(tileLeft, top, tileWidth, height);
- tileLeft += tileWidth;
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-/**
- * A single tile of the image mosaic.
- *
- * @param {Element} container Container element.
- * @param {Gallery.Item} item Gallery item associated with this tile.
- * @return {Element} The new tile element.
- * @constructor
- */
-Mosaic.Tile = function(container, item) {
- var self = container.ownerDocument.createElement('div');
- Mosaic.Tile.decorate(self, container, item);
- return self;
-};
-
-/**
- * @param {Element} self Self pointer.
- * @param {Element} container Container element.
- * @param {Gallery.Item} item Gallery item associated with this tile.
- */
-Mosaic.Tile.decorate = function(self, container, item) {
- self.__proto__ = Mosaic.Tile.prototype;
- self.className = 'mosaic-tile';
-
- self.container_ = container;
- self.item_ = item;
- self.left_ = null; // Mark as not laid out.
-};
-
-/**
- * Load mode for the tile's image.
- * @enum {number}
- */
-Mosaic.Tile.LoadMode = {
- LOW_DPI: 0,
- HIGH_DPI: 1
-};
-
-/**
-* Inherit from HTMLDivElement.
-*/
-Mosaic.Tile.prototype.__proto__ = HTMLDivElement.prototype;
-
-/**
- * Minimum tile content size.
- */
-Mosaic.Tile.MIN_CONTENT_SIZE = 64;
-
-/**
- * Maximum tile content size.
- */
-Mosaic.Tile.MAX_CONTENT_SIZE = 512;
-
-/**
- * Default size for a tile with no thumbnail image.
- */
-Mosaic.Tile.GENERIC_ICON_SIZE = 128;
-
-/**
- * Max size of an image considered to be 'small'.
- * Small images are laid out slightly differently.
- */
-Mosaic.Tile.SMALL_IMAGE_SIZE = 160;
-
-/**
- * @return {Gallery.Item} The Gallery item.
- */
-Mosaic.Tile.prototype.getItem = function() { return this.item_ };
-
-/**
- * @return {number} Maximum content height that this tile can have.
- */
-Mosaic.Tile.prototype.getMaxContentHeight = function() {
- return this.maxContentHeight_;
-};
-
-/**
- * @return {number} The aspect ratio of the tile image.
- */
-Mosaic.Tile.prototype.getAspectRatio = function() { return this.aspectRatio_ };
-
-/**
- * @return {boolean} True if the tile is initialized.
- */
-Mosaic.Tile.prototype.isInitialized = function() {
- return !!this.maxContentHeight_;
-};
-
-/**
- * Checks whether the image of specified (or better resolution) has been loaded.
- *
- * @param {Mosaic.Tile.LoadMode=} opt_loadMode Loading mode, default: LOW_DPI.
- * @return {boolean} True if the tile is loaded with the specified dpi or
- * better.
- */
-Mosaic.Tile.prototype.isLoaded = function(opt_loadMode) {
- var loadMode = opt_loadMode || Mosaic.Tile.LoadMode.LOW_DPI;
- switch (loadMode) {
- case Mosaic.Tile.LoadMode.LOW_DPI:
- if (this.imagePreloaded_ || this.imageLoaded_)
- return true;
- break;
- case Mosaic.Tile.LoadMode.HIGH_DPI:
- if (this.imageLoaded_)
- return true;
- break;
- }
- return false;
-};
-
-/**
- * Checks whether the image of specified (or better resolution) is being loaded.
- *
- * @param {Mosaic.Tile.LoadMode=} opt_loadMode Loading mode, default: LOW_DPI.
- * @return {boolean} True if the tile is being loaded with the specified dpi or
- * better.
- */
-Mosaic.Tile.prototype.isLoading = function(opt_loadMode) {
- var loadMode = opt_loadMode || Mosaic.Tile.LoadMode.LOW_DPI;
- switch (loadMode) {
- case Mosaic.Tile.LoadMode.LOW_DPI:
- if (this.imagePreloading_ || this.imageLoading_)
- return true;
- break;
- case Mosaic.Tile.LoadMode.HIGH_DPI:
- if (this.imageLoading_)
- return true;
- break;
- }
- return false;
-};
-
-/**
- * Mark the tile as not loaded to prevent it from participating in the layout.
- */
-Mosaic.Tile.prototype.markUnloaded = function() {
- this.maxContentHeight_ = 0;
- if (this.thumbnailLoader_) {
- this.thumbnailLoader_.cancel();
- this.imagePreloaded_ = false;
- this.imagePreloading_ = false;
- this.imageLoaded_ = false;
- this.imageLoading_ = false;
- }
-};
-
-/**
- * Initializes the thumbnail in the tile. Does not load an image, but sets
- * target dimensions using metadata.
- *
- * @param {Object} metadata Metadata object.
- * @param {function()} onImageMeasured Image measured callback.
- */
-Mosaic.Tile.prototype.init = function(metadata, onImageMeasured) {
- this.markUnloaded();
- this.left_ = null; // Mark as not laid out.
-
- // Set higher priority for the selected elements to load them first.
- var priority = this.getAttribute('selected') ? 2 : 3;
-
- // Use embedded thumbnails on Drive, since they have higher resolution.
- var hidpiEmbedded = FileType.isOnDrive(this.getItem().getEntry());
- this.thumbnailLoader_ = new ThumbnailLoader(
- this.getItem().getEntry().toURL(),
- ThumbnailLoader.LoaderType.CANVAS,
- metadata,
- undefined, // Media type.
- hidpiEmbedded ? ThumbnailLoader.UseEmbedded.USE_EMBEDDED :
- ThumbnailLoader.UseEmbedded.NO_EMBEDDED,
- priority);
-
- // If no hidpi embedded thumbnail available, then use the low resolution
- // for preloading.
- if (!hidpiEmbedded) {
- this.thumbnailPreloader_ = new ThumbnailLoader(
- this.getItem().getEntry().toURL(),
- ThumbnailLoader.LoaderType.CANVAS,
- metadata,
- undefined, // Media type.
- ThumbnailLoader.UseEmbedded.USE_EMBEDDED,
- 2); // Preloaders have always higher priotity, so the preload images
- // are loaded as soon as possible.
- }
-
- var setDimensions = function(width, height) {
- if (width > height) {
- if (width > Mosaic.Tile.MAX_CONTENT_SIZE) {
- height = Math.round(height * Mosaic.Tile.MAX_CONTENT_SIZE / width);
- width = Mosaic.Tile.MAX_CONTENT_SIZE;
- }
- } else {
- if (height > Mosaic.Tile.MAX_CONTENT_SIZE) {
- width = Math.round(width * Mosaic.Tile.MAX_CONTENT_SIZE / height);
- height = Mosaic.Tile.MAX_CONTENT_SIZE;
- }
- }
- this.maxContentHeight_ = Math.max(Mosaic.Tile.MIN_CONTENT_SIZE, height);
- this.aspectRatio_ = width / height;
- onImageMeasured();
- }.bind(this);
-
- // Dimensions are always acquired from the metadata. For local files, it is
- // extracted from headers. For Drive files, it is received via the Drive API.
- // If the dimensions are not available, then the fallback dimensions will be
- // used (same as for the generic icon).
- if (metadata.media && metadata.media.width) {
- setDimensions(metadata.media.width, metadata.media.height);
- } else if (metadata.drive && metadata.drive.imageWidth &&
- metadata.drive.imageHeight) {
- setDimensions(metadata.drive.imageWidth, metadata.drive.imageHeight);
- } else {
- // No dimensions in metadata, then use the generic dimensions.
- setDimensions(Mosaic.Tile.GENERIC_ICON_SIZE,
- Mosaic.Tile.GENERIC_ICON_SIZE);
- }
-};
-
-/**
- * Loads an image into the tile.
- *
- * The mode argument is a hint. Use low-dpi for faster response, and high-dpi
- * for better output, but possibly affecting performance.
- *
- * If the mode is high-dpi, then a the high-dpi image is loaded, but also
- * low-dpi image is loaded for preloading (if available).
- * For the low-dpi mode, only low-dpi image is loaded. If not available, then
- * the high-dpi image is loaded as a fallback.
- *
- * @param {Mosaic.Tile.LoadMode} loadMode Loading mode.
- * @param {function(boolean)} onImageLoaded Callback when image is loaded.
- * The argument is true for success, false for failure.
- */
-Mosaic.Tile.prototype.load = function(loadMode, onImageLoaded) {
- // Attaches the image to the tile and finalizes loading process for the
- // specified loader.
- var finalizeLoader = function(mode, success, loader) {
- if (success && this.wrapper_) {
- // Show the fade-in animation only when previously there was no image
- // attached in this tile.
- if (!this.imageLoaded_ && !this.imagePreloaded_)
- this.wrapper_.classList.add('animated');
- else
- this.wrapper_.classList.remove('animated');
- }
- loader.attachImage(this.wrapper_, ThumbnailLoader.FillMode.OVER_FILL);
- onImageLoaded(success);
- switch (mode) {
- case Mosaic.Tile.LoadMode.LOW_DPI:
- this.imagePreloading_ = false;
- this.imagePreloaded_ = true;
- break;
- case Mosaic.Tile.LoadMode.HIGH_DPI:
- this.imageLoading_ = false;
- this.imageLoaded_ = true;
- break;
- }
- }.bind(this);
-
- // Always load the low-dpi image first if it is available for the fastest
- // feedback.
- if (!this.imagePreloading_ && this.thumbnailPreloader_) {
- this.imagePreloading_ = true;
- this.thumbnailPreloader_.loadDetachedImage(function(success) {
- // Hi-dpi loaded first, ignore this call then.
- if (this.imageLoaded_)
- return;
- finalizeLoader(Mosaic.Tile.LoadMode.LOW_DPI,
- success,
- this.thumbnailPreloader_);
- }.bind(this));
- }
-
- // Load the high-dpi image only when it is requested, or the low-dpi is not
- // available.
- if (!this.imageLoading_ &&
- (loadMode == Mosaic.Tile.LoadMode.HIGH_DPI || !this.imagePreloading_)) {
- this.imageLoading_ = true;
- this.thumbnailLoader_.loadDetachedImage(function(success) {
- // Cancel preloading, since the hi-dpi image is ready.
- if (this.thumbnailPreloader_)
- this.thumbnailPreloader_.cancel();
- finalizeLoader(Mosaic.Tile.LoadMode.HIGH_DPI,
- success,
- this.thumbnailLoader_);
- }.bind(this));
- }
-};
-
-/**
- * Unloads an image from the tile.
- */
-Mosaic.Tile.prototype.unload = function() {
- this.thumbnailLoader_.cancel();
- if (this.thumbnailPreloader_)
- this.thumbnailPreloader_.cancel();
- this.imagePreloaded_ = false;
- this.imageLoaded_ = false;
- this.imagePreloading_ = false;
- this.imageLoading_ = false;
- this.wrapper_.innerText = '';
-};
-
-/**
- * Select/unselect the tile.
- *
- * @param {boolean} on True if selected.
- */
-Mosaic.Tile.prototype.select = function(on) {
- if (on)
- this.setAttribute('selected', true);
- else
- this.removeAttribute('selected');
-};
-
-/**
- * Position the tile in the mosaic.
- *
- * @param {number} left Left position.
- * @param {number} top Top position.
- * @param {number} width Width.
- * @param {number} height Height.
- */
-Mosaic.Tile.prototype.layout = function(left, top, width, height) {
- this.left_ = left;
- this.top_ = top;
- this.width_ = width;
- this.height_ = height;
-
- this.style.left = left + 'px';
- this.style.top = top + 'px';
- this.style.width = width + 'px';
- this.style.height = height + 'px';
-
- if (!this.wrapper_) { // First time, create DOM.
- this.container_.appendChild(this);
- var border = util.createChild(this, 'img-border');
- this.wrapper_ = util.createChild(border, 'img-wrapper');
- }
- if (this.hasAttribute('selected'))
- this.scrollIntoView(false);
-
- if (this.imageLoaded_) {
- this.thumbnailLoader_.attachImage(this.wrapper_,
- ThumbnailLoader.FillMode.FILL);
- }
-};
-
-/**
- * If the tile is not fully visible scroll the parent to make it fully visible.
- * @param {boolean=} opt_animated True, if scroll should be animated,
- * default: true.
- */
-Mosaic.Tile.prototype.scrollIntoView = function(opt_animated) {
- if (this.left_ == null) // Not laid out.
- return;
-
- var targetPosition;
- var tileLeft = this.left_ - Mosaic.Layout.SCROLL_MARGIN;
- if (tileLeft < this.container_.scrollLeft) {
- targetPosition = tileLeft;
- } else {
- var tileRight = this.left_ + this.width_ + Mosaic.Layout.SCROLL_MARGIN;
- var scrollRight = this.container_.scrollLeft + this.container_.clientWidth;
- if (tileRight > scrollRight)
- targetPosition = tileRight - this.container_.clientWidth;
- }
-
- if (targetPosition) {
- if (opt_animated === false)
- this.container_.scrollLeft = targetPosition;
- else
- this.container_.animatedScrollTo(targetPosition);
- }
-};
-
-/**
- * @return {Rect} Rectangle occupied by the tile's image,
- * relative to the viewport.
- */
-Mosaic.Tile.prototype.getImageRect = function() {
- if (this.left_ == null) // Not laid out.
- return null;
-
- var margin = Mosaic.Layout.SPACING / 2;
- return new Rect(this.left_ - this.container_.scrollLeft, this.top_,
- this.width_, this.height_).inflate(-margin, -margin);
-};
-
-/**
- * @return {number} X coordinate of the tile center.
- */
-Mosaic.Tile.prototype.getCenterX = function() {
- return this.left_ + Math.round(this.width_ / 2);
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/photo/ribbon.js b/chromium/chrome/browser/resources/file_manager/foreground/js/photo/ribbon.js
deleted file mode 100644
index 4d1c81c6c3c..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/photo/ribbon.js
+++ /dev/null
@@ -1,366 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Scrollable thumbnail ribbon at the bottom of the Gallery in the Slide mode.
- *
- * @param {Document} document Document.
- * @param {MetadataCache} metadataCache MetadataCache instance.
- * @param {cr.ui.ArrayDataModel} dataModel Data model.
- * @param {cr.ui.ListSelectionModel} selectionModel Selection model.
- * @return {Element} Ribbon element.
- * @constructor
- */
-function Ribbon(document, metadataCache, dataModel, selectionModel) {
- var self = document.createElement('div');
- Ribbon.decorate(self, metadataCache, dataModel, selectionModel);
- return self;
-}
-
-/**
- * Inherit from HTMLDivElement.
- */
-Ribbon.prototype.__proto__ = HTMLDivElement.prototype;
-
-/**
- * Decorate a Ribbon instance.
- *
- * @param {Ribbon} self Self pointer.
- * @param {MetadataCache} metadataCache MetadataCache instance.
- * @param {cr.ui.ArrayDataModel} dataModel Data model.
- * @param {cr.ui.ListSelectionModel} selectionModel Selection model.
- */
-Ribbon.decorate = function(self, metadataCache, dataModel, selectionModel) {
- self.__proto__ = Ribbon.prototype;
- self.metadataCache_ = metadataCache;
- self.dataModel_ = dataModel;
- self.selectionModel_ = selectionModel;
-
- self.className = 'ribbon';
-};
-
-/**
- * Max number of thumbnails in the ribbon.
- * @type {number}
- */
-Ribbon.ITEMS_COUNT = 5;
-
-/**
- * Force redraw the ribbon.
- */
-Ribbon.prototype.redraw = function() {
- this.onSelection_();
-};
-
-/**
- * Clear all cached data to force full redraw on the next selection change.
- */
-Ribbon.prototype.reset = function() {
- this.renderCache_ = {};
- this.firstVisibleIndex_ = 0;
- this.lastVisibleIndex_ = -1; // Zero thumbnails
-};
-
-/**
- * Enable the ribbon.
- */
-Ribbon.prototype.enable = function() {
- this.onContentBound_ = this.onContentChange_.bind(this);
- this.dataModel_.addEventListener('content', this.onContentBound_);
-
- this.onSpliceBound_ = this.onSplice_.bind(this);
- this.dataModel_.addEventListener('splice', this.onSpliceBound_);
-
- this.onSelectionBound_ = this.onSelection_.bind(this);
- this.selectionModel_.addEventListener('change', this.onSelectionBound_);
-
- this.reset();
- this.redraw();
-};
-
-/**
- * Disable ribbon.
- */
-Ribbon.prototype.disable = function() {
- this.dataModel_.removeEventListener('content', this.onContentBound_);
- this.dataModel_.removeEventListener('splice', this.onSpliceBound_);
- this.selectionModel_.removeEventListener('change', this.onSelectionBound_);
-
- this.removeVanishing_();
- this.textContent = '';
-};
-
-/**
- * Data model splice handler.
- * @param {Event} event Event.
- * @private
- */
-Ribbon.prototype.onSplice_ = function(event) {
- if (event.removed.length == 0)
- return;
-
- if (event.removed.length > 1) {
- console.error('Cannot remove multiple items');
- return;
- }
-
- var removed = this.renderCache_[event.removed[0].getEntry().toURL()];
- if (!removed || !removed.parentNode || !removed.hasAttribute('selected')) {
- console.error('Can only remove the selected item');
- return;
- }
-
- var persistentNodes = this.querySelectorAll('.ribbon-image:not([vanishing])');
- if (this.lastVisibleIndex_ < this.dataModel_.length) { // Not at the end.
- var lastNode = persistentNodes[persistentNodes.length - 1];
- if (lastNode.nextSibling) {
- // Pull back a vanishing node from the right.
- lastNode.nextSibling.removeAttribute('vanishing');
- } else {
- // Push a new item at the right end.
- this.appendChild(this.renderThumbnail_(this.lastVisibleIndex_));
- }
- } else {
- // No items to the right, move the window to the left.
- this.lastVisibleIndex_--;
- if (this.firstVisibleIndex_) {
- this.firstVisibleIndex_--;
- var firstNode = persistentNodes[0];
- if (firstNode.previousSibling) {
- // Pull back a vanishing node from the left.
- firstNode.previousSibling.removeAttribute('vanishing');
- } else {
- // Push a new item at the left end.
- var newThumbnail = this.renderThumbnail_(this.firstVisibleIndex_);
- newThumbnail.style.marginLeft = -(this.clientHeight - 2) + 'px';
- this.insertBefore(newThumbnail, this.firstChild);
- setTimeout(function() {
- newThumbnail.style.marginLeft = '0';
- }, 0);
- }
- }
- }
-
- removed.removeAttribute('selected');
- removed.setAttribute('vanishing', 'smooth');
- this.scheduleRemove_();
-};
-
-/**
- * Selection change handler.
- * @private
- */
-Ribbon.prototype.onSelection_ = function() {
- var indexes = this.selectionModel_.selectedIndexes;
- if (indexes.length == 0)
- return; // Ignore temporary empty selection.
- var selectedIndex = indexes[0];
-
- var length = this.dataModel_.length;
-
- // TODO(dgozman): use margin instead of 2 here.
- var itemWidth = this.clientHeight - 2;
- var fullItems = Ribbon.ITEMS_COUNT;
- fullItems = Math.min(fullItems, length);
- var right = Math.floor((fullItems - 1) / 2);
-
- var fullWidth = fullItems * itemWidth;
- this.style.width = fullWidth + 'px';
-
- var lastIndex = selectedIndex + right;
- lastIndex = Math.max(lastIndex, fullItems - 1);
- lastIndex = Math.min(lastIndex, length - 1);
- var firstIndex = lastIndex - fullItems + 1;
-
- if (this.firstVisibleIndex_ != firstIndex ||
- this.lastVisibleIndex_ != lastIndex) {
-
- if (this.lastVisibleIndex_ == -1) {
- this.firstVisibleIndex_ = firstIndex;
- this.lastVisibleIndex_ = lastIndex;
- }
-
- this.removeVanishing_();
-
- this.textContent = '';
- var startIndex = Math.min(firstIndex, this.firstVisibleIndex_);
- // All the items except the first one treated equally.
- for (var index = startIndex + 1;
- index <= Math.max(lastIndex, this.lastVisibleIndex_);
- ++index) {
- // Only add items that are in either old or the new viewport.
- if (this.lastVisibleIndex_ < index && index < firstIndex ||
- lastIndex < index && index < this.firstVisibleIndex_)
- continue;
- var box = this.renderThumbnail_(index);
- box.style.marginLeft = '0';
- this.appendChild(box);
- if (index < firstIndex || index > lastIndex) {
- // If the node is not in the new viewport we only need it while
- // the animation is playing out.
- box.setAttribute('vanishing', 'slide');
- }
- }
-
- var slideCount = this.childNodes.length + 1 - Ribbon.ITEMS_COUNT;
- var margin = itemWidth * slideCount;
- var startBox = this.renderThumbnail_(startIndex);
- if (startIndex == firstIndex) {
- // Sliding to the right.
- startBox.style.marginLeft = -margin + 'px';
- if (this.firstChild)
- this.insertBefore(startBox, this.firstChild);
- else
- this.appendChild(startBox);
- setTimeout(function() {
- startBox.style.marginLeft = '0';
- }, 0);
- } else {
- // Sliding to the left. Start item will become invisible and should be
- // removed afterwards.
- startBox.setAttribute('vanishing', 'slide');
- startBox.style.marginLeft = '0';
- if (this.firstChild)
- this.insertBefore(startBox, this.firstChild);
- else
- this.appendChild(startBox);
- setTimeout(function() {
- startBox.style.marginLeft = -margin + 'px';
- }, 0);
- }
-
- ImageUtil.setClass(this, 'fade-left',
- firstIndex > 0 && selectedIndex != firstIndex);
-
- ImageUtil.setClass(this, 'fade-right',
- lastIndex < length - 1 && selectedIndex != lastIndex);
-
- this.firstVisibleIndex_ = firstIndex;
- this.lastVisibleIndex_ = lastIndex;
-
- this.scheduleRemove_();
- }
-
- var oldSelected = this.querySelector('[selected]');
- if (oldSelected) oldSelected.removeAttribute('selected');
-
- var newSelected =
- this.renderCache_[this.dataModel_.item(selectedIndex).getEntry().toURL()];
- if (newSelected) newSelected.setAttribute('selected', true);
-};
-
-/**
- * Schedule the removal of thumbnails marked as vanishing.
- * @private
- */
-Ribbon.prototype.scheduleRemove_ = function() {
- if (this.removeTimeout_)
- clearTimeout(this.removeTimeout_);
-
- this.removeTimeout_ = setTimeout(function() {
- this.removeTimeout_ = null;
- this.removeVanishing_();
- }.bind(this), 200);
-};
-
-/**
- * Remove all thumbnails marked as vanishing.
- * @private
- */
-Ribbon.prototype.removeVanishing_ = function() {
- if (this.removeTimeout_) {
- clearTimeout(this.removeTimeout_);
- this.removeTimeout_ = 0;
- }
- var vanishingNodes = this.querySelectorAll('[vanishing]');
- for (var i = 0; i != vanishingNodes.length; i++) {
- vanishingNodes[i].removeAttribute('vanishing');
- this.removeChild(vanishingNodes[i]);
- }
-};
-
-/**
- * Create a DOM element for a thumbnail.
- *
- * @param {number} index Item index.
- * @return {Element} Newly created element.
- * @private
- */
-Ribbon.prototype.renderThumbnail_ = function(index) {
- var item = this.dataModel_.item(index);
- var url = item.getEntry().toURL();
-
- var cached = this.renderCache_[url];
- if (cached) {
- var img = cached.querySelector('img');
- if (img)
- img.classList.add('cached');
- return cached;
- }
-
- var thumbnail = this.ownerDocument.createElement('div');
- thumbnail.className = 'ribbon-image';
- thumbnail.addEventListener('click', function() {
- var index = this.dataModel_.indexOf(item);
- this.selectionModel_.unselectAll();
- this.selectionModel_.setIndexSelected(index, true);
- }.bind(this));
-
- util.createChild(thumbnail, 'image-wrapper');
-
- this.metadataCache_.get(item.getEntry(), Gallery.METADATA_TYPE,
- this.setThumbnailImage_.bind(this, thumbnail, url));
-
- // TODO: Implement LRU eviction.
- // Never evict the thumbnails that are currently in the DOM because we rely
- // on this cache to find them by URL.
- this.renderCache_[url] = thumbnail;
- return thumbnail;
-};
-
-/**
- * Set the thumbnail image.
- *
- * @param {Element} thumbnail Thumbnail element.
- * @param {string} url Image url.
- * @param {Object} metadata Metadata.
- * @private
- */
-Ribbon.prototype.setThumbnailImage_ = function(thumbnail, url, metadata) {
- new ThumbnailLoader(url, ThumbnailLoader.LoaderType.IMAGE, metadata).load(
- thumbnail.querySelector('.image-wrapper'),
- ThumbnailLoader.FillMode.FILL /* fill */,
- ThumbnailLoader.OptimizationMode.NEVER_DISCARD);
-};
-
-/**
- * Content change handler.
- *
- * @param {Event} event Event.
- * @private
- */
-Ribbon.prototype.onContentChange_ = function(event) {
- var url = event.item.getEntry().toURL();
- this.remapCache_(event.oldUrl, url);
-
- var thumbnail = this.renderCache_[url];
- if (thumbnail && event.metadata)
- this.setThumbnailImage_(thumbnail, url, event.metadata);
-};
-
-/**
- * Update the thumbnail element cache.
- *
- * @param {string} oldUrl Old url.
- * @param {string} newUrl New url.
- * @private
- */
-Ribbon.prototype.remapCache_ = function(oldUrl, newUrl) {
- if (oldUrl != newUrl && (oldUrl in this.renderCache_)) {
- this.renderCache_[newUrl] = this.renderCache_[oldUrl];
- delete this.renderCache_[oldUrl];
- }
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/photo/slide_mode.js b/chromium/chrome/browser/resources/file_manager/foreground/js/photo/slide_mode.js
deleted file mode 100644
index d9b47395bb9..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/photo/slide_mode.js
+++ /dev/null
@@ -1,1354 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Slide mode displays a single image and has a set of controls to navigate
- * between the images and to edit an image.
- *
- * TODO(kaznacheev): Introduce a parameter object.
- *
- * @param {Element} container Main container element.
- * @param {Element} content Content container element.
- * @param {Element} toolbar Toolbar element.
- * @param {ImageEditor.Prompt} prompt Prompt.
- * @param {cr.ui.ArrayDataModel} dataModel Data model.
- * @param {cr.ui.ListSelectionModel} selectionModel Selection model.
- * @param {Object} context Context.
- * @param {function(function())} toggleMode Function to toggle the Gallery mode.
- * @param {function(string):string} displayStringFunction String formatting
- * function.
- * @constructor
- */
-function SlideMode(container, content, toolbar, prompt,
- dataModel, selectionModel, context,
- toggleMode, displayStringFunction) {
- this.container_ = container;
- this.document_ = container.ownerDocument;
- this.content = content;
- this.toolbar_ = toolbar;
- this.prompt_ = prompt;
- this.dataModel_ = dataModel;
- this.selectionModel_ = selectionModel;
- this.context_ = context;
- this.metadataCache_ = context.metadataCache;
- this.toggleMode_ = toggleMode;
- this.displayStringFunction_ = displayStringFunction;
-
- this.onSelectionBound_ = this.onSelection_.bind(this);
- this.onSpliceBound_ = this.onSplice_.bind(this);
- this.onContentBound_ = this.onContentChange_.bind(this);
-
- // Unique numeric key, incremented per each load attempt used to discard
- // old attempts. This can happen especially when changing selection fast or
- // Internet connection is slow.
- this.currentUniqueKey_ = 0;
-
- this.initListeners_();
- this.initDom_();
-}
-
-/**
- * SlideMode extends cr.EventTarget.
- */
-SlideMode.prototype.__proto__ = cr.EventTarget.prototype;
-
-/**
- * List of available editor modes.
- * @type {Array.<ImageEditor.Mode>}
- */
-SlideMode.editorModes = [
- new ImageEditor.Mode.InstantAutofix(),
- new ImageEditor.Mode.Crop(),
- new ImageEditor.Mode.Exposure(),
- new ImageEditor.Mode.OneClick(
- 'rotate_left', 'GALLERY_ROTATE_LEFT', new Command.Rotate(-1)),
- new ImageEditor.Mode.OneClick(
- 'rotate_right', 'GALLERY_ROTATE_RIGHT', new Command.Rotate(1))
-];
-
-/**
- * @return {string} Mode name.
- */
-SlideMode.prototype.getName = function() { return 'slide' };
-
-/**
- * @return {string} Mode title.
- */
-SlideMode.prototype.getTitle = function() { return 'GALLERY_SLIDE' };
-
-/**
- * Initialize the listeners.
- * @private
- */
-SlideMode.prototype.initListeners_ = function() {
- window.addEventListener('resize', this.onResize_.bind(this), false);
-};
-
-/**
- * Initialize the UI.
- * @private
- */
-SlideMode.prototype.initDom_ = function() {
- // Container for displayed image or video.
- this.imageContainer_ = util.createChild(
- this.document_.querySelector('.content'), 'image-container');
- this.imageContainer_.addEventListener('click', this.onClick_.bind(this));
-
- this.document_.addEventListener('click', this.onDocumentClick_.bind(this));
-
- // Overwrite options and info bubble.
- this.options_ = util.createChild(
- this.toolbar_.querySelector('.filename-spacer'), 'options');
-
- this.savedLabel_ = util.createChild(this.options_, 'saved');
- this.savedLabel_.textContent = this.displayStringFunction_('GALLERY_SAVED');
-
- var overwriteOriginalBox =
- util.createChild(this.options_, 'overwrite-original');
-
- this.overwriteOriginal_ = util.createChild(
- overwriteOriginalBox, 'common white', 'input');
- this.overwriteOriginal_.type = 'checkbox';
- this.overwriteOriginal_.id = 'overwrite-checkbox';
- util.platform.getPreference(SlideMode.OVERWRITE_KEY, function(value) {
- // Out-of-the box default is 'true'
- this.overwriteOriginal_.checked =
- (typeof value !== 'string' || value === 'true');
- }.bind(this));
- this.overwriteOriginal_.addEventListener('click',
- this.onOverwriteOriginalClick_.bind(this));
-
- var overwriteLabel = util.createChild(overwriteOriginalBox, '', 'label');
- overwriteLabel.textContent =
- this.displayStringFunction_('GALLERY_OVERWRITE_ORIGINAL');
- overwriteLabel.setAttribute('for', 'overwrite-checkbox');
-
- this.bubble_ = util.createChild(this.toolbar_, 'bubble');
- this.bubble_.hidden = true;
-
- var bubbleContent = util.createChild(this.bubble_);
- bubbleContent.innerHTML = this.displayStringFunction_(
- 'GALLERY_OVERWRITE_BUBBLE');
-
- util.createChild(this.bubble_, 'pointer bottom', 'span');
-
- var bubbleClose = util.createChild(this.bubble_, 'close-x');
- bubbleClose.addEventListener('click', this.onCloseBubble_.bind(this));
-
- // Video player controls.
- this.mediaSpacer_ =
- util.createChild(this.container_, 'video-controls-spacer');
- this.mediaToolbar_ = util.createChild(this.mediaSpacer_, 'tool');
- this.mediaControls_ = new VideoControls(
- this.mediaToolbar_,
- this.showErrorBanner_.bind(this, 'GALLERY_VIDEO_ERROR'),
- this.displayStringFunction_.bind(this),
- this.toggleFullScreen_.bind(this),
- this.container_);
-
- // Ribbon and related controls.
- this.arrowBox_ = util.createChild(this.container_, 'arrow-box');
-
- this.arrowLeft_ =
- util.createChild(this.arrowBox_, 'arrow left tool dimmable');
- this.arrowLeft_.addEventListener('click',
- this.advanceManually.bind(this, -1));
- util.createChild(this.arrowLeft_);
-
- util.createChild(this.arrowBox_, 'arrow-spacer');
-
- this.arrowRight_ =
- util.createChild(this.arrowBox_, 'arrow right tool dimmable');
- this.arrowRight_.addEventListener('click',
- this.advanceManually.bind(this, 1));
- util.createChild(this.arrowRight_);
-
- this.ribbonSpacer_ = util.createChild(this.toolbar_, 'ribbon-spacer');
- this.ribbon_ = new Ribbon(this.document_,
- this.metadataCache_, this.dataModel_, this.selectionModel_);
- this.ribbonSpacer_.appendChild(this.ribbon_);
-
- // Error indicator.
- var errorWrapper = util.createChild(this.container_, 'prompt-wrapper');
- errorWrapper.setAttribute('pos', 'center');
-
- this.errorBanner_ = util.createChild(errorWrapper, 'error-banner');
-
- util.createChild(this.container_, 'spinner');
-
- var slideShowButton = util.createChild(this.toolbar_,
- 'button slideshow', 'button');
- slideShowButton.title = this.displayStringFunction_('GALLERY_SLIDESHOW');
- slideShowButton.addEventListener('click',
- this.startSlideshow.bind(this, SlideMode.SLIDESHOW_INTERVAL_FIRST));
-
- var slideShowToolbar =
- util.createChild(this.container_, 'tool slideshow-toolbar');
- util.createChild(slideShowToolbar, 'slideshow-play').
- addEventListener('click', this.toggleSlideshowPause_.bind(this));
- util.createChild(slideShowToolbar, 'slideshow-end').
- addEventListener('click', this.stopSlideshow_.bind(this));
-
- // Editor.
-
- this.editButton_ = util.createChild(this.toolbar_, 'button edit', 'button');
- this.editButton_.title = this.displayStringFunction_('GALLERY_EDIT');
- this.editButton_.setAttribute('disabled', ''); // Disabled by default.
- this.editButton_.addEventListener('click', this.toggleEditor.bind(this));
-
- this.printButton_ = util.createChild(this.toolbar_, 'button print', 'button');
- this.printButton_.title = this.displayStringFunction_('GALLERY_PRINT');
- this.printButton_.setAttribute('disabled', ''); // Disabled by default.
- this.printButton_.addEventListener('click', this.print_.bind(this));
-
- this.editBarSpacer_ = util.createChild(this.toolbar_, 'edit-bar-spacer');
- this.editBarMain_ = util.createChild(this.editBarSpacer_, 'edit-main');
-
- this.editBarMode_ = util.createChild(this.container_, 'edit-modal');
- this.editBarModeWrapper_ = util.createChild(
- this.editBarMode_, 'edit-modal-wrapper');
- this.editBarModeWrapper_.hidden = true;
-
- // Objects supporting image display and editing.
- this.viewport_ = new Viewport();
-
- this.imageView_ = new ImageView(
- this.imageContainer_,
- this.viewport_,
- this.metadataCache_);
-
- this.editor_ = new ImageEditor(
- this.viewport_,
- this.imageView_,
- this.prompt_,
- {
- root: this.container_,
- image: this.imageContainer_,
- toolbar: this.editBarMain_,
- mode: this.editBarModeWrapper_
- },
- SlideMode.editorModes,
- this.displayStringFunction_,
- this.onToolsVisibilityChanged_.bind(this));
-
- this.editor_.getBuffer().addOverlay(
- new SwipeOverlay(this.advanceManually.bind(this)));
-};
-
-/**
- * Load items, display the selected item.
- * @param {Rect} zoomFromRect Rectangle for zoom effect.
- * @param {function} displayCallback Called when the image is displayed.
- * @param {function} loadCallback Called when the image is displayed.
- */
-SlideMode.prototype.enter = function(
- zoomFromRect, displayCallback, loadCallback) {
- this.sequenceDirection_ = 0;
- this.sequenceLength_ = 0;
-
- var loadDone = function(loadType, delay) {
- this.active_ = true;
-
- this.selectionModel_.addEventListener('change', this.onSelectionBound_);
- this.dataModel_.addEventListener('splice', this.onSpliceBound_);
- this.dataModel_.addEventListener('content', this.onContentBound_);
-
- ImageUtil.setAttribute(this.arrowBox_, 'active', this.getItemCount_() > 1);
- this.ribbon_.enable();
-
- // Wait 1000ms after the animation is done, then prefetch the next image.
- this.requestPrefetch(1, delay + 1000);
-
- if (loadCallback) loadCallback();
- }.bind(this);
-
- // The latest |leave| call might have left the image animating. Remove it.
- this.unloadImage_();
-
- if (this.getItemCount_() === 0) {
- this.displayedIndex_ = -1;
- //TODO(kaznacheev) Show this message in the grid mode too.
- this.showErrorBanner_('GALLERY_NO_IMAGES');
- loadDone();
- } else {
- // Remember the selection if it is empty or multiple. It will be restored
- // in |leave| if the user did not changing the selection manually.
- var currentSelection = this.selectionModel_.selectedIndexes;
- if (currentSelection.length === 1)
- this.savedSelection_ = null;
- else
- this.savedSelection_ = currentSelection;
-
- // Ensure valid single selection.
- // Note that the SlideMode object is not listening to selection change yet.
- this.select(Math.max(0, this.getSelectedIndex()));
- this.displayedIndex_ = this.getSelectedIndex();
-
- var selectedItem = this.getSelectedItem();
- // Show the selected item ASAP, then complete the initialization
- // (loading the ribbon thumbnails can take some time).
- this.metadataCache_.get(selectedItem.getEntry(), Gallery.METADATA_TYPE,
- function(metadata) {
- this.loadItem_(selectedItem.getEntry(), metadata,
- zoomFromRect && this.imageView_.createZoomEffect(zoomFromRect),
- displayCallback, loadDone);
- }.bind(this));
-
- }
-};
-
-/**
- * Leave the mode.
- * @param {Rect} zoomToRect Rectangle for zoom effect.
- * @param {function} callback Called when the image is committed and
- * the zoom-out animation has started.
- */
-SlideMode.prototype.leave = function(zoomToRect, callback) {
- var commitDone = function() {
- this.stopEditing_();
- this.stopSlideshow_();
- ImageUtil.setAttribute(this.arrowBox_, 'active', false);
- this.selectionModel_.removeEventListener(
- 'change', this.onSelectionBound_);
- this.dataModel_.removeEventListener('splice', this.onSpliceBound_);
- this.dataModel_.removeEventListener('content', this.onContentBound_);
- this.ribbon_.disable();
- this.active_ = false;
- if (this.savedSelection_)
- this.selectionModel_.selectedIndexes = this.savedSelection_;
- this.unloadImage_(zoomToRect);
- callback();
- }.bind(this);
-
- if (this.getItemCount_() === 0) {
- this.showErrorBanner_(false);
- commitDone();
- } else {
- this.commitItem_(commitDone);
- }
-
- // Disable the slide-mode only buttons when leaving.
- this.editButton_.setAttribute('disabled', '');
- this.printButton_.setAttribute('disabled', '');
-};
-
-
-/**
- * Execute an action when the editor is not busy.
- *
- * @param {function} action Function to execute.
- */
-SlideMode.prototype.executeWhenReady = function(action) {
- this.editor_.executeWhenReady(action);
-};
-
-/**
- * @return {boolean} True if the mode has active tools (that should not fade).
- */
-SlideMode.prototype.hasActiveTool = function() {
- return this.isEditing();
-};
-
-/**
- * @return {number} Item count.
- * @private
- */
-SlideMode.prototype.getItemCount_ = function() {
- return this.dataModel_.length;
-};
-
-/**
- * @param {number} index Index.
- * @return {Gallery.Item} Item.
- */
-SlideMode.prototype.getItem = function(index) {
- return this.dataModel_.item(index);
-};
-
-/**
- * @return {Gallery.Item} Selected index.
- */
-SlideMode.prototype.getSelectedIndex = function() {
- return this.selectionModel_.selectedIndex;
-};
-
-/**
- * @return {Rect} Screen rectangle of the selected image.
- */
-SlideMode.prototype.getSelectedImageRect = function() {
- if (this.getSelectedIndex() < 0)
- return null;
- else
- return this.viewport_.getScreenClipped();
-};
-
-/**
- * @return {Gallery.Item} Selected item.
- */
-SlideMode.prototype.getSelectedItem = function() {
- return this.getItem(this.getSelectedIndex());
-};
-
-/**
- * Toggles the full screen mode.
- * @private
- */
-SlideMode.prototype.toggleFullScreen_ = function() {
- util.toggleFullScreen(this.context_.appWindow,
- !util.isFullScreen(this.context_.appWindow));
-};
-
-/**
- * Selection change handler.
- *
- * Commits the current image and displays the newly selected image.
- * @private
- */
-SlideMode.prototype.onSelection_ = function() {
- if (this.selectionModel_.selectedIndexes.length === 0)
- return; // Temporary empty selection.
-
- // Forget the saved selection if the user changed the selection manually.
- if (!this.isSlideshowOn_())
- this.savedSelection_ = null;
-
- if (this.getSelectedIndex() === this.displayedIndex_)
- return; // Do not reselect.
-
- this.commitItem_(this.loadSelectedItem_.bind(this));
-};
-
-/**
- * Handles changes in tools visibility, and if the header is dimmed, then
- * requests disabling the draggable app region.
- *
- * @private
- */
-SlideMode.prototype.onToolsVisibilityChanged_ = function() {
- var headerDimmed =
- this.document_.querySelector('.header').hasAttribute('dimmed');
- this.context_.onAppRegionChanged(!headerDimmed);
-};
-
-/**
- * Change the selection.
- *
- * @param {number} index New selected index.
- * @param {number=} opt_slideHint Slide animation direction (-1|1).
- */
-SlideMode.prototype.select = function(index, opt_slideHint) {
- this.slideHint_ = opt_slideHint;
- this.selectionModel_.selectedIndex = index;
- this.selectionModel_.leadIndex = index;
-};
-
-/**
- * Load the selected item.
- *
- * @private
- */
-SlideMode.prototype.loadSelectedItem_ = function() {
- var slideHint = this.slideHint_;
- this.slideHint_ = undefined;
-
- var index = this.getSelectedIndex();
- if (index === this.displayedIndex_)
- return; // Do not reselect.
-
- var step = slideHint || (index - this.displayedIndex_);
-
- if (Math.abs(step) != 1) {
- // Long leap, the sequence is broken, we have no good prefetch candidate.
- this.sequenceDirection_ = 0;
- this.sequenceLength_ = 0;
- } else if (this.sequenceDirection_ === step) {
- // Keeping going in sequence.
- this.sequenceLength_++;
- } else {
- // Reversed the direction. Reset the counter.
- this.sequenceDirection_ = step;
- this.sequenceLength_ = 1;
- }
-
- if (this.sequenceLength_ <= 1) {
- // We have just broke the sequence. Touch the current image so that it stays
- // in the cache longer.
- this.imageView_.prefetch(this.imageView_.contentEntry_);
- }
-
- this.displayedIndex_ = index;
-
- function shouldPrefetch(loadType, step, sequenceLength) {
- // Never prefetch when selecting out of sequence.
- if (Math.abs(step) != 1)
- return false;
-
- // Never prefetch after a video load (decoding the next image can freeze
- // the UI for a second or two).
- if (loadType === ImageView.LOAD_TYPE_VIDEO_FILE)
- return false;
-
- // Always prefetch if the previous load was from cache.
- if (loadType === ImageView.LOAD_TYPE_CACHED_FULL)
- return true;
-
- // Prefetch if we have been going in the same direction for long enough.
- return sequenceLength >= 3;
- }
-
- var selectedItem = this.getSelectedItem();
- this.currentUniqueKey_++;
- var selectedUniqueKey = this.currentUniqueKey_;
- var onMetadata = function(metadata) {
- // Discard, since another load has been invoked after this one.
- if (selectedUniqueKey != this.currentUniqueKey_) return;
- this.loadItem_(selectedItem.getEntry(), metadata,
- new ImageView.Effect.Slide(step, this.isSlideshowPlaying_()),
- function() {} /* no displayCallback */,
- function(loadType, delay) {
- // Discard, since another load has been invoked after this one.
- if (selectedUniqueKey != this.currentUniqueKey_) return;
- if (shouldPrefetch(loadType, step, this.sequenceLength_)) {
- this.requestPrefetch(step, delay);
- }
- if (this.isSlideshowPlaying_())
- this.scheduleNextSlide_();
- }.bind(this));
- }.bind(this);
- this.metadataCache_.get(
- selectedItem.getEntry(), Gallery.METADATA_TYPE, onMetadata);
-};
-
-/**
- * Unload the current image.
- *
- * @param {Rect} zoomToRect Rectangle for zoom effect.
- * @private
- */
-SlideMode.prototype.unloadImage_ = function(zoomToRect) {
- this.imageView_.unload(zoomToRect);
- this.container_.removeAttribute('video');
-};
-
-/**
- * Data model 'splice' event handler.
- * @param {Event} event Event.
- * @private
- */
-SlideMode.prototype.onSplice_ = function(event) {
- ImageUtil.setAttribute(this.arrowBox_, 'active', this.getItemCount_() > 1);
-
- // Splice invalidates saved indices, drop the saved selection.
- this.savedSelection_ = null;
-
- if (event.removed.length != 1)
- return;
-
- // Delay the selection to let the ribbon splice handler work first.
- setTimeout(function() {
- if (event.index < this.dataModel_.length) {
- // There is the next item, select it.
- // The next item is now at the same index as the removed one, so we need
- // to correct displayIndex_ so that loadSelectedItem_ does not think
- // we are re-selecting the same item (and does right-to-left slide-in
- // animation).
- this.displayedIndex_ = event.index - 1;
- this.select(event.index);
- } else if (this.dataModel_.length) {
- // Removed item is the rightmost, but there are more items.
- this.select(event.index - 1); // Select the new last index.
- } else {
- // No items left. Unload the image and show the banner.
- this.commitItem_(function() {
- this.unloadImage_();
- this.showErrorBanner_('GALLERY_NO_IMAGES');
- }.bind(this));
- }
- }.bind(this), 0);
-};
-
-/**
- * @param {number} direction -1 for left, 1 for right.
- * @return {number} Next index in the given direction, with wrapping.
- * @private
- */
-SlideMode.prototype.getNextSelectedIndex_ = function(direction) {
- function advance(index, limit) {
- index += (direction > 0 ? 1 : -1);
- if (index < 0)
- return limit - 1;
- if (index === limit)
- return 0;
- return index;
- }
-
- // If the saved selection is multiple the Slideshow should cycle through
- // the saved selection.
- if (this.isSlideshowOn_() &&
- this.savedSelection_ && this.savedSelection_.length > 1) {
- var pos = advance(this.savedSelection_.indexOf(this.getSelectedIndex()),
- this.savedSelection_.length);
- return this.savedSelection_[pos];
- } else {
- return advance(this.getSelectedIndex(), this.getItemCount_());
- }
-};
-
-/**
- * Advance the selection based on the pressed key ID.
- * @param {string} keyID Key identifier.
- */
-SlideMode.prototype.advanceWithKeyboard = function(keyID) {
- this.advanceManually(keyID === 'Up' || keyID === 'Left' ? -1 : 1);
-};
-
-/**
- * Advance the selection as a result of a user action (as opposed to an
- * automatic change in the slideshow mode).
- * @param {number} direction -1 for left, 1 for right.
- */
-SlideMode.prototype.advanceManually = function(direction) {
- if (this.isSlideshowPlaying_()) {
- this.pauseSlideshow_();
- cr.dispatchSimpleEvent(this, 'useraction');
- }
- this.selectNext(direction);
-};
-
-/**
- * Select the next item.
- * @param {number} direction -1 for left, 1 for right.
- */
-SlideMode.prototype.selectNext = function(direction) {
- this.select(this.getNextSelectedIndex_(direction), direction);
-};
-
-/**
- * Select the first item.
- */
-SlideMode.prototype.selectFirst = function() {
- this.select(0);
-};
-
-/**
- * Select the last item.
- */
-SlideMode.prototype.selectLast = function() {
- this.select(this.getItemCount_() - 1);
-};
-
-// Loading/unloading
-
-/**
- * Load and display an item.
- *
- * @param {FileEntry} entry Item entry to be loaded.
- * @param {Object} metadata Item metadata.
- * @param {Object} effect Transition effect object.
- * @param {function} displayCallback Called when the image is displayed
- * (which can happen before the image load due to caching).
- * @param {function} loadCallback Called when the image is fully loaded.
- * @private
- */
-SlideMode.prototype.loadItem_ = function(
- entry, metadata, effect, displayCallback, loadCallback) {
- this.selectedImageMetadata_ = MetadataCache.cloneMetadata(metadata);
-
- this.showSpinner_(true);
-
- var loadDone = function(loadType, delay, error) {
- var video = this.isShowingVideo_();
- ImageUtil.setAttribute(this.container_, 'video', video);
-
- this.showSpinner_(false);
- if (loadType === ImageView.LOAD_TYPE_ERROR) {
- // if we have a specific error, then display it
- if (error) {
- this.showErrorBanner_(error);
- } else {
- // otherwise try to infer general error
- this.showErrorBanner_(
- video ? 'GALLERY_VIDEO_ERROR' : 'GALLERY_IMAGE_ERROR');
- }
- } else if (loadType === ImageView.LOAD_TYPE_OFFLINE) {
- this.showErrorBanner_(
- video ? 'GALLERY_VIDEO_OFFLINE' : 'GALLERY_IMAGE_OFFLINE');
- }
-
- if (video) {
- // The editor toolbar does not make sense for video, hide it.
- this.stopEditing_();
- this.mediaControls_.attachMedia(this.imageView_.getVideo());
-
- // TODO(kaznacheev): Add metrics for video playback.
- } else {
- ImageUtil.metrics.recordUserAction(ImageUtil.getMetricName('View'));
-
- var toMillions = function(number) {
- return Math.round(number / (1000 * 1000));
- };
-
- ImageUtil.metrics.recordSmallCount(ImageUtil.getMetricName('Size.MB'),
- toMillions(metadata.filesystem.size));
-
- var canvas = this.imageView_.getCanvas();
- ImageUtil.metrics.recordSmallCount(ImageUtil.getMetricName('Size.MPix'),
- toMillions(canvas.width * canvas.height));
-
- var extIndex = entry.name.lastIndexOf('.');
- var ext = extIndex < 0 ? '' :
- entry.name.substr(extIndex + 1).toLowerCase();
- if (ext === 'jpeg') ext = 'jpg';
- ImageUtil.metrics.recordEnum(
- ImageUtil.getMetricName('FileType'), ext, ImageUtil.FILE_TYPES);
- }
-
- // Enable or disable buttons for editing and printing.
- if (video || error) {
- this.editButton_.setAttribute('disabled', '');
- this.printButton_.setAttribute('disabled', '');
- } else {
- this.editButton_.removeAttribute('disabled');
- this.printButton_.removeAttribute('disabled');
- }
-
- // For once edited image, disallow the 'overwrite' setting change.
- ImageUtil.setAttribute(this.options_, 'saved',
- !this.getSelectedItem().isOriginal());
-
- util.platform.getPreference(SlideMode.OVERWRITE_BUBBLE_KEY,
- function(value) {
- var times = typeof value === 'string' ? parseInt(value, 10) : 0;
- if (times < SlideMode.OVERWRITE_BUBBLE_MAX_TIMES) {
- this.bubble_.hidden = false;
- if (this.isEditing()) {
- util.platform.setPreference(
- SlideMode.OVERWRITE_BUBBLE_KEY, times + 1);
- }
- }
- }.bind(this));
-
- loadCallback(loadType, delay);
- }.bind(this);
-
- var displayDone = function() {
- cr.dispatchSimpleEvent(this, 'image-displayed');
- displayCallback();
- }.bind(this);
-
- this.editor_.openSession(entry, metadata, effect,
- this.saveCurrentImage_.bind(this), displayDone, loadDone);
-};
-
-/**
- * Commit changes to the current item and reset all messages/indicators.
- *
- * @param {function} callback Callback.
- * @private
- */
-SlideMode.prototype.commitItem_ = function(callback) {
- this.showSpinner_(false);
- this.showErrorBanner_(false);
- this.editor_.getPrompt().hide();
-
- // Detach any media attached to the controls.
- if (this.mediaControls_.getMedia())
- this.mediaControls_.detachMedia();
-
- // If showing the video, then pause it. Note, that it may not be attached
- // to the media controls yet.
- if (this.isShowingVideo_()) {
- this.imageView_.getVideo().pause();
- // Force stop downloading, if uncached on Drive.
- this.imageView_.getVideo().src = '';
- this.imageView_.getVideo().load();
- }
-
- this.editor_.closeSession(callback);
-};
-
-/**
- * Request a prefetch for the next image.
- *
- * @param {number} direction -1 or 1.
- * @param {number} delay Delay in ms. Used to prevent the CPU-heavy image
- * loading from disrupting the animation that might be still in progress.
- */
-SlideMode.prototype.requestPrefetch = function(direction, delay) {
- if (this.getItemCount_() <= 1) return;
-
- var index = this.getNextSelectedIndex_(direction);
- var nextItemEntry = this.getItem(index).getEntry();
- this.imageView_.prefetch(nextItemEntry, delay);
-};
-
-// Event handlers.
-
-/**
- * Unload handler, to be called from the top frame.
- * @param {boolean} exiting True if the app is exiting.
- */
-SlideMode.prototype.onUnload = function(exiting) {
- if (this.isShowingVideo_() && this.mediaControls_.isPlaying()) {
- this.mediaControls_.savePosition(exiting);
- }
-};
-
-/**
- * beforeunload handler, to be called from the top frame.
- * @return {string} Message to show if there are unsaved changes.
- */
-SlideMode.prototype.onBeforeUnload = function() {
- if (this.editor_.isBusy())
- return this.displayStringFunction_('GALLERY_UNSAVED_CHANGES');
- return null;
-};
-
-/**
- * Click handler for the image container.
- *
- * @param {Event} event Mouse click event.
- * @private
- */
-SlideMode.prototype.onClick_ = function(event) {
- if (!this.isShowingVideo_() || !this.mediaControls_.getMedia())
- return;
- if (event.ctrlKey) {
- this.mediaControls_.toggleLoopedModeWithFeedback(true);
- if (!this.mediaControls_.isPlaying())
- this.mediaControls_.togglePlayStateWithFeedback();
- } else {
- this.mediaControls_.togglePlayStateWithFeedback();
- }
-};
-
-/**
- * Click handler for the entire document.
- * @param {Event} e Mouse click event.
- * @private
- */
-SlideMode.prototype.onDocumentClick_ = function(e) {
- // Close the bubble if clicked outside of it and if it is visible.
- if (!this.bubble_.contains(e.target) &&
- !this.editButton_.contains(e.target) &&
- !this.arrowLeft_.contains(e.target) &&
- !this.arrowRight_.contains(e.target) &&
- !this.bubble_.hidden) {
- this.bubble_.hidden = true;
- }
-};
-
-/**
- * Keydown handler.
- *
- * @param {Event} event Event.
- * @return {boolean} True if handled.
- */
-SlideMode.prototype.onKeyDown = function(event) {
- var keyID = util.getKeyModifiers(event) + event.keyIdentifier;
-
- if (this.isSlideshowOn_()) {
- switch (keyID) {
- case 'U+001B': // Escape exits the slideshow.
- this.stopSlideshow_(event);
- break;
-
- case 'U+0020': // Space pauses/resumes the slideshow.
- this.toggleSlideshowPause_();
- break;
-
- case 'Up':
- case 'Down':
- case 'Left':
- case 'Right':
- this.advanceWithKeyboard(keyID);
- break;
- }
- return true; // Consume all keystrokes in the slideshow mode.
- }
-
- if (this.isEditing() && this.editor_.onKeyDown(event))
- return true;
-
- switch (keyID) {
- case 'U+0020': // Space toggles the video playback.
- if (this.isShowingVideo_() && this.mediaControls_.getMedia())
- this.mediaControls_.togglePlayStateWithFeedback();
- break;
-
- case 'Ctrl-U+0050': // Ctrl+'p' prints the current image.
- if (!this.printButton_.hasAttribute('disabled'))
- this.print_();
- break;
-
- case 'U+0045': // 'e' toggles the editor.
- if (!this.editButton_.hasAttribute('disabled'))
- this.toggleEditor(event);
- break;
-
- case 'U+001B': // Escape
- if (!this.isEditing())
- return false; // Not handled.
- this.toggleEditor(event);
- break;
-
- case 'Home':
- this.selectFirst();
- break;
- case 'End':
- this.selectLast();
- break;
- case 'Up':
- case 'Down':
- case 'Left':
- case 'Right':
- this.advanceWithKeyboard(keyID);
- break;
-
- default: return false;
- }
-
- return true;
-};
-
-/**
- * Resize handler.
- * @private
- */
-SlideMode.prototype.onResize_ = function() {
- this.viewport_.sizeByFrameAndFit(this.container_);
- this.viewport_.repaint();
-};
-
-/**
- * Update thumbnails.
- */
-SlideMode.prototype.updateThumbnails = function() {
- this.ribbon_.reset();
- if (this.active_)
- this.ribbon_.redraw();
-};
-
-// Saving
-
-/**
- * Save the current image to a file.
- *
- * @param {function} callback Callback.
- * @private
- */
-SlideMode.prototype.saveCurrentImage_ = function(callback) {
- var item = this.getSelectedItem();
- var oldEntry = item.getEntry();
- var canvas = this.imageView_.getCanvas();
-
- this.showSpinner_(true);
- var metadataEncoder = ImageEncoder.encodeMetadata(
- this.selectedImageMetadata_.media, canvas, 1 /* quality */);
-
- this.selectedImageMetadata_ = ContentProvider.ConvertContentMetadata(
- metadataEncoder.getMetadata(), this.selectedImageMetadata_);
-
- item.saveToFile(
- this.context_.saveDirEntry,
- this.shouldOverwriteOriginal_(),
- canvas,
- metadataEncoder,
- function(success) {
- // TODO(kaznacheev): Implement write error handling.
- // Until then pretend that the save succeeded.
- this.showSpinner_(false);
- this.flashSavedLabel_();
-
- var event = new Event('content');
- event.item = item;
- event.oldEntry = oldEntry;
- event.metadata = this.selectedImageMetadata_;
- this.dataModel_.dispatchEvent(event);
-
- // Allow changing the 'Overwrite original' setting only if the user
- // used Undo to restore the original image AND it is not a copy.
- // Otherwise lock the setting in its current state.
- var mayChangeOverwrite = !this.editor_.canUndo() && item.isOriginal();
- ImageUtil.setAttribute(this.options_, 'saved', !mayChangeOverwrite);
-
- if (this.imageView_.getContentRevision() === 1) { // First edit.
- ImageUtil.metrics.recordUserAction(ImageUtil.getMetricName('Edit'));
- }
-
- if (!util.isSameEntry(oldEntry, item.getEntry())) {
- this.dataModel_.splice(
- this.getSelectedIndex(), 0, new Gallery.Item(oldEntry));
- // The ribbon will ignore the splice above and redraw after the
- // select call below (while being obscured by the Editor toolbar,
- // so there is no need for nice animation here).
- // SlideMode will ignore the selection change as the displayed item
- // index has not changed.
- this.select(++this.displayedIndex_);
- }
- callback();
- cr.dispatchSimpleEvent(this, 'image-saved');
- }.bind(this));
-};
-
-/**
- * Update caches when the selected item has been renamed.
- * @param {Event} event Event.
- * @private
- */
-SlideMode.prototype.onContentChange_ = function(event) {
- var newEntry = event.item.getEntry();
- if (util.isSameEntry(newEntry, event.oldEntry))
- this.imageView_.changeEntry(newEntry);
- this.metadataCache_.clear(event.oldEntry, Gallery.METADATA_TYPE);
-};
-
-/**
- * Flash 'Saved' label briefly to indicate that the image has been saved.
- * @private
- */
-SlideMode.prototype.flashSavedLabel_ = function() {
- var setLabelHighlighted =
- ImageUtil.setAttribute.bind(null, this.savedLabel_, 'highlighted');
- setTimeout(setLabelHighlighted.bind(null, true), 0);
- setTimeout(setLabelHighlighted.bind(null, false), 300);
-};
-
-/**
- * Local storage key for the 'Overwrite original' setting.
- * @type {string}
- */
-SlideMode.OVERWRITE_KEY = 'gallery-overwrite-original';
-
-/**
- * Local storage key for the number of times that
- * the overwrite info bubble has been displayed.
- * @type {string}
- */
-SlideMode.OVERWRITE_BUBBLE_KEY = 'gallery-overwrite-bubble';
-
-/**
- * Max number that the overwrite info bubble is shown.
- * @type {number}
- */
-SlideMode.OVERWRITE_BUBBLE_MAX_TIMES = 5;
-
-/**
- * @return {boolean} True if 'Overwrite original' is set.
- * @private
- */
-SlideMode.prototype.shouldOverwriteOriginal_ = function() {
- return this.overwriteOriginal_.checked;
-};
-
-/**
- * 'Overwrite original' checkbox handler.
- * @param {Event} event Event.
- * @private
- */
-SlideMode.prototype.onOverwriteOriginalClick_ = function(event) {
- util.platform.setPreference(SlideMode.OVERWRITE_KEY, event.target.checked);
-};
-
-/**
- * Overwrite info bubble close handler.
- * @private
- */
-SlideMode.prototype.onCloseBubble_ = function() {
- this.bubble_.hidden = true;
- util.platform.setPreference(SlideMode.OVERWRITE_BUBBLE_KEY,
- SlideMode.OVERWRITE_BUBBLE_MAX_TIMES);
-};
-
-// Slideshow
-
-/**
- * Slideshow interval in ms.
- */
-SlideMode.SLIDESHOW_INTERVAL = 5000;
-
-/**
- * First slideshow interval in ms. It should be shorter so that the user
- * is not guessing whether the button worked.
- */
-SlideMode.SLIDESHOW_INTERVAL_FIRST = 1000;
-
-/**
- * Empirically determined duration of the fullscreen toggle animation.
- */
-SlideMode.FULLSCREEN_TOGGLE_DELAY = 500;
-
-/**
- * @return {boolean} True if the slideshow is on.
- * @private
- */
-SlideMode.prototype.isSlideshowOn_ = function() {
- return this.container_.hasAttribute('slideshow');
-};
-
-/**
- * Start the slideshow.
- * @param {number=} opt_interval First interval in ms.
- * @param {Event=} opt_event Event.
- */
-SlideMode.prototype.startSlideshow = function(opt_interval, opt_event) {
- // Set the attribute early to prevent the toolbar from flashing when
- // the slideshow is being started from the mosaic view.
- this.container_.setAttribute('slideshow', 'playing');
-
- if (this.active_) {
- this.stopEditing_();
- } else {
- // We are in the Mosaic mode. Toggle the mode but remember to return.
- this.leaveAfterSlideshow_ = true;
- this.toggleMode_(this.startSlideshow.bind(
- this, SlideMode.SLIDESHOW_INTERVAL, opt_event));
- return;
- }
-
- if (opt_event) // Caused by user action, notify the Gallery.
- cr.dispatchSimpleEvent(this, 'useraction');
-
- this.fullscreenBeforeSlideshow_ = util.isFullScreen(this.context_.appWindow);
- if (!this.fullscreenBeforeSlideshow_) {
- // Wait until the zoom animation from the mosaic mode is done.
- setTimeout(this.toggleFullScreen_.bind(this),
- ImageView.ZOOM_ANIMATION_DURATION);
- opt_interval = (opt_interval || SlideMode.SLIDESHOW_INTERVAL) +
- SlideMode.FULLSCREEN_TOGGLE_DELAY;
- }
-
- this.resumeSlideshow_(opt_interval);
-};
-
-/**
- * Stop the slideshow.
- * @param {Event=} opt_event Event.
- * @private
- */
-SlideMode.prototype.stopSlideshow_ = function(opt_event) {
- if (!this.isSlideshowOn_())
- return;
-
- if (opt_event) // Caused by user action, notify the Gallery.
- cr.dispatchSimpleEvent(this, 'useraction');
-
- this.pauseSlideshow_();
- this.container_.removeAttribute('slideshow');
-
- // Do not restore fullscreen if we exited fullscreen while in slideshow.
- var fullscreen = util.isFullScreen(this.context_.appWindow);
- var toggleModeDelay = 0;
- if (!this.fullscreenBeforeSlideshow_ && fullscreen) {
- this.toggleFullScreen_();
- toggleModeDelay = SlideMode.FULLSCREEN_TOGGLE_DELAY;
- }
- if (this.leaveAfterSlideshow_) {
- this.leaveAfterSlideshow_ = false;
- setTimeout(this.toggleMode_.bind(this), toggleModeDelay);
- }
-};
-
-/**
- * @return {boolean} True if the slideshow is playing (not paused).
- * @private
- */
-SlideMode.prototype.isSlideshowPlaying_ = function() {
- return this.container_.getAttribute('slideshow') === 'playing';
-};
-
-/**
- * Pause/resume the slideshow.
- * @private
- */
-SlideMode.prototype.toggleSlideshowPause_ = function() {
- cr.dispatchSimpleEvent(this, 'useraction'); // Show the tools.
- if (this.isSlideshowPlaying_()) {
- this.pauseSlideshow_();
- } else {
- this.resumeSlideshow_(SlideMode.SLIDESHOW_INTERVAL_FIRST);
- }
-};
-
-/**
- * @param {number=} opt_interval Slideshow interval in ms.
- * @private
- */
-SlideMode.prototype.scheduleNextSlide_ = function(opt_interval) {
- console.assert(this.isSlideshowPlaying_(), 'Inconsistent slideshow state');
-
- if (this.slideShowTimeout_)
- clearTimeout(this.slideShowTimeout_);
-
- this.slideShowTimeout_ = setTimeout(function() {
- this.slideShowTimeout_ = null;
- this.selectNext(1);
- }.bind(this),
- opt_interval || SlideMode.SLIDESHOW_INTERVAL);
-};
-
-/**
- * Resume the slideshow.
- * @param {number=} opt_interval Slideshow interval in ms.
- * @private
- */
-SlideMode.prototype.resumeSlideshow_ = function(opt_interval) {
- this.container_.setAttribute('slideshow', 'playing');
- this.scheduleNextSlide_(opt_interval);
-};
-
-/**
- * Pause the slideshow.
- * @private
- */
-SlideMode.prototype.pauseSlideshow_ = function() {
- this.container_.setAttribute('slideshow', 'paused');
- if (this.slideShowTimeout_) {
- clearTimeout(this.slideShowTimeout_);
- this.slideShowTimeout_ = null;
- }
-};
-
-/**
- * @return {boolean} True if the editor is active.
- */
-SlideMode.prototype.isEditing = function() {
- return this.container_.hasAttribute('editing');
-};
-
-/**
- * Stop editing.
- * @private
- */
-SlideMode.prototype.stopEditing_ = function() {
- if (this.isEditing())
- this.toggleEditor();
-};
-
-/**
- * Activate/deactivate editor.
- * @param {Event=} opt_event Event.
- */
-SlideMode.prototype.toggleEditor = function(opt_event) {
- if (opt_event) // Caused by user action, notify the Gallery.
- cr.dispatchSimpleEvent(this, 'useraction');
-
- if (!this.active_) {
- this.toggleMode_(this.toggleEditor.bind(this));
- return;
- }
-
- this.stopSlideshow_();
- if (!this.isEditing() && this.isShowingVideo_())
- return; // No editing for videos.
-
- ImageUtil.setAttribute(this.container_, 'editing', !this.isEditing());
-
- if (this.isEditing()) { // isEditing has just been flipped to a new value.
- if (this.context_.readonlyDirName) {
- this.editor_.getPrompt().showAt(
- 'top', 'GALLERY_READONLY_WARNING', 0, this.context_.readonlyDirName);
- }
- } else {
- this.editor_.getPrompt().hide();
- this.editor_.leaveModeGently();
- }
-};
-
-/**
- * Prints the current item.
- * @private
- */
-SlideMode.prototype.print_ = function() {
- cr.dispatchSimpleEvent(this, 'useraction');
- window.print();
-};
-
-/**
- * Display the error banner.
- * @param {string} message Message.
- * @private
- */
-SlideMode.prototype.showErrorBanner_ = function(message) {
- if (message) {
- this.errorBanner_.textContent = this.displayStringFunction_(message);
- }
- ImageUtil.setAttribute(this.container_, 'error', !!message);
-};
-
-/**
- * Show/hide the busy spinner.
- *
- * @param {boolean} on True if show, false if hide.
- * @private
- */
-SlideMode.prototype.showSpinner_ = function(on) {
- if (this.spinnerTimer_) {
- clearTimeout(this.spinnerTimer_);
- this.spinnerTimer_ = null;
- }
-
- if (on) {
- this.spinnerTimer_ = setTimeout(function() {
- this.spinnerTimer_ = null;
- ImageUtil.setAttribute(this.container_, 'spinner', true);
- }.bind(this), 1000);
- } else {
- ImageUtil.setAttribute(this.container_, 'spinner', false);
- }
-};
-
-/**
- * @return {boolean} True if the current item is a video.
- * @private
- */
-SlideMode.prototype.isShowingVideo_ = function() {
- return !!this.imageView_.getVideo();
-};
-
-/**
- * Overlay that handles swipe gestures. Changes to the next or previous file.
- * @param {function(number)} callback A callback accepting the swipe direction
- * (1 means left, -1 right).
- * @constructor
- * @implements {ImageBuffer.Overlay}
- */
-function SwipeOverlay(callback) {
- this.callback_ = callback;
-}
-
-/**
- * Inherit ImageBuffer.Overlay.
- */
-SwipeOverlay.prototype.__proto__ = ImageBuffer.Overlay.prototype;
-
-/**
- * @param {number} x X pointer position.
- * @param {number} y Y pointer position.
- * @param {boolean} touch True if dragging caused by touch.
- * @return {function} The closure to call on drag.
- */
-SwipeOverlay.prototype.getDragHandler = function(x, y, touch) {
- if (!touch)
- return null;
- var origin = x;
- var done = false;
- return function(x, y) {
- if (!done && origin - x > SwipeOverlay.SWIPE_THRESHOLD) {
- this.callback_(1);
- done = true;
- } else if (!done && x - origin > SwipeOverlay.SWIPE_THRESHOLD) {
- this.callback_(-1);
- done = true;
- }
- }.bind(this);
-};
-
-/**
- * If the user touched the image and moved the finger more than SWIPE_THRESHOLD
- * horizontally it's considered as a swipe gesture (change the current image).
- */
-SwipeOverlay.SWIPE_THRESHOLD = 100;
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/scrollbar.js b/chromium/chrome/browser/resources/file_manager/foreground/js/scrollbar.js
deleted file mode 100644
index a81fe8db12f..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/scrollbar.js
+++ /dev/null
@@ -1,294 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Creates a new scroll bar element.
- * @extends {HTMLDivElement}
- * @constructor
- */
-var ScrollBar = cr.ui.define('div');
-
-/**
- * Mode of the scrollbar. As for now, only vertical scrollbars are supported.
- * @type {number}
- */
-ScrollBar.Mode = {
- VERTICAL: 0,
- HORIZONTAL: 1
-};
-
-ScrollBar.prototype = {
- set mode(value) {
- this.mode_ = value;
- if (this.mode_ == ScrollBar.Mode.VERTICAL) {
- this.classList.remove('scrollbar-horizontal');
- this.classList.add('scrollbar-vertical');
- } else {
- this.classList.remove('scrollbar-vertical');
- this.classList.add('scrollbar-horizontal');
- }
- this.redraw_();
- },
- get mode() {
- return this.mode_;
- }
-};
-
-/**
- * Inherits after HTMLDivElement.
- */
-ScrollBar.prototype.__proto__ = HTMLDivElement.prototype;
-
-/**
- * Initializes the DOM structure of the scrollbar.
- */
-ScrollBar.prototype.decorate = function() {
- this.classList.add('scrollbar');
- this.button_ = util.createChild(this, 'scrollbar-button', 'div');
- this.mode = ScrollBar.Mode.VERTICAL;
-
- this.button_.addEventListener('mousedown',
- this.onButtonPressed_.bind(this));
- window.addEventListener('mouseup', this.onMouseUp_.bind(this));
- window.addEventListener('mousemove', this.onMouseMove_.bind(this));
-};
-
-/**
- * Initialize a scrollbar.
- *
- * @param {Element} parent Parent element, must have a relative or absolute
- * positioning.
- * @param {Element=} opt_scrollableArea Element with scrollable contents.
- * If not passed, then call attachToView manually when the scrollable
- * element becomes available.
- */
-ScrollBar.prototype.initialize = function(parent, opt_scrollableArea) {
- parent.appendChild(this);
- if (opt_scrollableArea)
- this.attachToView(opt_scrollableArea);
-};
-
-/**
- * Attaches the scrollbar to a scrollable element and attaches handlers.
- * @param {Element} view Scrollable element.
- */
-ScrollBar.prototype.attachToView = function(view) {
- this.view_ = view;
- this.view_.addEventListener('scroll', this.onScroll_.bind(this));
- this.view_.addEventListener('relayout', this.onRelayout_.bind(this));
- this.domObserver_ = new MutationObserver(this.onDomChanged_.bind(this));
- this.domObserver_.observe(this.view_, {subtree: true, attributes: true});
- this.onRelayout_();
-};
-
-/**
- * Scroll handler.
- * @private
- */
-ScrollBar.prototype.onScroll_ = function() {
- this.scrollTop_ = this.view_.scrollTop;
- this.redraw_();
-};
-
-/**
- * Relayout handler.
- * @private
- */
-ScrollBar.prototype.onRelayout_ = function() {
- this.scrollHeight_ = this.view_.scrollHeight;
- this.clientHeight_ = this.view_.clientHeight;
- this.offsetTop_ = this.view_.offsetTop;
- this.scrollTop_ = this.view_.scrollTop;
- this.redraw_();
-};
-
-/**
- * Pressing on the scrollbar's button handler.
- *
- * @param {Event} event Pressing event.
- * @private
- */
-ScrollBar.prototype.onButtonPressed_ = function(event) {
- this.buttonPressed_ = true;
- this.buttonPressedEvent_ = event;
- this.buttonPressedPosition_ = this.button_.offsetTop - this.view_.offsetTop;
- this.button_.classList.add('pressed');
-
- event.preventDefault();
-};
-
-/**
- * Releasing the button handler. Note, that it may not be called when releasing
- * outside of the window. Therefore this is also called from onMouseMove_.
- *
- * @param {Event} event Mouse event.
- * @private
- */
-ScrollBar.prototype.onMouseUp_ = function(event) {
- this.buttonPressed_ = false;
- this.button_.classList.remove('pressed');
-};
-
-/**
- * Mouse move handler. Updates the scroll position.
- *
- * @param {Event} event Mouse event.
- * @private
- */
-ScrollBar.prototype.onMouseMove_ = function(event) {
- if (!this.buttonPressed_)
- return;
- if (!event.which) {
- this.onMouseUp_(event);
- return;
- }
- var clientSize = this.getClientHeight();
- var totalSize = this.getTotalHeight();
- // TODO(hirono): Fix the geometric calculation. crbug.com/253779
- var buttonSize = Math.max(50, clientSize / totalSize * clientSize);
- var buttonPosition = this.buttonPressedPosition_ +
- (event.screenY - this.buttonPressedEvent_.screenY);
- // Ensures the scrollbar is in the view.
- buttonPosition =
- Math.max(0, Math.min(buttonPosition, clientSize - buttonSize));
- var scrollPosition;
- if (clientSize > buttonSize) {
- scrollPosition = Math.max(totalSize - clientSize, 0) *
- buttonPosition / (clientSize - buttonSize);
- } else {
- scrollPosition = 0;
- }
-
- this.scrollTop_ = scrollPosition;
- this.view_.scrollTop = scrollPosition;
- this.redraw_();
-};
-
-/**
- * Handles changed in Dom by redrawing the scrollbar. Ignores consecutive calls.
- * @private
- */
-ScrollBar.prototype.onDomChanged_ = function() {
- if (this.domChangedTimer_) {
- clearTimeout(this.domChangedTimer_);
- this.domChangedTimer_ = null;
- }
- this.domChangedTimer_ = setTimeout(function() {
- this.onRelayout_();
- this.domChangedTimer_ = null;
- }.bind(this), 50);
-};
-
-/**
- * Redraws the scrollbar.
- * @private
- */
-ScrollBar.prototype.redraw_ = function() {
- if (!this.view_)
- return;
-
- var clientSize = this.getClientHeight();
- var clientTop = this.offsetTop_;
- var scrollPosition = this.scrollTop_;
- var totalSize = this.getTotalHeight();
- var hidden = totalSize <= clientSize;
-
- var buttonSize = Math.max(50, clientSize / totalSize * clientSize);
- var buttonPosition;
- if (clientSize - buttonSize > 0) {
- buttonPosition = scrollPosition / (totalSize - clientSize) *
- (clientSize - buttonSize);
- } else {
- buttonPosition = 0;
- }
- var buttonTop = buttonPosition + clientTop;
-
- var time = Date.now();
- if (this.hidden != hidden ||
- this.lastButtonTop_ != buttonTop ||
- this.lastButtonSize_ != buttonSize) {
- requestAnimationFrame(function() {
- this.hidden = hidden;
- this.button_.style.top = buttonTop + 'px';
- this.button_.style.height = buttonSize + 'px';
- }.bind(this));
- }
-
- this.lastButtonTop_ = buttonTop;
- this.lastButtonSize_ = buttonSize;
-};
-
-/**
- * Returns the viewport height of the view.
- * @return {number} The viewport height of the view in px.
- * @protected
- */
-ScrollBar.prototype.getClientHeight = function() {
- return this.clientHeight_;
-};
-
-/**
- * Returns the total height of the view.
- * @return {number} The total height of the view in px.
- * @protected
- */
-ScrollBar.prototype.getTotalHeight = function() {
- return this.scrollHeight_;
-};
-
-/**
- * Creates a new scroll bar for elements in the main panel.
- * @extends {ScrollBar}
- * @constructor
- */
-var MainPanelScrollBar = cr.ui.define('div');
-
-/**
- * Inherits after ScrollBar.
- */
-MainPanelScrollBar.prototype.__proto__ = ScrollBar.prototype;
-
-/** @override */
-MainPanelScrollBar.prototype.decorate = function() {
- ScrollBar.prototype.decorate.call(this);
-
- /**
- * Margin for the transparent preview panel at the bottom.
- * @type {number}
- * @private
- */
- this.bottomMarginForPanel_ = 0;
-};
-
-/**
- * GReturns the viewport height of the view, considering the preview panel.
- *
- * @return {number} The viewport height of the view in px.
- * @override
- * @protected
- */
-MainPanelScrollBar.prototype.getClientHeight = function() {
- return this.clientHeight_ - this.bottomMarginForPanel_;
-};
-
-/**
- * Returns the total height of the view, considering the preview panel.
- *
- * @return {number} The total height of the view in px.
- * @override
- * @protected
- */
-MainPanelScrollBar.prototype.getTotalHeight = function() {
- return this.scrollHeight_ - this.bottomMarginForPanel_;
-};
-
-/**
- * Sets the bottom margin height of the view for the transparent preview panel.
- * @param {number} margin Margin to be set in px.
- */
-MainPanelScrollBar.prototype.setBottomMarginForPanel = function(margin) {
- this.bottomMarginForPanel_ = margin;
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/share_client.js b/chromium/chrome/browser/resources/file_manager/foreground/js/share_client.js
deleted file mode 100644
index 3044b21a17e..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/share_client.js
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * @param {WebView} webView Web View tag.
- * @param {string} url Share Url for an entry.
- * @param {ShareClient.Observer} observer Observer instance.
- * @constructor
- */
-function ShareClient(webView, url, observer) {
- this.webView_ = webView;
- this.url_ = url;
- this.observer_ = observer;
- this.loaded_ = false;
- this.loading_ = false;
- this.onMessageBound_ = this.onMessage_.bind(this);
- this.onLoadStopBound_ = this.onLoadStop_.bind(this);
- this.onLoadAbortBound_ = this.onLoadAbort_.bind(this);
-}
-
-/**
- * Source origin of the client.
- * @type {string}
- * @const
- */
-ShareClient.SHARE_ORIGIN =
- 'chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj';
-
-/**
- * Target origin of the embedded dialog.
- * @type {string}
- * @const
- */
-ShareClient.SHARE_TARGET = 'https://drive.google.com';
-
-/**
- * Observes for state changes of the embedded dialog.
- * @interface
- */
-ShareClient.Observer = function() {
-};
-
-/**
- * Notifies about the embedded dialog being loaded.
- */
-ShareClient.Observer.prototype.onLoaded = function() {
-};
-
-/**
- * Notifies when the the embedded dialog failed to load.
- */
-ShareClient.Observer.prototype.onLoadingFailed = function() {
-};
-
-/**
- * Notifies about changed dimensions of the embedded dialog.
- * @param {number} width Width in pixels.
- * @param {number} height Height in pixels.
- * @param {function()} callback Completion callback. Call when finished
- * handling the resize.
- */
-ShareClient.Observer.prototype.onResized = function(width, height, callback) {
-};
-
-/**
- * Notifies about the embedded dialog being closed.
- */
-ShareClient.Observer.prototype.onClosed = function() {
-};
-
-/**
- * Handles messages from the embedded dialog.
- * @param {Event} e Message event.
- * @private
- */
-ShareClient.prototype.onMessage_ = function(e) {
- if (e.origin != ShareClient.SHARE_TARGET && !window.IN_TEST) {
- // Logs added temporarily to track crbug.com/288783.
- console.debug('Received a message from an illegal origin: ' + e.origin);
- return;
- }
-
- var data = JSON.parse(e.data);
- // Logs added temporarily to track crbug.com/288783.
- console.debug('Received message: ' + data.type);
-
- switch (data.type) {
- case 'resize':
- this.observer_.onResized(data.args.width,
- data.args.height,
- this.postMessage_.bind(this, 'resizeComplete'));
- break;
- case 'prepareForVisible':
- this.postMessage_('prepareComplete');
- if (!this.loaded_) {
- this.loading_ = false;
- this.loaded_ = true;
- this.observer_.onLoaded();
- }
- break;
- case 'setVisible':
- if (!data.args.visible)
- this.observer_.onClosed();
- break;
- }
-};
-
-/**
- * Handles completion of the web view request.
- * @param {Event} e Message event.
- * @private
- */
-ShareClient.prototype.onLoadStop_ = function(e) {
- // Logs added temporarily to track crbug.com/288783.
- console.debug('Web View loaded.');
-
- this.postMessage_('makeBodyVisible');
-};
-
-/**
- * Handles termination of the web view request.
- * @param {Event} e Message event.
- * @private
- */
-ShareClient.prototype.onLoadAbort_ = function(e) {
- // Logs added temporarily to track crbug.com/288783.
- console.debug('Web View failed to load with error: ' + e.reason + ', url: ' +
- e.url + ' while requested: ' + this.url_);
-
- this.observer_.onLoadFailed();
-};
-
-/**
- * Sends a message to the embedded dialog.
- * @param {string} type Message type.
- * @param {Object=} opt_args Optional arguments.
- * @private
- */
-ShareClient.prototype.postMessage_ = function(type, opt_args) {
- // Logs added temporarily to track crbug.com/288783.
- console.debug('Sending message: ' + type);
-
- var message = {
- type: type,
- args: opt_args
- };
- this.webView_.contentWindow.postMessage(
- JSON.stringify(message),
- !window.IN_TEST ? ShareClient.SHARE_TARGET : '*');
-};
-
-/**
- * Loads the embedded dialog. Can be called only one.
- */
-ShareClient.prototype.load = function() {
- if (this.loading_ || this.loaded_)
- throw new Error('Already loaded.');
- this.loading_ = true;
-
- // Logs added temporarily to track crbug.com/288783.
- console.debug('Loading.');
-
- window.addEventListener('message', this.onMessageBound_);
- this.webView_.addEventListener('loadstop', this.onLoadStopBound_);
- this.webView_.addEventListener('loadabort', this.onLoadAbortBound_);
- this.webView_.setAttribute('src', this.url_);
-};
-
-/**
- * Aborts loading of the embedded dialog and performs cleanup.
- */
-ShareClient.prototype.abort = function() {
- window.removeEventListener('message', this.onMessageBound_);
- this.webView_.removeEventListener('loadstop', this.onLoadStopBound_);
- this.webView_.removeEventListener(
- 'loadabort', this.onLoadAbortBound_);
- this.webView_.stop();
-};
-
-/**
- * Cleans the dialog by removing all handlers.
- */
-ShareClient.prototype.dispose = function() {
- this.abort();
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/share_dialog.js b/chromium/chrome/browser/resources/file_manager/foreground/js/share_dialog.js
deleted file mode 100644
index ff7fbf6b665..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/share_dialog.js
+++ /dev/null
@@ -1,314 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * @param {HTMLElement} parentNode Node to be parent for this dialog.
- * @constructor
- * @extends {FileManagerDialogBase}
- * @implements {ShareClient.Observer}
- */
-function ShareDialog(parentNode) {
- this.queue_ = new AsyncUtil.Queue();
- this.onQueueTaskFinished_ = null;
- this.shareClient_ = null;
- this.spinner_ = null;
- this.spinnerLayer_ = null;
- this.webViewWrapper_ = null;
- this.webView_ = null;
- this.failureTimeout_ = null;
- this.callback_ = null;
-
- FileManagerDialogBase.call(this, parentNode);
-}
-
-/**
- * Timeout for loading the share dialog before giving up.
- * @type {number}
- * @const
- */
-ShareDialog.FAILURE_TIMEOUT = 10000;
-
-/**
- * The result of opening the dialog.
- * @enum {string}
- * @const
- */
-ShareDialog.Result = Object.freeze({
- // The dialog is closed normally. This includes user cancel.
- SUCCESS: 'success',
- // The dialog is closed by network error.
- NETWORK_ERROR: 'networkError',
- // The dialog is not opened because it is already showing.
- ALREADY_SHOWING: 'alreadyShowing'
-});
-
-/**
- * Wraps a Web View element and adds authorization headers to it.
- * @param {string} urlPattern Pattern of urls to be authorized.
- * @param {WebView} webView Web View element to be wrapped.
- * @constructor
- */
-ShareDialog.WebViewAuthorizer = function(urlPattern, webView) {
- this.urlPattern_ = urlPattern;
- this.webView_ = webView;
- this.initialized_ = false;
- this.accessToken_ = null;
-};
-
-/**
- * Initializes the web view by installing hooks injecting the authorization
- * headers.
- * @param {function()} callback Completion callback.
- */
-ShareDialog.WebViewAuthorizer.prototype.initialize = function(callback) {
- if (this.initialized_) {
- callback();
- return;
- }
-
- var registerInjectionHooks = function() {
- this.webView_.removeEventListener('loadstop', registerInjectionHooks);
- this.webView_.request.onBeforeSendHeaders.addListener(
- this.authorizeRequest_.bind(this),
- {urls: [this.urlPattern_]},
- ['blocking', 'requestHeaders']);
- this.initialized_ = true;
- callback();
- }.bind(this);
-
- this.webView_.addEventListener('loadstop', registerInjectionHooks);
- this.webView_.setAttribute('src', 'data:text/html,');
-};
-
-/**
- * Authorizes the web view by fetching the freshest access tokens.
- * @param {function()} callback Completion callback.
- */
-ShareDialog.WebViewAuthorizer.prototype.authorize = function(callback) {
- // Fetch or update the access token.
- chrome.fileBrowserPrivate.requestAccessToken(false, // force_refresh
- function(inAccessToken) {
- this.accessToken_ = inAccessToken;
- callback();
- }.bind(this));
-};
-
-/**
- * Injects headers into the passed request.
- * @param {Event} e Request event.
- * @return {{requestHeaders: HttpHeaders}} Modified headers.
- * @private
- */
-ShareDialog.WebViewAuthorizer.prototype.authorizeRequest_ = function(e) {
- e.requestHeaders.push({
- name: 'Authorization',
- value: 'Bearer ' + this.accessToken_
- });
- return {requestHeaders: e.requestHeaders};
-};
-
-ShareDialog.prototype = {
- __proto__: FileManagerDialogBase.prototype
-};
-
-/**
- * One-time initialization of DOM.
- * @private
- */
-ShareDialog.prototype.initDom_ = function() {
- FileManagerDialogBase.prototype.initDom_.call(this);
- this.frame_.classList.add('share-dialog-frame');
-
- this.spinnerLayer_ = this.document_.createElement('div');
- this.spinnerLayer_.className = 'spinner-layer';
- this.frame_.appendChild(this.spinnerLayer_);
-
- this.webViewWrapper_ = this.document_.createElement('div');
- this.webViewWrapper_.className = 'share-dialog-webview-wrapper';
- this.cancelButton_.hidden = true;
- this.okButton_.hidden = true;
- this.frame_.insertBefore(this.webViewWrapper_,
- this.frame_.querySelector('.cr-dialog-buttons'));
-};
-
-/**
- * @override
- */
-ShareDialog.prototype.onResized = function(width, height, callback) {
- if (width && height) {
- this.webViewWrapper_.style.width = width + 'px';
- this.webViewWrapper_.style.height = height + 'px';
- this.webView_.style.width = width + 'px';
- this.webView_.style.height = height + 'px';
- }
- setTimeout(callback, 0);
-};
-
-/**
- * @override
- */
-ShareDialog.prototype.onClosed = function() {
- this.hide();
-};
-
-/**
- * @override
- */
-ShareDialog.prototype.onLoaded = function() {
- if (this.failureTimeout_) {
- clearTimeout(this.failureTimeout_);
- this.failureTimeout_ = null;
- }
-
- // Logs added temporarily to track crbug.com/288783.
- console.debug('Loaded.');
-
- this.okButton_.hidden = false;
- this.spinnerLayer_.hidden = true;
- this.webViewWrapper_.classList.add('loaded');
- this.webView_.focus();
-};
-
-/**
- * @override
- */
-ShareDialog.prototype.onLoadFailed = function() {
- this.hideWithResult(ShareDialog.Result.NETWORK_ERROR);
-};
-
-/**
- * @override
- */
-ShareDialog.prototype.hide = function(opt_onHide) {
- this.hideWithResult(ShareDialog.Result.SUCCESS, opt_onHide);
-};
-
-/**
- * Hide the dialog with the result and the callback.
- * @param {ShareDialog.Result} result Result passed to the closing callback.
- * @param {function()=} opt_onHide Callback called at the end of hiding.
- */
-ShareDialog.prototype.hideWithResult = function(result, opt_onHide) {
- if (!this.isShowing())
- return;
-
- if (this.shareClient_) {
- this.shareClient_.dispose();
- this.shareClient_ = null;
- }
-
- this.webViewWrapper_.textContent = '';
- if (this.failureTimeout_) {
- clearTimeout(this.failureTimeout_);
- this.failureTimeout_ = null;
- }
-
- FileManagerDialogBase.prototype.hide.call(
- this,
- function() {
- if (opt_onHide)
- opt_onHide();
- this.callback_(result);
- this.callback_ = null;
- }.bind(this));
-};
-
-/**
- * Shows the dialog.
- * @param {FileEntry} entry Entry to share.
- * @param {function(boolean)} callback Callback to be called when the showing
- * task is completed. The argument is whether to succeed or not. Note that
- * cancel is regarded as success.
- */
-ShareDialog.prototype.show = function(entry, callback) {
- // If the dialog is already showing, return the error.
- if (this.isShowing()) {
- callback(ShareDialog.Result.ALREADY_SHOWING);
- return;
- }
-
- // Initialize the variables.
- this.callback_ = callback;
- this.spinnerLayer_.hidden = false;
- this.webViewWrapper_.style.width = '';
- this.webViewWrapper_.style.height = '';
-
- // If the embedded share dialog is not started within some time, then
- // give up and show an error message.
- this.failureTimeout_ = setTimeout(function() {
- this.hideWithResult(ShareDialog.Result.NETWORK_ERROR);
-
- // Logs added temporarily to track crbug.com/288783.
- console.debug('Timeout. Web View points at: ' + this.webView_.src);
- }.bind(this), ShareDialog.FAILURE_TIMEOUT);
-
- // TODO(mtomasz): Move to initDom_() once and reuse <webview> once it gets
- // fixed. See: crbug.com/260622.
- this.webView_ = util.createChild(
- this.webViewWrapper_, 'share-dialog-webview', 'webview');
- this.webView_.setAttribute('tabIndex', '-1');
- this.webViewAuthorizer_ = new ShareDialog.WebViewAuthorizer(
- !window.IN_TEST ? (ShareClient.SHARE_TARGET + '/*') : '<all_urls>',
- this.webView_);
- this.webView_.addEventListener('newwindow', function(e) {
- // Discard the window object and reopen in an external window.
- e.window.discard();
- util.visitURL(e.targetUrl);
- e.preventDefault();
- });
- var show = FileManagerDialogBase.prototype.showBlankDialog.call(this);
- if (!show) {
- // The code shoundn't get here, since already-showing was handled before.
- console.error('ShareDialog can\'t be shown.');
- return;
- }
-
- // Initialize and authorize the Web View tag asynchronously.
- var group = new AsyncUtil.Group();
-
- // Fetches an url to the sharing dialog.
- var shareUrl;
- group.add(function(inCallback) {
- chrome.fileBrowserPrivate.getShareUrl(
- entry.toURL(),
- function(inShareUrl) {
- if (!chrome.runtime.lastError)
- shareUrl = inShareUrl;
- inCallback();
- });
- });
- group.add(this.webViewAuthorizer_.initialize.bind(this.webViewAuthorizer_));
- group.add(this.webViewAuthorizer_.authorize.bind(this.webViewAuthorizer_));
-
- // Loads the share widget once all the previous async calls are finished.
- group.run(function() {
- // If the url is not obtained, return the network error.
- if (!shareUrl) {
- // Logs added temporarily to track crbug.com/288783.
- console.debug('URL not available.');
-
- this.hideWithResult(ShareDialog.Result.NETWORK_ERROR);
- return;
- }
- // Already inactive, therefore ignore.
- if (!this.isShowing())
- return;
- this.shareClient_ = new ShareClient(this.webView_,
- shareUrl,
- this);
- this.shareClient_.load();
- }.bind(this));
-};
-
-/**
- * Tells whether the share dialog is showing or not.
- *
- * @return {boolean} True since the show method is called and until the closing
- * callback is invoked.
- */
-ShareDialog.prototype.isShowing = function() {
- return !!this.callback_;
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/suggest_apps_dialog.js b/chromium/chrome/browser/resources/file_manager/foreground/js/suggest_apps_dialog.js
deleted file mode 100644
index 27d12dfe19b..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/suggest_apps_dialog.js
+++ /dev/null
@@ -1,554 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * SuggestAppsDialog contains a list box to select an app to be opened the file
- * with. This dialog should be used as action picker for file operations.
- */
-
-/**
- * The width of the widget (in pixel).
- * @type {number}
- * @const
- */
-var WEBVIEW_WIDTH = 735;
-/**
- * The height of the widget (in pixel).
- * @type {number}
- * @const
- */
-var WEBVIEW_HEIGHT = 480;
-
-/**
- * The URL of the widget.
- * @type {string}
- * @const
- */
-var CWS_WIDGET_URL =
- 'https://clients5.google.com/webstore/wall/cros-widget-container';
-/**
- * The origin of the widget.
- * @type {string}
- * @const
- */
-var CWS_WIDGET_ORIGIN = 'https://clients5.google.com';
-
-/**
- * Creates dialog in DOM tree.
- *
- * @param {HTMLElement} parentNode Node to be parent for this dialog.
- * @param {Object} state Static state of suggest app dialog.
- * @constructor
- * @extends {FileManagerDialogBase}
- */
-function SuggestAppsDialog(parentNode, state) {
- FileManagerDialogBase.call(this, parentNode);
-
- this.frame_.id = 'suggest-app-dialog';
-
- this.webviewContainer_ = this.document_.createElement('div');
- this.webviewContainer_.id = 'webview-container';
- this.webviewContainer_.style.width = WEBVIEW_WIDTH + 'px';
- this.webviewContainer_.style.height = WEBVIEW_HEIGHT + 'px';
- this.frame_.insertBefore(this.webviewContainer_, this.text_.nextSibling);
-
- var spinnerLayer = this.document_.createElement('div');
- spinnerLayer.className = 'spinner-layer';
- this.webviewContainer_.appendChild(spinnerLayer);
-
- this.buttons_ = this.document_.createElement('div');
- this.buttons_.id = 'buttons';
- this.frame_.appendChild(this.buttons_);
-
- this.webstoreButton_ = this.document_.createElement('div');
- this.webstoreButton_.id = 'webstore-button';
- this.webstoreButton_.innerHTML = str('SUGGEST_DIALOG_LINK_TO_WEBSTORE');
- this.webstoreButton_.addEventListener(
- 'click', this.onWebstoreLinkClicked_.bind(this));
- this.buttons_.appendChild(this.webstoreButton_);
-
- this.initialFocusElement_ = this.webviewContainer_;
-
- this.webview_ = null;
- this.accessToken_ = null;
- this.widgetUrl_ =
- state.overrideCwsContainerUrlForTest || CWS_WIDGET_URL;
- this.widgetOrigin_ =
- state.overrideCwsContainerOriginForTest || CWS_WIDGET_ORIGIN;
-
- this.extension_ = null;
- this.mime_ = null;
- this.installingItemId_ = null;
- this.state_ = SuggestAppsDialog.State.UNINITIALIZED;
-
- this.initializationTask_ = new AsyncUtil.Group();
- this.initializationTask_.add(this.retrieveAuthorizeToken_.bind(this));
- this.initializationTask_.run();
-}
-
-SuggestAppsDialog.prototype = {
- __proto__: FileManagerDialogBase.prototype
-};
-
-/**
- * @enum {string}
- * @const
- */
-SuggestAppsDialog.State = {
- UNINITIALIZED: 'SuggestAppsDialog.State.UNINITIALIZED',
- INITIALIZING: 'SuggestAppsDialog.State.INITIALIZING',
- INITIALIZE_FAILED_CLOSING:
- 'SuggestAppsDialog.State.INITIALIZE_FAILED_CLOSING',
- INITIALIZED: 'SuggestAppsDialog.State.INITIALIZED',
- INSTALLING: 'SuggestAppsDialog.State.INSTALLING',
- INSTALLED_CLOSING: 'SuggestAppsDialog.State.INSTALLED_CLOSING',
- OPENING_WEBSTORE_CLOSING: 'SuggestAppsDialog.State.OPENING_WEBSTORE_CLOSING',
- CANCELED_CLOSING: 'SuggestAppsDialog.State.CANCELED_CLOSING'
-};
-Object.freeze(SuggestAppsDialog.State);
-
-/**
- * @enum {string}
- * @const
- */
-SuggestAppsDialog.Result = {
- // Install is done. The install app should be opened.
- INSTALL_SUCCESSFUL: 'SuggestAppsDialog.Result.INSTALL_SUCCESSFUL',
- // User cancelled the suggest app dialog. No message should be shown.
- USER_CANCELL: 'SuggestAppsDialog.Result.USER_CANCELL',
- // User clicked the link to web store so the dialog is closed.
- WEBSTORE_LINK_OPENED: 'SuggestAppsDialog.Result.WEBSTORE_LINK_OPENED',
- // Failed to load the widget. Error message should be shown.
- FAILED: 'SuggestAppsDialog.Result.FAILED'
-};
-Object.freeze(SuggestAppsDialog.Result);
-
-/**
- * @override
- */
-SuggestAppsDialog.prototype.onInputFocus = function() {
- this.webviewContainer_.select();
-};
-
-/**
- * Injects headers into the passed request.
- *
- * @param {Event} e Request event.
- * @return {{requestHeaders: HttpHeaders}} Modified headers.
- * @private
- */
-SuggestAppsDialog.prototype.authorizeRequest_ = function(e) {
- e.requestHeaders.push({
- name: 'Authorization',
- value: 'Bearer ' + this.accessToken_
- });
- return {requestHeaders: e.requestHeaders};
-};
-
-/**
- * Retrieves the authorize token. This method should be called in
- * initialization of the dialog.
- *
- * @param {function()} callback Called when the token is retrieved.
- * @private
- */
-SuggestAppsDialog.prototype.retrieveAuthorizeToken_ = function(callback) {
- if (window.IN_TEST) {
- // In test, use a dummy string as token. This must be a non-empty string.
- this.accessToken_ = 'DUMMY_ACCESS_TOKEN_FOR_TEST';
- }
-
- if (this.accessToken_) {
- callback();
- return;
- }
-
- // Fetch or update the access token.
- chrome.fileBrowserPrivate.requestWebStoreAccessToken(
- function(accessToken) {
- // In case of error, this.accessToken_ will be set to null.
- this.accessToken_ = accessToken;
- callback();
- }.bind(this));
-};
-
-/**
- * Dummy function for SuggestAppsDialog.show() not to be called unintentionally.
- */
-SuggestAppsDialog.prototype.show = function() {
- console.error('SuggestAppsDialog.show() shouldn\'t be called directly.');
-};
-
-/**
- * Shows suggest-apps dialog by file extension and mime.
- *
- * @param {string} extension Extension of the file.
- * @param {string} mime Mime of the file.
- * @param {function(boolean)} onDialogClosed Called when the dialog is closed.
- * The argument is the result of installation: true if an app is installed,
- * false otherwise.
- */
-SuggestAppsDialog.prototype.showByExtensionAndMime =
- function(extension, mime, onDialogClosed) {
- this.text_.hidden = true;
- this.dialogText_ = '';
- this.showInternal_(null, extension, mime, onDialogClosed);
-};
-
-/**
- * Shows suggest-apps dialog by the filename.
- *
- * @param {string} filename Filename (without extension) of the file.
- * @param {function(boolean)} onDialogClosed Called when the dialog is closed.
- * The argument is the result of installation: true if an app is installed,
- * false otherwise.
- */
-SuggestAppsDialog.prototype.showByFilename =
- function(filename, onDialogClosed) {
- this.text_.hidden = false;
- this.dialogText_ = str('SUGGEST_DIALOG_MESSAGE_FOR_EXECUTABLE');
- this.showInternal_(filename, null, null, onDialogClosed);
-};
-
-/**
- * Internal methdo to shows a dialog. This should be called only from 'Suggest.
- * appDialog.showXxxx()' functions.
- *
- * @param {string} filename Filename (without extension) of the file.
- * @param {string} extension Extension of the file.
- * @param {string} mime Mime of the file.
- * @param {function(boolean)} onDialogClosed Called when the dialog is closed.
- * The argument is the result of installation: true if an app is installed,
- * false otherwise.
- * @private
- */
-SuggestAppsDialog.prototype.showInternal_ =
- function(filename, extension, mime, onDialogClosed) {
- if (this.state_ != SuggestAppsDialog.State.UNINITIALIZED) {
- console.error('Invalid state.');
- return;
- }
-
- this.extension_ = extension;
- this.mimeType_ = mime;
- this.onDialogClosed_ = onDialogClosed;
- this.state_ = SuggestAppsDialog.State.INITIALIZING;
-
- SuggestAppsDialog.Metrics.recordShowDialog();
- SuggestAppsDialog.Metrics.startLoad();
-
- // Makes it sure that the initialization is completed.
- this.initializationTask_.run(function() {
- if (!this.accessToken_) {
- this.state_ = SuggestAppsDialog.State.INITIALIZE_FAILED_CLOSING;
- this.onHide_();
- return;
- }
-
- var title = str('SUGGEST_DIALOG_TITLE');
- var show = this.dialogText_ ?
- FileManagerDialogBase.prototype.showTitleAndTextDialog.call(
- this, title, this.dialogText_) :
- FileManagerDialogBase.prototype.showTitleOnlyDialog.call(
- this, title);
- if (!show) {
- console.error('SuggestAppsDialog can\'t be shown');
- this.state_ = SuggestAppsDialog.State.UNINITIALIZED;
- this.onHide();
- return;
- }
-
- this.webview_ = this.document_.createElement('webview');
- this.webview_.id = 'cws-widget';
- this.webview_.partition = 'persist:cwswidgets';
- this.webview_.style.width = WEBVIEW_WIDTH + 'px';
- this.webview_.style.height = WEBVIEW_HEIGHT + 'px';
- this.webview_.request.onBeforeSendHeaders.addListener(
- this.authorizeRequest_.bind(this),
- {urls: [this.widgetOrigin_ + '/*']},
- ['blocking', 'requestHeaders']);
- this.webview_.addEventListener('newwindow', function(event) {
- // Discard the window object and reopen in an external window.
- event.window.discard();
- util.visitURL(event.targetUrl);
- event.preventDefault();
- });
- this.webviewContainer_.appendChild(this.webview_);
-
- this.frame_.classList.add('show-spinner');
-
- this.webviewClient_ = new CWSContainerClient(
- this.webview_,
- extension, mime, filename,
- WEBVIEW_WIDTH, WEBVIEW_HEIGHT,
- this.widgetUrl_, this.widgetOrigin_);
- this.webviewClient_.addEventListener(CWSContainerClient.Events.LOADED,
- this.onWidgetLoaded_.bind(this));
- this.webviewClient_.addEventListener(CWSContainerClient.Events.LOAD_FAILED,
- this.onWidgetLoadFailed_.bind(this));
- this.webviewClient_.addEventListener(
- CWSContainerClient.Events.REQUEST_INSTALL,
- this.onInstallRequest_.bind(this));
- this.webviewClient_.load();
- }.bind(this));
-};
-
-/**
- * Called when the 'See more...' link is clicked to be navigated to Webstore.
- * @param {Event} e Event.
- * @private
- */
-SuggestAppsDialog.prototype.onWebstoreLinkClicked_ = function(e) {
- var webStoreUrl =
- FileTasks.createWebStoreLink(this.extension_, this.mimeType_);
- chrome.windows.create({url: webStoreUrl});
- this.state_ = SuggestAppsDialog.State.OPENING_WEBSTORE_CLOSING;
- this.hide();
-};
-
-/**
- * Called when the widget is loaded successfully.
- * @param {Event} event Event.
- * @private
- */
-SuggestAppsDialog.prototype.onWidgetLoaded_ = function(event) {
- SuggestAppsDialog.Metrics.finishLoad();
- SuggestAppsDialog.Metrics.recordLoad(
- SuggestAppsDialog.Metrics.LOAD.SUCCEEDED);
-
- this.frame_.classList.remove('show-spinner');
- this.state_ = SuggestAppsDialog.State.INITIALIZED;
-
- this.webview_.focus();
-};
-
-/**
- * Called when the widget is failed to load.
- * @param {Event} event Event.
- * @private
- */
-SuggestAppsDialog.prototype.onWidgetLoadFailed_ = function(event) {
- SuggestAppsDialog.Metrics.recordLoad(SuggestAppsDialog.Metrics.LOAD.FAILURE);
-
- this.frame_.classList.remove('show-spinner');
- this.state_ = SuggestAppsDialog.State.INITIALIZE_FAILED_CLOSING;
-
- this.hide();
-};
-
-/**
- * Called when the connection status is changed.
- * @param {util.DriveConnectionType} connectionType Current connection type.
- */
-SuggestAppsDialog.prototype.onDriveConnectionChanged =
- function(connectionType) {
- if (this.state_ !== SuggestAppsDialog.State.UNINITIALIZED &&
- connectionType === util.DriveConnectionType.OFFLINE) {
- this.state_ = SuggestAppsDialog.State.INITIALIZE_FAILED_CLOSING;
- this.hide();
- }
-};
-
-/**
- * Called when receiving the install request from the webview client.
- * @param {Event} e Event.
- * @private
- */
-SuggestAppsDialog.prototype.onInstallRequest_ = function(e) {
- var itemId = e.itemId;
- this.installingItemId_ = itemId;
-
- this.appInstaller_ = new AppInstaller(itemId);
- this.appInstaller_.install(this.onInstallCompleted_.bind(this));
-
- this.frame_.classList.add('show-spinner');
- this.state_ = SuggestAppsDialog.State.INSTALLING;
-};
-
-/**
- * Called when the installation is completed from the app installer.
- * @param {AppInstaller.Result} result Result of the installation.
- * @param {string} error Detail of the error.
- * @private
- */
-SuggestAppsDialog.prototype.onInstallCompleted_ = function(result, error) {
- var success = (result === AppInstaller.Result.SUCCESS);
-
- this.frame_.classList.remove('show-spinner');
- this.state_ = success ?
- SuggestAppsDialog.State.INSTALLED_CLOSING :
- SuggestAppsDialog.State.INITIALIZED; // Back to normal state.
- this.webviewClient_.onInstallCompleted(success, this.installingItemId_);
- this.installingItemId_ = null;
-
- switch (result) {
- case AppInstaller.Result.SUCCESS:
- SuggestAppsDialog.Metrics.recordInstall(
- SuggestAppsDialog.Metrics.INSTALL.SUCCESS);
- this.hide();
- break;
- case AppInstaller.Result.CANCELLED:
- SuggestAppsDialog.Metrics.recordInstall(
- SuggestAppsDialog.Metrics.INSTALL.CANCELLED);
- // User cancelled the installation. Do nothing.
- break;
- case AppInstaller.Result.ERROR:
- SuggestAppsDialog.Metrics.recordInstall(
- SuggestAppsDialog.Metrics.INSTALL.FAILED);
- fileManager.error.show(str('SUGGEST_DIALOG_INSTALLATION_FAILED'));
- break;
- }
-};
-
-/**
- * @override
- */
-SuggestAppsDialog.prototype.hide = function(opt_originalOnHide) {
- switch (this.state_) {
- case SuggestAppsDialog.State.INSTALLING:
- // Install is being aborted. Send the failure result.
- // Cancels the install.
- if (this.webviewClient_)
- this.webviewClient_.onInstallCompleted(false, this.installingItemId_);
- this.installingItemId_ = null;
-
- // Assumes closing the dialog as canceling the install.
- this.state_ = SuggestAppsDialog.State.CANCELED_CLOSING;
- break;
- case SuggestAppsDialog.State.INITIALIZING:
- SuggestAppsDialog.Metrics.recordLoad(
- SuggestAppsDialog.Metrics.LOAD.CANCELLED);
- this.state_ = SuggestAppsDialog.State.CANCELED_CLOSING;
- break;
- case SuggestAppsDialog.State.INSTALLED_CLOSING:
- case SuggestAppsDialog.State.INITIALIZE_FAILED_CLOSING:
- case SuggestAppsDialog.State.OPENING_WEBSTORE_CLOSING:
- // Do nothing.
- break;
- case SuggestAppsDialog.State.INITIALIZED:
- this.state_ = SuggestAppsDialog.State.CANCELED_CLOSING;
- break;
- default:
- this.state_ = SuggestAppsDialog.State.CANCELED_CLOSING;
- console.error('Invalid state.');
- }
-
- if (this.webviewClient_) {
- this.webviewClient_.dispose();
- this.webviewClient_ = null;
- }
-
- this.webviewContainer_.removeChild(this.webview_);
- this.webview_ = null;
- this.extension_ = null;
- this.mime_ = null;
-
- FileManagerDialogBase.prototype.hide.call(
- this,
- this.onHide_.bind(this, opt_originalOnHide));
-};
-
-/**
- * @param {function()=} opt_originalOnHide Original onHide function passed to
- * SuggestAppsDialog.hide().
- * @private
- */
-SuggestAppsDialog.prototype.onHide_ = function(opt_originalOnHide) {
- // Calls the callback after the dialog hides.
- if (opt_originalOnHide)
- opt_originalOnHide();
-
- var result;
- switch (this.state_) {
- case SuggestAppsDialog.State.INSTALLED_CLOSING:
- result = SuggestAppsDialog.Result.INSTALL_SUCCESSFUL;
- SuggestAppsDialog.Metrics.recordCloseDialog(
- SuggestAppsDialog.Metrics.CLOSE_DIALOG.ITEM_INSTALLED);
- break;
- case SuggestAppsDialog.State.INITIALIZE_FAILED_CLOSING:
- result = SuggestAppsDialog.Result.FAILED;
- break;
- case SuggestAppsDialog.State.CANCELED_CLOSING:
- result = SuggestAppsDialog.Result.USER_CANCELL;
- SuggestAppsDialog.Metrics.recordCloseDialog(
- SuggestAppsDialog.Metrics.CLOSE_DIALOG.USER_CANCELL);
- break;
- case SuggestAppsDialog.State.OPENING_WEBSTORE_CLOSING:
- result = SuggestAppsDialog.Result.WEBSTORE_LINK_OPENED;
- SuggestAppsDialog.Metrics.recordCloseDialog(
- SuggestAppsDialog.Metrics.CLOSE_DIALOG.WEB_STORE_LINK);
- break;
- default:
- result = SuggestAppsDialog.Result.USER_CANCELL;
- SuggestAppsDialog.Metrics.recordCloseDialog(
- SuggestAppsDialog.Metrics.CLOSE_DIALOG.UNKNOWN_ERROR);
- console.error('Invalid state.');
- }
- this.state_ = SuggestAppsDialog.State.UNINITIALIZED;
-
- this.onDialogClosed_(result);
-};
-
-/**
- * Utility methods and constants to record histograms.
- */
-SuggestAppsDialog.Metrics = Object.freeze({
- LOAD: Object.freeze({
- SUCCEEDED: 0,
- CANCELLED: 1,
- FAILED: 2,
- }),
-
- /**
- * @param {SuggestAppsDialog.Metrics.LOAD} result Result of load.
- */
- recordLoad: function(result) {
- if (0 <= result && result < 3)
- metrics.recordEnum('SuggestApps.Load', result, 3);
- },
-
- CLOSE_DIALOG: Object.freeze({
- UNKOWN_ERROR: 0,
- ITEM_INSTALLED: 1,
- USER_CANCELLED: 2,
- WEBSTORE_LINK_OPENED: 3,
- }),
-
- /**
- * @param {SuggestAppsDialog.Metrics.CLOSE_DIALOG} reason Reason of closing
- * dialog.
- */
- recordCloseDialog: function(reason) {
- if (0 <= reason && reason < 4)
- metrics.recordEnum('SuggestApps.CloseDialog', reason, 4);
- },
-
- INSTALL: Object.freeze({
- SUCCEEDED: 0,
- CANCELLED: 1,
- FAILED: 2,
- }),
-
- /**
- * @param {SuggestAppsDialog.Metrics.INSTALL} result Result of installation.
- */
- recordInstall: function(result) {
- if (0 <= result && result < 3)
- metrics.recordEnum('SuggestApps.Install', result, 3);
- },
-
- recordShowDialog: function() {
- metrics.recordUserAction('SuggestApps.ShowDialog');
- },
-
- startLoad: function() {
- metrics.startInterval('SuggestApps.LoadTime');
- },
-
- finishLoad: function() {
- metrics.recordInterval('SuggestApps.LoadTime');
- },
-});
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/text_measure.js b/chromium/chrome/browser/resources/file_manager/foreground/js/text_measure.js
deleted file mode 100644
index a8db83ae582..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/text_measure.js
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * TextMeasure constructor.
- *
- * TextMeasure is a measure for text that returns the width of text. This
- * class has a dummy span element. When measuring the width of text, it sets
- * the text to the element and obtains the element's size by
- * getBoundingClientRect.
- *
- * @constructor
- * @param {HTMLElement} element Element that has styles of measured text. The
- * width of text is measures like as it is rendered in this element.
- */
-var TextMeasure = function(element) {
- var doc = element.ownerDocument;
- this.dummySpan_ = doc.createElement('span');
- this.dummySpan_ = doc.getElementsByTagName('body')[0].
- appendChild(this.dummySpan_);
- this.dummySpan_.style.position = 'absolute';
- this.dummySpan_.style.visibility = 'hidden';
- var styles = window.getComputedStyle(element, '');
- var stylesToBeCopied = [
- 'fontSize',
- 'fontStyle',
- 'fontWeight',
- 'fontFamily',
- 'letterSpacing'
- ];
- for (var i = 0; i < stylesToBeCopied.length; i++) {
- this.dummySpan_.style[stylesToBeCopied[i]] = styles[stylesToBeCopied[i]];
- }
- Object.seal(this);
-};
-
-/**
- * Measures the width of text.
- *
- * @param {string} text Text that is measured the width.
- * @return {number} Width of the specified text.
- */
-TextMeasure.prototype.getWidth = function(text) {
- this.dummySpan_.innerText = text;
- var rect = this.dummySpan_.getBoundingClientRect();
- return rect ? rect.width : 0;
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/tree.css.js b/chromium/chrome/browser/resources/file_manager/foreground/js/tree.css.js
deleted file mode 100644
index 6b89acbdb86..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/tree.css.js
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Custom version of chrome://resources/css/tree.css.js, adding support for
- * inverted arrow icons.
- */
-(function() {
- /**
- * @type {number}
- * @const
- */
- var WIDTH = 14;
-
- /**
- * @type {number}
- * @const
- */
- var HEIGHT = WIDTH / 2 + 2;
-
- /**
- * @type {number}
- * @const
- */
- var MARGIN = 1;
-
- /**
- * @param {string} name CSS canvas identifier.
- * @param {string} backgroundColor Background color.
- * @param {string} strokeColor Outline color.
- */
- function prepareTriangle(name, backgroundColor, strokeColor) {
- var ctx = document.getCSSCanvasContext('2d',
- name,
- WIDTH + MARGIN * 2,
- HEIGHT + MARGIN * 2);
-
- ctx.fillStyle = backgroundColor;
- ctx.strokeStyle = strokeColor;
- ctx.translate(MARGIN, MARGIN);
-
- ctx.beginPath();
- ctx.moveTo(0, 0);
- ctx.lineTo(0, 2);
- ctx.lineTo(WIDTH / 2, HEIGHT);
- ctx.lineTo(WIDTH, 2);
- ctx.lineTo(WIDTH, 0);
- ctx.closePath();
- ctx.fill();
- ctx.stroke();
- }
-
- prepareTriangle(
- 'tree-triangle', 'rgba(122, 122, 122, 0.6)', 'rgba(0, 0, 0, 0)');
- prepareTriangle('tree-triangle-inverted', '#ffffff', '#ffffff');
-})();
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/ui/breadcrumbs_controller.js b/chromium/chrome/browser/resources/file_manager/foreground/js/ui/breadcrumbs_controller.js
deleted file mode 100644
index 4189ef9ea0b..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/ui/breadcrumbs_controller.js
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * @extends cr.EventTarget
- * @param {HTMLDivElement} div Div container for breadcrumbs.
- * @param {MetadataCache} metadataCache To retrieve metadata.
- * @param {VolumeManagerWrapper} volumeManager Volume manager.
- * @constructor
- */
-function BreadcrumbsController(div, metadataCache, volumeManager) {
- this.bc_ = div;
- this.metadataCache_ = metadataCache;
- this.volumeManager_ = volumeManager;
- this.entry_ = null;
-
- /**
- * Sequence value to skip requests that are out of date.
- * @type {number}
- * @private
- */
- this.showSequence_ = 0;
-
- // Register events and seql the object.
- div.addEventListener('click', this.onClick_.bind(this));
-}
-
-/**
- * Extends cr.EventTarget.
- */
-BreadcrumbsController.prototype.__proto__ = cr.EventTarget.prototype;
-
-/**
- * Shows breadcrumbs.
- *
- * @param {Entry} entry Target entry.
- */
-BreadcrumbsController.prototype.show = function(entry) {
- if (entry === this.entry_)
- return;
-
- this.entry_ = entry;
- this.bc_.hidden = false;
- this.bc_.textContent = '';
- this.showSequence_++;
-
- var queue = new AsyncUtil.Queue();
- var entries = [];
- var error = false;
-
- // Obtain entries from the target entry to the root.
- var loop;
- var resolveParent = function(inEntry, callback) {
- entries.unshift(inEntry);
- if (!this.volumeManager_.getLocationInfo(inEntry).isRootEntry) {
- inEntry.getParent(function(parent) {
- resolveParent(parent, callback);
- }, function() {
- error = true;
- callback();
- });
- } else {
- callback();
- }
- }.bind(this);
- queue.run(resolveParent.bind(null, entry));
-
- // Override DRIVE_OTHER root to DRIVE_SHARED_WITH_ME root.
- queue.run(function(callback) {
- // If an error was occured, just skip.
- if (error) {
- callback();
- return;
- }
-
- // If the path is not under the drive other root, it is not needed to
- // override root type.
- var locationInfo = this.volumeManager_.getLocationInfo(entry);
- if (!locationInfo) {
- error = true;
- callback();
- return;
- }
- if (locationInfo.rootType !== RootType.DRIVE_OTHER) {
- callback();
- return;
- }
-
- // Otherwise check the metadata of the directory localted at just under
- // drive other.
- if (!entries[1]) {
- error = true;
- callback();
- return;
- }
- this.metadataCache_.getOne(entries[1], 'drive', function(result) {
- if (result && result.sharedWithMe)
- entries[0] = RootType.DRIVE_SHARED_WITH_ME;
- else
- entries.shift();
- callback();
- });
- }.bind(this));
-
- // Update DOM element.
- queue.run(function(sequence, callback) {
- // Check the sequence number to skip requests that are out of date.
- if (this.showSequence_ === sequence && !error)
- this.updateInternal_(entries);
- callback();
- }.bind(this, this.showSequence_));
-};
-
-/**
- * Updates the breadcrumb display.
- * @param {Array.<Entry|RootType>} entries Location information of target path.
- * @private
- */
-BreadcrumbsController.prototype.updateInternal_ = function(entries) {
- // Make elements.
- var doc = this.bc_.ownerDocument;
- for (var i = 0; i < entries.length; i++) {
- // Add a component.
- var entry = entries[i];
- var div = doc.createElement('div');
- div.className = 'breadcrumb-path';
- if (entry === RootType.DRIVE_SHARED_WITH_ME) {
- div.textContent = PathUtil.getRootLabel(RootType.DRIVE_SHARED_WITH_ME);
- } else {
- var location = this.volumeManager_.getLocationInfo(entry);
- div.textContent = (location && location.isRootEntry) ?
- PathUtil.getRootLabel(entry.fullPath) : entry.name;
- }
- div.entry = entry;
- this.bc_.appendChild(div);
-
- // If this is the last component, break here.
- if (i === entries.length - 1) {
- div.classList.add('breadcrumb-last');
- break;
- }
-
- // Add a separator.
- var separator = doc.createElement('div');
- separator.className = 'separator';
- this.bc_.appendChild(separator);
- }
-
- this.truncate();
-};
-
-/**
- * Updates breadcrumbs widths in order to truncate it properly.
- */
-BreadcrumbsController.prototype.truncate = function() {
- if (!this.bc_.firstChild)
- return;
-
- // Assume style.width == clientWidth (items have no margins or paddings).
-
- for (var item = this.bc_.firstChild; item; item = item.nextSibling) {
- item.removeAttribute('style');
- item.removeAttribute('collapsed');
- }
-
- var containerWidth = this.bc_.clientWidth;
-
- var pathWidth = 0;
- var currentWidth = 0;
- var lastSeparator;
- for (var item = this.bc_.firstChild; item; item = item.nextSibling) {
- if (item.className == 'separator') {
- pathWidth += currentWidth;
- currentWidth = item.clientWidth;
- lastSeparator = item;
- } else {
- currentWidth += item.clientWidth;
- }
- }
- if (pathWidth + currentWidth <= containerWidth)
- return;
- if (!lastSeparator) {
- this.bc_.lastChild.style.width = Math.min(currentWidth, containerWidth) +
- 'px';
- return;
- }
- var lastCrumbSeparatorWidth = lastSeparator.clientWidth;
- // Current directory name may occupy up to 70% of space or even more if the
- // path is short.
- var maxPathWidth = Math.max(Math.round(containerWidth * 0.3),
- containerWidth - currentWidth);
- maxPathWidth = Math.min(pathWidth, maxPathWidth);
-
- var parentCrumb = lastSeparator.previousSibling;
- var collapsedWidth = 0;
- if (parentCrumb && pathWidth - maxPathWidth > parentCrumb.clientWidth) {
- // At least one crumb is hidden completely (or almost completely).
- // Show sign of hidden crumbs like this:
- // root > some di... > ... > current directory.
- parentCrumb.setAttribute('collapsed', '');
- collapsedWidth = Math.min(maxPathWidth, parentCrumb.clientWidth);
- maxPathWidth -= collapsedWidth;
- if (parentCrumb.clientWidth != collapsedWidth)
- parentCrumb.style.width = collapsedWidth + 'px';
-
- lastSeparator = parentCrumb.previousSibling;
- if (!lastSeparator)
- return;
- collapsedWidth += lastSeparator.clientWidth;
- maxPathWidth = Math.max(0, maxPathWidth - lastSeparator.clientWidth);
- }
-
- pathWidth = 0;
- for (var item = this.bc_.firstChild; item != lastSeparator;
- item = item.nextSibling) {
- // TODO(serya): Mixing access item.clientWidth and modifying style and
- // attributes could cause multiple layout reflows.
- if (pathWidth + item.clientWidth <= maxPathWidth) {
- pathWidth += item.clientWidth;
- } else if (pathWidth == maxPathWidth) {
- item.style.width = '0';
- } else if (item.classList.contains('separator')) {
- // Do not truncate separator. Instead let the last crumb be longer.
- item.style.width = '0';
- maxPathWidth = pathWidth;
- } else {
- // Truncate the last visible crumb.
- item.style.width = (maxPathWidth - pathWidth) + 'px';
- pathWidth = maxPathWidth;
- }
- }
-
- currentWidth = Math.min(currentWidth,
- containerWidth - pathWidth - collapsedWidth);
- this.bc_.lastChild.style.width =
- (currentWidth - lastCrumbSeparatorWidth) + 'px';
-};
-
-/**
- * Hide breadcrumbs div.
- */
-BreadcrumbsController.prototype.hide = function() {
- this.bc_.hidden = true;
-};
-
-/**
- * Handle a click event on a breadcrumb element.
- * @param {Event} event The click event.
- * @private
- */
-BreadcrumbsController.prototype.onClick_ = function(event) {
- if (!event.target.classList.contains('breadcrumb-path') ||
- event.target.classList.contains('breadcrumb-last'))
- return;
-
- var newEvent = new Event('pathclick');
- newEvent.entry = event.target.entry;
- this.dispatchEvent(newEvent);
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/ui/conflict_dialog.js b/chromium/chrome/browser/resources/file_manager/foreground/js/ui/conflict_dialog.js
deleted file mode 100644
index 8aecd737228..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/ui/conflict_dialog.js
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Dialog to confirm the operation for conflicted file operations.
- *
- * @param {HTMLElement} parentNode Node to be parent for this dialog.
- * @constructor
- * @extends {FileManagerDialogBase}
- */
-function ConflictDialog(parentNode) {
- FileManagerDialogBase.call(this, parentNode);
-
- /**
- * Callback to be called when the showing task is completed. The first
- * argument is which button is pressed. The second argument is whether to
- * apply all or not.
- *
- * @type {function(ConflictDialog.Result, boolean)}
- * @private
- */
- this.callback_ = null;
-
- /**
- * Checkbox to specify whether to apply the selection to all entries or not.
- * @type {HTMLElement}
- * @private
- */
- this.applyAllCheckbox_ = parentNode.ownerDocument.createElement('input');
- this.applyAllCheckbox_.id = 'conflict-confirm-dialog-apply-all-checkbox';
- this.applyAllCheckbox_.type = 'checkbox';
-
- // Apply all line.
- var applyAllLabel = parentNode.ownerDocument.createElement('label');
- applyAllLabel.textContent = str('CONFLICT_DIALOG_APPLY_TO_ALL');
- applyAllLabel.setAttribute('for', this.applyAllCheckbox_.id);
-
- /**
- * Element of the keep both button.
- * @type {HTMLElement}
- * @private
- */
- this.keepBothButton_ = parentNode.ownerDocument.createElement('button');
- this.keepBothButton_.textContent = str('CONFLICT_DIALOG_KEEP_BOTH');
- this.keepBothButton_.addEventListener(
- 'click',
- this.hideWithResult_.bind(this, ConflictDialog.Result.KEEP_BOTH));
-
- /**
- * Element of the replace button.
- * @type {HTMLElement}
- * @private
- */
- this.replaceButton_ = parentNode.ownerDocument.createElement('button');
- this.replaceButton_.textContent = str('CONFLICT_DIALOG_REPLACE');
- this.replaceButton_.addEventListener(
- 'click',
- this.hideWithResult_.bind(this, ConflictDialog.Result.REPLACE));
-
- // Buttons line.
- var buttons = this.okButton_.parentNode;
- buttons.insertBefore(this.applyAllCheckbox_, this.okButton_);
- buttons.insertBefore(applyAllLabel, this.okButton_);
- buttons.replaceChild(this.keepBothButton_, this.okButton_);
- buttons.appendChild(this.replaceButton_);
-
- // Frame
- this.frame_.id = 'conflict-confirm-dialog';
-}
-
-/**
- * Result of conflict confirm dialogs.
- * @enum {string}
- * @const
- */
-ConflictDialog.Result = Object.freeze({
- KEEP_BOTH: 'keepBoth',
- CANCEL: 'cancel',
- REPLACE: 'replace'
-});
-
-ConflictDialog.prototype = {
- __proto__: FileManagerDialogBase.prototype
-};
-
-/**
- * Shows the conflict confirm dialog.
- *
- * @param {string} fileName Filename that is conflicted.
- * @param {function(ConflictDialog.Result, boolean)} callback Complete
- * callbak. See also ConflictDialog#callback_.
- * @return {boolean} True if the dialog can show successfully. False if the
- * dialog failed to show due to an existing dialog.
- */
-ConflictDialog.prototype.show = function(fileName, callback) {
- if (this.callback_)
- return false;
-
- this.callback_ = callback;
- FileManagerDialogBase.prototype.showOkCancelDialog.call(
- this,
- '', // We dont't show the title for the dialog.
- strf('CONFLICT_DIALOG_MESSAGE', fileName));
- return true;
-};
-
-/**
- * Handles cancellation.
- * @param {Event} event Click event.
- * @private
- */
-ConflictDialog.prototype.onCancelClick_ = function(event) {
- this.hideWithResult_(ConflictDialog.Result.CANCEL);
-};
-
-/**
- * Hides the dialog box with the result.
- * @param {ConflictDialog.Result} result Result.
- * @private
- */
-ConflictDialog.prototype.hideWithResult_ = function(result) {
- this.hide(function() {
- if (!this.callback_)
- return;
- this.callback_(result, this.applyAllCheckbox_.checked);
- this.callback_ = null;
- this.applyAllCheckbox_.checked = false;
- }.bind(this));
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/ui/file_manager_dialog_base.js b/chromium/chrome/browser/resources/file_manager/foreground/js/ui/file_manager_dialog_base.js
deleted file mode 100644
index 63b856f087f..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/ui/file_manager_dialog_base.js
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * This class is an extended class, to manage the status of the dialogs.
- *
- * @param {HTMLElement} parentNode Parent node of the dialog.
- * @extends {cr.ui.dialogs.FileManagerDialogBase}
- * @constructor
- */
-var FileManagerDialogBase = function(parentNode) {
- cr.ui.dialogs.BaseDialog.call(this, parentNode);
-};
-
-FileManagerDialogBase.prototype = {
- __proto__: cr.ui.dialogs.BaseDialog.prototype
-};
-
-/**
- * The FileManager object. This is used to notify events of showing or hiding
- * dialog to file manager.
- *
- * @type {FileManager}
- * @private
- */
-FileManagerDialogBase.fileManager_ = null;
-
-/**
- * Setter of FileManagerDialogBase.fileManager_.
- * @param {FileManager} fileManager The fileManager object.
- */
-FileManagerDialogBase.setFileManager = function(fileManager) {
- FileManagerDialogBase.fileManager_ = fileManager;
-};
-
-/**
- * The flag if any dialog is shown. True if a dialog is visible, false
- * otherwise.
- * @type {boolean}
- */
-FileManagerDialogBase.shown = false;
-
-/**
- * @param {string} title Title.
- * @param {string} message Message.
- * @param {function()} onOk Called when the OK button is pressed.
- * @param {function()} onCancel Called when the cancel button is pressed.
- * @return {boolean} True if the dialog can show successfully. False if the
- * dialog failed to show due to an existing dialog.
- */
-FileManagerDialogBase.prototype.showOkCancelDialog = function(
- title, message, onOk, onCancel) {
- return this.showImpl_(title, message, onOk, onCancel);
-};
-
-/**
- * @param {string} title Title.
- * @param {string} message Message.
- * @param {function()} onOk Called when the OK button is pressed.
- * @param {function()} onCancel Called when the cancel button is pressed.
- * @return {boolean} True if the dialog can show successfully. False if the
- * dialog failed to show due to an existing dialog.
- * @private
- */
-FileManagerDialogBase.prototype.showImpl_ = function(
- title, message, onOk, onCancel) {
- if (FileManagerDialogBase.shown)
- return false;
-
- FileManagerDialogBase.shown = true;
- if (FileManagerDialogBase.fileManager_)
- FileManagerDialogBase.fileManager_.onDialogShownOrHidden(true);
- cr.ui.dialogs.BaseDialog.prototype.showWithTitle.call(
- this, title, message, onOk, onCancel, null);
-
- return true;
-};
-
-/**
- * @return {boolean} True if the dialog can show successfully. False if the
- * dialog failed to show due to an existing dialog.
- */
-FileManagerDialogBase.prototype.showBlankDialog = function() {
- return this.showImpl_('', '', null, null, null);
-};
-
-/**
- * @param {string} title Title.
- * @return {boolean} True if the dialog can show successfully. False if the
- * dialog failed to show due to an existing dialog.
- */
-FileManagerDialogBase.prototype.showTitleOnlyDialog = function(title) {
- return this.showImpl_(title, '', null, null, null);
-};
-
-/**
- * @param {string} title Title.
- * @param {string} text Text to be shown in the dialog.
- * @return {boolean} True if the dialog can show successfully. False if the
- * dialog failed to show due to an existing dialog.
- */
-FileManagerDialogBase.prototype.showTitleAndTextDialog = function(title, text) {
- return this.showImpl_(title, text, null, null, null);
-};
-
-/**
- * @param {function()=} opt_onHide Called when the dialog is hidden.
- */
-FileManagerDialogBase.prototype.hide = function(opt_onHide) {
- cr.ui.dialogs.BaseDialog.prototype.hide.call(
- this,
- function() {
- if (opt_onHide)
- opt_onHide();
- if (FileManagerDialogBase.fileManager_)
- FileManagerDialogBase.fileManager_.onDialogShownOrHidden(false);
- FileManagerDialogBase.shown = false;
- });
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/ui/file_manager_ui.js b/chromium/chrome/browser/resources/file_manager/foreground/js/ui/file_manager_ui.js
deleted file mode 100644
index 1d460f54cdb..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/ui/file_manager_ui.js
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * The root of the file manager's view managing the DOM of Files.app.
- *
- * @param {HTMLElement} element Top level element of Files.app.
- * @param {DialogType} dialogType Dialog type.
- * @constructor.
- */
-var FileManagerUI = function(element, dialogType) {
- /**
- * Top level element of Files.app.
- * @type {HTMLElement}
- * @private
- */
- this.element_ = element;
-
- /**
- * Dialog type.
- * @type {DialogType}
- * @private
- */
- this.dialogType_ = dialogType;
-
- /**
- * Error dialog.
- * @type {ErrorDialog}
- */
- this.errorDialog = null;
-
- /**
- * Alert dialog.
- * @type {cr.ui.dialogs.AlertDialog}
- */
- this.alertDialog = null;
-
- /**
- * Confirm dialog.
- * @type {cr.ui.dialogs.ConfirmDialog}
- */
- this.confirmDialog = null;
-
- /**
- * Prompt dialog.
- * @type {cr.ui.dialogs.PromptDialog}
- */
- this.promptDialog = null;
-
- /**
- * Share dialog.
- * @type {ShareDialog}
- */
- this.shareDialog = null;
-
- /**
- * Default task picker.
- * @type {DefaultActionDialog}
- */
- this.defaultTaskPicker = null;
-
- /**
- * Suggest apps dialog.
- * @type {SuggestAppsDialog}
- */
- this.suggestAppsDialog = null;
-
- /**
- * Conflict dialog.
- * @type {ConflictDialog}
- */
- this.conflictDialog = null;
-
- /**
- * Search box.
- * @type {SearchBox}
- */
- this.searchBox = null;
-
- /**
- * File type selector in the footer.
- * @type {HTMLElement}
- */
- this.fileTypeSelector = null;
-
- /**
- * OK button in the footer.
- * @type {HTMLElement}
- */
- this.okButton = null;
-
- /**
- * Cancel button in the footer.
- * @type {HTMLElement}
- */
- this.cancelButton = null;
-
- Object.seal(this);
-
- // Initialize the header.
- this.element_.querySelector('#app-name').innerText =
- chrome.runtime.getManifest().name;
-
- // Initialize dialog type.
- this.initDialogType_();
-
- // Pre-populate the static localized strings.
- i18nTemplate.process(this.element_.ownerDocument, loadTimeData);
-};
-
-/**
- * Tweak the UI to become a particular kind of dialog, as determined by the
- * dialog type parameter passed to the constructor.
- *
- * @private
- */
-FileManagerUI.prototype.initDialogType_ = function() {
- // Obtain elements.
- var hasFooterPanel =
- this.dialogType_ == DialogType.SELECT_SAVEAS_FILE ||
- DialogType.isFolderDialog(this.dialogType_);
-
- // If the footer panel exists, the buttons are placed there. Otherwise,
- // the buttons are on the preview panel.
- var parentPanelOfButtons = this.element_.ownerDocument.querySelector(
- !hasFooterPanel ? '.preview-panel' : '.dialog-footer');
- parentPanelOfButtons.classList.add('button-panel');
- this.fileTypeSelector = parentPanelOfButtons.querySelector('.file-type');
- this.okButton = parentPanelOfButtons.querySelector('.ok');
- this.cancelButton = parentPanelOfButtons.querySelector('.cancel');
-
- // Set attributes.
- var okLabel = str('OPEN_LABEL');
-
- switch (this.dialogType_) {
- case DialogType.SELECT_UPLOAD_FOLDER:
- okLabel = str('UPLOAD_LABEL');
- break;
-
- case DialogType.SELECT_SAVEAS_FILE:
- okLabel = str('SAVE_LABEL');
- break;
-
- case DialogType.SELECT_FOLDER:
- case DialogType.SELECT_OPEN_FILE:
- case DialogType.SELECT_OPEN_MULTI_FILE:
- case DialogType.FULL_PAGE:
- break;
-
- default:
- throw new Error('Unknown dialog type: ' + this.dialogType);
- }
-
- this.okButton.textContent = okLabel;
- this.element_.setAttribute('type', this.dialogType_);
-};
-
-/**
- * Initialize the dialogs.
- */
-FileManagerUI.prototype.initDialogs = function() {
- // Initialize the dialog label.
- var dialogs = cr.ui.dialogs;
- dialogs.BaseDialog.OK_LABEL = str('OK_LABEL');
- dialogs.BaseDialog.CANCEL_LABEL = str('CANCEL_LABEL');
- var appState = window.appState || {};
-
- // Create the dialog instances.
- this.errorDialog = new ErrorDialog(this.element_);
- this.alertDialog = new dialogs.AlertDialog(this.element_);
- this.confirmDialog = new dialogs.ConfirmDialog(this.element_);
- this.promptDialog = new dialogs.PromptDialog(this.element_);
- this.shareDialog = new ShareDialog(this.element_);
- this.defaultTaskPicker =
- new cr.filebrowser.DefaultActionDialog(this.element_);
- this.suggestAppsDialog = new SuggestAppsDialog(
- this.element_, appState.suggestAppsDialogState || {});
- this.conflictDialog = new ConflictDialog(this.element_);
-};
-
-/**
- * Initialize here elements, which are expensive
- * or hidden in the beginning.
- */
-FileManagerUI.prototype.initAdditionalUI = function() {
- this.searchBox = new SearchBox(this.element_.querySelector('#search-box'));
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/ui/navigation_list.js b/chromium/chrome/browser/resources/file_manager/foreground/js/ui/navigation_list.js
deleted file mode 100644
index f471aa6c0de..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/ui/navigation_list.js
+++ /dev/null
@@ -1,386 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * A navigation list item.
- * @constructor
- * @extends {HTMLLIElement}
- */
-var NavigationListItem = cr.ui.define('li');
-
-NavigationListItem.prototype = {
- __proto__: HTMLLIElement.prototype,
- get modelItem() { return this.modelItem_; }
-};
-
-/**
- * Decorate the item.
- */
-NavigationListItem.prototype.decorate = function() {
- // decorate() may be called twice: from the constructor and from
- // List.createItem(). This check prevents double-decorating.
- if (this.className)
- return;
-
- this.className = 'root-item';
- this.setAttribute('role', 'option');
-
- this.iconDiv_ = cr.doc.createElement('div');
- this.iconDiv_.className = 'volume-icon';
- this.appendChild(this.iconDiv_);
-
- this.label_ = cr.doc.createElement('div');
- this.label_.className = 'root-label';
- this.appendChild(this.label_);
-
- cr.defineProperty(this, 'lead', cr.PropertyKind.BOOL_ATTR);
- cr.defineProperty(this, 'selected', cr.PropertyKind.BOOL_ATTR);
-};
-
-/**
- * Associate a path with this item.
- * @param {NavigationModelItem} modelItem NavigationModelItem of this item.
- * @param {string=} opt_deviceType The type of the device. Available iff the
- * path represents removable storage.
- */
-NavigationListItem.prototype.setModelItem =
- function(modelItem, opt_deviceType) {
- if (this.modelItem_)
- console.warn('NavigationListItem.setModelItem should be called only once.');
-
- this.modelItem_ = modelItem;
-
- var rootType = PathUtil.getRootType(modelItem.path);
- this.iconDiv_.setAttribute('volume-type-icon', rootType);
- if (opt_deviceType) {
- this.iconDiv_.setAttribute('volume-subtype', opt_deviceType);
- }
-
- this.label_.textContent = modelItem.label;
-
- if (rootType === RootType.ARCHIVE || rootType === RootType.REMOVABLE) {
- this.eject_ = cr.doc.createElement('div');
- // Block other mouse handlers.
- this.eject_.addEventListener(
- 'mouseup', function(event) { event.stopPropagation() });
- this.eject_.addEventListener(
- 'mousedown', function(event) { event.stopPropagation() });
-
- this.eject_.className = 'root-eject';
- this.eject_.addEventListener('click', function(event) {
- event.stopPropagation();
- cr.dispatchSimpleEvent(this, 'eject');
- }.bind(this));
-
- this.appendChild(this.eject_);
- }
-};
-
-/**
- * Associate a context menu with this item.
- * @param {cr.ui.Menu} menu Menu this item.
- */
-NavigationListItem.prototype.maybeSetContextMenu = function(menu) {
- if (!this.modelItem_.path) {
- console.error('NavigationListItem.maybeSetContextMenu must be called ' +
- 'after setModelItem().');
- return;
- }
-
- var isRoot = PathUtil.isRootPath(this.modelItem_.path);
- var rootType = PathUtil.getRootType(this.modelItem_.path);
- // The context menu is shown on the following items:
- // - Removable and Archive volumes
- // - Folder shortcuts
- if (!isRoot ||
- (rootType != RootType.DRIVE && rootType != RootType.DOWNLOADS))
- cr.ui.contextMenuHandler.setContextMenu(this, menu);
-};
-
-/**
- * A navigation list.
- * @constructor
- * @extends {cr.ui.List}
- */
-function NavigationList() {
-}
-
-/**
- * NavigationList inherits cr.ui.List.
- */
-NavigationList.prototype = {
- __proto__: cr.ui.List.prototype,
-
- set dataModel(dataModel) {
- if (!this.onListContentChangedBound_)
- this.onListContentChangedBound_ = this.onListContentChanged_.bind(this);
-
- if (this.dataModel_) {
- this.dataModel_.removeEventListener(
- 'change', this.onListContentChangedBound_);
- this.dataModel_.removeEventListener(
- 'permuted', this.onListContentChangedBound_);
- }
-
- var parentSetter = cr.ui.List.prototype.__lookupSetter__('dataModel');
- parentSetter.call(this, dataModel);
-
- // This must be placed after the parent method is called, in order to make
- // it sure that the list was changed.
- dataModel.addEventListener('change', this.onListContentChangedBound_);
- dataModel.addEventListener('permuted', this.onListContentChangedBound_);
- },
-
- get dataModel() {
- return this.dataModel_;
- },
-
- // TODO(yoshiki): Add a setter of 'directoryModel'.
-};
-
-/**
- * @param {HTMLElement} el Element to be DirectoryItem.
- * @param {VolumeManagerWrapper} volumeManager The VolumeManager of the system.
- * @param {DirectoryModel} directoryModel Current DirectoryModel.
- * folders.
- */
-NavigationList.decorate = function(el, volumeManager, directoryModel) {
- el.__proto__ = NavigationList.prototype;
- el.decorate(volumeManager, directoryModel);
-};
-
-/**
- * @param {VolumeManagerWrapper} volumeManager The VolumeManager of the system.
- * @param {DirectoryModel} directoryModel Current DirectoryModel.
- */
-NavigationList.prototype.decorate = function(volumeManager, directoryModel) {
- cr.ui.List.decorate(this);
- this.__proto__ = NavigationList.prototype;
-
- this.directoryModel_ = directoryModel;
- this.volumeManager_ = volumeManager;
- this.selectionModel = new cr.ui.ListSingleSelectionModel();
-
- this.directoryModel_.addEventListener('directory-changed',
- this.onCurrentDirectoryChanged_.bind(this));
- this.selectionModel.addEventListener(
- 'change', this.onSelectionChange_.bind(this));
- this.selectionModel.addEventListener(
- 'beforeChange', this.onBeforeSelectionChange_.bind(this));
-
- this.scrollBar_ = new ScrollBar();
- this.scrollBar_.initialize(this.parentNode, this);
-
- // Overriding default role 'list' set by cr.ui.List.decorate() to 'listbox'
- // role for better accessibility on ChromeOS.
- this.setAttribute('role', 'listbox');
-
- var self = this;
- this.itemConstructor = function(modelItem) {
- return self.renderRoot_(modelItem);
- };
-};
-
-/**
- * This overrides cr.ui.List.measureItem().
- * In the method, a temporary element is added/removed from the list, and we
- * need to omit animations for such temporary items.
- *
- * @param {ListItem=} opt_item The list item to be measured.
- * @return {{height: number, marginTop: number, marginBottom:number,
- * width: number, marginLeft: number, marginRight:number}} Size.
- * @override
- */
-NavigationList.prototype.measureItem = function(opt_item) {
- this.measuringTemporaryItemNow_ = true;
- var result = cr.ui.List.prototype.measureItem.call(this, opt_item);
- this.measuringTemporaryItemNow_ = false;
- return result;
-};
-
-/**
- * Creates an element of a navigation list. This method is called from
- * cr.ui.List internally.
- *
- * @param {NavigationModelItem} modelItem NavigationModelItem to be rendered.
- * @return {NavigationListItem} Rendered element.
- * @private
- */
-NavigationList.prototype.renderRoot_ = function(modelItem) {
- var item = new NavigationListItem();
- var volumeInfo =
- PathUtil.isRootPath(modelItem.path) &&
- this.volumeManager_.getVolumeInfo(modelItem.path);
- item.setModelItem(modelItem, volumeInfo && volumeInfo.deviceType);
-
- var handleClick = function() {
- if (item.selected &&
- modelItem.path !== this.directoryModel_.getCurrentDirPath()) {
- metrics.recordUserAction('FolderShortcut.Navigate');
- this.changeDirectory_(modelItem);
- }
- }.bind(this);
- item.addEventListener('click', handleClick);
-
- var handleEject = function() {
- var unmountCommand = cr.doc.querySelector('command#unmount');
- // Let's make sure 'canExecute' state of the command is properly set for
- // the root before executing it.
- unmountCommand.canExecuteChange(item);
- unmountCommand.execute(item);
- };
- item.addEventListener('eject', handleEject);
-
- if (this.contextMenu_)
- item.maybeSetContextMenu(this.contextMenu_);
-
- return item;
-};
-
-/**
- * Changes the current directory to the given path.
- * If the given path is not found, a 'shortcut-target-not-found' event is
- * fired.
- *
- * @param {NavigationModelItem} modelItem Directory to be chagned to.
- * @private
- */
-NavigationList.prototype.changeDirectory_ = function(modelItem) {
- var onErrorCallback = function(error) {
- if (error.code === FileError.NOT_FOUND_ERR)
- this.dataModel.onItemNotFoundError(modelItem);
- }.bind(this);
-
- this.directoryModel_.changeDirectory(modelItem.path, onErrorCallback);
-};
-
-/**
- * Sets a context menu. Context menu is enabled only on archive and removable
- * volumes as of now.
- *
- * @param {cr.ui.Menu} menu Context menu.
- */
-NavigationList.prototype.setContextMenu = function(menu) {
- this.contextMenu_ = menu;
-
- for (var i = 0; i < this.dataModel.length; i++) {
- this.getListItemByIndex(i).maybeSetContextMenu(this.contextMenu_);
- }
-};
-
-/**
- * Selects the n-th item from the list.
- *
- * @param {number} index Item index.
- * @return {boolean} True for success, otherwise false.
- */
-NavigationList.prototype.selectByIndex = function(index) {
- if (index < 0 || index > this.dataModel.length - 1)
- return false;
-
- var newModelItem = this.dataModel.item(index);
- var newPath = newModelItem.path;
- if (!newPath)
- return false;
-
- // Prevents double-moving to the current directory.
- // eg. When user clicks the item, changing directory has already been done in
- // click handler.
- var entry = this.directoryModel_.getCurrentDirEntry();
- if (entry && entry.fullPath == newPath)
- return false;
-
- metrics.recordUserAction('FolderShortcut.Navigate');
- this.changeDirectory_(newModelItem);
- return true;
-};
-
-/**
- * Handler before root item change.
- * @param {Event} event The event.
- * @private
- */
-NavigationList.prototype.onBeforeSelectionChange_ = function(event) {
- if (event.changes.length == 1 && !event.changes[0].selected)
- event.preventDefault();
-};
-
-/**
- * Handler for root item being clicked.
- * @param {Event} event The event.
- * @private
- */
-NavigationList.prototype.onSelectionChange_ = function(event) {
- // This handler is invoked even when the navigation list itself changes the
- // selection. In such case, we shouldn't handle the event.
- if (this.dontHandleSelectionEvent_)
- return;
-
- this.selectByIndex(this.selectionModel.selectedIndex);
-};
-
-/**
- * Invoked when the current directory is changed.
- * @param {Event} event The event.
- * @private
- */
-NavigationList.prototype.onCurrentDirectoryChanged_ = function(event) {
- this.selectBestMatchItem_();
-};
-
-/**
- * Invoked when the content in the data model is changed.
- * @param {Event} event The event.
- * @private
- */
-NavigationList.prototype.onListContentChanged_ = function(event) {
- this.selectBestMatchItem_();
-};
-
-/**
- * Synchronizes the volume list selection with the current directory, after
- * it is changed outside of the volume list.
- * @private
- */
-NavigationList.prototype.selectBestMatchItem_ = function() {
- var entry = this.directoryModel_.getCurrentDirEntry();
- var path = entry && entry.fullPath;
- if (!path)
- return;
-
- // (1) Select the nearest parent directory (including the shortcut folders).
- var bestMatchIndex = -1;
- var bestMatchSubStringLen = 0;
- for (var i = 0; i < this.dataModel.length; i++) {
- var itemPath = this.dataModel.item(i).path;
- if (path.indexOf(itemPath) == 0) {
- if (bestMatchSubStringLen < itemPath.length) {
- bestMatchIndex = i;
- bestMatchSubStringLen = itemPath.length;
- }
- }
- }
- if (bestMatchIndex != -1) {
- // Not to invoke the handler of this instance, sets the guard.
- this.dontHandleSelectionEvent_ = true;
- this.selectionModel.selectedIndex = bestMatchIndex;
- this.dontHandleSelectionEvent_ = false;
- return;
- }
-
- // (2) Selects the volume of the current directory.
- var newRootPath = PathUtil.getRootPath(path);
- for (var i = 0; i < this.dataModel.length; i++) {
- var itemPath = this.dataModel.item(i).path;
- if (PathUtil.getRootPath(itemPath) == newRootPath) {
- // Not to invoke the handler of this instance, sets the guard.
- this.dontHandleSelectionEvent_ = true;
- this.selectionModel.selectedIndex = i;
- this.dontHandleSelectionEvent_ = false;
- return;
- }
- }
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/ui/preview_panel.js b/chromium/chrome/browser/resources/file_manager/foreground/js/ui/preview_panel.js
deleted file mode 100644
index a8d0db482df..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/ui/preview_panel.js
+++ /dev/null
@@ -1,518 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * PreviewPanel UI class.
- * @param {HTMLElement} element DOM Element of preview panel.
- * @param {PreviewPanel.VisibilityType} visibilityType Initial value of the
- * visibility type.
- * @param {MetadataCache} metadataCache Metadata cache.
- * @param {VolumeManagerWrapper} volumeManager Volume manager.
- * @constructor
- * @extends {cr.EventTarget}
- */
-var PreviewPanel = function(element,
- visibilityType,
- metadataCache,
- volumeManager) {
- /**
- * The cached height of preview panel.
- * @type {number}
- * @private
- */
- this.height_ = 0;
-
- /**
- * Visibility type of the preview panel.
- * @type {PreviewPanel.VisiblityType}
- * @private
- */
- this.visibilityType_ = visibilityType;
-
- /**
- * Current entry to be displayed.
- * @type {Entry}
- * @private
- */
- this.currentEntry_ = null;
-
- /**
- * Dom element of the preview panel.
- * @type {HTMLElement}
- * @private
- */
- this.element_ = element;
-
- /**
- * @type {BreadcrumbsController}
- */
- this.breadcrumbs = new BreadcrumbsController(
- element.querySelector('#search-breadcrumbs'),
- metadataCache,
- volumeManager);
-
- /**
- * @type {PreviewPanel.Thumbnails}
- */
- this.thumbnails = new PreviewPanel.Thumbnails(
- element.querySelector('.preview-thumbnails'), metadataCache);
-
- /**
- * @type {HTMLElement}
- * @private
- */
- this.summaryElement_ = element.querySelector('.preview-summary');
-
- /**
- * @type {PreviewPanel.CalculatingSizeLabel}
- * @private
- */
- this.calculatingSizeLabel_ = new PreviewPanel.CalculatingSizeLabel(
- this.summaryElement_.querySelector('.calculating-size'));
-
- /**
- * @type {HTMLElement}
- * @private
- */
- this.previewText_ = element.querySelector('.preview-text');
-
- /**
- * FileSelection to be displayed.
- * @type {FileSelection}
- * @private
- */
- this.selection_ = {entries: [], computeBytes: function() {}};
-
- /**
- * Sequence value that is incremented by every selection update and is used to
- * check if the callback is up to date or not.
- * @type {number}
- * @private
- */
- this.sequence_ = 0;
-
- /**
- * @type {VolumeManager}
- * @private
- */
- this.volumeManager_ = volumeManager;
-
- cr.EventTarget.call(this);
-};
-
-/**
- * Name of PreviewPanels's event.
- * @enum {string}
- * @const
- */
-PreviewPanel.Event = Object.freeze({
- // Event to be triggered at the end of visibility change.
- VISIBILITY_CHANGE: 'visibilityChange'
-});
-
-/**
- * Visibility type of the preview panel.
- */
-PreviewPanel.VisibilityType = Object.freeze({
- // Preview panel always shows.
- ALWAYS_VISIBLE: 'alwaysVisible',
- // Preview panel shows when the selection property are set.
- AUTO: 'auto',
- // Preview panel does not show.
- ALWAYS_HIDDEN: 'alwaysHidden'
-});
-
-/**
- * @private
- */
-PreviewPanel.Visibility_ = Object.freeze({
- VISIBLE: 'visible',
- HIDING: 'hiding',
- HIDDEN: 'hidden'
-});
-
-PreviewPanel.prototype = {
- __proto__: cr.EventTarget.prototype,
-
- /**
- * Setter for the current entry.
- * @param {Entry} entry New entry.
- */
- set currentEntry(entry) {
- if (util.isSameEntry(this.currentEntry_, entry))
- return;
- this.currentEntry_ = entry;
- this.updateVisibility_();
- this.updatePreviewArea_();
- },
-
- /**
- * Setter for the visibility type.
- * @param {PreviewPanel.VisibilityType} visibilityType New value of visibility
- * type.
- */
- set visibilityType(visibilityType) {
- this.visibilityType_ = visibilityType;
- this.updateVisibility_();
- },
-
- get visible() {
- return this.element_.getAttribute('visibility') ==
- PreviewPanel.Visibility_.VISIBLE;
- },
-
- /**
- * Obtains the height of preview panel.
- * @return {number} Height of preview panel.
- */
- get height() {
- this.height_ = this.height_ || this.element_.clientHeight;
- return this.height_;
- }
-};
-
-/**
- * Initializes the element.
- */
-PreviewPanel.prototype.initialize = function() {
- this.element_.addEventListener('webkitTransitionEnd',
- this.onTransitionEnd_.bind(this));
- this.updatePreviewArea_();
- this.updateVisibility_();
-};
-
-/**
- * Apply the selection and update the view of the preview panel.
- * @param {FileSelection} selection Selection to be applied.
- */
-PreviewPanel.prototype.setSelection = function(selection) {
- this.sequence_++;
- this.selection_ = selection;
- this.updateVisibility_();
- // If the previw panel is hiding, does not update the current view.
- if (this.visible)
- this.updatePreviewArea_();
-};
-
-/**
- * Update the visibility of the preview panel.
- * @private
- */
-PreviewPanel.prototype.updateVisibility_ = function() {
- // Get the new visibility value.
- var visibility = this.element_.getAttribute('visibility');
- var newVisible = null;
- switch (this.visibilityType_) {
- case PreviewPanel.VisibilityType.ALWAYS_VISIBLE:
- newVisible = true;
- break;
- case PreviewPanel.VisibilityType.AUTO:
- newVisible =
- this.selection_.entries.length !== 0 ||
- (this.currentEntry_ &&
- !this.volumeManager_.getLocationInfo(
- this.currentEntry_).isRootEntry);
- break;
- case PreviewPanel.VisibilityType.ALWAYS_HIDDEN:
- newVisible = false;
- break;
- default:
- console.error('Invalid visibilityType.');
- return;
- }
-
- // If the visibility has been already the new value, just return.
- if ((visibility == PreviewPanel.Visibility_.VISIBLE && newVisible) ||
- (visibility == PreviewPanel.Visibility_.HIDDEN && !newVisible))
- return;
-
- // Set the new visibility value.
- if (newVisible) {
- this.element_.setAttribute('visibility', PreviewPanel.Visibility_.VISIBLE);
- cr.dispatchSimpleEvent(this, PreviewPanel.Event.VISIBILITY_CHANGE);
- } else {
- this.element_.setAttribute('visibility', PreviewPanel.Visibility_.HIDING);
- }
-};
-
-/**
- * Update the text in the preview panel.
- *
- * @param {boolean} breadCrumbsVisible Whether the bread crumbs is visible or
- * not.
- * @private
- */
-PreviewPanel.prototype.updatePreviewArea_ = function(breadCrumbsVisible) {
- var selection = this.selection_;
-
- // Update thumbnails.
- this.thumbnails.selection = selection.totalCount !== 0 ?
- selection : {entries: [this.currentEntry_]};
-
- // Check if the breadcrumb list should show instead on the preview text.
- var entry;
- if (this.selection_.totalCount == 1)
- entry = this.selection_.entries[0];
- else if (this.selection_.totalCount == 0)
- entry = this.currentEntry_;
-
- if (entry) {
- this.breadcrumbs.show(entry);
- this.calculatingSizeLabel_.hidden = true;
- this.previewText_.textContent = '';
- return;
- }
- this.breadcrumbs.hide();
-
- // Obtains the preview text.
- var text;
- if (selection.directoryCount == 0)
- text = strf('MANY_FILES_SELECTED', selection.fileCount);
- else if (selection.fileCount == 0)
- text = strf('MANY_DIRECTORIES_SELECTED', selection.directoryCount);
- else
- text = strf('MANY_ENTRIES_SELECTED', selection.totalCount);
-
- // Obtains the size of files.
- this.calculatingSizeLabel_.hidden = selection.bytesKnown;
- if (selection.bytesKnown && selection.showBytes)
- text += ', ' + util.bytesToString(selection.bytes);
-
- // Set the preview text to the element.
- this.previewText_.textContent = text;
-
- // Request the byte calculation if needed.
- if (!selection.bytesKnown) {
- this.selection_.computeBytes(function(sequence) {
- // Selection has been already updated.
- if (this.sequence_ != sequence)
- return;
- this.updatePreviewArea_();
- }.bind(this, this.sequence_));
- }
-};
-
-/**
- * Event handler to be called at the end of hiding transition.
- * @param {Event} event The webkitTransitionEnd event.
- * @private
- */
-PreviewPanel.prototype.onTransitionEnd_ = function(event) {
- if (event.target != this.element_ || event.propertyName != 'opacity')
- return;
- var visibility = this.element_.getAttribute('visibility');
- if (visibility != PreviewPanel.Visibility_.HIDING)
- return;
- this.element_.setAttribute('visibility', PreviewPanel.Visibility_.HIDDEN);
- cr.dispatchSimpleEvent(this, PreviewPanel.Event.VISIBILITY_CHANGE);
-};
-
-/**
- * Animating label that is shown during the bytes of selection entries is being
- * calculated.
- *
- * This label shows dots and varying the number of dots every
- * CalculatingSizeLabel.PERIOD milliseconds.
- * @param {HTMLElement} element DOM element of the label.
- * @constructor
- */
-PreviewPanel.CalculatingSizeLabel = function(element) {
- this.element_ = element;
- this.count_ = 0;
- this.intervalID_ = null;
- Object.seal(this);
-};
-
-/**
- * Time period in milliseconds.
- * @const {number}
- */
-PreviewPanel.CalculatingSizeLabel.PERIOD = 500;
-
-PreviewPanel.CalculatingSizeLabel.prototype = {
- /**
- * Set visibility of the label.
- * When it is displayed, the text is animated.
- * @param {boolean} hidden Whether to hide the label or not.
- */
- set hidden(hidden) {
- this.element_.hidden = hidden;
- if (!hidden) {
- if (this.intervalID_ != null)
- return;
- this.count_ = 2;
- this.intervalID_ =
- setInterval(this.onStep_.bind(this),
- PreviewPanel.CalculatingSizeLabel.PERIOD);
- this.onStep_();
- } else {
- if (this.intervalID_ == null)
- return;
- clearInterval(this.intervalID_);
- this.intervalID_ = null;
- }
- }
-};
-
-/**
- * Increments the counter and updates the number of dots.
- * @private
- */
-PreviewPanel.CalculatingSizeLabel.prototype.onStep_ = function() {
- var text = str('CALCULATING_SIZE');
- for (var i = 0; i < ~~(this.count_ / 2) % 4; i++) {
- text += '.';
- }
- this.element_.textContent = text;
- this.count_++;
-};
-
-/**
- * Thumbnails on the preview panel.
- *
- * @param {HTMLElement} element DOM Element of thumbnail container.
- * @param {MetadataCache} metadataCache MetadataCache.
- * @constructor
- */
-PreviewPanel.Thumbnails = function(element, metadataCache) {
- this.element_ = element;
- this.metadataCache_ = metadataCache;
- this.sequence_ = 0;
- Object.seal(this);
-};
-
-/**
- * Maximum number of thumbnails.
- * @const {number}
- */
-PreviewPanel.Thumbnails.MAX_THUMBNAIL_COUNT = 4;
-
-/**
- * Edge length of the thumbnail square.
- * @const {number}
- */
-PreviewPanel.Thumbnails.THUMBNAIL_SIZE = 35;
-
-/**
- * Longer edge length of zoomed thumbnail rectangle.
- * @const {number}
- */
-PreviewPanel.Thumbnails.ZOOMED_THUMBNAIL_SIZE = 200;
-
-PreviewPanel.Thumbnails.prototype = {
- /**
- * Sets entries to be displayed in the view.
- * @param {Array.<Entry>} value Entries.
- */
- set selection(value) {
- this.sequence_++;
- this.loadThumbnails_(value);
- }
-};
-
-/**
- * Loads thumbnail images.
- * @param {FileSelection} selection Selection containing entries that are
- * sources of images.
- * @private
- */
-PreviewPanel.Thumbnails.prototype.loadThumbnails_ = function(selection) {
- var entries = selection.entries;
- this.element_.classList.remove('has-zoom');
- this.element_.innerText = '';
- var clickHandler = selection.tasks &&
- selection.tasks.executeDefault.bind(selection.tasks);
- var length = Math.min(entries.length,
- PreviewPanel.Thumbnails.MAX_THUMBNAIL_COUNT);
- for (var i = 0; i < length; i++) {
- // Create a box.
- var box = this.element_.ownerDocument.createElement('div');
- box.style.zIndex = PreviewPanel.Thumbnails.MAX_THUMBNAIL_COUNT + 1 - i;
-
- // Load the image.
- if (entries[i]) {
- FileGrid.decorateThumbnailBox(box,
- entries[i],
- this.metadataCache_,
- ThumbnailLoader.FillMode.FILL,
- FileGrid.ThumbnailQuality.LOW,
- i == 0 && length == 1 &&
- this.setZoomedImage_.bind(this));
- }
-
- // Register the click handler.
- if (clickHandler)
- box.addEventListener('click', clickHandler);
-
- // Append
- this.element_.appendChild(box);
- }
-};
-
-/**
- * Create the zoomed version of image and set it to the DOM element to show the
- * zoomed image.
- *
- * @param {Image} image Image to be source of the zoomed image.
- * @param {transform} transform Transformation to be applied to the image.
- * @private
- */
-PreviewPanel.Thumbnails.prototype.setZoomedImage_ = function(image, transform) {
- if (!image)
- return;
- var width = image.width || 0;
- var height = image.height || 0;
- if (width == 0 ||
- height == 0 ||
- (width < PreviewPanel.Thumbnails.THUMBNAIL_SIZE * 2 &&
- height < PreviewPanel.Thumbnails.THUMBNAIL_SIZE * 2))
- return;
-
- var scale = Math.min(1,
- PreviewPanel.Thumbnails.ZOOMED_THUMBNAIL_SIZE /
- Math.max(width, height));
- var imageWidth = ~~(width * scale);
- var imageHeight = ~~(height * scale);
- var zoomedImage = this.element_.ownerDocument.createElement('img');
-
- if (scale < 0.3) {
- // Scaling large images kills animation. Downscale it in advance.
- // Canvas scales images with liner interpolation. Make a larger
- // image (but small enough to not kill animation) and let IMAGE
- // scale it smoothly.
- var INTERMEDIATE_SCALE = 3;
- var canvas = this.element_.ownerDocument.createElement('canvas');
- canvas.width = imageWidth * INTERMEDIATE_SCALE;
- canvas.height = imageHeight * INTERMEDIATE_SCALE;
- var ctx = canvas.getContext('2d');
- ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
- // Using bigger than default compression reduces image size by
- // several times. Quality degradation compensated by greater resolution.
- zoomedImage.src = canvas.toDataURL('image/jpeg', 0.6);
- } else {
- zoomedImage.src = image.src;
- }
-
- var boxWidth = Math.max(PreviewPanel.Thumbnails.THUMBNAIL_SIZE, imageWidth);
- var boxHeight = Math.max(PreviewPanel.Thumbnails.THUMBNAIL_SIZE, imageHeight);
- if (transform && transform.rotate90 % 2 == 1) {
- var t = boxWidth;
- boxWidth = boxHeight;
- boxHeight = t;
- }
-
- util.applyTransform(zoomedImage, transform);
-
- var zoomedBox = this.element_.ownerDocument.createElement('div');
- zoomedBox.className = 'popup';
- zoomedBox.style.width = boxWidth + 'px';
- zoomedBox.style.height = boxHeight + 'px';
- zoomedBox.appendChild(zoomedImage);
-
- this.element_.appendChild(zoomedBox);
- this.element_.classList.add('has-zoom');
- return;
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/ui/progress_center_panel.js b/chromium/chrome/browser/resources/file_manager/foreground/js/ui/progress_center_panel.js
deleted file mode 100644
index bcfe6d8e747..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/ui/progress_center_panel.js
+++ /dev/null
@@ -1,329 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Progress center panel.
- *
- * @param {HTMLElement} element DOM Element of the process center panel.
- * @constructor
- */
-var ProgressCenterPanel = function(element) {
- /**
- * Root element of the progress center.
- * @type {!HTMLElement}
- * @private
- */
- this.element_ = element;
-
- /**
- * Open view containing multiple progress items.
- * @type {!HTMLElement}
- * @private
- */
- this.openView_ = this.element_.querySelector('#progress-center-open-view');
-
- /**
- * Close view that is a summarized progress item.
- * @type {!HTMLElement}
- * @private
- */
- this.closeView_ = this.element_.querySelector('#progress-center-close-view');
-
- /**
- * Toggle animation rule of the progress center.
- * @type {!CSSKeyFrameRule}
- * @private
- */
- this.toggleAnimation_ = ProgressCenterPanel.getToggleAnimation_(
- element.ownerDocument);
-
- /**
- * Reset is requested but it is pending until the transition of progress bar
- * is complete.
- * @type {boolean}
- * @private
- */
- this.resetRequested_ = false;
-
- /**
- * Callback to becalled with the ID of the progress item when the cancel
- * button is clicked.
- */
- this.cancelCallback = null;
-
- Object.seal(this);
-
- // Register event handlers.
- element.addEventListener('click', this.onClick_.bind(this));
- element.addEventListener(
- 'webkitAnimationEnd', this.onToggleAnimationEnd_.bind(this));
- element.addEventListener(
- 'webkitTransitionEnd', this.onItemTransitionEnd_.bind(this));
-};
-
-/**
- * Updates attributes of the item element.
- * @param {!HTMLElement} element Element to be updated.
- * @param {!ProgressCenterItem} item Progress center item.
- * @private
- */
-ProgressCenterPanel.updateItemElement_ = function(element, item) {
- // Sets element attributes.
- element.setAttribute('data-progress-id', item.id);
- element.classList.toggle('error', item.state === ProgressItemState.ERROR);
- element.classList.toggle('cancelable', item.cancelable);
-
- // Only when the previousWidthRate is not NaN (when style width is already
- // set) and the progress rate increases, we use transition animation.
- var previousWidthRate =
- parseInt(element.querySelector('.progress-track').style.width);
- var targetWidthRate = item.progressRateInPercent;
- var animation = !isNaN(previousWidthRate) &&
- previousWidthRate < targetWidthRate;
- if (item.state === ProgressItemState.COMPLETED && animation) {
- // The attribute pre-complete means that the actual operation is already
- // done but the UI transition of progress bar is not complete.
- element.setAttribute('pre-complete', '');
- } else {
- element.querySelector('label').textContent = item.message;
- }
-
- // To commit the property change and to trigger the transition even if the
- // change is done synchronously, assign the width value asynchronously.
- var updateTrackWidth = function() {
- var track = element.querySelector('.progress-track');
- track.classList.toggle('animated', animation);
- track.style.width = targetWidthRate + '%';
- track.hidden = false;
- };
- if (animation)
- setTimeout(updateTrackWidth);
- else
- updateTrackWidth();
-};
-
-/**
- * Obtains the toggle animation keyframes rule from the document.
- * @param {HTMLDocument} document Document containing the rule.
- * @return {CSSKeyFrameRules} Animation rule.
- * @private
- */
-ProgressCenterPanel.getToggleAnimation_ = function(document) {
- for (var i = 0; i < document.styleSheets.length; i++) {
- var styleSheet = document.styleSheets[i];
- for (var j = 0; j < styleSheet.cssRules.length; j++) {
- var rule = styleSheet.cssRules[j];
- if (rule.type === CSSRule.WEBKIT_KEYFRAMES_RULE &&
- rule.name === 'progress-center-toggle') {
- return rule;
- }
- }
- }
- throw new Error('The progress-center-toggle rules is not found.');
-};
-
-/**
- * Updates an item to the progress center panel.
- * @param {!ProgressCenterItem} item Item including new contents.
- */
-ProgressCenterPanel.prototype.updateItem = function(item) {
- // If reset is requested, force to reset.
- if (this.resetRequested_)
- this.reset(true);
-
- var itemElement = this.getItemElement_(item.id);
-
- // Check whether the item should be displayed or not by referring its state.
- switch (item.state) {
- // Should show the item.
- case ProgressItemState.PROGRESSING:
- case ProgressItemState.ERROR:
- // If the item has not been added yet, create a new element and add it.
- if (!itemElement) {
- itemElement = this.createNewItemElement_();
- this.openView_.insertBefore(itemElement, this.openView_.firstNode);
- }
-
- // Update the element by referring the item model.
- ProgressCenterPanel.updateItemElement_(itemElement, item);
- this.element_.hidden = false;
- break;
-
- // Should not show the item.
- case ProgressItemState.COMPLETED:
- case ProgressItemState.CANCELED:
- // If itemElement is not shown, just break.
- if (!itemElement)
- break;
-
- // If the item is complete state, once update it because it may turn to
- // have the pre-complete attribute.
- if (item.state === ProgressItemState.COMPLETED)
- ProgressCenterPanel.updateItemElement_(itemElement, item);
-
- // If the item has the pre-complete attribute, keep showing it. Otherwise,
- // just remove it.
- if (item.state !== ProgressItemState.COMPLETED ||
- !itemElement.hasAttribute('pre-complete')) {
- this.openView_.removeChild(itemElement);
- }
- break;
- }
-};
-
-/**
- * Updates close showing summarized item.
- * @param {!ProgressCenterItem} summarizedItem Item to be displayed in the close
- * view.
- */
-ProgressCenterPanel.prototype.updateCloseView = function(summarizedItem) {
- this.closeView_.classList.toggle('single', !summarizedItem.summarized);
- ProgressCenterPanel.updateItemElement_(this.closeView_, summarizedItem);
-};
-
-/**
- * Remove all the items.
- * @param {boolean=} opt_force True if we force to reset and do not wait the
- * transition of progress bar. False otherwise. False is default.
- */
-ProgressCenterPanel.prototype.reset = function(opt_force) {
- if (!opt_force && this.element_.querySelector('[pre-complete]')) {
- this.resetRequested_ = true;
- return;
- }
-
- // Clear the flag.
- this.resetRequested_ = false;
-
- // Clear the all compete item.
- this.openView_.innerHTML = '';
-
- // Clear track width of close view.
- this.closeView_.querySelector('.progress-track').style.width = '';
-
- // Hide the progress center.
- this.element_.hidden = true;
- this.closeView_.querySelector('.progress-track').hidden = true;
- this.element_.classList.remove('opened');
-};
-
-/**
- * Gets an item element having the specified ID.
- * @param {string} id progress item ID.
- * @return {HTMLElement} Item element having the ID.
- * @private
- */
-ProgressCenterPanel.prototype.getItemElement_ = function(id) {
- var query = 'li[data-progress-id="' + id + '"]';
- return this.openView_.querySelector(query);
-};
-
-/**
- * Creates an item element.
- * @return {HTMLElement} Created item element.
- * @private
- */
-ProgressCenterPanel.prototype.createNewItemElement_ = function() {
- var label = this.element_.ownerDocument.createElement('label');
- label.className = 'label';
-
- var progressBarIndicator = this.element_.ownerDocument.createElement('div');
- progressBarIndicator.className = 'progress-track';
-
- var progressBar = this.element_.ownerDocument.createElement('div');
- progressBar.className = 'progress-bar';
- progressBar.appendChild(progressBarIndicator);
-
- var cancelButton = this.element_.ownerDocument.createElement('button');
- cancelButton.className = 'cancel';
- cancelButton.setAttribute('tabindex', '-1');
-
- var progressFrame = this.element_.ownerDocument.createElement('div');
- progressFrame.className = 'progress-frame';
- progressFrame.appendChild(progressBar);
- progressFrame.appendChild(cancelButton);
-
- var itemElement = this.element_.ownerDocument.createElement('li');
- itemElement.appendChild(label);
- itemElement.appendChild(progressFrame);
-
- return itemElement;
-};
-
-/**
- * Handles the animation end event of the progress center.
- * @param {Event} event Animation end event.
- * @private
- */
-ProgressCenterPanel.prototype.onToggleAnimationEnd_ = function(event) {
- // Transition end of the root element's height.
- if (event.target === this.element_ &&
- event.animationName === 'progress-center-toggle') {
- this.element_.classList.remove('animated');
- return;
- }
-};
-
-/**
- * Handles the transition end event of items.
- * @param {Event} event Transition end event.
- * @private
- */
-ProgressCenterPanel.prototype.onItemTransitionEnd_ = function(event) {
- var itemElement = event.target.parentNode.parentNode.parentNode;
- if (!itemElement.hasAttribute('pre-complete') ||
- event.propertyName !== 'width')
- return;
- if (itemElement !== this.closeView_)
- this.openView_.removeChild(itemElement);
- itemElement.removeAttribute('pre-complete');
-
- if (this.resetRequested_)
- this.reset();
-};
-
-/**
- * Handles the click event.
- * @param {Event} event Click event.
- * @private
- */
-ProgressCenterPanel.prototype.onClick_ = function(event) {
- // Toggle button.
- if (event.target.classList.contains('toggle') &&
- (!this.closeView_.classList.contains('single') ||
- this.element_.classList.contains('opened'))) {
-
- // If the progress center has already animated, just return.
- if (this.element_.classList.contains('animated'))
- return;
-
- // Obtains current and target height.
- var currentHeight;
- var targetHeight;
- if (this.element_.classList.contains('opened')) {
- currentHeight = this.openView_.getBoundingClientRect().height;
- targetHeight = this.closeView_.getBoundingClientRect().height;
- } else {
- currentHeight = this.closeView_.getBoundingClientRect().height;
- targetHeight = this.openView_.getBoundingClientRect().height;
- }
-
- // Set styles for animation.
- this.toggleAnimation_.cssRules[0].style.height = currentHeight + 'px';
- this.toggleAnimation_.cssRules[1].style.height = targetHeight + 'px';
- this.element_.classList.add('animated');
- this.element_.classList.toggle('opened');
- return;
- }
-
- // Cancel button.
- if (this.cancelCallback) {
- var id = event.target.classList.contains('toggle') ?
- this.closeView_.getAttribute('data-progress-id') :
- event.target.parentNode.parentNode.getAttribute('data-progress-id');
- this.cancelCallback(id);
- }
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/ui/search_box.js b/chromium/chrome/browser/resources/file_manager/foreground/js/ui/search_box.js
deleted file mode 100644
index 30a7ea73faf..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/ui/search_box.js
+++ /dev/null
@@ -1,202 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * Search box.
- *
- * @param {element} element Root element of the search box.
- * @constructor
- */
-function SearchBox(element) {
- /**
- * Autocomplete List.
- * @type {AutocompleteList}
- */
- this.autocompleteList = new SearchBox.AutocompleteList(element.ownerDocument);
-
- /**
- * Root element of the search box.
- * @type {HTMLElement}
- */
- this.element = element;
-
- /**
- * Text input of the search box.
- * @type {HTMLElement}
- */
- this.inputElement = element.querySelector('input');
-
- /**
- * Clear button of the search box.
- * @type {HTMLElement}
- */
- this.clearButton = element.querySelector('.clear');
-
- /**
- * Text measure.
- * @type {TextMeasure}
- * @private
- */
- this.textMeasure_ = new TextMeasure(this.inputElement);
-
- Object.freeze(this);
-
- // Register events.
- this.inputElement.addEventListener('input', this.updateStyles_.bind(this));
- this.inputElement.addEventListener('keydown', this.onKeyDown_.bind(this));
- this.inputElement.addEventListener('focus', this.onFocus_.bind(this));
- this.inputElement.addEventListener('blur', this.onBlur_.bind(this));
- element.querySelector('.icon').addEventListener(
- 'click', this.onIconClick_.bind(this));
- element.parentNode.appendChild(this.autocompleteList);
-}
-
-/**
- * Autocomplete list for search box.
- * @param {HTMLDocument} document Document.
- * @constructor
- */
-SearchBox.AutocompleteList = function(document) {
- var self = cr.ui.AutocompleteList.call(this);
- self.__proto__ = SearchBox.AutocompleteList.prototype;
- self.id = 'autocomplete-list';
- self.autoExpands = true;
- self.itemConstructor = SearchBox.AutocompleteListItem_.bind(null, document);
- self.addEventListener('mouseover', self.onMouseOver_.bind(self));
- return self;
-};
-
-SearchBox.AutocompleteList.prototype = {
- __proto__: cr.ui.AutocompleteList.prototype
-};
-
-/**
- * Do nothing when a suggestion is selected.
- * @override
- */
-SearchBox.AutocompleteList.prototype.handleSelectedSuggestion = function() {};
-
-/**
- * Change the selection by a mouse over instead of just changing the
- * color of moused over element with :hover in CSS. Here's why:
- *
- * 1) The user selects an item A with up/down keys (item A is highlighted)
- * 2) Then the user moves the cursor to another item B
- *
- * If we just change the color of moused over element (item B), both
- * the item A and B are highlighted. This is bad. We should change the
- * selection so only the item B is highlighted.
- *
- * @param {Event} event Event.
- * @private
- */
-SearchBox.AutocompleteList.prototype.onMouseOver_ = function(event) {
- if (event.target.itemInfo)
- this.selectedItem = event.target.itemInfo;
-};
-
-/**
- * ListItem element for autocomple.
- *
- * @param {HTMLDocument} document Document.
- * @param {Object} item An object representing a suggestion.
- * @constructor
- * @private
- */
-SearchBox.AutocompleteListItem_ = function(document, item) {
- var li = new cr.ui.ListItem();
- li.itemInfo = item;
-
- var icon = document.createElement('div');
- icon.className = 'detail-icon';
-
- var text = document.createElement('div');
- text.className = 'detail-text';
-
- if (item.isHeaderItem) {
- icon.setAttribute('search-icon', '');
- text.innerHTML =
- strf('SEARCH_DRIVE_HTML', util.htmlEscape(item.searchQuery));
- } else {
- var iconType = FileType.getIcon(item.entry);
- icon.setAttribute('file-type-icon', iconType);
- // highlightedBaseName is a piece of HTML with meta characters properly
- // escaped. See the comment at fileBrowserPrivate.searchDriveMetadata().
- text.innerHTML = item.highlightedBaseName;
- }
- li.appendChild(icon);
- li.appendChild(text);
- return li;
-};
-
-/**
- * Updates the size related style.
- */
-SearchBox.prototype.updateSizeRelatedStyle = function() {
- // Hide the search box if there is not enough space.
- this.element.classList.toggle(
- 'too-short',
- this.element.clientWidth < 100);
-};
-
-/**
- * Clears the search query.
- */
-SearchBox.prototype.clear = function() {
- this.inputElement.value = '';
- this.updateStyles_();
-};
-
-/**
- * Handles a focus event of the search box.
- * @private
- */
-SearchBox.prototype.onFocus_ = function() {
- this.element.classList.toggle('has-cursor', true);
- this.inputElement.tabIndex = '99'; // See: go/filesapp-tabindex.
- this.autocompleteList.attachToInput(this.inputElement);
-};
-
-/**
- * Handles a blur event of the search box.
- * @private
- */
-SearchBox.prototype.onBlur_ = function() {
- this.element.classList.toggle('has-cursor', false);
- this.inputElement.tabIndex = '-1';
- this.autocompleteList.detach();
-};
-
-/**
- * Handles a keydown event of the search box.
- * @private
- */
-SearchBox.prototype.onKeyDown_ = function() {
- // Handle only Esc key now.
- if (event.keyCode != 27 || this.inputElement.value)
- return;
- this.inputElement.blur();
-};
-
-/**
- * Handles a click event of the search icon.
- * @private
- */
-SearchBox.prototype.onIconClick_ = function() {
- this.inputElement.focus();
-};
-
-/**
- * Updates styles of the search box.
- * @private
- */
-SearchBox.prototype.updateStyles_ = function() {
- this.element.classList.toggle('has-text',
- !!this.inputElement.value);
- var width = this.textMeasure_.getWidth(this.inputElement.value) +
- 16 /* Extra space to allow leeway. */;
- this.inputElement.style.width = width + 'px';
-};
diff --git a/chromium/chrome/browser/resources/file_manager/foreground/js/volume_manager_wrapper.js b/chromium/chrome/browser/resources/file_manager/foreground/js/volume_manager_wrapper.js
deleted file mode 100644
index a9631dc92d9..00000000000
--- a/chromium/chrome/browser/resources/file_manager/foreground/js/volume_manager_wrapper.js
+++ /dev/null
@@ -1,334 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * Thin wrapper for VolumeManager. This should be an interface proxy to talk
- * to VolumeManager. This class also filters Drive related data/events if
- * driveEnabled is set to false.
- *
- * @param {VolumeManagerWrapper.DriveEnabledStatus} driveEnabled DRIVE_ENABLED
- * if drive should be available. DRIVE_DISABLED if drive related
- * data/events should be hidden.
- * @param {DOMWindow} opt_backgroundPage Window object of the background
- * page. If this is specified, the class skips to get background page.
- * TOOD(hirono): Let all clients of the class pass the background page and
- * make the argument not optional.
- * @constructor
- * @extends {cr.EventTarget}
- */
-function VolumeManagerWrapper(driveEnabled, opt_backgroundPage) {
- cr.EventTarget.call(this);
-
- this.driveEnabled_ = driveEnabled;
- this.volumeInfoList = new cr.ui.ArrayDataModel([]);
-
- this.volumeManager_ = null;
- this.pendingTasks_ = [];
- this.onEventBound_ = this.onEvent_.bind(this);
- this.onVolumeInfoListUpdatedBound_ =
- this.onVolumeInfoListUpdated_.bind(this);
-
- this.disposed_ = false;
-
- // Start initialize the VolumeManager.
- var queue = new AsyncUtil.Queue();
-
- if (opt_backgroundPage) {
- this.backgroundPage_ = opt_backgroundPage;
- } else {
- queue.run(function(callNextStep) {
- chrome.runtime.getBackgroundPage(function(backgroundPage) {
- this.backgroundPage_ = backgroundPage;
- callNextStep();
- }.bind(this));
- }.bind(this));
- }
-
- queue.run(function(callNextStep) {
- this.backgroundPage_.VolumeManager.getInstance(function(volumeManager) {
- this.onReady_(volumeManager);
- callNextStep();
- }.bind(this));
- }.bind(this));
-}
-
-/**
- * If the drive is enabled on the wrapper.
- * @enum {boolean}
- */
-VolumeManagerWrapper.DriveEnabledStatus = {
- DRIVE_ENABLED: true,
- DRIVE_DISABLED: false
-};
-
-/**
- * Extends cr.EventTarget.
- */
-VolumeManagerWrapper.prototype.__proto__ = cr.EventTarget.prototype;
-
-/**
- * Called when the VolumeManager gets ready for post initialization.
- * @param {VolumeManager} volumeManager The initialized VolumeManager instance.
- * @private
- */
-VolumeManagerWrapper.prototype.onReady_ = function(volumeManager) {
- if (this.disposed_)
- return;
-
- this.volumeManager_ = volumeManager;
-
- // Subscribe to VolumeManager.
- this.volumeManager_.addEventListener(
- 'drive-connection-changed', this.onEventBound_);
- this.volumeManager_.addEventListener(
- 'externally-unmounted', this.onEventBound_);
-
- // Cache volumeInfoList.
- var volumeInfoList = [];
- for (var i = 0; i < this.volumeManager_.volumeInfoList.length; i++) {
- var volumeInfo = this.volumeManager_.volumeInfoList.item(i);
- // TODO(hidehiko): Filter mounted volumes located on Drive File System.
- if (!this.driveEnabled_ && volumeInfo.volumeType === util.VolumeType.DRIVE)
- continue;
- volumeInfoList.push(volumeInfo);
- }
- this.volumeInfoList.splice.apply(
- this.volumeInfoList,
- [0, this.volumeInfoList.length].concat(volumeInfoList));
-
- // Subscribe to VolumeInfoList.
- // In VolumeInfoList, we only use 'splice' event.
- this.volumeManager_.volumeInfoList.addEventListener(
- 'splice', this.onVolumeInfoListUpdatedBound_);
-
- // Run pending tasks.
- var pendingTasks = this.pendingTasks_;
- this.pendingTasks_ = null;
- for (var i = 0; i < pendingTasks.length; i++)
- pendingTasks[i]();
-};
-
-/**
- * Disposes the instance. After the invocation of this method, any other
- * method should not be called.
- */
-VolumeManagerWrapper.prototype.dispose = function() {
- this.disposed_ = true;
-
- if (!this.volumeManager_)
- return;
- this.volumeManager_.removeEventListener(
- 'drive-connection-changed', this.onEventBound_);
- this.volumeManager_.removeEventListener(
- 'externally-unmounted', this.onEventBound_);
- this.volumeManager_.volumeInfoList.removeEventListener(
- 'splice', this.onVolumeInfoListUpdatedBound_);
-};
-
-/**
- * Called on events sent from VolumeManager. This has responsibility to
- * re-dispatch the event to the listeners.
- * @param {Event} event Event object sent from VolumeManager.
- * @private
- */
-VolumeManagerWrapper.prototype.onEvent_ = function(event) {
- if (!this.driveEnabled_) {
- // If the drive is disabled, ignore all drive related events.
- if (event.type === 'drive-connection-changed' ||
- (event.type === 'externally-unmounted' &&
- event.volumeInfo.volumeType === util.VolumeType.DRIVE))
- return;
- }
-
- this.dispatchEvent(event);
-};
-
-/**
- * Called on events of modifying VolumeInfoList.
- * @param {Event} event Event object sent from VolumeInfoList.
- * @private
- */
-VolumeManagerWrapper.prototype.onVolumeInfoListUpdated_ = function(event) {
- if (this.driveEnabled_) {
- // Apply the splice as is.
- this.volumeInfoList.splice.apply(
- this.volumeInfoList,
- [event.index, event.removed.length].concat(event.added));
- } else {
- // Filters drive related volumes.
- var index = event.index;
- for (var i = 0; i < event.index; i++) {
- if (this.volumeManager_.volumeInfoList.item(i).volumeType ===
- util.VolumeType.DRIVE)
- index--;
- }
-
- var numRemovedVolumes = 0;
- for (var i = 0; i < event.removed.length; i++) {
- if (event.removed[i].volumeType !== util.VolumeType.DRIVE)
- numRemovedVolumes++;
- }
-
- var addedVolumes = [];
- for (var i = 0; i < event.added.length; i++) {
- var volumeInfo = event.added[i];
- if (volumeInfo.volumeType !== util.VolumeType.DRIVE)
- addedVolumes.push(volumeInfo);
- }
-
- this.volumeInfoList.splice.apply(
- this.volumeInfoList,
- [index, numRemovedVolumes].concat(addedVolumes));
- }
-};
-
-/**
- * Ensures the VolumeManager is initialized, and then invokes callback.
- * If the VolumeManager is already initialized, callback will be called
- * immediately.
- * @param {function()} callback Called on initialization completion.
- */
-VolumeManagerWrapper.prototype.ensureInitialized = function(callback) {
- if (this.pendingTasks_) {
- this.pendingTasks_.push(this.ensureInitialized.bind(this, callback));
- return;
- }
-
- callback();
-};
-
-/**
- * @return {util.DriveConnectionType} Current drive connection state.
- */
-VolumeManagerWrapper.prototype.getDriveConnectionState = function() {
- if (!this.driveEnabled_ || !this.volumeManager_) {
- return {
- type: util.DriveConnectionType.OFFLINE,
- reason: util.DriveConnectionReason.NO_SERVICE
- };
- }
-
- return this.volumeManager_.getDriveConnectionState();
-};
-
-/**
- * @param {string} mountPath The path to mount location of the volume.
- * @return {VolumeInfo} The VolumeInfo instance for the volume mounted at
- * mountPath, or null if no volume is found
- */
-VolumeManagerWrapper.prototype.getVolumeInfo = function(mountPath) {
- return this.filterDisabledDriveVolume_(
- this.volumeManager_ && this.volumeManager_.getVolumeInfo(mountPath));
-};
-
-/**
- * Obtains a volume information from a file entry URL.
- * TODO(hirono): Check a file system to find a volume.
- *
- * @param {string} url URL of entry.
- * @return {VolumeInfo} Volume info.
- */
-VolumeManagerWrapper.prototype.getVolumeInfoByURL = function(url) {
- return this.filterDisabledDriveVolume_(
- this.volumeManager_ && this.volumeManager_.getVolumeInfoByURL(url));
-};
-
-/**
- * Obtains a volume infomration of the current profile.
- *
- * @param {util.VolumeType} volumeType Volume type.
- * @return {VolumeInfo} Found volume info.
- */
-VolumeManagerWrapper.prototype.getCurrentProfileVolumeInfo =
- function(volumeType) {
- return this.filterDisabledDriveVolume_(
- this.volumeManager_ &&
- this.volumeManager_.getCurrentProfileVolumeInfo(volumeType));
-};
-
-/**
- * Obtains location information from an entry.
- *
- * @param {Entry} entry File or directory entry.
- * @return {EntryLocation} Location information.
- */
-VolumeManagerWrapper.prototype.getLocationInfo = function(entry) {
- return this.volumeManager_ && this.volumeManager_.getLocationInfo(entry);
-};
-
-/**
- * Requests to mount the archive file.
- * @param {string} fileUrl The path to the archive file to be mounted.
- * @param {function(string)} successCallback Called with mount path on success.
- * @param {function(util.VolumeError)} errorCallback Called when an error
- * occurs.
- */
-VolumeManagerWrapper.prototype.mountArchive = function(
- fileUrl, successCallback, errorCallback) {
- if (this.pendingTasks_) {
- this.pendingTasks_.push(
- this.mountArchive.bind(this, fileUrl, successCallback, errorCallback));
- return;
- }
-
- this.volumeManager_.mountArchive(fileUrl, successCallback, errorCallback);
-};
-
-/**
- * Requests unmount the volume at mountPath.
- * @param {string} mountPath The path to the mount location of the volume.
- * @param {function(string)} successCallback Called with the mount path
- * on success.
- * @param {function(util.VolumeError)} errorCallback Called when an error
- * occurs.
- */
-VolumeManagerWrapper.prototype.unmount = function(
- mountPath, successCallback, errorCallback) {
- if (this.pendingTasks_) {
- this.pendingTasks_.push(
- this.unmount.bind(this, mountPath, successCallback, errorCallback));
- return;
- }
-
- this.volumeManager_.unmount(mountPath, successCallback, errorCallback);
-};
-
-/**
- * Resolves the absolute path to an entry instance.
- * @param {string} path The path to be resolved.
- * @param {function(Entry)} successCallback Called with the resolved entry
- * on success.
- * @param {function(FileError)} errorCallback Called with the error on error.
- */
-VolumeManagerWrapper.prototype.resolveAbsolutePath = function(
- path, successCallback, errorCallback) {
- if (this.pendingTasks_) {
- this.pendingTasks_.push(this.resolveAbsolutePath.bind(
- this, path, successCallback, errorCallback));
- return;
- }
-
- // If the drive is disabled, any resolving the path under drive should be
- // failed.
- if (!this.driveEnabled_ && PathUtil.isDriveBasedPath(path)) {
- errorCallback(util.createFileError(FileError.NOT_FOUND_ERR));
- return;
- }
-
- this.volumeManager_.resolveAbsolutePath(path, successCallback, errorCallback);
-};
-
-/**
- * Filters volume info by referring driveEnabled.
- *
- * @param {VolumeInfo} volumeInfo Volume info.
- * @return {VolumeInfo} Null if the drive is disabled and the given volume is
- * drive. Otherwise just returns the volume.
- * @private
- */
-VolumeManagerWrapper.prototype.filterDisabledDriveVolume_ =
- function(volumeInfo) {
- var isDrive = volumeInfo && volumeInfo.volumeType === util.VolumeType.DRIVE;
- return this.driveEnabled_ || !isDrive ? volumeInfo : null;
-};