18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * Copyright (C) 2006, 2008, 2009 Apple Inc. All rights reserved. 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DeleteButtonController.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CachedImage.h" 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CSSMutableStyleDeclaration.h" 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CSSPrimitiveValue.h" 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CSSPropertyNames.h" 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CSSValueKeywords.h" 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DeleteButton.h" 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Document.h" 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Editor.h" 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h" 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "htmlediting.h" 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLDivElement.h" 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h" 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Image.h" 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Node.h" 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Range.h" 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RemoveNodeCommand.h" 45635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "RenderBox.h" 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SelectionController.h" 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace HTMLNames; 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst char* const DeleteButtonController::containerElementIdentifier = "WebKit-Editing-Delete-Container"; 538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst char* const DeleteButtonController::buttonElementIdentifier = "WebKit-Editing-Delete-Button"; 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst char* const DeleteButtonController::outlineElementIdentifier = "WebKit-Editing-Delete-Outline"; 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectDeleteButtonController::DeleteButtonController(Frame* frame) 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project : m_frame(frame) 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_wasStaticPositioned(false) 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_wasAutoZIndex(false) 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_disableStack(0) 618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool isDeletableElement(const Node* node) 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 662bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!node || !node->isHTMLElement() || !node->inDocument() || !node->rendererIsEditable()) 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 69d0825bca7fe65beaee391d30da42e937db621564Steve Block // In general we want to only draw the UI around object of a certain area, but we still keep the min width/height to 705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // make sure we don't end up with very thin or very short elements getting the UI. 715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian const int minimumArea = 2500; 725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian const int minimumWidth = 48; 735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian const int minimumHeight = 16; 745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian const unsigned minimumVisibleBorders = 1; 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* renderer = node->renderer(); 77635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!renderer || !renderer->isBox()) 78635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return false; 79635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Disallow the body element since it isn't practical to delete, and the deletion UI would be clipped. 815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (node->hasTagName(bodyTag)) 825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return false; 835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Disallow elements with any overflow clip, since the deletion UI would be clipped as well. <rdar://problem/6840161> 855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (renderer->hasOverflowClip()) 865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return false; 875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Disallow Mail blockquotes since the deletion UI would get in the way of editing for these. 895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (isMailBlockquote(node)) 905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return false; 915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 92635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RenderBox* box = toRenderBox(renderer); 93635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project IntRect borderBoundingBox = box->borderBoundingBox(); 94635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (borderBoundingBox.width() < minimumWidth || borderBoundingBox.height() < minimumHeight) 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if ((borderBoundingBox.width() * borderBoundingBox.height()) < minimumArea) 985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return false; 995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (renderer->isTable()) 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (node->hasTagName(ulTag) || node->hasTagName(olTag) || node->hasTagName(iframeTag)) 1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (renderer->isPositioned()) 1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (renderer->isRenderBlock() && !renderer->isTableCell()) { 1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderStyle* style = renderer->style(); 1115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!style) 1125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return false; 1135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Allow blocks that have background images 1152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (style->hasBackgroundImage()) { 1162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch for (const FillLayer* background = style->backgroundLayers(); background; background = background->next()) { 1172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (background->image() && background->image()->canRender(1)) 1182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 1192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 1202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 1215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Allow blocks with a minimum number of non-transparent borders 1235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian unsigned visibleBorders = style->borderTop().isVisible() + style->borderBottom().isVisible() + style->borderLeft().isVisible() + style->borderRight().isVisible(); 1245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (visibleBorders >= minimumVisibleBorders) 1255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return true; 1265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Allow blocks that have a different background from it's parent 128a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ContainerNode* parentNode = node->parentNode(); 1295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!parentNode) 1305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return false; 1315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian RenderObject* parentRenderer = parentNode->renderer(); 1335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!parentRenderer) 1345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return false; 1355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian RenderStyle* parentStyle = parentRenderer->style(); 1375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!parentStyle) 1385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return false; 1395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 140e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (renderer->hasBackground() && (!parentRenderer->hasBackground() || style->visitedDependentColor(CSSPropertyBackgroundColor) != parentStyle->visitedDependentColor(CSSPropertyBackgroundColor))) 1415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return true; 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic HTMLElement* enclosingDeletableElement(const VisibleSelection& selection) 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!selection.isContentEditable()) 1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RefPtr<Range> range = selection.toNormalizedRange(); 1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!range) 1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ExceptionCode ec = 0; 1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* container = range->commonAncestorContainer(ec); 1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(container); 1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(ec == 0); 1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // The enclosingNodeOfType function only works on nodes that are editable 1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // (which is strange, given its name). 1632bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!container->rendererIsEditable()) 1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Node* element = enclosingNodeOfType(firstPositionInNode(container), &isDeletableElement); 1672bde8e466a4451c7319e3a072d118917957d6554Steve Block return element && element->isHTMLElement() ? toHTMLElement(element) : 0; 1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid DeleteButtonController::respondToChangedSelection(const VisibleSelection& oldSelection) 1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!enabled()) 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HTMLElement* oldElement = enclosingDeletableElement(oldSelection); 1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HTMLElement* newElement = enclosingDeletableElement(m_frame->selection()->selection()); 1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (oldElement == newElement) 1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the base is inside a deletable element, give the element a delete widget. 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (newElement) 1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project show(newElement); 1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hide(); 1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid DeleteButtonController::createDeletionUI() 1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1895af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke RefPtr<HTMLDivElement> container = HTMLDivElement::create(m_target->document()); 190545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch container->setIdAttribute(containerElementIdentifier); 1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CSSMutableStyleDeclaration* style = container->getInlineStyleDecl(); 1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project style->setProperty(CSSPropertyWebkitUserDrag, CSSValueNone); 1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project style->setProperty(CSSPropertyWebkitUserSelect, CSSValueNone); 1952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch style->setProperty(CSSPropertyWebkitUserModify, CSSValueReadOnly); 1968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian style->setProperty(CSSPropertyVisibility, CSSValueHidden); 1978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian style->setProperty(CSSPropertyPosition, CSSValueAbsolute); 1988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian style->setProperty(CSSPropertyCursor, CSSValueDefault); 1998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian style->setProperty(CSSPropertyTop, "0"); 2008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian style->setProperty(CSSPropertyRight, "0"); 2018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian style->setProperty(CSSPropertyBottom, "0"); 2028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian style->setProperty(CSSPropertyLeft, "0"); 2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2045af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke RefPtr<HTMLDivElement> outline = HTMLDivElement::create(m_target->document()); 205545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch outline->setIdAttribute(outlineElementIdentifier); 2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const int borderWidth = 4; 2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const int borderRadius = 6; 2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project style = outline->getInlineStyleDecl(); 2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project style->setProperty(CSSPropertyPosition, CSSValueAbsolute); 2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project style->setProperty(CSSPropertyZIndex, String::number(-1000000)); 213635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project style->setProperty(CSSPropertyTop, String::number(-borderWidth - m_target->renderBox()->borderTop()) + "px"); 214635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project style->setProperty(CSSPropertyRight, String::number(-borderWidth - m_target->renderBox()->borderRight()) + "px"); 215635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project style->setProperty(CSSPropertyBottom, String::number(-borderWidth - m_target->renderBox()->borderBottom()) + "px"); 216635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project style->setProperty(CSSPropertyLeft, String::number(-borderWidth - m_target->renderBox()->borderLeft()) + "px"); 2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project style->setProperty(CSSPropertyBorder, String::number(borderWidth) + "px solid rgba(0, 0, 0, 0.6)"); 2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project style->setProperty(CSSPropertyWebkitBorderRadius, String::number(borderRadius) + "px"); 2198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian style->setProperty(CSSPropertyVisibility, CSSValueVisible); 2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ExceptionCode ec = 0; 2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project container->appendChild(outline.get(), ec); 2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(ec == 0); 2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (ec) 2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2275af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke RefPtr<DeleteButton> button = DeleteButton::create(m_target->document()); 228545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch button->setIdAttribute(buttonElementIdentifier); 2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const int buttonWidth = 30; 2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const int buttonHeight = 30; 2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const int buttonBottomShadowOffset = 2; 2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project style = button->getInlineStyleDecl(); 2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project style->setProperty(CSSPropertyPosition, CSSValueAbsolute); 2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project style->setProperty(CSSPropertyZIndex, String::number(1000000)); 237635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project style->setProperty(CSSPropertyTop, String::number((-buttonHeight / 2) - m_target->renderBox()->borderTop() - (borderWidth / 2) + buttonBottomShadowOffset) + "px"); 238635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project style->setProperty(CSSPropertyLeft, String::number((-buttonWidth / 2) - m_target->renderBox()->borderLeft() - (borderWidth / 2)) + "px"); 2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project style->setProperty(CSSPropertyWidth, String::number(buttonWidth) + "px"); 2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project style->setProperty(CSSPropertyHeight, String::number(buttonHeight) + "px"); 2418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian style->setProperty(CSSPropertyVisibility, CSSValueVisible); 2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RefPtr<Image> buttonImage = Image::loadPlatformResource("deleteButton"); 2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (buttonImage->isNull()) 2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project button->setCachedImage(new CachedImage(buttonImage.get())); 2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project container->appendChild(button.get(), ec); 2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(ec == 0); 2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (ec) 2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_containerElement = container.release(); 2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_outlineElement = outline.release(); 2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_buttonElement = button.release(); 2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid DeleteButtonController::show(HTMLElement* element) 2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hide(); 2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!enabled() || !element || !element->inDocument() || !isDeletableElement(element)) 2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!m_frame->editor()->shouldShowDeleteInterface(toHTMLElement(element))) 2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // we rely on the renderer having current information, so we should update the layout if needed 2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_frame->document()->updateLayoutIgnorePendingStylesheets(); 2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_target = element; 2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_containerElement) { 2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project createDeletionUI(); 2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_containerElement) { 2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hide(); 2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ExceptionCode ec = 0; 2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_target->appendChild(m_containerElement.get(), ec); 2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(ec == 0); 2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (ec) { 2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hide(); 2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_target->renderer()->style()->position() == StaticPosition) { 2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_target->getInlineStyleDecl()->setProperty(CSSPropertyPosition, CSSValueRelative); 2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_wasStaticPositioned = true; 2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_target->renderer()->style()->hasAutoZIndex()) { 2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_target->getInlineStyleDecl()->setProperty(CSSPropertyZIndex, "0"); 2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_wasAutoZIndex = true; 2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid DeleteButtonController::hide() 3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_outlineElement = 0; 3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_buttonElement = 0; 3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ExceptionCode ec = 0; 3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_containerElement && m_containerElement->parentNode()) 3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_containerElement->parentNode()->removeChild(m_containerElement.get(), ec); 3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_target) { 3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_wasStaticPositioned) 3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_target->getInlineStyleDecl()->setProperty(CSSPropertyPosition, CSSValueStatic); 3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_wasAutoZIndex) 3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_target->getInlineStyleDecl()->setProperty(CSSPropertyZIndex, CSSValueAuto); 3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_wasStaticPositioned = false; 3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_wasAutoZIndex = false; 3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid DeleteButtonController::enable() 3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(m_disableStack > 0); 3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_disableStack > 0) 3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_disableStack--; 3268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (enabled()) { 3278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Determining if the element is deletable currently depends on style 3288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // because whether something is editable depends on style, so we need 3298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // to recalculate style before calling enclosingDeletableElement. 3305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_frame->document()->updateStyleIfNeeded(); 3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project show(enclosingDeletableElement(m_frame->selection()->selection())); 3328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid DeleteButtonController::disable() 3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (enabled()) 3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hide(); 3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_disableStack++; 3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid DeleteButtonController::deleteTarget() 3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!enabled() || !m_target) 3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RefPtr<Node> element = m_target; 3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hide(); 3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Because the deletion UI only appears when the selection is entirely 3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // within the target, we unconditionally update the selection to be 3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // a caret where the target had been. 353231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block Position pos = positionInParentBeforeNode(element.get()); 3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project applyCommand(RemoveNodeCommand::create(element.release())); 3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_frame->selection()->setSelection(VisiblePosition(pos)); 3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore 359