18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version. 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful, 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details. 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB. If not, write to 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA. 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderFileUploadControl.h" 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "Chrome.h" 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FileList.h" 268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "Frame.h" 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameView.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "GraphicsContext.h" 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLInputElement.h" 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h" 31545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch#include "ShadowElement.h" 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Icon.h" 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "LocalizedStrings.h" 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Page.h" 3565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "PaintInfo.h" 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderButton.h" 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderText.h" 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderTheme.h" 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderView.h" 40ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include "TextRun.h" 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <math.h> 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std; 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace HTMLNames; 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst int afterButtonSpacing = 4; 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst int iconHeight = 16; 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst int iconWidth = 16; 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst int iconFilenameSpacing = 2; 538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst int defaultWidthNumChars = 34; 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst int buttonShadowHeight = 2; 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderFileUploadControl::RenderFileUploadControl(HTMLInputElement* input) 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project : RenderBlock(input) 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 59643ca7872b450ea4efacab6188849e5aac2ba161Steve Block FileList* list = input->files(); 60643ca7872b450ea4efacab6188849e5aac2ba161Steve Block Vector<String> filenames; 61643ca7872b450ea4efacab6188849e5aac2ba161Steve Block unsigned length = list ? list->length() : 0; 62643ca7872b450ea4efacab6188849e5aac2ba161Steve Block for (unsigned i = 0; i < length; ++i) 63643ca7872b450ea4efacab6188849e5aac2ba161Steve Block filenames.append(list->item(i)->path()); 64643ca7872b450ea4efacab6188849e5aac2ba161Steve Block m_fileChooser = FileChooser::create(this, filenames); 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderFileUploadControl::~RenderFileUploadControl() 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_button) 708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_button->detach(); 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_fileChooser->disconnectClient(); 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderFileUploadControl::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderBlock::styleDidChange(diff, oldStyle); 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_button) 788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_button->renderer()->setStyle(createButtonStyle(style())); 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderFileUploadControl::valueChanged() 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // dispatchFormControlChangeEvent may destroy this renderer 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RefPtr<FileChooser> fileChooser = m_fileChooser; 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(node()); 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inputElement->setFileListFromRenderer(fileChooser->filenames()); 885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian inputElement->dispatchFormControlChangeEvent(); 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // only repaint if it doesn't seem we have been destroyed 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!fileChooser->disconnected()) 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project repaint(); 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderFileUploadControl::allowsMultipleFiles() 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 97967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#if ENABLE(DIRECTORY_UPLOAD) 98967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (allowsDirectoryUpload()) 99967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return true; 100967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#endif 101967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HTMLInputElement* input = static_cast<HTMLInputElement*>(node()); 103f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return input->fastHasAttribute(multipleAttr); 1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 106967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#if ENABLE(DIRECTORY_UPLOAD) 107967717af5423377c967781471ee106e2bb4e11c8Ben Murdochbool RenderFileUploadControl::allowsDirectoryUpload() 108967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{ 109967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch HTMLInputElement* input = static_cast<HTMLInputElement*>(node()); 110f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return input->fastHasAttribute(webkitdirectoryAttr); 111967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch} 1122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid RenderFileUploadControl::receiveDropForDirectoryUpload(const Vector<String>& paths) 1142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 1152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (Chrome* chromePointer = chrome()) 1162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch chromePointer->enumerateChosenDirectory(paths[0], m_fileChooser.get()); 1172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 118967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#endif 119967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 120d0825bca7fe65beaee391d30da42e937db621564Steve BlockString RenderFileUploadControl::acceptTypes() 121d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 122d0825bca7fe65beaee391d30da42e937db621564Steve Block return static_cast<HTMLInputElement*>(node())->accept(); 123d0825bca7fe65beaee391d30da42e937db621564Steve Block} 124d0825bca7fe65beaee391d30da42e937db621564Steve Block 12516e49e63e74d9236b0d8b72846201697a8ebaedcBen Murdoch#if ENABLE(MEDIA_CAPTURE) 12616e49e63e74d9236b0d8b72846201697a8ebaedcBen MurdochString RenderFileUploadControl::capture() 12716e49e63e74d9236b0d8b72846201697a8ebaedcBen Murdoch{ 12816e49e63e74d9236b0d8b72846201697a8ebaedcBen Murdoch return static_cast<HTMLInputElement*>(node())->capture(); 12916e49e63e74d9236b0d8b72846201697a8ebaedcBen Murdoch} 13016e49e63e74d9236b0d8b72846201697a8ebaedcBen Murdoch#endif 13116e49e63e74d9236b0d8b72846201697a8ebaedcBen Murdoch 132dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid RenderFileUploadControl::chooseIconForFiles(FileChooser* chooser, const Vector<String>& filenames) 133692e5dbf12901edacf14812a6fae25462920af42Steve Block{ 134692e5dbf12901edacf14812a6fae25462920af42Steve Block if (Chrome* chromePointer = chrome()) 135dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block chromePointer->chooseIconForFiles(filenames, chooser); 136692e5dbf12901edacf14812a6fae25462920af42Steve Block} 137692e5dbf12901edacf14812a6fae25462920af42Steve Block 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderFileUploadControl::click() 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 140a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // Requires a user gesture to open the file dialog. 141a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!frame() || !frame()->loader()->isProcessingUserGesture()) 142a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return; 143692e5dbf12901edacf14812a6fae25462920af42Steve Block if (Chrome* chromePointer = chrome()) 144a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch chromePointer->runOpenPanel(frame(), m_fileChooser); 145692e5dbf12901edacf14812a6fae25462920af42Steve Block} 146692e5dbf12901edacf14812a6fae25462920af42Steve Block 147692e5dbf12901edacf14812a6fae25462920af42Steve BlockChrome* RenderFileUploadControl::chrome() const 148692e5dbf12901edacf14812a6fae25462920af42Steve Block{ 1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Frame* frame = node()->document()->frame(); 1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!frame) 151692e5dbf12901edacf14812a6fae25462920af42Steve Block return 0; 1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Page* page = frame->page(); 1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!page) 154692e5dbf12901edacf14812a6fae25462920af42Steve Block return 0; 155692e5dbf12901edacf14812a6fae25462920af42Steve Block return page->chrome(); 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderFileUploadControl::updateFromElement() 1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(node()); 16168513a70bcd92384395513322f1b801e7bf9c729Steve Block ASSERT(inputElement->isFileUpload()); 1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_button) { 1645af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke m_button = ShadowInputElement::create(inputElement); 16568513a70bcd92384395513322f1b801e7bf9c729Steve Block m_button->setType("button"); 1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_button->setValue(fileButtonChooseFileLabel()); 1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RefPtr<RenderStyle> buttonStyle = createButtonStyle(style()); 1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* renderer = m_button->createRenderer(renderArena(), buttonStyle.get()); 1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_button->setRenderer(renderer); 1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project renderer->setStyle(buttonStyle.release()); 1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project renderer->updateFromElement(); 1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_button->setAttached(); 17321939df44de1705786c545cd1bf519d47250322dBen Murdoch m_button->setInDocument(); 1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project addChild(renderer); 1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_button->setDisabled(!theme()->isEnabled(this)); 1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This only supports clearing out the files, but that's OK because for 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // security reasons that's the only change the DOM is allowed to make. 1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FileList* files = inputElement->files(); 1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(files); 1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (files && files->isEmpty() && !m_fileChooser->filenames().isEmpty()) { 1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_fileChooser->clear(); 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project repaint(); 1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderFileUploadControl::maxFilenameWidth() const 1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 192635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return max(0, contentWidth() - m_button->renderBox()->width() - afterButtonSpacing 1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project - (m_fileChooser->icon() ? iconWidth + iconFilenameSpacing : 0)); 1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<RenderStyle> RenderFileUploadControl::createButtonStyle(const RenderStyle* parentStyle) const 1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RefPtr<RenderStyle> style = getCachedPseudoStyle(FILE_UPLOAD_BUTTON); 1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!style) { 2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project style = RenderStyle::create(); 2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (parentStyle) 2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project style->inheritFrom(parentStyle); 2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Button text will wrap on file upload controls with widths smaller than the intrinsic button width 2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // without this setWhiteSpace. 2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project style->setWhiteSpace(NOWRAP); 2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return style.release(); 2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderFileUploadControl::paintObject(PaintInfo& paintInfo, int tx, int ty) 2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (style()->visibility() != VISIBLE) 2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 216dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(m_fileChooser); 2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Push a clip. 2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseChildBlockBackgrounds) { 2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project IntRect clipRect(tx + borderLeft(), ty + borderTop(), 2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project width() - borderLeft() - borderRight(), height() - borderBottom() - borderTop() + buttonShadowHeight); 2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (clipRect.isEmpty()) 2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project paintInfo.context->save(); 2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project paintInfo.context->clip(clipRect); 2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (paintInfo.phase == PaintPhaseForeground) { 229643ca7872b450ea4efacab6188849e5aac2ba161Steve Block const String& displayedFilename = fileTextValue(); 2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned length = displayedFilename.length(); 2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const UChar* string = displayedFilename.characters(); 2322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block TextRun textRun(string, length, false, 0, 0, TextRun::AllowTrailingExpansion, !style()->isLeftToRightDirection(), style()->unicodeBidi() == Override); 2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Determine where the filename should be placed 2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int contentLeft = tx + borderLeft() + paddingLeft(); 236635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project int buttonAndIconWidth = m_button->renderBox()->width() + afterButtonSpacing 2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project + (m_fileChooser->icon() ? iconWidth + iconFilenameSpacing : 0); 2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int textX; 239a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (style()->isLeftToRightDirection()) 2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project textX = contentLeft + buttonAndIconWidth; 2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project textX = contentLeft + contentWidth() - buttonAndIconWidth - style()->font().width(textRun); 2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We want to match the button's baseline 2448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderButton* buttonRenderer = toRenderButton(m_button->renderer()); 2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int textY = buttonRenderer->absoluteBoundingBoxRect().y() 2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project + buttonRenderer->marginTop() + buttonRenderer->borderTop() + buttonRenderer->paddingTop() 2476b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner + buttonRenderer->baselinePosition(AlphabeticBaseline, true, HorizontalLine, PositionOnContainingLine); 2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 249e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block paintInfo.context->setFillColor(style()->visitedDependentColor(CSSPropertyColor), style()->colorSpace()); 2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Draw the filename 252635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project paintInfo.context->drawBidiText(style()->font(), textRun, IntPoint(textX, textY)); 2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_fileChooser->icon()) { 2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Determine where the icon should be placed 2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int iconY = ty + borderTop() + paddingTop() + (contentHeight() - iconHeight) / 2; 2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int iconX; 258a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (style()->isLeftToRightDirection()) 259635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project iconX = contentLeft + m_button->renderBox()->width() + afterButtonSpacing; 2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 261635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project iconX = contentLeft + contentWidth() - m_button->renderBox()->width() - afterButtonSpacing - iconWidth; 2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Draw the file icon 2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_fileChooser->icon()->paint(paintInfo.context, IntRect(iconX, iconY, iconWidth, iconHeight)); 2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Paint the children. 2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderBlock::paintObject(paintInfo, tx, ty); 2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Pop the clip. 2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseChildBlockBackgrounds) 2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project paintInfo.context->restore(); 2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 276bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderFileUploadControl::computePreferredLogicalWidths() 2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 278bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen ASSERT(preferredLogicalWidthsDirty()); 2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 280bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_minPreferredLogicalWidth = 0; 281bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_maxPreferredLogicalWidth = 0; 2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (style()->width().isFixed() && style()->width().value() > 0) 284bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeContentBoxLogicalWidth(style()->width().value()); 2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Figure out how big the filename space needs to be for a given number of characters 2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // (using "0" as the nominal character). 2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const UChar ch = '0'; 28981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float charWidth = style()->font().width(TextRun(&ch, 1, false, 0, 0, TextRun::AllowTrailingExpansion, false)); 290bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_maxPreferredLogicalWidth = (int)ceilf(charWidth * defaultWidthNumChars); 2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) { 294bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->minWidth().value())); 295bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->minWidth().value())); 2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else if (style()->width().isPercent() || (style()->width().isAuto() && style()->height().isPercent())) 297bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_minPreferredLogicalWidth = 0; 2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 299bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth; 3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (style()->maxWidth().isFixed() && style()->maxWidth().value() != undefinedLength) { 302bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->maxWidth().value())); 303bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->maxWidth().value())); 3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 30621939df44de1705786c545cd1bf519d47250322dBen Murdoch int toAdd = borderAndPaddingWidth(); 307bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_minPreferredLogicalWidth += toAdd; 308bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_maxPreferredLogicalWidth += toAdd; 3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 310bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen setPreferredLogicalWidthsDirty(false); 3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3132fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockVisiblePosition RenderFileUploadControl::positionForPoint(const IntPoint&) 3142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 3152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return VisiblePosition(); 3162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 3172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderFileUploadControl::receiveDroppedFiles(const Vector<String>& paths) 3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if ENABLE(DIRECTORY_UPLOAD) 3212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (allowsDirectoryUpload()) { 3222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch receiveDropForDirectoryUpload(paths); 3232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return; 3242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 3252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#endif 3262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (allowsMultipleFiles()) 3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_fileChooser->chooseFiles(paths); 3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_fileChooser->chooseFile(paths[0]); 3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString RenderFileUploadControl::buttonValue() 3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_button) 3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return String(); 3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_button->value(); 3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 341643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockString RenderFileUploadControl::fileTextValue() const 3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_fileChooser->basenameForWidth(style()->font(), maxFilenameWidth()); 3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore 347