diff options
Diffstat (limited to 'WebCore/page/mac/FrameMac.mm')
-rw-r--r-- | WebCore/page/mac/FrameMac.mm | 553 |
1 files changed, 0 insertions, 553 deletions
diff --git a/WebCore/page/mac/FrameMac.mm b/WebCore/page/mac/FrameMac.mm deleted file mode 100644 index 66e2d04..0000000 --- a/WebCore/page/mac/FrameMac.mm +++ /dev/null @@ -1,553 +0,0 @@ -/* - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) - * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "config.h" -#import "Frame.h" - -#import "BlockExceptions.h" -#import "ColorMac.h" -#import "Cursor.h" -#import "DOMInternal.h" -#import "DocumentLoader.h" -#import "EditorClient.h" -#import "Event.h" -#import "FrameLoaderClient.h" -#import "FramePrivate.h" -#import "FrameView.h" -#import "GraphicsContext.h" -#import "HTMLNames.h" -#import "HTMLTableCellElement.h" -#import "HitTestRequest.h" -#import "HitTestResult.h" -#import "KeyboardEvent.h" -#import "Logging.h" -#import "MouseEventWithHitTestResults.h" -#import "Page.h" -#import "PlatformKeyboardEvent.h" -#import "PlatformWheelEvent.h" -#import "RegularExpression.h" -#import "RenderTableCell.h" -#import "Scrollbar.h" -#import "SimpleFontData.h" -#import "UserStyleSheetLoader.h" -#import "WebCoreViewFactory.h" -#import "visible_units.h" - -#import <Carbon/Carbon.h> -#import <runtime/JSLock.h> - -#if ENABLE(DASHBOARD_SUPPORT) -#import "WebDashboardRegion.h" -#endif - -@interface NSView (WebCoreHTMLDocumentView) -- (void)drawSingleRect:(NSRect)rect; -@end - -using namespace std; - -using JSC::JSLock; - -namespace WebCore { - -using namespace HTMLNames; - -// Either get cached regexp or build one that matches any of the labels. -// The regexp we build is of the form: (STR1|STR2|STRN) -RegularExpression* regExpForLabels(NSArray* labels) -{ - // All the ObjC calls in this method are simple array and string - // calls which we can assume do not raise exceptions - - - // Parallel arrays that we use to cache regExps. In practice the number of expressions - // that the app will use is equal to the number of locales is used in searching. - static const unsigned int regExpCacheSize = 4; - static NSMutableArray* regExpLabels = nil; - static Vector<RegularExpression*> regExps; - static RegularExpression wordRegExp = RegularExpression("\\w"); - - RegularExpression* result; - if (!regExpLabels) - regExpLabels = [[NSMutableArray alloc] initWithCapacity:regExpCacheSize]; - CFIndex cacheHit = [regExpLabels indexOfObject:labels]; - if (cacheHit != NSNotFound) - result = regExps.at(cacheHit); - else { - String pattern("("); - unsigned int numLabels = [labels count]; - unsigned int i; - for (i = 0; i < numLabels; i++) { - String label = [labels objectAtIndex:i]; - - bool startsWithWordChar = false; - bool endsWithWordChar = false; - if (label.length() != 0) { - startsWithWordChar = wordRegExp.search(label.substring(0, 1)) >= 0; - endsWithWordChar = wordRegExp.search(label.substring(label.length() - 1, 1)) >= 0; - } - - if (i != 0) - pattern.append("|"); - // Search for word boundaries only if label starts/ends with "word characters". - // If we always searched for word boundaries, this wouldn't work for languages - // such as Japanese. - if (startsWithWordChar) - pattern.append("\\b"); - pattern.append(label); - if (endsWithWordChar) - pattern.append("\\b"); - } - pattern.append(")"); - result = new RegularExpression(pattern, false); - } - - // add regexp to the cache, making sure it is at the front for LRU ordering - if (cacheHit != 0) { - if (cacheHit != NSNotFound) { - // remove from old spot - [regExpLabels removeObjectAtIndex:cacheHit]; - regExps.remove(cacheHit); - } - // add to start - [regExpLabels insertObject:labels atIndex:0]; - regExps.insert(0, result); - // trim if too big - if ([regExpLabels count] > regExpCacheSize) { - [regExpLabels removeObjectAtIndex:regExpCacheSize]; - RegularExpression* last = regExps.last(); - regExps.removeLast(); - delete last; - } - } - return result; -} - -NSString* Frame::searchForNSLabelsAboveCell(RegularExpression* regExp, HTMLTableCellElement* cell) -{ - RenderTableCell* cellRenderer = static_cast<RenderTableCell*>(cell->renderer()); - - if (cellRenderer && cellRenderer->isTableCell()) { - RenderTableCell* cellAboveRenderer = cellRenderer->table()->cellAbove(cellRenderer); - - if (cellAboveRenderer) { - HTMLTableCellElement* aboveCell = - static_cast<HTMLTableCellElement*>(cellAboveRenderer->element()); - - if (aboveCell) { - // search within the above cell we found for a match - for (Node* n = aboveCell->firstChild(); n; n = n->traverseNextNode(aboveCell)) { - if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) { - // For each text chunk, run the regexp - String nodeString = n->nodeValue(); - int pos = regExp->searchRev(nodeString); - if (pos >= 0) - return nodeString.substring(pos, regExp->matchedLength()); - } - } - } - } - } - // Any reason in practice to search all cells in that are above cell? - return nil; -} - -NSString* Frame::searchForLabelsBeforeElement(NSArray* labels, Element* element) -{ - RegularExpression* regExp = regExpForLabels(labels); - // We stop searching after we've seen this many chars - const unsigned int charsSearchedThreshold = 500; - // This is the absolute max we search. We allow a little more slop than - // charsSearchedThreshold, to make it more likely that we'll search whole nodes. - const unsigned int maxCharsSearched = 600; - // If the starting element is within a table, the cell that contains it - HTMLTableCellElement* startingTableCell = 0; - bool searchedCellAbove = false; - - // walk backwards in the node tree, until another element, or form, or end of tree - int unsigned lengthSearched = 0; - Node* n; - for (n = element->traversePreviousNode(); - n && lengthSearched < charsSearchedThreshold; - n = n->traversePreviousNode()) - { - if (n->hasTagName(formTag) - || (n->isHTMLElement() - && static_cast<HTMLElement*>(n)->isGenericFormElement())) - { - // We hit another form element or the start of the form - bail out - break; - } else if (n->hasTagName(tdTag) && !startingTableCell) { - startingTableCell = static_cast<HTMLTableCellElement*>(n); - } else if (n->hasTagName(trTag) && startingTableCell) { - NSString* result = searchForLabelsAboveCell(regExp, startingTableCell); - if (result && [result length] > 0) - return result; - searchedCellAbove = true; - } else if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) { - // For each text chunk, run the regexp - String nodeString = n->nodeValue(); - // add 100 for slop, to make it more likely that we'll search whole nodes - if (lengthSearched + nodeString.length() > maxCharsSearched) - nodeString = nodeString.right(charsSearchedThreshold - lengthSearched); - int pos = regExp->searchRev(nodeString); - if (pos >= 0) - return nodeString.substring(pos, regExp->matchedLength()); - - lengthSearched += nodeString.length(); - } - } - - // If we started in a cell, but bailed because we found the start of the form or the - // previous element, we still might need to search the row above us for a label. - if (startingTableCell && !searchedCellAbove) { - NSString* result = searchForLabelsAboveCell(regExp, startingTableCell); - if (result && [result length] > 0) - return result; - } - - return nil; -} - -NSString* Frame::matchLabelsAgainstElement(NSArray* labels, Element* element) -{ - String name = element->getAttribute(nameAttr); - if (name.isEmpty()) - return nil; - - // Make numbers and _'s in field names behave like word boundaries, e.g., "address2" - replace(name, RegularExpression("\\d"), " "); - name.replace('_', ' '); - - RegularExpression* regExp = regExpForLabels(labels); - // Use the largest match we can find in the whole name string - int pos; - int length; - int bestPos = -1; - int bestLength = -1; - int start = 0; - do { - pos = regExp->search(name, start); - if (pos != -1) { - length = regExp->matchedLength(); - if (length >= bestLength) { - bestPos = pos; - bestLength = length; - } - start = pos + 1; - } - } while (pos != -1); - - if (bestPos != -1) - return name.substring(bestPos, bestLength); - return nil; -} - -NSImage* Frame::imageFromRect(NSRect rect) const -{ - NSView* view = d->m_view->documentView(); - if (!view) - return nil; - if (![view respondsToSelector:@selector(drawSingleRect:)]) - return nil; - - NSImage* resultImage; - BEGIN_BLOCK_OBJC_EXCEPTIONS; - - NSRect bounds = [view bounds]; - - // Round image rect size in window coordinate space to avoid pixel cracks at HiDPI (4622794) - rect = [view convertRect:rect toView:nil]; - rect.size.height = roundf(rect.size.height); - rect.size.width = roundf(rect.size.width); - rect = [view convertRect:rect fromView:nil]; - - resultImage = [[[NSImage alloc] initWithSize:rect.size] autorelease]; - - if (rect.size.width != 0 && rect.size.height != 0) { - [resultImage setFlipped:YES]; - [resultImage lockFocus]; - CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; - CGContextSaveGState(context); - CGContextTranslateCTM(context, bounds.origin.x - rect.origin.x, bounds.origin.y - rect.origin.y); - - // Note: Must not call drawRect: here, because drawRect: assumes that it's called from AppKit's - // display machinery. It calls getRectsBeingDrawn:count:, which can only be called inside - // when a real AppKit display is underway. - [view drawSingleRect:rect]; - - CGContextRestoreGState(context); - [resultImage unlockFocus]; - [resultImage setFlipped:NO]; - } - - return resultImage; - - END_BLOCK_OBJC_EXCEPTIONS; - - return nil; -} - -NSImage* Frame::selectionImage(bool forceBlackText) const -{ - d->m_view->setPaintRestriction(forceBlackText ? PaintRestrictionSelectionOnlyBlackText : PaintRestrictionSelectionOnly); - d->m_doc->updateLayout(); - NSImage* result = imageFromRect(selectionRect()); - d->m_view->setPaintRestriction(PaintRestrictionNone); - return result; -} - -NSImage* Frame::snapshotDragImage(Node* node, NSRect* imageRect, NSRect* elementRect) const -{ - RenderObject* renderer = node->renderer(); - if (!renderer) - return nil; - - renderer->updateDragState(true); // mark dragged nodes (so they pick up the right CSS) - d->m_doc->updateLayout(); // forces style recalc - needed since changing the drag state might - // imply new styles, plus JS could have changed other things - IntRect topLevelRect; - NSRect paintingRect = renderer->paintingRootRect(topLevelRect); - - d->m_view->setNodeToDraw(node); // invoke special sub-tree drawing mode - NSImage* result = imageFromRect(paintingRect); - renderer->updateDragState(false); - d->m_doc->updateLayout(); - d->m_view->setNodeToDraw(0); - - if (elementRect) - *elementRect = topLevelRect; - if (imageRect) - *imageRect = paintingRect; - return result; -} - -NSImage* Frame::nodeImage(Node* node) const -{ - RenderObject* renderer = node->renderer(); - if (!renderer) - return nil; - - d->m_doc->updateLayout(); // forces style recalc - - IntRect topLevelRect; - NSRect paintingRect = renderer->paintingRootRect(topLevelRect); - - d->m_view->setNodeToDraw(node); // invoke special sub-tree drawing mode - NSImage* result = imageFromRect(paintingRect); - d->m_view->setNodeToDraw(0); - - return result; -} - -NSDictionary* Frame::fontAttributesForSelectionStart() const -{ - Node* nodeToRemove; - RenderStyle* style = styleForSelectionStart(nodeToRemove); - if (!style) - return nil; - - NSMutableDictionary* result = [NSMutableDictionary dictionary]; - - if (style->backgroundColor().isValid() && style->backgroundColor().alpha() != 0) - [result setObject:nsColor(style->backgroundColor()) forKey:NSBackgroundColorAttributeName]; - - if (style->font().primaryFont()->getNSFont()) - [result setObject:style->font().primaryFont()->getNSFont() forKey:NSFontAttributeName]; - - if (style->color().isValid() && style->color() != Color::black) - [result setObject:nsColor(style->color()) forKey:NSForegroundColorAttributeName]; - - ShadowData* shadow = style->textShadow(); - if (shadow) { - NSShadow* s = [[NSShadow alloc] init]; - [s setShadowOffset:NSMakeSize(shadow->x, shadow->y)]; - [s setShadowBlurRadius:shadow->blur]; - [s setShadowColor:nsColor(shadow->color)]; - [result setObject:s forKey:NSShadowAttributeName]; - } - - int decoration = style->textDecorationsInEffect(); - if (decoration & LINE_THROUGH) - [result setObject:[NSNumber numberWithInt:NSUnderlineStyleSingle] forKey:NSStrikethroughStyleAttributeName]; - - int superscriptInt = 0; - switch (style->verticalAlign()) { - case BASELINE: - case BOTTOM: - case BASELINE_MIDDLE: - case LENGTH: - case MIDDLE: - case TEXT_BOTTOM: - case TEXT_TOP: - case TOP: - break; - case SUB: - superscriptInt = -1; - break; - case SUPER: - superscriptInt = 1; - break; - } - if (superscriptInt) - [result setObject:[NSNumber numberWithInt:superscriptInt] forKey:NSSuperscriptAttributeName]; - - if (decoration & UNDERLINE) - [result setObject:[NSNumber numberWithInt:NSUnderlineStyleSingle] forKey:NSUnderlineStyleAttributeName]; - - if (nodeToRemove) { - ExceptionCode ec = 0; - nodeToRemove->remove(ec); - ASSERT(ec == 0); - } - - return result; -} - -NSWritingDirection Frame::baseWritingDirectionForSelectionStart() const -{ - NSWritingDirection result = NSWritingDirectionLeftToRight; - - Position pos = selection()->selection().visibleStart().deepEquivalent(); - Node* node = pos.node(); - if (!node) - return result; - - RenderObject* renderer = node->renderer(); - if (!renderer) - return result; - - if (!renderer->isBlockFlow()) { - renderer = renderer->containingBlock(); - if (!renderer) - return result; - } - - RenderStyle* style = renderer->style(); - if (!style) - return result; - - switch (style->direction()) { - case LTR: - result = NSWritingDirectionLeftToRight; - break; - case RTL: - result = NSWritingDirectionRightToLeft; - break; - } - - return result; -} - -const short enableRomanKeyboardsOnly = -23; -void Frame::setUseSecureKeyboardEntry(bool enable) -{ - if (enable == IsSecureEventInputEnabled()) - return; - if (enable) { - EnableSecureEventInput(); -#ifdef BUILDING_ON_TIGER - KeyScript(enableRomanKeyboardsOnly); -#else - CFArrayRef inputSources = TISCreateASCIICapableInputSourceList(); - TSMSetDocumentProperty(TSMGetActiveDocument(), kTSMDocumentEnabledInputSourcesPropertyTag, sizeof(CFArrayRef), &inputSources); - CFRelease(inputSources); -#endif - } else { - DisableSecureEventInput(); -#ifdef BUILDING_ON_TIGER - KeyScript(smKeyEnableKybds); -#else - TSMRemoveDocumentProperty(TSMGetActiveDocument(), kTSMDocumentEnabledInputSourcesPropertyTag); -#endif - } -} - -#if ENABLE(DASHBOARD_SUPPORT) -NSMutableDictionary* Frame::dashboardRegionsDictionary() -{ - Document* doc = document(); - if (!doc) - return nil; - - const Vector<DashboardRegionValue>& regions = doc->dashboardRegions(); - size_t n = regions.size(); - - // Convert the Vector<DashboardRegionValue> into a NSDictionary of WebDashboardRegions - NSMutableDictionary* webRegions = [NSMutableDictionary dictionaryWithCapacity:n]; - for (size_t i = 0; i < n; i++) { - const DashboardRegionValue& region = regions[i]; - - if (region.type == StyleDashboardRegion::None) - continue; - - NSString *label = region.label; - WebDashboardRegionType type = WebDashboardRegionTypeNone; - if (region.type == StyleDashboardRegion::Circle) - type = WebDashboardRegionTypeCircle; - else if (region.type == StyleDashboardRegion::Rectangle) - type = WebDashboardRegionTypeRectangle; - NSMutableArray *regionValues = [webRegions objectForKey:label]; - if (!regionValues) { - regionValues = [[NSMutableArray alloc] initWithCapacity:1]; - [webRegions setObject:regionValues forKey:label]; - [regionValues release]; - } - - WebDashboardRegion *webRegion = [[WebDashboardRegion alloc] initWithRect:region.bounds clip:region.clip type:type]; - [regionValues addObject:webRegion]; - [webRegion release]; - } - - return webRegions; -} -#endif - -DragImageRef Frame::dragImageForSelection() -{ - if (!selection()->isRange()) - return nil; - return selectionImage(); -} - -void Frame::setUserStyleSheetLocation(const KURL& url) -{ - delete d->m_userStyleSheetLoader; - d->m_userStyleSheetLoader = 0; - if (d->m_doc && d->m_doc->docLoader()) - d->m_userStyleSheetLoader = new UserStyleSheetLoader(d->m_doc, url.string()); -} - -void Frame::setUserStyleSheet(const String& styleSheet) -{ - delete d->m_userStyleSheetLoader; - d->m_userStyleSheetLoader = 0; - if (d->m_doc) - d->m_doc->setUserStyleSheet(styleSheet); -} - -} // namespace WebCore |