1 /*
   2  * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #pragma once
  27 
  28 #include "config.h"
  29 
  30 #include "SharedBuffer.h"
  31 #include <wtf/text/StringHash.h>
  32 #include <wtf/ListHashSet.h>
  33 #include <wtf/Vector.h>
  34 #include <URL.h>
  35 
  36 namespace WebCore {
  37 // A data object for holding data that would be in a clipboard or moved
  38 // during a drag-n-drop operation.  This is the data that WebCore is aware
  39 // of and is not specific to a platform.
  40 class DataObjectJava : public RefCounted<DataObjectJava> {
  41 public:
  42     static const URL& emptyURL()            { static URL r; return r; }
  43     static const String& emptyString()      { static String r; return r; }
  44 
  45     static const String &mimePlainText()    { static String r("text/plain"); return r; }
  46     static const String &mimeHTML()         { static String r("text/html"); return r; }
  47     static const String &mimeURIList()      { static String r("text/uri-list"); return r; }
  48     static const String &mimeShortcutName() { static String r("text/ie-shortcut-filename"); return r; }
  49 
  50     // We provide the IE clipboard types (URL and Text),
  51     // and the clipboard types specified in the WHATWG Web Applications 1.0 draft
  52     // see http://www.whatwg.org/specs/web-apps/current-work/ Section 6.3.5.3
  53     static String normalizeMIMEType(const String& type)
  54     {
  55         String qType = type.stripWhiteSpace().convertToLowercaseWithoutLocale();
  56         // two special cases for IE compatibility
  57         if (qType == "text" || qType.startsWith("text/plain;"))
  58             return mimePlainText();
  59         if (qType == "url")
  60             return mimeURIList();
  61         return qType;
  62     }
  63 
  64     static RefPtr<DataObjectJava> create()
  65     {
  66         return adoptRef(new DataObjectJava);
  67     }
  68 
  69     RefPtr<DataObjectJava> copy() const
  70     {
  71         return adoptRef(new DataObjectJava(*this));
  72     }
  73 
  74     void clear() {
  75         m_availMimeTypes.clear();
  76     }
  77 
  78     void clearData(const String& mimeType) {
  79         size_t pos = m_availMimeTypes.find(mimeType);
  80         if (pos != WTF::notFound) {
  81             m_availMimeTypes.remove(pos);
  82         }
  83     }
  84 
  85     bool hasData() const {
  86         return !m_availMimeTypes.isEmpty();
  87     }
  88 
  89     //setters
  90     void setURL(const URL &url, const String &urlTitle) {
  91         m_availMimeTypes.append(mimeURIList());
  92         m_availMimeTypes.append(mimeShortcutName());
  93         m_url = url;
  94         m_urlTitle = urlTitle;
  95         m_filenames.clear();
  96     }
  97 
  98     void setFiles(const Vector<String> &filenames) {
  99         m_availMimeTypes.append(mimeURIList());
 100         clearData(mimeShortcutName());
 101         m_url = emptyURL();
 102         m_urlTitle = emptyString();
 103         m_filenames = filenames;
 104     }
 105 
 106     void setPlainText(const String &plainText){
 107         m_availMimeTypes.append(mimePlainText());
 108         m_plainText = plainText;
 109     }
 110 
 111     void setHTML(const String &textHtml, const URL &htmlBaseUrl) {
 112         m_availMimeTypes.append(mimeHTML());
 113         m_textHtml = textHtml;
 114         m_htmlBaseUrl = htmlBaseUrl;
 115     }
 116 
 117     bool setData(const String& mimeType, const String& data) {
 118         bool succeeded = true;
 119         String canonicalMimeType = normalizeMIMEType(mimeType);
 120         if (canonicalMimeType == mimeURIList())
 121             setURL(URL(ParsedURLString, data), emptyString());
 122         else if (canonicalMimeType == mimeHTML())
 123             setHTML(data, emptyURL());
 124         else if (canonicalMimeType == mimePlainText()) // two special cases for IE compatibility
 125             setPlainText(data);
 126         else if (canonicalMimeType == mimeShortcutName())
 127             m_urlTitle = data; //activates by previous setUrl call
 128         else
 129             succeeded = false;
 130         return succeeded;
 131     }
 132 
 133     //getters
 134     //URL
 135     Vector<String> types() {
 136         //returns MIME Types available in clipboard.
 137         return m_availMimeTypes;
 138     }
 139 
 140     String getData(const String& mimeType) {
 141         String canonicalMimeType = normalizeMIMEType(mimeType);
 142         String ret;
 143         if (canonicalMimeType == mimeURIList())
 144             ret = asURL();
 145         else if (canonicalMimeType == mimeHTML())
 146             ret = asHTML();
 147         else if (canonicalMimeType == mimePlainText())
 148             ret = asPlainText();
 149         else if (canonicalMimeType == mimeShortcutName())
 150             ret = m_urlTitle;
 151         return ret;
 152     }
 153 
 154     bool containsURL() const {
 155         return m_availMimeTypes.contains(mimeURIList());
 156     }
 157 
 158     String asURL(String* title = NULL) const
 159     {
 160         if (!containsURL())
 161             return String();
 162 
 163         if(m_url.isEmpty() && !m_filenames.isEmpty())
 164             return m_filenames.at(0);
 165 
 166         // |title| can be NULL
 167         if (title)
 168             *title = m_urlTitle;
 169         return m_url.string();
 170     }
 171 
 172     //File List
 173     bool containsFiles() const {
 174         return containsURL();
 175     }
 176 
 177     Vector<String> asFilenames() const {
 178         Vector<String> result {};
 179         if(m_url.isEmpty() && !m_filenames.isEmpty())
 180             result = m_filenames;
 181         else if(!m_url.isEmpty())
 182             result.append(m_url.string());
 183         return result;
 184     }
 185 
 186     //Plain Text
 187     bool containsPlainText() const {
 188         return m_availMimeTypes.contains(mimePlainText());
 189     }
 190     String asPlainText() const {
 191         return m_plainText;
 192     }
 193 
 194 
 195     bool containsHTML() const {
 196         return m_availMimeTypes.contains(mimeHTML());
 197     }
 198     String asHTML(String* baseURL = NULL) const
 199     {
 200         if (!containsHTML())
 201             return String();
 202 
 203         // |baseURL| can be NULL
 204         if (baseURL)
 205             *baseURL = m_htmlBaseUrl;
 206         return m_textHtml;
 207     }
 208 
 209     // tav todo: where and how it's supposed to be used?
 210     String m_fileContentFilename;
 211     RefPtr<SharedBuffer> m_fileContent;
 212 
 213     ~DataObjectJava() {
 214     }
 215 
 216     const Vector<String>& filenames() const {
 217         return m_filenames;
 218     }
 219 
 220 private:
 221     Vector<String> m_availMimeTypes;
 222 
 223     //URL
 224     URL m_url;
 225     String m_urlTitle;
 226     Vector<String> m_filenames;
 227 
 228     //plain text
 229     String m_plainText;
 230 
 231     //html text
 232     String m_textHtml;
 233     URL m_htmlBaseUrl;
 234 
 235     DataObjectJava() {
 236     }
 237 
 238     DataObjectJava(const DataObjectJava& data) :
 239         RefCounted<WebCore::DataObjectJava>(),
 240         m_availMimeTypes(data.m_availMimeTypes),
 241         m_url(data.m_url),
 242         m_urlTitle(data.m_urlTitle),
 243         m_filenames(data.m_filenames),
 244         m_plainText(data.m_plainText),
 245         m_textHtml(data.m_textHtml),
 246         m_htmlBaseUrl(data.m_htmlBaseUrl)
 247     {
 248     }
 249 };
 250 } // namespace WebCore